diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 0a7141c1be3..1fcdb6ba53c 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -6,4 +6,3 @@ /cmake/** @jtattermusch @nicolasnoble @apolcyn /src/core/ext/filters/client_channel/** @markdroth @apolcyn @AspirinSJL /tools/dockerfile/** @jtattermusch @apolcyn @nicolasnoble -/tools/run_tests/performance/** @ncteisen @apolcyn @jtattermusch diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md old mode 100644 new mode 100755 index d31aea6c736..acfcdc14845 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -3,7 +3,7 @@ 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 +- StackOverflow, with "grpc" tag: https://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) --> @@ -11,7 +11,7 @@ Issues specific to *grpc-java*, *grpc-go*, *grpc-node*, *grpc-dart*, *grpc-web* ### What version of gRPC and what language are you using? -### What operating system (Linux, Windows, …) and version? +### What operating system (Linux, Windows,...) and version? ### What runtime / compiler are you using (e.g. python version or version of gcc) @@ -27,7 +27,7 @@ If possible, provide a recipe for reproducing the error. Try being specific and Make sure you include information that can help us debug (full error message, exception listing, stack trace, logs). -See https://github.com/grpc/grpc/blob/master/TROUBLESHOOTING.md for how to diagnose problems better. +See [TROUBLESHOOTING.md](https://github.com/grpc/grpc/blob/master/TROUBLESHOOTING.md) for how to diagnose problems better. ### Anything else we should know about your project / environment? diff --git a/.github/mergeable.yml b/.github/mergeable.yml index b9dc51a2c6f..103b6fd15c8 100644 --- a/.github/mergeable.yml +++ b/.github/mergeable.yml @@ -1,14 +1,18 @@ mergeable: pull_requests: label: - or: - - and: + and: + - must_exclude: + regex: '^disposition/DO NOT MERGE' + message: 'Pull request marked not mergeable' + - or: + - and: + - must_include: + regex: 'release notes: yes' + message: 'Please add the label "release notes: yes"' + - must_include: + regex: '^lang\/' + message: 'Please add a language ("lang/*") label' - must_include: - regex: 'release notes: yes' - message: 'Please add the label "release notes: yes"' - - must_include: - regex: '^lang\/' - message: 'Please add a language ("lang/*") label' - - must_include: - regex: 'release notes: no' - message: 'Please add the label "release notes: no"' + regex: 'release notes: no' + message: 'Please add the label "release notes: no"' \ No newline at end of file diff --git a/.gitignore b/.gitignore index cde82bc3d36..bc324b5f826 100644 --- a/.gitignore +++ b/.gitignore @@ -109,12 +109,14 @@ Podfile.lock # IDE specific folder for JetBrains IDEs .idea/ -# Blaze files +# Bazel files bazel-bin bazel-genfiles bazel-grpc bazel-out bazel-testlogs +bazel_format_virtual_environment/ +tools/bazel-* # Debug output gdb.txt @@ -134,3 +136,11 @@ bm_*.json # cmake build files /cmake/build + +# Visual Studio Code artifacts +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json + diff --git a/.gitmodules b/.gitmodules index bb4b749beee..f4690a2687f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -50,4 +50,7 @@ url = https://github.com/googleapis/googleapis.git [submodule "third_party/protoc-gen-validate"] path = third_party/protoc-gen-validate - url = https://github.com/lyft/protoc-gen-validate.git + url = https://github.com/envoyproxy/protoc-gen-validate.git +[submodule "third_party/upb"] + path = third_party/upb + url = https://github.com/google/upb.git diff --git a/.pylintrc b/.pylintrc index 90e8989ffcc..fcc8e73cb41 100644 --- a/.pylintrc +++ b/.pylintrc @@ -1,3 +1,13 @@ +[MASTER] +ignore= + src/python/grpcio/grpc/beta, + src/python/grpcio/grpc/framework, + src/python/grpcio/grpc/framework/common, + src/python/grpcio/grpc/framework/foundation, + src/python/grpcio/grpc/framework/interfaces, + +extension-pkg-whitelist=grpc._cython.cygrpc + [VARIABLES] # TODO(https://github.com/PyCQA/pylint/issues/1345): How does the inspection @@ -9,7 +19,7 @@ dummy-variables-rgx=^ignored_|^unused_ # 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 +max-args=7 [MISCELLANEOUS] @@ -82,3 +92,5 @@ disable= # if:/else: and for:/else:. useless-else-on-loop, no-else-return, + # NOTE(lidiz): Python 3 make object inheritance default, but not PY2 + useless-object-inheritance, diff --git a/.pylintrc-examples b/.pylintrc-examples new file mode 100644 index 00000000000..9480d6ea56a --- /dev/null +++ b/.pylintrc-examples @@ -0,0 +1,100 @@ +[MASTER] +ignore= + src/python/grpcio/grpc/beta, + src/python/grpcio/grpc/framework, + src/python/grpcio/grpc/framework/common, + src/python/grpcio/grpc/framework/foundation, + src/python/grpcio/grpc/framework/interfaces, + +[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(): " and +# "NOTE(): ". We do not allow "TODO:", +# "TODO():", "FIXME:", or anything else. +notes=FIXME,XXX + +[MESSAGES CONTROL] + +disable= + # -- START OF EXAMPLE-SPECIFIC SUPPRESSIONS -- + no-self-use, + unused-argument, + unused-variable, + # -- END OF EXAMPLE-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, + # TODO(https://github.com/grpc/grpc/issues/261): Disable unnecessary + # super-init requirement for abstract class implementations for now. + super-init-not-called, + # NOTE(nathaniel): A single statement that always returns program + # control is better than two statements the first of which sometimes + # returns program control and the second of which always returns + # program control. Probably generally, but definitely in the cases of + # if:/else: and for:/else:. + useless-else-on-loop, + no-else-return, + # NOTE(lidiz): Python 3 make object inheritance default, but not PY2 + useless-object-inheritance, diff --git a/.pylintrc-tests b/.pylintrc-tests index e68755c674e..d9cc4d107ef 100644 --- a/.pylintrc-tests +++ b/.pylintrc-tests @@ -1,3 +1,10 @@ +[MASTER] +ignore= + src/python/grpcio_tests/tests/unit/beta, + src/python/grpcio_tests/tests/unit/framework, + src/python/grpcio_tests/tests/unit/framework/common, + src/python/grpcio_tests/tests/unit/framework/foundation, + [VARIABLES] # TODO(https://github.com/PyCQA/pylint/issues/1345): How does the inspection @@ -115,3 +122,5 @@ disable= # if:/else: and for:/else:. useless-else-on-loop, no-else-return, + # NOTE(lidiz): Python 3 make object inheritance default, but not PY2 + useless-object-inheritance, diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 700c61cceae..00000000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "version": "0.2.0", - "configurations": [ - { - "type": "node", - "request": "launch", - "name": "Mocha Tests", - "cwd": "${workspaceRoot}", - "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/mocha", - "windows": { - "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/mocha.cmd" - }, - "runtimeArgs": [ - "-u", - "tdd", - "--timeout", - "999999", - "--colors", - "${workspaceRoot}/src/node/test" - ], - "internalConsoleOptions": "openOnSessionStart" - }, - { - "type": "node", - "request": "attach", - "name": "Attach to Process", - "port": 5858 - } - ] -} diff --git a/AUTHORS b/AUTHORS index 3e130afda2d..0e8797391f2 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,2 +1,3 @@ +Dropbox, Inc. Google Inc. WeWork Companies Inc. diff --git a/BUILD b/BUILD index 3627096f2d2..61a031ec022 100644 --- a/BUILD +++ b/BUILD @@ -63,12 +63,22 @@ config_setting( values = {"cpu": "x64_windows_msvc"}, ) +config_setting( + name = "python3", + values = {"python_path": "python3"}, +) + +config_setting( + name = "mac_x86_64", + values = {"cpu": "darwin"}, +) + # This should be updated along with build.yaml -g_stands_for = "gizmo" +g_stands_for = "gale" -core_version = "7.0.0-dev" +core_version = "7.0.0" -version = "1.17.0-dev" +version = "1.22.0-dev" GPR_PUBLIC_HDRS = [ "include/grpc/support/alloc.h", @@ -182,8 +192,8 @@ GRPCXX_PUBLIC_HDRS = [ "include/grpc++/impl/service_type.h", "include/grpc++/impl/sync_cxx11.h", "include/grpc++/impl/sync_no_cxx11.h", - "include/grpc++/resource_quota.h", "include/grpc++/security/auth_context.h", + "include/grpc++/resource_quota.h", "include/grpc++/security/auth_metadata_processor.h", "include/grpc++/security/credentials.h", "include/grpc++/security/server_credentials.h", @@ -204,16 +214,22 @@ GRPCXX_PUBLIC_HDRS = [ "include/grpc++/support/sync_stream.h", "include/grpc++/support/time.h", "include/grpcpp/alarm.h", + "include/grpcpp/alarm_impl.h", "include/grpcpp/channel.h", + "include/grpcpp/channel_impl.h", "include/grpcpp/client_context.h", "include/grpcpp/completion_queue.h", "include/grpcpp/create_channel.h", + "include/grpcpp/create_channel_impl.h", "include/grpcpp/create_channel_posix.h", + "include/grpcpp/create_channel_posix_impl.h", "include/grpcpp/ext/health_check_service_server_builder_option.h", "include/grpcpp/generic/async_generic_service.h", "include/grpcpp/generic/generic_stub.h", + "include/grpcpp/generic/generic_stub_impl.h", "include/grpcpp/grpcpp.h", "include/grpcpp/health_check_service_interface.h", + "include/grpcpp/health_check_service_interface_impl.h", "include/grpcpp/impl/call.h", "include/grpcpp/impl/channel_argument_option.h", "include/grpcpp/impl/client_unary_call.h", @@ -224,29 +240,43 @@ GRPCXX_PUBLIC_HDRS = [ "include/grpcpp/impl/rpc_service_method.h", "include/grpcpp/impl/serialization_traits.h", "include/grpcpp/impl/server_builder_option.h", + "include/grpcpp/impl/server_builder_option_impl.h", "include/grpcpp/impl/server_builder_plugin.h", "include/grpcpp/impl/server_initializer.h", + "include/grpcpp/impl/server_initializer_impl.h", "include/grpcpp/impl/service_type.h", "include/grpcpp/impl/sync_cxx11.h", "include/grpcpp/impl/sync_no_cxx11.h", "include/grpcpp/resource_quota.h", + "include/grpcpp/resource_quota_impl.h", "include/grpcpp/security/auth_context.h", "include/grpcpp/security/auth_metadata_processor.h", + "include/grpcpp/security/auth_metadata_processor_impl.h", "include/grpcpp/security/credentials.h", + "include/grpcpp/security/credentials_impl.h", "include/grpcpp/security/server_credentials.h", + "include/grpcpp/security/server_credentials_impl.h", "include/grpcpp/server.h", + "include/grpcpp/server_impl.h", "include/grpcpp/server_builder.h", + "include/grpcpp/server_builder_impl.h", "include/grpcpp/server_context.h", "include/grpcpp/server_posix.h", + "include/grpcpp/server_posix_impl.h", "include/grpcpp/support/async_stream.h", "include/grpcpp/support/async_unary_call.h", "include/grpcpp/support/byte_buffer.h", "include/grpcpp/support/channel_arguments.h", + "include/grpcpp/support/channel_arguments_impl.h", "include/grpcpp/support/client_callback.h", + "include/grpcpp/support/client_interceptor.h", "include/grpcpp/support/config.h", + "include/grpcpp/support/interceptor.h", + "include/grpcpp/support/message_allocator.h", "include/grpcpp/support/proto_buffer_reader.h", "include/grpcpp/support/proto_buffer_writer.h", "include/grpcpp/support/server_callback.h", + "include/grpcpp/support/server_interceptor.h", "include/grpcpp/support/slice.h", "include/grpcpp/support/status.h", "include/grpcpp/support/status_code_enum.h", @@ -379,6 +409,7 @@ grpc_cc_library( hdrs = [ "include/grpc++/support/error_details.h", "include/grpcpp/support/error_details.h", + "include/grpcpp/support/error_details_impl.h", ], language = "c++", standalone = True, @@ -403,6 +434,7 @@ grpc_cc_library( "src/compiler/config.h", "src/compiler/cpp_generator.h", "src/compiler/cpp_generator_helpers.h", + "src/compiler/cpp_plugin.h", "src/compiler/csharp_generator.h", "src/compiler/csharp_generator_helpers.h", "src/compiler/generator_helpers.h", @@ -499,11 +531,21 @@ grpc_cc_library( ], ) +grpc_cc_library( + name = "grpc++_internal_hdrs_only", + hdrs = [ + "include/grpcpp/impl/codegen/sync.h", + ], + language = "c++", + deps = [ + "gpr_codegen", + ], +) + grpc_cc_library( name = "gpr_base", srcs = [ "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", @@ -536,7 +578,9 @@ grpc_cc_library( "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/arena.cc", "src/core/lib/gprpp/fork.cc", + "src/core/lib/gprpp/global_config_env.cc", "src/core/lib/gprpp/thd_posix.cc", "src/core/lib/gprpp/thd_windows.cc", "src/core/lib/profiling/basic_timers.cc", @@ -560,10 +604,18 @@ grpc_cc_library( "src/core/lib/gpr/tmpfile.h", "src/core/lib/gpr/useful.h", "src/core/lib/gprpp/abstract.h", + "src/core/lib/gprpp/arena.h", + "src/core/lib/gprpp/atomic.h", "src/core/lib/gprpp/fork.h", + "src/core/lib/gprpp/global_config_custom.h", + "src/core/lib/gprpp/global_config_env.h", + "src/core/lib/gprpp/global_config_generic.h", + "src/core/lib/gprpp/global_config.h", "src/core/lib/gprpp/manual_constructor.h", + "src/core/lib/gprpp/map.h", "src/core/lib/gprpp/memory.h", - "src/core/lib/gprpp/mutex_lock.h", + "src/core/lib/gprpp/pair.h", + "src/core/lib/gprpp/sync.h", "src/core/lib/gprpp/thd.h", "src/core/lib/profiling/timers.h", ], @@ -609,10 +661,6 @@ grpc_cc_library( grpc_cc_library( name = "atomic", - hdrs = [ - "src/core/lib/gprpp/atomic_with_atm.h", - "src/core/lib/gprpp/atomic_with_std.h", - ], language = "c++", public_hdrs = [ "src/core/lib/gprpp/atomic.h", @@ -639,6 +687,17 @@ grpc_cc_library( public_hdrs = ["src/core/lib/gprpp/debug_location.h"], ) +grpc_cc_library( + name = "optional", + language = "c++", + public_hdrs = [ + "src/core/lib/gprpp/optional.h", + ], + deps = [ + "gpr_base", + ], +) + grpc_cc_library( name = "orphanable", language = "c++", @@ -647,6 +706,7 @@ grpc_cc_library( "debug_location", "gpr_base", "grpc_trace", + "ref_counted", "ref_counted_ptr", ], ) @@ -656,6 +716,7 @@ grpc_cc_library( language = "c++", public_hdrs = ["src/core/lib/gprpp/ref_counted.h"], deps = [ + "atomic", "debug_location", "gpr_base", "grpc_trace", @@ -685,10 +746,10 @@ grpc_cc_library( "src/core/lib/channel/channelz_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_args.cc", "src/core/lib/compression/compression_internal.cc", "src/core/lib/compression/message_compress.cc", "src/core/lib/compression/stream_compression.cc", @@ -701,12 +762,15 @@ grpc_cc_library( "src/core/lib/http/parser.cc", "src/core/lib/iomgr/buffer_list.cc", "src/core/lib/iomgr/call_combiner.cc", + "src/core/lib/iomgr/cfstream_handle.cc", "src/core/lib/iomgr/combiner.cc", "src/core/lib/iomgr/endpoint.cc", + "src/core/lib/iomgr/endpoint_cfstream.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/error_cfstream.cc", "src/core/lib/iomgr/ev_epoll1_linux.cc", "src/core/lib/iomgr/ev_epollex_linux.cc", "src/core/lib/iomgr/ev_poll_posix.cc", @@ -719,17 +783,19 @@ grpc_cc_library( "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/grpc_if_nametoindex_posix.cc", + "src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc", "src/core/lib/iomgr/internal_errqueue.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_posix_cfstream.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", @@ -752,6 +818,7 @@ grpc_cc_library( "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_cfstream.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", @@ -776,7 +843,6 @@ grpc_cc_library( "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", @@ -815,7 +881,6 @@ grpc_cc_library( "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", @@ -840,6 +905,7 @@ grpc_cc_library( "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_args.h", "src/core/lib/compression/compression_internal.h", "src/core/lib/compression/message_compress.h", "src/core/lib/compression/stream_compression.h", @@ -853,11 +919,15 @@ grpc_cc_library( "src/core/lib/iomgr/block_annotate.h", "src/core/lib/iomgr/buffer_list.h", "src/core/lib/iomgr/call_combiner.h", + "src/core/lib/iomgr/cfstream_handle.h", "src/core/lib/iomgr/closure.h", "src/core/lib/iomgr/combiner.h", + "src/core/lib/iomgr/dynamic_annotations.h", "src/core/lib/iomgr/endpoint.h", + "src/core/lib/iomgr/endpoint_cfstream.h", "src/core/lib/iomgr/endpoint_pair.h", "src/core/lib/iomgr/error.h", + "src/core/lib/iomgr/error_cfstream.h", "src/core/lib/iomgr/error_internal.h", "src/core/lib/iomgr/ev_epoll1_linux.h", "src/core/lib/iomgr/ev_epollex_linux.h", @@ -867,6 +937,7 @@ grpc_cc_library( "src/core/lib/iomgr/executor.h", "src/core/lib/iomgr/gethostname.h", "src/core/lib/iomgr/gevent_util.h", + "src/core/lib/iomgr/grpc_if_nametoindex.h", "src/core/lib/iomgr/internal_errqueue.h", "src/core/lib/iomgr/iocp_windows.h", "src/core/lib/iomgr/iomgr.h", @@ -877,7 +948,6 @@ grpc_cc_library( "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", @@ -916,7 +986,6 @@ grpc_cc_library( "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", @@ -928,6 +997,7 @@ grpc_cc_library( "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_utils.h", "src/core/lib/slice/slice_weak_hash_table.h", "src/core/lib/surface/api_trace.h", "src/core/lib/surface/call.h", @@ -950,7 +1020,6 @@ grpc_cc_library( "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", @@ -964,11 +1033,13 @@ grpc_cc_library( ], language = "c++", public_hdrs = GRPC_PUBLIC_HDRS, + use_cfstream = True, deps = [ "gpr_base", "grpc_codegen", "grpc_trace", "inlined_vector", + "optional", "orphanable", "ref_counted", "ref_counted_ptr", @@ -1012,26 +1083,6 @@ grpc_cc_library( ], ) -grpc_cc_library( - name = "grpc_cfstream", - srcs = [ - "src/core/lib/iomgr/cfstream_handle.cc", - "src/core/lib/iomgr/endpoint_cfstream.cc", - "src/core/lib/iomgr/error_cfstream.cc", - "src/core/lib/iomgr/iomgr_posix_cfstream.cc", - "src/core/lib/iomgr/tcp_client_cfstream.cc", - ], - hdrs = [ - "src/core/lib/iomgr/cfstream_handle.h", - "src/core/lib/iomgr/endpoint_cfstream.h", - "src/core/lib/iomgr/error_cfstream.h", - ], - deps = [ - ":gpr_base", - ":grpc_base", - ], -) - grpc_cc_library( name = "grpc_client_channel", srcs = [ @@ -1042,21 +1093,25 @@ grpc_cc_library( "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/global_subchannel_pool.cc", "src/core/ext/filters/client_channel/health/health_check_client.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/local_subchannel_pool.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/resolver_result_parsing.cc", + "src/core/ext/filters/client_channel/resolving_lb_policy.cc", "src/core/ext/filters/client_channel/retry_throttle.cc", + "src/core/ext/filters/client_channel/server_address.cc", + "src/core/ext/filters/client_channel/service_config.cc", "src/core/ext/filters/client_channel/subchannel.cc", - "src/core/ext/filters/client_channel/subchannel_index.cc", + "src/core/ext/filters/client_channel/subchannel_pool_interface.cc", ], hdrs = [ "src/core/ext/filters/client_channel/backup_poller.h", @@ -1064,12 +1119,14 @@ grpc_cc_library( "src/core/ext/filters/client_channel/client_channel_channelz.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/global_subchannel_pool.h", "src/core/ext/filters/client_channel/health/health_check_client.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/local_subchannel_pool.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", @@ -1077,9 +1134,12 @@ grpc_cc_library( "src/core/ext/filters/client_channel/resolver_factory.h", "src/core/ext/filters/client_channel/resolver_registry.h", "src/core/ext/filters/client_channel/resolver_result_parsing.h", + "src/core/ext/filters/client_channel/resolving_lb_policy.h", "src/core/ext/filters/client_channel/retry_throttle.h", + "src/core/ext/filters/client_channel/server_address.h", + "src/core/ext/filters/client_channel/service_config.h", "src/core/ext/filters/client_channel/subchannel.h", - "src/core/ext/filters/client_channel/subchannel_index.h", + "src/core/ext/filters/client_channel/subchannel_pool_interface.h", ], language = "c++", deps = [ @@ -1087,11 +1147,11 @@ grpc_cc_library( "grpc_base", "grpc_client_authority_filter", "grpc_deadline_filter", + "health_proto", "inlined_vector", "orphanable", "ref_counted", "ref_counted_ptr", - "health_proto", ], ) @@ -1148,6 +1208,7 @@ grpc_cc_library( language = "c++", deps = [ "grpc_base", + "grpc_client_channel", ], ) @@ -1441,6 +1502,7 @@ grpc_cc_library( language = "c++", public_hdrs = [ "include/grpcpp/ext/server_load_reporting.h", + "include/grpcpp/ext/server_load_reporting_impl.h", ], deps = [ "lb_server_load_reporting_filter", @@ -1517,16 +1579,20 @@ grpc_cc_library( srcs = [ "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.cc", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc", ], hdrs = [ "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h", ], external_deps = [ "cares", @@ -1583,14 +1649,17 @@ grpc_cc_library( "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/tls/grpc_tls_credentials_options.cc", + "src/core/lib/security/credentials/tls/spiffe_credentials.cc", "src/core/lib/security/security_connector/alts/alts_security_connector.cc", "src/core/lib/security/security_connector/fake/fake_security_connector.cc", "src/core/lib/security/security_connector/load_system_roots_fallback.cc", "src/core/lib/security/security_connector/load_system_roots_linux.cc", "src/core/lib/security/security_connector/local/local_security_connector.cc", "src/core/lib/security/security_connector/security_connector.cc", - "src/core/lib/security/security_connector/ssl_utils.cc", "src/core/lib/security/security_connector/ssl/ssl_security_connector.cc", + "src/core/lib/security/security_connector/ssl_utils.cc", + "src/core/lib/security/security_connector/tls/spiffe_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", @@ -1617,14 +1686,17 @@ grpc_cc_library( "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/tls/grpc_tls_credentials_options.h", + "src/core/lib/security/credentials/tls/spiffe_credentials.h", "src/core/lib/security/security_connector/alts/alts_security_connector.h", "src/core/lib/security/security_connector/fake/fake_security_connector.h", "src/core/lib/security/security_connector/load_system_roots.h", "src/core/lib/security/security_connector/load_system_roots_linux.h", "src/core/lib/security/security_connector/local/local_security_connector.h", "src/core/lib/security/security_connector/security_connector.h", - "src/core/lib/security/security_connector/ssl_utils.h", "src/core/lib/security/security_connector/ssl/ssl_security_connector.h", + "src/core/lib/security/security_connector/ssl_utils.h", + "src/core/lib/security/security_connector/tls/spiffe_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", @@ -1650,6 +1722,7 @@ grpc_cc_library( "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/context_list.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", @@ -1673,6 +1746,7 @@ grpc_cc_library( "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/context_list.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", @@ -2074,6 +2148,7 @@ grpc_cc_library( "include/grpcpp/impl/codegen/client_interceptor.h", "include/grpcpp/impl/codegen/client_unary_call.h", "include/grpcpp/impl/codegen/completion_queue.h", + "include/grpcpp/impl/codegen/completion_queue_impl.h", "include/grpcpp/impl/codegen/completion_queue_tag.h", "include/grpcpp/impl/codegen/config.h", "include/grpcpp/impl/codegen/core_codegen_interface.h", @@ -2082,6 +2157,7 @@ grpc_cc_library( "include/grpcpp/impl/codegen/intercepted_channel.h", "include/grpcpp/impl/codegen/interceptor.h", "include/grpcpp/impl/codegen/interceptor_common.h", + "include/grpcpp/impl/codegen/message_allocator.h", "include/grpcpp/impl/codegen/metadata_map.h", "include/grpcpp/impl/codegen/method_handler_impl.h", "include/grpcpp/impl/codegen/rpc_method.h", @@ -2102,6 +2178,7 @@ grpc_cc_library( "include/grpcpp/impl/codegen/time.h", ], deps = [ + "grpc++_internal_hdrs_only", "grpc_codegen", ], ) @@ -2157,6 +2234,7 @@ grpc_cc_library( public_hdrs = [ "include/grpc++/ext/proto_server_reflection_plugin.h", "include/grpcpp/ext/proto_server_reflection_plugin.h", + "include/grpcpp/ext/proto_server_reflection_plugin_impl.h", ], deps = [ ":grpc++", @@ -2177,6 +2255,7 @@ grpc_cc_library( language = "c++", public_hdrs = [ "include/grpcpp/ext/channelz_service_plugin.h", + "include/grpcpp/ext/channelz_service_plugin_impl.h", ], deps = [ ":grpc++", @@ -2241,6 +2320,7 @@ grpc_cc_library( ], hdrs = [ "include/grpcpp/opencensus.h", + "include/grpcpp/opencensus_impl.h", "src/cpp/ext/filters/census/channel_filter.h", "src/cpp/ext/filters/census/client_filter.h", "src/cpp/ext/filters/census/context.h", @@ -2269,4 +2349,174 @@ grpc_cc_library( ], ) +#TODO: Get this into build.yaml once we start using it. +grpc_cc_library( + name = "envoy_lrs_upb", + srcs = [ + "src/core/ext/upb-generated/envoy/api/v2/endpoint/load_report.upb.c", + "src/core/ext/upb-generated/envoy/service/load_stats/v2/lrs.upb.c", + ], + hdrs = [ + "src/core/ext/upb-generated/envoy/api/v2/endpoint/load_report.upb.h", + "src/core/ext/upb-generated/envoy/service/load_stats/v2/lrs.upb.h", + ], + language = "c++", + external_deps = [ + "upb_lib", + ], + deps = [ + ":envoy_core_upb", + ":google_api_upb", + ":proto_gen_validate_upb", + ], + tags = ["no_windows"], +) + +grpc_cc_library( + name = "envoy_ads_upb", + srcs = [ + "src/core/ext/upb-generated/envoy/api/v2/auth/cert.upb.c", + "src/core/ext/upb-generated/envoy/api/v2/cds.upb.c", + "src/core/ext/upb-generated/envoy/api/v2/cluster/circuit_breaker.upb.c", + "src/core/ext/upb-generated/envoy/api/v2/cluster/outlier_detection.upb.c", + "src/core/ext/upb-generated/envoy/api/v2/discovery.upb.c", + "src/core/ext/upb-generated/envoy/api/v2/eds.upb.c", + "src/core/ext/upb-generated/envoy/api/v2/endpoint/endpoint.upb.c", + "src/core/ext/upb-generated/envoy/service/discovery/v2/ads.upb.c", + ], + hdrs = [ + "src/core/ext/upb-generated/envoy/api/v2/auth/cert.upb.h", + "src/core/ext/upb-generated/envoy/api/v2/cds.upb.h", + "src/core/ext/upb-generated/envoy/api/v2/cluster/circuit_breaker.upb.h", + "src/core/ext/upb-generated/envoy/api/v2/cluster/outlier_detection.upb.h", + "src/core/ext/upb-generated/envoy/api/v2/discovery.upb.h", + "src/core/ext/upb-generated/envoy/api/v2/eds.upb.h", + "src/core/ext/upb-generated/envoy/api/v2/endpoint/endpoint.upb.h", + "src/core/ext/upb-generated/envoy/service/discovery/v2/ads.upb.h", + ], + external_deps = [ + "upb_lib", + ], + language = "c++", + deps = [ + ":envoy_core_upb", + ":envoy_type_upb", + ":google_api_upb", + ":proto_gen_validate_upb", + ], + tags = ["no_windows"], +) + +grpc_cc_library( + name = "envoy_core_upb", + srcs = [ + "src/core/ext/upb-generated/envoy/api/v2/core/address.upb.c", + "src/core/ext/upb-generated/envoy/api/v2/core/base.upb.c", + "src/core/ext/upb-generated/envoy/api/v2/core/config_source.upb.c", + "src/core/ext/upb-generated/envoy/api/v2/core/grpc_service.upb.c", + "src/core/ext/upb-generated/envoy/api/v2/core/health_check.upb.c", + "src/core/ext/upb-generated/envoy/api/v2/core/protocol.upb.c", + ], + hdrs = [ + "src/core/ext/upb-generated/envoy/api/v2/core/address.upb.h", + "src/core/ext/upb-generated/envoy/api/v2/core/base.upb.h", + "src/core/ext/upb-generated/envoy/api/v2/core/config_source.upb.h", + "src/core/ext/upb-generated/envoy/api/v2/core/grpc_service.upb.h", + "src/core/ext/upb-generated/envoy/api/v2/core/health_check.upb.h", + "src/core/ext/upb-generated/envoy/api/v2/core/protocol.upb.h", + ], + external_deps = [ + "upb_lib", + ], + language = "c++", + tags = ["no_windows"], + deps = [ + ":envoy_type_upb", + ":google_api_upb", + ":proto_gen_validate_upb", + ], +) + +grpc_cc_library( + name = "envoy_type_upb", + srcs = [ + "src/core/ext/upb-generated/envoy/type/percent.upb.c", + "src/core/ext/upb-generated/envoy/type/range.upb.c", + ], + hdrs = [ + "src/core/ext/upb-generated/envoy/type/percent.upb.h", + "src/core/ext/upb-generated/envoy/type/range.upb.h", + ], + external_deps = [ + "upb_lib", + ], + language = "c++", + tags = ["no_windows"], + deps = [ + ":google_api_upb", + ":proto_gen_validate_upb", + ], +) + +grpc_cc_library( + name = "proto_gen_validate_upb", + srcs = [ + "src/core/ext/upb-generated/gogoproto/gogo.upb.c", + "src/core/ext/upb-generated/validate/validate.upb.c", + ], + hdrs = [ + "src/core/ext/upb-generated/gogoproto/gogo.upb.h", + "src/core/ext/upb-generated/validate/validate.upb.h", + ], + external_deps = [ + "upb_lib", + ], + language = "c++", + tags = ["no_windows"], + deps = [ + ":google_api_upb", + ], +) + +grpc_cc_library( + name = "google_api_upb", + srcs = [ + "src/core/ext/upb-generated/google/api/annotations.upb.c", + "src/core/ext/upb-generated/google/api/http.upb.c", + "src/core/ext/upb-generated/google/protobuf/any.upb.c", + "src/core/ext/upb-generated/google/protobuf/descriptor.upb.c", + "src/core/ext/upb-generated/google/protobuf/duration.upb.c", + "src/core/ext/upb-generated/google/protobuf/empty.upb.c", + "src/core/ext/upb-generated/google/protobuf/struct.upb.c", + "src/core/ext/upb-generated/google/protobuf/timestamp.upb.c", + "src/core/ext/upb-generated/google/protobuf/wrappers.upb.c", + "src/core/ext/upb-generated/google/rpc/status.upb.c", + ], + hdrs = [ + "src/core/ext/upb-generated/google/api/annotations.upb.h", + "src/core/ext/upb-generated/google/api/http.upb.h", + "src/core/ext/upb-generated/google/protobuf/any.upb.h", + "src/core/ext/upb-generated/google/protobuf/descriptor.upb.h", + "src/core/ext/upb-generated/google/protobuf/duration.upb.h", + "src/core/ext/upb-generated/google/protobuf/empty.upb.h", + "src/core/ext/upb-generated/google/protobuf/struct.upb.h", + "src/core/ext/upb-generated/google/protobuf/timestamp.upb.h", + "src/core/ext/upb-generated/google/protobuf/wrappers.upb.h", + "src/core/ext/upb-generated/google/rpc/status.upb.h", + ], + external_deps = [ + "upb_lib", + ], + language = "c++", + tags = ["no_windows"], +) + grpc_generate_one_off_targets() + +filegroup( + name = "root_certificates", + srcs = [ + "etc/roots.pem", + ], + visibility = ["//visibility:public"], +) diff --git a/BUILD.gn b/BUILD.gn new file mode 100644 index 00000000000..a46e70e1565 --- /dev/null +++ b/BUILD.gn @@ -0,0 +1,1446 @@ +# GRPC Fuchsia GN build file + +# This file has been automatically generated from a template file. +# Please look at the templates directory instead. +# This file can be regenerated from the template by running +# tools/buildgen/generate_projects.sh + +# Copyright 2019 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. + +config("grpc_config") { + include_dirs = [ + ".", + "include/", + ] + defines = [ + "GRPC_USE_PROTO_LITE", + "GPR_SUPPORT_CHANNELS_FROM_FD", + "PB_FIELD_16BIT", + ] +} + + + + source_set("health_proto") { + sources = [ + "src/core/ext/filters/client_channel/health/health.pb.c", + "src/core/ext/filters/client_channel/health/health.pb.h", + ] + deps = [ + ":nanopb", + ] + + public_configs = [ + ":grpc_config", + ] + include_dirs = [ + "third_party/nanopb", + ] + } + + + + source_set("nanopb") { + sources = [ + "third_party/nanopb/pb.h", + "third_party/nanopb/pb_common.c", + "third_party/nanopb/pb_common.h", + "third_party/nanopb/pb_decode.c", + "third_party/nanopb/pb_decode.h", + "third_party/nanopb/pb_encode.c", + "third_party/nanopb/pb_encode.h", + ] + deps = [ + ] + + public_configs = [ + ":grpc_config", + ] + include_dirs = [ + "third_party/nanopb", + ] + } + + + + source_set("address_sorting") { + sources = [ + "third_party/address_sorting/address_sorting.c", + "third_party/address_sorting/address_sorting_internal.h", + "third_party/address_sorting/address_sorting_posix.c", + "third_party/address_sorting/address_sorting_windows.c", + "third_party/address_sorting/include/address_sorting/address_sorting.h", + ] + deps = [ + ] + + public_configs = [ + ":grpc_config", + ] + include_dirs = [ + "third_party/address_sorting/include", + ] + } + + + + source_set("gpr") { + sources = [ + "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/log.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/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", + "src/core/lib/gpr/alloc.cc", + "src/core/lib/gpr/alloc.h", + "src/core/lib/gpr/arena.h", + "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.h", + "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/host_port.cc", + "src/core/lib/gpr/host_port.h", + "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/mpscq.h", + "src/core/lib/gpr/murmur_hash.cc", + "src/core/lib/gpr/murmur_hash.h", + "src/core/lib/gpr/spinlock.h", + "src/core/lib/gpr/string.cc", + "src/core/lib/gpr/string.h", + "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/string_windows.h", + "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_precise.h", + "src/core/lib/gpr/time_windows.cc", + "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.cc", + "src/core/lib/gpr/tls_pthread.h", + "src/core/lib/gpr/tmpfile.h", + "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/useful.h", + "src/core/lib/gpr/wrap_memcpy.cc", + "src/core/lib/gprpp/abstract.h", + "src/core/lib/gprpp/arena.cc", + "src/core/lib/gprpp/arena.h", + "src/core/lib/gprpp/atomic.h", + "src/core/lib/gprpp/fork.cc", + "src/core/lib/gprpp/fork.h", + "src/core/lib/gprpp/global_config.h", + "src/core/lib/gprpp/global_config_custom.h", + "src/core/lib/gprpp/global_config_env.cc", + "src/core/lib/gprpp/global_config_env.h", + "src/core/lib/gprpp/global_config_generic.h", + "src/core/lib/gprpp/manual_constructor.h", + "src/core/lib/gprpp/map.h", + "src/core/lib/gprpp/memory.h", + "src/core/lib/gprpp/pair.h", + "src/core/lib/gprpp/sync.h", + "src/core/lib/gprpp/thd.h", + "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/profiling/timers.h", + ] + deps = [ + ] + + public_configs = [ + ":grpc_config", + ] + } + + + + source_set("grpc") { + sources = [ + "include/grpc/byte_buffer.h", + "include/grpc/byte_buffer_reader.h", + "include/grpc/census.h", + "include/grpc/compression.h", + "include/grpc/fork.h", + "include/grpc/grpc.h", + "include/grpc/grpc_posix.h", + "include/grpc/grpc_security.h", + "include/grpc/grpc_security_constants.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/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/fork.h", + "include/grpc/impl/codegen/gpr_slice.h", + "include/grpc/impl/codegen/gpr_types.h", + "include/grpc/impl/codegen/grpc_types.h", + "include/grpc/impl/codegen/log.h", + "include/grpc/impl/codegen/port_platform.h", + "include/grpc/impl/codegen/propagation_bits.h", + "include/grpc/impl/codegen/slice.h", + "include/grpc/impl/codegen/status.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/load_reporting.h", + "include/grpc/slice.h", + "include/grpc/slice_buffer.h", + "include/grpc/status.h", + "include/grpc/support/workaround_list.h", + "src/core/ext/filters/census/grpc_context.cc", + "src/core/ext/filters/client_channel/backup_poller.cc", + "src/core/ext/filters/client_channel/backup_poller.h", + "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.h", + "src/core/ext/filters/client_channel/client_channel_channelz.cc", + "src/core/ext/filters/client_channel/client_channel_channelz.h", + "src/core/ext/filters/client_channel/client_channel_factory.cc", + "src/core/ext/filters/client_channel/client_channel_factory.h", + "src/core/ext/filters/client_channel/client_channel_plugin.cc", + "src/core/ext/filters/client_channel/connector.cc", + "src/core/ext/filters/client_channel/connector.h", + "src/core/ext/filters/client_channel/global_subchannel_pool.cc", + "src/core/ext/filters/client_channel/global_subchannel_pool.h", + "src/core/ext/filters/client_channel/health/health_check_client.cc", + "src/core/ext/filters/client_channel/health/health_check_client.h", + "src/core/ext/filters/client_channel/http_connect_handshaker.cc", + "src/core/ext/filters/client_channel/http_connect_handshaker.h", + "src/core/ext/filters/client_channel/http_proxy.cc", + "src/core/ext/filters/client_channel/http_proxy.h", + "src/core/ext/filters/client_channel/lb_policy.cc", + "src/core/ext/filters/client_channel/lb_policy.h", + "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", + "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.cc", + "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h", + "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c", + "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h", + "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c", + "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h", + "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c", + "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.h", + "src/core/ext/filters/client_channel/lb_policy/xds/xds.cc", + "src/core/ext/filters/client_channel/lb_policy/xds/xds.h", + "src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h", + "src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_secure.cc", + "src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.cc", + "src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.h", + "src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.cc", + "src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h", + "src/core/ext/filters/client_channel/lb_policy_factory.h", + "src/core/ext/filters/client_channel/lb_policy_registry.cc", + "src/core/ext/filters/client_channel/lb_policy_registry.h", + "src/core/ext/filters/client_channel/local_subchannel_pool.cc", + "src/core/ext/filters/client_channel/local_subchannel_pool.h", + "src/core/ext/filters/client_channel/parse_address.cc", + "src/core/ext/filters/client_channel/parse_address.h", + "src/core/ext/filters/client_channel/proxy_mapper.cc", + "src/core/ext/filters/client_channel/proxy_mapper.h", + "src/core/ext/filters/client_channel/proxy_mapper_registry.cc", + "src/core/ext/filters/client_channel/proxy_mapper_registry.h", + "src/core/ext/filters/client_channel/resolver.cc", + "src/core/ext/filters/client_channel/resolver.h", + "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.cc", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc", + "src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc", + "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc", + "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h", + "src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc", + "src/core/ext/filters/client_channel/resolver_factory.h", + "src/core/ext/filters/client_channel/resolver_registry.cc", + "src/core/ext/filters/client_channel/resolver_registry.h", + "src/core/ext/filters/client_channel/resolver_result_parsing.cc", + "src/core/ext/filters/client_channel/resolver_result_parsing.h", + "src/core/ext/filters/client_channel/resolving_lb_policy.cc", + "src/core/ext/filters/client_channel/resolving_lb_policy.h", + "src/core/ext/filters/client_channel/retry_throttle.cc", + "src/core/ext/filters/client_channel/retry_throttle.h", + "src/core/ext/filters/client_channel/server_address.cc", + "src/core/ext/filters/client_channel/server_address.h", + "src/core/ext/filters/client_channel/service_config.cc", + "src/core/ext/filters/client_channel/service_config.h", + "src/core/ext/filters/client_channel/subchannel.cc", + "src/core/ext/filters/client_channel/subchannel.h", + "src/core/ext/filters/client_channel/subchannel_pool_interface.cc", + "src/core/ext/filters/client_channel/subchannel_pool_interface.h", + "src/core/ext/filters/deadline/deadline_filter.cc", + "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", + "src/core/ext/filters/http/server/http_server_filter.cc", + "src/core/ext/filters/http/server/http_server_filter.h", + "src/core/ext/filters/max_age/max_age_filter.cc", + "src/core/ext/filters/max_age/max_age_filter.h", + "src/core/ext/filters/message_size/message_size_filter.cc", + "src/core/ext/filters/message_size/message_size_filter.h", + "src/core/ext/filters/workarounds/workaround_cronet_compression_filter.cc", + "src/core/ext/filters/workarounds/workaround_cronet_compression_filter.h", + "src/core/ext/filters/workarounds/workaround_utils.cc", + "src/core/ext/filters/workarounds/workaround_utils.h", + "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/channel_create.cc", + "src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc", + "src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc", + "src/core/ext/transport/chttp2/server/chttp2_server.cc", + "src/core/ext/transport/chttp2/server/chttp2_server.h", + "src/core/ext/transport/chttp2/server/insecure/server_chttp2.cc", + "src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc", + "src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.cc", + "src/core/ext/transport/chttp2/transport/bin_decoder.cc", + "src/core/ext/transport/chttp2/transport/bin_decoder.h", + "src/core/ext/transport/chttp2/transport/bin_encoder.cc", + "src/core/ext/transport/chttp2/transport/bin_encoder.h", + "src/core/ext/transport/chttp2/transport/chttp2_plugin.cc", + "src/core/ext/transport/chttp2/transport/chttp2_transport.cc", + "src/core/ext/transport/chttp2/transport/chttp2_transport.h", + "src/core/ext/transport/chttp2/transport/context_list.cc", + "src/core/ext/transport/chttp2/transport/context_list.h", + "src/core/ext/transport/chttp2/transport/flow_control.cc", + "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.cc", + "src/core/ext/transport/chttp2/transport/frame_data.h", + "src/core/ext/transport/chttp2/transport/frame_goaway.cc", + "src/core/ext/transport/chttp2/transport/frame_goaway.h", + "src/core/ext/transport/chttp2/transport/frame_ping.cc", + "src/core/ext/transport/chttp2/transport/frame_ping.h", + "src/core/ext/transport/chttp2/transport/frame_rst_stream.cc", + "src/core/ext/transport/chttp2/transport/frame_rst_stream.h", + "src/core/ext/transport/chttp2/transport/frame_settings.cc", + "src/core/ext/transport/chttp2/transport/frame_settings.h", + "src/core/ext/transport/chttp2/transport/frame_window_update.cc", + "src/core/ext/transport/chttp2/transport/frame_window_update.h", + "src/core/ext/transport/chttp2/transport/hpack_encoder.cc", + "src/core/ext/transport/chttp2/transport/hpack_encoder.h", + "src/core/ext/transport/chttp2/transport/hpack_parser.cc", + "src/core/ext/transport/chttp2/transport/hpack_parser.h", + "src/core/ext/transport/chttp2/transport/hpack_table.cc", + "src/core/ext/transport/chttp2/transport/hpack_table.h", + "src/core/ext/transport/chttp2/transport/http2_settings.cc", + "src/core/ext/transport/chttp2/transport/http2_settings.h", + "src/core/ext/transport/chttp2/transport/huffsyms.cc", + "src/core/ext/transport/chttp2/transport/huffsyms.h", + "src/core/ext/transport/chttp2/transport/incoming_metadata.cc", + "src/core/ext/transport/chttp2/transport/incoming_metadata.h", + "src/core/ext/transport/chttp2/transport/internal.h", + "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/stream_map.h", + "src/core/ext/transport/chttp2/transport/varint.cc", + "src/core/ext/transport/chttp2/transport/varint.h", + "src/core/ext/transport/chttp2/transport/writing.cc", + "src/core/ext/transport/inproc/inproc_plugin.cc", + "src/core/ext/transport/inproc/inproc_transport.cc", + "src/core/ext/transport/inproc/inproc_transport.h", + "src/core/lib/avl/avl.cc", + "src/core/lib/avl/avl.h", + "src/core/lib/backoff/backoff.cc", + "src/core/lib/backoff/backoff.h", + "src/core/lib/channel/channel_args.cc", + "src/core/lib/channel/channel_args.h", + "src/core/lib/channel/channel_stack.cc", + "src/core/lib/channel/channel_stack.h", + "src/core/lib/channel/channel_stack_builder.cc", + "src/core/lib/channel/channel_stack_builder.h", + "src/core/lib/channel/channel_trace.cc", + "src/core/lib/channel/channel_trace.h", + "src/core/lib/channel/channelz.cc", + "src/core/lib/channel/channelz.h", + "src/core/lib/channel/channelz_registry.cc", + "src/core/lib/channel/channelz_registry.h", + "src/core/lib/channel/connected_channel.cc", + "src/core/lib/channel/connected_channel.h", + "src/core/lib/channel/context.h", + "src/core/lib/channel/handshaker.cc", + "src/core/lib/channel/handshaker.h", + "src/core/lib/channel/handshaker_factory.h", + "src/core/lib/channel/handshaker_registry.cc", + "src/core/lib/channel/handshaker_registry.h", + "src/core/lib/channel/status_util.cc", + "src/core/lib/channel/status_util.h", + "src/core/lib/compression/algorithm_metadata.h", + "src/core/lib/compression/compression.cc", + "src/core/lib/compression/compression_args.cc", + "src/core/lib/compression/compression_args.h", + "src/core/lib/compression/compression_internal.cc", + "src/core/lib/compression/compression_internal.h", + "src/core/lib/compression/message_compress.cc", + "src/core/lib/compression/message_compress.h", + "src/core/lib/compression/stream_compression.cc", + "src/core/lib/compression/stream_compression.h", + "src/core/lib/compression/stream_compression_gzip.cc", + "src/core/lib/compression/stream_compression_gzip.h", + "src/core/lib/compression/stream_compression_identity.cc", + "src/core/lib/compression/stream_compression_identity.h", + "src/core/lib/debug/stats.cc", + "src/core/lib/debug/stats.h", + "src/core/lib/debug/stats_data.cc", + "src/core/lib/debug/stats_data.h", + "src/core/lib/debug/trace.cc", + "src/core/lib/debug/trace.h", + "src/core/lib/gprpp/debug_location.h", + "src/core/lib/gprpp/inlined_vector.h", + "src/core/lib/gprpp/optional.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.cc", + "src/core/lib/http/format_request.h", + "src/core/lib/http/httpcli.cc", + "src/core/lib/http/httpcli.h", + "src/core/lib/http/httpcli_security_connector.cc", + "src/core/lib/http/parser.cc", + "src/core/lib/http/parser.h", + "src/core/lib/iomgr/block_annotate.h", + "src/core/lib/iomgr/buffer_list.cc", + "src/core/lib/iomgr/buffer_list.h", + "src/core/lib/iomgr/call_combiner.cc", + "src/core/lib/iomgr/call_combiner.h", + "src/core/lib/iomgr/cfstream_handle.cc", + "src/core/lib/iomgr/cfstream_handle.h", + "src/core/lib/iomgr/closure.h", + "src/core/lib/iomgr/combiner.cc", + "src/core/lib/iomgr/combiner.h", + "src/core/lib/iomgr/dynamic_annotations.h", + "src/core/lib/iomgr/endpoint.cc", + "src/core/lib/iomgr/endpoint.h", + "src/core/lib/iomgr/endpoint_cfstream.cc", + "src/core/lib/iomgr/endpoint_cfstream.h", + "src/core/lib/iomgr/endpoint_pair.h", + "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/error.h", + "src/core/lib/iomgr/error_cfstream.cc", + "src/core/lib/iomgr/error_cfstream.h", + "src/core/lib/iomgr/error_internal.h", + "src/core/lib/iomgr/ev_epoll1_linux.cc", + "src/core/lib/iomgr/ev_epoll1_linux.h", + "src/core/lib/iomgr/ev_epollex_linux.cc", + "src/core/lib/iomgr/ev_epollex_linux.h", + "src/core/lib/iomgr/ev_poll_posix.cc", + "src/core/lib/iomgr/ev_poll_posix.h", + "src/core/lib/iomgr/ev_posix.cc", + "src/core/lib/iomgr/ev_posix.h", + "src/core/lib/iomgr/ev_windows.cc", + "src/core/lib/iomgr/exec_ctx.cc", + "src/core/lib/iomgr/exec_ctx.h", + "src/core/lib/iomgr/executor.cc", + "src/core/lib/iomgr/executor.h", + "src/core/lib/iomgr/fork_posix.cc", + "src/core/lib/iomgr/fork_windows.cc", + "src/core/lib/iomgr/gethostname.h", + "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/grpc_if_nametoindex.h", + "src/core/lib/iomgr/grpc_if_nametoindex_posix.cc", + "src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc", + "src/core/lib/iomgr/internal_errqueue.cc", + "src/core/lib/iomgr/internal_errqueue.h", + "src/core/lib/iomgr/iocp_windows.cc", + "src/core/lib/iomgr/iocp_windows.h", + "src/core/lib/iomgr/iomgr.cc", + "src/core/lib/iomgr/iomgr.h", + "src/core/lib/iomgr/iomgr_custom.cc", + "src/core/lib/iomgr/iomgr_custom.h", + "src/core/lib/iomgr/iomgr_internal.cc", + "src/core/lib/iomgr/iomgr_internal.h", + "src/core/lib/iomgr/iomgr_posix.cc", + "src/core/lib/iomgr/iomgr_posix.h", + "src/core/lib/iomgr/iomgr_posix_cfstream.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/is_epollexclusive_available.h", + "src/core/lib/iomgr/load_file.cc", + "src/core/lib/iomgr/load_file.h", + "src/core/lib/iomgr/lockfree_event.cc", + "src/core/lib/iomgr/lockfree_event.h", + "src/core/lib/iomgr/nameser.h", + "src/core/lib/iomgr/polling_entity.cc", + "src/core/lib/iomgr/polling_entity.h", + "src/core/lib/iomgr/pollset.cc", + "src/core/lib/iomgr/pollset.h", + "src/core/lib/iomgr/pollset_custom.cc", + "src/core/lib/iomgr/pollset_custom.h", + "src/core/lib/iomgr/pollset_set.cc", + "src/core/lib/iomgr/pollset_set.h", + "src/core/lib/iomgr/pollset_set_custom.cc", + "src/core/lib/iomgr/pollset_set_custom.h", + "src/core/lib/iomgr/pollset_set_windows.cc", + "src/core/lib/iomgr/pollset_set_windows.h", + "src/core/lib/iomgr/pollset_uv.cc", + "src/core/lib/iomgr/pollset_windows.cc", + "src/core/lib/iomgr/pollset_windows.h", + "src/core/lib/iomgr/port.h", + "src/core/lib/iomgr/resolve_address.cc", + "src/core/lib/iomgr/resolve_address.h", + "src/core/lib/iomgr/resolve_address_custom.cc", + "src/core/lib/iomgr/resolve_address_custom.h", + "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/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.cc", + "src/core/lib/iomgr/sockaddr_utils.h", + "src/core/lib/iomgr/sockaddr_windows.h", + "src/core/lib/iomgr/socket_factory_posix.cc", + "src/core/lib/iomgr/socket_factory_posix.h", + "src/core/lib/iomgr/socket_mutator.cc", + "src/core/lib/iomgr/socket_mutator.h", + "src/core/lib/iomgr/socket_utils.h", + "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_posix.h", + "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/socket_windows.h", + "src/core/lib/iomgr/sys_epoll_wrapper.h", + "src/core/lib/iomgr/tcp_client.cc", + "src/core/lib/iomgr/tcp_client.h", + "src/core/lib/iomgr/tcp_client_cfstream.cc", + "src/core/lib/iomgr/tcp_client_custom.cc", + "src/core/lib/iomgr/tcp_client_posix.cc", + "src/core/lib/iomgr/tcp_client_posix.h", + "src/core/lib/iomgr/tcp_client_windows.cc", + "src/core/lib/iomgr/tcp_custom.cc", + "src/core/lib/iomgr/tcp_custom.h", + "src/core/lib/iomgr/tcp_posix.cc", + "src/core/lib/iomgr/tcp_posix.h", + "src/core/lib/iomgr/tcp_server.cc", + "src/core/lib/iomgr/tcp_server.h", + "src/core/lib/iomgr/tcp_server_custom.cc", + "src/core/lib/iomgr/tcp_server_posix.cc", + "src/core/lib/iomgr/tcp_server_utils_posix.h", + "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/tcp_windows.h", + "src/core/lib/iomgr/time_averaged_stats.cc", + "src/core/lib/iomgr/time_averaged_stats.h", + "src/core/lib/iomgr/timer.cc", + "src/core/lib/iomgr/timer.h", + "src/core/lib/iomgr/timer_custom.cc", + "src/core/lib/iomgr/timer_custom.h", + "src/core/lib/iomgr/timer_generic.cc", + "src/core/lib/iomgr/timer_heap.cc", + "src/core/lib/iomgr/timer_heap.h", + "src/core/lib/iomgr/timer_manager.cc", + "src/core/lib/iomgr/timer_manager.h", + "src/core/lib/iomgr/timer_uv.cc", + "src/core/lib/iomgr/udp_server.cc", + "src/core/lib/iomgr/udp_server.h", + "src/core/lib/iomgr/unix_sockets_posix.cc", + "src/core/lib/iomgr/unix_sockets_posix.h", + "src/core/lib/iomgr/unix_sockets_posix_noop.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_pipe.h", + "src/core/lib/iomgr/wakeup_fd_posix.cc", + "src/core/lib/iomgr/wakeup_fd_posix.h", + "src/core/lib/json/json.cc", + "src/core/lib/json/json.h", + "src/core/lib/json/json_common.h", + "src/core/lib/json/json_reader.cc", + "src/core/lib/json/json_reader.h", + "src/core/lib/json/json_string.cc", + "src/core/lib/json/json_writer.cc", + "src/core/lib/json/json_writer.h", + "src/core/lib/security/context/security_context.cc", + "src/core/lib/security/context/security_context.h", + "src/core/lib/security/credentials/alts/alts_credentials.cc", + "src/core/lib/security/credentials/alts/alts_credentials.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", + "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_options.h", + "src/core/lib/security/credentials/alts/grpc_alts_credentials_server_options.cc", + "src/core/lib/security/credentials/composite/composite_credentials.cc", + "src/core/lib/security/credentials/composite/composite_credentials.h", + "src/core/lib/security/credentials/credentials.cc", + "src/core/lib/security/credentials/credentials.h", + "src/core/lib/security/credentials/credentials_metadata.cc", + "src/core/lib/security/credentials/fake/fake_credentials.cc", + "src/core/lib/security/credentials/fake/fake_credentials.h", + "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/google_default/google_default_credentials.h", + "src/core/lib/security/credentials/iam/iam_credentials.cc", + "src/core/lib/security/credentials/iam/iam_credentials.h", + "src/core/lib/security/credentials/jwt/json_token.cc", + "src/core/lib/security/credentials/jwt/json_token.h", + "src/core/lib/security/credentials/jwt/jwt_credentials.cc", + "src/core/lib/security/credentials/jwt/jwt_credentials.h", + "src/core/lib/security/credentials/jwt/jwt_verifier.cc", + "src/core/lib/security/credentials/jwt/jwt_verifier.h", + "src/core/lib/security/credentials/local/local_credentials.cc", + "src/core/lib/security/credentials/local/local_credentials.h", + "src/core/lib/security/credentials/oauth2/oauth2_credentials.cc", + "src/core/lib/security/credentials/oauth2/oauth2_credentials.h", + "src/core/lib/security/credentials/plugin/plugin_credentials.cc", + "src/core/lib/security/credentials/plugin/plugin_credentials.h", + "src/core/lib/security/credentials/ssl/ssl_credentials.cc", + "src/core/lib/security/credentials/ssl/ssl_credentials.h", + "src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc", + "src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h", + "src/core/lib/security/credentials/tls/spiffe_credentials.cc", + "src/core/lib/security/credentials/tls/spiffe_credentials.h", + "src/core/lib/security/security_connector/alts/alts_security_connector.cc", + "src/core/lib/security/security_connector/alts/alts_security_connector.h", + "src/core/lib/security/security_connector/fake/fake_security_connector.cc", + "src/core/lib/security/security_connector/fake/fake_security_connector.h", + "src/core/lib/security/security_connector/load_system_roots.h", + "src/core/lib/security/security_connector/load_system_roots_fallback.cc", + "src/core/lib/security/security_connector/load_system_roots_linux.cc", + "src/core/lib/security/security_connector/load_system_roots_linux.h", + "src/core/lib/security/security_connector/local/local_security_connector.cc", + "src/core/lib/security/security_connector/local/local_security_connector.h", + "src/core/lib/security/security_connector/security_connector.cc", + "src/core/lib/security/security_connector/security_connector.h", + "src/core/lib/security/security_connector/ssl/ssl_security_connector.cc", + "src/core/lib/security/security_connector/ssl/ssl_security_connector.h", + "src/core/lib/security/security_connector/ssl_utils.cc", + "src/core/lib/security/security_connector/ssl_utils.h", + "src/core/lib/security/security_connector/tls/spiffe_security_connector.cc", + "src/core/lib/security/security_connector/tls/spiffe_security_connector.h", + "src/core/lib/security/transport/auth_filters.h", + "src/core/lib/security/transport/client_auth_filter.cc", + "src/core/lib/security/transport/secure_endpoint.cc", + "src/core/lib/security/transport/secure_endpoint.h", + "src/core/lib/security/transport/security_handshaker.cc", + "src/core/lib/security/transport/security_handshaker.h", + "src/core/lib/security/transport/server_auth_filter.cc", + "src/core/lib/security/transport/target_authority_table.cc", + "src/core/lib/security/transport/target_authority_table.h", + "src/core/lib/security/transport/tsi_error.cc", + "src/core/lib/security/transport/tsi_error.h", + "src/core/lib/security/util/json_util.cc", + "src/core/lib/security/util/json_util.h", + "src/core/lib/slice/b64.cc", + "src/core/lib/slice/b64.h", + "src/core/lib/slice/percent_encoding.cc", + "src/core/lib/slice/percent_encoding.h", + "src/core/lib/slice/slice.cc", + "src/core/lib/slice/slice_buffer.cc", + "src/core/lib/slice/slice_hash_table.h", + "src/core/lib/slice/slice_intern.cc", + "src/core/lib/slice/slice_internal.h", + "src/core/lib/slice/slice_string_helpers.cc", + "src/core/lib/slice/slice_string_helpers.h", + "src/core/lib/slice/slice_utils.h", + "src/core/lib/slice/slice_weak_hash_table.h", + "src/core/lib/surface/api_trace.cc", + "src/core/lib/surface/api_trace.h", + "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.h", + "src/core/lib/surface/call_details.cc", + "src/core/lib/surface/call_log_batch.cc", + "src/core/lib/surface/call_test_only.h", + "src/core/lib/surface/channel.cc", + "src/core/lib/surface/channel.h", + "src/core/lib/surface/channel_init.cc", + "src/core/lib/surface/channel_init.h", + "src/core/lib/surface/channel_ping.cc", + "src/core/lib/surface/channel_stack_type.cc", + "src/core/lib/surface/channel_stack_type.h", + "src/core/lib/surface/completion_queue.cc", + "src/core/lib/surface/completion_queue.h", + "src/core/lib/surface/completion_queue_factory.cc", + "src/core/lib/surface/completion_queue_factory.h", + "src/core/lib/surface/event_string.cc", + "src/core/lib/surface/event_string.h", + "src/core/lib/surface/init.cc", + "src/core/lib/surface/init.h", + "src/core/lib/surface/init_secure.cc", + "src/core/lib/surface/lame_client.cc", + "src/core/lib/surface/lame_client.h", + "src/core/lib/surface/metadata_array.cc", + "src/core/lib/surface/server.cc", + "src/core/lib/surface/server.h", + "src/core/lib/surface/validate_metadata.cc", + "src/core/lib/surface/validate_metadata.h", + "src/core/lib/surface/version.cc", + "src/core/lib/transport/bdp_estimator.cc", + "src/core/lib/transport/bdp_estimator.h", + "src/core/lib/transport/byte_stream.cc", + "src/core/lib/transport/byte_stream.h", + "src/core/lib/transport/connectivity_state.cc", + "src/core/lib/transport/connectivity_state.h", + "src/core/lib/transport/error_utils.cc", + "src/core/lib/transport/error_utils.h", + "src/core/lib/transport/http2_errors.h", + "src/core/lib/transport/metadata.cc", + "src/core/lib/transport/metadata.h", + "src/core/lib/transport/metadata_batch.cc", + "src/core/lib/transport/metadata_batch.h", + "src/core/lib/transport/pid_controller.cc", + "src/core/lib/transport/pid_controller.h", + "src/core/lib/transport/static_metadata.cc", + "src/core/lib/transport/static_metadata.h", + "src/core/lib/transport/status_conversion.cc", + "src/core/lib/transport/status_conversion.h", + "src/core/lib/transport/status_metadata.cc", + "src/core/lib/transport/status_metadata.h", + "src/core/lib/transport/timeout_encoding.cc", + "src/core/lib/transport/timeout_encoding.h", + "src/core/lib/transport/transport.cc", + "src/core/lib/transport/transport.h", + "src/core/lib/transport/transport_impl.h", + "src/core/lib/transport/transport_op_string.cc", + "src/core/lib/uri/uri_parser.cc", + "src/core/lib/uri/uri_parser.h", + "src/core/plugin_registry/grpc_plugin_registry.cc", + "src/core/tsi/alts/crypt/aes_gcm.cc", + "src/core/tsi/alts/crypt/gsec.cc", + "src/core/tsi/alts/crypt/gsec.h", + "src/core/tsi/alts/frame_protector/alts_counter.cc", + "src/core/tsi/alts/frame_protector/alts_counter.h", + "src/core/tsi/alts/frame_protector/alts_crypter.cc", + "src/core/tsi/alts/frame_protector/alts_crypter.h", + "src/core/tsi/alts/frame_protector/alts_frame_protector.cc", + "src/core/tsi/alts/frame_protector/alts_frame_protector.h", + "src/core/tsi/alts/frame_protector/alts_record_protocol_crypter_common.cc", + "src/core/tsi/alts/frame_protector/alts_record_protocol_crypter_common.h", + "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/frame_protector/frame_handler.h", + "src/core/tsi/alts/handshaker/alts_handshaker_client.cc", + "src/core/tsi/alts/handshaker/alts_handshaker_client.h", + "src/core/tsi/alts/handshaker/alts_handshaker_service_api.cc", + "src/core/tsi/alts/handshaker/alts_handshaker_service_api.h", + "src/core/tsi/alts/handshaker/alts_handshaker_service_api_util.cc", + "src/core/tsi/alts/handshaker/alts_handshaker_service_api_util.h", + "src/core/tsi/alts/handshaker/alts_shared_resource.cc", + "src/core/tsi/alts/handshaker/alts_shared_resource.h", + "src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc", + "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.cc", + "src/core/tsi/alts/handshaker/alts_tsi_utils.h", + "src/core/tsi/alts/handshaker/altscontext.pb.c", + "src/core/tsi/alts/handshaker/altscontext.pb.h", + "src/core/tsi/alts/handshaker/handshaker.pb.c", + "src/core/tsi/alts/handshaker/handshaker.pb.h", + "src/core/tsi/alts/handshaker/transport_security_common.pb.c", + "src/core/tsi/alts/handshaker/transport_security_common.pb.h", + "src/core/tsi/alts/handshaker/transport_security_common_api.cc", + "src/core/tsi/alts/handshaker/transport_security_common_api.h", + "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_integrity_only_record_protocol.h", + "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_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.cc", + "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.cc", + "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.cc", + "src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.h", + "src/core/tsi/fake_transport_security.cc", + "src/core/tsi/fake_transport_security.h", + "src/core/tsi/grpc_shadow_boringssl.h", + "src/core/tsi/local_transport_security.cc", + "src/core/tsi/local_transport_security.h", + "src/core/tsi/ssl/session_cache/ssl_session.h", + "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_cache.h", + "src/core/tsi/ssl/session_cache/ssl_session_openssl.cc", + "src/core/tsi/ssl_transport_security.cc", + "src/core/tsi/ssl_transport_security.h", + "src/core/tsi/ssl_types.h", + "src/core/tsi/transport_security.cc", + "src/core/tsi/transport_security.h", + "src/core/tsi/transport_security_grpc.cc", + "src/core/tsi/transport_security_grpc.h", + "src/core/tsi/transport_security_interface.h", + ] + deps = [ + "//third_party/boringssl", + "//third_party/zlib", + ":gpr", + "//third_party/cares", + ":address_sorting", + ":nanopb", + ":health_proto", + ] + + public_configs = [ + ":grpc_config", + ] + include_dirs = [ + "third_party/cares", + "third_party/address_sorting/include", + "third_party/nanopb", + ] + } + + + + source_set("grpc++") { + sources = [ + "include/grpc++/alarm.h", + "include/grpc++/channel.h", + "include/grpc++/client_context.h", + "include/grpc++/completion_queue.h", + "include/grpc++/create_channel.h", + "include/grpc++/create_channel_posix.h", + "include/grpc++/ext/health_check_service_server_builder_option.h", + "include/grpc++/generic/async_generic_service.h", + "include/grpc++/generic/generic_stub.h", + "include/grpc++/grpc++.h", + "include/grpc++/health_check_service_interface.h", + "include/grpc++/impl/call.h", + "include/grpc++/impl/channel_argument_option.h", + "include/grpc++/impl/client_unary_call.h", + "include/grpc++/impl/codegen/async_stream.h", + "include/grpc++/impl/codegen/async_unary_call.h", + "include/grpc++/impl/codegen/byte_buffer.h", + "include/grpc++/impl/codegen/call.h", + "include/grpc++/impl/codegen/call_hook.h", + "include/grpc++/impl/codegen/channel_interface.h", + "include/grpc++/impl/codegen/client_context.h", + "include/grpc++/impl/codegen/client_unary_call.h", + "include/grpc++/impl/codegen/completion_queue.h", + "include/grpc++/impl/codegen/completion_queue_tag.h", + "include/grpc++/impl/codegen/config.h", + "include/grpc++/impl/codegen/config_protobuf.h", + "include/grpc++/impl/codegen/core_codegen.h", + "include/grpc++/impl/codegen/core_codegen.h", + "include/grpc++/impl/codegen/core_codegen_interface.h", + "include/grpc++/impl/codegen/create_auth_context.h", + "include/grpc++/impl/codegen/grpc_library.h", + "include/grpc++/impl/codegen/metadata_map.h", + "include/grpc++/impl/codegen/method_handler_impl.h", + "include/grpc++/impl/codegen/proto_utils.h", + "include/grpc++/impl/codegen/rpc_method.h", + "include/grpc++/impl/codegen/rpc_service_method.h", + "include/grpc++/impl/codegen/security/auth_context.h", + "include/grpc++/impl/codegen/serialization_traits.h", + "include/grpc++/impl/codegen/server_context.h", + "include/grpc++/impl/codegen/server_interface.h", + "include/grpc++/impl/codegen/service_type.h", + "include/grpc++/impl/codegen/slice.h", + "include/grpc++/impl/codegen/status.h", + "include/grpc++/impl/codegen/status_code_enum.h", + "include/grpc++/impl/codegen/string_ref.h", + "include/grpc++/impl/codegen/stub_options.h", + "include/grpc++/impl/codegen/sync_stream.h", + "include/grpc++/impl/codegen/time.h", + "include/grpc++/impl/grpc_library.h", + "include/grpc++/impl/method_handler_impl.h", + "include/grpc++/impl/rpc_method.h", + "include/grpc++/impl/rpc_service_method.h", + "include/grpc++/impl/serialization_traits.h", + "include/grpc++/impl/server_builder_option.h", + "include/grpc++/impl/server_builder_plugin.h", + "include/grpc++/impl/server_initializer.h", + "include/grpc++/impl/service_type.h", + "include/grpc++/resource_quota.h", + "include/grpc++/security/auth_context.h", + "include/grpc++/security/auth_metadata_processor.h", + "include/grpc++/security/credentials.h", + "include/grpc++/security/server_credentials.h", + "include/grpc++/server.h", + "include/grpc++/server_builder.h", + "include/grpc++/server_context.h", + "include/grpc++/server_posix.h", + "include/grpc++/support/async_stream.h", + "include/grpc++/support/async_unary_call.h", + "include/grpc++/support/byte_buffer.h", + "include/grpc++/support/channel_arguments.h", + "include/grpc++/support/config.h", + "include/grpc++/support/slice.h", + "include/grpc++/support/status.h", + "include/grpc++/support/status_code_enum.h", + "include/grpc++/support/string_ref.h", + "include/grpc++/support/stub_options.h", + "include/grpc++/support/sync_stream.h", + "include/grpc++/support/time.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/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/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/fork.h", + "include/grpc/impl/codegen/gpr_slice.h", + "include/grpc/impl/codegen/gpr_types.h", + "include/grpc/impl/codegen/grpc_types.h", + "include/grpc/impl/codegen/log.h", + "include/grpc/impl/codegen/port_platform.h", + "include/grpc/impl/codegen/propagation_bits.h", + "include/grpc/impl/codegen/slice.h", + "include/grpc/impl/codegen/status.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/load_reporting.h", + "include/grpc/slice.h", + "include/grpc/slice_buffer.h", + "include/grpc/status.h", + "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/support/workaround_list.h", + "include/grpcpp/alarm.h", + "include/grpcpp/alarm_impl.h", + "include/grpcpp/channel.h", + "include/grpcpp/channel_impl.h", + "include/grpcpp/client_context.h", + "include/grpcpp/completion_queue.h", + "include/grpcpp/create_channel.h", + "include/grpcpp/create_channel_impl.h", + "include/grpcpp/create_channel_posix.h", + "include/grpcpp/create_channel_posix_impl.h", + "include/grpcpp/ext/health_check_service_server_builder_option.h", + "include/grpcpp/generic/async_generic_service.h", + "include/grpcpp/generic/generic_stub.h", + "include/grpcpp/generic/generic_stub_impl.h", + "include/grpcpp/grpcpp.h", + "include/grpcpp/health_check_service_interface.h", + "include/grpcpp/health_check_service_interface_impl.h", + "include/grpcpp/impl/call.h", + "include/grpcpp/impl/channel_argument_option.h", + "include/grpcpp/impl/client_unary_call.h", + "include/grpcpp/impl/codegen/async_generic_service.h", + "include/grpcpp/impl/codegen/async_stream.h", + "include/grpcpp/impl/codegen/async_unary_call.h", + "include/grpcpp/impl/codegen/byte_buffer.h", + "include/grpcpp/impl/codegen/call.h", + "include/grpcpp/impl/codegen/call_hook.h", + "include/grpcpp/impl/codegen/call_op_set.h", + "include/grpcpp/impl/codegen/call_op_set_interface.h", + "include/grpcpp/impl/codegen/callback_common.h", + "include/grpcpp/impl/codegen/channel_interface.h", + "include/grpcpp/impl/codegen/client_callback.h", + "include/grpcpp/impl/codegen/client_context.h", + "include/grpcpp/impl/codegen/client_interceptor.h", + "include/grpcpp/impl/codegen/client_unary_call.h", + "include/grpcpp/impl/codegen/completion_queue.h", + "include/grpcpp/impl/codegen/completion_queue_impl.h", + "include/grpcpp/impl/codegen/completion_queue_tag.h", + "include/grpcpp/impl/codegen/config.h", + "include/grpcpp/impl/codegen/config_protobuf.h", + "include/grpcpp/impl/codegen/core_codegen.h", + "include/grpcpp/impl/codegen/core_codegen.h", + "include/grpcpp/impl/codegen/core_codegen_interface.h", + "include/grpcpp/impl/codegen/create_auth_context.h", + "include/grpcpp/impl/codegen/grpc_library.h", + "include/grpcpp/impl/codegen/intercepted_channel.h", + "include/grpcpp/impl/codegen/interceptor.h", + "include/grpcpp/impl/codegen/interceptor_common.h", + "include/grpcpp/impl/codegen/message_allocator.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", + "include/grpcpp/impl/codegen/security/auth_context.h", + "include/grpcpp/impl/codegen/serialization_traits.h", + "include/grpcpp/impl/codegen/server_callback.h", + "include/grpcpp/impl/codegen/server_context.h", + "include/grpcpp/impl/codegen/server_interceptor.h", + "include/grpcpp/impl/codegen/server_interface.h", + "include/grpcpp/impl/codegen/service_type.h", + "include/grpcpp/impl/codegen/slice.h", + "include/grpcpp/impl/codegen/status.h", + "include/grpcpp/impl/codegen/status_code_enum.h", + "include/grpcpp/impl/codegen/string_ref.h", + "include/grpcpp/impl/codegen/stub_options.h", + "include/grpcpp/impl/codegen/sync.h", + "include/grpcpp/impl/codegen/sync_stream.h", + "include/grpcpp/impl/codegen/time.h", + "include/grpcpp/impl/grpc_library.h", + "include/grpcpp/impl/method_handler_impl.h", + "include/grpcpp/impl/rpc_method.h", + "include/grpcpp/impl/rpc_service_method.h", + "include/grpcpp/impl/serialization_traits.h", + "include/grpcpp/impl/server_builder_option.h", + "include/grpcpp/impl/server_builder_option_impl.h", + "include/grpcpp/impl/server_builder_plugin.h", + "include/grpcpp/impl/server_initializer.h", + "include/grpcpp/impl/server_initializer_impl.h", + "include/grpcpp/impl/service_type.h", + "include/grpcpp/resource_quota.h", + "include/grpcpp/resource_quota_impl.h", + "include/grpcpp/security/auth_context.h", + "include/grpcpp/security/auth_metadata_processor.h", + "include/grpcpp/security/auth_metadata_processor_impl.h", + "include/grpcpp/security/credentials.h", + "include/grpcpp/security/credentials_impl.h", + "include/grpcpp/security/server_credentials.h", + "include/grpcpp/security/server_credentials_impl.h", + "include/grpcpp/server.h", + "include/grpcpp/server_builder.h", + "include/grpcpp/server_builder_impl.h", + "include/grpcpp/server_context.h", + "include/grpcpp/server_impl.h", + "include/grpcpp/server_posix.h", + "include/grpcpp/server_posix_impl.h", + "include/grpcpp/support/async_stream.h", + "include/grpcpp/support/async_unary_call.h", + "include/grpcpp/support/byte_buffer.h", + "include/grpcpp/support/channel_arguments.h", + "include/grpcpp/support/channel_arguments_impl.h", + "include/grpcpp/support/client_callback.h", + "include/grpcpp/support/client_interceptor.h", + "include/grpcpp/support/config.h", + "include/grpcpp/support/interceptor.h", + "include/grpcpp/support/message_allocator.h", + "include/grpcpp/support/proto_buffer_reader.h", + "include/grpcpp/support/proto_buffer_writer.h", + "include/grpcpp/support/server_callback.h", + "include/grpcpp/support/server_interceptor.h", + "include/grpcpp/support/slice.h", + "include/grpcpp/support/status.h", + "include/grpcpp/support/status_code_enum.h", + "include/grpcpp/support/string_ref.h", + "include/grpcpp/support/stub_options.h", + "include/grpcpp/support/sync_stream.h", + "include/grpcpp/support/time.h", + "src/core/ext/transport/inproc/inproc_transport.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/channelz.h", + "src/core/lib/channel/channelz_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_args.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/debug/trace.h", + "src/core/lib/gpr/alloc.h", + "src/core/lib/gpr/arena.h", + "src/core/lib/gpr/env.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/arena.h", + "src/core/lib/gprpp/atomic.h", + "src/core/lib/gprpp/debug_location.h", + "src/core/lib/gprpp/fork.h", + "src/core/lib/gprpp/global_config.h", + "src/core/lib/gprpp/global_config_custom.h", + "src/core/lib/gprpp/global_config_env.h", + "src/core/lib/gprpp/global_config_generic.h", + "src/core/lib/gprpp/inlined_vector.h", + "src/core/lib/gprpp/manual_constructor.h", + "src/core/lib/gprpp/map.h", + "src/core/lib/gprpp/memory.h", + "src/core/lib/gprpp/optional.h", + "src/core/lib/gprpp/orphanable.h", + "src/core/lib/gprpp/pair.h", + "src/core/lib/gprpp/ref_counted.h", + "src/core/lib/gprpp/ref_counted_ptr.h", + "src/core/lib/gprpp/sync.h", + "src/core/lib/gprpp/thd.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/buffer_list.h", + "src/core/lib/iomgr/call_combiner.h", + "src/core/lib/iomgr/cfstream_handle.h", + "src/core/lib/iomgr/closure.h", + "src/core/lib/iomgr/combiner.h", + "src/core/lib/iomgr/dynamic_annotations.h", + "src/core/lib/iomgr/endpoint.h", + "src/core/lib/iomgr/endpoint_cfstream.h", + "src/core/lib/iomgr/endpoint_pair.h", + "src/core/lib/iomgr/error.h", + "src/core/lib/iomgr/error_cfstream.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_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/grpc_if_nametoindex.h", + "src/core/lib/iomgr/internal_errqueue.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/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_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/profiling/timers.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_utils.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/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/uri/uri_parser.h", + "src/cpp/client/channel_cc.cc", + "src/cpp/client/client_context.cc", + "src/cpp/client/client_interceptor.cc", + "src/cpp/client/create_channel.cc", + "src/cpp/client/create_channel_internal.cc", + "src/cpp/client/create_channel_internal.h", + "src/cpp/client/create_channel_posix.cc", + "src/cpp/client/credentials_cc.cc", + "src/cpp/client/generic_stub.cc", + "src/cpp/client/insecure_credentials.cc", + "src/cpp/client/secure_credentials.cc", + "src/cpp/client/secure_credentials.h", + "src/cpp/codegen/codegen_init.cc", + "src/cpp/common/alarm.cc", + "src/cpp/common/auth_property_iterator.cc", + "src/cpp/common/channel_arguments.cc", + "src/cpp/common/channel_filter.cc", + "src/cpp/common/channel_filter.h", + "src/cpp/common/completion_queue_cc.cc", + "src/cpp/common/core_codegen.cc", + "src/cpp/common/resource_quota_cc.cc", + "src/cpp/common/rpc_method.cc", + "src/cpp/common/secure_auth_context.cc", + "src/cpp/common/secure_auth_context.h", + "src/cpp/common/secure_channel_arguments.cc", + "src/cpp/common/secure_create_auth_context.cc", + "src/cpp/common/version_cc.cc", + "src/cpp/server/async_generic_service.cc", + "src/cpp/server/channel_argument_option.cc", + "src/cpp/server/create_default_thread_pool.cc", + "src/cpp/server/dynamic_thread_pool.cc", + "src/cpp/server/dynamic_thread_pool.h", + "src/cpp/server/health/default_health_check_service.cc", + "src/cpp/server/health/default_health_check_service.h", + "src/cpp/server/health/health_check_service.cc", + "src/cpp/server/health/health_check_service_server_builder_option.cc", + "src/cpp/server/insecure_server_credentials.cc", + "src/cpp/server/secure_server_credentials.cc", + "src/cpp/server/secure_server_credentials.h", + "src/cpp/server/server_builder.cc", + "src/cpp/server/server_cc.cc", + "src/cpp/server/server_context.cc", + "src/cpp/server/server_credentials.cc", + "src/cpp/server/server_posix.cc", + "src/cpp/server/thread_pool_interface.h", + "src/cpp/thread_manager/thread_manager.cc", + "src/cpp/thread_manager/thread_manager.h", + "src/cpp/util/byte_buffer_cc.cc", + "src/cpp/util/status.cc", + "src/cpp/util/string_ref.cc", + "src/cpp/util/time_cc.cc", + ] + deps = [ + "//third_party/boringssl", + "//third_party/protobuf:protobuf_lite", + ":grpc", + ":gpr", + ":nanopb", + ":health_proto", + ] + + public_configs = [ + ":grpc_config", + ] + include_dirs = [ + "third_party/nanopb", + ] + } + + # Only compile the plugin for the host architecture. + if (current_toolchain == host_toolchain) { + + + source_set("grpc_plugin_support") { + sources = [ + "include/grpc++/impl/codegen/config_protobuf.h", + "include/grpcpp/impl/codegen/config_protobuf.h", + "src/compiler/config.h", + "src/compiler/cpp_generator.cc", + "src/compiler/cpp_generator.h", + "src/compiler/cpp_generator_helpers.h", + "src/compiler/csharp_generator.cc", + "src/compiler/csharp_generator.h", + "src/compiler/csharp_generator_helpers.h", + "src/compiler/generator_helpers.h", + "src/compiler/node_generator.cc", + "src/compiler/node_generator.h", + "src/compiler/node_generator_helpers.h", + "src/compiler/objective_c_generator.cc", + "src/compiler/objective_c_generator.h", + "src/compiler/objective_c_generator_helpers.h", + "src/compiler/php_generator.cc", + "src/compiler/php_generator.h", + "src/compiler/php_generator_helpers.h", + "src/compiler/protobuf_plugin.h", + "src/compiler/python_generator.cc", + "src/compiler/python_generator.h", + "src/compiler/python_generator_helpers.h", + "src/compiler/python_private_generator.h", + "src/compiler/schema_interface.h", + ] + deps = [ + "//third_party/protobuf:protoc_lib", + ] + + public_configs = [ + ":grpc_config", + ] + } + + } + # Only compile the plugin for the host architecture. + if (current_toolchain == host_toolchain) { + + executable("grpc_cpp_plugin") { + sources = [ + "src/compiler/cpp_plugin.cc", + ] + deps = [ + "//third_party/protobuf:protoc_lib", + ":grpc_plugin_support", + ] + + configs += [ + "//third_party/protobuf:protobuf_config", + ] + public_configs = [ ":grpc_config" ] + } + + } + + diff --git a/CMakeLists.txt b/CMakeLists.txt index 5c2ba2048c0..37fbc14fc26 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.17.0-dev") +set(PACKAGE_VERSION "1.22.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/") @@ -94,7 +94,7 @@ endif() set(CMAKE_POSITION_INDEPENDENT_CODE TRUE) -add_definitions(-DPB_FIELD_16BIT) +add_definitions(-DPB_FIELD_32BIT) if (MSVC) include(cmake/msvc_static_runtime.cmake) @@ -190,6 +190,13 @@ function(protobuf_generate_grpc_cpp) get_filename_component(REL_DIR ${REL_FIL} DIRECTORY) set(RELFIL_WE "${REL_DIR}/${FIL_WE}") + #if cross-compiling, find host plugin + if(CMAKE_CROSSCOMPILING) + find_program(_gRPC_CPP_PLUGIN grpc_cpp_plugin) + else() + set(_gRPC_CPP_PLUGIN $) + endif() + add_custom_command( OUTPUT "${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.grpc.pb.cc" "${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.grpc.pb.h" @@ -199,7 +206,7 @@ function(protobuf_generate_grpc_cpp) COMMAND ${_gRPC_PROTOBUF_PROTOC_EXECUTABLE} ARGS --grpc_out=generate_mock_code=true:${_gRPC_PROTO_GENS_DIR} --cpp_out=${_gRPC_PROTO_GENS_DIR} - --plugin=protoc-gen-grpc=$ + --plugin=protoc-gen-grpc=${_gRPC_CPP_PLUGIN} ${_protobuf_include_path} ${REL_FIL} DEPENDS ${ABS_FIL} ${_gRPC_PROTOBUF_PROTOC} grpc_cpp_plugin @@ -257,6 +264,9 @@ add_dependencies(buildtests_c channel_create_test) add_dependencies(buildtests_c chttp2_hpack_encoder_test) add_dependencies(buildtests_c chttp2_stream_map_test) add_dependencies(buildtests_c chttp2_varint_test) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) +add_dependencies(buildtests_c close_fd_test) +endif() add_dependencies(buildtests_c cmdline_test) add_dependencies(buildtests_c combiner_test) add_dependencies(buildtests_c compression_test) @@ -371,11 +381,17 @@ add_dependencies(buildtests_c murmur_hash_test) add_dependencies(buildtests_c no_server_test) add_dependencies(buildtests_c num_external_connectivity_watchers_test) add_dependencies(buildtests_c parse_address_test) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) +add_dependencies(buildtests_c parse_address_with_named_scope_id_test) +endif() add_dependencies(buildtests_c percent_encoding_test) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) -add_dependencies(buildtests_c resolve_address_posix_test) +add_dependencies(buildtests_c resolve_address_using_ares_resolver_posix_test) endif() add_dependencies(buildtests_c resolve_address_using_ares_resolver_test) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) +add_dependencies(buildtests_c resolve_address_using_native_resolver_posix_test) +endif() add_dependencies(buildtests_c resolve_address_using_native_resolver_test) add_dependencies(buildtests_c resource_quota_test) add_dependencies(buildtests_c secure_channel_create_test) @@ -421,9 +437,6 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_dependencies(buildtests_c udp_server_test) endif() add_dependencies(buildtests_c uri_parser_test) -if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) -add_dependencies(buildtests_c wakeup_fd_cv_test) -endif() add_dependencies(buildtests_c public_headers_must_be_c89) add_dependencies(buildtests_c badreq_bad_client_test) add_dependencies(buildtests_c connection_prefix_bad_client_test) @@ -456,14 +469,22 @@ add_dependencies(buildtests_c h2_full+trace_test) add_dependencies(buildtests_c h2_full+workarounds_test) add_dependencies(buildtests_c h2_http_proxy_test) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) -add_dependencies(buildtests_c h2_local_test) +add_dependencies(buildtests_c h2_local_ipv4_test) +endif() +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) +add_dependencies(buildtests_c h2_local_ipv6_test) +endif() +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) +add_dependencies(buildtests_c h2_local_uds_test) endif() add_dependencies(buildtests_c h2_oauth2_test) add_dependencies(buildtests_c h2_proxy_test) add_dependencies(buildtests_c h2_sockpair_test) add_dependencies(buildtests_c h2_sockpair+trace_test) add_dependencies(buildtests_c h2_sockpair_1byte_test) +add_dependencies(buildtests_c h2_spiffe_test) add_dependencies(buildtests_c h2_ssl_test) +add_dependencies(buildtests_c h2_ssl_cred_reload_test) add_dependencies(buildtests_c h2_ssl_proxy_test) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_dependencies(buildtests_c h2_uds_test) @@ -523,12 +544,24 @@ add_dependencies(buildtests_cxx auth_property_iterator_test) add_dependencies(buildtests_cxx backoff_test) add_dependencies(buildtests_cxx bdp_estimator_test) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) +add_dependencies(buildtests_cxx bm_alarm) +endif() +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_dependencies(buildtests_cxx bm_arena) endif() if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) +add_dependencies(buildtests_cxx bm_byte_buffer) +endif() +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_dependencies(buildtests_cxx bm_call_create) endif() if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) +add_dependencies(buildtests_cxx bm_callback_streaming_ping_pong) +endif() +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) +add_dependencies(buildtests_cxx bm_callback_unary_ping_pong) +endif() +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_dependencies(buildtests_cxx bm_channel) endif() if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) @@ -567,6 +600,9 @@ endif() if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_dependencies(buildtests_cxx bm_pollset) endif() +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) +add_dependencies(buildtests_cxx bm_timer) +endif() add_dependencies(buildtests_cxx byte_stream_test) add_dependencies(buildtests_cxx channel_arguments_test) add_dependencies(buildtests_cxx channel_filter_test) @@ -588,6 +624,7 @@ add_dependencies(buildtests_cxx client_interceptors_end2end_test) add_dependencies(buildtests_cxx client_lb_end2end_test) add_dependencies(buildtests_cxx codegen_test_full) add_dependencies(buildtests_cxx codegen_test_minimal) +add_dependencies(buildtests_cxx context_list_test) add_dependencies(buildtests_cxx credentials_test) add_dependencies(buildtests_cxx cxx_byte_buffer_test) add_dependencies(buildtests_cxx cxx_slice_test) @@ -598,9 +635,12 @@ add_dependencies(buildtests_cxx error_details_test) add_dependencies(buildtests_cxx exception_test) add_dependencies(buildtests_cxx filter_end2end_test) add_dependencies(buildtests_cxx generic_end2end_test) +add_dependencies(buildtests_cxx global_config_env_test) +add_dependencies(buildtests_cxx global_config_test) add_dependencies(buildtests_cxx golden_file_test) add_dependencies(buildtests_cxx grpc_alts_credentials_options_test) add_dependencies(buildtests_cxx grpc_cli) +add_dependencies(buildtests_cxx grpc_core_map_test) add_dependencies(buildtests_cxx grpc_linux_system_roots_test) add_dependencies(buildtests_cxx grpc_tool_test) add_dependencies(buildtests_cxx grpclb_api_test) @@ -629,10 +669,12 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_dependencies(buildtests_cxx json_run_localhost) endif() add_dependencies(buildtests_cxx memory_test) +add_dependencies(buildtests_cxx message_allocator_end2end_test) add_dependencies(buildtests_cxx metrics_client) add_dependencies(buildtests_cxx mock_test) add_dependencies(buildtests_cxx nonblocking_test) add_dependencies(buildtests_cxx noop-benchmark) +add_dependencies(buildtests_cxx optional_test) add_dependencies(buildtests_cxx orphanable_test) add_dependencies(buildtests_cxx proto_server_reflection_test) add_dependencies(buildtests_cxx proto_utils_test) @@ -667,6 +709,8 @@ add_dependencies(buildtests_cxx server_crash_test_client) add_dependencies(buildtests_cxx server_early_return_test) add_dependencies(buildtests_cxx server_interceptors_end2end_test) add_dependencies(buildtests_cxx server_request_call_test) +add_dependencies(buildtests_cxx service_config_end2end_test) +add_dependencies(buildtests_cxx service_config_test) add_dependencies(buildtests_cxx shutdown_test) add_dependencies(buildtests_cxx slice_hash_table_test) add_dependencies(buildtests_cxx slice_weak_hash_table_test) @@ -679,11 +723,15 @@ endif() add_dependencies(buildtests_cxx stress_test) add_dependencies(buildtests_cxx thread_manager_test) add_dependencies(buildtests_cxx thread_stress_test) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) +add_dependencies(buildtests_cxx time_change_test) +endif() add_dependencies(buildtests_cxx transport_pid_controller_test) add_dependencies(buildtests_cxx transport_security_common_api_test) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_dependencies(buildtests_cxx writes_per_rpc_test) endif() +add_dependencies(buildtests_cxx xds_end2end_test) add_dependencies(buildtests_cxx resolver_component_test_unsecure) add_dependencies(buildtests_cxx resolver_component_test) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) @@ -800,7 +848,6 @@ endif (gRPC_BUILD_TESTS) add_library(gpr 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 @@ -833,7 +880,9 @@ add_library(gpr 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/arena.cc src/core/lib/gprpp/fork.cc + src/core/lib/gprpp/global_config_env.cc src/core/lib/gprpp/thd_posix.cc src/core/lib/gprpp/thd_windows.cc src/core/lib/profiling/basic_timers.cc @@ -929,49 +978,6 @@ if (gRPC_INSTALL) ) endif() -if (gRPC_BUILD_TESTS) - -add_library(gpr_test_util - test/core/util/test_config.cc -) - -if(WIN32 AND MSVC) - set_target_properties(gpr_test_util PROPERTIES COMPILE_PDB_NAME "gpr_test_util" - COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" - ) - if (gRPC_INSTALL) - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/gpr_test_util.pdb - DESTINATION ${gRPC_INSTALL_LIBDIR} OPTIONAL - ) - endif() -endif() - - -target_include_directories(gpr_test_util - PUBLIC $ $ - 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 ${_gRPC_NANOPB_INCLUDE_DIR} -) - # avoid dependency on libstdc++ - if (_gRPC_CORE_NOSTDCXX_FLAGS) - set_target_properties(gpr_test_util PROPERTIES LINKER_LANGUAGE C) - # only use the flags for C++ source files - target_compile_options(gpr_test_util PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) - endif() -target_link_libraries(gpr_test_util - ${_gRPC_ALLTARGETS_LIBRARIES} - gpr -) - - -endif (gRPC_BUILD_TESTS) add_library(grpc src/core/lib/surface/init.cc @@ -985,10 +991,10 @@ add_library(grpc src/core/lib/channel/channelz_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_args.cc src/core/lib/compression/compression_internal.cc src/core/lib/compression/message_compress.cc src/core/lib/compression/stream_compression.cc @@ -1001,12 +1007,15 @@ add_library(grpc src/core/lib/http/parser.cc src/core/lib/iomgr/buffer_list.cc src/core/lib/iomgr/call_combiner.cc + src/core/lib/iomgr/cfstream_handle.cc src/core/lib/iomgr/combiner.cc src/core/lib/iomgr/endpoint.cc + src/core/lib/iomgr/endpoint_cfstream.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/error_cfstream.cc src/core/lib/iomgr/ev_epoll1_linux.cc src/core/lib/iomgr/ev_epollex_linux.cc src/core/lib/iomgr/ev_poll_posix.cc @@ -1019,18 +1028,20 @@ add_library(grpc 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/grpc_if_nametoindex_posix.cc + src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc src/core/lib/iomgr/internal_errqueue.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_posix_cfstream.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 @@ -1054,6 +1065,7 @@ add_library(grpc 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_cfstream.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 @@ -1078,7 +1090,6 @@ add_library(grpc 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 @@ -1118,7 +1129,6 @@ add_library(grpc 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 @@ -1132,6 +1142,7 @@ add_library(grpc 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/context_list.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 @@ -1172,6 +1183,8 @@ add_library(grpc 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/tls/grpc_tls_credentials_options.cc + src/core/lib/security/credentials/tls/spiffe_credentials.cc src/core/lib/security/security_connector/alts/alts_security_connector.cc src/core/lib/security/security_connector/fake/fake_security_connector.cc src/core/lib/security/security_connector/load_system_roots_fallback.cc @@ -1180,6 +1193,7 @@ add_library(grpc src/core/lib/security/security_connector/security_connector.cc src/core/lib/security/security_connector/ssl/ssl_security_connector.cc src/core/lib/security/security_connector/ssl_utils.cc + src/core/lib/security/security_connector/tls/spiffe_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 @@ -1234,21 +1248,25 @@ add_library(grpc 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/global_subchannel_pool.cc src/core/ext/filters/client_channel/health/health_check_client.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/local_subchannel_pool.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/resolver_result_parsing.cc + src/core/ext/filters/client_channel/resolving_lb_policy.cc src/core/ext/filters/client_channel/retry_throttle.cc + src/core/ext/filters/client_channel/server_address.cc + src/core/ext/filters/client_channel/service_config.cc src/core/ext/filters/client_channel/subchannel.cc - src/core/ext/filters/client_channel/subchannel_index.cc + src/core/ext/filters/client_channel/subchannel_pool_interface.cc src/core/ext/filters/deadline/deadline_filter.cc src/core/ext/filters/client_channel/health/health.pb.c src/core/tsi/fake_transport_security.cc @@ -1281,10 +1299,13 @@ add_library(grpc 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.cc + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc @@ -1405,10 +1426,10 @@ add_library(grpc_cronet src/core/lib/channel/channelz_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_args.cc src/core/lib/compression/compression_internal.cc src/core/lib/compression/message_compress.cc src/core/lib/compression/stream_compression.cc @@ -1421,12 +1442,15 @@ add_library(grpc_cronet src/core/lib/http/parser.cc src/core/lib/iomgr/buffer_list.cc src/core/lib/iomgr/call_combiner.cc + src/core/lib/iomgr/cfstream_handle.cc src/core/lib/iomgr/combiner.cc src/core/lib/iomgr/endpoint.cc + src/core/lib/iomgr/endpoint_cfstream.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/error_cfstream.cc src/core/lib/iomgr/ev_epoll1_linux.cc src/core/lib/iomgr/ev_epollex_linux.cc src/core/lib/iomgr/ev_poll_posix.cc @@ -1439,18 +1463,20 @@ add_library(grpc_cronet 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/grpc_if_nametoindex_posix.cc + src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc src/core/lib/iomgr/internal_errqueue.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_posix_cfstream.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 @@ -1474,6 +1500,7 @@ add_library(grpc_cronet 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_cfstream.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 @@ -1498,7 +1525,6 @@ add_library(grpc_cronet 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 @@ -1538,7 +1564,6 @@ add_library(grpc_cronet 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 @@ -1555,6 +1580,7 @@ add_library(grpc_cronet 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/context_list.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 @@ -1585,21 +1611,25 @@ add_library(grpc_cronet 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/global_subchannel_pool.cc src/core/ext/filters/client_channel/health/health_check_client.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/local_subchannel_pool.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/resolver_result_parsing.cc + src/core/ext/filters/client_channel/resolving_lb_policy.cc src/core/ext/filters/client_channel/retry_throttle.cc + src/core/ext/filters/client_channel/server_address.cc + src/core/ext/filters/client_channel/service_config.cc src/core/ext/filters/client_channel/subchannel.cc - src/core/ext/filters/client_channel/subchannel_index.cc + src/core/ext/filters/client_channel/subchannel_pool_interface.cc src/core/ext/filters/deadline/deadline_filter.cc src/core/ext/filters/client_channel/health/health.pb.c third_party/nanopb/pb_common.c @@ -1622,6 +1652,8 @@ add_library(grpc_cronet 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/tls/grpc_tls_credentials_options.cc + src/core/lib/security/credentials/tls/spiffe_credentials.cc src/core/lib/security/security_connector/alts/alts_security_connector.cc src/core/lib/security/security_connector/fake/fake_security_connector.cc src/core/lib/security/security_connector/load_system_roots_fallback.cc @@ -1630,6 +1662,7 @@ add_library(grpc_cronet src/core/lib/security/security_connector/security_connector.cc src/core/lib/security/security_connector/ssl/ssl_security_connector.cc src/core/lib/security/security_connector/ssl_utils.cc + src/core/lib/security/security_connector/tls/spiffe_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 @@ -1778,6 +1811,7 @@ add_library(grpc_test_util src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc test/core/end2end/cq_verifier.cc test/core/end2end/fixtures/http_proxy_fixture.cc + test/core/end2end/fixtures/local_util.cc test/core/end2end/fixtures/proxy.cc test/core/iomgr/endpoint_tests.cc test/core/util/debugger_macros.cc @@ -1794,6 +1828,8 @@ add_library(grpc_test_util test/core/util/slice_splitter.cc test/core/util/subprocess_posix.cc test/core/util/subprocess_windows.cc + test/core/util/test_config.cc + test/core/util/test_lb_policies.cc test/core/util/tracer_util.cc test/core/util/trickle_endpoint.cc test/core/util/cmdline.cc @@ -1807,10 +1843,10 @@ add_library(grpc_test_util src/core/lib/channel/channelz_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_args.cc src/core/lib/compression/compression_internal.cc src/core/lib/compression/message_compress.cc src/core/lib/compression/stream_compression.cc @@ -1823,12 +1859,15 @@ add_library(grpc_test_util src/core/lib/http/parser.cc src/core/lib/iomgr/buffer_list.cc src/core/lib/iomgr/call_combiner.cc + src/core/lib/iomgr/cfstream_handle.cc src/core/lib/iomgr/combiner.cc src/core/lib/iomgr/endpoint.cc + src/core/lib/iomgr/endpoint_cfstream.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/error_cfstream.cc src/core/lib/iomgr/ev_epoll1_linux.cc src/core/lib/iomgr/ev_epollex_linux.cc src/core/lib/iomgr/ev_poll_posix.cc @@ -1841,18 +1880,20 @@ add_library(grpc_test_util 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/grpc_if_nametoindex_posix.cc + src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc src/core/lib/iomgr/internal_errqueue.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_posix_cfstream.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 @@ -1876,6 +1917,7 @@ add_library(grpc_test_util 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_cfstream.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 @@ -1900,7 +1942,6 @@ add_library(grpc_test_util 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 @@ -1940,7 +1981,6 @@ add_library(grpc_test_util 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 @@ -1956,21 +1996,25 @@ add_library(grpc_test_util 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/global_subchannel_pool.cc src/core/ext/filters/client_channel/health/health_check_client.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/local_subchannel_pool.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/resolver_result_parsing.cc + src/core/ext/filters/client_channel/resolving_lb_policy.cc src/core/ext/filters/client_channel/retry_throttle.cc + src/core/ext/filters/client_channel/server_address.cc + src/core/ext/filters/client_channel/service_config.cc src/core/ext/filters/client_channel/subchannel.cc - src/core/ext/filters/client_channel/subchannel_index.cc + src/core/ext/filters/client_channel/subchannel_pool_interface.cc src/core/ext/filters/deadline/deadline_filter.cc src/core/ext/filters/client_channel/health/health.pb.c third_party/nanopb/pb_common.c @@ -1980,6 +2024,7 @@ add_library(grpc_test_util 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/context_list.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 @@ -2037,7 +2082,6 @@ target_include_directories(grpc_test_util endif() target_link_libraries(grpc_test_util ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util gpr grpc ) @@ -2097,6 +2141,7 @@ add_library(grpc_test_util_unsecure src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc test/core/end2end/cq_verifier.cc test/core/end2end/fixtures/http_proxy_fixture.cc + test/core/end2end/fixtures/local_util.cc test/core/end2end/fixtures/proxy.cc test/core/iomgr/endpoint_tests.cc test/core/util/debugger_macros.cc @@ -2113,6 +2158,8 @@ add_library(grpc_test_util_unsecure test/core/util/slice_splitter.cc test/core/util/subprocess_posix.cc test/core/util/subprocess_windows.cc + test/core/util/test_config.cc + test/core/util/test_lb_policies.cc test/core/util/tracer_util.cc test/core/util/trickle_endpoint.cc test/core/util/cmdline.cc @@ -2126,10 +2173,10 @@ add_library(grpc_test_util_unsecure src/core/lib/channel/channelz_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_args.cc src/core/lib/compression/compression_internal.cc src/core/lib/compression/message_compress.cc src/core/lib/compression/stream_compression.cc @@ -2142,12 +2189,15 @@ add_library(grpc_test_util_unsecure src/core/lib/http/parser.cc src/core/lib/iomgr/buffer_list.cc src/core/lib/iomgr/call_combiner.cc + src/core/lib/iomgr/cfstream_handle.cc src/core/lib/iomgr/combiner.cc src/core/lib/iomgr/endpoint.cc + src/core/lib/iomgr/endpoint_cfstream.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/error_cfstream.cc src/core/lib/iomgr/ev_epoll1_linux.cc src/core/lib/iomgr/ev_epollex_linux.cc src/core/lib/iomgr/ev_poll_posix.cc @@ -2160,18 +2210,20 @@ add_library(grpc_test_util_unsecure 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/grpc_if_nametoindex_posix.cc + src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc src/core/lib/iomgr/internal_errqueue.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_posix_cfstream.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 @@ -2195,6 +2247,7 @@ add_library(grpc_test_util_unsecure 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_cfstream.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 @@ -2219,7 +2272,6 @@ add_library(grpc_test_util_unsecure 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 @@ -2259,7 +2311,6 @@ add_library(grpc_test_util_unsecure 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 @@ -2275,21 +2326,25 @@ add_library(grpc_test_util_unsecure 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/global_subchannel_pool.cc src/core/ext/filters/client_channel/health/health_check_client.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/local_subchannel_pool.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/resolver_result_parsing.cc + src/core/ext/filters/client_channel/resolving_lb_policy.cc src/core/ext/filters/client_channel/retry_throttle.cc + src/core/ext/filters/client_channel/server_address.cc + src/core/ext/filters/client_channel/service_config.cc src/core/ext/filters/client_channel/subchannel.cc - src/core/ext/filters/client_channel/subchannel_index.cc + src/core/ext/filters/client_channel/subchannel_pool_interface.cc src/core/ext/filters/deadline/deadline_filter.cc src/core/ext/filters/client_channel/health/health.pb.c third_party/nanopb/pb_common.c @@ -2299,6 +2354,7 @@ add_library(grpc_test_util_unsecure 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/context_list.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 @@ -2357,7 +2413,6 @@ target_include_directories(grpc_test_util_unsecure target_link_libraries(grpc_test_util_unsecure ${_gRPC_ALLTARGETS_LIBRARIES} gpr - gpr_test_util grpc_unsecure ) @@ -2424,10 +2479,10 @@ add_library(grpc_unsecure src/core/lib/channel/channelz_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_args.cc src/core/lib/compression/compression_internal.cc src/core/lib/compression/message_compress.cc src/core/lib/compression/stream_compression.cc @@ -2440,12 +2495,15 @@ add_library(grpc_unsecure src/core/lib/http/parser.cc src/core/lib/iomgr/buffer_list.cc src/core/lib/iomgr/call_combiner.cc + src/core/lib/iomgr/cfstream_handle.cc src/core/lib/iomgr/combiner.cc src/core/lib/iomgr/endpoint.cc + src/core/lib/iomgr/endpoint_cfstream.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/error_cfstream.cc src/core/lib/iomgr/ev_epoll1_linux.cc src/core/lib/iomgr/ev_epollex_linux.cc src/core/lib/iomgr/ev_poll_posix.cc @@ -2458,18 +2516,20 @@ add_library(grpc_unsecure 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/grpc_if_nametoindex_posix.cc + src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc src/core/lib/iomgr/internal_errqueue.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_posix_cfstream.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 @@ -2493,6 +2553,7 @@ add_library(grpc_unsecure 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_cfstream.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 @@ -2517,7 +2578,6 @@ add_library(grpc_unsecure 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 @@ -2557,7 +2617,6 @@ add_library(grpc_unsecure 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 @@ -2572,6 +2631,7 @@ add_library(grpc_unsecure 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/context_list.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 @@ -2607,21 +2667,25 @@ add_library(grpc_unsecure 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/global_subchannel_pool.cc src/core/ext/filters/client_channel/health/health_check_client.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/local_subchannel_pool.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/resolver_result_parsing.cc + src/core/ext/filters/client_channel/resolving_lb_policy.cc src/core/ext/filters/client_channel/retry_throttle.cc + src/core/ext/filters/client_channel/server_address.cc + src/core/ext/filters/client_channel/service_config.cc src/core/ext/filters/client_channel/subchannel.cc - src/core/ext/filters/client_channel/subchannel_index.cc + src/core/ext/filters/client_channel/subchannel_pool_interface.cc src/core/ext/filters/deadline/deadline_filter.cc src/core/ext/filters/client_channel/health/health.pb.c third_party/nanopb/pb_common.c @@ -2631,10 +2695,13 @@ add_library(grpc_unsecure src/core/ext/transport/inproc/inproc_transport.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.cc + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc @@ -2796,7 +2863,6 @@ target_link_libraries(reconnect_server test_tcp_server grpc_test_util grpc - gpr_test_util gpr ) @@ -2842,11 +2908,114 @@ target_link_libraries(test_tcp_server ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) + +if (gRPC_BUILD_CODEGEN) +add_library(bm_callback_test_service_impl + ${_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 + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_mock.grpc.pb.h + test/cpp/microbenchmarks/callback_test_service.cc +) + +if(WIN32 AND MSVC) + set_target_properties(bm_callback_test_service_impl PROPERTIES COMPILE_PDB_NAME "bm_callback_test_service_impl" + COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" + ) + if (gRPC_INSTALL) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/bm_callback_test_service_impl.pdb + DESTINATION ${gRPC_INSTALL_LIBDIR} OPTIONAL + ) + endif() +endif() + +protobuf_generate_grpc_cpp( + src/proto/grpc/testing/echo.proto +) + +target_include_directories(bm_callback_test_service_impl + PUBLIC $ $ + 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 ${_gRPC_NANOPB_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(bm_callback_test_service_impl + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_benchmark + ${_gRPC_BENCHMARK_LIBRARIES} + grpc++_test_util_unsecure + grpc_test_util_unsecure + grpc++_unsecure + grpc_unsecure + gpr + grpc++_test_config + ${_gRPC_GFLAGS_LIBRARIES} +) + +endif (gRPC_BUILD_CODEGEN) + +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) + +add_library(dns_test_util + test/cpp/naming/dns_test_util.cc +) + +if(WIN32 AND MSVC) + set_target_properties(dns_test_util PROPERTIES COMPILE_PDB_NAME "dns_test_util" + COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" + ) + if (gRPC_INSTALL) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/dns_test_util.pdb + DESTINATION ${gRPC_INSTALL_LIBDIR} OPTIONAL + ) + endif() +endif() + + +target_include_directories(dns_test_util + PUBLIC $ $ + 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 ${_gRPC_NANOPB_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(dns_test_util + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + ${_gRPC_GFLAGS_LIBRARIES} +) + + endif (gRPC_BUILD_TESTS) add_library(grpc++ @@ -2979,16 +3148,22 @@ foreach(_hdr include/grpc++/support/sync_stream.h include/grpc++/support/time.h include/grpcpp/alarm.h + include/grpcpp/alarm_impl.h include/grpcpp/channel.h + include/grpcpp/channel_impl.h include/grpcpp/client_context.h include/grpcpp/completion_queue.h include/grpcpp/create_channel.h + include/grpcpp/create_channel_impl.h include/grpcpp/create_channel_posix.h + include/grpcpp/create_channel_posix_impl.h include/grpcpp/ext/health_check_service_server_builder_option.h include/grpcpp/generic/async_generic_service.h include/grpcpp/generic/generic_stub.h + include/grpcpp/generic/generic_stub_impl.h include/grpcpp/grpcpp.h include/grpcpp/health_check_service_interface.h + include/grpcpp/health_check_service_interface_impl.h include/grpcpp/impl/call.h include/grpcpp/impl/channel_argument_option.h include/grpcpp/impl/client_unary_call.h @@ -2999,27 +3174,41 @@ foreach(_hdr include/grpcpp/impl/rpc_service_method.h include/grpcpp/impl/serialization_traits.h include/grpcpp/impl/server_builder_option.h + include/grpcpp/impl/server_builder_option_impl.h include/grpcpp/impl/server_builder_plugin.h include/grpcpp/impl/server_initializer.h + include/grpcpp/impl/server_initializer_impl.h include/grpcpp/impl/service_type.h include/grpcpp/resource_quota.h + include/grpcpp/resource_quota_impl.h include/grpcpp/security/auth_context.h include/grpcpp/security/auth_metadata_processor.h + include/grpcpp/security/auth_metadata_processor_impl.h include/grpcpp/security/credentials.h + include/grpcpp/security/credentials_impl.h include/grpcpp/security/server_credentials.h + include/grpcpp/security/server_credentials_impl.h include/grpcpp/server.h include/grpcpp/server_builder.h + include/grpcpp/server_builder_impl.h include/grpcpp/server_context.h + include/grpcpp/server_impl.h include/grpcpp/server_posix.h + include/grpcpp/server_posix_impl.h include/grpcpp/support/async_stream.h include/grpcpp/support/async_unary_call.h include/grpcpp/support/byte_buffer.h include/grpcpp/support/channel_arguments.h + include/grpcpp/support/channel_arguments_impl.h include/grpcpp/support/client_callback.h + include/grpcpp/support/client_interceptor.h include/grpcpp/support/config.h + include/grpcpp/support/interceptor.h + include/grpcpp/support/message_allocator.h include/grpcpp/support/proto_buffer_reader.h include/grpcpp/support/proto_buffer_writer.h include/grpcpp/support/server_callback.h + include/grpcpp/support/server_interceptor.h include/grpcpp/support/slice.h include/grpcpp/support/status.h include/grpcpp/support/status_code_enum.h @@ -3123,6 +3312,7 @@ foreach(_hdr include/grpcpp/impl/codegen/client_interceptor.h include/grpcpp/impl/codegen/client_unary_call.h include/grpcpp/impl/codegen/completion_queue.h + include/grpcpp/impl/codegen/completion_queue_impl.h include/grpcpp/impl/codegen/completion_queue_tag.h include/grpcpp/impl/codegen/config.h include/grpcpp/impl/codegen/core_codegen_interface.h @@ -3131,6 +3321,7 @@ foreach(_hdr include/grpcpp/impl/codegen/intercepted_channel.h include/grpcpp/impl/codegen/interceptor.h include/grpcpp/impl/codegen/interceptor_common.h + include/grpcpp/impl/codegen/message_allocator.h include/grpcpp/impl/codegen/metadata_map.h include/grpcpp/impl/codegen/method_handler_impl.h include/grpcpp/impl/codegen/rpc_method.h @@ -3149,6 +3340,7 @@ foreach(_hdr include/grpcpp/impl/codegen/stub_options.h include/grpcpp/impl/codegen/sync_stream.h include/grpcpp/impl/codegen/time.h + include/grpcpp/impl/codegen/sync.h include/grpc++/impl/codegen/proto_utils.h include/grpcpp/impl/codegen/proto_buffer_reader.h include/grpcpp/impl/codegen/proto_buffer_writer.h @@ -3219,6 +3411,7 @@ target_link_libraries(grpc++_core_stats ${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES} grpc++ + ${_gRPC_GFLAGS_LIBRARIES} ) endif (gRPC_BUILD_CODEGEN) @@ -3276,6 +3469,7 @@ add_library(grpc++_cronet 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/context_list.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 @@ -3304,10 +3498,10 @@ add_library(grpc++_cronet src/core/lib/channel/channelz_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_args.cc src/core/lib/compression/compression_internal.cc src/core/lib/compression/message_compress.cc src/core/lib/compression/stream_compression.cc @@ -3320,12 +3514,15 @@ add_library(grpc++_cronet src/core/lib/http/parser.cc src/core/lib/iomgr/buffer_list.cc src/core/lib/iomgr/call_combiner.cc + src/core/lib/iomgr/cfstream_handle.cc src/core/lib/iomgr/combiner.cc src/core/lib/iomgr/endpoint.cc + src/core/lib/iomgr/endpoint_cfstream.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/error_cfstream.cc src/core/lib/iomgr/ev_epoll1_linux.cc src/core/lib/iomgr/ev_epollex_linux.cc src/core/lib/iomgr/ev_poll_posix.cc @@ -3338,18 +3535,20 @@ add_library(grpc++_cronet 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/grpc_if_nametoindex_posix.cc + src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc src/core/lib/iomgr/internal_errqueue.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_posix_cfstream.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 @@ -3373,6 +3572,7 @@ add_library(grpc++_cronet 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_cfstream.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 @@ -3397,7 +3597,6 @@ add_library(grpc++_cronet 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 @@ -3437,7 +3636,6 @@ add_library(grpc++_cronet 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 @@ -3458,21 +3656,25 @@ add_library(grpc++_cronet 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/global_subchannel_pool.cc src/core/ext/filters/client_channel/health/health_check_client.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/local_subchannel_pool.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/resolver_result_parsing.cc + src/core/ext/filters/client_channel/resolving_lb_policy.cc src/core/ext/filters/client_channel/retry_throttle.cc + src/core/ext/filters/client_channel/server_address.cc + src/core/ext/filters/client_channel/service_config.cc src/core/ext/filters/client_channel/subchannel.cc - src/core/ext/filters/client_channel/subchannel_index.cc + src/core/ext/filters/client_channel/subchannel_pool_interface.cc src/core/ext/filters/deadline/deadline_filter.cc src/core/ext/transport/chttp2/server/insecure/server_chttp2.cc src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc @@ -3562,16 +3764,22 @@ foreach(_hdr include/grpc++/support/sync_stream.h include/grpc++/support/time.h include/grpcpp/alarm.h + include/grpcpp/alarm_impl.h include/grpcpp/channel.h + include/grpcpp/channel_impl.h include/grpcpp/client_context.h include/grpcpp/completion_queue.h include/grpcpp/create_channel.h + include/grpcpp/create_channel_impl.h include/grpcpp/create_channel_posix.h + include/grpcpp/create_channel_posix_impl.h include/grpcpp/ext/health_check_service_server_builder_option.h include/grpcpp/generic/async_generic_service.h include/grpcpp/generic/generic_stub.h + include/grpcpp/generic/generic_stub_impl.h include/grpcpp/grpcpp.h include/grpcpp/health_check_service_interface.h + include/grpcpp/health_check_service_interface_impl.h include/grpcpp/impl/call.h include/grpcpp/impl/channel_argument_option.h include/grpcpp/impl/client_unary_call.h @@ -3582,27 +3790,41 @@ foreach(_hdr include/grpcpp/impl/rpc_service_method.h include/grpcpp/impl/serialization_traits.h include/grpcpp/impl/server_builder_option.h + include/grpcpp/impl/server_builder_option_impl.h include/grpcpp/impl/server_builder_plugin.h include/grpcpp/impl/server_initializer.h + include/grpcpp/impl/server_initializer_impl.h include/grpcpp/impl/service_type.h include/grpcpp/resource_quota.h + include/grpcpp/resource_quota_impl.h include/grpcpp/security/auth_context.h include/grpcpp/security/auth_metadata_processor.h + include/grpcpp/security/auth_metadata_processor_impl.h include/grpcpp/security/credentials.h + include/grpcpp/security/credentials_impl.h include/grpcpp/security/server_credentials.h + include/grpcpp/security/server_credentials_impl.h include/grpcpp/server.h include/grpcpp/server_builder.h + include/grpcpp/server_builder_impl.h include/grpcpp/server_context.h + include/grpcpp/server_impl.h include/grpcpp/server_posix.h + include/grpcpp/server_posix_impl.h include/grpcpp/support/async_stream.h include/grpcpp/support/async_unary_call.h include/grpcpp/support/byte_buffer.h include/grpcpp/support/channel_arguments.h + include/grpcpp/support/channel_arguments_impl.h include/grpcpp/support/client_callback.h + include/grpcpp/support/client_interceptor.h include/grpcpp/support/config.h + include/grpcpp/support/interceptor.h + include/grpcpp/support/message_allocator.h include/grpcpp/support/proto_buffer_reader.h include/grpcpp/support/proto_buffer_writer.h include/grpcpp/support/server_callback.h + include/grpcpp/support/server_interceptor.h include/grpcpp/support/slice.h include/grpcpp/support/status.h include/grpcpp/support/status_code_enum.h @@ -3706,6 +3928,7 @@ foreach(_hdr include/grpcpp/impl/codegen/client_interceptor.h include/grpcpp/impl/codegen/client_unary_call.h include/grpcpp/impl/codegen/completion_queue.h + include/grpcpp/impl/codegen/completion_queue_impl.h include/grpcpp/impl/codegen/completion_queue_tag.h include/grpcpp/impl/codegen/config.h include/grpcpp/impl/codegen/core_codegen_interface.h @@ -3714,6 +3937,7 @@ foreach(_hdr include/grpcpp/impl/codegen/intercepted_channel.h include/grpcpp/impl/codegen/interceptor.h include/grpcpp/impl/codegen/interceptor_common.h + include/grpcpp/impl/codegen/message_allocator.h include/grpcpp/impl/codegen/metadata_map.h include/grpcpp/impl/codegen/method_handler_impl.h include/grpcpp/impl/codegen/rpc_method.h @@ -3732,6 +3956,7 @@ foreach(_hdr include/grpcpp/impl/codegen/stub_options.h include/grpcpp/impl/codegen/sync_stream.h include/grpcpp/impl/codegen/time.h + include/grpcpp/impl/codegen/sync.h include/grpc/census.h ) string(REPLACE "include/" "" _path ${_hdr}) @@ -3798,6 +4023,7 @@ target_link_libraries(grpc++_error_details foreach(_hdr include/grpc++/support/error_details.h include/grpcpp/support/error_details.h + include/grpcpp/support/error_details_impl.h ) string(REPLACE "include/" "" _path ${_hdr}) get_filename_component(_path ${_path} PATH) @@ -3807,6 +4033,7 @@ foreach(_hdr endforeach() endif (gRPC_BUILD_CODEGEN) +if (gRPC_BUILD_CODEGEN) if (gRPC_INSTALL) install(TARGETS grpc++_error_details EXPORT gRPCTargets @@ -3816,6 +4043,7 @@ if (gRPC_INSTALL) ) endif() +endif (gRPC_BUILD_CODEGEN) if (gRPC_BUILD_TESTS) if (gRPC_BUILD_CODEGEN) @@ -3864,6 +4092,7 @@ target_link_libraries(grpc++_proto_reflection_desc_db ${_gRPC_ALLTARGETS_LIBRARIES} grpc++ grpc + ${_gRPC_GFLAGS_LIBRARIES} ) foreach(_hdr @@ -3928,6 +4157,7 @@ target_link_libraries(grpc++_reflection foreach(_hdr include/grpc++/ext/proto_server_reflection_plugin.h include/grpcpp/ext/proto_server_reflection_plugin.h + include/grpcpp/ext/proto_server_reflection_plugin_impl.h ) string(REPLACE "include/" "" _path ${_hdr}) get_filename_component(_path ${_path} PATH) @@ -3937,6 +4167,7 @@ foreach(_hdr endforeach() endif (gRPC_BUILD_CODEGEN) +if (gRPC_BUILD_CODEGEN) if (gRPC_INSTALL) install(TARGETS grpc++_reflection EXPORT gRPCTargets @@ -3946,6 +4177,7 @@ if (gRPC_INSTALL) ) endif() +endif (gRPC_BUILD_CODEGEN) if (gRPC_BUILD_TESTS) add_library(grpc++_test_config @@ -3984,6 +4216,7 @@ target_include_directories(grpc++_test_config target_link_libraries(grpc++_test_config ${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES} + ${_gRPC_GFLAGS_LIBRARIES} ) @@ -4013,6 +4246,11 @@ add_library(grpc++_test_util ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.pb.h ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.h + test/cpp/end2end/test_health_check_service_impl.cc test/cpp/end2end/test_service_impl.cc test/cpp/util/byte_buffer_proto_helper.cc test/cpp/util/channel_trace_proto_helper.cc @@ -4049,6 +4287,9 @@ protobuf_generate_grpc_cpp( protobuf_generate_grpc_cpp( src/proto/grpc/testing/duplicate/echo_duplicate.proto ) +protobuf_generate_grpc_cpp( + src/proto/grpc/testing/simple_messages.proto +) target_include_directories(grpc++_test_util PUBLIC $ $ @@ -4073,6 +4314,7 @@ target_link_libraries(grpc++_test_util grpc++ grpc_test_util grpc + ${_gRPC_GFLAGS_LIBRARIES} ) foreach(_hdr @@ -4121,6 +4363,7 @@ foreach(_hdr include/grpcpp/impl/codegen/client_interceptor.h include/grpcpp/impl/codegen/client_unary_call.h include/grpcpp/impl/codegen/completion_queue.h + include/grpcpp/impl/codegen/completion_queue_impl.h include/grpcpp/impl/codegen/completion_queue_tag.h include/grpcpp/impl/codegen/config.h include/grpcpp/impl/codegen/core_codegen_interface.h @@ -4129,6 +4372,7 @@ foreach(_hdr include/grpcpp/impl/codegen/intercepted_channel.h include/grpcpp/impl/codegen/interceptor.h include/grpcpp/impl/codegen/interceptor_common.h + include/grpcpp/impl/codegen/message_allocator.h include/grpcpp/impl/codegen/metadata_map.h include/grpcpp/impl/codegen/method_handler_impl.h include/grpcpp/impl/codegen/rpc_method.h @@ -4169,6 +4413,7 @@ foreach(_hdr include/grpc/impl/codegen/sync_generic.h include/grpc/impl/codegen/sync_posix.h include/grpc/impl/codegen/sync_windows.h + include/grpcpp/impl/codegen/sync.h include/grpc++/impl/codegen/proto_utils.h include/grpcpp/impl/codegen/proto_buffer_reader.h include/grpcpp/impl/codegen/proto_buffer_writer.h @@ -4206,6 +4451,11 @@ add_library(grpc++_test_util_unsecure ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.pb.h ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.h + test/cpp/end2end/test_health_check_service_impl.cc test/cpp/end2end/test_service_impl.cc test/cpp/util/byte_buffer_proto_helper.cc test/cpp/util/string_ref_helper.cc @@ -4236,6 +4486,9 @@ protobuf_generate_grpc_cpp( protobuf_generate_grpc_cpp( src/proto/grpc/testing/duplicate/echo_duplicate.proto ) +protobuf_generate_grpc_cpp( + src/proto/grpc/testing/simple_messages.proto +) target_include_directories(grpc++_test_util_unsecure PUBLIC $ $ @@ -4260,6 +4513,7 @@ target_link_libraries(grpc++_test_util_unsecure grpc++_unsecure grpc_test_util_unsecure grpc_unsecure + ${_gRPC_GFLAGS_LIBRARIES} ) foreach(_hdr @@ -4308,6 +4562,7 @@ foreach(_hdr include/grpcpp/impl/codegen/client_interceptor.h include/grpcpp/impl/codegen/client_unary_call.h include/grpcpp/impl/codegen/completion_queue.h + include/grpcpp/impl/codegen/completion_queue_impl.h include/grpcpp/impl/codegen/completion_queue_tag.h include/grpcpp/impl/codegen/config.h include/grpcpp/impl/codegen/core_codegen_interface.h @@ -4316,6 +4571,7 @@ foreach(_hdr include/grpcpp/impl/codegen/intercepted_channel.h include/grpcpp/impl/codegen/interceptor.h include/grpcpp/impl/codegen/interceptor_common.h + include/grpcpp/impl/codegen/message_allocator.h include/grpcpp/impl/codegen/metadata_map.h include/grpcpp/impl/codegen/method_handler_impl.h include/grpcpp/impl/codegen/rpc_method.h @@ -4356,6 +4612,7 @@ foreach(_hdr include/grpc/impl/codegen/sync_generic.h include/grpc/impl/codegen/sync_posix.h include/grpc/impl/codegen/sync_windows.h + include/grpcpp/impl/codegen/sync.h include/grpc++/impl/codegen/proto_utils.h include/grpcpp/impl/codegen/proto_buffer_reader.h include/grpcpp/impl/codegen/proto_buffer_writer.h @@ -4497,16 +4754,22 @@ foreach(_hdr include/grpc++/support/sync_stream.h include/grpc++/support/time.h include/grpcpp/alarm.h + include/grpcpp/alarm_impl.h include/grpcpp/channel.h + include/grpcpp/channel_impl.h include/grpcpp/client_context.h include/grpcpp/completion_queue.h include/grpcpp/create_channel.h + include/grpcpp/create_channel_impl.h include/grpcpp/create_channel_posix.h + include/grpcpp/create_channel_posix_impl.h include/grpcpp/ext/health_check_service_server_builder_option.h include/grpcpp/generic/async_generic_service.h include/grpcpp/generic/generic_stub.h + include/grpcpp/generic/generic_stub_impl.h include/grpcpp/grpcpp.h include/grpcpp/health_check_service_interface.h + include/grpcpp/health_check_service_interface_impl.h include/grpcpp/impl/call.h include/grpcpp/impl/channel_argument_option.h include/grpcpp/impl/client_unary_call.h @@ -4517,27 +4780,41 @@ foreach(_hdr include/grpcpp/impl/rpc_service_method.h include/grpcpp/impl/serialization_traits.h include/grpcpp/impl/server_builder_option.h + include/grpcpp/impl/server_builder_option_impl.h include/grpcpp/impl/server_builder_plugin.h include/grpcpp/impl/server_initializer.h + include/grpcpp/impl/server_initializer_impl.h include/grpcpp/impl/service_type.h include/grpcpp/resource_quota.h + include/grpcpp/resource_quota_impl.h include/grpcpp/security/auth_context.h include/grpcpp/security/auth_metadata_processor.h + include/grpcpp/security/auth_metadata_processor_impl.h include/grpcpp/security/credentials.h + include/grpcpp/security/credentials_impl.h include/grpcpp/security/server_credentials.h + include/grpcpp/security/server_credentials_impl.h include/grpcpp/server.h include/grpcpp/server_builder.h + include/grpcpp/server_builder_impl.h include/grpcpp/server_context.h + include/grpcpp/server_impl.h include/grpcpp/server_posix.h + include/grpcpp/server_posix_impl.h include/grpcpp/support/async_stream.h include/grpcpp/support/async_unary_call.h include/grpcpp/support/byte_buffer.h include/grpcpp/support/channel_arguments.h + include/grpcpp/support/channel_arguments_impl.h include/grpcpp/support/client_callback.h + include/grpcpp/support/client_interceptor.h include/grpcpp/support/config.h + include/grpcpp/support/interceptor.h + include/grpcpp/support/message_allocator.h include/grpcpp/support/proto_buffer_reader.h include/grpcpp/support/proto_buffer_writer.h include/grpcpp/support/server_callback.h + include/grpcpp/support/server_interceptor.h include/grpcpp/support/slice.h include/grpcpp/support/status.h include/grpcpp/support/status_code_enum.h @@ -4641,6 +4918,7 @@ foreach(_hdr include/grpcpp/impl/codegen/client_interceptor.h include/grpcpp/impl/codegen/client_unary_call.h include/grpcpp/impl/codegen/completion_queue.h + include/grpcpp/impl/codegen/completion_queue_impl.h include/grpcpp/impl/codegen/completion_queue_tag.h include/grpcpp/impl/codegen/config.h include/grpcpp/impl/codegen/core_codegen_interface.h @@ -4649,6 +4927,7 @@ foreach(_hdr include/grpcpp/impl/codegen/intercepted_channel.h include/grpcpp/impl/codegen/interceptor.h include/grpcpp/impl/codegen/interceptor_common.h + include/grpcpp/impl/codegen/message_allocator.h include/grpcpp/impl/codegen/metadata_map.h include/grpcpp/impl/codegen/method_handler_impl.h include/grpcpp/impl/codegen/rpc_method.h @@ -4667,6 +4946,7 @@ foreach(_hdr include/grpcpp/impl/codegen/stub_options.h include/grpcpp/impl/codegen/sync_stream.h include/grpcpp/impl/codegen/time.h + include/grpcpp/impl/codegen/sync.h ) string(REPLACE "include/" "" _path ${_hdr}) get_filename_component(_path ${_path} PATH) @@ -4784,6 +5064,7 @@ target_link_libraries(grpc_cli_libs grpc++_proto_reflection_desc_db grpc++ grpc + ${_gRPC_GFLAGS_LIBRARIES} ) foreach(_hdr @@ -4909,6 +5190,7 @@ target_link_libraries(grpcpp_channelz foreach(_hdr include/grpcpp/ext/channelz_service_plugin.h + include/grpcpp/ext/channelz_service_plugin_impl.h ) string(REPLACE "include/" "" _path ${_hdr}) get_filename_component(_path ${_path} PATH) @@ -4918,6 +5200,7 @@ foreach(_hdr endforeach() endif (gRPC_BUILD_CODEGEN) +if (gRPC_BUILD_CODEGEN) if (gRPC_INSTALL) install(TARGETS grpcpp_channelz EXPORT gRPCTargets @@ -4927,6 +5210,7 @@ if (gRPC_INSTALL) ) endif() +endif (gRPC_BUILD_CODEGEN) if (gRPC_BUILD_TESTS) if (gRPC_BUILD_CODEGEN) @@ -4992,6 +5276,7 @@ target_link_libraries(http2_client_main grpc++ grpc grpc++_test_config + ${_gRPC_GFLAGS_LIBRARIES} ) endif (gRPC_BUILD_CODEGEN) @@ -5048,6 +5333,7 @@ target_link_libraries(interop_client_helper grpc++ grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) endif (gRPC_BUILD_CODEGEN) @@ -5119,9 +5405,9 @@ target_link_libraries(interop_client_main grpc_test_util grpc++ grpc - gpr_test_util gpr grpc++_test_config + ${_gRPC_GFLAGS_LIBRARIES} ) endif (gRPC_BUILD_CODEGEN) @@ -5170,6 +5456,7 @@ target_link_libraries(interop_server_helper grpc++ grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) @@ -5239,9 +5526,9 @@ target_link_libraries(interop_server_lib grpc_test_util grpc++ grpc - gpr_test_util gpr grpc++_test_config + ${_gRPC_GFLAGS_LIBRARIES} ) endif (gRPC_BUILD_CODEGEN) @@ -5286,6 +5573,7 @@ target_link_libraries(interop_server_main ${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES} interop_server_lib + ${_gRPC_GFLAGS_LIBRARIES} ) @@ -5395,6 +5683,7 @@ target_link_libraries(qps grpc++_core_stats grpc++ grpc + ${_gRPC_GFLAGS_LIBRARIES} ) endif (gRPC_BUILD_CODEGEN) @@ -5455,6 +5744,58 @@ endif() endif (gRPC_BUILD_CSHARP_EXT) if (gRPC_BUILD_TESTS) +add_library(upb + third_party/upb/google/protobuf/descriptor.upb.c + third_party/upb/upb/decode.c + third_party/upb/upb/def.c + third_party/upb/upb/encode.c + third_party/upb/upb/handlers.c + third_party/upb/upb/msg.c + third_party/upb/upb/msgfactory.c + third_party/upb/upb/sink.c + third_party/upb/upb/table.c + third_party/upb/upb/upb.c +) + +if(WIN32 AND MSVC) + set_target_properties(upb PROPERTIES COMPILE_PDB_NAME "upb" + COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" + ) + if (gRPC_INSTALL) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/upb.pdb + DESTINATION ${gRPC_INSTALL_LIBDIR} OPTIONAL + ) + endif() +endif() + + +target_include_directories(upb + PUBLIC $ $ + 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 ${_gRPC_NANOPB_INCLUDE_DIR} +) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(upb PROPERTIES LINKER_LANGUAGE C) + # only use the flags for C++ source files + target_compile_options(upb PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() +target_link_libraries(upb + ${_gRPC_SSL_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} +) + + +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) + add_library(bad_client_test test/core/bad_client/bad_client.cc ) @@ -5493,7 +5834,6 @@ target_link_libraries(bad_client_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -5539,7 +5879,6 @@ target_link_libraries(bad_ssl_test_server ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -5571,6 +5910,7 @@ add_library(end2end_tests test/core/end2end/tests/empty_batch.cc test/core/end2end/tests/filter_call_init_fails.cc test/core/end2end/tests/filter_causes_close.cc + test/core/end2end/tests/filter_context.cc test/core/end2end/tests/filter_latency.cc test/core/end2end/tests/filter_status_code.cc test/core/end2end/tests/graceful_server_shutdown.cc @@ -5585,7 +5925,6 @@ add_library(end2end_tests test/core/end2end/tests/max_connection_idle.cc test/core/end2end/tests/max_message_length.cc test/core/end2end/tests/negative_deadline.cc - test/core/end2end/tests/network_status_change.cc test/core/end2end/tests/no_error_on_hotpath.cc test/core/end2end/tests/no_logging.cc test/core/end2end/tests/no_op.cc @@ -5665,7 +6004,6 @@ target_link_libraries(end2end_tests ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -5696,6 +6034,7 @@ add_library(end2end_nosec_tests test/core/end2end/tests/empty_batch.cc test/core/end2end/tests/filter_call_init_fails.cc test/core/end2end/tests/filter_causes_close.cc + test/core/end2end/tests/filter_context.cc test/core/end2end/tests/filter_latency.cc test/core/end2end/tests/filter_status_code.cc test/core/end2end/tests/graceful_server_shutdown.cc @@ -5710,7 +6049,6 @@ add_library(end2end_nosec_tests test/core/end2end/tests/max_connection_idle.cc test/core/end2end/tests/max_message_length.cc test/core/end2end/tests/negative_deadline.cc - test/core/end2end/tests/network_status_change.cc test/core/end2end/tests/no_error_on_hotpath.cc test/core/end2end/tests/no_logging.cc test/core/end2end/tests/no_op.cc @@ -5789,7 +6127,6 @@ target_link_libraries(end2end_nosec_tests ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -5820,7 +6157,6 @@ target_link_libraries(algorithm_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -5853,8 +6189,9 @@ target_include_directories(alloc_test target_link_libraries(alloc_test ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util gpr + grpc_test_util_unsecure + grpc_unsecure ) # avoid dependency on libstdc++ @@ -5888,7 +6225,6 @@ target_link_libraries(alpn_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -5921,8 +6257,9 @@ target_include_directories(arena_test target_link_libraries(arena_test ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util gpr + grpc_test_util_unsecure + grpc_unsecure ) # avoid dependency on libstdc++ @@ -5954,8 +6291,8 @@ target_include_directories(avl_test target_link_libraries(avl_test ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util gpr + grpc_test_util grpc ) @@ -5991,7 +6328,6 @@ target_link_libraries(bad_server_response_test test_tcp_server grpc_test_util grpc - gpr_test_util gpr ) @@ -6093,7 +6429,6 @@ target_link_libraries(buffer_list_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6129,7 +6464,6 @@ target_link_libraries(channel_create_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6195,7 +6529,6 @@ target_link_libraries(chttp2_hpack_encoder_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6230,7 +6563,6 @@ target_link_libraries(chttp2_stream_map_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6265,7 +6597,6 @@ target_link_libraries(chttp2_varint_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6277,6 +6608,42 @@ target_link_libraries(chttp2_varint_test endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + +add_executable(close_fd_test + test/core/bad_connection/close_fd_test.cc +) + + +target_include_directories(close_fd_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 ${_gRPC_NANOPB_INCLUDE_DIR} +) + +target_link_libraries(close_fd_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + grpc + gpr +) + + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(close_fd_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(close_fd_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + +endif() +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) add_executable(cmdline_test test/core/util/cmdline_test.cc @@ -6299,8 +6666,8 @@ target_include_directories(cmdline_test target_link_libraries(cmdline_test ${_gRPC_ALLTARGETS_LIBRARIES} gpr - gpr_test_util grpc_test_util + grpc ) # avoid dependency on libstdc++ @@ -6334,7 +6701,6 @@ target_link_libraries(combiner_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6369,7 +6735,6 @@ target_link_libraries(compression_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6404,7 +6769,6 @@ target_link_libraries(concurrent_connectivity_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6439,7 +6803,6 @@ target_link_libraries(connection_refused_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6474,7 +6837,6 @@ target_link_libraries(dns_resolver_connectivity_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6509,7 +6871,6 @@ target_link_libraries(dns_resolver_cooldown_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6544,7 +6905,6 @@ target_link_libraries(dns_resolver_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6580,7 +6940,6 @@ target_link_libraries(dualstack_socket_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6616,7 +6975,6 @@ target_link_libraries(endpoint_pair_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6651,7 +7009,6 @@ target_link_libraries(error_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6687,7 +7044,6 @@ target_link_libraries(ev_epollex_linux_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6723,7 +7079,6 @@ target_link_libraries(fake_resolver_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6758,8 +7113,8 @@ target_include_directories(fake_transport_security_test target_link_libraries(fake_transport_security_test ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util gpr + grpc_test_util grpc ) @@ -6796,7 +7151,6 @@ target_link_libraries(fd_conservation_posix_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6833,7 +7187,6 @@ target_link_libraries(fd_posix_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6869,7 +7222,6 @@ target_link_libraries(fling_client ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6904,7 +7256,6 @@ target_link_libraries(fling_server ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6940,7 +7291,6 @@ target_link_libraries(fling_stream_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -6977,7 +7327,6 @@ target_link_libraries(fling_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -7012,8 +7361,9 @@ target_include_directories(fork_test target_link_libraries(fork_test ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util gpr + grpc_test_util_unsecure + grpc_unsecure ) # avoid dependency on libstdc++ @@ -7049,7 +7399,6 @@ target_link_libraries(goaway_server_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -7083,8 +7432,9 @@ target_include_directories(gpr_cpu_test target_link_libraries(gpr_cpu_test ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util gpr + grpc_test_util_unsecure + grpc_unsecure ) # avoid dependency on libstdc++ @@ -7116,8 +7466,9 @@ target_include_directories(gpr_env_test target_link_libraries(gpr_env_test ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util gpr + grpc_test_util_unsecure + grpc_unsecure ) # avoid dependency on libstdc++ @@ -7149,8 +7500,9 @@ target_include_directories(gpr_host_port_test target_link_libraries(gpr_host_port_test ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util gpr + grpc_test_util_unsecure + grpc_unsecure ) # avoid dependency on libstdc++ @@ -7182,8 +7534,9 @@ target_include_directories(gpr_log_test target_link_libraries(gpr_log_test ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util gpr + grpc_test_util_unsecure + grpc_unsecure ) # avoid dependency on libstdc++ @@ -7215,8 +7568,9 @@ target_include_directories(gpr_manual_constructor_test target_link_libraries(gpr_manual_constructor_test ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util gpr + grpc_test_util_unsecure + grpc_unsecure ) # avoid dependency on libstdc++ @@ -7248,8 +7602,9 @@ target_include_directories(gpr_mpscq_test target_link_libraries(gpr_mpscq_test ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util gpr + grpc_test_util_unsecure + grpc_unsecure ) # avoid dependency on libstdc++ @@ -7281,8 +7636,9 @@ target_include_directories(gpr_spinlock_test target_link_libraries(gpr_spinlock_test ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util gpr + grpc_test_util_unsecure + grpc_unsecure ) # avoid dependency on libstdc++ @@ -7314,8 +7670,9 @@ target_include_directories(gpr_string_test target_link_libraries(gpr_string_test ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util gpr + grpc_test_util_unsecure + grpc_unsecure ) # avoid dependency on libstdc++ @@ -7347,8 +7704,9 @@ target_include_directories(gpr_sync_test target_link_libraries(gpr_sync_test ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util gpr + grpc_test_util_unsecure + grpc_unsecure ) # avoid dependency on libstdc++ @@ -7380,8 +7738,9 @@ target_include_directories(gpr_thd_test target_link_libraries(gpr_thd_test ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util gpr + grpc_test_util_unsecure + grpc_unsecure ) # avoid dependency on libstdc++ @@ -7413,8 +7772,9 @@ target_include_directories(gpr_time_test target_link_libraries(gpr_time_test ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util gpr + grpc_test_util_unsecure + grpc_unsecure ) # avoid dependency on libstdc++ @@ -7446,8 +7806,9 @@ target_include_directories(gpr_tls_test target_link_libraries(gpr_tls_test ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util gpr + grpc_test_util_unsecure + grpc_unsecure ) # avoid dependency on libstdc++ @@ -7479,8 +7840,9 @@ target_include_directories(gpr_useful_test target_link_libraries(gpr_useful_test ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util gpr + grpc_test_util_unsecure + grpc_unsecure ) # avoid dependency on libstdc++ @@ -7514,7 +7876,6 @@ target_link_libraries(grpc_auth_context_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -7549,7 +7910,6 @@ target_link_libraries(grpc_b64_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -7584,7 +7944,6 @@ target_link_libraries(grpc_byte_buffer_reader_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -7619,7 +7978,6 @@ target_link_libraries(grpc_channel_args_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -7654,7 +8012,6 @@ target_link_libraries(grpc_channel_stack_builder_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -7689,7 +8046,6 @@ target_link_libraries(grpc_channel_stack_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -7724,7 +8080,6 @@ target_link_libraries(grpc_completion_queue_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -7759,7 +8114,6 @@ target_link_libraries(grpc_completion_queue_threading_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -7827,7 +8181,6 @@ target_link_libraries(grpc_credentials_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -7862,7 +8215,6 @@ target_link_libraries(grpc_fetch_oauth2 ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -7897,7 +8249,6 @@ target_link_libraries(grpc_ipv6_loopback_available_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -7933,7 +8284,6 @@ target_link_libraries(grpc_json_token_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -7969,7 +8319,6 @@ target_link_libraries(grpc_jwt_verifier_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8036,7 +8385,6 @@ target_link_libraries(grpc_security_connector_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8071,7 +8419,6 @@ target_link_libraries(grpc_ssl_credentials_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8140,7 +8487,6 @@ target_link_libraries(handshake_client_ssl ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8179,7 +8525,6 @@ target_link_libraries(handshake_server_ssl ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8218,7 +8563,6 @@ target_link_libraries(handshake_server_with_readahead_handshaker ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8256,7 +8600,6 @@ target_link_libraries(handshake_verify_peer_options ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8325,7 +8668,6 @@ target_link_libraries(hpack_parser_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8360,7 +8702,6 @@ target_link_libraries(hpack_table_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8395,7 +8736,6 @@ target_link_libraries(http_parser_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8430,7 +8770,6 @@ target_link_libraries(httpcli_format_request_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8466,7 +8805,6 @@ target_link_libraries(httpcli_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8503,7 +8841,6 @@ target_link_libraries(httpscli_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8539,7 +8876,6 @@ target_link_libraries(init_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8574,7 +8910,6 @@ target_link_libraries(inproc_callback_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8609,7 +8944,6 @@ target_link_libraries(invalid_call_argument_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8644,7 +8978,6 @@ target_link_libraries(json_rewrite ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8679,7 +9012,6 @@ target_link_libraries(json_rewrite_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8714,7 +9046,6 @@ target_link_libraries(json_stream_error_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8749,7 +9080,6 @@ target_link_libraries(json_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8784,7 +9114,6 @@ target_link_libraries(lame_client_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8819,7 +9148,6 @@ target_link_libraries(load_file_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8854,7 +9182,6 @@ target_link_libraries(memory_usage_client ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8889,7 +9216,6 @@ target_link_libraries(memory_usage_server ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8925,7 +9251,6 @@ target_link_libraries(memory_usage_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8961,7 +9286,6 @@ target_link_libraries(message_compress_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -8996,7 +9320,6 @@ target_link_libraries(minimal_stack_is_minimal_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9031,7 +9354,6 @@ target_link_libraries(multiple_server_queues_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9064,8 +9386,9 @@ target_include_directories(murmur_hash_test target_link_libraries(murmur_hash_test ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util gpr + grpc_test_util_unsecure + grpc_unsecure ) # avoid dependency on libstdc++ @@ -9099,7 +9422,6 @@ target_link_libraries(no_server_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9134,7 +9456,6 @@ target_link_libraries(num_external_connectivity_watchers_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9169,7 +9490,6 @@ target_link_libraries(parse_address_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9181,6 +9501,42 @@ target_link_libraries(parse_address_test endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + +add_executable(parse_address_with_named_scope_id_test + test/core/client_channel/parse_address_with_named_scope_id_test.cc +) + + +target_include_directories(parse_address_with_named_scope_id_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 ${_gRPC_NANOPB_INCLUDE_DIR} +) + +target_link_libraries(parse_address_with_named_scope_id_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + grpc + gpr +) + + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(parse_address_with_named_scope_id_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(parse_address_with_named_scope_id_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + +endif() +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) add_executable(percent_encoding_test test/core/slice/percent_encoding_test.cc @@ -9204,7 +9560,6 @@ target_link_libraries(percent_encoding_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9218,12 +9573,12 @@ endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) -add_executable(resolve_address_posix_test +add_executable(resolve_address_using_ares_resolver_posix_test test/core/iomgr/resolve_address_posix_test.cc ) -target_include_directories(resolve_address_posix_test +target_include_directories(resolve_address_using_ares_resolver_posix_test PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include PRIVATE ${_gRPC_SSL_INCLUDE_DIR} @@ -9236,18 +9591,17 @@ target_include_directories(resolve_address_posix_test PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} ) -target_link_libraries(resolve_address_posix_test +target_link_libraries(resolve_address_using_ares_resolver_posix_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) # avoid dependency on libstdc++ if (_gRPC_CORE_NOSTDCXX_FLAGS) - set_target_properties(resolve_address_posix_test PROPERTIES LINKER_LANGUAGE C) - target_compile_options(resolve_address_posix_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + set_target_properties(resolve_address_using_ares_resolver_posix_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(resolve_address_using_ares_resolver_posix_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) endif() endif() @@ -9276,7 +9630,6 @@ target_link_libraries(resolve_address_using_ares_resolver_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9288,6 +9641,42 @@ target_link_libraries(resolve_address_using_ares_resolver_test endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + +add_executable(resolve_address_using_native_resolver_posix_test + test/core/iomgr/resolve_address_posix_test.cc +) + + +target_include_directories(resolve_address_using_native_resolver_posix_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 ${_gRPC_NANOPB_INCLUDE_DIR} +) + +target_link_libraries(resolve_address_using_native_resolver_posix_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + grpc + gpr +) + + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(resolve_address_using_native_resolver_posix_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(resolve_address_using_native_resolver_posix_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + +endif() +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) add_executable(resolve_address_using_native_resolver_test test/core/iomgr/resolve_address_test.cc @@ -9311,7 +9700,6 @@ target_link_libraries(resolve_address_using_native_resolver_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9346,7 +9734,6 @@ target_link_libraries(resource_quota_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9381,7 +9768,6 @@ target_link_libraries(secure_channel_create_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9416,7 +9802,6 @@ target_link_libraries(secure_endpoint_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9451,7 +9836,6 @@ target_link_libraries(sequential_connectivity_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9486,7 +9870,6 @@ target_link_libraries(server_chttp2_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9521,7 +9904,6 @@ target_link_libraries(server_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9556,7 +9938,6 @@ target_link_libraries(slice_buffer_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9591,7 +9972,6 @@ target_link_libraries(slice_string_helpers_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9626,7 +10006,6 @@ target_link_libraries(slice_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9661,7 +10040,6 @@ target_link_libraries(sockaddr_resolver_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9696,7 +10074,6 @@ target_link_libraries(sockaddr_utils_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9732,7 +10109,6 @@ target_link_libraries(socket_utils_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9768,8 +10144,8 @@ target_include_directories(ssl_transport_security_test target_link_libraries(ssl_transport_security_test ${_gRPC_ALLTARGETS_LIBRARIES} - gpr_test_util gpr + grpc_test_util grpc ) @@ -9805,7 +10181,6 @@ target_link_libraries(status_conversion_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9840,7 +10215,6 @@ target_link_libraries(stream_compression_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9875,7 +10249,6 @@ target_link_libraries(stream_owned_slice_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9911,7 +10284,6 @@ target_link_libraries(tcp_client_posix_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9947,7 +10319,6 @@ target_link_libraries(tcp_client_uv_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -9983,7 +10354,6 @@ target_link_libraries(tcp_posix_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -10020,7 +10390,6 @@ target_link_libraries(tcp_server_posix_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -10056,7 +10425,6 @@ target_link_libraries(tcp_server_uv_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -10091,7 +10459,6 @@ target_link_libraries(time_averaged_stats_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -10126,7 +10493,6 @@ target_link_libraries(timeout_encoding_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -10161,7 +10527,6 @@ target_link_libraries(timer_heap_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -10196,7 +10561,6 @@ target_link_libraries(timer_list_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -10231,7 +10595,6 @@ target_link_libraries(transport_connectivity_state_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -10266,7 +10629,6 @@ target_link_libraries(transport_metadata_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -10302,7 +10664,6 @@ target_link_libraries(transport_security_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -10339,7 +10700,6 @@ target_link_libraries(udp_server_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -10375,7 +10735,6 @@ target_link_libraries(uri_parser_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -10387,43 +10746,6 @@ target_link_libraries(uri_parser_test endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) -if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) - -add_executable(wakeup_fd_cv_test - test/core/iomgr/wakeup_fd_cv_test.cc -) - - -target_include_directories(wakeup_fd_cv_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 ${_gRPC_NANOPB_INCLUDE_DIR} -) - -target_link_libraries(wakeup_fd_cv_test - ${_gRPC_ALLTARGETS_LIBRARIES} - grpc_test_util - grpc - gpr_test_util - gpr -) - - # avoid dependency on libstdc++ - if (_gRPC_CORE_NOSTDCXX_FLAGS) - set_target_properties(wakeup_fd_cv_test PROPERTIES LINKER_LANGUAGE C) - target_compile_options(wakeup_fd_cv_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) - endif() - -endif() -endif (gRPC_BUILD_TESTS) -if (gRPC_BUILD_TESTS) add_executable(alarm_test test/cpp/common/alarm_test.cc @@ -10457,7 +10779,6 @@ target_link_libraries(alarm_test grpc_test_util_unsecure grpc++_unsecure grpc_unsecure - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -10533,8 +10854,8 @@ target_link_libraries(alts_crypt_test ${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES} alts_test_util - gpr_test_util gpr + grpc_test_util grpc ${_gRPC_GFLAGS_LIBRARIES} ) @@ -10993,7 +11314,6 @@ target_link_libraries(async_end2end_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -11034,7 +11354,6 @@ target_link_libraries(auth_property_iterator_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -11073,7 +11392,6 @@ target_link_libraries(backoff_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -11114,7 +11432,6 @@ target_link_libraries(bdp_estimator_test grpc++ grpc_test_util grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -11124,6 +11441,51 @@ endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) +add_executable(bm_alarm + test/cpp/microbenchmarks/bm_alarm.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + + +target_include_directories(bm_alarm + 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 ${_gRPC_NANOPB_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(bm_alarm + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_benchmark + ${_gRPC_BENCHMARK_LIBRARIES} + grpc++_test_util_unsecure + grpc_test_util_unsecure + grpc++_unsecure + grpc_unsecure + gpr + grpc++_test_config + ${_gRPC_GFLAGS_LIBRARIES} +) + + +endif() +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + add_executable(bm_arena test/cpp/microbenchmarks/bm_arena.cc third_party/googletest/googletest/src/gtest-all.cc @@ -11158,7 +11520,51 @@ target_link_libraries(bm_arena grpc_test_util_unsecure grpc++_unsecure grpc_unsecure - gpr_test_util + gpr + grpc++_test_config + ${_gRPC_GFLAGS_LIBRARIES} +) + + +endif() +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + +add_executable(bm_byte_buffer + test/cpp/microbenchmarks/bm_byte_buffer.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + + +target_include_directories(bm_byte_buffer + 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 ${_gRPC_NANOPB_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(bm_byte_buffer + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_benchmark + ${_gRPC_BENCHMARK_LIBRARIES} + grpc++_test_util_unsecure + grpc_test_util_unsecure + grpc++_unsecure + grpc_unsecure gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -11204,13 +11610,104 @@ target_link_libraries(bm_call_create grpc_test_util_unsecure grpc++_unsecure grpc_unsecure - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} ) +endif() +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + +add_executable(bm_callback_streaming_ping_pong + test/cpp/microbenchmarks/bm_callback_streaming_ping_pong.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + + +target_include_directories(bm_callback_streaming_ping_pong + 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 ${_gRPC_NANOPB_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(bm_callback_streaming_ping_pong + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_benchmark + ${_gRPC_BENCHMARK_LIBRARIES} + grpc++_test_util_unsecure + grpc_test_util_unsecure + grpc++_unsecure + grpc_unsecure + gpr + grpc++_test_config + bm_callback_test_service_impl + ${_gRPC_GFLAGS_LIBRARIES} +) + + +endif() +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + +add_executable(bm_callback_unary_ping_pong + test/cpp/microbenchmarks/bm_callback_unary_ping_pong.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + + +target_include_directories(bm_callback_unary_ping_pong + 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 ${_gRPC_NANOPB_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(bm_callback_unary_ping_pong + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_benchmark + ${_gRPC_BENCHMARK_LIBRARIES} + grpc++_test_util_unsecure + grpc_test_util_unsecure + grpc++_unsecure + grpc_unsecure + gpr + grpc++_test_config + bm_callback_test_service_impl + ${_gRPC_GFLAGS_LIBRARIES} +) + + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -11250,7 +11747,6 @@ target_link_libraries(bm_channel grpc_test_util_unsecure grpc++_unsecure grpc_unsecure - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -11296,7 +11792,6 @@ target_link_libraries(bm_chttp2_hpack grpc_test_util_unsecure grpc++_unsecure grpc_unsecure - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -11342,7 +11837,6 @@ target_link_libraries(bm_chttp2_transport grpc_test_util_unsecure grpc++_unsecure grpc_unsecure - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -11388,7 +11882,6 @@ target_link_libraries(bm_closure grpc_test_util_unsecure grpc++_unsecure grpc_unsecure - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -11434,7 +11927,6 @@ target_link_libraries(bm_cq grpc_test_util_unsecure grpc++_unsecure grpc_unsecure - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -11480,7 +11972,6 @@ target_link_libraries(bm_cq_multiple_threads grpc_test_util_unsecure grpc++_unsecure grpc_unsecure - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -11526,7 +12017,6 @@ target_link_libraries(bm_error grpc_test_util_unsecure grpc++_unsecure grpc_unsecure - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -11572,7 +12062,6 @@ target_link_libraries(bm_fullstack_streaming_ping_pong grpc_test_util_unsecure grpc++_unsecure grpc_unsecure - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -11618,7 +12107,6 @@ target_link_libraries(bm_fullstack_streaming_pump grpc_test_util_unsecure grpc++_unsecure grpc_unsecure - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -11664,7 +12152,6 @@ target_link_libraries(bm_fullstack_trickle grpc_test_util_unsecure grpc++_unsecure grpc_unsecure - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -11710,7 +12197,6 @@ target_link_libraries(bm_fullstack_unary_ping_pong grpc_test_util_unsecure grpc++_unsecure grpc_unsecure - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -11756,7 +12242,6 @@ target_link_libraries(bm_metadata grpc_test_util_unsecure grpc++_unsecure grpc_unsecure - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -11802,7 +12287,51 @@ target_link_libraries(bm_pollset grpc_test_util_unsecure grpc++_unsecure grpc_unsecure - gpr_test_util + gpr + grpc++_test_config + ${_gRPC_GFLAGS_LIBRARIES} +) + + +endif() +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + +add_executable(bm_timer + test/cpp/microbenchmarks/bm_timer.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + + +target_include_directories(bm_timer + 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 ${_gRPC_NANOPB_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(bm_timer + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_benchmark + ${_gRPC_BENCHMARK_LIBRARIES} + grpc++_test_util_unsecure + grpc_test_util_unsecure + grpc++_unsecure + grpc_unsecure gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -11843,7 +12372,6 @@ target_link_libraries(byte_stream_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -11967,7 +12495,6 @@ target_link_libraries(channel_trace_test grpc++_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -12008,7 +12535,6 @@ target_link_libraries(channelz_registry_test grpc++_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -12057,7 +12583,6 @@ target_link_libraries(channelz_service_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -12105,7 +12630,6 @@ target_link_libraries(channelz_test grpc++_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -12218,7 +12742,6 @@ target_link_libraries(chttp2_settings_timeout_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -12260,7 +12783,6 @@ target_link_libraries(cli_call_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -12271,6 +12793,7 @@ if (gRPC_BUILD_TESTS) add_executable(client_callback_end2end_test test/cpp/end2end/client_callback_end2end_test.cc + test/cpp/end2end/interceptors_util.cc third_party/googletest/googletest/src/gtest-all.cc third_party/googletest/googlemock/src/gmock-all.cc ) @@ -12301,7 +12824,6 @@ target_link_libraries(client_callback_end2end_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -12349,7 +12871,6 @@ target_link_libraries(client_channel_stress_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -12391,7 +12912,6 @@ target_link_libraries(client_crash_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -12429,11 +12949,11 @@ target_include_directories(client_crash_test_server target_link_libraries(client_crash_test_server ${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test_config grpc++_test_util grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -12475,7 +12995,6 @@ target_link_libraries(client_interceptors_end2end_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -12516,7 +13035,6 @@ target_link_libraries(client_lb_end2end_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -12698,6 +13216,44 @@ target_link_libraries(codegen_test_minimal ) +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) + +add_executable(context_list_test + test/core/transport/chttp2/context_list_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + + +target_include_directories(context_list_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 ${_gRPC_NANOPB_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(context_list_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + grpc + gpr + ${_gRPC_GFLAGS_LIBRARIES} +) + + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -12770,7 +13326,6 @@ target_link_libraries(cxx_byte_buffer_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -12810,7 +13365,6 @@ target_link_libraries(cxx_slice_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -12887,7 +13441,6 @@ target_link_libraries(cxx_time_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -12929,7 +13482,6 @@ target_link_libraries(end2end_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -13014,7 +13566,6 @@ target_link_libraries(exception_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -13055,7 +13606,6 @@ target_link_libraries(filter_end2end_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -13096,12 +13646,85 @@ target_link_libraries(generic_end2end_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) + +add_executable(global_config_env_test + test/core/gprpp/global_config_env_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + + +target_include_directories(global_config_env_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 ${_gRPC_NANOPB_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(global_config_env_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + gpr + grpc_test_util_unsecure + ${_gRPC_GFLAGS_LIBRARIES} +) + + +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) + +add_executable(global_config_test + test/core/gprpp/global_config_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + + +target_include_directories(global_config_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 ${_gRPC_NANOPB_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(global_config_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + gpr + grpc_test_util_unsecure + ${_gRPC_GFLAGS_LIBRARIES} +) + + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -13140,6 +13763,7 @@ target_include_directories(golden_file_test target_link_libraries(golden_file_test ${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test_config grpc++ grpc gpr @@ -13225,6 +13849,45 @@ target_link_libraries(grpc_cli ) +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) + +add_executable(grpc_core_map_test + test/core/gprpp/map_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + + +target_include_directories(grpc_core_map_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 ${_gRPC_NANOPB_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(grpc_core_map_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + grpc++ + grpc + gpr + ${_gRPC_GFLAGS_LIBRARIES} +) + + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_CODEGEN) @@ -13336,7 +13999,6 @@ target_link_libraries(grpc_linux_system_roots_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -13589,7 +14251,6 @@ target_link_libraries(grpc_tool_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -13683,7 +14344,6 @@ target_link_libraries(grpclb_end2end_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -13723,7 +14383,6 @@ target_link_libraries(h2_ssl_cert_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -13763,7 +14422,6 @@ target_link_libraries(h2_ssl_session_reuse_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -13804,7 +14462,6 @@ target_link_libraries(health_service_end2end_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -13887,7 +14544,6 @@ target_link_libraries(hybrid_end2end_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -13927,7 +14583,6 @@ target_link_libraries(inlined_vector_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -13971,7 +14626,6 @@ target_link_libraries(inproc_sync_unary_ping_pong_test grpc_test_util grpc++ grpc - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -14016,7 +14670,6 @@ target_link_libraries(interop_client grpc_test_util grpc++ grpc - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -14062,7 +14715,6 @@ target_link_libraries(interop_server grpc_test_util grpc++ grpc - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -14104,7 +14756,6 @@ target_link_libraries(interop_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -14148,7 +14799,6 @@ target_link_libraries(json_run_localhost grpc_test_util grpc++ grpc - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -14190,7 +14840,46 @@ target_link_libraries(memory_test grpc_test_util grpc++ grpc - gpr_test_util + gpr + ${_gRPC_GFLAGS_LIBRARIES} +) + + +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) + +add_executable(message_allocator_end2end_test + test/cpp/end2end/message_allocator_end2end_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + + +target_include_directories(message_allocator_end2end_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 ${_gRPC_NANOPB_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(message_allocator_end2end_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test_util + grpc_test_util + grpc++ + grpc gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -14277,7 +14966,6 @@ target_link_libraries(mock_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -14318,7 +15006,6 @@ target_link_libraries(nonblocking_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -14360,6 +15047,45 @@ target_link_libraries(noop-benchmark ) +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) + +add_executable(optional_test + test/core/gprpp/optional_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + + +target_include_directories(optional_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 ${_gRPC_NANOPB_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(optional_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + grpc++ + grpc + gpr + ${_gRPC_GFLAGS_LIBRARIES} +) + + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -14394,7 +15120,6 @@ target_link_libraries(orphanable_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -14437,7 +15162,6 @@ target_link_libraries(proto_server_reflection_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -14517,7 +15241,6 @@ target_link_libraries(qps_interarrival_test grpc_test_util grpc++ grpc - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -14562,7 +15285,6 @@ target_link_libraries(qps_json_driver grpc_test_util grpc++ grpc - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -14607,7 +15329,6 @@ target_link_libraries(qps_openloop_test grpc_test_util grpc++ grpc - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -14652,7 +15373,6 @@ target_link_libraries(qps_worker grpc_test_util grpc++ grpc - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -14694,7 +15414,6 @@ target_link_libraries(raw_end2end_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -14756,7 +15475,6 @@ target_link_libraries(reconnect_interop_client grpc_test_util grpc++ grpc - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -14821,7 +15539,6 @@ target_link_libraries(reconnect_interop_server grpc_test_util grpc++ grpc - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -14862,7 +15579,6 @@ target_link_libraries(ref_counted_ptr_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -14902,7 +15618,6 @@ target_link_libraries(ref_counted_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -14941,7 +15656,6 @@ target_link_libraries(retry_throttle_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -14982,7 +15696,6 @@ target_link_libraries(secure_auth_context_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -15026,7 +15739,6 @@ target_link_libraries(secure_sync_unary_ping_pong_test grpc_test_util grpc++ grpc - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -15069,7 +15781,6 @@ target_link_libraries(server_builder_plugin_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -15122,7 +15833,6 @@ target_link_libraries(server_builder_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc++_test_util_unsecure grpc_test_util_unsecure - gpr_test_util grpc++_unsecure grpc_unsecure gpr @@ -15178,7 +15888,6 @@ target_link_libraries(server_builder_with_socket_mutator_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc++_test_util_unsecure grpc_test_util_unsecure - gpr_test_util grpc++_unsecure grpc_unsecure gpr @@ -15221,7 +15930,6 @@ target_link_libraries(server_context_test_spouse_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -15263,7 +15971,6 @@ target_link_libraries(server_crash_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -15301,11 +16008,11 @@ target_include_directories(server_crash_test_client target_link_libraries(server_crash_test_client ${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test_config grpc++_test_util grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -15346,7 +16053,6 @@ target_link_libraries(server_early_return_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -15388,7 +16094,6 @@ target_link_libraries(server_interceptors_end2end_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -15441,7 +16146,6 @@ target_link_libraries(server_request_call_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc++_test_util_unsecure grpc_test_util_unsecure - gpr_test_util grpc++_unsecure grpc_unsecure gpr @@ -15449,6 +16153,85 @@ target_link_libraries(server_request_call_test ) +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) + +add_executable(service_config_end2end_test + test/cpp/end2end/service_config_end2end_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + + +target_include_directories(service_config_end2end_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 ${_gRPC_NANOPB_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(service_config_end2end_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test_util + grpc_test_util + grpc++ + grpc + gpr + ${_gRPC_GFLAGS_LIBRARIES} +) + + +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) + +add_executable(service_config_test + test/core/client_channel/service_config_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + + +target_include_directories(service_config_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 ${_gRPC_NANOPB_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(service_config_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + grpc++ + grpc + gpr + ${_gRPC_GFLAGS_LIBRARIES} +) + + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -15484,7 +16267,6 @@ target_link_libraries(shutdown_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -15523,7 +16305,6 @@ target_link_libraries(slice_hash_table_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -15562,7 +16343,6 @@ target_link_libraries(slice_weak_hash_table_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -15602,7 +16382,6 @@ target_link_libraries(stats_test grpc++_test_util grpc_test_util grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -15716,7 +16495,6 @@ target_link_libraries(streaming_throughput_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -15789,7 +16567,6 @@ target_link_libraries(stress_test grpc_test_util grpc++ grpc - gpr_test_util gpr grpc++_test_config ${_gRPC_GFLAGS_LIBRARIES} @@ -15870,12 +16647,53 @@ target_link_libraries(thread_stress_test grpc_test_util_unsecure grpc++_unsecure grpc_unsecure - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + +add_executable(time_change_test + test/cpp/end2end/time_change_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + + +target_include_directories(time_change_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 ${_gRPC_NANOPB_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(time_change_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test_util + grpc_test_util + grpc++ + grpc + gpr + ${_gRPC_GFLAGS_LIBRARIES} +) + + +endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -15911,7 +16729,6 @@ target_link_libraries(transport_pid_controller_test grpc++ grpc_test_util grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -15991,7 +16808,6 @@ target_link_libraries(writes_per_rpc_test grpc_test_util grpc++ grpc - gpr_test_util gpr ${_gRPC_GFLAGS_LIBRARIES} ) @@ -16001,6 +16817,53 @@ endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) +add_executable(xds_end2end_test + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lb/v1/load_balancer.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lb/v1/load_balancer.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lb/v1/load_balancer.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lb/v1/load_balancer.grpc.pb.h + test/cpp/end2end/xds_end2end_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/lb/v1/load_balancer.proto +) + +target_include_directories(xds_end2end_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 ${_gRPC_NANOPB_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(xds_end2end_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test_util + grpc_test_util + grpc++ + grpc + gpr + ${_gRPC_GFLAGS_LIBRARIES} +) + + +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) + add_executable(public_headers_must_be_c89 test/core/surface/public_headers_must_be_c89.c ) @@ -16127,7 +16990,6 @@ target_link_libraries(badreq_bad_client_test bad_client_test grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -16164,7 +17026,6 @@ target_link_libraries(connection_prefix_bad_client_test bad_client_test grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -16201,7 +17062,6 @@ target_link_libraries(duplicate_header_bad_client_test bad_client_test grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -16238,7 +17098,6 @@ target_link_libraries(head_of_line_blocking_bad_client_test bad_client_test grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -16275,7 +17134,6 @@ target_link_libraries(headers_bad_client_test bad_client_test grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -16312,7 +17170,6 @@ target_link_libraries(initial_settings_frame_bad_client_test bad_client_test grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -16349,7 +17206,6 @@ target_link_libraries(large_metadata_bad_client_test bad_client_test grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -16386,7 +17242,6 @@ target_link_libraries(server_registered_method_bad_client_test bad_client_test grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -16423,7 +17278,6 @@ target_link_libraries(simple_request_bad_client_test bad_client_test grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -16460,7 +17314,6 @@ target_link_libraries(unknown_frame_bad_client_test bad_client_test grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -16497,7 +17350,6 @@ target_link_libraries(window_overflow_bad_client_test bad_client_test grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -16534,7 +17386,6 @@ target_link_libraries(bad_ssl_cert_server bad_ssl_test_server grpc_test_util grpc - gpr_test_util gpr ) @@ -16571,7 +17422,6 @@ target_link_libraries(bad_ssl_cert_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -16608,7 +17458,6 @@ target_link_libraries(h2_census_test end2end_tests grpc_test_util grpc - gpr_test_util gpr ) @@ -16644,7 +17493,6 @@ target_link_libraries(h2_compress_test end2end_tests grpc_test_util grpc - gpr_test_util gpr ) @@ -16680,7 +17528,6 @@ target_link_libraries(h2_fakesec_test end2end_tests grpc_test_util grpc - gpr_test_util gpr ) @@ -16717,7 +17564,6 @@ target_link_libraries(h2_fd_test end2end_tests grpc_test_util grpc - gpr_test_util gpr ) @@ -16754,7 +17600,6 @@ target_link_libraries(h2_full_test end2end_tests grpc_test_util grpc - gpr_test_util gpr ) @@ -16791,7 +17636,6 @@ target_link_libraries(h2_full+pipe_test end2end_tests grpc_test_util grpc - gpr_test_util gpr ) @@ -16828,7 +17672,6 @@ target_link_libraries(h2_full+trace_test end2end_tests grpc_test_util grpc - gpr_test_util gpr ) @@ -16864,7 +17707,6 @@ target_link_libraries(h2_full+workarounds_test end2end_tests grpc_test_util grpc - gpr_test_util gpr ) @@ -16900,7 +17742,6 @@ target_link_libraries(h2_http_proxy_test end2end_tests grpc_test_util grpc - gpr_test_util gpr ) @@ -16914,12 +17755,12 @@ endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) -add_executable(h2_local_test - test/core/end2end/fixtures/h2_local.cc +add_executable(h2_local_ipv4_test + test/core/end2end/fixtures/h2_local_ipv4.cc ) -target_include_directories(h2_local_test +target_include_directories(h2_local_ipv4_test PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include PRIVATE ${_gRPC_SSL_INCLUDE_DIR} @@ -16932,19 +17773,92 @@ target_include_directories(h2_local_test PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} ) -target_link_libraries(h2_local_test +target_link_libraries(h2_local_ipv4_test ${_gRPC_ALLTARGETS_LIBRARIES} end2end_tests grpc_test_util grpc - gpr_test_util gpr ) # avoid dependency on libstdc++ if (_gRPC_CORE_NOSTDCXX_FLAGS) - set_target_properties(h2_local_test PROPERTIES LINKER_LANGUAGE C) - target_compile_options(h2_local_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + set_target_properties(h2_local_ipv4_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(h2_local_ipv4_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + +endif() +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + +add_executable(h2_local_ipv6_test + test/core/end2end/fixtures/h2_local_ipv6.cc +) + + +target_include_directories(h2_local_ipv6_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 ${_gRPC_NANOPB_INCLUDE_DIR} +) + +target_link_libraries(h2_local_ipv6_test + ${_gRPC_ALLTARGETS_LIBRARIES} + end2end_tests + grpc_test_util + grpc + gpr +) + + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(h2_local_ipv6_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(h2_local_ipv6_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + +endif() +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + +add_executable(h2_local_uds_test + test/core/end2end/fixtures/h2_local_uds.cc +) + + +target_include_directories(h2_local_uds_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 ${_gRPC_NANOPB_INCLUDE_DIR} +) + +target_link_libraries(h2_local_uds_test + ${_gRPC_ALLTARGETS_LIBRARIES} + end2end_tests + grpc_test_util + grpc + gpr +) + + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(h2_local_uds_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(h2_local_uds_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) endif() endif() @@ -16974,7 +17888,6 @@ target_link_libraries(h2_oauth2_test end2end_tests grpc_test_util grpc - gpr_test_util gpr ) @@ -17010,7 +17923,6 @@ target_link_libraries(h2_proxy_test end2end_tests grpc_test_util grpc - gpr_test_util gpr ) @@ -17046,7 +17958,6 @@ target_link_libraries(h2_sockpair_test end2end_tests grpc_test_util grpc - gpr_test_util gpr ) @@ -17082,7 +17993,6 @@ target_link_libraries(h2_sockpair+trace_test end2end_tests grpc_test_util grpc - gpr_test_util gpr ) @@ -17118,7 +18028,6 @@ target_link_libraries(h2_sockpair_1byte_test end2end_tests grpc_test_util grpc - gpr_test_util gpr ) @@ -17131,6 +18040,41 @@ target_link_libraries(h2_sockpair_1byte_test endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) +add_executable(h2_spiffe_test + test/core/end2end/fixtures/h2_spiffe.cc +) + + +target_include_directories(h2_spiffe_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 ${_gRPC_NANOPB_INCLUDE_DIR} +) + +target_link_libraries(h2_spiffe_test + ${_gRPC_ALLTARGETS_LIBRARIES} + end2end_tests + grpc_test_util + grpc + gpr +) + + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(h2_spiffe_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(h2_spiffe_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) + add_executable(h2_ssl_test test/core/end2end/fixtures/h2_ssl.cc ) @@ -17154,7 +18098,6 @@ target_link_libraries(h2_ssl_test end2end_tests grpc_test_util grpc - gpr_test_util gpr ) @@ -17167,6 +18110,41 @@ target_link_libraries(h2_ssl_test endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) +add_executable(h2_ssl_cred_reload_test + test/core/end2end/fixtures/h2_ssl_cred_reload.cc +) + + +target_include_directories(h2_ssl_cred_reload_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 ${_gRPC_NANOPB_INCLUDE_DIR} +) + +target_link_libraries(h2_ssl_cred_reload_test + ${_gRPC_ALLTARGETS_LIBRARIES} + end2end_tests + grpc_test_util + grpc + gpr +) + + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(h2_ssl_cred_reload_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(h2_ssl_cred_reload_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) + add_executable(h2_ssl_proxy_test test/core/end2end/fixtures/h2_ssl_proxy.cc ) @@ -17190,7 +18168,6 @@ target_link_libraries(h2_ssl_proxy_test end2end_tests grpc_test_util grpc - gpr_test_util gpr ) @@ -17227,7 +18204,6 @@ target_link_libraries(h2_uds_test end2end_tests grpc_test_util grpc - gpr_test_util gpr ) @@ -17264,7 +18240,6 @@ target_link_libraries(inproc_test end2end_tests grpc_test_util grpc - gpr_test_util gpr ) @@ -17300,7 +18275,6 @@ target_link_libraries(h2_census_nosec_test end2end_nosec_tests grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -17336,7 +18310,6 @@ target_link_libraries(h2_compress_nosec_test end2end_nosec_tests grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -17373,7 +18346,6 @@ target_link_libraries(h2_fd_nosec_test end2end_nosec_tests grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -17410,7 +18382,6 @@ target_link_libraries(h2_full_nosec_test end2end_nosec_tests grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -17447,7 +18418,6 @@ target_link_libraries(h2_full+pipe_nosec_test end2end_nosec_tests grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -17484,7 +18454,6 @@ target_link_libraries(h2_full+trace_nosec_test end2end_nosec_tests grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -17520,7 +18489,6 @@ target_link_libraries(h2_full+workarounds_nosec_test end2end_nosec_tests grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -17556,7 +18524,6 @@ target_link_libraries(h2_http_proxy_nosec_test end2end_nosec_tests grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -17592,7 +18559,6 @@ target_link_libraries(h2_proxy_nosec_test end2end_nosec_tests grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -17628,7 +18594,6 @@ target_link_libraries(h2_sockpair_nosec_test end2end_nosec_tests grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -17664,7 +18629,6 @@ target_link_libraries(h2_sockpair+trace_nosec_test end2end_nosec_tests grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -17700,7 +18664,6 @@ target_link_libraries(h2_sockpair_1byte_nosec_test end2end_nosec_tests grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -17737,7 +18700,6 @@ target_link_libraries(h2_uds_nosec_test end2end_nosec_tests grpc_test_util_unsecure grpc_unsecure - gpr_test_util gpr ) @@ -17779,9 +18741,9 @@ target_include_directories(resolver_component_test_unsecure target_link_libraries(resolver_component_test_unsecure ${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES} + dns_test_util grpc++_test_util_unsecure grpc_test_util_unsecure - gpr_test_util grpc++_unsecure grpc_unsecure gpr @@ -17821,9 +18783,9 @@ target_include_directories(resolver_component_test target_link_libraries(resolver_component_test ${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES} + dns_test_util grpc++_test_util grpc_test_util - gpr_test_util grpc++ grpc gpr @@ -17866,7 +18828,6 @@ target_link_libraries(resolver_component_tests_runner_invoker_unsecure ${_gRPC_ALLTARGETS_LIBRARIES} grpc++_test_util grpc_test_util - gpr_test_util grpc++ grpc gpr @@ -17910,7 +18871,6 @@ target_link_libraries(resolver_component_tests_runner_invoker ${_gRPC_ALLTARGETS_LIBRARIES} grpc++_test_util grpc_test_util - gpr_test_util grpc++ grpc gpr @@ -17953,7 +18913,6 @@ target_link_libraries(address_sorting_test_unsecure ${_gRPC_ALLTARGETS_LIBRARIES} grpc++_test_util_unsecure grpc_test_util_unsecure - gpr_test_util grpc++_unsecure grpc_unsecure gpr @@ -17995,7 +18954,6 @@ target_link_libraries(address_sorting_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc++_test_util grpc_test_util - gpr_test_util grpc++ grpc gpr @@ -18035,9 +18993,9 @@ target_include_directories(cancel_ares_query_test target_link_libraries(cancel_ares_query_test ${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES} + dns_test_util grpc++_test_util grpc_test_util - gpr_test_util grpc++ grpc gpr @@ -18072,7 +19030,6 @@ target_link_libraries(alts_credentials_fuzzer_one_entry ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -18108,7 +19065,6 @@ target_link_libraries(api_fuzzer_one_entry ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -18144,7 +19100,6 @@ target_link_libraries(client_fuzzer_one_entry ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -18180,7 +19135,6 @@ target_link_libraries(hpack_parser_fuzzer_test_one_entry ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -18216,7 +19170,6 @@ target_link_libraries(http_request_fuzzer_test_one_entry ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -18252,7 +19205,6 @@ target_link_libraries(http_response_fuzzer_test_one_entry ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -18288,7 +19240,6 @@ target_link_libraries(json_fuzzer_test_one_entry ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -18324,7 +19275,6 @@ target_link_libraries(nanopb_fuzzer_response_test_one_entry ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -18360,7 +19310,6 @@ target_link_libraries(nanopb_fuzzer_serverlist_test_one_entry ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -18396,7 +19345,6 @@ target_link_libraries(percent_decode_fuzzer_one_entry ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -18432,7 +19380,6 @@ target_link_libraries(percent_encode_fuzzer_one_entry ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -18468,7 +19415,6 @@ target_link_libraries(server_fuzzer_one_entry ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -18504,7 +19450,6 @@ target_link_libraries(ssl_server_fuzzer_one_entry ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) @@ -18540,7 +19485,6 @@ target_link_libraries(uri_fuzzer_test_one_entry ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - gpr_test_util gpr ) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e8582d9af5e..862a9019cce 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -81,7 +81,7 @@ How to get your contributions merged smoothly and quickly. copyright holder for the contribution (yourself, if you are signing the individual CLA, or your company, for corporate CLAs) in the same PR as your contribution. This needs to be done only once, for each company, or - individual. + individual. Please keep this file in alphabetical order. - Maintain **clean commit history** and use **meaningful commit messages**. PRs with messy commit history are difficult to review and won't be merged. @@ -110,5 +110,16 @@ How to get your contributions merged smoothly and quickly. - Exceptions to the rules can be made if there's a compelling reason for doing so. +## Obtaining Commit Access +We grant Commit Access to contributors based on the following criteria: +* Sustained contribution to the gRPC project. +* Deep understanding of the areas contributed to, and good consideration of various reliability, usability and performance tradeoffs. +* Contributions demonstrate that obtaining Commit Access will significantly reduce friction for the contributors or others. +In addition to submitting PRs, a Contributor with Commit Access can: +* Review PRs and merge once other checks and criteria pass. +* Triage bugs and PRs and assign appropriate labels and reviewers. + +### Obtaining Commit Access without Code Contributions +The [gRPC organization](https://github.com/grpc) is comprised of multiple repositories and commit access is usually restricted to one or more of these repositories. Some repositories such as the [grpc.github.io](https://github.com/grpc/grpc.github.io/) do not have code, but the same principle of sustained, high quality contributions, with a good understanding of the fundamentals, apply. diff --git a/Makefile b/Makefile index 12603f1fc8b..26883daedec 100644 --- a/Makefile +++ b/Makefile @@ -404,6 +404,28 @@ LIBS = m pthread ws2_32 LDFLAGS += -pthread endif +# If we are installing into a non-default prefix, both +# the libraries we build, and the apps users build, +# need to know how to find the libraries they depend on. +# There is much gnashing of teeth about this subject. +# It's tricky to do that without editing images during install, +# as you don't want tests during build to find previously installed and +# now stale libraries, etc. +ifeq ($(SYSTEM),Linux) +ifneq ($(prefix),/usr) +# Linux best practice for rpath on installed files is probably: +# 1) .pc file provides -Wl,-rpath,$(prefix)/lib +# 2) binaries we install into $(prefix)/bin use -Wl,-rpath,$ORIGIN/../lib +# 3) libraries we install into $(prefix)/lib use -Wl,-rpath,$ORIGIN +# cf. https://www.akkadia.org/drepper/dsohowto.pdf +# Doing all of that right is hard, but using -Wl,-rpath,$ORIGIN is always +# safe, and solves problems seen in the wild. Note that $ORIGIN +# is a literal string interpreted much later by ld.so. Escape it +# here with a dollar sign so Make doesn't expand $O. +LDFLAGS += '-Wl,-rpath,$$ORIGIN' +endif +endif + # # The steps for cross-compiling are as follows: # First, clone and make install of grpc using the native compilers for the host. @@ -437,9 +459,9 @@ E = @echo Q = @ endif -CORE_VERSION = 7.0.0-dev -CPP_VERSION = 1.17.0-dev -CSHARP_VERSION = 1.17.0-dev +CORE_VERSION = 7.0.0 +CPP_VERSION = 1.22.0-dev +CSHARP_VERSION = 1.22.0-dev CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES)) CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS) @@ -456,11 +478,11 @@ LDFLAGS += $(EXTRA_LDFLAGS) DEFINES += $(EXTRA_DEFINES) LDLIBS += $(EXTRA_LDLIBS) -HOST_CPPFLAGS = $(CPPFLAGS) -HOST_CFLAGS = $(CFLAGS) -HOST_CXXFLAGS = $(CXXFLAGS) -HOST_LDFLAGS = $(LDFLAGS) -HOST_LDLIBS = $(LDLIBS) +HOST_CPPFLAGS += $(CPPFLAGS) +HOST_CFLAGS += $(CFLAGS) +HOST_CXXFLAGS += $(CXXFLAGS) +HOST_LDFLAGS += $(LDFLAGS) +HOST_LDLIBS += $(LDLIBS) # These are automatically computed variables. # There shouldn't be any need to change anything from now on. @@ -809,7 +831,7 @@ ifeq ($(HAS_SYSTEM_PROTOBUF),true) ifeq ($(HAS_PKG_CONFIG),true) PROTOBUF_PKG_CONFIG = true PC_REQUIRES_GRPCXX = protobuf -CPPFLAGS := $(shell $(PKG_CONFIG) --cflags protobuf) $(CPPFLAGS) +CPPFLAGS := $(CPPFLAGS) $(shell $(PKG_CONFIG) --cflags protobuf) LDFLAGS_PROTOBUF_PKG_CONFIG = $(shell $(PKG_CONFIG) --libs-only-L protobuf) ifeq ($(SYSTEM),Linux) ifneq ($(LDFLAGS_PROTOBUF_PKG_CONFIG),) @@ -986,6 +1008,7 @@ chttp2_hpack_encoder_test: $(BINDIR)/$(CONFIG)/chttp2_hpack_encoder_test chttp2_stream_map_test: $(BINDIR)/$(CONFIG)/chttp2_stream_map_test chttp2_varint_test: $(BINDIR)/$(CONFIG)/chttp2_varint_test client_fuzzer: $(BINDIR)/$(CONFIG)/client_fuzzer +close_fd_test: $(BINDIR)/$(CONFIG)/close_fd_test cmdline_test: $(BINDIR)/$(CONFIG)/cmdline_test combiner_test: $(BINDIR)/$(CONFIG)/combiner_test compression_test: $(BINDIR)/$(CONFIG)/compression_test @@ -1076,11 +1099,13 @@ nanopb_fuzzer_serverlist_test: $(BINDIR)/$(CONFIG)/nanopb_fuzzer_serverlist_test no_server_test: $(BINDIR)/$(CONFIG)/no_server_test num_external_connectivity_watchers_test: $(BINDIR)/$(CONFIG)/num_external_connectivity_watchers_test parse_address_test: $(BINDIR)/$(CONFIG)/parse_address_test +parse_address_with_named_scope_id_test: $(BINDIR)/$(CONFIG)/parse_address_with_named_scope_id_test percent_decode_fuzzer: $(BINDIR)/$(CONFIG)/percent_decode_fuzzer percent_encode_fuzzer: $(BINDIR)/$(CONFIG)/percent_encode_fuzzer percent_encoding_test: $(BINDIR)/$(CONFIG)/percent_encoding_test -resolve_address_posix_test: $(BINDIR)/$(CONFIG)/resolve_address_posix_test +resolve_address_using_ares_resolver_posix_test: $(BINDIR)/$(CONFIG)/resolve_address_using_ares_resolver_posix_test resolve_address_using_ares_resolver_test: $(BINDIR)/$(CONFIG)/resolve_address_using_ares_resolver_test +resolve_address_using_native_resolver_posix_test: $(BINDIR)/$(CONFIG)/resolve_address_using_native_resolver_posix_test resolve_address_using_native_resolver_test: $(BINDIR)/$(CONFIG)/resolve_address_using_native_resolver_test resource_quota_test: $(BINDIR)/$(CONFIG)/resource_quota_test secure_channel_create_test: $(BINDIR)/$(CONFIG)/secure_channel_create_test @@ -1115,7 +1140,6 @@ transport_security_test: $(BINDIR)/$(CONFIG)/transport_security_test udp_server_test: $(BINDIR)/$(CONFIG)/udp_server_test uri_fuzzer_test: $(BINDIR)/$(CONFIG)/uri_fuzzer_test uri_parser_test: $(BINDIR)/$(CONFIG)/uri_parser_test -wakeup_fd_cv_test: $(BINDIR)/$(CONFIG)/wakeup_fd_cv_test alarm_test: $(BINDIR)/$(CONFIG)/alarm_test alts_counter_test: $(BINDIR)/$(CONFIG)/alts_counter_test alts_crypt_test: $(BINDIR)/$(CONFIG)/alts_crypt_test @@ -1134,8 +1158,12 @@ async_end2end_test: $(BINDIR)/$(CONFIG)/async_end2end_test auth_property_iterator_test: $(BINDIR)/$(CONFIG)/auth_property_iterator_test backoff_test: $(BINDIR)/$(CONFIG)/backoff_test bdp_estimator_test: $(BINDIR)/$(CONFIG)/bdp_estimator_test +bm_alarm: $(BINDIR)/$(CONFIG)/bm_alarm bm_arena: $(BINDIR)/$(CONFIG)/bm_arena +bm_byte_buffer: $(BINDIR)/$(CONFIG)/bm_byte_buffer bm_call_create: $(BINDIR)/$(CONFIG)/bm_call_create +bm_callback_streaming_ping_pong: $(BINDIR)/$(CONFIG)/bm_callback_streaming_ping_pong +bm_callback_unary_ping_pong: $(BINDIR)/$(CONFIG)/bm_callback_unary_ping_pong bm_channel: $(BINDIR)/$(CONFIG)/bm_channel bm_chttp2_hpack: $(BINDIR)/$(CONFIG)/bm_chttp2_hpack bm_chttp2_transport: $(BINDIR)/$(CONFIG)/bm_chttp2_transport @@ -1149,6 +1177,7 @@ bm_fullstack_trickle: $(BINDIR)/$(CONFIG)/bm_fullstack_trickle bm_fullstack_unary_ping_pong: $(BINDIR)/$(CONFIG)/bm_fullstack_unary_ping_pong bm_metadata: $(BINDIR)/$(CONFIG)/bm_metadata bm_pollset: $(BINDIR)/$(CONFIG)/bm_pollset +bm_timer: $(BINDIR)/$(CONFIG)/bm_timer byte_stream_test: $(BINDIR)/$(CONFIG)/byte_stream_test channel_arguments_test: $(BINDIR)/$(CONFIG)/channel_arguments_test channel_filter_test: $(BINDIR)/$(CONFIG)/channel_filter_test @@ -1168,6 +1197,7 @@ client_interceptors_end2end_test: $(BINDIR)/$(CONFIG)/client_interceptors_end2en client_lb_end2end_test: $(BINDIR)/$(CONFIG)/client_lb_end2end_test codegen_test_full: $(BINDIR)/$(CONFIG)/codegen_test_full codegen_test_minimal: $(BINDIR)/$(CONFIG)/codegen_test_minimal +context_list_test: $(BINDIR)/$(CONFIG)/context_list_test credentials_test: $(BINDIR)/$(CONFIG)/credentials_test cxx_byte_buffer_test: $(BINDIR)/$(CONFIG)/cxx_byte_buffer_test cxx_slice_test: $(BINDIR)/$(CONFIG)/cxx_slice_test @@ -1178,9 +1208,12 @@ error_details_test: $(BINDIR)/$(CONFIG)/error_details_test exception_test: $(BINDIR)/$(CONFIG)/exception_test filter_end2end_test: $(BINDIR)/$(CONFIG)/filter_end2end_test generic_end2end_test: $(BINDIR)/$(CONFIG)/generic_end2end_test +global_config_env_test: $(BINDIR)/$(CONFIG)/global_config_env_test +global_config_test: $(BINDIR)/$(CONFIG)/global_config_test golden_file_test: $(BINDIR)/$(CONFIG)/golden_file_test grpc_alts_credentials_options_test: $(BINDIR)/$(CONFIG)/grpc_alts_credentials_options_test grpc_cli: $(BINDIR)/$(CONFIG)/grpc_cli +grpc_core_map_test: $(BINDIR)/$(CONFIG)/grpc_core_map_test grpc_cpp_plugin: $(BINDIR)/$(CONFIG)/grpc_cpp_plugin grpc_csharp_plugin: $(BINDIR)/$(CONFIG)/grpc_csharp_plugin grpc_linux_system_roots_test: $(BINDIR)/$(CONFIG)/grpc_linux_system_roots_test @@ -1204,10 +1237,12 @@ interop_server: $(BINDIR)/$(CONFIG)/interop_server interop_test: $(BINDIR)/$(CONFIG)/interop_test json_run_localhost: $(BINDIR)/$(CONFIG)/json_run_localhost memory_test: $(BINDIR)/$(CONFIG)/memory_test +message_allocator_end2end_test: $(BINDIR)/$(CONFIG)/message_allocator_end2end_test metrics_client: $(BINDIR)/$(CONFIG)/metrics_client mock_test: $(BINDIR)/$(CONFIG)/mock_test nonblocking_test: $(BINDIR)/$(CONFIG)/nonblocking_test noop-benchmark: $(BINDIR)/$(CONFIG)/noop-benchmark +optional_test: $(BINDIR)/$(CONFIG)/optional_test orphanable_test: $(BINDIR)/$(CONFIG)/orphanable_test proto_server_reflection_test: $(BINDIR)/$(CONFIG)/proto_server_reflection_test proto_utils_test: $(BINDIR)/$(CONFIG)/proto_utils_test @@ -1232,6 +1267,8 @@ server_crash_test_client: $(BINDIR)/$(CONFIG)/server_crash_test_client server_early_return_test: $(BINDIR)/$(CONFIG)/server_early_return_test server_interceptors_end2end_test: $(BINDIR)/$(CONFIG)/server_interceptors_end2end_test server_request_call_test: $(BINDIR)/$(CONFIG)/server_request_call_test +service_config_end2end_test: $(BINDIR)/$(CONFIG)/service_config_end2end_test +service_config_test: $(BINDIR)/$(CONFIG)/service_config_test shutdown_test: $(BINDIR)/$(CONFIG)/shutdown_test slice_hash_table_test: $(BINDIR)/$(CONFIG)/slice_hash_table_test slice_weak_hash_table_test: $(BINDIR)/$(CONFIG)/slice_weak_hash_table_test @@ -1242,64 +1279,17 @@ streaming_throughput_test: $(BINDIR)/$(CONFIG)/streaming_throughput_test stress_test: $(BINDIR)/$(CONFIG)/stress_test thread_manager_test: $(BINDIR)/$(CONFIG)/thread_manager_test thread_stress_test: $(BINDIR)/$(CONFIG)/thread_stress_test +time_change_test: $(BINDIR)/$(CONFIG)/time_change_test transport_pid_controller_test: $(BINDIR)/$(CONFIG)/transport_pid_controller_test transport_security_common_api_test: $(BINDIR)/$(CONFIG)/transport_security_common_api_test writes_per_rpc_test: $(BINDIR)/$(CONFIG)/writes_per_rpc_test +xds_end2end_test: $(BINDIR)/$(CONFIG)/xds_end2end_test public_headers_must_be_c89: $(BINDIR)/$(CONFIG)/public_headers_must_be_c89 gen_hpack_tables: $(BINDIR)/$(CONFIG)/gen_hpack_tables gen_legal_metadata_characters: $(BINDIR)/$(CONFIG)/gen_legal_metadata_characters gen_percent_encoding_tables: $(BINDIR)/$(CONFIG)/gen_percent_encoding_tables -boringssl_crypto_test_data: $(BINDIR)/$(CONFIG)/boringssl_crypto_test_data -boringssl_asn1_test: $(BINDIR)/$(CONFIG)/boringssl_asn1_test -boringssl_base64_test: $(BINDIR)/$(CONFIG)/boringssl_base64_test -boringssl_bio_test: $(BINDIR)/$(CONFIG)/boringssl_bio_test -boringssl_buf_test: $(BINDIR)/$(CONFIG)/boringssl_buf_test -boringssl_bytestring_test: $(BINDIR)/$(CONFIG)/boringssl_bytestring_test -boringssl_chacha_test: $(BINDIR)/$(CONFIG)/boringssl_chacha_test -boringssl_aead_test: $(BINDIR)/$(CONFIG)/boringssl_aead_test -boringssl_cipher_test: $(BINDIR)/$(CONFIG)/boringssl_cipher_test -boringssl_cmac_test: $(BINDIR)/$(CONFIG)/boringssl_cmac_test -boringssl_compiler_test: $(BINDIR)/$(CONFIG)/boringssl_compiler_test -boringssl_constant_time_test: $(BINDIR)/$(CONFIG)/boringssl_constant_time_test -boringssl_ed25519_test: $(BINDIR)/$(CONFIG)/boringssl_ed25519_test -boringssl_spake25519_test: $(BINDIR)/$(CONFIG)/boringssl_spake25519_test -boringssl_x25519_test: $(BINDIR)/$(CONFIG)/boringssl_x25519_test -boringssl_dh_test: $(BINDIR)/$(CONFIG)/boringssl_dh_test -boringssl_digest_test: $(BINDIR)/$(CONFIG)/boringssl_digest_test -boringssl_dsa_test: $(BINDIR)/$(CONFIG)/boringssl_dsa_test -boringssl_ecdh_test: $(BINDIR)/$(CONFIG)/boringssl_ecdh_test -boringssl_err_test: $(BINDIR)/$(CONFIG)/boringssl_err_test -boringssl_evp_extra_test: $(BINDIR)/$(CONFIG)/boringssl_evp_extra_test -boringssl_evp_test: $(BINDIR)/$(CONFIG)/boringssl_evp_test -boringssl_pbkdf_test: $(BINDIR)/$(CONFIG)/boringssl_pbkdf_test -boringssl_scrypt_test: $(BINDIR)/$(CONFIG)/boringssl_scrypt_test -boringssl_aes_test: $(BINDIR)/$(CONFIG)/boringssl_aes_test -boringssl_bn_test: $(BINDIR)/$(CONFIG)/boringssl_bn_test -boringssl_ec_test: $(BINDIR)/$(CONFIG)/boringssl_ec_test -boringssl_p256-x86_64_test: $(BINDIR)/$(CONFIG)/boringssl_p256-x86_64_test -boringssl_ecdsa_test: $(BINDIR)/$(CONFIG)/boringssl_ecdsa_test -boringssl_gcm_test: $(BINDIR)/$(CONFIG)/boringssl_gcm_test -boringssl_ctrdrbg_test: $(BINDIR)/$(CONFIG)/boringssl_ctrdrbg_test -boringssl_hkdf_test: $(BINDIR)/$(CONFIG)/boringssl_hkdf_test -boringssl_hmac_test: $(BINDIR)/$(CONFIG)/boringssl_hmac_test -boringssl_lhash_test: $(BINDIR)/$(CONFIG)/boringssl_lhash_test -boringssl_obj_test: $(BINDIR)/$(CONFIG)/boringssl_obj_test -boringssl_pkcs7_test: $(BINDIR)/$(CONFIG)/boringssl_pkcs7_test -boringssl_pkcs12_test: $(BINDIR)/$(CONFIG)/boringssl_pkcs12_test -boringssl_pkcs8_test: $(BINDIR)/$(CONFIG)/boringssl_pkcs8_test -boringssl_poly1305_test: $(BINDIR)/$(CONFIG)/boringssl_poly1305_test -boringssl_pool_test: $(BINDIR)/$(CONFIG)/boringssl_pool_test -boringssl_refcount_test: $(BINDIR)/$(CONFIG)/boringssl_refcount_test -boringssl_rsa_test: $(BINDIR)/$(CONFIG)/boringssl_rsa_test -boringssl_self_test: $(BINDIR)/$(CONFIG)/boringssl_self_test -boringssl_file_test_gtest: $(BINDIR)/$(CONFIG)/boringssl_file_test_gtest -boringssl_gtest_main: $(BINDIR)/$(CONFIG)/boringssl_gtest_main -boringssl_thread_test: $(BINDIR)/$(CONFIG)/boringssl_thread_test -boringssl_x509_test: $(BINDIR)/$(CONFIG)/boringssl_x509_test -boringssl_tab_test: $(BINDIR)/$(CONFIG)/boringssl_tab_test -boringssl_v3name_test: $(BINDIR)/$(CONFIG)/boringssl_v3name_test -boringssl_span_test: $(BINDIR)/$(CONFIG)/boringssl_span_test boringssl_ssl_test: $(BINDIR)/$(CONFIG)/boringssl_ssl_test +boringssl_crypto_test: $(BINDIR)/$(CONFIG)/boringssl_crypto_test badreq_bad_client_test: $(BINDIR)/$(CONFIG)/badreq_bad_client_test connection_prefix_bad_client_test: $(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test duplicate_header_bad_client_test: $(BINDIR)/$(CONFIG)/duplicate_header_bad_client_test @@ -1322,13 +1312,17 @@ h2_full+pipe_test: $(BINDIR)/$(CONFIG)/h2_full+pipe_test h2_full+trace_test: $(BINDIR)/$(CONFIG)/h2_full+trace_test h2_full+workarounds_test: $(BINDIR)/$(CONFIG)/h2_full+workarounds_test h2_http_proxy_test: $(BINDIR)/$(CONFIG)/h2_http_proxy_test -h2_local_test: $(BINDIR)/$(CONFIG)/h2_local_test +h2_local_ipv4_test: $(BINDIR)/$(CONFIG)/h2_local_ipv4_test +h2_local_ipv6_test: $(BINDIR)/$(CONFIG)/h2_local_ipv6_test +h2_local_uds_test: $(BINDIR)/$(CONFIG)/h2_local_uds_test h2_oauth2_test: $(BINDIR)/$(CONFIG)/h2_oauth2_test h2_proxy_test: $(BINDIR)/$(CONFIG)/h2_proxy_test h2_sockpair_test: $(BINDIR)/$(CONFIG)/h2_sockpair_test h2_sockpair+trace_test: $(BINDIR)/$(CONFIG)/h2_sockpair+trace_test h2_sockpair_1byte_test: $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_test +h2_spiffe_test: $(BINDIR)/$(CONFIG)/h2_spiffe_test h2_ssl_test: $(BINDIR)/$(CONFIG)/h2_ssl_test +h2_ssl_cred_reload_test: $(BINDIR)/$(CONFIG)/h2_ssl_cred_reload_test h2_ssl_proxy_test: $(BINDIR)/$(CONFIG)/h2_ssl_proxy_test h2_uds_test: $(BINDIR)/$(CONFIG)/h2_uds_test inproc_test: $(BINDIR)/$(CONFIG)/inproc_test @@ -1410,7 +1404,7 @@ plugins: $(PROTOC_PLUGINS) privatelibs: privatelibs_c privatelibs_cxx -privatelibs_c: $(LIBDIR)/$(CONFIG)/libalts_test_util.a $(LIBDIR)/$(CONFIG)/libcxxabi.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBDIR)/$(CONFIG)/libz.a $(LIBDIR)/$(CONFIG)/libares.a $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a +privatelibs_c: $(LIBDIR)/$(CONFIG)/libalts_test_util.a $(LIBDIR)/$(CONFIG)/libcxxabi.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBDIR)/$(CONFIG)/libupb.a $(LIBDIR)/$(CONFIG)/libz.a $(LIBDIR)/$(CONFIG)/libares.a $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a pc_c: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc.pc $(LIBDIR)/$(CONFIG)/pkgconfig/gpr.pc pc_c_unsecure: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc_unsecure.pc $(LIBDIR)/$(CONFIG)/pkgconfig/gpr.pc @@ -1420,9 +1414,9 @@ pc_cxx: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc++.pc 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_self_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)/libdns_test_util.a $(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)/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)/libdns_test_util.a $(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 endif @@ -1442,6 +1436,7 @@ buildtests_c: privatelibs_c \ $(BINDIR)/$(CONFIG)/chttp2_hpack_encoder_test \ $(BINDIR)/$(CONFIG)/chttp2_stream_map_test \ $(BINDIR)/$(CONFIG)/chttp2_varint_test \ + $(BINDIR)/$(CONFIG)/close_fd_test \ $(BINDIR)/$(CONFIG)/cmdline_test \ $(BINDIR)/$(CONFIG)/combiner_test \ $(BINDIR)/$(CONFIG)/compression_test \ @@ -1522,9 +1517,11 @@ buildtests_c: privatelibs_c \ $(BINDIR)/$(CONFIG)/no_server_test \ $(BINDIR)/$(CONFIG)/num_external_connectivity_watchers_test \ $(BINDIR)/$(CONFIG)/parse_address_test \ + $(BINDIR)/$(CONFIG)/parse_address_with_named_scope_id_test \ $(BINDIR)/$(CONFIG)/percent_encoding_test \ - $(BINDIR)/$(CONFIG)/resolve_address_posix_test \ + $(BINDIR)/$(CONFIG)/resolve_address_using_ares_resolver_posix_test \ $(BINDIR)/$(CONFIG)/resolve_address_using_ares_resolver_test \ + $(BINDIR)/$(CONFIG)/resolve_address_using_native_resolver_posix_test \ $(BINDIR)/$(CONFIG)/resolve_address_using_native_resolver_test \ $(BINDIR)/$(CONFIG)/resource_quota_test \ $(BINDIR)/$(CONFIG)/secure_channel_create_test \ @@ -1556,7 +1553,6 @@ buildtests_c: privatelibs_c \ $(BINDIR)/$(CONFIG)/transport_security_test \ $(BINDIR)/$(CONFIG)/udp_server_test \ $(BINDIR)/$(CONFIG)/uri_parser_test \ - $(BINDIR)/$(CONFIG)/wakeup_fd_cv_test \ $(BINDIR)/$(CONFIG)/public_headers_must_be_c89 \ $(BINDIR)/$(CONFIG)/badreq_bad_client_test \ $(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test \ @@ -1580,13 +1576,17 @@ buildtests_c: privatelibs_c \ $(BINDIR)/$(CONFIG)/h2_full+trace_test \ $(BINDIR)/$(CONFIG)/h2_full+workarounds_test \ $(BINDIR)/$(CONFIG)/h2_http_proxy_test \ - $(BINDIR)/$(CONFIG)/h2_local_test \ + $(BINDIR)/$(CONFIG)/h2_local_ipv4_test \ + $(BINDIR)/$(CONFIG)/h2_local_ipv6_test \ + $(BINDIR)/$(CONFIG)/h2_local_uds_test \ $(BINDIR)/$(CONFIG)/h2_oauth2_test \ $(BINDIR)/$(CONFIG)/h2_proxy_test \ $(BINDIR)/$(CONFIG)/h2_sockpair_test \ $(BINDIR)/$(CONFIG)/h2_sockpair+trace_test \ $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_test \ + $(BINDIR)/$(CONFIG)/h2_spiffe_test \ $(BINDIR)/$(CONFIG)/h2_ssl_test \ + $(BINDIR)/$(CONFIG)/h2_ssl_cred_reload_test \ $(BINDIR)/$(CONFIG)/h2_ssl_proxy_test \ $(BINDIR)/$(CONFIG)/h2_uds_test \ $(BINDIR)/$(CONFIG)/inproc_test \ @@ -1639,8 +1639,12 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/auth_property_iterator_test \ $(BINDIR)/$(CONFIG)/backoff_test \ $(BINDIR)/$(CONFIG)/bdp_estimator_test \ + $(BINDIR)/$(CONFIG)/bm_alarm \ $(BINDIR)/$(CONFIG)/bm_arena \ + $(BINDIR)/$(CONFIG)/bm_byte_buffer \ $(BINDIR)/$(CONFIG)/bm_call_create \ + $(BINDIR)/$(CONFIG)/bm_callback_streaming_ping_pong \ + $(BINDIR)/$(CONFIG)/bm_callback_unary_ping_pong \ $(BINDIR)/$(CONFIG)/bm_channel \ $(BINDIR)/$(CONFIG)/bm_chttp2_hpack \ $(BINDIR)/$(CONFIG)/bm_chttp2_transport \ @@ -1654,6 +1658,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/bm_fullstack_unary_ping_pong \ $(BINDIR)/$(CONFIG)/bm_metadata \ $(BINDIR)/$(CONFIG)/bm_pollset \ + $(BINDIR)/$(CONFIG)/bm_timer \ $(BINDIR)/$(CONFIG)/byte_stream_test \ $(BINDIR)/$(CONFIG)/channel_arguments_test \ $(BINDIR)/$(CONFIG)/channel_filter_test \ @@ -1673,6 +1678,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/client_lb_end2end_test \ $(BINDIR)/$(CONFIG)/codegen_test_full \ $(BINDIR)/$(CONFIG)/codegen_test_minimal \ + $(BINDIR)/$(CONFIG)/context_list_test \ $(BINDIR)/$(CONFIG)/credentials_test \ $(BINDIR)/$(CONFIG)/cxx_byte_buffer_test \ $(BINDIR)/$(CONFIG)/cxx_slice_test \ @@ -1683,9 +1689,12 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/exception_test \ $(BINDIR)/$(CONFIG)/filter_end2end_test \ $(BINDIR)/$(CONFIG)/generic_end2end_test \ + $(BINDIR)/$(CONFIG)/global_config_env_test \ + $(BINDIR)/$(CONFIG)/global_config_test \ $(BINDIR)/$(CONFIG)/golden_file_test \ $(BINDIR)/$(CONFIG)/grpc_alts_credentials_options_test \ $(BINDIR)/$(CONFIG)/grpc_cli \ + $(BINDIR)/$(CONFIG)/grpc_core_map_test \ $(BINDIR)/$(CONFIG)/grpc_linux_system_roots_test \ $(BINDIR)/$(CONFIG)/grpc_tool_test \ $(BINDIR)/$(CONFIG)/grpclb_api_test \ @@ -1702,10 +1711,12 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/interop_test \ $(BINDIR)/$(CONFIG)/json_run_localhost \ $(BINDIR)/$(CONFIG)/memory_test \ + $(BINDIR)/$(CONFIG)/message_allocator_end2end_test \ $(BINDIR)/$(CONFIG)/metrics_client \ $(BINDIR)/$(CONFIG)/mock_test \ $(BINDIR)/$(CONFIG)/nonblocking_test \ $(BINDIR)/$(CONFIG)/noop-benchmark \ + $(BINDIR)/$(CONFIG)/optional_test \ $(BINDIR)/$(CONFIG)/orphanable_test \ $(BINDIR)/$(CONFIG)/proto_server_reflection_test \ $(BINDIR)/$(CONFIG)/proto_utils_test \ @@ -1730,6 +1741,8 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/server_early_return_test \ $(BINDIR)/$(CONFIG)/server_interceptors_end2end_test \ $(BINDIR)/$(CONFIG)/server_request_call_test \ + $(BINDIR)/$(CONFIG)/service_config_end2end_test \ + $(BINDIR)/$(CONFIG)/service_config_test \ $(BINDIR)/$(CONFIG)/shutdown_test \ $(BINDIR)/$(CONFIG)/slice_hash_table_test \ $(BINDIR)/$(CONFIG)/slice_weak_hash_table_test \ @@ -1740,60 +1753,13 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/stress_test \ $(BINDIR)/$(CONFIG)/thread_manager_test \ $(BINDIR)/$(CONFIG)/thread_stress_test \ + $(BINDIR)/$(CONFIG)/time_change_test \ $(BINDIR)/$(CONFIG)/transport_pid_controller_test \ $(BINDIR)/$(CONFIG)/transport_security_common_api_test \ $(BINDIR)/$(CONFIG)/writes_per_rpc_test \ - $(BINDIR)/$(CONFIG)/boringssl_crypto_test_data \ - $(BINDIR)/$(CONFIG)/boringssl_asn1_test \ - $(BINDIR)/$(CONFIG)/boringssl_base64_test \ - $(BINDIR)/$(CONFIG)/boringssl_bio_test \ - $(BINDIR)/$(CONFIG)/boringssl_buf_test \ - $(BINDIR)/$(CONFIG)/boringssl_bytestring_test \ - $(BINDIR)/$(CONFIG)/boringssl_chacha_test \ - $(BINDIR)/$(CONFIG)/boringssl_aead_test \ - $(BINDIR)/$(CONFIG)/boringssl_cipher_test \ - $(BINDIR)/$(CONFIG)/boringssl_cmac_test \ - $(BINDIR)/$(CONFIG)/boringssl_compiler_test \ - $(BINDIR)/$(CONFIG)/boringssl_constant_time_test \ - $(BINDIR)/$(CONFIG)/boringssl_ed25519_test \ - $(BINDIR)/$(CONFIG)/boringssl_spake25519_test \ - $(BINDIR)/$(CONFIG)/boringssl_x25519_test \ - $(BINDIR)/$(CONFIG)/boringssl_dh_test \ - $(BINDIR)/$(CONFIG)/boringssl_digest_test \ - $(BINDIR)/$(CONFIG)/boringssl_dsa_test \ - $(BINDIR)/$(CONFIG)/boringssl_ecdh_test \ - $(BINDIR)/$(CONFIG)/boringssl_err_test \ - $(BINDIR)/$(CONFIG)/boringssl_evp_extra_test \ - $(BINDIR)/$(CONFIG)/boringssl_evp_test \ - $(BINDIR)/$(CONFIG)/boringssl_pbkdf_test \ - $(BINDIR)/$(CONFIG)/boringssl_scrypt_test \ - $(BINDIR)/$(CONFIG)/boringssl_aes_test \ - $(BINDIR)/$(CONFIG)/boringssl_bn_test \ - $(BINDIR)/$(CONFIG)/boringssl_ec_test \ - $(BINDIR)/$(CONFIG)/boringssl_p256-x86_64_test \ - $(BINDIR)/$(CONFIG)/boringssl_ecdsa_test \ - $(BINDIR)/$(CONFIG)/boringssl_gcm_test \ - $(BINDIR)/$(CONFIG)/boringssl_ctrdrbg_test \ - $(BINDIR)/$(CONFIG)/boringssl_hkdf_test \ - $(BINDIR)/$(CONFIG)/boringssl_hmac_test \ - $(BINDIR)/$(CONFIG)/boringssl_lhash_test \ - $(BINDIR)/$(CONFIG)/boringssl_obj_test \ - $(BINDIR)/$(CONFIG)/boringssl_pkcs7_test \ - $(BINDIR)/$(CONFIG)/boringssl_pkcs12_test \ - $(BINDIR)/$(CONFIG)/boringssl_pkcs8_test \ - $(BINDIR)/$(CONFIG)/boringssl_poly1305_test \ - $(BINDIR)/$(CONFIG)/boringssl_pool_test \ - $(BINDIR)/$(CONFIG)/boringssl_refcount_test \ - $(BINDIR)/$(CONFIG)/boringssl_rsa_test \ - $(BINDIR)/$(CONFIG)/boringssl_self_test \ - $(BINDIR)/$(CONFIG)/boringssl_file_test_gtest \ - $(BINDIR)/$(CONFIG)/boringssl_gtest_main \ - $(BINDIR)/$(CONFIG)/boringssl_thread_test \ - $(BINDIR)/$(CONFIG)/boringssl_x509_test \ - $(BINDIR)/$(CONFIG)/boringssl_tab_test \ - $(BINDIR)/$(CONFIG)/boringssl_v3name_test \ - $(BINDIR)/$(CONFIG)/boringssl_span_test \ + $(BINDIR)/$(CONFIG)/xds_end2end_test \ $(BINDIR)/$(CONFIG)/boringssl_ssl_test \ + $(BINDIR)/$(CONFIG)/boringssl_crypto_test \ $(BINDIR)/$(CONFIG)/resolver_component_test_unsecure \ $(BINDIR)/$(CONFIG)/resolver_component_test \ $(BINDIR)/$(CONFIG)/resolver_component_tests_runner_invoker_unsecure \ @@ -1822,8 +1788,12 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/auth_property_iterator_test \ $(BINDIR)/$(CONFIG)/backoff_test \ $(BINDIR)/$(CONFIG)/bdp_estimator_test \ + $(BINDIR)/$(CONFIG)/bm_alarm \ $(BINDIR)/$(CONFIG)/bm_arena \ + $(BINDIR)/$(CONFIG)/bm_byte_buffer \ $(BINDIR)/$(CONFIG)/bm_call_create \ + $(BINDIR)/$(CONFIG)/bm_callback_streaming_ping_pong \ + $(BINDIR)/$(CONFIG)/bm_callback_unary_ping_pong \ $(BINDIR)/$(CONFIG)/bm_channel \ $(BINDIR)/$(CONFIG)/bm_chttp2_hpack \ $(BINDIR)/$(CONFIG)/bm_chttp2_transport \ @@ -1837,6 +1807,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/bm_fullstack_unary_ping_pong \ $(BINDIR)/$(CONFIG)/bm_metadata \ $(BINDIR)/$(CONFIG)/bm_pollset \ + $(BINDIR)/$(CONFIG)/bm_timer \ $(BINDIR)/$(CONFIG)/byte_stream_test \ $(BINDIR)/$(CONFIG)/channel_arguments_test \ $(BINDIR)/$(CONFIG)/channel_filter_test \ @@ -1856,6 +1827,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/client_lb_end2end_test \ $(BINDIR)/$(CONFIG)/codegen_test_full \ $(BINDIR)/$(CONFIG)/codegen_test_minimal \ + $(BINDIR)/$(CONFIG)/context_list_test \ $(BINDIR)/$(CONFIG)/credentials_test \ $(BINDIR)/$(CONFIG)/cxx_byte_buffer_test \ $(BINDIR)/$(CONFIG)/cxx_slice_test \ @@ -1866,9 +1838,12 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/exception_test \ $(BINDIR)/$(CONFIG)/filter_end2end_test \ $(BINDIR)/$(CONFIG)/generic_end2end_test \ + $(BINDIR)/$(CONFIG)/global_config_env_test \ + $(BINDIR)/$(CONFIG)/global_config_test \ $(BINDIR)/$(CONFIG)/golden_file_test \ $(BINDIR)/$(CONFIG)/grpc_alts_credentials_options_test \ $(BINDIR)/$(CONFIG)/grpc_cli \ + $(BINDIR)/$(CONFIG)/grpc_core_map_test \ $(BINDIR)/$(CONFIG)/grpc_linux_system_roots_test \ $(BINDIR)/$(CONFIG)/grpc_tool_test \ $(BINDIR)/$(CONFIG)/grpclb_api_test \ @@ -1885,10 +1860,12 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/interop_test \ $(BINDIR)/$(CONFIG)/json_run_localhost \ $(BINDIR)/$(CONFIG)/memory_test \ + $(BINDIR)/$(CONFIG)/message_allocator_end2end_test \ $(BINDIR)/$(CONFIG)/metrics_client \ $(BINDIR)/$(CONFIG)/mock_test \ $(BINDIR)/$(CONFIG)/nonblocking_test \ $(BINDIR)/$(CONFIG)/noop-benchmark \ + $(BINDIR)/$(CONFIG)/optional_test \ $(BINDIR)/$(CONFIG)/orphanable_test \ $(BINDIR)/$(CONFIG)/proto_server_reflection_test \ $(BINDIR)/$(CONFIG)/proto_utils_test \ @@ -1913,6 +1890,8 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/server_early_return_test \ $(BINDIR)/$(CONFIG)/server_interceptors_end2end_test \ $(BINDIR)/$(CONFIG)/server_request_call_test \ + $(BINDIR)/$(CONFIG)/service_config_end2end_test \ + $(BINDIR)/$(CONFIG)/service_config_test \ $(BINDIR)/$(CONFIG)/shutdown_test \ $(BINDIR)/$(CONFIG)/slice_hash_table_test \ $(BINDIR)/$(CONFIG)/slice_weak_hash_table_test \ @@ -1923,9 +1902,11 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/stress_test \ $(BINDIR)/$(CONFIG)/thread_manager_test \ $(BINDIR)/$(CONFIG)/thread_stress_test \ + $(BINDIR)/$(CONFIG)/time_change_test \ $(BINDIR)/$(CONFIG)/transport_pid_controller_test \ $(BINDIR)/$(CONFIG)/transport_security_common_api_test \ $(BINDIR)/$(CONFIG)/writes_per_rpc_test \ + $(BINDIR)/$(CONFIG)/xds_end2end_test \ $(BINDIR)/$(CONFIG)/resolver_component_test_unsecure \ $(BINDIR)/$(CONFIG)/resolver_component_test \ $(BINDIR)/$(CONFIG)/resolver_component_tests_runner_invoker_unsecure \ @@ -1968,6 +1949,8 @@ test_c: buildtests_c $(Q) $(BINDIR)/$(CONFIG)/chttp2_stream_map_test || ( echo test chttp2_stream_map_test failed ; exit 1 ) $(E) "[RUN] Testing chttp2_varint_test" $(Q) $(BINDIR)/$(CONFIG)/chttp2_varint_test || ( echo test chttp2_varint_test failed ; exit 1 ) + $(E) "[RUN] Testing close_fd_test" + $(Q) $(BINDIR)/$(CONFIG)/close_fd_test || ( echo test close_fd_test failed ; exit 1 ) $(E) "[RUN] Testing cmdline_test" $(Q) $(BINDIR)/$(CONFIG)/cmdline_test || ( echo test cmdline_test failed ; exit 1 ) $(E) "[RUN] Testing combiner_test" @@ -2116,12 +2099,16 @@ test_c: buildtests_c $(Q) $(BINDIR)/$(CONFIG)/num_external_connectivity_watchers_test || ( echo test num_external_connectivity_watchers_test failed ; exit 1 ) $(E) "[RUN] Testing parse_address_test" $(Q) $(BINDIR)/$(CONFIG)/parse_address_test || ( echo test parse_address_test failed ; exit 1 ) + $(E) "[RUN] Testing parse_address_with_named_scope_id_test" + $(Q) $(BINDIR)/$(CONFIG)/parse_address_with_named_scope_id_test || ( echo test parse_address_with_named_scope_id_test failed ; exit 1 ) $(E) "[RUN] Testing percent_encoding_test" $(Q) $(BINDIR)/$(CONFIG)/percent_encoding_test || ( echo test percent_encoding_test failed ; exit 1 ) - $(E) "[RUN] Testing resolve_address_posix_test" - $(Q) $(BINDIR)/$(CONFIG)/resolve_address_posix_test || ( echo test resolve_address_posix_test failed ; exit 1 ) + $(E) "[RUN] Testing resolve_address_using_ares_resolver_posix_test" + $(Q) $(BINDIR)/$(CONFIG)/resolve_address_using_ares_resolver_posix_test || ( echo test resolve_address_using_ares_resolver_posix_test failed ; exit 1 ) $(E) "[RUN] Testing resolve_address_using_ares_resolver_test" $(Q) $(BINDIR)/$(CONFIG)/resolve_address_using_ares_resolver_test || ( echo test resolve_address_using_ares_resolver_test failed ; exit 1 ) + $(E) "[RUN] Testing resolve_address_using_native_resolver_posix_test" + $(Q) $(BINDIR)/$(CONFIG)/resolve_address_using_native_resolver_posix_test || ( echo test resolve_address_using_native_resolver_posix_test failed ; exit 1 ) $(E) "[RUN] Testing resolve_address_using_native_resolver_test" $(Q) $(BINDIR)/$(CONFIG)/resolve_address_using_native_resolver_test || ( echo test resolve_address_using_native_resolver_test failed ; exit 1 ) $(E) "[RUN] Testing resource_quota_test" @@ -2184,8 +2171,6 @@ test_c: buildtests_c $(Q) $(BINDIR)/$(CONFIG)/udp_server_test || ( echo test udp_server_test failed ; exit 1 ) $(E) "[RUN] Testing uri_parser_test" $(Q) $(BINDIR)/$(CONFIG)/uri_parser_test || ( echo test uri_parser_test failed ; exit 1 ) - $(E) "[RUN] Testing wakeup_fd_cv_test" - $(Q) $(BINDIR)/$(CONFIG)/wakeup_fd_cv_test || ( echo test wakeup_fd_cv_test failed ; exit 1 ) $(E) "[RUN] Testing public_headers_must_be_c89" $(Q) $(BINDIR)/$(CONFIG)/public_headers_must_be_c89 || ( echo test public_headers_must_be_c89 failed ; exit 1 ) $(E) "[RUN] Testing badreq_bad_client_test" @@ -2254,10 +2239,18 @@ test_cxx: buildtests_cxx $(Q) $(BINDIR)/$(CONFIG)/backoff_test || ( echo test backoff_test failed ; exit 1 ) $(E) "[RUN] Testing bdp_estimator_test" $(Q) $(BINDIR)/$(CONFIG)/bdp_estimator_test || ( echo test bdp_estimator_test failed ; exit 1 ) + $(E) "[RUN] Testing bm_alarm" + $(Q) $(BINDIR)/$(CONFIG)/bm_alarm || ( echo test bm_alarm failed ; exit 1 ) $(E) "[RUN] Testing bm_arena" $(Q) $(BINDIR)/$(CONFIG)/bm_arena || ( echo test bm_arena failed ; exit 1 ) + $(E) "[RUN] Testing bm_byte_buffer" + $(Q) $(BINDIR)/$(CONFIG)/bm_byte_buffer || ( echo test bm_byte_buffer failed ; exit 1 ) $(E) "[RUN] Testing bm_call_create" $(Q) $(BINDIR)/$(CONFIG)/bm_call_create || ( echo test bm_call_create failed ; exit 1 ) + $(E) "[RUN] Testing bm_callback_streaming_ping_pong" + $(Q) $(BINDIR)/$(CONFIG)/bm_callback_streaming_ping_pong || ( echo test bm_callback_streaming_ping_pong failed ; exit 1 ) + $(E) "[RUN] Testing bm_callback_unary_ping_pong" + $(Q) $(BINDIR)/$(CONFIG)/bm_callback_unary_ping_pong || ( echo test bm_callback_unary_ping_pong failed ; exit 1 ) $(E) "[RUN] Testing bm_channel" $(Q) $(BINDIR)/$(CONFIG)/bm_channel || ( echo test bm_channel failed ; exit 1 ) $(E) "[RUN] Testing bm_chttp2_hpack" @@ -2284,6 +2277,8 @@ test_cxx: buildtests_cxx $(Q) $(BINDIR)/$(CONFIG)/bm_metadata || ( echo test bm_metadata failed ; exit 1 ) $(E) "[RUN] Testing bm_pollset" $(Q) $(BINDIR)/$(CONFIG)/bm_pollset || ( echo test bm_pollset failed ; exit 1 ) + $(E) "[RUN] Testing bm_timer" + $(Q) $(BINDIR)/$(CONFIG)/bm_timer || ( echo test bm_timer failed ; exit 1 ) $(E) "[RUN] Testing byte_stream_test" $(Q) $(BINDIR)/$(CONFIG)/byte_stream_test || ( echo test byte_stream_test failed ; exit 1 ) $(E) "[RUN] Testing channel_arguments_test" @@ -2320,6 +2315,8 @@ test_cxx: buildtests_cxx $(Q) $(BINDIR)/$(CONFIG)/codegen_test_full || ( echo test codegen_test_full failed ; exit 1 ) $(E) "[RUN] Testing codegen_test_minimal" $(Q) $(BINDIR)/$(CONFIG)/codegen_test_minimal || ( echo test codegen_test_minimal failed ; exit 1 ) + $(E) "[RUN] Testing context_list_test" + $(Q) $(BINDIR)/$(CONFIG)/context_list_test || ( echo test context_list_test failed ; exit 1 ) $(E) "[RUN] Testing credentials_test" $(Q) $(BINDIR)/$(CONFIG)/credentials_test || ( echo test credentials_test failed ; exit 1 ) $(E) "[RUN] Testing cxx_byte_buffer_test" @@ -2340,10 +2337,16 @@ test_cxx: buildtests_cxx $(Q) $(BINDIR)/$(CONFIG)/filter_end2end_test || ( echo test filter_end2end_test failed ; exit 1 ) $(E) "[RUN] Testing generic_end2end_test" $(Q) $(BINDIR)/$(CONFIG)/generic_end2end_test || ( echo test generic_end2end_test failed ; exit 1 ) + $(E) "[RUN] Testing global_config_env_test" + $(Q) $(BINDIR)/$(CONFIG)/global_config_env_test || ( echo test global_config_env_test failed ; exit 1 ) + $(E) "[RUN] Testing global_config_test" + $(Q) $(BINDIR)/$(CONFIG)/global_config_test || ( echo test global_config_test failed ; exit 1 ) $(E) "[RUN] Testing golden_file_test" $(Q) $(BINDIR)/$(CONFIG)/golden_file_test || ( echo test golden_file_test failed ; exit 1 ) $(E) "[RUN] Testing grpc_alts_credentials_options_test" $(Q) $(BINDIR)/$(CONFIG)/grpc_alts_credentials_options_test || ( echo test grpc_alts_credentials_options_test failed ; exit 1 ) + $(E) "[RUN] Testing grpc_core_map_test" + $(Q) $(BINDIR)/$(CONFIG)/grpc_core_map_test || ( echo test grpc_core_map_test failed ; exit 1 ) $(E) "[RUN] Testing grpc_linux_system_roots_test" $(Q) $(BINDIR)/$(CONFIG)/grpc_linux_system_roots_test || ( echo test grpc_linux_system_roots_test failed ; exit 1 ) $(E) "[RUN] Testing grpc_tool_test" @@ -2366,12 +2369,16 @@ test_cxx: buildtests_cxx $(Q) $(BINDIR)/$(CONFIG)/interop_test || ( echo test interop_test failed ; exit 1 ) $(E) "[RUN] Testing memory_test" $(Q) $(BINDIR)/$(CONFIG)/memory_test || ( echo test memory_test failed ; exit 1 ) + $(E) "[RUN] Testing message_allocator_end2end_test" + $(Q) $(BINDIR)/$(CONFIG)/message_allocator_end2end_test || ( echo test message_allocator_end2end_test failed ; exit 1 ) $(E) "[RUN] Testing mock_test" $(Q) $(BINDIR)/$(CONFIG)/mock_test || ( echo test mock_test failed ; exit 1 ) $(E) "[RUN] Testing nonblocking_test" $(Q) $(BINDIR)/$(CONFIG)/nonblocking_test || ( echo test nonblocking_test failed ; exit 1 ) $(E) "[RUN] Testing noop-benchmark" $(Q) $(BINDIR)/$(CONFIG)/noop-benchmark || ( echo test noop-benchmark failed ; exit 1 ) + $(E) "[RUN] Testing optional_test" + $(Q) $(BINDIR)/$(CONFIG)/optional_test || ( echo test optional_test failed ; exit 1 ) $(E) "[RUN] Testing orphanable_test" $(Q) $(BINDIR)/$(CONFIG)/orphanable_test || ( echo test orphanable_test failed ; exit 1 ) $(E) "[RUN] Testing proto_server_reflection_test" @@ -2408,6 +2415,10 @@ test_cxx: buildtests_cxx $(Q) $(BINDIR)/$(CONFIG)/server_interceptors_end2end_test || ( echo test server_interceptors_end2end_test failed ; exit 1 ) $(E) "[RUN] Testing server_request_call_test" $(Q) $(BINDIR)/$(CONFIG)/server_request_call_test || ( echo test server_request_call_test failed ; exit 1 ) + $(E) "[RUN] Testing service_config_end2end_test" + $(Q) $(BINDIR)/$(CONFIG)/service_config_end2end_test || ( echo test service_config_end2end_test failed ; exit 1 ) + $(E) "[RUN] Testing service_config_test" + $(Q) $(BINDIR)/$(CONFIG)/service_config_test || ( echo test service_config_test failed ; exit 1 ) $(E) "[RUN] Testing shutdown_test" $(Q) $(BINDIR)/$(CONFIG)/shutdown_test || ( echo test shutdown_test failed ; exit 1 ) $(E) "[RUN] Testing slice_hash_table_test" @@ -2426,12 +2437,16 @@ test_cxx: buildtests_cxx $(Q) $(BINDIR)/$(CONFIG)/thread_manager_test || ( echo test thread_manager_test failed ; exit 1 ) $(E) "[RUN] Testing thread_stress_test" $(Q) $(BINDIR)/$(CONFIG)/thread_stress_test || ( echo test thread_stress_test failed ; exit 1 ) + $(E) "[RUN] Testing time_change_test" + $(Q) $(BINDIR)/$(CONFIG)/time_change_test || ( echo test time_change_test failed ; exit 1 ) $(E) "[RUN] Testing transport_pid_controller_test" $(Q) $(BINDIR)/$(CONFIG)/transport_pid_controller_test || ( echo test transport_pid_controller_test failed ; exit 1 ) $(E) "[RUN] Testing transport_security_common_api_test" $(Q) $(BINDIR)/$(CONFIG)/transport_security_common_api_test || ( echo test transport_security_common_api_test failed ; exit 1 ) $(E) "[RUN] Testing writes_per_rpc_test" $(Q) $(BINDIR)/$(CONFIG)/writes_per_rpc_test || ( echo test writes_per_rpc_test failed ; exit 1 ) + $(E) "[RUN] Testing xds_end2end_test" + $(Q) $(BINDIR)/$(CONFIG)/xds_end2end_test || ( echo test xds_end2end_test failed ; exit 1 ) $(E) "[RUN] Testing resolver_component_tests_runner_invoker_unsecure" $(Q) $(BINDIR)/$(CONFIG)/resolver_component_tests_runner_invoker_unsecure || ( echo test resolver_component_tests_runner_invoker_unsecure failed ; exit 1 ) $(E) "[RUN] Testing resolver_component_tests_runner_invoker" @@ -2738,12 +2753,12 @@ $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc: protoc_dep_error else -$(GENDIR)/src/proto/grpc/testing/echo.pb.cc: src/proto/grpc/testing/echo.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc +$(GENDIR)/src/proto/grpc/testing/echo.pb.cc: src/proto/grpc/testing/echo.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_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/echo.grpc.pb.cc: src/proto/grpc/testing/echo.proto $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(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.grpc.pb.cc: src/proto/grpc/testing/echo.proto $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_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=generate_mock_code=true:$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $< @@ -2845,6 +2860,22 @@ $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.cc: src/pro $(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/simple_messages.pb.cc: protoc_dep_error +$(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc: protoc_dep_error +else + +$(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc: src/proto/grpc/testing/simple_messages.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) + $(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/simple_messages.grpc.pb.cc: src/proto/grpc/testing/simple_messages.proto $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) + $(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/stats.pb.cc: protoc_dep_error $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc: protoc_dep_error @@ -3314,7 +3345,6 @@ endif LIBGPR_SRC = \ 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 \ @@ -3347,7 +3377,9 @@ LIBGPR_SRC = \ 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/arena.cc \ src/core/lib/gprpp/fork.cc \ + src/core/lib/gprpp/global_config_env.cc \ src/core/lib/gprpp/thd_posix.cc \ src/core/lib/gprpp/thd_windows.cc \ src/core/lib/profiling/basic_timers.cc \ @@ -3423,31 +3455,6 @@ ifneq ($(NO_DEPS),true) endif -LIBGPR_TEST_UTIL_SRC = \ - test/core/util/test_config.cc \ - -PUBLIC_HEADERS_C += \ - -LIBGPR_TEST_UTIL_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGPR_TEST_UTIL_SRC)))) - - -$(LIBDIR)/$(CONFIG)/libgpr_test_util.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(LIBGPR_TEST_UTIL_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgpr_test_util.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBGPR_TEST_UTIL_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgpr_test_util.a -endif - - - - -ifneq ($(NO_DEPS),true) --include $(LIBGPR_TEST_UTIL_OBJS:.o=.dep) -endif - - LIBGRPC_SRC = \ src/core/lib/surface/init.cc \ src/core/lib/avl/avl.cc \ @@ -3460,10 +3467,10 @@ LIBGRPC_SRC = \ src/core/lib/channel/channelz_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_args.cc \ src/core/lib/compression/compression_internal.cc \ src/core/lib/compression/message_compress.cc \ src/core/lib/compression/stream_compression.cc \ @@ -3476,12 +3483,15 @@ LIBGRPC_SRC = \ src/core/lib/http/parser.cc \ src/core/lib/iomgr/buffer_list.cc \ src/core/lib/iomgr/call_combiner.cc \ + src/core/lib/iomgr/cfstream_handle.cc \ src/core/lib/iomgr/combiner.cc \ src/core/lib/iomgr/endpoint.cc \ + src/core/lib/iomgr/endpoint_cfstream.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/error_cfstream.cc \ src/core/lib/iomgr/ev_epoll1_linux.cc \ src/core/lib/iomgr/ev_epollex_linux.cc \ src/core/lib/iomgr/ev_poll_posix.cc \ @@ -3494,18 +3504,20 @@ LIBGRPC_SRC = \ 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/grpc_if_nametoindex_posix.cc \ + src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc \ src/core/lib/iomgr/internal_errqueue.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_posix_cfstream.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 \ @@ -3529,6 +3541,7 @@ LIBGRPC_SRC = \ 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_cfstream.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 \ @@ -3553,7 +3566,6 @@ LIBGRPC_SRC = \ 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 \ @@ -3593,7 +3605,6 @@ LIBGRPC_SRC = \ 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 \ @@ -3607,6 +3618,7 @@ LIBGRPC_SRC = \ 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/context_list.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 \ @@ -3647,6 +3659,8 @@ LIBGRPC_SRC = \ 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/tls/grpc_tls_credentials_options.cc \ + src/core/lib/security/credentials/tls/spiffe_credentials.cc \ src/core/lib/security/security_connector/alts/alts_security_connector.cc \ src/core/lib/security/security_connector/fake/fake_security_connector.cc \ src/core/lib/security/security_connector/load_system_roots_fallback.cc \ @@ -3655,6 +3669,7 @@ LIBGRPC_SRC = \ src/core/lib/security/security_connector/security_connector.cc \ src/core/lib/security/security_connector/ssl/ssl_security_connector.cc \ src/core/lib/security/security_connector/ssl_utils.cc \ + src/core/lib/security/security_connector/tls/spiffe_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 \ @@ -3709,21 +3724,25 @@ LIBGRPC_SRC = \ 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/global_subchannel_pool.cc \ src/core/ext/filters/client_channel/health/health_check_client.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/local_subchannel_pool.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/resolver_result_parsing.cc \ + src/core/ext/filters/client_channel/resolving_lb_policy.cc \ src/core/ext/filters/client_channel/retry_throttle.cc \ + src/core/ext/filters/client_channel/server_address.cc \ + src/core/ext/filters/client_channel/service_config.cc \ src/core/ext/filters/client_channel/subchannel.cc \ - src/core/ext/filters/client_channel/subchannel_index.cc \ + src/core/ext/filters/client_channel/subchannel_pool_interface.cc \ src/core/ext/filters/deadline/deadline_filter.cc \ src/core/ext/filters/client_channel/health/health.pb.c \ src/core/tsi/fake_transport_security.cc \ @@ -3756,10 +3775,13 @@ LIBGRPC_SRC = \ 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.cc \ + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc \ + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc \ + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc \ src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc \ @@ -3874,10 +3896,10 @@ LIBGRPC_CRONET_SRC = \ src/core/lib/channel/channelz_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_args.cc \ src/core/lib/compression/compression_internal.cc \ src/core/lib/compression/message_compress.cc \ src/core/lib/compression/stream_compression.cc \ @@ -3890,12 +3912,15 @@ LIBGRPC_CRONET_SRC = \ src/core/lib/http/parser.cc \ src/core/lib/iomgr/buffer_list.cc \ src/core/lib/iomgr/call_combiner.cc \ + src/core/lib/iomgr/cfstream_handle.cc \ src/core/lib/iomgr/combiner.cc \ src/core/lib/iomgr/endpoint.cc \ + src/core/lib/iomgr/endpoint_cfstream.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/error_cfstream.cc \ src/core/lib/iomgr/ev_epoll1_linux.cc \ src/core/lib/iomgr/ev_epollex_linux.cc \ src/core/lib/iomgr/ev_poll_posix.cc \ @@ -3908,18 +3933,20 @@ LIBGRPC_CRONET_SRC = \ 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/grpc_if_nametoindex_posix.cc \ + src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc \ src/core/lib/iomgr/internal_errqueue.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_posix_cfstream.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 \ @@ -3943,6 +3970,7 @@ LIBGRPC_CRONET_SRC = \ 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_cfstream.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 \ @@ -3967,7 +3995,6 @@ LIBGRPC_CRONET_SRC = \ 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 \ @@ -4007,7 +4034,6 @@ LIBGRPC_CRONET_SRC = \ 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 \ @@ -4024,6 +4050,7 @@ LIBGRPC_CRONET_SRC = \ 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/context_list.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 \ @@ -4054,21 +4081,25 @@ LIBGRPC_CRONET_SRC = \ 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/global_subchannel_pool.cc \ src/core/ext/filters/client_channel/health/health_check_client.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/local_subchannel_pool.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/resolver_result_parsing.cc \ + src/core/ext/filters/client_channel/resolving_lb_policy.cc \ src/core/ext/filters/client_channel/retry_throttle.cc \ + src/core/ext/filters/client_channel/server_address.cc \ + src/core/ext/filters/client_channel/service_config.cc \ src/core/ext/filters/client_channel/subchannel.cc \ - src/core/ext/filters/client_channel/subchannel_index.cc \ + src/core/ext/filters/client_channel/subchannel_pool_interface.cc \ src/core/ext/filters/deadline/deadline_filter.cc \ src/core/ext/filters/client_channel/health/health.pb.c \ third_party/nanopb/pb_common.c \ @@ -4091,6 +4122,8 @@ LIBGRPC_CRONET_SRC = \ 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/tls/grpc_tls_credentials_options.cc \ + src/core/lib/security/credentials/tls/spiffe_credentials.cc \ src/core/lib/security/security_connector/alts/alts_security_connector.cc \ src/core/lib/security/security_connector/fake/fake_security_connector.cc \ src/core/lib/security/security_connector/load_system_roots_fallback.cc \ @@ -4099,6 +4132,7 @@ LIBGRPC_CRONET_SRC = \ src/core/lib/security/security_connector/security_connector.cc \ src/core/lib/security/security_connector/ssl/ssl_security_connector.cc \ src/core/lib/security/security_connector/ssl_utils.cc \ + src/core/lib/security/security_connector/tls/spiffe_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 \ @@ -4240,6 +4274,7 @@ LIBGRPC_TEST_UTIL_SRC = \ src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc \ test/core/end2end/cq_verifier.cc \ test/core/end2end/fixtures/http_proxy_fixture.cc \ + test/core/end2end/fixtures/local_util.cc \ test/core/end2end/fixtures/proxy.cc \ test/core/iomgr/endpoint_tests.cc \ test/core/util/debugger_macros.cc \ @@ -4256,6 +4291,8 @@ LIBGRPC_TEST_UTIL_SRC = \ test/core/util/slice_splitter.cc \ test/core/util/subprocess_posix.cc \ test/core/util/subprocess_windows.cc \ + test/core/util/test_config.cc \ + test/core/util/test_lb_policies.cc \ test/core/util/tracer_util.cc \ test/core/util/trickle_endpoint.cc \ test/core/util/cmdline.cc \ @@ -4269,10 +4306,10 @@ LIBGRPC_TEST_UTIL_SRC = \ src/core/lib/channel/channelz_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_args.cc \ src/core/lib/compression/compression_internal.cc \ src/core/lib/compression/message_compress.cc \ src/core/lib/compression/stream_compression.cc \ @@ -4285,12 +4322,15 @@ LIBGRPC_TEST_UTIL_SRC = \ src/core/lib/http/parser.cc \ src/core/lib/iomgr/buffer_list.cc \ src/core/lib/iomgr/call_combiner.cc \ + src/core/lib/iomgr/cfstream_handle.cc \ src/core/lib/iomgr/combiner.cc \ src/core/lib/iomgr/endpoint.cc \ + src/core/lib/iomgr/endpoint_cfstream.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/error_cfstream.cc \ src/core/lib/iomgr/ev_epoll1_linux.cc \ src/core/lib/iomgr/ev_epollex_linux.cc \ src/core/lib/iomgr/ev_poll_posix.cc \ @@ -4303,18 +4343,20 @@ LIBGRPC_TEST_UTIL_SRC = \ 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/grpc_if_nametoindex_posix.cc \ + src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc \ src/core/lib/iomgr/internal_errqueue.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_posix_cfstream.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 \ @@ -4338,6 +4380,7 @@ LIBGRPC_TEST_UTIL_SRC = \ 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_cfstream.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 \ @@ -4362,7 +4405,6 @@ LIBGRPC_TEST_UTIL_SRC = \ 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 \ @@ -4402,7 +4444,6 @@ LIBGRPC_TEST_UTIL_SRC = \ 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 \ @@ -4418,21 +4459,25 @@ LIBGRPC_TEST_UTIL_SRC = \ 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/global_subchannel_pool.cc \ src/core/ext/filters/client_channel/health/health_check_client.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/local_subchannel_pool.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/resolver_result_parsing.cc \ + src/core/ext/filters/client_channel/resolving_lb_policy.cc \ src/core/ext/filters/client_channel/retry_throttle.cc \ + src/core/ext/filters/client_channel/server_address.cc \ + src/core/ext/filters/client_channel/service_config.cc \ src/core/ext/filters/client_channel/subchannel.cc \ - src/core/ext/filters/client_channel/subchannel_index.cc \ + src/core/ext/filters/client_channel/subchannel_pool_interface.cc \ src/core/ext/filters/deadline/deadline_filter.cc \ src/core/ext/filters/client_channel/health/health.pb.c \ third_party/nanopb/pb_common.c \ @@ -4442,6 +4487,7 @@ LIBGRPC_TEST_UTIL_SRC = \ 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/context_list.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 \ @@ -4545,6 +4591,7 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc \ test/core/end2end/cq_verifier.cc \ test/core/end2end/fixtures/http_proxy_fixture.cc \ + test/core/end2end/fixtures/local_util.cc \ test/core/end2end/fixtures/proxy.cc \ test/core/iomgr/endpoint_tests.cc \ test/core/util/debugger_macros.cc \ @@ -4561,6 +4608,8 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ test/core/util/slice_splitter.cc \ test/core/util/subprocess_posix.cc \ test/core/util/subprocess_windows.cc \ + test/core/util/test_config.cc \ + test/core/util/test_lb_policies.cc \ test/core/util/tracer_util.cc \ test/core/util/trickle_endpoint.cc \ test/core/util/cmdline.cc \ @@ -4574,10 +4623,10 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ src/core/lib/channel/channelz_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_args.cc \ src/core/lib/compression/compression_internal.cc \ src/core/lib/compression/message_compress.cc \ src/core/lib/compression/stream_compression.cc \ @@ -4590,12 +4639,15 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ src/core/lib/http/parser.cc \ src/core/lib/iomgr/buffer_list.cc \ src/core/lib/iomgr/call_combiner.cc \ + src/core/lib/iomgr/cfstream_handle.cc \ src/core/lib/iomgr/combiner.cc \ src/core/lib/iomgr/endpoint.cc \ + src/core/lib/iomgr/endpoint_cfstream.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/error_cfstream.cc \ src/core/lib/iomgr/ev_epoll1_linux.cc \ src/core/lib/iomgr/ev_epollex_linux.cc \ src/core/lib/iomgr/ev_poll_posix.cc \ @@ -4608,18 +4660,20 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ 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/grpc_if_nametoindex_posix.cc \ + src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc \ src/core/lib/iomgr/internal_errqueue.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_posix_cfstream.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 \ @@ -4643,6 +4697,7 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ 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_cfstream.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 \ @@ -4667,7 +4722,6 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ 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 \ @@ -4707,7 +4761,6 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ 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 \ @@ -4723,21 +4776,25 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ 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/global_subchannel_pool.cc \ src/core/ext/filters/client_channel/health/health_check_client.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/local_subchannel_pool.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/resolver_result_parsing.cc \ + src/core/ext/filters/client_channel/resolving_lb_policy.cc \ src/core/ext/filters/client_channel/retry_throttle.cc \ + src/core/ext/filters/client_channel/server_address.cc \ + src/core/ext/filters/client_channel/service_config.cc \ src/core/ext/filters/client_channel/subchannel.cc \ - src/core/ext/filters/client_channel/subchannel_index.cc \ + src/core/ext/filters/client_channel/subchannel_pool_interface.cc \ src/core/ext/filters/deadline/deadline_filter.cc \ src/core/ext/filters/client_channel/health/health.pb.c \ third_party/nanopb/pb_common.c \ @@ -4747,6 +4804,7 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ 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/context_list.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 \ @@ -4845,10 +4903,10 @@ LIBGRPC_UNSECURE_SRC = \ src/core/lib/channel/channelz_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_args.cc \ src/core/lib/compression/compression_internal.cc \ src/core/lib/compression/message_compress.cc \ src/core/lib/compression/stream_compression.cc \ @@ -4861,12 +4919,15 @@ LIBGRPC_UNSECURE_SRC = \ src/core/lib/http/parser.cc \ src/core/lib/iomgr/buffer_list.cc \ src/core/lib/iomgr/call_combiner.cc \ + src/core/lib/iomgr/cfstream_handle.cc \ src/core/lib/iomgr/combiner.cc \ src/core/lib/iomgr/endpoint.cc \ + src/core/lib/iomgr/endpoint_cfstream.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/error_cfstream.cc \ src/core/lib/iomgr/ev_epoll1_linux.cc \ src/core/lib/iomgr/ev_epollex_linux.cc \ src/core/lib/iomgr/ev_poll_posix.cc \ @@ -4879,18 +4940,20 @@ LIBGRPC_UNSECURE_SRC = \ 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/grpc_if_nametoindex_posix.cc \ + src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc \ src/core/lib/iomgr/internal_errqueue.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_posix_cfstream.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 \ @@ -4914,6 +4977,7 @@ LIBGRPC_UNSECURE_SRC = \ 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_cfstream.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 \ @@ -4938,7 +5002,6 @@ LIBGRPC_UNSECURE_SRC = \ 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 \ @@ -4978,7 +5041,6 @@ LIBGRPC_UNSECURE_SRC = \ 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 \ @@ -4993,6 +5055,7 @@ LIBGRPC_UNSECURE_SRC = \ 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/context_list.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 \ @@ -5028,21 +5091,25 @@ LIBGRPC_UNSECURE_SRC = \ 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/global_subchannel_pool.cc \ src/core/ext/filters/client_channel/health/health_check_client.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/local_subchannel_pool.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/resolver_result_parsing.cc \ + src/core/ext/filters/client_channel/resolving_lb_policy.cc \ src/core/ext/filters/client_channel/retry_throttle.cc \ + src/core/ext/filters/client_channel/server_address.cc \ + src/core/ext/filters/client_channel/service_config.cc \ src/core/ext/filters/client_channel/subchannel.cc \ - src/core/ext/filters/client_channel/subchannel_index.cc \ + src/core/ext/filters/client_channel/subchannel_pool_interface.cc \ src/core/ext/filters/deadline/deadline_filter.cc \ src/core/ext/filters/client_channel/health/health.pb.c \ third_party/nanopb/pb_common.c \ @@ -5052,10 +5119,13 @@ LIBGRPC_UNSECURE_SRC = \ src/core/ext/transport/inproc/inproc_transport.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.cc \ + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc \ + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc \ + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc \ src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc \ @@ -5235,6 +5305,107 @@ endif endif +LIBBM_CALLBACK_TEST_SERVICE_IMPL_SRC = \ + $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc \ + test/cpp/microbenchmarks/callback_test_service.cc \ + +PUBLIC_HEADERS_CXX += \ + +LIBBM_CALLBACK_TEST_SERVICE_IMPL_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBM_CALLBACK_TEST_SERVICE_IMPL_SRC)))) + +$(LIBBM_CALLBACK_TEST_SERVICE_IMPL_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX + +ifeq ($(NO_SECURE),true) + +# You can't build secure libraries if you don't have OpenSSL. + +$(LIBDIR)/$(CONFIG)/libbm_callback_test_service_impl.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)/libbm_callback_test_service_impl.a: protobuf_dep_error + + +else + +$(LIBDIR)/$(CONFIG)/libbm_callback_test_service_impl.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBM_CALLBACK_TEST_SERVICE_IMPL_OBJS) + $(E) "[AR] Creating $@" + $(Q) mkdir -p `dirname $@` + $(Q) rm -f $(LIBDIR)/$(CONFIG)/libbm_callback_test_service_impl.a + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libbm_callback_test_service_impl.a $(LIBBM_CALLBACK_TEST_SERVICE_IMPL_OBJS) +ifeq ($(SYSTEM),Darwin) + $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libbm_callback_test_service_impl.a +endif + + + + +endif + +endif + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(LIBBM_CALLBACK_TEST_SERVICE_IMPL_OBJS:.o=.dep) +endif +endif +$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/callback_test_service.o: $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc + + +LIBDNS_TEST_UTIL_SRC = \ + test/cpp/naming/dns_test_util.cc \ + +PUBLIC_HEADERS_CXX += \ + +LIBDNS_TEST_UTIL_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBDNS_TEST_UTIL_SRC)))) + + +ifeq ($(NO_SECURE),true) + +# You can't build secure libraries if you don't have OpenSSL. + +$(LIBDIR)/$(CONFIG)/libdns_test_util.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)/libdns_test_util.a: protobuf_dep_error + + +else + +$(LIBDIR)/$(CONFIG)/libdns_test_util.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBDNS_TEST_UTIL_OBJS) + $(E) "[AR] Creating $@" + $(Q) mkdir -p `dirname $@` + $(Q) rm -f $(LIBDIR)/$(CONFIG)/libdns_test_util.a + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libdns_test_util.a $(LIBDNS_TEST_UTIL_OBJS) +ifeq ($(SYSTEM),Darwin) + $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libdns_test_util.a +endif + + + + +endif + +endif + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(LIBDNS_TEST_UTIL_OBJS:.o=.dep) +endif +endif + + LIBGRPC++_SRC = \ src/cpp/client/insecure_credentials.cc \ src/cpp/client/secure_credentials.cc \ @@ -5330,16 +5501,22 @@ PUBLIC_HEADERS_CXX += \ include/grpc++/support/sync_stream.h \ include/grpc++/support/time.h \ include/grpcpp/alarm.h \ + include/grpcpp/alarm_impl.h \ include/grpcpp/channel.h \ + include/grpcpp/channel_impl.h \ include/grpcpp/client_context.h \ include/grpcpp/completion_queue.h \ include/grpcpp/create_channel.h \ + include/grpcpp/create_channel_impl.h \ include/grpcpp/create_channel_posix.h \ + include/grpcpp/create_channel_posix_impl.h \ include/grpcpp/ext/health_check_service_server_builder_option.h \ include/grpcpp/generic/async_generic_service.h \ include/grpcpp/generic/generic_stub.h \ + include/grpcpp/generic/generic_stub_impl.h \ include/grpcpp/grpcpp.h \ include/grpcpp/health_check_service_interface.h \ + include/grpcpp/health_check_service_interface_impl.h \ include/grpcpp/impl/call.h \ include/grpcpp/impl/channel_argument_option.h \ include/grpcpp/impl/client_unary_call.h \ @@ -5350,27 +5527,41 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/rpc_service_method.h \ include/grpcpp/impl/serialization_traits.h \ include/grpcpp/impl/server_builder_option.h \ + include/grpcpp/impl/server_builder_option_impl.h \ include/grpcpp/impl/server_builder_plugin.h \ include/grpcpp/impl/server_initializer.h \ + include/grpcpp/impl/server_initializer_impl.h \ include/grpcpp/impl/service_type.h \ include/grpcpp/resource_quota.h \ + include/grpcpp/resource_quota_impl.h \ include/grpcpp/security/auth_context.h \ include/grpcpp/security/auth_metadata_processor.h \ + include/grpcpp/security/auth_metadata_processor_impl.h \ include/grpcpp/security/credentials.h \ + include/grpcpp/security/credentials_impl.h \ include/grpcpp/security/server_credentials.h \ + include/grpcpp/security/server_credentials_impl.h \ include/grpcpp/server.h \ include/grpcpp/server_builder.h \ + include/grpcpp/server_builder_impl.h \ include/grpcpp/server_context.h \ + include/grpcpp/server_impl.h \ include/grpcpp/server_posix.h \ + include/grpcpp/server_posix_impl.h \ include/grpcpp/support/async_stream.h \ include/grpcpp/support/async_unary_call.h \ include/grpcpp/support/byte_buffer.h \ include/grpcpp/support/channel_arguments.h \ + include/grpcpp/support/channel_arguments_impl.h \ include/grpcpp/support/client_callback.h \ + include/grpcpp/support/client_interceptor.h \ include/grpcpp/support/config.h \ + include/grpcpp/support/interceptor.h \ + include/grpcpp/support/message_allocator.h \ include/grpcpp/support/proto_buffer_reader.h \ include/grpcpp/support/proto_buffer_writer.h \ include/grpcpp/support/server_callback.h \ + include/grpcpp/support/server_interceptor.h \ include/grpcpp/support/slice.h \ include/grpcpp/support/status.h \ include/grpcpp/support/status_code_enum.h \ @@ -5474,6 +5665,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/client_interceptor.h \ include/grpcpp/impl/codegen/client_unary_call.h \ include/grpcpp/impl/codegen/completion_queue.h \ + include/grpcpp/impl/codegen/completion_queue_impl.h \ include/grpcpp/impl/codegen/completion_queue_tag.h \ include/grpcpp/impl/codegen/config.h \ include/grpcpp/impl/codegen/core_codegen_interface.h \ @@ -5482,6 +5674,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/intercepted_channel.h \ include/grpcpp/impl/codegen/interceptor.h \ include/grpcpp/impl/codegen/interceptor_common.h \ + include/grpcpp/impl/codegen/message_allocator.h \ include/grpcpp/impl/codegen/metadata_map.h \ include/grpcpp/impl/codegen/method_handler_impl.h \ include/grpcpp/impl/codegen/rpc_method.h \ @@ -5500,6 +5693,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/stub_options.h \ include/grpcpp/impl/codegen/sync_stream.h \ include/grpcpp/impl/codegen/time.h \ + include/grpcpp/impl/codegen/sync.h \ include/grpc++/impl/codegen/proto_utils.h \ include/grpcpp/impl/codegen/proto_buffer_reader.h \ include/grpcpp/impl/codegen/proto_buffer_writer.h \ @@ -5672,6 +5866,7 @@ LIBGRPC++_CRONET_SRC = \ 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/context_list.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 \ @@ -5700,10 +5895,10 @@ LIBGRPC++_CRONET_SRC = \ src/core/lib/channel/channelz_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_args.cc \ src/core/lib/compression/compression_internal.cc \ src/core/lib/compression/message_compress.cc \ src/core/lib/compression/stream_compression.cc \ @@ -5716,12 +5911,15 @@ LIBGRPC++_CRONET_SRC = \ src/core/lib/http/parser.cc \ src/core/lib/iomgr/buffer_list.cc \ src/core/lib/iomgr/call_combiner.cc \ + src/core/lib/iomgr/cfstream_handle.cc \ src/core/lib/iomgr/combiner.cc \ src/core/lib/iomgr/endpoint.cc \ + src/core/lib/iomgr/endpoint_cfstream.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/error_cfstream.cc \ src/core/lib/iomgr/ev_epoll1_linux.cc \ src/core/lib/iomgr/ev_epollex_linux.cc \ src/core/lib/iomgr/ev_poll_posix.cc \ @@ -5734,18 +5932,20 @@ LIBGRPC++_CRONET_SRC = \ 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/grpc_if_nametoindex_posix.cc \ + src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc \ src/core/lib/iomgr/internal_errqueue.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_posix_cfstream.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 \ @@ -5769,6 +5969,7 @@ LIBGRPC++_CRONET_SRC = \ 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_cfstream.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 \ @@ -5793,7 +5994,6 @@ LIBGRPC++_CRONET_SRC = \ 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 \ @@ -5833,7 +6033,6 @@ LIBGRPC++_CRONET_SRC = \ 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 \ @@ -5854,21 +6053,25 @@ LIBGRPC++_CRONET_SRC = \ 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/global_subchannel_pool.cc \ src/core/ext/filters/client_channel/health/health_check_client.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/local_subchannel_pool.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/resolver_result_parsing.cc \ + src/core/ext/filters/client_channel/resolving_lb_policy.cc \ src/core/ext/filters/client_channel/retry_throttle.cc \ + src/core/ext/filters/client_channel/server_address.cc \ + src/core/ext/filters/client_channel/service_config.cc \ src/core/ext/filters/client_channel/subchannel.cc \ - src/core/ext/filters/client_channel/subchannel_index.cc \ + src/core/ext/filters/client_channel/subchannel_pool_interface.cc \ src/core/ext/filters/deadline/deadline_filter.cc \ src/core/ext/transport/chttp2/server/insecure/server_chttp2.cc \ src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc \ @@ -5922,16 +6125,22 @@ PUBLIC_HEADERS_CXX += \ include/grpc++/support/sync_stream.h \ include/grpc++/support/time.h \ include/grpcpp/alarm.h \ + include/grpcpp/alarm_impl.h \ include/grpcpp/channel.h \ + include/grpcpp/channel_impl.h \ include/grpcpp/client_context.h \ include/grpcpp/completion_queue.h \ include/grpcpp/create_channel.h \ + include/grpcpp/create_channel_impl.h \ include/grpcpp/create_channel_posix.h \ + include/grpcpp/create_channel_posix_impl.h \ include/grpcpp/ext/health_check_service_server_builder_option.h \ include/grpcpp/generic/async_generic_service.h \ include/grpcpp/generic/generic_stub.h \ + include/grpcpp/generic/generic_stub_impl.h \ include/grpcpp/grpcpp.h \ include/grpcpp/health_check_service_interface.h \ + include/grpcpp/health_check_service_interface_impl.h \ include/grpcpp/impl/call.h \ include/grpcpp/impl/channel_argument_option.h \ include/grpcpp/impl/client_unary_call.h \ @@ -5942,27 +6151,41 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/rpc_service_method.h \ include/grpcpp/impl/serialization_traits.h \ include/grpcpp/impl/server_builder_option.h \ + include/grpcpp/impl/server_builder_option_impl.h \ include/grpcpp/impl/server_builder_plugin.h \ include/grpcpp/impl/server_initializer.h \ + include/grpcpp/impl/server_initializer_impl.h \ include/grpcpp/impl/service_type.h \ include/grpcpp/resource_quota.h \ + include/grpcpp/resource_quota_impl.h \ include/grpcpp/security/auth_context.h \ include/grpcpp/security/auth_metadata_processor.h \ + include/grpcpp/security/auth_metadata_processor_impl.h \ include/grpcpp/security/credentials.h \ + include/grpcpp/security/credentials_impl.h \ include/grpcpp/security/server_credentials.h \ + include/grpcpp/security/server_credentials_impl.h \ include/grpcpp/server.h \ include/grpcpp/server_builder.h \ + include/grpcpp/server_builder_impl.h \ include/grpcpp/server_context.h \ + include/grpcpp/server_impl.h \ include/grpcpp/server_posix.h \ + include/grpcpp/server_posix_impl.h \ include/grpcpp/support/async_stream.h \ include/grpcpp/support/async_unary_call.h \ include/grpcpp/support/byte_buffer.h \ include/grpcpp/support/channel_arguments.h \ + include/grpcpp/support/channel_arguments_impl.h \ include/grpcpp/support/client_callback.h \ + include/grpcpp/support/client_interceptor.h \ include/grpcpp/support/config.h \ + include/grpcpp/support/interceptor.h \ + include/grpcpp/support/message_allocator.h \ include/grpcpp/support/proto_buffer_reader.h \ include/grpcpp/support/proto_buffer_writer.h \ include/grpcpp/support/server_callback.h \ + include/grpcpp/support/server_interceptor.h \ include/grpcpp/support/slice.h \ include/grpcpp/support/status.h \ include/grpcpp/support/status_code_enum.h \ @@ -6066,6 +6289,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/client_interceptor.h \ include/grpcpp/impl/codegen/client_unary_call.h \ include/grpcpp/impl/codegen/completion_queue.h \ + include/grpcpp/impl/codegen/completion_queue_impl.h \ include/grpcpp/impl/codegen/completion_queue_tag.h \ include/grpcpp/impl/codegen/config.h \ include/grpcpp/impl/codegen/core_codegen_interface.h \ @@ -6074,6 +6298,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/intercepted_channel.h \ include/grpcpp/impl/codegen/interceptor.h \ include/grpcpp/impl/codegen/interceptor_common.h \ + include/grpcpp/impl/codegen/message_allocator.h \ include/grpcpp/impl/codegen/metadata_map.h \ include/grpcpp/impl/codegen/method_handler_impl.h \ include/grpcpp/impl/codegen/rpc_method.h \ @@ -6092,6 +6317,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/stub_options.h \ include/grpcpp/impl/codegen/sync_stream.h \ include/grpcpp/impl/codegen/time.h \ + include/grpcpp/impl/codegen/sync.h \ include/grpc/census.h \ LIBGRPC++_CRONET_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_CRONET_SRC)))) @@ -6164,6 +6390,7 @@ LIBGRPC++_ERROR_DETAILS_SRC = \ PUBLIC_HEADERS_CXX += \ include/grpc++/support/error_details.h \ include/grpcpp/support/error_details.h \ + include/grpcpp/support/error_details_impl.h \ LIBGRPC++_ERROR_DETAILS_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_ERROR_DETAILS_SRC)))) @@ -6290,6 +6517,7 @@ LIBGRPC++_REFLECTION_SRC = \ PUBLIC_HEADERS_CXX += \ include/grpc++/ext/proto_server_reflection_plugin.h \ include/grpcpp/ext/proto_server_reflection_plugin.h \ + include/grpcpp/ext/proto_server_reflection_plugin_impl.h \ LIBGRPC++_REFLECTION_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_REFLECTION_SRC)))) @@ -6411,6 +6639,8 @@ LIBGRPC++_TEST_UTIL_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 \ $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc \ + $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc \ + test/cpp/end2end/test_health_check_service_impl.cc \ test/cpp/end2end/test_service_impl.cc \ test/cpp/util/byte_buffer_proto_helper.cc \ test/cpp/util/channel_trace_proto_helper.cc \ @@ -6466,6 +6696,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/client_interceptor.h \ include/grpcpp/impl/codegen/client_unary_call.h \ include/grpcpp/impl/codegen/completion_queue.h \ + include/grpcpp/impl/codegen/completion_queue_impl.h \ include/grpcpp/impl/codegen/completion_queue_tag.h \ include/grpcpp/impl/codegen/config.h \ include/grpcpp/impl/codegen/core_codegen_interface.h \ @@ -6474,6 +6705,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/intercepted_channel.h \ include/grpcpp/impl/codegen/interceptor.h \ include/grpcpp/impl/codegen/interceptor_common.h \ + include/grpcpp/impl/codegen/message_allocator.h \ include/grpcpp/impl/codegen/metadata_map.h \ include/grpcpp/impl/codegen/method_handler_impl.h \ include/grpcpp/impl/codegen/rpc_method.h \ @@ -6514,6 +6746,7 @@ PUBLIC_HEADERS_CXX += \ include/grpc/impl/codegen/sync_generic.h \ include/grpc/impl/codegen/sync_posix.h \ include/grpc/impl/codegen/sync_windows.h \ + include/grpcpp/impl/codegen/sync.h \ include/grpc++/impl/codegen/proto_utils.h \ include/grpcpp/impl/codegen/proto_buffer_reader.h \ include/grpcpp/impl/codegen/proto_buffer_writer.h \ @@ -6563,14 +6796,15 @@ ifneq ($(NO_DEPS),true) -include $(LIBGRPC++_TEST_UTIL_OBJS:.o=.dep) endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/test_service_impl.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(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 $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc -$(OBJDIR)/$(CONFIG)/test/cpp/util/byte_buffer_proto_helper.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(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 $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc -$(OBJDIR)/$(CONFIG)/test/cpp/util/channel_trace_proto_helper.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(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 $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc -$(OBJDIR)/$(CONFIG)/test/cpp/util/create_test_channel.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(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 $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc -$(OBJDIR)/$(CONFIG)/test/cpp/util/string_ref_helper.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(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 $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc -$(OBJDIR)/$(CONFIG)/test/cpp/util/subprocess.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(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 $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc -$(OBJDIR)/$(CONFIG)/test/cpp/util/test_credentials_provider.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(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 $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc -$(OBJDIR)/$(CONFIG)/src/cpp/codegen/codegen_init.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(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 $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/test_health_check_service_impl.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(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 $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/test_service_impl.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(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 $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc +$(OBJDIR)/$(CONFIG)/test/cpp/util/byte_buffer_proto_helper.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(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 $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc +$(OBJDIR)/$(CONFIG)/test/cpp/util/channel_trace_proto_helper.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(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 $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc +$(OBJDIR)/$(CONFIG)/test/cpp/util/create_test_channel.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(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 $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc +$(OBJDIR)/$(CONFIG)/test/cpp/util/string_ref_helper.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(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 $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc +$(OBJDIR)/$(CONFIG)/test/cpp/util/subprocess.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(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 $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc +$(OBJDIR)/$(CONFIG)/test/cpp/util/test_credentials_provider.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(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 $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc +$(OBJDIR)/$(CONFIG)/src/cpp/codegen/codegen_init.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(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 $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc LIBGRPC++_TEST_UTIL_UNSECURE_SRC = \ @@ -6578,6 +6812,8 @@ LIBGRPC++_TEST_UTIL_UNSECURE_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 \ $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc \ + $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc \ + test/cpp/end2end/test_health_check_service_impl.cc \ test/cpp/end2end/test_service_impl.cc \ test/cpp/util/byte_buffer_proto_helper.cc \ test/cpp/util/string_ref_helper.cc \ @@ -6630,6 +6866,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/client_interceptor.h \ include/grpcpp/impl/codegen/client_unary_call.h \ include/grpcpp/impl/codegen/completion_queue.h \ + include/grpcpp/impl/codegen/completion_queue_impl.h \ include/grpcpp/impl/codegen/completion_queue_tag.h \ include/grpcpp/impl/codegen/config.h \ include/grpcpp/impl/codegen/core_codegen_interface.h \ @@ -6638,6 +6875,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/intercepted_channel.h \ include/grpcpp/impl/codegen/interceptor.h \ include/grpcpp/impl/codegen/interceptor_common.h \ + include/grpcpp/impl/codegen/message_allocator.h \ include/grpcpp/impl/codegen/metadata_map.h \ include/grpcpp/impl/codegen/method_handler_impl.h \ include/grpcpp/impl/codegen/rpc_method.h \ @@ -6678,6 +6916,7 @@ PUBLIC_HEADERS_CXX += \ include/grpc/impl/codegen/sync_generic.h \ include/grpc/impl/codegen/sync_posix.h \ include/grpc/impl/codegen/sync_windows.h \ + include/grpcpp/impl/codegen/sync.h \ include/grpc++/impl/codegen/proto_utils.h \ include/grpcpp/impl/codegen/proto_buffer_reader.h \ include/grpcpp/impl/codegen/proto_buffer_writer.h \ @@ -6727,11 +6966,12 @@ ifneq ($(NO_DEPS),true) -include $(LIBGRPC++_TEST_UTIL_UNSECURE_OBJS:.o=.dep) endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/test_service_impl.o: $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(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 $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc -$(OBJDIR)/$(CONFIG)/test/cpp/util/byte_buffer_proto_helper.o: $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(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 $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc -$(OBJDIR)/$(CONFIG)/test/cpp/util/string_ref_helper.o: $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(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 $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc -$(OBJDIR)/$(CONFIG)/test/cpp/util/subprocess.o: $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(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 $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc -$(OBJDIR)/$(CONFIG)/src/cpp/codegen/codegen_init.o: $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(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 $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/test_health_check_service_impl.o: $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(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 $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/test_service_impl.o: $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(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 $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc +$(OBJDIR)/$(CONFIG)/test/cpp/util/byte_buffer_proto_helper.o: $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(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 $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc +$(OBJDIR)/$(CONFIG)/test/cpp/util/string_ref_helper.o: $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(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 $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc +$(OBJDIR)/$(CONFIG)/test/cpp/util/subprocess.o: $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(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 $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc +$(OBJDIR)/$(CONFIG)/src/cpp/codegen/codegen_init.o: $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(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 $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc LIBGRPC++_UNSECURE_SRC = \ @@ -6824,16 +7064,22 @@ PUBLIC_HEADERS_CXX += \ include/grpc++/support/sync_stream.h \ include/grpc++/support/time.h \ include/grpcpp/alarm.h \ + include/grpcpp/alarm_impl.h \ include/grpcpp/channel.h \ + include/grpcpp/channel_impl.h \ include/grpcpp/client_context.h \ include/grpcpp/completion_queue.h \ include/grpcpp/create_channel.h \ + include/grpcpp/create_channel_impl.h \ include/grpcpp/create_channel_posix.h \ + include/grpcpp/create_channel_posix_impl.h \ include/grpcpp/ext/health_check_service_server_builder_option.h \ include/grpcpp/generic/async_generic_service.h \ include/grpcpp/generic/generic_stub.h \ + include/grpcpp/generic/generic_stub_impl.h \ include/grpcpp/grpcpp.h \ include/grpcpp/health_check_service_interface.h \ + include/grpcpp/health_check_service_interface_impl.h \ include/grpcpp/impl/call.h \ include/grpcpp/impl/channel_argument_option.h \ include/grpcpp/impl/client_unary_call.h \ @@ -6844,27 +7090,41 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/rpc_service_method.h \ include/grpcpp/impl/serialization_traits.h \ include/grpcpp/impl/server_builder_option.h \ + include/grpcpp/impl/server_builder_option_impl.h \ include/grpcpp/impl/server_builder_plugin.h \ include/grpcpp/impl/server_initializer.h \ + include/grpcpp/impl/server_initializer_impl.h \ include/grpcpp/impl/service_type.h \ include/grpcpp/resource_quota.h \ + include/grpcpp/resource_quota_impl.h \ include/grpcpp/security/auth_context.h \ include/grpcpp/security/auth_metadata_processor.h \ + include/grpcpp/security/auth_metadata_processor_impl.h \ include/grpcpp/security/credentials.h \ + include/grpcpp/security/credentials_impl.h \ include/grpcpp/security/server_credentials.h \ + include/grpcpp/security/server_credentials_impl.h \ include/grpcpp/server.h \ include/grpcpp/server_builder.h \ + include/grpcpp/server_builder_impl.h \ include/grpcpp/server_context.h \ + include/grpcpp/server_impl.h \ include/grpcpp/server_posix.h \ + include/grpcpp/server_posix_impl.h \ include/grpcpp/support/async_stream.h \ include/grpcpp/support/async_unary_call.h \ include/grpcpp/support/byte_buffer.h \ include/grpcpp/support/channel_arguments.h \ + include/grpcpp/support/channel_arguments_impl.h \ include/grpcpp/support/client_callback.h \ + include/grpcpp/support/client_interceptor.h \ include/grpcpp/support/config.h \ + include/grpcpp/support/interceptor.h \ + include/grpcpp/support/message_allocator.h \ include/grpcpp/support/proto_buffer_reader.h \ include/grpcpp/support/proto_buffer_writer.h \ include/grpcpp/support/server_callback.h \ + include/grpcpp/support/server_interceptor.h \ include/grpcpp/support/slice.h \ include/grpcpp/support/status.h \ include/grpcpp/support/status_code_enum.h \ @@ -6968,6 +7228,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/client_interceptor.h \ include/grpcpp/impl/codegen/client_unary_call.h \ include/grpcpp/impl/codegen/completion_queue.h \ + include/grpcpp/impl/codegen/completion_queue_impl.h \ include/grpcpp/impl/codegen/completion_queue_tag.h \ include/grpcpp/impl/codegen/config.h \ include/grpcpp/impl/codegen/core_codegen_interface.h \ @@ -6976,6 +7237,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/intercepted_channel.h \ include/grpcpp/impl/codegen/interceptor.h \ include/grpcpp/impl/codegen/interceptor_common.h \ + include/grpcpp/impl/codegen/message_allocator.h \ include/grpcpp/impl/codegen/metadata_map.h \ include/grpcpp/impl/codegen/method_handler_impl.h \ include/grpcpp/impl/codegen/rpc_method.h \ @@ -6994,6 +7256,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/stub_options.h \ include/grpcpp/impl/codegen/sync_stream.h \ include/grpcpp/impl/codegen/time.h \ + include/grpcpp/impl/codegen/sync.h \ LIBGRPC++_UNSECURE_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_UNSECURE_SRC)))) @@ -7206,6 +7469,7 @@ LIBGRPCPP_CHANNELZ_SRC = \ PUBLIC_HEADERS_CXX += \ include/grpcpp/ext/channelz_service_plugin.h \ + include/grpcpp/ext/channelz_service_plugin_impl.h \ LIBGRPCPP_CHANNELZ_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPCPP_CHANNELZ_SRC)))) @@ -8045,1997 +8309,9 @@ ifneq ($(NO_DEPS),true) endif -LIBBORINGSSL_CRYPTO_TEST_DATA_LIB_SRC = \ - src/boringssl/crypto_test_data.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_CRYPTO_TEST_DATA_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_CRYPTO_TEST_DATA_LIB_SRC)))) - -$(LIBBORINGSSL_CRYPTO_TEST_DATA_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_CRYPTO_TEST_DATA_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_CRYPTO_TEST_DATA_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -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)/libboringssl_crypto_test_data_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_crypto_test_data_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_CRYPTO_TEST_DATA_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_crypto_test_data_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_crypto_test_data_lib.a $(LIBBORINGSSL_CRYPTO_TEST_DATA_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_crypto_test_data_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_CRYPTO_TEST_DATA_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_ASN1_TEST_LIB_SRC = \ - third_party/boringssl/crypto/asn1/asn1_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_ASN1_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_ASN1_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_ASN1_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_ASN1_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_ASN1_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -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)/libboringssl_asn1_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_asn1_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_ASN1_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_asn1_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_asn1_test_lib.a $(LIBBORINGSSL_ASN1_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_asn1_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_ASN1_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_BASE64_TEST_LIB_SRC = \ - third_party/boringssl/crypto/base64/base64_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_BASE64_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_BASE64_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_BASE64_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_BASE64_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_BASE64_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -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)/libboringssl_base64_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_base64_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_BASE64_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_base64_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_base64_test_lib.a $(LIBBORINGSSL_BASE64_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_base64_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_BASE64_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_BIO_TEST_LIB_SRC = \ - third_party/boringssl/crypto/bio/bio_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_BIO_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_BIO_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_BIO_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_BIO_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_BIO_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -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)/libboringssl_bio_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_bio_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_BIO_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_bio_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_bio_test_lib.a $(LIBBORINGSSL_BIO_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_bio_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_BIO_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_BUF_TEST_LIB_SRC = \ - third_party/boringssl/crypto/buf/buf_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_BUF_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_BUF_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_BUF_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_BUF_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_BUF_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -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)/libboringssl_buf_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_buf_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_BUF_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_buf_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_buf_test_lib.a $(LIBBORINGSSL_BUF_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_buf_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_BUF_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_BYTESTRING_TEST_LIB_SRC = \ - third_party/boringssl/crypto/bytestring/bytestring_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_BYTESTRING_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_BYTESTRING_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_BYTESTRING_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_BYTESTRING_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_BYTESTRING_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -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)/libboringssl_bytestring_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_bytestring_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_BYTESTRING_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_bytestring_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_bytestring_test_lib.a $(LIBBORINGSSL_BYTESTRING_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_bytestring_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_BYTESTRING_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_CHACHA_TEST_LIB_SRC = \ - third_party/boringssl/crypto/chacha/chacha_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_CHACHA_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_CHACHA_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_CHACHA_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_CHACHA_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_CHACHA_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -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)/libboringssl_chacha_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_chacha_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_CHACHA_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_chacha_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_chacha_test_lib.a $(LIBBORINGSSL_CHACHA_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_chacha_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_CHACHA_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_AEAD_TEST_LIB_SRC = \ - third_party/boringssl/crypto/cipher_extra/aead_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_AEAD_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_AEAD_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_AEAD_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_AEAD_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_AEAD_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -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)/libboringssl_aead_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_aead_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_AEAD_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_aead_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_aead_test_lib.a $(LIBBORINGSSL_AEAD_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_aead_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_AEAD_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_CIPHER_TEST_LIB_SRC = \ - third_party/boringssl/crypto/cipher_extra/cipher_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_CIPHER_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_CIPHER_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_CIPHER_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_CIPHER_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_CIPHER_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -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)/libboringssl_cipher_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_cipher_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_CIPHER_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_cipher_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_cipher_test_lib.a $(LIBBORINGSSL_CIPHER_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_cipher_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_CIPHER_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_CMAC_TEST_LIB_SRC = \ - third_party/boringssl/crypto/cmac/cmac_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_CMAC_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_CMAC_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_CMAC_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_CMAC_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_CMAC_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -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)/libboringssl_cmac_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_cmac_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_CMAC_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_cmac_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_cmac_test_lib.a $(LIBBORINGSSL_CMAC_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_cmac_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_CMAC_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_COMPILER_TEST_LIB_SRC = \ - third_party/boringssl/crypto/compiler_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_COMPILER_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_COMPILER_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_COMPILER_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_COMPILER_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_COMPILER_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -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)/libboringssl_compiler_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_compiler_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_COMPILER_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_compiler_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_compiler_test_lib.a $(LIBBORINGSSL_COMPILER_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_compiler_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_COMPILER_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_CONSTANT_TIME_TEST_LIB_SRC = \ - third_party/boringssl/crypto/constant_time_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_CONSTANT_TIME_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_CONSTANT_TIME_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_CONSTANT_TIME_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_CONSTANT_TIME_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_CONSTANT_TIME_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -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)/libboringssl_constant_time_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_constant_time_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_CONSTANT_TIME_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_constant_time_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_constant_time_test_lib.a $(LIBBORINGSSL_CONSTANT_TIME_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_constant_time_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_CONSTANT_TIME_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_ED25519_TEST_LIB_SRC = \ - third_party/boringssl/crypto/curve25519/ed25519_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_ED25519_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_ED25519_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_ED25519_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_ED25519_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_ED25519_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -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)/libboringssl_ed25519_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_ed25519_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_ED25519_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_ed25519_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_ed25519_test_lib.a $(LIBBORINGSSL_ED25519_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_ed25519_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_ED25519_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_SPAKE25519_TEST_LIB_SRC = \ - third_party/boringssl/crypto/curve25519/spake25519_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_SPAKE25519_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_SPAKE25519_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_SPAKE25519_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_SPAKE25519_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_SPAKE25519_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -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)/libboringssl_spake25519_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_spake25519_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_SPAKE25519_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_spake25519_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_spake25519_test_lib.a $(LIBBORINGSSL_SPAKE25519_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_spake25519_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_SPAKE25519_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_X25519_TEST_LIB_SRC = \ - third_party/boringssl/crypto/curve25519/x25519_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_X25519_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_X25519_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_X25519_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_X25519_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_X25519_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -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)/libboringssl_x25519_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_x25519_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_X25519_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_x25519_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_x25519_test_lib.a $(LIBBORINGSSL_X25519_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_x25519_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_X25519_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_DH_TEST_LIB_SRC = \ - third_party/boringssl/crypto/dh/dh_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_DH_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_DH_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_DH_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_DH_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_DH_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -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)/libboringssl_dh_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_dh_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_DH_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_dh_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_dh_test_lib.a $(LIBBORINGSSL_DH_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_dh_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_DH_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_DIGEST_TEST_LIB_SRC = \ - third_party/boringssl/crypto/digest_extra/digest_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_DIGEST_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_DIGEST_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_DIGEST_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_DIGEST_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_DIGEST_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -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)/libboringssl_digest_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_digest_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_DIGEST_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_digest_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_digest_test_lib.a $(LIBBORINGSSL_DIGEST_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_digest_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_DIGEST_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_DSA_TEST_LIB_SRC = \ - third_party/boringssl/crypto/dsa/dsa_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_DSA_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_DSA_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_DSA_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_DSA_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_DSA_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -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)/libboringssl_dsa_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_dsa_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_DSA_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_dsa_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_dsa_test_lib.a $(LIBBORINGSSL_DSA_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_dsa_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_DSA_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_ECDH_TEST_LIB_SRC = \ - third_party/boringssl/crypto/ecdh/ecdh_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_ECDH_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_ECDH_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_ECDH_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_ECDH_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_ECDH_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -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)/libboringssl_ecdh_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_ecdh_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_ECDH_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_ecdh_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_ecdh_test_lib.a $(LIBBORINGSSL_ECDH_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_ecdh_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_ECDH_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_ERR_TEST_LIB_SRC = \ - third_party/boringssl/crypto/err/err_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_ERR_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_ERR_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_ERR_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_ERR_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_ERR_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -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)/libboringssl_err_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_err_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_ERR_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_err_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_err_test_lib.a $(LIBBORINGSSL_ERR_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_err_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_ERR_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_EVP_EXTRA_TEST_LIB_SRC = \ - third_party/boringssl/crypto/evp/evp_extra_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_EVP_EXTRA_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_EVP_EXTRA_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_EVP_EXTRA_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_EVP_EXTRA_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_EVP_EXTRA_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -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)/libboringssl_evp_extra_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_evp_extra_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_EVP_EXTRA_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_evp_extra_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_evp_extra_test_lib.a $(LIBBORINGSSL_EVP_EXTRA_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_evp_extra_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_EVP_EXTRA_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_EVP_TEST_LIB_SRC = \ - third_party/boringssl/crypto/evp/evp_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_EVP_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_EVP_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_EVP_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_EVP_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_EVP_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -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)/libboringssl_evp_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_evp_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_EVP_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_evp_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_evp_test_lib.a $(LIBBORINGSSL_EVP_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_evp_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_EVP_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_PBKDF_TEST_LIB_SRC = \ - third_party/boringssl/crypto/evp/pbkdf_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_PBKDF_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_PBKDF_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_PBKDF_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_PBKDF_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_PBKDF_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -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)/libboringssl_pbkdf_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_pbkdf_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_PBKDF_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_pbkdf_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_pbkdf_test_lib.a $(LIBBORINGSSL_PBKDF_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_pbkdf_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_PBKDF_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_SCRYPT_TEST_LIB_SRC = \ - third_party/boringssl/crypto/evp/scrypt_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_SCRYPT_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_SCRYPT_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_SCRYPT_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_SCRYPT_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_SCRYPT_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -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)/libboringssl_scrypt_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_scrypt_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_SCRYPT_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_scrypt_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_scrypt_test_lib.a $(LIBBORINGSSL_SCRYPT_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_scrypt_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_SCRYPT_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_AES_TEST_LIB_SRC = \ - third_party/boringssl/crypto/fipsmodule/aes/aes_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_AES_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_AES_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_AES_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_AES_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_AES_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -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)/libboringssl_aes_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_aes_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_AES_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_aes_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_aes_test_lib.a $(LIBBORINGSSL_AES_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_aes_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_AES_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_BN_TEST_LIB_SRC = \ - third_party/boringssl/crypto/fipsmodule/bn/bn_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_BN_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_BN_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_BN_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_BN_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_BN_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -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)/libboringssl_bn_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_bn_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_BN_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_bn_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_bn_test_lib.a $(LIBBORINGSSL_BN_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_bn_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_BN_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_EC_TEST_LIB_SRC = \ - third_party/boringssl/crypto/fipsmodule/ec/ec_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_EC_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_EC_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_EC_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_EC_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_EC_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -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)/libboringssl_ec_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_ec_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_EC_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_ec_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_ec_test_lib.a $(LIBBORINGSSL_EC_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_ec_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_EC_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_P256-X86_64_TEST_LIB_SRC = \ - third_party/boringssl/crypto/fipsmodule/ec/p256-x86_64_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_P256-X86_64_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_P256-X86_64_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_P256-X86_64_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_P256-X86_64_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_P256-X86_64_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -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)/libboringssl_p256-x86_64_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_p256-x86_64_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_P256-X86_64_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_p256-x86_64_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_p256-x86_64_test_lib.a $(LIBBORINGSSL_P256-X86_64_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_p256-x86_64_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_P256-X86_64_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_ECDSA_TEST_LIB_SRC = \ - third_party/boringssl/crypto/fipsmodule/ecdsa/ecdsa_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_ECDSA_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_ECDSA_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_ECDSA_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_ECDSA_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_ECDSA_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -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)/libboringssl_ecdsa_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_ECDSA_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_test_lib.a $(LIBBORINGSSL_ECDSA_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_ECDSA_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_GCM_TEST_LIB_SRC = \ - third_party/boringssl/crypto/fipsmodule/modes/gcm_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_GCM_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_GCM_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_GCM_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_GCM_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_GCM_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -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)/libboringssl_gcm_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_gcm_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_GCM_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_gcm_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_gcm_test_lib.a $(LIBBORINGSSL_GCM_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_gcm_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_GCM_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_CTRDRBG_TEST_LIB_SRC = \ - third_party/boringssl/crypto/fipsmodule/rand/ctrdrbg_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_CTRDRBG_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_CTRDRBG_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_CTRDRBG_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_CTRDRBG_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_CTRDRBG_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -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)/libboringssl_ctrdrbg_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_ctrdrbg_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_CTRDRBG_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_ctrdrbg_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_ctrdrbg_test_lib.a $(LIBBORINGSSL_CTRDRBG_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_ctrdrbg_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_CTRDRBG_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_HKDF_TEST_LIB_SRC = \ - third_party/boringssl/crypto/hkdf/hkdf_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_HKDF_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_HKDF_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_HKDF_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_HKDF_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_HKDF_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -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)/libboringssl_hkdf_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_hkdf_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_HKDF_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_hkdf_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_hkdf_test_lib.a $(LIBBORINGSSL_HKDF_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_hkdf_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_HKDF_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_HMAC_TEST_LIB_SRC = \ - third_party/boringssl/crypto/hmac_extra/hmac_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_HMAC_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_HMAC_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_HMAC_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_HMAC_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_HMAC_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -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)/libboringssl_hmac_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_hmac_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_HMAC_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_hmac_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_hmac_test_lib.a $(LIBBORINGSSL_HMAC_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_hmac_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_HMAC_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_LHASH_TEST_LIB_SRC = \ - third_party/boringssl/crypto/lhash/lhash_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_LHASH_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_LHASH_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_LHASH_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_LHASH_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_LHASH_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -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)/libboringssl_lhash_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_lhash_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_LHASH_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_lhash_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_lhash_test_lib.a $(LIBBORINGSSL_LHASH_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_lhash_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_LHASH_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_OBJ_TEST_LIB_SRC = \ - third_party/boringssl/crypto/obj/obj_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_OBJ_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_OBJ_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_OBJ_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_OBJ_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_OBJ_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -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)/libboringssl_obj_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_obj_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_OBJ_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_obj_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_obj_test_lib.a $(LIBBORINGSSL_OBJ_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_obj_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_OBJ_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_PKCS7_TEST_LIB_SRC = \ - third_party/boringssl/crypto/pkcs7/pkcs7_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_PKCS7_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_PKCS7_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_PKCS7_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_PKCS7_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_PKCS7_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -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)/libboringssl_pkcs7_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_pkcs7_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_PKCS7_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_pkcs7_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_pkcs7_test_lib.a $(LIBBORINGSSL_PKCS7_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_pkcs7_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_PKCS7_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_PKCS12_TEST_LIB_SRC = \ - third_party/boringssl/crypto/pkcs8/pkcs12_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_PKCS12_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_PKCS12_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_PKCS12_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_PKCS12_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_PKCS12_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -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)/libboringssl_pkcs12_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_pkcs12_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_PKCS12_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_pkcs12_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_pkcs12_test_lib.a $(LIBBORINGSSL_PKCS12_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_pkcs12_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_PKCS12_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_PKCS8_TEST_LIB_SRC = \ - third_party/boringssl/crypto/pkcs8/pkcs8_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_PKCS8_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_PKCS8_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_PKCS8_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_PKCS8_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_PKCS8_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -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)/libboringssl_pkcs8_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_pkcs8_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_PKCS8_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_pkcs8_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_pkcs8_test_lib.a $(LIBBORINGSSL_PKCS8_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_pkcs8_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_PKCS8_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_POLY1305_TEST_LIB_SRC = \ - third_party/boringssl/crypto/poly1305/poly1305_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_POLY1305_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_POLY1305_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_POLY1305_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_POLY1305_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_POLY1305_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -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)/libboringssl_poly1305_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_poly1305_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_POLY1305_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_poly1305_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_poly1305_test_lib.a $(LIBBORINGSSL_POLY1305_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_poly1305_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_POLY1305_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_POOL_TEST_LIB_SRC = \ - third_party/boringssl/crypto/pool/pool_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_POOL_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_POOL_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_POOL_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_POOL_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_POOL_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -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)/libboringssl_pool_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_pool_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_POOL_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_pool_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_pool_test_lib.a $(LIBBORINGSSL_POOL_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_pool_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_POOL_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_REFCOUNT_TEST_LIB_SRC = \ - third_party/boringssl/crypto/refcount_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_REFCOUNT_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_REFCOUNT_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_REFCOUNT_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_REFCOUNT_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_REFCOUNT_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -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)/libboringssl_refcount_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_refcount_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_REFCOUNT_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_refcount_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_refcount_test_lib.a $(LIBBORINGSSL_REFCOUNT_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_refcount_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_REFCOUNT_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_RSA_TEST_LIB_SRC = \ - third_party/boringssl/crypto/rsa_extra/rsa_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_RSA_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_RSA_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_RSA_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_RSA_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_RSA_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -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)/libboringssl_rsa_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_rsa_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_RSA_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_rsa_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_rsa_test_lib.a $(LIBBORINGSSL_RSA_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_rsa_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_RSA_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_SELF_TEST_LIB_SRC = \ - third_party/boringssl/crypto/self_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_SELF_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_SELF_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_SELF_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_SELF_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_SELF_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -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)/libboringssl_self_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_self_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_SELF_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_self_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_self_test_lib.a $(LIBBORINGSSL_SELF_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_self_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_SELF_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_FILE_TEST_GTEST_LIB_SRC = \ - third_party/boringssl/crypto/test/file_test_gtest.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_FILE_TEST_GTEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_FILE_TEST_GTEST_LIB_SRC)))) - -$(LIBBORINGSSL_FILE_TEST_GTEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_FILE_TEST_GTEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_FILE_TEST_GTEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -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)/libboringssl_file_test_gtest_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_file_test_gtest_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_FILE_TEST_GTEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_file_test_gtest_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_file_test_gtest_lib.a $(LIBBORINGSSL_FILE_TEST_GTEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_file_test_gtest_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_FILE_TEST_GTEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_GTEST_MAIN_LIB_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_GTEST_MAIN_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_GTEST_MAIN_LIB_SRC)))) - -$(LIBBORINGSSL_GTEST_MAIN_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_GTEST_MAIN_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_GTEST_MAIN_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -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)/libboringssl_gtest_main_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_gtest_main_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_GTEST_MAIN_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_gtest_main_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_gtest_main_lib.a $(LIBBORINGSSL_GTEST_MAIN_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_gtest_main_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_GTEST_MAIN_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_THREAD_TEST_LIB_SRC = \ - third_party/boringssl/crypto/thread_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_THREAD_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_THREAD_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_THREAD_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_THREAD_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_THREAD_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -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)/libboringssl_thread_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_thread_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_THREAD_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_thread_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_thread_test_lib.a $(LIBBORINGSSL_THREAD_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_thread_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_THREAD_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_X509_TEST_LIB_SRC = \ - third_party/boringssl/crypto/x509/x509_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_X509_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_X509_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_X509_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_X509_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_X509_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -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)/libboringssl_x509_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_x509_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_X509_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_x509_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_x509_test_lib.a $(LIBBORINGSSL_X509_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_x509_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_X509_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_TAB_TEST_LIB_SRC = \ - third_party/boringssl/crypto/x509v3/tab_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_TAB_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_TAB_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_TAB_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_TAB_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_TAB_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -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)/libboringssl_tab_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_tab_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_TAB_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_tab_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_tab_test_lib.a $(LIBBORINGSSL_TAB_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_tab_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_TAB_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_V3NAME_TEST_LIB_SRC = \ - third_party/boringssl/crypto/x509v3/v3name_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_V3NAME_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_V3NAME_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_V3NAME_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_V3NAME_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_V3NAME_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -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)/libboringssl_v3name_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_v3name_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_V3NAME_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_v3name_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_v3name_test_lib.a $(LIBBORINGSSL_V3NAME_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_v3name_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_V3NAME_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_SPAN_TEST_LIB_SRC = \ - third_party/boringssl/ssl/span_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_SPAN_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_SPAN_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_SPAN_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_SPAN_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_SPAN_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -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)/libboringssl_span_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_span_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_SPAN_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_span_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_span_test_lib.a $(LIBBORINGSSL_SPAN_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_span_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_SPAN_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_SSL_TEST_LIB_SRC = \ - third_party/boringssl/ssl/ssl_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_SSL_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_SSL_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_SSL_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_SSL_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_SSL_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -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)/libboringssl_ssl_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_ssl_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_SSL_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_ssl_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_ssl_test_lib.a $(LIBBORINGSSL_SSL_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_ssl_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_SSL_TEST_LIB_OBJS:.o=.dep) -endif - - LIBBENCHMARK_SRC = \ third_party/benchmark/src/benchmark.cc \ + third_party/benchmark/src/benchmark_main.cc \ third_party/benchmark/src/benchmark_register.cc \ third_party/benchmark/src/colorprint.cc \ third_party/benchmark/src/commandlineflags.cc \ @@ -10046,6 +8322,7 @@ LIBBENCHMARK_SRC = \ third_party/benchmark/src/json_reporter.cc \ third_party/benchmark/src/reporter.cc \ third_party/benchmark/src/sleep.cc \ + third_party/benchmark/src/statistics.cc \ third_party/benchmark/src/string_util.cc \ third_party/benchmark/src/sysinfo.cc \ third_party/benchmark/src/timers.cc \ @@ -10084,6 +8361,41 @@ ifneq ($(NO_DEPS),true) endif +LIBUPB_SRC = \ + third_party/upb/google/protobuf/descriptor.upb.c \ + third_party/upb/upb/decode.c \ + third_party/upb/upb/def.c \ + third_party/upb/upb/encode.c \ + third_party/upb/upb/handlers.c \ + third_party/upb/upb/msg.c \ + third_party/upb/upb/msgfactory.c \ + third_party/upb/upb/sink.c \ + third_party/upb/upb/table.c \ + third_party/upb/upb/upb.c \ + +PUBLIC_HEADERS_C += \ + +LIBUPB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBUPB_SRC)))) + +$(LIBUPB_OBJS): CFLAGS += -Ithird_party/upb -Wno-sign-conversion -Wno-shadow -Wno-conversion -Wno-implicit-fallthrough -Wno-sign-compare -Wno-missing-field-initializers + +$(LIBDIR)/$(CONFIG)/libupb.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(LIBUPB_OBJS) + $(E) "[AR] Creating $@" + $(Q) mkdir -p `dirname $@` + $(Q) rm -f $(LIBDIR)/$(CONFIG)/libupb.a + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libupb.a $(LIBUPB_OBJS) +ifeq ($(SYSTEM),Darwin) + $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libupb.a +endif + + + + +ifneq ($(NO_DEPS),true) +-include $(LIBUPB_OBJS:.o=.dep) +endif + + LIBZ_SRC = \ third_party/zlib/adler32.c \ third_party/zlib/compress.c \ @@ -10167,6 +8479,7 @@ LIBARES_SRC = \ third_party/cares/cares/ares_strcasecmp.c \ third_party/cares/cares/ares_strdup.c \ third_party/cares/cares/ares_strerror.c \ + third_party/cares/cares/ares_strsplit.c \ third_party/cares/cares/ares_timeout.c \ third_party/cares/cares/ares_version.c \ third_party/cares/cares/ares_writev.c \ @@ -10301,6 +8614,7 @@ LIBEND2END_TESTS_SRC = \ test/core/end2end/tests/empty_batch.cc \ test/core/end2end/tests/filter_call_init_fails.cc \ test/core/end2end/tests/filter_causes_close.cc \ + test/core/end2end/tests/filter_context.cc \ test/core/end2end/tests/filter_latency.cc \ test/core/end2end/tests/filter_status_code.cc \ test/core/end2end/tests/graceful_server_shutdown.cc \ @@ -10315,7 +8629,6 @@ LIBEND2END_TESTS_SRC = \ test/core/end2end/tests/max_connection_idle.cc \ test/core/end2end/tests/max_message_length.cc \ test/core/end2end/tests/negative_deadline.cc \ - test/core/end2end/tests/network_status_change.cc \ test/core/end2end/tests/no_error_on_hotpath.cc \ test/core/end2end/tests/no_logging.cc \ test/core/end2end/tests/no_op.cc \ @@ -10418,6 +8731,7 @@ LIBEND2END_NOSEC_TESTS_SRC = \ test/core/end2end/tests/empty_batch.cc \ test/core/end2end/tests/filter_call_init_fails.cc \ test/core/end2end/tests/filter_causes_close.cc \ + test/core/end2end/tests/filter_context.cc \ test/core/end2end/tests/filter_latency.cc \ test/core/end2end/tests/filter_status_code.cc \ test/core/end2end/tests/graceful_server_shutdown.cc \ @@ -10432,7 +8746,6 @@ LIBEND2END_NOSEC_TESTS_SRC = \ test/core/end2end/tests/max_connection_idle.cc \ test/core/end2end/tests/max_message_length.cc \ test/core/end2end/tests/negative_deadline.cc \ - test/core/end2end/tests/network_status_change.cc \ test/core/end2end/tests/no_error_on_hotpath.cc \ test/core/end2end/tests/no_logging.cc \ test/core/end2end/tests/no_op.cc \ @@ -10516,14 +8829,14 @@ else -$(BINDIR)/$(CONFIG)/algorithm_test: $(ALGORITHM_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/algorithm_test: $(ALGORITHM_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(ALGORITHM_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)/algorithm_test + $(Q) $(LD) $(LDFLAGS) $(ALGORITHM_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/algorithm_test endif -$(OBJDIR)/$(CONFIG)/test/core/compression/algorithm_test.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/compression/algorithm_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_algorithm_test: $(ALGORITHM_TEST_OBJS:.o=.dep) @@ -10548,14 +8861,14 @@ else -$(BINDIR)/$(CONFIG)/alloc_test: $(ALLOC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/alloc_test: $(ALLOC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(ALLOC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/alloc_test + $(Q) $(LD) $(LDFLAGS) $(ALLOC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/alloc_test endif -$(OBJDIR)/$(CONFIG)/test/core/gpr/alloc_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gpr/alloc_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a deps_alloc_test: $(ALLOC_TEST_OBJS:.o=.dep) @@ -10580,14 +8893,14 @@ else -$(BINDIR)/$(CONFIG)/alpn_test: $(ALPN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/alpn_test: $(ALPN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(ALPN_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)/alpn_test + $(Q) $(LD) $(LDFLAGS) $(ALPN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/alpn_test endif -$(OBJDIR)/$(CONFIG)/test/core/transport/chttp2/alpn_test.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/transport/chttp2/alpn_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_alpn_test: $(ALPN_TEST_OBJS:.o=.dep) @@ -10612,14 +8925,14 @@ 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 +$(BINDIR)/$(CONFIG)/alts_credentials_fuzzer: $(ALTS_CREDENTIALS_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.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 + $(Q) $(LDXX) $(LDFLAGS) $(ALTS_CREDENTIALS_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.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 +$(OBJDIR)/$(CONFIG)/test/core/security/alts_credentials_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_alts_credentials_fuzzer: $(ALTS_CREDENTIALS_FUZZER_OBJS:.o=.dep) @@ -10644,14 +8957,14 @@ else -$(BINDIR)/$(CONFIG)/api_fuzzer: $(API_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/api_fuzzer: $(API_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(API_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)/api_fuzzer + $(Q) $(LDXX) $(LDFLAGS) $(API_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/api_fuzzer endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fuzzers/api_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/end2end/fuzzers/api_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_api_fuzzer: $(API_FUZZER_OBJS:.o=.dep) @@ -10676,14 +8989,14 @@ else -$(BINDIR)/$(CONFIG)/arena_test: $(ARENA_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/arena_test: $(ARENA_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(ARENA_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/arena_test + $(Q) $(LD) $(LDFLAGS) $(ARENA_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/arena_test endif -$(OBJDIR)/$(CONFIG)/test/core/gpr/arena_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gpr/arena_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a deps_arena_test: $(ARENA_TEST_OBJS:.o=.dep) @@ -10708,14 +9021,14 @@ else -$(BINDIR)/$(CONFIG)/avl_test: $(AVL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a +$(BINDIR)/$(CONFIG)/avl_test: $(AVL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(AVL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/avl_test + $(Q) $(LD) $(LDFLAGS) $(AVL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/avl_test endif -$(OBJDIR)/$(CONFIG)/test/core/avl/avl_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a +$(OBJDIR)/$(CONFIG)/test/core/avl/avl_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a deps_avl_test: $(AVL_TEST_OBJS:.o=.dep) @@ -10740,14 +9053,14 @@ else -$(BINDIR)/$(CONFIG)/bad_server_response_test: $(BAD_SERVER_RESPONSE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/bad_server_response_test: $(BAD_SERVER_RESPONSE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(BAD_SERVER_RESPONSE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(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)/bad_server_response_test + $(Q) $(LD) $(LDFLAGS) $(BAD_SERVER_RESPONSE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/bad_server_response_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/bad_server_response_test.o: $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/bad_server_response_test.o: $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_bad_server_response_test: $(BAD_SERVER_RESPONSE_TEST_OBJS:.o=.dep) @@ -10836,14 +9149,14 @@ else -$(BINDIR)/$(CONFIG)/buffer_list_test: $(BUFFER_LIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/buffer_list_test: $(BUFFER_LIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(BUFFER_LIST_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)/buffer_list_test + $(Q) $(LD) $(LDFLAGS) $(BUFFER_LIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/buffer_list_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/buffer_list_test.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/iomgr/buffer_list_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_buffer_list_test: $(BUFFER_LIST_TEST_OBJS:.o=.dep) @@ -10868,14 +9181,14 @@ else -$(BINDIR)/$(CONFIG)/channel_create_test: $(CHANNEL_CREATE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/channel_create_test: $(CHANNEL_CREATE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(CHANNEL_CREATE_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)/channel_create_test + $(Q) $(LD) $(LDFLAGS) $(CHANNEL_CREATE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/channel_create_test endif -$(OBJDIR)/$(CONFIG)/test/core/surface/channel_create_test.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/surface/channel_create_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_channel_create_test: $(CHANNEL_CREATE_TEST_OBJS:.o=.dep) @@ -10932,14 +9245,14 @@ else -$(BINDIR)/$(CONFIG)/chttp2_hpack_encoder_test: $(CHTTP2_HPACK_ENCODER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/chttp2_hpack_encoder_test: $(CHTTP2_HPACK_ENCODER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(CHTTP2_HPACK_ENCODER_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)/chttp2_hpack_encoder_test + $(Q) $(LD) $(LDFLAGS) $(CHTTP2_HPACK_ENCODER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/chttp2_hpack_encoder_test endif -$(OBJDIR)/$(CONFIG)/test/core/transport/chttp2/hpack_encoder_test.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/transport/chttp2/hpack_encoder_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_chttp2_hpack_encoder_test: $(CHTTP2_HPACK_ENCODER_TEST_OBJS:.o=.dep) @@ -10964,14 +9277,14 @@ else -$(BINDIR)/$(CONFIG)/chttp2_stream_map_test: $(CHTTP2_STREAM_MAP_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/chttp2_stream_map_test: $(CHTTP2_STREAM_MAP_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(CHTTP2_STREAM_MAP_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)/chttp2_stream_map_test + $(Q) $(LD) $(LDFLAGS) $(CHTTP2_STREAM_MAP_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/chttp2_stream_map_test endif -$(OBJDIR)/$(CONFIG)/test/core/transport/chttp2/stream_map_test.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/transport/chttp2/stream_map_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_chttp2_stream_map_test: $(CHTTP2_STREAM_MAP_TEST_OBJS:.o=.dep) @@ -10996,14 +9309,14 @@ else -$(BINDIR)/$(CONFIG)/chttp2_varint_test: $(CHTTP2_VARINT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/chttp2_varint_test: $(CHTTP2_VARINT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(CHTTP2_VARINT_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)/chttp2_varint_test + $(Q) $(LD) $(LDFLAGS) $(CHTTP2_VARINT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/chttp2_varint_test endif -$(OBJDIR)/$(CONFIG)/test/core/transport/chttp2/varint_test.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/transport/chttp2/varint_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_chttp2_varint_test: $(CHTTP2_VARINT_TEST_OBJS:.o=.dep) @@ -11028,14 +9341,14 @@ else -$(BINDIR)/$(CONFIG)/client_fuzzer: $(CLIENT_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/client_fuzzer: $(CLIENT_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(CLIENT_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)/client_fuzzer + $(Q) $(LDXX) $(LDFLAGS) $(CLIENT_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/client_fuzzer endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fuzzers/client_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/end2end/fuzzers/client_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_client_fuzzer: $(CLIENT_FUZZER_OBJS:.o=.dep) @@ -11046,6 +9359,38 @@ endif endif +CLOSE_FD_TEST_SRC = \ + test/core/bad_connection/close_fd_test.cc \ + +CLOSE_FD_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(CLOSE_FD_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/close_fd_test: openssl_dep_error + +else + + + +$(BINDIR)/$(CONFIG)/close_fd_test: $(CLOSE_FD_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LD) $(LDFLAGS) $(CLOSE_FD_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/close_fd_test + +endif + +$(OBJDIR)/$(CONFIG)/test/core/bad_connection/close_fd_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_close_fd_test: $(CLOSE_FD_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(CLOSE_FD_TEST_OBJS:.o=.dep) +endif +endif + + CMDLINE_TEST_SRC = \ test/core/util/cmdline_test.cc \ @@ -11060,14 +9405,14 @@ else -$(BINDIR)/$(CONFIG)/cmdline_test: $(CMDLINE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a +$(BINDIR)/$(CONFIG)/cmdline_test: $(CMDLINE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(CMDLINE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/cmdline_test + $(Q) $(LD) $(LDFLAGS) $(CMDLINE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/cmdline_test endif -$(OBJDIR)/$(CONFIG)/test/core/util/cmdline_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a +$(OBJDIR)/$(CONFIG)/test/core/util/cmdline_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a deps_cmdline_test: $(CMDLINE_TEST_OBJS:.o=.dep) @@ -11092,14 +9437,14 @@ else -$(BINDIR)/$(CONFIG)/combiner_test: $(COMBINER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/combiner_test: $(COMBINER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(COMBINER_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)/combiner_test + $(Q) $(LD) $(LDFLAGS) $(COMBINER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/combiner_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/combiner_test.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/iomgr/combiner_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_combiner_test: $(COMBINER_TEST_OBJS:.o=.dep) @@ -11124,14 +9469,14 @@ else -$(BINDIR)/$(CONFIG)/compression_test: $(COMPRESSION_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/compression_test: $(COMPRESSION_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(COMPRESSION_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)/compression_test + $(Q) $(LD) $(LDFLAGS) $(COMPRESSION_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/compression_test endif -$(OBJDIR)/$(CONFIG)/test/core/compression/compression_test.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/compression/compression_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_compression_test: $(COMPRESSION_TEST_OBJS:.o=.dep) @@ -11156,14 +9501,14 @@ else -$(BINDIR)/$(CONFIG)/concurrent_connectivity_test: $(CONCURRENT_CONNECTIVITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/concurrent_connectivity_test: $(CONCURRENT_CONNECTIVITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(CONCURRENT_CONNECTIVITY_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)/concurrent_connectivity_test + $(Q) $(LD) $(LDFLAGS) $(CONCURRENT_CONNECTIVITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/concurrent_connectivity_test endif -$(OBJDIR)/$(CONFIG)/test/core/surface/concurrent_connectivity_test.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/surface/concurrent_connectivity_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_concurrent_connectivity_test: $(CONCURRENT_CONNECTIVITY_TEST_OBJS:.o=.dep) @@ -11188,14 +9533,14 @@ else -$(BINDIR)/$(CONFIG)/connection_refused_test: $(CONNECTION_REFUSED_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/connection_refused_test: $(CONNECTION_REFUSED_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(CONNECTION_REFUSED_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)/connection_refused_test + $(Q) $(LD) $(LDFLAGS) $(CONNECTION_REFUSED_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/connection_refused_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/connection_refused_test.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/end2end/connection_refused_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_connection_refused_test: $(CONNECTION_REFUSED_TEST_OBJS:.o=.dep) @@ -11220,14 +9565,14 @@ else -$(BINDIR)/$(CONFIG)/dns_resolver_connectivity_test: $(DNS_RESOLVER_CONNECTIVITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/dns_resolver_connectivity_test: $(DNS_RESOLVER_CONNECTIVITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(DNS_RESOLVER_CONNECTIVITY_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)/dns_resolver_connectivity_test + $(Q) $(LD) $(LDFLAGS) $(DNS_RESOLVER_CONNECTIVITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/dns_resolver_connectivity_test endif -$(OBJDIR)/$(CONFIG)/test/core/client_channel/resolvers/dns_resolver_connectivity_test.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/client_channel/resolvers/dns_resolver_connectivity_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_dns_resolver_connectivity_test: $(DNS_RESOLVER_CONNECTIVITY_TEST_OBJS:.o=.dep) @@ -11252,14 +9597,14 @@ else -$(BINDIR)/$(CONFIG)/dns_resolver_cooldown_test: $(DNS_RESOLVER_COOLDOWN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/dns_resolver_cooldown_test: $(DNS_RESOLVER_COOLDOWN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(DNS_RESOLVER_COOLDOWN_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)/dns_resolver_cooldown_test + $(Q) $(LD) $(LDFLAGS) $(DNS_RESOLVER_COOLDOWN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/dns_resolver_cooldown_test endif -$(OBJDIR)/$(CONFIG)/test/core/client_channel/resolvers/dns_resolver_cooldown_test.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/client_channel/resolvers/dns_resolver_cooldown_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_dns_resolver_cooldown_test: $(DNS_RESOLVER_COOLDOWN_TEST_OBJS:.o=.dep) @@ -11284,14 +9629,14 @@ else -$(BINDIR)/$(CONFIG)/dns_resolver_test: $(DNS_RESOLVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/dns_resolver_test: $(DNS_RESOLVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(DNS_RESOLVER_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)/dns_resolver_test + $(Q) $(LD) $(LDFLAGS) $(DNS_RESOLVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/dns_resolver_test endif -$(OBJDIR)/$(CONFIG)/test/core/client_channel/resolvers/dns_resolver_test.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/client_channel/resolvers/dns_resolver_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_dns_resolver_test: $(DNS_RESOLVER_TEST_OBJS:.o=.dep) @@ -11316,14 +9661,14 @@ else -$(BINDIR)/$(CONFIG)/dualstack_socket_test: $(DUALSTACK_SOCKET_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/dualstack_socket_test: $(DUALSTACK_SOCKET_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(DUALSTACK_SOCKET_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)/dualstack_socket_test + $(Q) $(LD) $(LDFLAGS) $(DUALSTACK_SOCKET_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/dualstack_socket_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/dualstack_socket_test.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/end2end/dualstack_socket_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_dualstack_socket_test: $(DUALSTACK_SOCKET_TEST_OBJS:.o=.dep) @@ -11348,14 +9693,14 @@ else -$(BINDIR)/$(CONFIG)/endpoint_pair_test: $(ENDPOINT_PAIR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/endpoint_pair_test: $(ENDPOINT_PAIR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(ENDPOINT_PAIR_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)/endpoint_pair_test + $(Q) $(LD) $(LDFLAGS) $(ENDPOINT_PAIR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/endpoint_pair_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/endpoint_pair_test.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/iomgr/endpoint_pair_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_endpoint_pair_test: $(ENDPOINT_PAIR_TEST_OBJS:.o=.dep) @@ -11380,14 +9725,14 @@ else -$(BINDIR)/$(CONFIG)/error_test: $(ERROR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/error_test: $(ERROR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(ERROR_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)/error_test + $(Q) $(LD) $(LDFLAGS) $(ERROR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/error_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/error_test.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/iomgr/error_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_error_test: $(ERROR_TEST_OBJS:.o=.dep) @@ -11412,14 +9757,14 @@ else -$(BINDIR)/$(CONFIG)/ev_epollex_linux_test: $(EV_EPOLLEX_LINUX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/ev_epollex_linux_test: $(EV_EPOLLEX_LINUX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(EV_EPOLLEX_LINUX_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)/ev_epollex_linux_test + $(Q) $(LD) $(LDFLAGS) $(EV_EPOLLEX_LINUX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/ev_epollex_linux_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/ev_epollex_linux_test.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/iomgr/ev_epollex_linux_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_ev_epollex_linux_test: $(EV_EPOLLEX_LINUX_TEST_OBJS:.o=.dep) @@ -11444,14 +9789,14 @@ else -$(BINDIR)/$(CONFIG)/fake_resolver_test: $(FAKE_RESOLVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/fake_resolver_test: $(FAKE_RESOLVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(FAKE_RESOLVER_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)/fake_resolver_test + $(Q) $(LD) $(LDFLAGS) $(FAKE_RESOLVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/fake_resolver_test endif -$(OBJDIR)/$(CONFIG)/test/core/client_channel/resolvers/fake_resolver_test.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/client_channel/resolvers/fake_resolver_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_fake_resolver_test: $(FAKE_RESOLVER_TEST_OBJS:.o=.dep) @@ -11477,16 +9822,16 @@ else -$(BINDIR)/$(CONFIG)/fake_transport_security_test: $(FAKE_TRANSPORT_SECURITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a +$(BINDIR)/$(CONFIG)/fake_transport_security_test: $(FAKE_TRANSPORT_SECURITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(FAKE_TRANSPORT_SECURITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/fake_transport_security_test + $(Q) $(LD) $(LDFLAGS) $(FAKE_TRANSPORT_SECURITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/fake_transport_security_test endif -$(OBJDIR)/$(CONFIG)/test/core/tsi/fake_transport_security_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a +$(OBJDIR)/$(CONFIG)/test/core/tsi/fake_transport_security_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a -$(OBJDIR)/$(CONFIG)/test/core/tsi/transport_security_test_lib.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a +$(OBJDIR)/$(CONFIG)/test/core/tsi/transport_security_test_lib.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a deps_fake_transport_security_test: $(FAKE_TRANSPORT_SECURITY_TEST_OBJS:.o=.dep) @@ -11511,14 +9856,14 @@ else -$(BINDIR)/$(CONFIG)/fd_conservation_posix_test: $(FD_CONSERVATION_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/fd_conservation_posix_test: $(FD_CONSERVATION_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(FD_CONSERVATION_POSIX_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)/fd_conservation_posix_test + $(Q) $(LD) $(LDFLAGS) $(FD_CONSERVATION_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/fd_conservation_posix_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/fd_conservation_posix_test.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/iomgr/fd_conservation_posix_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_fd_conservation_posix_test: $(FD_CONSERVATION_POSIX_TEST_OBJS:.o=.dep) @@ -11543,14 +9888,14 @@ else -$(BINDIR)/$(CONFIG)/fd_posix_test: $(FD_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/fd_posix_test: $(FD_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(FD_POSIX_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)/fd_posix_test + $(Q) $(LD) $(LDFLAGS) $(FD_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/fd_posix_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/fd_posix_test.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/iomgr/fd_posix_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_fd_posix_test: $(FD_POSIX_TEST_OBJS:.o=.dep) @@ -11575,14 +9920,14 @@ else -$(BINDIR)/$(CONFIG)/fling_client: $(FLING_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/fling_client: $(FLING_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(FLING_CLIENT_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)/fling_client + $(Q) $(LD) $(LDFLAGS) $(FLING_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/fling_client endif -$(OBJDIR)/$(CONFIG)/test/core/fling/client.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/fling/client.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_fling_client: $(FLING_CLIENT_OBJS:.o=.dep) @@ -11607,14 +9952,14 @@ else -$(BINDIR)/$(CONFIG)/fling_server: $(FLING_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/fling_server: $(FLING_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(FLING_SERVER_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)/fling_server + $(Q) $(LD) $(LDFLAGS) $(FLING_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/fling_server endif -$(OBJDIR)/$(CONFIG)/test/core/fling/server.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/fling/server.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_fling_server: $(FLING_SERVER_OBJS:.o=.dep) @@ -11639,14 +9984,14 @@ else -$(BINDIR)/$(CONFIG)/fling_stream_test: $(FLING_STREAM_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/fling_stream_test: $(FLING_STREAM_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(FLING_STREAM_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)/fling_stream_test + $(Q) $(LD) $(LDFLAGS) $(FLING_STREAM_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/fling_stream_test endif -$(OBJDIR)/$(CONFIG)/test/core/fling/fling_stream_test.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/fling/fling_stream_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_fling_stream_test: $(FLING_STREAM_TEST_OBJS:.o=.dep) @@ -11671,14 +10016,14 @@ else -$(BINDIR)/$(CONFIG)/fling_test: $(FLING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/fling_test: $(FLING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(FLING_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)/fling_test + $(Q) $(LD) $(LDFLAGS) $(FLING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/fling_test endif -$(OBJDIR)/$(CONFIG)/test/core/fling/fling_test.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/fling/fling_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_fling_test: $(FLING_TEST_OBJS:.o=.dep) @@ -11703,14 +10048,14 @@ else -$(BINDIR)/$(CONFIG)/fork_test: $(FORK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/fork_test: $(FORK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(FORK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/fork_test + $(Q) $(LD) $(LDFLAGS) $(FORK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/fork_test endif -$(OBJDIR)/$(CONFIG)/test/core/gprpp/fork_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gprpp/fork_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a deps_fork_test: $(FORK_TEST_OBJS:.o=.dep) @@ -11735,14 +10080,14 @@ else -$(BINDIR)/$(CONFIG)/goaway_server_test: $(GOAWAY_SERVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/goaway_server_test: $(GOAWAY_SERVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GOAWAY_SERVER_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)/goaway_server_test + $(Q) $(LD) $(LDFLAGS) $(GOAWAY_SERVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/goaway_server_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/goaway_server_test.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/end2end/goaway_server_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_goaway_server_test: $(GOAWAY_SERVER_TEST_OBJS:.o=.dep) @@ -11767,14 +10112,14 @@ else -$(BINDIR)/$(CONFIG)/gpr_cpu_test: $(GPR_CPU_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/gpr_cpu_test: $(GPR_CPU_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GPR_CPU_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_cpu_test + $(Q) $(LD) $(LDFLAGS) $(GPR_CPU_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_cpu_test endif -$(OBJDIR)/$(CONFIG)/test/core/gpr/cpu_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gpr/cpu_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a deps_gpr_cpu_test: $(GPR_CPU_TEST_OBJS:.o=.dep) @@ -11799,14 +10144,14 @@ else -$(BINDIR)/$(CONFIG)/gpr_env_test: $(GPR_ENV_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/gpr_env_test: $(GPR_ENV_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GPR_ENV_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_env_test + $(Q) $(LD) $(LDFLAGS) $(GPR_ENV_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_env_test endif -$(OBJDIR)/$(CONFIG)/test/core/gpr/env_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gpr/env_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a deps_gpr_env_test: $(GPR_ENV_TEST_OBJS:.o=.dep) @@ -11831,14 +10176,14 @@ else -$(BINDIR)/$(CONFIG)/gpr_host_port_test: $(GPR_HOST_PORT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/gpr_host_port_test: $(GPR_HOST_PORT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GPR_HOST_PORT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_host_port_test + $(Q) $(LD) $(LDFLAGS) $(GPR_HOST_PORT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_host_port_test endif -$(OBJDIR)/$(CONFIG)/test/core/gpr/host_port_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gpr/host_port_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a deps_gpr_host_port_test: $(GPR_HOST_PORT_TEST_OBJS:.o=.dep) @@ -11863,14 +10208,14 @@ else -$(BINDIR)/$(CONFIG)/gpr_log_test: $(GPR_LOG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/gpr_log_test: $(GPR_LOG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GPR_LOG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_log_test + $(Q) $(LD) $(LDFLAGS) $(GPR_LOG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_log_test endif -$(OBJDIR)/$(CONFIG)/test/core/gpr/log_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gpr/log_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a deps_gpr_log_test: $(GPR_LOG_TEST_OBJS:.o=.dep) @@ -11895,14 +10240,14 @@ else -$(BINDIR)/$(CONFIG)/gpr_manual_constructor_test: $(GPR_MANUAL_CONSTRUCTOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/gpr_manual_constructor_test: $(GPR_MANUAL_CONSTRUCTOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GPR_MANUAL_CONSTRUCTOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_manual_constructor_test + $(Q) $(LD) $(LDFLAGS) $(GPR_MANUAL_CONSTRUCTOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_manual_constructor_test endif -$(OBJDIR)/$(CONFIG)/test/core/gprpp/manual_constructor_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gprpp/manual_constructor_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a deps_gpr_manual_constructor_test: $(GPR_MANUAL_CONSTRUCTOR_TEST_OBJS:.o=.dep) @@ -11927,14 +10272,14 @@ else -$(BINDIR)/$(CONFIG)/gpr_mpscq_test: $(GPR_MPSCQ_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/gpr_mpscq_test: $(GPR_MPSCQ_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GPR_MPSCQ_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_mpscq_test + $(Q) $(LD) $(LDFLAGS) $(GPR_MPSCQ_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_mpscq_test endif -$(OBJDIR)/$(CONFIG)/test/core/gpr/mpscq_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gpr/mpscq_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a deps_gpr_mpscq_test: $(GPR_MPSCQ_TEST_OBJS:.o=.dep) @@ -11959,14 +10304,14 @@ else -$(BINDIR)/$(CONFIG)/gpr_spinlock_test: $(GPR_SPINLOCK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/gpr_spinlock_test: $(GPR_SPINLOCK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GPR_SPINLOCK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_spinlock_test + $(Q) $(LD) $(LDFLAGS) $(GPR_SPINLOCK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_spinlock_test endif -$(OBJDIR)/$(CONFIG)/test/core/gpr/spinlock_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gpr/spinlock_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a deps_gpr_spinlock_test: $(GPR_SPINLOCK_TEST_OBJS:.o=.dep) @@ -11991,14 +10336,14 @@ else -$(BINDIR)/$(CONFIG)/gpr_string_test: $(GPR_STRING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/gpr_string_test: $(GPR_STRING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GPR_STRING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_string_test + $(Q) $(LD) $(LDFLAGS) $(GPR_STRING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_string_test endif -$(OBJDIR)/$(CONFIG)/test/core/gpr/string_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gpr/string_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a deps_gpr_string_test: $(GPR_STRING_TEST_OBJS:.o=.dep) @@ -12023,14 +10368,14 @@ else -$(BINDIR)/$(CONFIG)/gpr_sync_test: $(GPR_SYNC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/gpr_sync_test: $(GPR_SYNC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GPR_SYNC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_sync_test + $(Q) $(LD) $(LDFLAGS) $(GPR_SYNC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_sync_test endif -$(OBJDIR)/$(CONFIG)/test/core/gpr/sync_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gpr/sync_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a deps_gpr_sync_test: $(GPR_SYNC_TEST_OBJS:.o=.dep) @@ -12055,14 +10400,14 @@ else -$(BINDIR)/$(CONFIG)/gpr_thd_test: $(GPR_THD_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/gpr_thd_test: $(GPR_THD_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GPR_THD_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_thd_test + $(Q) $(LD) $(LDFLAGS) $(GPR_THD_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_thd_test endif -$(OBJDIR)/$(CONFIG)/test/core/gprpp/thd_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gprpp/thd_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a deps_gpr_thd_test: $(GPR_THD_TEST_OBJS:.o=.dep) @@ -12087,14 +10432,14 @@ else -$(BINDIR)/$(CONFIG)/gpr_time_test: $(GPR_TIME_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/gpr_time_test: $(GPR_TIME_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GPR_TIME_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_time_test + $(Q) $(LD) $(LDFLAGS) $(GPR_TIME_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_time_test endif -$(OBJDIR)/$(CONFIG)/test/core/gpr/time_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gpr/time_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a deps_gpr_time_test: $(GPR_TIME_TEST_OBJS:.o=.dep) @@ -12119,14 +10464,14 @@ else -$(BINDIR)/$(CONFIG)/gpr_tls_test: $(GPR_TLS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/gpr_tls_test: $(GPR_TLS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GPR_TLS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_tls_test + $(Q) $(LD) $(LDFLAGS) $(GPR_TLS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_tls_test endif -$(OBJDIR)/$(CONFIG)/test/core/gpr/tls_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gpr/tls_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a deps_gpr_tls_test: $(GPR_TLS_TEST_OBJS:.o=.dep) @@ -12151,14 +10496,14 @@ else -$(BINDIR)/$(CONFIG)/gpr_useful_test: $(GPR_USEFUL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/gpr_useful_test: $(GPR_USEFUL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GPR_USEFUL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_useful_test + $(Q) $(LD) $(LDFLAGS) $(GPR_USEFUL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_useful_test endif -$(OBJDIR)/$(CONFIG)/test/core/gpr/useful_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gpr/useful_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a deps_gpr_useful_test: $(GPR_USEFUL_TEST_OBJS:.o=.dep) @@ -12183,14 +10528,14 @@ else -$(BINDIR)/$(CONFIG)/grpc_auth_context_test: $(GRPC_AUTH_CONTEXT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/grpc_auth_context_test: $(GRPC_AUTH_CONTEXT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GRPC_AUTH_CONTEXT_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_auth_context_test + $(Q) $(LD) $(LDFLAGS) $(GRPC_AUTH_CONTEXT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_auth_context_test endif -$(OBJDIR)/$(CONFIG)/test/core/security/auth_context_test.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/security/auth_context_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_grpc_auth_context_test: $(GRPC_AUTH_CONTEXT_TEST_OBJS:.o=.dep) @@ -12215,14 +10560,14 @@ else -$(BINDIR)/$(CONFIG)/grpc_b64_test: $(GRPC_B64_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/grpc_b64_test: $(GRPC_B64_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GRPC_B64_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_b64_test + $(Q) $(LD) $(LDFLAGS) $(GRPC_B64_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_b64_test endif -$(OBJDIR)/$(CONFIG)/test/core/slice/b64_test.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/slice/b64_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_grpc_b64_test: $(GRPC_B64_TEST_OBJS:.o=.dep) @@ -12247,14 +10592,14 @@ else -$(BINDIR)/$(CONFIG)/grpc_byte_buffer_reader_test: $(GRPC_BYTE_BUFFER_READER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/grpc_byte_buffer_reader_test: $(GRPC_BYTE_BUFFER_READER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GRPC_BYTE_BUFFER_READER_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_byte_buffer_reader_test + $(Q) $(LD) $(LDFLAGS) $(GRPC_BYTE_BUFFER_READER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_byte_buffer_reader_test endif -$(OBJDIR)/$(CONFIG)/test/core/surface/byte_buffer_reader_test.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/surface/byte_buffer_reader_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_grpc_byte_buffer_reader_test: $(GRPC_BYTE_BUFFER_READER_TEST_OBJS:.o=.dep) @@ -12279,14 +10624,14 @@ else -$(BINDIR)/$(CONFIG)/grpc_channel_args_test: $(GRPC_CHANNEL_ARGS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/grpc_channel_args_test: $(GRPC_CHANNEL_ARGS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GRPC_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_channel_args_test + $(Q) $(LD) $(LDFLAGS) $(GRPC_CHANNEL_ARGS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_channel_args_test endif -$(OBJDIR)/$(CONFIG)/test/core/channel/channel_args_test.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/channel/channel_args_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_grpc_channel_args_test: $(GRPC_CHANNEL_ARGS_TEST_OBJS:.o=.dep) @@ -12311,14 +10656,14 @@ else -$(BINDIR)/$(CONFIG)/grpc_channel_stack_builder_test: $(GRPC_CHANNEL_STACK_BUILDER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/grpc_channel_stack_builder_test: $(GRPC_CHANNEL_STACK_BUILDER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GRPC_CHANNEL_STACK_BUILDER_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_channel_stack_builder_test + $(Q) $(LD) $(LDFLAGS) $(GRPC_CHANNEL_STACK_BUILDER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_channel_stack_builder_test endif -$(OBJDIR)/$(CONFIG)/test/core/channel/channel_stack_builder_test.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/channel/channel_stack_builder_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_grpc_channel_stack_builder_test: $(GRPC_CHANNEL_STACK_BUILDER_TEST_OBJS:.o=.dep) @@ -12343,14 +10688,14 @@ else -$(BINDIR)/$(CONFIG)/grpc_channel_stack_test: $(GRPC_CHANNEL_STACK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/grpc_channel_stack_test: $(GRPC_CHANNEL_STACK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GRPC_CHANNEL_STACK_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_channel_stack_test + $(Q) $(LD) $(LDFLAGS) $(GRPC_CHANNEL_STACK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_channel_stack_test endif -$(OBJDIR)/$(CONFIG)/test/core/channel/channel_stack_test.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/channel/channel_stack_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_grpc_channel_stack_test: $(GRPC_CHANNEL_STACK_TEST_OBJS:.o=.dep) @@ -12375,14 +10720,14 @@ else -$(BINDIR)/$(CONFIG)/grpc_completion_queue_test: $(GRPC_COMPLETION_QUEUE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/grpc_completion_queue_test: $(GRPC_COMPLETION_QUEUE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GRPC_COMPLETION_QUEUE_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_completion_queue_test + $(Q) $(LD) $(LDFLAGS) $(GRPC_COMPLETION_QUEUE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_completion_queue_test endif -$(OBJDIR)/$(CONFIG)/test/core/surface/completion_queue_test.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/surface/completion_queue_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_grpc_completion_queue_test: $(GRPC_COMPLETION_QUEUE_TEST_OBJS:.o=.dep) @@ -12407,14 +10752,14 @@ else -$(BINDIR)/$(CONFIG)/grpc_completion_queue_threading_test: $(GRPC_COMPLETION_QUEUE_THREADING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/grpc_completion_queue_threading_test: $(GRPC_COMPLETION_QUEUE_THREADING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GRPC_COMPLETION_QUEUE_THREADING_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_completion_queue_threading_test + $(Q) $(LD) $(LDFLAGS) $(GRPC_COMPLETION_QUEUE_THREADING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_completion_queue_threading_test endif -$(OBJDIR)/$(CONFIG)/test/core/surface/completion_queue_threading_test.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/surface/completion_queue_threading_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_grpc_completion_queue_threading_test: $(GRPC_COMPLETION_QUEUE_THREADING_TEST_OBJS:.o=.dep) @@ -12474,14 +10819,14 @@ else -$(BINDIR)/$(CONFIG)/grpc_credentials_test: $(GRPC_CREDENTIALS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/grpc_credentials_test: $(GRPC_CREDENTIALS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GRPC_CREDENTIALS_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_credentials_test + $(Q) $(LD) $(LDFLAGS) $(GRPC_CREDENTIALS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_credentials_test endif -$(OBJDIR)/$(CONFIG)/test/core/security/credentials_test.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/security/credentials_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_grpc_credentials_test: $(GRPC_CREDENTIALS_TEST_OBJS:.o=.dep) @@ -12506,14 +10851,14 @@ else -$(BINDIR)/$(CONFIG)/grpc_fetch_oauth2: $(GRPC_FETCH_OAUTH2_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/grpc_fetch_oauth2: $(GRPC_FETCH_OAUTH2_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GRPC_FETCH_OAUTH2_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_fetch_oauth2 + $(Q) $(LD) $(LDFLAGS) $(GRPC_FETCH_OAUTH2_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_fetch_oauth2 endif -$(OBJDIR)/$(CONFIG)/test/core/security/fetch_oauth2.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/security/fetch_oauth2.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_grpc_fetch_oauth2: $(GRPC_FETCH_OAUTH2_OBJS:.o=.dep) @@ -12538,14 +10883,14 @@ else -$(BINDIR)/$(CONFIG)/grpc_ipv6_loopback_available_test: $(GRPC_IPV6_LOOPBACK_AVAILABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/grpc_ipv6_loopback_available_test: $(GRPC_IPV6_LOOPBACK_AVAILABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GRPC_IPV6_LOOPBACK_AVAILABLE_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_ipv6_loopback_available_test + $(Q) $(LD) $(LDFLAGS) $(GRPC_IPV6_LOOPBACK_AVAILABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_ipv6_loopback_available_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/grpc_ipv6_loopback_available_test.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/iomgr/grpc_ipv6_loopback_available_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_grpc_ipv6_loopback_available_test: $(GRPC_IPV6_LOOPBACK_AVAILABLE_TEST_OBJS:.o=.dep) @@ -12570,14 +10915,14 @@ else -$(BINDIR)/$(CONFIG)/grpc_json_token_test: $(GRPC_JSON_TOKEN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/grpc_json_token_test: $(GRPC_JSON_TOKEN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GRPC_JSON_TOKEN_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_json_token_test + $(Q) $(LD) $(LDFLAGS) $(GRPC_JSON_TOKEN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_json_token_test endif -$(OBJDIR)/$(CONFIG)/test/core/security/json_token_test.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/security/json_token_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_grpc_json_token_test: $(GRPC_JSON_TOKEN_TEST_OBJS:.o=.dep) @@ -12602,14 +10947,14 @@ else -$(BINDIR)/$(CONFIG)/grpc_jwt_verifier_test: $(GRPC_JWT_VERIFIER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/grpc_jwt_verifier_test: $(GRPC_JWT_VERIFIER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GRPC_JWT_VERIFIER_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_jwt_verifier_test + $(Q) $(LD) $(LDFLAGS) $(GRPC_JWT_VERIFIER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_jwt_verifier_test endif -$(OBJDIR)/$(CONFIG)/test/core/security/jwt_verifier_test.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/security/jwt_verifier_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_grpc_jwt_verifier_test: $(GRPC_JWT_VERIFIER_TEST_OBJS:.o=.dep) @@ -12669,14 +11014,14 @@ else -$(BINDIR)/$(CONFIG)/grpc_security_connector_test: $(GRPC_SECURITY_CONNECTOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/grpc_security_connector_test: $(GRPC_SECURITY_CONNECTOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GRPC_SECURITY_CONNECTOR_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_security_connector_test + $(Q) $(LD) $(LDFLAGS) $(GRPC_SECURITY_CONNECTOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_security_connector_test endif -$(OBJDIR)/$(CONFIG)/test/core/security/security_connector_test.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/security/security_connector_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_grpc_security_connector_test: $(GRPC_SECURITY_CONNECTOR_TEST_OBJS:.o=.dep) @@ -12701,14 +11046,14 @@ else -$(BINDIR)/$(CONFIG)/grpc_ssl_credentials_test: $(GRPC_SSL_CREDENTIALS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/grpc_ssl_credentials_test: $(GRPC_SSL_CREDENTIALS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GRPC_SSL_CREDENTIALS_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_ssl_credentials_test + $(Q) $(LD) $(LDFLAGS) $(GRPC_SSL_CREDENTIALS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_ssl_credentials_test endif -$(OBJDIR)/$(CONFIG)/test/core/security/ssl_credentials_test.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/security/ssl_credentials_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_grpc_ssl_credentials_test: $(GRPC_SSL_CREDENTIALS_TEST_OBJS:.o=.dep) @@ -12768,14 +11113,14 @@ else -$(BINDIR)/$(CONFIG)/handshake_client_ssl: $(HANDSHAKE_CLIENT_SSL_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/handshake_client_ssl: $(HANDSHAKE_CLIENT_SSL_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(HANDSHAKE_CLIENT_SSL_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)/handshake_client_ssl + $(Q) $(LD) $(LDFLAGS) $(HANDSHAKE_CLIENT_SSL_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/handshake_client_ssl endif -$(OBJDIR)/$(CONFIG)/test/core/handshake/client_ssl.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/handshake/client_ssl.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_handshake_client_ssl: $(HANDSHAKE_CLIENT_SSL_OBJS:.o=.dep) @@ -12801,16 +11146,16 @@ else -$(BINDIR)/$(CONFIG)/handshake_server_ssl: $(HANDSHAKE_SERVER_SSL_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/handshake_server_ssl: $(HANDSHAKE_SERVER_SSL_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(HANDSHAKE_SERVER_SSL_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)/handshake_server_ssl + $(Q) $(LD) $(LDFLAGS) $(HANDSHAKE_SERVER_SSL_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/handshake_server_ssl endif -$(OBJDIR)/$(CONFIG)/test/core/handshake/server_ssl.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/handshake/server_ssl.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a -$(OBJDIR)/$(CONFIG)/test/core/handshake/server_ssl_common.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/handshake/server_ssl_common.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_handshake_server_ssl: $(HANDSHAKE_SERVER_SSL_OBJS:.o=.dep) @@ -12836,16 +11181,16 @@ else -$(BINDIR)/$(CONFIG)/handshake_server_with_readahead_handshaker: $(HANDSHAKE_SERVER_WITH_READAHEAD_HANDSHAKER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/handshake_server_with_readahead_handshaker: $(HANDSHAKE_SERVER_WITH_READAHEAD_HANDSHAKER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(HANDSHAKE_SERVER_WITH_READAHEAD_HANDSHAKER_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)/handshake_server_with_readahead_handshaker + $(Q) $(LD) $(LDFLAGS) $(HANDSHAKE_SERVER_WITH_READAHEAD_HANDSHAKER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/handshake_server_with_readahead_handshaker endif -$(OBJDIR)/$(CONFIG)/test/core/handshake/readahead_handshaker_server_ssl.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/handshake/readahead_handshaker_server_ssl.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a -$(OBJDIR)/$(CONFIG)/test/core/handshake/server_ssl_common.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/handshake/server_ssl_common.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_handshake_server_with_readahead_handshaker: $(HANDSHAKE_SERVER_WITH_READAHEAD_HANDSHAKER_OBJS:.o=.dep) @@ -12870,14 +11215,14 @@ else -$(BINDIR)/$(CONFIG)/handshake_verify_peer_options: $(HANDSHAKE_VERIFY_PEER_OPTIONS_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/handshake_verify_peer_options: $(HANDSHAKE_VERIFY_PEER_OPTIONS_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(HANDSHAKE_VERIFY_PEER_OPTIONS_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)/handshake_verify_peer_options + $(Q) $(LD) $(LDFLAGS) $(HANDSHAKE_VERIFY_PEER_OPTIONS_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/handshake_verify_peer_options endif -$(OBJDIR)/$(CONFIG)/test/core/handshake/verify_peer_options.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/handshake/verify_peer_options.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_handshake_verify_peer_options: $(HANDSHAKE_VERIFY_PEER_OPTIONS_OBJS:.o=.dep) @@ -12934,14 +11279,14 @@ else -$(BINDIR)/$(CONFIG)/hpack_parser_fuzzer_test: $(HPACK_PARSER_FUZZER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/hpack_parser_fuzzer_test: $(HPACK_PARSER_FUZZER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(HPACK_PARSER_FUZZER_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) -lFuzzer -o $(BINDIR)/$(CONFIG)/hpack_parser_fuzzer_test + $(Q) $(LDXX) $(LDFLAGS) $(HPACK_PARSER_FUZZER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/hpack_parser_fuzzer_test endif -$(OBJDIR)/$(CONFIG)/test/core/transport/chttp2/hpack_parser_fuzzer_test.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/transport/chttp2/hpack_parser_fuzzer_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_hpack_parser_fuzzer_test: $(HPACK_PARSER_FUZZER_TEST_OBJS:.o=.dep) @@ -12966,14 +11311,14 @@ else -$(BINDIR)/$(CONFIG)/hpack_parser_test: $(HPACK_PARSER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/hpack_parser_test: $(HPACK_PARSER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(HPACK_PARSER_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)/hpack_parser_test + $(Q) $(LD) $(LDFLAGS) $(HPACK_PARSER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/hpack_parser_test endif -$(OBJDIR)/$(CONFIG)/test/core/transport/chttp2/hpack_parser_test.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/transport/chttp2/hpack_parser_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_hpack_parser_test: $(HPACK_PARSER_TEST_OBJS:.o=.dep) @@ -12998,14 +11343,14 @@ else -$(BINDIR)/$(CONFIG)/hpack_table_test: $(HPACK_TABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/hpack_table_test: $(HPACK_TABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(HPACK_TABLE_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)/hpack_table_test + $(Q) $(LD) $(LDFLAGS) $(HPACK_TABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/hpack_table_test endif -$(OBJDIR)/$(CONFIG)/test/core/transport/chttp2/hpack_table_test.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/transport/chttp2/hpack_table_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_hpack_table_test: $(HPACK_TABLE_TEST_OBJS:.o=.dep) @@ -13030,14 +11375,14 @@ else -$(BINDIR)/$(CONFIG)/http_parser_test: $(HTTP_PARSER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/http_parser_test: $(HTTP_PARSER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(HTTP_PARSER_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)/http_parser_test + $(Q) $(LD) $(LDFLAGS) $(HTTP_PARSER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/http_parser_test endif -$(OBJDIR)/$(CONFIG)/test/core/http/parser_test.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/http/parser_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_http_parser_test: $(HTTP_PARSER_TEST_OBJS:.o=.dep) @@ -13062,14 +11407,14 @@ else -$(BINDIR)/$(CONFIG)/http_request_fuzzer_test: $(HTTP_REQUEST_FUZZER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/http_request_fuzzer_test: $(HTTP_REQUEST_FUZZER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(HTTP_REQUEST_FUZZER_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) -lFuzzer -o $(BINDIR)/$(CONFIG)/http_request_fuzzer_test + $(Q) $(LDXX) $(LDFLAGS) $(HTTP_REQUEST_FUZZER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/http_request_fuzzer_test endif -$(OBJDIR)/$(CONFIG)/test/core/http/request_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/http/request_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_http_request_fuzzer_test: $(HTTP_REQUEST_FUZZER_TEST_OBJS:.o=.dep) @@ -13094,14 +11439,14 @@ else -$(BINDIR)/$(CONFIG)/http_response_fuzzer_test: $(HTTP_RESPONSE_FUZZER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/http_response_fuzzer_test: $(HTTP_RESPONSE_FUZZER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(HTTP_RESPONSE_FUZZER_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) -lFuzzer -o $(BINDIR)/$(CONFIG)/http_response_fuzzer_test + $(Q) $(LDXX) $(LDFLAGS) $(HTTP_RESPONSE_FUZZER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/http_response_fuzzer_test endif -$(OBJDIR)/$(CONFIG)/test/core/http/response_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/http/response_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_http_response_fuzzer_test: $(HTTP_RESPONSE_FUZZER_TEST_OBJS:.o=.dep) @@ -13126,14 +11471,14 @@ else -$(BINDIR)/$(CONFIG)/httpcli_format_request_test: $(HTTPCLI_FORMAT_REQUEST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/httpcli_format_request_test: $(HTTPCLI_FORMAT_REQUEST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(HTTPCLI_FORMAT_REQUEST_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)/httpcli_format_request_test + $(Q) $(LD) $(LDFLAGS) $(HTTPCLI_FORMAT_REQUEST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/httpcli_format_request_test endif -$(OBJDIR)/$(CONFIG)/test/core/http/format_request_test.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/http/format_request_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_httpcli_format_request_test: $(HTTPCLI_FORMAT_REQUEST_TEST_OBJS:.o=.dep) @@ -13158,14 +11503,14 @@ else -$(BINDIR)/$(CONFIG)/httpcli_test: $(HTTPCLI_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/httpcli_test: $(HTTPCLI_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(HTTPCLI_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)/httpcli_test + $(Q) $(LD) $(LDFLAGS) $(HTTPCLI_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/httpcli_test endif -$(OBJDIR)/$(CONFIG)/test/core/http/httpcli_test.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/http/httpcli_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_httpcli_test: $(HTTPCLI_TEST_OBJS:.o=.dep) @@ -13190,14 +11535,14 @@ else -$(BINDIR)/$(CONFIG)/httpscli_test: $(HTTPSCLI_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/httpscli_test: $(HTTPSCLI_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(HTTPSCLI_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)/httpscli_test + $(Q) $(LD) $(LDFLAGS) $(HTTPSCLI_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/httpscli_test endif -$(OBJDIR)/$(CONFIG)/test/core/http/httpscli_test.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/http/httpscli_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_httpscli_test: $(HTTPSCLI_TEST_OBJS:.o=.dep) @@ -13222,14 +11567,14 @@ else -$(BINDIR)/$(CONFIG)/init_test: $(INIT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/init_test: $(INIT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(INIT_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)/init_test + $(Q) $(LD) $(LDFLAGS) $(INIT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/init_test endif -$(OBJDIR)/$(CONFIG)/test/core/surface/init_test.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/surface/init_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_init_test: $(INIT_TEST_OBJS:.o=.dep) @@ -13254,14 +11599,14 @@ else -$(BINDIR)/$(CONFIG)/inproc_callback_test: $(INPROC_CALLBACK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/inproc_callback_test: $(INPROC_CALLBACK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(INPROC_CALLBACK_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)/inproc_callback_test + $(Q) $(LD) $(LDFLAGS) $(INPROC_CALLBACK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/inproc_callback_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/inproc_callback_test.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/end2end/inproc_callback_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_inproc_callback_test: $(INPROC_CALLBACK_TEST_OBJS:.o=.dep) @@ -13286,14 +11631,14 @@ else -$(BINDIR)/$(CONFIG)/invalid_call_argument_test: $(INVALID_CALL_ARGUMENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/invalid_call_argument_test: $(INVALID_CALL_ARGUMENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(INVALID_CALL_ARGUMENT_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)/invalid_call_argument_test + $(Q) $(LD) $(LDFLAGS) $(INVALID_CALL_ARGUMENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/invalid_call_argument_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/invalid_call_argument_test.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/end2end/invalid_call_argument_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_invalid_call_argument_test: $(INVALID_CALL_ARGUMENT_TEST_OBJS:.o=.dep) @@ -13318,14 +11663,14 @@ else -$(BINDIR)/$(CONFIG)/json_fuzzer_test: $(JSON_FUZZER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/json_fuzzer_test: $(JSON_FUZZER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(JSON_FUZZER_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) -lFuzzer -o $(BINDIR)/$(CONFIG)/json_fuzzer_test + $(Q) $(LDXX) $(LDFLAGS) $(JSON_FUZZER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/json_fuzzer_test endif -$(OBJDIR)/$(CONFIG)/test/core/json/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/json/fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_json_fuzzer_test: $(JSON_FUZZER_TEST_OBJS:.o=.dep) @@ -13350,14 +11695,14 @@ else -$(BINDIR)/$(CONFIG)/json_rewrite: $(JSON_REWRITE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/json_rewrite: $(JSON_REWRITE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(JSON_REWRITE_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)/json_rewrite + $(Q) $(LD) $(LDFLAGS) $(JSON_REWRITE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/json_rewrite endif -$(OBJDIR)/$(CONFIG)/test/core/json/json_rewrite.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/json/json_rewrite.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_json_rewrite: $(JSON_REWRITE_OBJS:.o=.dep) @@ -13382,14 +11727,14 @@ else -$(BINDIR)/$(CONFIG)/json_rewrite_test: $(JSON_REWRITE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/json_rewrite_test: $(JSON_REWRITE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(JSON_REWRITE_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)/json_rewrite_test + $(Q) $(LD) $(LDFLAGS) $(JSON_REWRITE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/json_rewrite_test endif -$(OBJDIR)/$(CONFIG)/test/core/json/json_rewrite_test.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/json/json_rewrite_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_json_rewrite_test: $(JSON_REWRITE_TEST_OBJS:.o=.dep) @@ -13414,14 +11759,14 @@ else -$(BINDIR)/$(CONFIG)/json_stream_error_test: $(JSON_STREAM_ERROR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/json_stream_error_test: $(JSON_STREAM_ERROR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(JSON_STREAM_ERROR_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)/json_stream_error_test + $(Q) $(LD) $(LDFLAGS) $(JSON_STREAM_ERROR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/json_stream_error_test endif -$(OBJDIR)/$(CONFIG)/test/core/json/json_stream_error_test.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/json/json_stream_error_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_json_stream_error_test: $(JSON_STREAM_ERROR_TEST_OBJS:.o=.dep) @@ -13446,14 +11791,14 @@ else -$(BINDIR)/$(CONFIG)/json_test: $(JSON_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/json_test: $(JSON_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(JSON_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)/json_test + $(Q) $(LD) $(LDFLAGS) $(JSON_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/json_test endif -$(OBJDIR)/$(CONFIG)/test/core/json/json_test.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/json/json_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_json_test: $(JSON_TEST_OBJS:.o=.dep) @@ -13478,14 +11823,14 @@ else -$(BINDIR)/$(CONFIG)/lame_client_test: $(LAME_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/lame_client_test: $(LAME_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(LAME_CLIENT_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)/lame_client_test + $(Q) $(LD) $(LDFLAGS) $(LAME_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/lame_client_test endif -$(OBJDIR)/$(CONFIG)/test/core/surface/lame_client_test.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/surface/lame_client_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_lame_client_test: $(LAME_CLIENT_TEST_OBJS:.o=.dep) @@ -13510,14 +11855,14 @@ else -$(BINDIR)/$(CONFIG)/load_file_test: $(LOAD_FILE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/load_file_test: $(LOAD_FILE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(LOAD_FILE_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)/load_file_test + $(Q) $(LD) $(LDFLAGS) $(LOAD_FILE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/load_file_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/load_file_test.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/iomgr/load_file_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_load_file_test: $(LOAD_FILE_TEST_OBJS:.o=.dep) @@ -13542,14 +11887,14 @@ else -$(BINDIR)/$(CONFIG)/low_level_ping_pong_benchmark: $(LOW_LEVEL_PING_PONG_BENCHMARK_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/low_level_ping_pong_benchmark: $(LOW_LEVEL_PING_PONG_BENCHMARK_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(LOW_LEVEL_PING_PONG_BENCHMARK_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)/low_level_ping_pong_benchmark + $(Q) $(LD) $(LDFLAGS) $(LOW_LEVEL_PING_PONG_BENCHMARK_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/low_level_ping_pong_benchmark endif -$(OBJDIR)/$(CONFIG)/test/core/network_benchmarks/low_level_ping_pong.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/network_benchmarks/low_level_ping_pong.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_low_level_ping_pong_benchmark: $(LOW_LEVEL_PING_PONG_BENCHMARK_OBJS:.o=.dep) @@ -13574,14 +11919,14 @@ else -$(BINDIR)/$(CONFIG)/memory_usage_client: $(MEMORY_USAGE_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/memory_usage_client: $(MEMORY_USAGE_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(MEMORY_USAGE_CLIENT_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)/memory_usage_client + $(Q) $(LD) $(LDFLAGS) $(MEMORY_USAGE_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/memory_usage_client endif -$(OBJDIR)/$(CONFIG)/test/core/memory_usage/client.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/memory_usage/client.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_memory_usage_client: $(MEMORY_USAGE_CLIENT_OBJS:.o=.dep) @@ -13606,14 +11951,14 @@ else -$(BINDIR)/$(CONFIG)/memory_usage_server: $(MEMORY_USAGE_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/memory_usage_server: $(MEMORY_USAGE_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(MEMORY_USAGE_SERVER_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)/memory_usage_server + $(Q) $(LD) $(LDFLAGS) $(MEMORY_USAGE_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/memory_usage_server endif -$(OBJDIR)/$(CONFIG)/test/core/memory_usage/server.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/memory_usage/server.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_memory_usage_server: $(MEMORY_USAGE_SERVER_OBJS:.o=.dep) @@ -13638,14 +11983,14 @@ else -$(BINDIR)/$(CONFIG)/memory_usage_test: $(MEMORY_USAGE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/memory_usage_test: $(MEMORY_USAGE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(MEMORY_USAGE_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)/memory_usage_test + $(Q) $(LD) $(LDFLAGS) $(MEMORY_USAGE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/memory_usage_test endif -$(OBJDIR)/$(CONFIG)/test/core/memory_usage/memory_usage_test.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/memory_usage/memory_usage_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_memory_usage_test: $(MEMORY_USAGE_TEST_OBJS:.o=.dep) @@ -13670,14 +12015,14 @@ else -$(BINDIR)/$(CONFIG)/message_compress_test: $(MESSAGE_COMPRESS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/message_compress_test: $(MESSAGE_COMPRESS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(MESSAGE_COMPRESS_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)/message_compress_test + $(Q) $(LD) $(LDFLAGS) $(MESSAGE_COMPRESS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/message_compress_test endif -$(OBJDIR)/$(CONFIG)/test/core/compression/message_compress_test.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/compression/message_compress_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_message_compress_test: $(MESSAGE_COMPRESS_TEST_OBJS:.o=.dep) @@ -13702,14 +12047,14 @@ else -$(BINDIR)/$(CONFIG)/minimal_stack_is_minimal_test: $(MINIMAL_STACK_IS_MINIMAL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/minimal_stack_is_minimal_test: $(MINIMAL_STACK_IS_MINIMAL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(MINIMAL_STACK_IS_MINIMAL_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)/minimal_stack_is_minimal_test + $(Q) $(LD) $(LDFLAGS) $(MINIMAL_STACK_IS_MINIMAL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/minimal_stack_is_minimal_test endif -$(OBJDIR)/$(CONFIG)/test/core/channel/minimal_stack_is_minimal_test.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/channel/minimal_stack_is_minimal_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_minimal_stack_is_minimal_test: $(MINIMAL_STACK_IS_MINIMAL_TEST_OBJS:.o=.dep) @@ -13734,14 +12079,14 @@ else -$(BINDIR)/$(CONFIG)/multiple_server_queues_test: $(MULTIPLE_SERVER_QUEUES_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/multiple_server_queues_test: $(MULTIPLE_SERVER_QUEUES_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(MULTIPLE_SERVER_QUEUES_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)/multiple_server_queues_test + $(Q) $(LD) $(LDFLAGS) $(MULTIPLE_SERVER_QUEUES_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/multiple_server_queues_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/multiple_server_queues_test.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/end2end/multiple_server_queues_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_multiple_server_queues_test: $(MULTIPLE_SERVER_QUEUES_TEST_OBJS:.o=.dep) @@ -13766,14 +12111,14 @@ else -$(BINDIR)/$(CONFIG)/murmur_hash_test: $(MURMUR_HASH_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/murmur_hash_test: $(MURMUR_HASH_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(MURMUR_HASH_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/murmur_hash_test + $(Q) $(LD) $(LDFLAGS) $(MURMUR_HASH_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/murmur_hash_test endif -$(OBJDIR)/$(CONFIG)/test/core/gpr/murmur_hash_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gpr/murmur_hash_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a deps_murmur_hash_test: $(MURMUR_HASH_TEST_OBJS:.o=.dep) @@ -13798,14 +12143,14 @@ else -$(BINDIR)/$(CONFIG)/nanopb_fuzzer_response_test: $(NANOPB_FUZZER_RESPONSE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/nanopb_fuzzer_response_test: $(NANOPB_FUZZER_RESPONSE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(NANOPB_FUZZER_RESPONSE_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) -lFuzzer -o $(BINDIR)/$(CONFIG)/nanopb_fuzzer_response_test + $(Q) $(LDXX) $(LDFLAGS) $(NANOPB_FUZZER_RESPONSE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/nanopb_fuzzer_response_test endif -$(OBJDIR)/$(CONFIG)/test/core/nanopb/fuzzer_response.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/nanopb/fuzzer_response.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_nanopb_fuzzer_response_test: $(NANOPB_FUZZER_RESPONSE_TEST_OBJS:.o=.dep) @@ -13830,14 +12175,14 @@ else -$(BINDIR)/$(CONFIG)/nanopb_fuzzer_serverlist_test: $(NANOPB_FUZZER_SERVERLIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/nanopb_fuzzer_serverlist_test: $(NANOPB_FUZZER_SERVERLIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(NANOPB_FUZZER_SERVERLIST_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) -lFuzzer -o $(BINDIR)/$(CONFIG)/nanopb_fuzzer_serverlist_test + $(Q) $(LDXX) $(LDFLAGS) $(NANOPB_FUZZER_SERVERLIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/nanopb_fuzzer_serverlist_test endif -$(OBJDIR)/$(CONFIG)/test/core/nanopb/fuzzer_serverlist.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/nanopb/fuzzer_serverlist.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_nanopb_fuzzer_serverlist_test: $(NANOPB_FUZZER_SERVERLIST_TEST_OBJS:.o=.dep) @@ -13862,14 +12207,14 @@ else -$(BINDIR)/$(CONFIG)/no_server_test: $(NO_SERVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/no_server_test: $(NO_SERVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(NO_SERVER_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)/no_server_test + $(Q) $(LD) $(LDFLAGS) $(NO_SERVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/no_server_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/no_server_test.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/end2end/no_server_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_no_server_test: $(NO_SERVER_TEST_OBJS:.o=.dep) @@ -13894,14 +12239,14 @@ else -$(BINDIR)/$(CONFIG)/num_external_connectivity_watchers_test: $(NUM_EXTERNAL_CONNECTIVITY_WATCHERS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/num_external_connectivity_watchers_test: $(NUM_EXTERNAL_CONNECTIVITY_WATCHERS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(NUM_EXTERNAL_CONNECTIVITY_WATCHERS_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)/num_external_connectivity_watchers_test + $(Q) $(LD) $(LDFLAGS) $(NUM_EXTERNAL_CONNECTIVITY_WATCHERS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/num_external_connectivity_watchers_test endif -$(OBJDIR)/$(CONFIG)/test/core/surface/num_external_connectivity_watchers_test.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/surface/num_external_connectivity_watchers_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_num_external_connectivity_watchers_test: $(NUM_EXTERNAL_CONNECTIVITY_WATCHERS_TEST_OBJS:.o=.dep) @@ -13926,14 +12271,14 @@ else -$(BINDIR)/$(CONFIG)/parse_address_test: $(PARSE_ADDRESS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/parse_address_test: $(PARSE_ADDRESS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(PARSE_ADDRESS_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)/parse_address_test + $(Q) $(LD) $(LDFLAGS) $(PARSE_ADDRESS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/parse_address_test endif -$(OBJDIR)/$(CONFIG)/test/core/client_channel/parse_address_test.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/client_channel/parse_address_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_parse_address_test: $(PARSE_ADDRESS_TEST_OBJS:.o=.dep) @@ -13944,6 +12289,38 @@ endif endif +PARSE_ADDRESS_WITH_NAMED_SCOPE_ID_TEST_SRC = \ + test/core/client_channel/parse_address_with_named_scope_id_test.cc \ + +PARSE_ADDRESS_WITH_NAMED_SCOPE_ID_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(PARSE_ADDRESS_WITH_NAMED_SCOPE_ID_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/parse_address_with_named_scope_id_test: openssl_dep_error + +else + + + +$(BINDIR)/$(CONFIG)/parse_address_with_named_scope_id_test: $(PARSE_ADDRESS_WITH_NAMED_SCOPE_ID_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LD) $(LDFLAGS) $(PARSE_ADDRESS_WITH_NAMED_SCOPE_ID_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/parse_address_with_named_scope_id_test + +endif + +$(OBJDIR)/$(CONFIG)/test/core/client_channel/parse_address_with_named_scope_id_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_parse_address_with_named_scope_id_test: $(PARSE_ADDRESS_WITH_NAMED_SCOPE_ID_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(PARSE_ADDRESS_WITH_NAMED_SCOPE_ID_TEST_OBJS:.o=.dep) +endif +endif + + PERCENT_DECODE_FUZZER_SRC = \ test/core/slice/percent_decode_fuzzer.cc \ @@ -13958,14 +12335,14 @@ else -$(BINDIR)/$(CONFIG)/percent_decode_fuzzer: $(PERCENT_DECODE_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/percent_decode_fuzzer: $(PERCENT_DECODE_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(PERCENT_DECODE_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)/percent_decode_fuzzer + $(Q) $(LDXX) $(LDFLAGS) $(PERCENT_DECODE_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/percent_decode_fuzzer endif -$(OBJDIR)/$(CONFIG)/test/core/slice/percent_decode_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/slice/percent_decode_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_percent_decode_fuzzer: $(PERCENT_DECODE_FUZZER_OBJS:.o=.dep) @@ -13990,14 +12367,14 @@ else -$(BINDIR)/$(CONFIG)/percent_encode_fuzzer: $(PERCENT_ENCODE_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/percent_encode_fuzzer: $(PERCENT_ENCODE_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(PERCENT_ENCODE_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)/percent_encode_fuzzer + $(Q) $(LDXX) $(LDFLAGS) $(PERCENT_ENCODE_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/percent_encode_fuzzer endif -$(OBJDIR)/$(CONFIG)/test/core/slice/percent_encode_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/slice/percent_encode_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_percent_encode_fuzzer: $(PERCENT_ENCODE_FUZZER_OBJS:.o=.dep) @@ -14022,14 +12399,14 @@ else -$(BINDIR)/$(CONFIG)/percent_encoding_test: $(PERCENT_ENCODING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/percent_encoding_test: $(PERCENT_ENCODING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(PERCENT_ENCODING_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)/percent_encoding_test + $(Q) $(LD) $(LDFLAGS) $(PERCENT_ENCODING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/percent_encoding_test endif -$(OBJDIR)/$(CONFIG)/test/core/slice/percent_encoding_test.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/slice/percent_encoding_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_percent_encoding_test: $(PERCENT_ENCODING_TEST_OBJS:.o=.dep) @@ -14040,34 +12417,34 @@ endif endif -RESOLVE_ADDRESS_POSIX_TEST_SRC = \ +RESOLVE_ADDRESS_USING_ARES_RESOLVER_POSIX_TEST_SRC = \ test/core/iomgr/resolve_address_posix_test.cc \ -RESOLVE_ADDRESS_POSIX_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(RESOLVE_ADDRESS_POSIX_TEST_SRC)))) +RESOLVE_ADDRESS_USING_ARES_RESOLVER_POSIX_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(RESOLVE_ADDRESS_USING_ARES_RESOLVER_POSIX_TEST_SRC)))) ifeq ($(NO_SECURE),true) # You can't build secure targets if you don't have OpenSSL. -$(BINDIR)/$(CONFIG)/resolve_address_posix_test: openssl_dep_error +$(BINDIR)/$(CONFIG)/resolve_address_using_ares_resolver_posix_test: openssl_dep_error else -$(BINDIR)/$(CONFIG)/resolve_address_posix_test: $(RESOLVE_ADDRESS_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/resolve_address_using_ares_resolver_posix_test: $(RESOLVE_ADDRESS_USING_ARES_RESOLVER_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(RESOLVE_ADDRESS_POSIX_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)/resolve_address_posix_test + $(Q) $(LD) $(LDFLAGS) $(RESOLVE_ADDRESS_USING_ARES_RESOLVER_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/resolve_address_using_ares_resolver_posix_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/resolve_address_posix_test.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/iomgr/resolve_address_posix_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a -deps_resolve_address_posix_test: $(RESOLVE_ADDRESS_POSIX_TEST_OBJS:.o=.dep) +deps_resolve_address_using_ares_resolver_posix_test: $(RESOLVE_ADDRESS_USING_ARES_RESOLVER_POSIX_TEST_OBJS:.o=.dep) ifneq ($(NO_SECURE),true) ifneq ($(NO_DEPS),true) --include $(RESOLVE_ADDRESS_POSIX_TEST_OBJS:.o=.dep) +-include $(RESOLVE_ADDRESS_USING_ARES_RESOLVER_POSIX_TEST_OBJS:.o=.dep) endif endif @@ -14086,14 +12463,14 @@ else -$(BINDIR)/$(CONFIG)/resolve_address_using_ares_resolver_test: $(RESOLVE_ADDRESS_USING_ARES_RESOLVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/resolve_address_using_ares_resolver_test: $(RESOLVE_ADDRESS_USING_ARES_RESOLVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(RESOLVE_ADDRESS_USING_ARES_RESOLVER_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)/resolve_address_using_ares_resolver_test + $(Q) $(LD) $(LDFLAGS) $(RESOLVE_ADDRESS_USING_ARES_RESOLVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/resolve_address_using_ares_resolver_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/resolve_address_test.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/iomgr/resolve_address_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_resolve_address_using_ares_resolver_test: $(RESOLVE_ADDRESS_USING_ARES_RESOLVER_TEST_OBJS:.o=.dep) @@ -14104,6 +12481,38 @@ endif endif +RESOLVE_ADDRESS_USING_NATIVE_RESOLVER_POSIX_TEST_SRC = \ + test/core/iomgr/resolve_address_posix_test.cc \ + +RESOLVE_ADDRESS_USING_NATIVE_RESOLVER_POSIX_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(RESOLVE_ADDRESS_USING_NATIVE_RESOLVER_POSIX_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/resolve_address_using_native_resolver_posix_test: openssl_dep_error + +else + + + +$(BINDIR)/$(CONFIG)/resolve_address_using_native_resolver_posix_test: $(RESOLVE_ADDRESS_USING_NATIVE_RESOLVER_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LD) $(LDFLAGS) $(RESOLVE_ADDRESS_USING_NATIVE_RESOLVER_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/resolve_address_using_native_resolver_posix_test + +endif + +$(OBJDIR)/$(CONFIG)/test/core/iomgr/resolve_address_posix_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_resolve_address_using_native_resolver_posix_test: $(RESOLVE_ADDRESS_USING_NATIVE_RESOLVER_POSIX_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(RESOLVE_ADDRESS_USING_NATIVE_RESOLVER_POSIX_TEST_OBJS:.o=.dep) +endif +endif + + RESOLVE_ADDRESS_USING_NATIVE_RESOLVER_TEST_SRC = \ test/core/iomgr/resolve_address_test.cc \ @@ -14118,14 +12527,14 @@ else -$(BINDIR)/$(CONFIG)/resolve_address_using_native_resolver_test: $(RESOLVE_ADDRESS_USING_NATIVE_RESOLVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/resolve_address_using_native_resolver_test: $(RESOLVE_ADDRESS_USING_NATIVE_RESOLVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(RESOLVE_ADDRESS_USING_NATIVE_RESOLVER_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)/resolve_address_using_native_resolver_test + $(Q) $(LD) $(LDFLAGS) $(RESOLVE_ADDRESS_USING_NATIVE_RESOLVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/resolve_address_using_native_resolver_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/resolve_address_test.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/iomgr/resolve_address_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_resolve_address_using_native_resolver_test: $(RESOLVE_ADDRESS_USING_NATIVE_RESOLVER_TEST_OBJS:.o=.dep) @@ -14150,14 +12559,14 @@ else -$(BINDIR)/$(CONFIG)/resource_quota_test: $(RESOURCE_QUOTA_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/resource_quota_test: $(RESOURCE_QUOTA_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(RESOURCE_QUOTA_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)/resource_quota_test + $(Q) $(LD) $(LDFLAGS) $(RESOURCE_QUOTA_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/resource_quota_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/resource_quota_test.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/iomgr/resource_quota_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_resource_quota_test: $(RESOURCE_QUOTA_TEST_OBJS:.o=.dep) @@ -14182,14 +12591,14 @@ else -$(BINDIR)/$(CONFIG)/secure_channel_create_test: $(SECURE_CHANNEL_CREATE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/secure_channel_create_test: $(SECURE_CHANNEL_CREATE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(SECURE_CHANNEL_CREATE_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)/secure_channel_create_test + $(Q) $(LD) $(LDFLAGS) $(SECURE_CHANNEL_CREATE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/secure_channel_create_test endif -$(OBJDIR)/$(CONFIG)/test/core/surface/secure_channel_create_test.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/surface/secure_channel_create_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_secure_channel_create_test: $(SECURE_CHANNEL_CREATE_TEST_OBJS:.o=.dep) @@ -14214,14 +12623,14 @@ else -$(BINDIR)/$(CONFIG)/secure_endpoint_test: $(SECURE_ENDPOINT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/secure_endpoint_test: $(SECURE_ENDPOINT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(SECURE_ENDPOINT_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)/secure_endpoint_test + $(Q) $(LD) $(LDFLAGS) $(SECURE_ENDPOINT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/secure_endpoint_test endif -$(OBJDIR)/$(CONFIG)/test/core/security/secure_endpoint_test.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/security/secure_endpoint_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_secure_endpoint_test: $(SECURE_ENDPOINT_TEST_OBJS:.o=.dep) @@ -14246,14 +12655,14 @@ else -$(BINDIR)/$(CONFIG)/sequential_connectivity_test: $(SEQUENTIAL_CONNECTIVITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/sequential_connectivity_test: $(SEQUENTIAL_CONNECTIVITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(SEQUENTIAL_CONNECTIVITY_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)/sequential_connectivity_test + $(Q) $(LD) $(LDFLAGS) $(SEQUENTIAL_CONNECTIVITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/sequential_connectivity_test endif -$(OBJDIR)/$(CONFIG)/test/core/surface/sequential_connectivity_test.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/surface/sequential_connectivity_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_sequential_connectivity_test: $(SEQUENTIAL_CONNECTIVITY_TEST_OBJS:.o=.dep) @@ -14278,14 +12687,14 @@ else -$(BINDIR)/$(CONFIG)/server_chttp2_test: $(SERVER_CHTTP2_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/server_chttp2_test: $(SERVER_CHTTP2_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(SERVER_CHTTP2_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)/server_chttp2_test + $(Q) $(LD) $(LDFLAGS) $(SERVER_CHTTP2_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/server_chttp2_test endif -$(OBJDIR)/$(CONFIG)/test/core/surface/server_chttp2_test.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/surface/server_chttp2_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_server_chttp2_test: $(SERVER_CHTTP2_TEST_OBJS:.o=.dep) @@ -14310,14 +12719,14 @@ else -$(BINDIR)/$(CONFIG)/server_fuzzer: $(SERVER_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/server_fuzzer: $(SERVER_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(SERVER_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)/server_fuzzer + $(Q) $(LDXX) $(LDFLAGS) $(SERVER_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/server_fuzzer endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fuzzers/server_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/end2end/fuzzers/server_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_server_fuzzer: $(SERVER_FUZZER_OBJS:.o=.dep) @@ -14342,14 +12751,14 @@ else -$(BINDIR)/$(CONFIG)/server_test: $(SERVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/server_test: $(SERVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(SERVER_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)/server_test + $(Q) $(LD) $(LDFLAGS) $(SERVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/server_test endif -$(OBJDIR)/$(CONFIG)/test/core/surface/server_test.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/surface/server_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_server_test: $(SERVER_TEST_OBJS:.o=.dep) @@ -14374,14 +12783,14 @@ else -$(BINDIR)/$(CONFIG)/slice_buffer_test: $(SLICE_BUFFER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/slice_buffer_test: $(SLICE_BUFFER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(SLICE_BUFFER_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)/slice_buffer_test + $(Q) $(LD) $(LDFLAGS) $(SLICE_BUFFER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/slice_buffer_test endif -$(OBJDIR)/$(CONFIG)/test/core/slice/slice_buffer_test.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/slice/slice_buffer_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_slice_buffer_test: $(SLICE_BUFFER_TEST_OBJS:.o=.dep) @@ -14406,14 +12815,14 @@ else -$(BINDIR)/$(CONFIG)/slice_string_helpers_test: $(SLICE_STRING_HELPERS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/slice_string_helpers_test: $(SLICE_STRING_HELPERS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(SLICE_STRING_HELPERS_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)/slice_string_helpers_test + $(Q) $(LD) $(LDFLAGS) $(SLICE_STRING_HELPERS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/slice_string_helpers_test endif -$(OBJDIR)/$(CONFIG)/test/core/slice/slice_string_helpers_test.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/slice/slice_string_helpers_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_slice_string_helpers_test: $(SLICE_STRING_HELPERS_TEST_OBJS:.o=.dep) @@ -14438,14 +12847,14 @@ else -$(BINDIR)/$(CONFIG)/slice_test: $(SLICE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/slice_test: $(SLICE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(SLICE_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)/slice_test + $(Q) $(LD) $(LDFLAGS) $(SLICE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/slice_test endif -$(OBJDIR)/$(CONFIG)/test/core/slice/slice_test.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/slice/slice_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_slice_test: $(SLICE_TEST_OBJS:.o=.dep) @@ -14470,14 +12879,14 @@ else -$(BINDIR)/$(CONFIG)/sockaddr_resolver_test: $(SOCKADDR_RESOLVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/sockaddr_resolver_test: $(SOCKADDR_RESOLVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(SOCKADDR_RESOLVER_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)/sockaddr_resolver_test + $(Q) $(LD) $(LDFLAGS) $(SOCKADDR_RESOLVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/sockaddr_resolver_test endif -$(OBJDIR)/$(CONFIG)/test/core/client_channel/resolvers/sockaddr_resolver_test.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/client_channel/resolvers/sockaddr_resolver_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_sockaddr_resolver_test: $(SOCKADDR_RESOLVER_TEST_OBJS:.o=.dep) @@ -14502,14 +12911,14 @@ else -$(BINDIR)/$(CONFIG)/sockaddr_utils_test: $(SOCKADDR_UTILS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/sockaddr_utils_test: $(SOCKADDR_UTILS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(SOCKADDR_UTILS_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)/sockaddr_utils_test + $(Q) $(LD) $(LDFLAGS) $(SOCKADDR_UTILS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/sockaddr_utils_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/sockaddr_utils_test.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/iomgr/sockaddr_utils_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_sockaddr_utils_test: $(SOCKADDR_UTILS_TEST_OBJS:.o=.dep) @@ -14534,14 +12943,14 @@ else -$(BINDIR)/$(CONFIG)/socket_utils_test: $(SOCKET_UTILS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/socket_utils_test: $(SOCKET_UTILS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(SOCKET_UTILS_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)/socket_utils_test + $(Q) $(LD) $(LDFLAGS) $(SOCKET_UTILS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/socket_utils_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/socket_utils_test.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/iomgr/socket_utils_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_socket_utils_test: $(SOCKET_UTILS_TEST_OBJS:.o=.dep) @@ -14566,14 +12975,14 @@ else -$(BINDIR)/$(CONFIG)/ssl_server_fuzzer: $(SSL_SERVER_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/ssl_server_fuzzer: $(SSL_SERVER_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(SSL_SERVER_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)/ssl_server_fuzzer + $(Q) $(LDXX) $(LDFLAGS) $(SSL_SERVER_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/ssl_server_fuzzer endif -$(OBJDIR)/$(CONFIG)/test/core/security/ssl_server_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/security/ssl_server_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_ssl_server_fuzzer: $(SSL_SERVER_FUZZER_OBJS:.o=.dep) @@ -14599,16 +13008,16 @@ else -$(BINDIR)/$(CONFIG)/ssl_transport_security_test: $(SSL_TRANSPORT_SECURITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a +$(BINDIR)/$(CONFIG)/ssl_transport_security_test: $(SSL_TRANSPORT_SECURITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(SSL_TRANSPORT_SECURITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/ssl_transport_security_test + $(Q) $(LD) $(LDFLAGS) $(SSL_TRANSPORT_SECURITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/ssl_transport_security_test endif -$(OBJDIR)/$(CONFIG)/test/core/tsi/ssl_transport_security_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a +$(OBJDIR)/$(CONFIG)/test/core/tsi/ssl_transport_security_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a -$(OBJDIR)/$(CONFIG)/test/core/tsi/transport_security_test_lib.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a +$(OBJDIR)/$(CONFIG)/test/core/tsi/transport_security_test_lib.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a deps_ssl_transport_security_test: $(SSL_TRANSPORT_SECURITY_TEST_OBJS:.o=.dep) @@ -14633,14 +13042,14 @@ else -$(BINDIR)/$(CONFIG)/status_conversion_test: $(STATUS_CONVERSION_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/status_conversion_test: $(STATUS_CONVERSION_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(STATUS_CONVERSION_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)/status_conversion_test + $(Q) $(LD) $(LDFLAGS) $(STATUS_CONVERSION_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/status_conversion_test endif -$(OBJDIR)/$(CONFIG)/test/core/transport/status_conversion_test.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/transport/status_conversion_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_status_conversion_test: $(STATUS_CONVERSION_TEST_OBJS:.o=.dep) @@ -14665,14 +13074,14 @@ else -$(BINDIR)/$(CONFIG)/stream_compression_test: $(STREAM_COMPRESSION_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/stream_compression_test: $(STREAM_COMPRESSION_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(STREAM_COMPRESSION_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)/stream_compression_test + $(Q) $(LD) $(LDFLAGS) $(STREAM_COMPRESSION_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/stream_compression_test endif -$(OBJDIR)/$(CONFIG)/test/core/compression/stream_compression_test.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/compression/stream_compression_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_stream_compression_test: $(STREAM_COMPRESSION_TEST_OBJS:.o=.dep) @@ -14697,14 +13106,14 @@ else -$(BINDIR)/$(CONFIG)/stream_owned_slice_test: $(STREAM_OWNED_SLICE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/stream_owned_slice_test: $(STREAM_OWNED_SLICE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(STREAM_OWNED_SLICE_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)/stream_owned_slice_test + $(Q) $(LD) $(LDFLAGS) $(STREAM_OWNED_SLICE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/stream_owned_slice_test endif -$(OBJDIR)/$(CONFIG)/test/core/transport/stream_owned_slice_test.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/transport/stream_owned_slice_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_stream_owned_slice_test: $(STREAM_OWNED_SLICE_TEST_OBJS:.o=.dep) @@ -14729,14 +13138,14 @@ else -$(BINDIR)/$(CONFIG)/tcp_client_posix_test: $(TCP_CLIENT_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/tcp_client_posix_test: $(TCP_CLIENT_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(TCP_CLIENT_POSIX_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)/tcp_client_posix_test + $(Q) $(LD) $(LDFLAGS) $(TCP_CLIENT_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/tcp_client_posix_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/tcp_client_posix_test.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/iomgr/tcp_client_posix_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_tcp_client_posix_test: $(TCP_CLIENT_POSIX_TEST_OBJS:.o=.dep) @@ -14761,14 +13170,14 @@ else -$(BINDIR)/$(CONFIG)/tcp_client_uv_test: $(TCP_CLIENT_UV_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/tcp_client_uv_test: $(TCP_CLIENT_UV_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(TCP_CLIENT_UV_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)/tcp_client_uv_test + $(Q) $(LD) $(LDFLAGS) $(TCP_CLIENT_UV_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/tcp_client_uv_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/tcp_client_uv_test.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/iomgr/tcp_client_uv_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_tcp_client_uv_test: $(TCP_CLIENT_UV_TEST_OBJS:.o=.dep) @@ -14793,14 +13202,14 @@ else -$(BINDIR)/$(CONFIG)/tcp_posix_test: $(TCP_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/tcp_posix_test: $(TCP_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(TCP_POSIX_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)/tcp_posix_test + $(Q) $(LD) $(LDFLAGS) $(TCP_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/tcp_posix_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/tcp_posix_test.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/iomgr/tcp_posix_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_tcp_posix_test: $(TCP_POSIX_TEST_OBJS:.o=.dep) @@ -14825,14 +13234,14 @@ else -$(BINDIR)/$(CONFIG)/tcp_server_posix_test: $(TCP_SERVER_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/tcp_server_posix_test: $(TCP_SERVER_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(TCP_SERVER_POSIX_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)/tcp_server_posix_test + $(Q) $(LD) $(LDFLAGS) $(TCP_SERVER_POSIX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/tcp_server_posix_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/tcp_server_posix_test.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/iomgr/tcp_server_posix_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_tcp_server_posix_test: $(TCP_SERVER_POSIX_TEST_OBJS:.o=.dep) @@ -14857,14 +13266,14 @@ else -$(BINDIR)/$(CONFIG)/tcp_server_uv_test: $(TCP_SERVER_UV_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/tcp_server_uv_test: $(TCP_SERVER_UV_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(TCP_SERVER_UV_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)/tcp_server_uv_test + $(Q) $(LD) $(LDFLAGS) $(TCP_SERVER_UV_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/tcp_server_uv_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/tcp_server_uv_test.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/iomgr/tcp_server_uv_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_tcp_server_uv_test: $(TCP_SERVER_UV_TEST_OBJS:.o=.dep) @@ -14889,14 +13298,14 @@ else -$(BINDIR)/$(CONFIG)/time_averaged_stats_test: $(TIME_AVERAGED_STATS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/time_averaged_stats_test: $(TIME_AVERAGED_STATS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(TIME_AVERAGED_STATS_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)/time_averaged_stats_test + $(Q) $(LD) $(LDFLAGS) $(TIME_AVERAGED_STATS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/time_averaged_stats_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/time_averaged_stats_test.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/iomgr/time_averaged_stats_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_time_averaged_stats_test: $(TIME_AVERAGED_STATS_TEST_OBJS:.o=.dep) @@ -14921,14 +13330,14 @@ else -$(BINDIR)/$(CONFIG)/timeout_encoding_test: $(TIMEOUT_ENCODING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/timeout_encoding_test: $(TIMEOUT_ENCODING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(TIMEOUT_ENCODING_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)/timeout_encoding_test + $(Q) $(LD) $(LDFLAGS) $(TIMEOUT_ENCODING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/timeout_encoding_test endif -$(OBJDIR)/$(CONFIG)/test/core/transport/timeout_encoding_test.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/transport/timeout_encoding_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_timeout_encoding_test: $(TIMEOUT_ENCODING_TEST_OBJS:.o=.dep) @@ -14953,14 +13362,14 @@ else -$(BINDIR)/$(CONFIG)/timer_heap_test: $(TIMER_HEAP_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/timer_heap_test: $(TIMER_HEAP_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(TIMER_HEAP_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)/timer_heap_test + $(Q) $(LD) $(LDFLAGS) $(TIMER_HEAP_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/timer_heap_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/timer_heap_test.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/iomgr/timer_heap_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_timer_heap_test: $(TIMER_HEAP_TEST_OBJS:.o=.dep) @@ -14985,14 +13394,14 @@ else -$(BINDIR)/$(CONFIG)/timer_list_test: $(TIMER_LIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/timer_list_test: $(TIMER_LIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(TIMER_LIST_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)/timer_list_test + $(Q) $(LD) $(LDFLAGS) $(TIMER_LIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/timer_list_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/timer_list_test.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/iomgr/timer_list_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_timer_list_test: $(TIMER_LIST_TEST_OBJS:.o=.dep) @@ -15017,14 +13426,14 @@ else -$(BINDIR)/$(CONFIG)/transport_connectivity_state_test: $(TRANSPORT_CONNECTIVITY_STATE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/transport_connectivity_state_test: $(TRANSPORT_CONNECTIVITY_STATE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(TRANSPORT_CONNECTIVITY_STATE_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)/transport_connectivity_state_test + $(Q) $(LD) $(LDFLAGS) $(TRANSPORT_CONNECTIVITY_STATE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/transport_connectivity_state_test endif -$(OBJDIR)/$(CONFIG)/test/core/transport/connectivity_state_test.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/transport/connectivity_state_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_transport_connectivity_state_test: $(TRANSPORT_CONNECTIVITY_STATE_TEST_OBJS:.o=.dep) @@ -15049,14 +13458,14 @@ else -$(BINDIR)/$(CONFIG)/transport_metadata_test: $(TRANSPORT_METADATA_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/transport_metadata_test: $(TRANSPORT_METADATA_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(TRANSPORT_METADATA_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)/transport_metadata_test + $(Q) $(LD) $(LDFLAGS) $(TRANSPORT_METADATA_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/transport_metadata_test endif -$(OBJDIR)/$(CONFIG)/test/core/transport/metadata_test.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/transport/metadata_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_transport_metadata_test: $(TRANSPORT_METADATA_TEST_OBJS:.o=.dep) @@ -15081,14 +13490,14 @@ else -$(BINDIR)/$(CONFIG)/transport_security_test: $(TRANSPORT_SECURITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/transport_security_test: $(TRANSPORT_SECURITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(TRANSPORT_SECURITY_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)/transport_security_test + $(Q) $(LD) $(LDFLAGS) $(TRANSPORT_SECURITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/transport_security_test endif -$(OBJDIR)/$(CONFIG)/test/core/tsi/transport_security_test.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/tsi/transport_security_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_transport_security_test: $(TRANSPORT_SECURITY_TEST_OBJS:.o=.dep) @@ -15113,14 +13522,14 @@ else -$(BINDIR)/$(CONFIG)/udp_server_test: $(UDP_SERVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/udp_server_test: $(UDP_SERVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(UDP_SERVER_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)/udp_server_test + $(Q) $(LD) $(LDFLAGS) $(UDP_SERVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/udp_server_test endif -$(OBJDIR)/$(CONFIG)/test/core/iomgr/udp_server_test.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/iomgr/udp_server_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_udp_server_test: $(UDP_SERVER_TEST_OBJS:.o=.dep) @@ -15145,14 +13554,14 @@ else -$(BINDIR)/$(CONFIG)/uri_fuzzer_test: $(URI_FUZZER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/uri_fuzzer_test: $(URI_FUZZER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(URI_FUZZER_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) -lFuzzer -o $(BINDIR)/$(CONFIG)/uri_fuzzer_test + $(Q) $(LDXX) $(LDFLAGS) $(URI_FUZZER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/uri_fuzzer_test endif -$(OBJDIR)/$(CONFIG)/test/core/client_channel/uri_fuzzer_test.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/client_channel/uri_fuzzer_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_uri_fuzzer_test: $(URI_FUZZER_TEST_OBJS:.o=.dep) @@ -15177,14 +13586,14 @@ else -$(BINDIR)/$(CONFIG)/uri_parser_test: $(URI_PARSER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/uri_parser_test: $(URI_PARSER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(URI_PARSER_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)/uri_parser_test + $(Q) $(LD) $(LDFLAGS) $(URI_PARSER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/uri_parser_test endif -$(OBJDIR)/$(CONFIG)/test/core/client_channel/uri_parser_test.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/client_channel/uri_parser_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_uri_parser_test: $(URI_PARSER_TEST_OBJS:.o=.dep) @@ -15195,38 +13604,6 @@ endif endif -WAKEUP_FD_CV_TEST_SRC = \ - test/core/iomgr/wakeup_fd_cv_test.cc \ - -WAKEUP_FD_CV_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(WAKEUP_FD_CV_TEST_SRC)))) -ifeq ($(NO_SECURE),true) - -# You can't build secure targets if you don't have OpenSSL. - -$(BINDIR)/$(CONFIG)/wakeup_fd_cv_test: openssl_dep_error - -else - - - -$(BINDIR)/$(CONFIG)/wakeup_fd_cv_test: $(WAKEUP_FD_CV_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) $(WAKEUP_FD_CV_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)/wakeup_fd_cv_test - -endif - -$(OBJDIR)/$(CONFIG)/test/core/iomgr/wakeup_fd_cv_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a - -deps_wakeup_fd_cv_test: $(WAKEUP_FD_CV_TEST_OBJS:.o=.dep) - -ifneq ($(NO_SECURE),true) -ifneq ($(NO_DEPS),true) --include $(WAKEUP_FD_CV_TEST_OBJS:.o=.dep) -endif -endif - - ALARM_TEST_SRC = \ test/cpp/common/alarm_test.cc \ @@ -15250,16 +13627,16 @@ $(BINDIR)/$(CONFIG)/alarm_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/alarm_test: $(PROTOBUF_DEP) $(ALARM_TEST_OBJS) $(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)/alarm_test: $(PROTOBUF_DEP) $(ALARM_TEST_OBJS) $(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.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(ALARM_TEST_OBJS) $(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)/alarm_test + $(Q) $(LDXX) $(LDFLAGS) $(ALARM_TEST_OBJS) $(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.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/alarm_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/common/alarm_test.o: $(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/common/alarm_test.o: $(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.a deps_alarm_test: $(ALARM_TEST_OBJS:.o=.dep) @@ -15336,16 +13713,16 @@ $(BINDIR)/$(CONFIG)/alts_crypt_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/alts_crypt_test: $(PROTOBUF_DEP) $(ALTS_CRYPT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libalts_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a +$(BINDIR)/$(CONFIG)/alts_crypt_test: $(PROTOBUF_DEP) $(ALTS_CRYPT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libalts_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(ALTS_CRYPT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libalts_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/alts_crypt_test + $(Q) $(LDXX) $(LDFLAGS) $(ALTS_CRYPT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libalts_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/alts_crypt_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/tsi/alts/crypt/aes_gcm_test.o: $(LIBDIR)/$(CONFIG)/libalts_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a +$(OBJDIR)/$(CONFIG)/test/core/tsi/alts/crypt/aes_gcm_test.o: $(LIBDIR)/$(CONFIG)/libalts_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a deps_alts_crypt_test: $(ALTS_CRYPT_TEST_OBJS:.o=.dep) @@ -15855,16 +14232,16 @@ $(BINDIR)/$(CONFIG)/async_end2end_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/async_end2end_test: $(PROTOBUF_DEP) $(ASYNC_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/async_end2end_test: $(PROTOBUF_DEP) $(ASYNC_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(ASYNC_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/async_end2end_test + $(Q) $(LDXX) $(LDFLAGS) $(ASYNC_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/async_end2end_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/async_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/async_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_async_end2end_test: $(ASYNC_END2END_TEST_OBJS:.o=.dep) @@ -15898,16 +14275,16 @@ $(BINDIR)/$(CONFIG)/auth_property_iterator_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/auth_property_iterator_test: $(PROTOBUF_DEP) $(AUTH_PROPERTY_ITERATOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/auth_property_iterator_test: $(PROTOBUF_DEP) $(AUTH_PROPERTY_ITERATOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(AUTH_PROPERTY_ITERATOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/auth_property_iterator_test + $(Q) $(LDXX) $(LDFLAGS) $(AUTH_PROPERTY_ITERATOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/auth_property_iterator_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/common/auth_property_iterator_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/common/auth_property_iterator_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_auth_property_iterator_test: $(AUTH_PROPERTY_ITERATOR_TEST_OBJS:.o=.dep) @@ -15941,16 +14318,16 @@ $(BINDIR)/$(CONFIG)/backoff_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/backoff_test: $(PROTOBUF_DEP) $(BACKOFF_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/backoff_test: $(PROTOBUF_DEP) $(BACKOFF_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BACKOFF_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)/backoff_test + $(Q) $(LDXX) $(LDFLAGS) $(BACKOFF_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/backoff_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/backoff/backoff_test.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/backoff/backoff_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_backoff_test: $(BACKOFF_TEST_OBJS:.o=.dep) @@ -15984,16 +14361,16 @@ $(BINDIR)/$(CONFIG)/bdp_estimator_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/bdp_estimator_test: $(PROTOBUF_DEP) $(BDP_ESTIMATOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/bdp_estimator_test: $(PROTOBUF_DEP) $(BDP_ESTIMATOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BDP_ESTIMATOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(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)/bdp_estimator_test + $(Q) $(LDXX) $(LDFLAGS) $(BDP_ESTIMATOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bdp_estimator_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/transport/bdp_estimator_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/transport/bdp_estimator_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_bdp_estimator_test: $(BDP_ESTIMATOR_TEST_OBJS:.o=.dep) @@ -16004,6 +14381,50 @@ endif endif +BM_ALARM_SRC = \ + test/cpp/microbenchmarks/bm_alarm.cc \ + +BM_ALARM_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BM_ALARM_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/bm_alarm: 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)/bm_alarm: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/bm_alarm: $(PROTOBUF_DEP) $(BM_ALARM_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.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) $(BM_ALARM_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.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_alarm + +endif + +endif + +$(BM_ALARM_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX +$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_alarm.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.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a + +deps_bm_alarm: $(BM_ALARM_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(BM_ALARM_OBJS:.o=.dep) +endif +endif + + BM_ARENA_SRC = \ test/cpp/microbenchmarks/bm_arena.cc \ @@ -16027,17 +14448,17 @@ $(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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.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.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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.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.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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.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.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_bm_arena: $(BM_ARENA_OBJS:.o=.dep) @@ -16048,6 +14469,50 @@ endif endif +BM_BYTE_BUFFER_SRC = \ + test/cpp/microbenchmarks/bm_byte_buffer.cc \ + +BM_BYTE_BUFFER_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BM_BYTE_BUFFER_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/bm_byte_buffer: 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)/bm_byte_buffer: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/bm_byte_buffer: $(PROTOBUF_DEP) $(BM_BYTE_BUFFER_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.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) $(BM_BYTE_BUFFER_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.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_byte_buffer + +endif + +endif + +$(BM_BYTE_BUFFER_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX +$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_byte_buffer.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.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a + +deps_bm_byte_buffer: $(BM_BYTE_BUFFER_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(BM_BYTE_BUFFER_OBJS:.o=.dep) +endif +endif + + BM_CALL_CREATE_SRC = \ test/cpp/microbenchmarks/bm_call_create.cc \ @@ -16071,17 +14536,17 @@ $(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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.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.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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.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.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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.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.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_bm_call_create: $(BM_CALL_CREATE_OBJS:.o=.dep) @@ -16092,6 +14557,94 @@ endif endif +BM_CALLBACK_STREAMING_PING_PONG_SRC = \ + test/cpp/microbenchmarks/bm_callback_streaming_ping_pong.cc \ + +BM_CALLBACK_STREAMING_PING_PONG_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BM_CALLBACK_STREAMING_PING_PONG_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/bm_callback_streaming_ping_pong: 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)/bm_callback_streaming_ping_pong: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/bm_callback_streaming_ping_pong: $(PROTOBUF_DEP) $(BM_CALLBACK_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.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libbm_callback_test_service_impl.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) $(BM_CALLBACK_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.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libbm_callback_test_service_impl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_callback_streaming_ping_pong + +endif + +endif + +$(BM_CALLBACK_STREAMING_PING_PONG_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX +$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_callback_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.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libbm_callback_test_service_impl.a + +deps_bm_callback_streaming_ping_pong: $(BM_CALLBACK_STREAMING_PING_PONG_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(BM_CALLBACK_STREAMING_PING_PONG_OBJS:.o=.dep) +endif +endif + + +BM_CALLBACK_UNARY_PING_PONG_SRC = \ + test/cpp/microbenchmarks/bm_callback_unary_ping_pong.cc \ + +BM_CALLBACK_UNARY_PING_PONG_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BM_CALLBACK_UNARY_PING_PONG_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/bm_callback_unary_ping_pong: 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)/bm_callback_unary_ping_pong: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/bm_callback_unary_ping_pong: $(PROTOBUF_DEP) $(BM_CALLBACK_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.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libbm_callback_test_service_impl.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) $(BM_CALLBACK_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.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libbm_callback_test_service_impl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_callback_unary_ping_pong + +endif + +endif + +$(BM_CALLBACK_UNARY_PING_PONG_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX +$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_callback_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.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libbm_callback_test_service_impl.a + +deps_bm_callback_unary_ping_pong: $(BM_CALLBACK_UNARY_PING_PONG_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(BM_CALLBACK_UNARY_PING_PONG_OBJS:.o=.dep) +endif +endif + + BM_CHANNEL_SRC = \ test/cpp/microbenchmarks/bm_channel.cc \ @@ -16115,17 +14668,17 @@ $(BINDIR)/$(CONFIG)/bm_channel: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/bm_channel: $(PROTOBUF_DEP) $(BM_CHANNEL_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 +$(BINDIR)/$(CONFIG)/bm_channel: $(PROTOBUF_DEP) $(BM_CHANNEL_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.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BM_CHANNEL_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_channel + $(Q) $(LDXX) $(LDFLAGS) $(BM_CHANNEL_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.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_channel endif endif $(BM_CHANNEL_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX -$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_channel.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 +$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_channel.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.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_bm_channel: $(BM_CHANNEL_OBJS:.o=.dep) @@ -16159,17 +14712,17 @@ $(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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.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.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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.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.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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.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.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_bm_chttp2_hpack: $(BM_CHTTP2_HPACK_OBJS:.o=.dep) @@ -16203,17 +14756,17 @@ $(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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.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.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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.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.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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.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.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_bm_chttp2_transport: $(BM_CHTTP2_TRANSPORT_OBJS:.o=.dep) @@ -16247,17 +14800,17 @@ $(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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.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.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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.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.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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.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.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_bm_closure: $(BM_CLOSURE_OBJS:.o=.dep) @@ -16291,17 +14844,17 @@ $(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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.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.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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.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.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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.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.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_bm_cq: $(BM_CQ_OBJS:.o=.dep) @@ -16335,17 +14888,17 @@ $(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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.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.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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.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.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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.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.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_bm_cq_multiple_threads: $(BM_CQ_MULTIPLE_THREADS_OBJS:.o=.dep) @@ -16379,17 +14932,17 @@ $(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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.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.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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.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.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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.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.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_bm_error: $(BM_ERROR_OBJS:.o=.dep) @@ -16423,17 +14976,17 @@ $(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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.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.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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.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.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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.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.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_bm_fullstack_streaming_ping_pong: $(BM_FULLSTACK_STREAMING_PING_PONG_OBJS:.o=.dep) @@ -16467,17 +15020,17 @@ $(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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.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.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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.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.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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.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.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_bm_fullstack_streaming_pump: $(BM_FULLSTACK_STREAMING_PUMP_OBJS:.o=.dep) @@ -16511,17 +15064,17 @@ $(BINDIR)/$(CONFIG)/bm_fullstack_trickle: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/bm_fullstack_trickle: $(PROTOBUF_DEP) $(BM_FULLSTACK_TRICKLE_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 +$(BINDIR)/$(CONFIG)/bm_fullstack_trickle: $(PROTOBUF_DEP) $(BM_FULLSTACK_TRICKLE_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.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BM_FULLSTACK_TRICKLE_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_trickle + $(Q) $(LDXX) $(LDFLAGS) $(BM_FULLSTACK_TRICKLE_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.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_fullstack_trickle endif endif $(BM_FULLSTACK_TRICKLE_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX -$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_fullstack_trickle.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 +$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_fullstack_trickle.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.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_bm_fullstack_trickle: $(BM_FULLSTACK_TRICKLE_OBJS:.o=.dep) @@ -16555,17 +15108,17 @@ $(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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.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.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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.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.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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.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.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_bm_fullstack_unary_ping_pong: $(BM_FULLSTACK_UNARY_PING_PONG_OBJS:.o=.dep) @@ -16599,17 +15152,17 @@ $(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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.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.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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.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.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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.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.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_bm_metadata: $(BM_METADATA_OBJS:.o=.dep) @@ -16643,17 +15196,17 @@ $(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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.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.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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.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.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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.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.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_bm_pollset: $(BM_POLLSET_OBJS:.o=.dep) @@ -16664,6 +15217,50 @@ endif endif +BM_TIMER_SRC = \ + test/cpp/microbenchmarks/bm_timer.cc \ + +BM_TIMER_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BM_TIMER_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/bm_timer: 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)/bm_timer: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/bm_timer: $(PROTOBUF_DEP) $(BM_TIMER_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.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) $(BM_TIMER_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.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_timer + +endif + +endif + +$(BM_TIMER_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX +$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_timer.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.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a + +deps_bm_timer: $(BM_TIMER_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(BM_TIMER_OBJS:.o=.dep) +endif +endif + + BYTE_STREAM_TEST_SRC = \ test/core/transport/byte_stream_test.cc \ @@ -16687,16 +15284,16 @@ $(BINDIR)/$(CONFIG)/byte_stream_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/byte_stream_test: $(PROTOBUF_DEP) $(BYTE_STREAM_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/byte_stream_test: $(PROTOBUF_DEP) $(BYTE_STREAM_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BYTE_STREAM_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)/byte_stream_test + $(Q) $(LDXX) $(LDFLAGS) $(BYTE_STREAM_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/byte_stream_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/transport/byte_stream_test.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/transport/byte_stream_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_byte_stream_test: $(BYTE_STREAM_TEST_OBJS:.o=.dep) @@ -16817,18 +15414,18 @@ $(BINDIR)/$(CONFIG)/channel_trace_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/channel_trace_test: $(PROTOBUF_DEP) $(CHANNEL_TRACE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/channel_trace_test: $(PROTOBUF_DEP) $(CHANNEL_TRACE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(CHANNEL_TRACE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/channel_trace_test + $(Q) $(LDXX) $(LDFLAGS) $(CHANNEL_TRACE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/channel_trace_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/channel/channel_trace_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/channel/channel_trace_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a -$(OBJDIR)/$(CONFIG)/src/proto/grpc/channelz/channelz.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/src/proto/grpc/channelz/channelz.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_channel_trace_test: $(CHANNEL_TRACE_TEST_OBJS:.o=.dep) @@ -16863,16 +15460,16 @@ $(BINDIR)/$(CONFIG)/channelz_registry_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/channelz_registry_test: $(PROTOBUF_DEP) $(CHANNELZ_REGISTRY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/channelz_registry_test: $(PROTOBUF_DEP) $(CHANNELZ_REGISTRY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(CHANNELZ_REGISTRY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/channelz_registry_test + $(Q) $(LDXX) $(LDFLAGS) $(CHANNELZ_REGISTRY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/channelz_registry_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/channel/channelz_registry_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/channel/channelz_registry_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_channelz_registry_test: $(CHANNELZ_REGISTRY_TEST_OBJS:.o=.dep) @@ -16907,18 +15504,18 @@ $(BINDIR)/$(CONFIG)/channelz_service_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/channelz_service_test: $(PROTOBUF_DEP) $(CHANNELZ_SERVICE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/channelz_service_test: $(PROTOBUF_DEP) $(CHANNELZ_SERVICE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(CHANNELZ_SERVICE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz.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)/channelz_service_test + $(Q) $(LDXX) $(LDFLAGS) $(CHANNELZ_SERVICE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/channelz_service_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/channelz_service_test.o: $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/channelz_service_test.o: $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a -$(OBJDIR)/$(CONFIG)/src/proto/grpc/channelz/channelz.o: $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/src/proto/grpc/channelz/channelz.o: $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_channelz_service_test: $(CHANNELZ_SERVICE_TEST_OBJS:.o=.dep) @@ -16954,18 +15551,18 @@ $(BINDIR)/$(CONFIG)/channelz_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/channelz_test: $(PROTOBUF_DEP) $(CHANNELZ_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/channelz_test: $(PROTOBUF_DEP) $(CHANNELZ_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(CHANNELZ_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/channelz_test + $(Q) $(LDXX) $(LDFLAGS) $(CHANNELZ_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/channelz_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/channel/channelz_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/channel/channelz_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a -$(OBJDIR)/$(CONFIG)/src/proto/grpc/channelz/channelz.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/src/proto/grpc/channelz/channelz.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_channelz_test: $(CHANNELZ_TEST_OBJS:.o=.dep) @@ -17086,16 +15683,16 @@ $(BINDIR)/$(CONFIG)/chttp2_settings_timeout_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/chttp2_settings_timeout_test: $(PROTOBUF_DEP) $(CHTTP2_SETTINGS_TIMEOUT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/chttp2_settings_timeout_test: $(PROTOBUF_DEP) $(CHTTP2_SETTINGS_TIMEOUT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(CHTTP2_SETTINGS_TIMEOUT_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)/chttp2_settings_timeout_test + $(Q) $(LDXX) $(LDFLAGS) $(CHTTP2_SETTINGS_TIMEOUT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/chttp2_settings_timeout_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/transport/chttp2/settings_timeout_test.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/transport/chttp2/settings_timeout_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_chttp2_settings_timeout_test: $(CHTTP2_SETTINGS_TIMEOUT_TEST_OBJS:.o=.dep) @@ -17129,16 +15726,16 @@ $(BINDIR)/$(CONFIG)/cli_call_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/cli_call_test: $(PROTOBUF_DEP) $(CLI_CALL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/cli_call_test: $(PROTOBUF_DEP) $(CLI_CALL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(CLI_CALL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.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)/cli_call_test + $(Q) $(LDXX) $(LDFLAGS) $(CLI_CALL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/cli_call_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/util/cli_call_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/util/cli_call_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_cli_call_test: $(CLI_CALL_TEST_OBJS:.o=.dep) @@ -17151,6 +15748,7 @@ endif CLIENT_CALLBACK_END2END_TEST_SRC = \ test/cpp/end2end/client_callback_end2end_test.cc \ + test/cpp/end2end/interceptors_util.cc \ CLIENT_CALLBACK_END2END_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(CLIENT_CALLBACK_END2END_TEST_SRC)))) ifeq ($(NO_SECURE),true) @@ -17172,16 +15770,18 @@ $(BINDIR)/$(CONFIG)/client_callback_end2end_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/client_callback_end2end_test: $(PROTOBUF_DEP) $(CLIENT_CALLBACK_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/client_callback_end2end_test: $(PROTOBUF_DEP) $(CLIENT_CALLBACK_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(CLIENT_CALLBACK_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/client_callback_end2end_test + $(Q) $(LDXX) $(LDFLAGS) $(CLIENT_CALLBACK_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/client_callback_end2end_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/client_callback_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/client_callback_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/interceptors_util.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_client_callback_end2end_test: $(CLIENT_CALLBACK_END2END_TEST_OBJS:.o=.dep) @@ -17216,18 +15816,18 @@ $(BINDIR)/$(CONFIG)/client_channel_stress_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/client_channel_stress_test: $(PROTOBUF_DEP) $(CLIENT_CHANNEL_STRESS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/client_channel_stress_test: $(PROTOBUF_DEP) $(CLIENT_CHANNEL_STRESS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(CLIENT_CHANNEL_STRESS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/client_channel_stress_test + $(Q) $(LDXX) $(LDFLAGS) $(CLIENT_CHANNEL_STRESS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/client_channel_stress_test endif endif -$(OBJDIR)/$(CONFIG)/src/proto/grpc/lb/v1/load_balancer.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/src/proto/grpc/lb/v1/load_balancer.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a -$(OBJDIR)/$(CONFIG)/test/cpp/client/client_channel_stress_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/client/client_channel_stress_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_client_channel_stress_test: $(CLIENT_CHANNEL_STRESS_TEST_OBJS:.o=.dep) @@ -17262,16 +15862,16 @@ $(BINDIR)/$(CONFIG)/client_crash_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/client_crash_test: $(PROTOBUF_DEP) $(CLIENT_CRASH_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/client_crash_test: $(PROTOBUF_DEP) $(CLIENT_CRASH_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(CLIENT_CRASH_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/client_crash_test + $(Q) $(LDXX) $(LDFLAGS) $(CLIENT_CRASH_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/client_crash_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/client_crash_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/client_crash_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_client_crash_test: $(CLIENT_CRASH_TEST_OBJS:.o=.dep) @@ -17305,16 +15905,16 @@ $(BINDIR)/$(CONFIG)/client_crash_test_server: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/client_crash_test_server: $(PROTOBUF_DEP) $(CLIENT_CRASH_TEST_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/client_crash_test_server: $(PROTOBUF_DEP) $(CLIENT_CRASH_TEST_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(CLIENT_CRASH_TEST_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/client_crash_test_server + $(Q) $(LDXX) $(LDFLAGS) $(CLIENT_CRASH_TEST_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/client_crash_test_server endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/client_crash_test_server.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/client_crash_test_server.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_client_crash_test_server: $(CLIENT_CRASH_TEST_SERVER_OBJS:.o=.dep) @@ -17349,18 +15949,18 @@ $(BINDIR)/$(CONFIG)/client_interceptors_end2end_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/client_interceptors_end2end_test: $(PROTOBUF_DEP) $(CLIENT_INTERCEPTORS_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/client_interceptors_end2end_test: $(PROTOBUF_DEP) $(CLIENT_INTERCEPTORS_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(CLIENT_INTERCEPTORS_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/client_interceptors_end2end_test + $(Q) $(LDXX) $(LDFLAGS) $(CLIENT_INTERCEPTORS_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/client_interceptors_end2end_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/client_interceptors_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/client_interceptors_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/interceptors_util.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/interceptors_util.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_client_interceptors_end2end_test: $(CLIENT_INTERCEPTORS_END2END_TEST_OBJS:.o=.dep) @@ -17394,16 +15994,16 @@ $(BINDIR)/$(CONFIG)/client_lb_end2end_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/client_lb_end2end_test: $(PROTOBUF_DEP) $(CLIENT_LB_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/client_lb_end2end_test: $(PROTOBUF_DEP) $(CLIENT_LB_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(CLIENT_LB_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/client_lb_end2end_test + $(Q) $(LDXX) $(LDFLAGS) $(CLIENT_LB_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/client_lb_end2end_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/client_lb_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/client_lb_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_client_lb_end2end_test: $(CLIENT_LB_END2END_TEST_OBJS:.o=.dep) @@ -17548,6 +16148,49 @@ $(OBJDIR)/$(CONFIG)/test/cpp/codegen/codegen_test_minimal.o: $(GENDIR)/src/proto $(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 +CONTEXT_LIST_TEST_SRC = \ + test/core/transport/chttp2/context_list_test.cc \ + +CONTEXT_LIST_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(CONTEXT_LIST_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/context_list_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)/context_list_test: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/context_list_test: $(PROTOBUF_DEP) $(CONTEXT_LIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) $(CONTEXT_LIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/context_list_test + +endif + +endif + +$(OBJDIR)/$(CONFIG)/test/core/transport/chttp2/context_list_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_context_list_test: $(CONTEXT_LIST_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(CONTEXT_LIST_TEST_OBJS:.o=.dep) +endif +endif + + CREDENTIALS_TEST_SRC = \ test/cpp/client/credentials_test.cc \ @@ -17614,16 +16257,16 @@ $(BINDIR)/$(CONFIG)/cxx_byte_buffer_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/cxx_byte_buffer_test: $(PROTOBUF_DEP) $(CXX_BYTE_BUFFER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/cxx_byte_buffer_test: $(PROTOBUF_DEP) $(CXX_BYTE_BUFFER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(CXX_BYTE_BUFFER_TEST_OBJS) $(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)/cxx_byte_buffer_test + $(Q) $(LDXX) $(LDFLAGS) $(CXX_BYTE_BUFFER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/cxx_byte_buffer_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/util/byte_buffer_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/util/byte_buffer_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_cxx_byte_buffer_test: $(CXX_BYTE_BUFFER_TEST_OBJS:.o=.dep) @@ -17657,16 +16300,16 @@ $(BINDIR)/$(CONFIG)/cxx_slice_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/cxx_slice_test: $(PROTOBUF_DEP) $(CXX_SLICE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/cxx_slice_test: $(PROTOBUF_DEP) $(CXX_SLICE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(CXX_SLICE_TEST_OBJS) $(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)/cxx_slice_test + $(Q) $(LDXX) $(LDFLAGS) $(CXX_SLICE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/cxx_slice_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/util/slice_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/util/slice_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_cxx_slice_test: $(CXX_SLICE_TEST_OBJS:.o=.dep) @@ -17743,16 +16386,16 @@ $(BINDIR)/$(CONFIG)/cxx_time_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/cxx_time_test: $(PROTOBUF_DEP) $(CXX_TIME_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/cxx_time_test: $(PROTOBUF_DEP) $(CXX_TIME_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(CXX_TIME_TEST_OBJS) $(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)/cxx_time_test + $(Q) $(LDXX) $(LDFLAGS) $(CXX_TIME_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/cxx_time_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/util/time_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/util/time_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_cxx_time_test: $(CXX_TIME_TEST_OBJS:.o=.dep) @@ -17787,18 +16430,18 @@ $(BINDIR)/$(CONFIG)/end2end_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/end2end_test: $(PROTOBUF_DEP) $(END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/end2end_test: $(PROTOBUF_DEP) $(END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/end2end_test + $(Q) $(LDXX) $(LDFLAGS) $(END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/end2end_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/interceptors_util.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/interceptors_util.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_end2end_test: $(END2END_TEST_OBJS:.o=.dep) @@ -17879,16 +16522,16 @@ $(BINDIR)/$(CONFIG)/exception_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/exception_test: $(PROTOBUF_DEP) $(EXCEPTION_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/exception_test: $(PROTOBUF_DEP) $(EXCEPTION_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(EXCEPTION_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/exception_test + $(Q) $(LDXX) $(LDFLAGS) $(EXCEPTION_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/exception_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/exception_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/exception_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_exception_test: $(EXCEPTION_TEST_OBJS:.o=.dep) @@ -17922,16 +16565,16 @@ $(BINDIR)/$(CONFIG)/filter_end2end_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/filter_end2end_test: $(PROTOBUF_DEP) $(FILTER_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/filter_end2end_test: $(PROTOBUF_DEP) $(FILTER_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(FILTER_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/filter_end2end_test + $(Q) $(LDXX) $(LDFLAGS) $(FILTER_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/filter_end2end_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/filter_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/filter_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_filter_end2end_test: $(FILTER_END2END_TEST_OBJS:.o=.dep) @@ -17965,16 +16608,16 @@ $(BINDIR)/$(CONFIG)/generic_end2end_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/generic_end2end_test: $(PROTOBUF_DEP) $(GENERIC_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/generic_end2end_test: $(PROTOBUF_DEP) $(GENERIC_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(GENERIC_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/generic_end2end_test + $(Q) $(LDXX) $(LDFLAGS) $(GENERIC_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/generic_end2end_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/generic_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/generic_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_generic_end2end_test: $(GENERIC_END2END_TEST_OBJS:.o=.dep) @@ -17985,6 +16628,92 @@ endif endif +GLOBAL_CONFIG_ENV_TEST_SRC = \ + test/core/gprpp/global_config_env_test.cc \ + +GLOBAL_CONFIG_ENV_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GLOBAL_CONFIG_ENV_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/global_config_env_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)/global_config_env_test: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/global_config_env_test: $(PROTOBUF_DEP) $(GLOBAL_CONFIG_ENV_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) $(GLOBAL_CONFIG_ENV_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/global_config_env_test + +endif + +endif + +$(OBJDIR)/$(CONFIG)/test/core/gprpp/global_config_env_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a + +deps_global_config_env_test: $(GLOBAL_CONFIG_ENV_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(GLOBAL_CONFIG_ENV_TEST_OBJS:.o=.dep) +endif +endif + + +GLOBAL_CONFIG_TEST_SRC = \ + test/core/gprpp/global_config_test.cc \ + +GLOBAL_CONFIG_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GLOBAL_CONFIG_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/global_config_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)/global_config_test: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/global_config_test: $(PROTOBUF_DEP) $(GLOBAL_CONFIG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) $(GLOBAL_CONFIG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/global_config_test + +endif + +endif + +$(OBJDIR)/$(CONFIG)/test/core/gprpp/global_config_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a + +deps_global_config_test: $(GLOBAL_CONFIG_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(GLOBAL_CONFIG_TEST_OBJS:.o=.dep) +endif +endif + + GOLDEN_FILE_TEST_SRC = \ $(GENDIR)/src/proto/grpc/testing/compiler_test.pb.cc $(GENDIR)/src/proto/grpc/testing/compiler_test.grpc.pb.cc \ test/cpp/codegen/golden_file_test.cc \ @@ -18009,18 +16738,18 @@ $(BINDIR)/$(CONFIG)/golden_file_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/golden_file_test: $(PROTOBUF_DEP) $(GOLDEN_FILE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/golden_file_test: $(PROTOBUF_DEP) $(GOLDEN_FILE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(GOLDEN_FILE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/golden_file_test + $(Q) $(LDXX) $(LDFLAGS) $(GOLDEN_FILE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/golden_file_test endif endif -$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/compiler_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/compiler_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a -$(OBJDIR)/$(CONFIG)/test/cpp/codegen/golden_file_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/codegen/golden_file_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_golden_file_test: $(GOLDEN_FILE_TEST_OBJS:.o=.dep) @@ -18118,6 +16847,49 @@ endif endif +GRPC_CORE_MAP_TEST_SRC = \ + test/core/gprpp/map_test.cc \ + +GRPC_CORE_MAP_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GRPC_CORE_MAP_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/grpc_core_map_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)/grpc_core_map_test: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/grpc_core_map_test: $(PROTOBUF_DEP) $(GRPC_CORE_MAP_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) $(GRPC_CORE_MAP_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/grpc_core_map_test + +endif + +endif + +$(OBJDIR)/$(CONFIG)/test/core/gprpp/map_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_grpc_core_map_test: $(GRPC_CORE_MAP_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(GRPC_CORE_MAP_TEST_OBJS:.o=.dep) +endif +endif + + GRPC_CPP_PLUGIN_SRC = \ src/compiler/cpp_plugin.cc \ @@ -18203,16 +16975,16 @@ $(BINDIR)/$(CONFIG)/grpc_linux_system_roots_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/grpc_linux_system_roots_test: $(PROTOBUF_DEP) $(GRPC_LINUX_SYSTEM_ROOTS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/grpc_linux_system_roots_test: $(PROTOBUF_DEP) $(GRPC_LINUX_SYSTEM_ROOTS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(GRPC_LINUX_SYSTEM_ROOTS_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)/grpc_linux_system_roots_test + $(Q) $(LDXX) $(LDFLAGS) $(GRPC_LINUX_SYSTEM_ROOTS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/grpc_linux_system_roots_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/security/linux_system_roots_test.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/security/linux_system_roots_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_grpc_linux_system_roots_test: $(GRPC_LINUX_SYSTEM_ROOTS_TEST_OBJS:.o=.dep) @@ -18403,20 +17175,20 @@ $(BINDIR)/$(CONFIG)/grpc_tool_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/grpc_tool_test: $(PROTOBUF_DEP) $(GRPC_TOOL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/grpc_tool_test: $(PROTOBUF_DEP) $(GRPC_TOOL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(GRPC_TOOL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.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)/grpc_tool_test + $(Q) $(LDXX) $(LDFLAGS) $(GRPC_TOOL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/grpc_tool_test endif endif -$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/echo.o: $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/echo.o: $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a -$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/echo_messages.o: $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/echo_messages.o: $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a -$(OBJDIR)/$(CONFIG)/test/cpp/util/grpc_tool_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/util/grpc_tool_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_grpc_tool_test: $(GRPC_TOOL_TEST_OBJS:.o=.dep) @@ -18499,18 +17271,18 @@ $(BINDIR)/$(CONFIG)/grpclb_end2end_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/grpclb_end2end_test: $(PROTOBUF_DEP) $(GRPCLB_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/grpclb_end2end_test: $(PROTOBUF_DEP) $(GRPCLB_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(GRPCLB_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/grpclb_end2end_test + $(Q) $(LDXX) $(LDFLAGS) $(GRPCLB_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/grpclb_end2end_test endif endif -$(OBJDIR)/$(CONFIG)/src/proto/grpc/lb/v1/load_balancer.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/src/proto/grpc/lb/v1/load_balancer.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/grpclb_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/grpclb_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_grpclb_end2end_test: $(GRPCLB_END2END_TEST_OBJS:.o=.dep) @@ -18545,16 +17317,16 @@ $(BINDIR)/$(CONFIG)/h2_ssl_cert_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/h2_ssl_cert_test: $(PROTOBUF_DEP) $(H2_SSL_CERT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_ssl_cert_test: $(PROTOBUF_DEP) $(H2_SSL_CERT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(H2_SSL_CERT_TEST_OBJS) $(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)/h2_ssl_cert_test + $(Q) $(LDXX) $(LDFLAGS) $(H2_SSL_CERT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/h2_ssl_cert_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/h2_ssl_cert_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/h2_ssl_cert_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_ssl_cert_test: $(H2_SSL_CERT_TEST_OBJS:.o=.dep) @@ -18588,16 +17360,16 @@ $(BINDIR)/$(CONFIG)/h2_ssl_session_reuse_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/h2_ssl_session_reuse_test: $(PROTOBUF_DEP) $(H2_SSL_SESSION_REUSE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_ssl_session_reuse_test: $(PROTOBUF_DEP) $(H2_SSL_SESSION_REUSE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(H2_SSL_SESSION_REUSE_TEST_OBJS) $(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)/h2_ssl_session_reuse_test + $(Q) $(LDXX) $(LDFLAGS) $(H2_SSL_SESSION_REUSE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/h2_ssl_session_reuse_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/h2_ssl_session_reuse_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/h2_ssl_session_reuse_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_ssl_session_reuse_test: $(H2_SSL_SESSION_REUSE_TEST_OBJS:.o=.dep) @@ -18631,16 +17403,16 @@ $(BINDIR)/$(CONFIG)/health_service_end2end_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/health_service_end2end_test: $(PROTOBUF_DEP) $(HEALTH_SERVICE_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/health_service_end2end_test: $(PROTOBUF_DEP) $(HEALTH_SERVICE_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(HEALTH_SERVICE_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/health_service_end2end_test + $(Q) $(LDXX) $(LDFLAGS) $(HEALTH_SERVICE_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/health_service_end2end_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/health_service_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/health_service_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_health_service_end2end_test: $(HEALTH_SERVICE_END2END_TEST_OBJS:.o=.dep) @@ -18705,16 +17477,16 @@ $(BINDIR)/$(CONFIG)/hybrid_end2end_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/hybrid_end2end_test: $(PROTOBUF_DEP) $(HYBRID_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/hybrid_end2end_test: $(PROTOBUF_DEP) $(HYBRID_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(HYBRID_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/hybrid_end2end_test + $(Q) $(LDXX) $(LDFLAGS) $(HYBRID_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/hybrid_end2end_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/hybrid_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/hybrid_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_hybrid_end2end_test: $(HYBRID_END2END_TEST_OBJS:.o=.dep) @@ -18748,16 +17520,16 @@ $(BINDIR)/$(CONFIG)/inlined_vector_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/inlined_vector_test: $(PROTOBUF_DEP) $(INLINED_VECTOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/inlined_vector_test: $(PROTOBUF_DEP) $(INLINED_VECTOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(INLINED_VECTOR_TEST_OBJS) $(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)/inlined_vector_test + $(Q) $(LDXX) $(LDFLAGS) $(INLINED_VECTOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/inlined_vector_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/gprpp/inlined_vector_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gprpp/inlined_vector_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_inlined_vector_test: $(INLINED_VECTOR_TEST_OBJS:.o=.dep) @@ -18791,16 +17563,16 @@ $(BINDIR)/$(CONFIG)/inproc_sync_unary_ping_pong_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/inproc_sync_unary_ping_pong_test: $(PROTOBUF_DEP) $(INPROC_SYNC_UNARY_PING_PONG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/inproc_sync_unary_ping_pong_test: $(PROTOBUF_DEP) $(INPROC_SYNC_UNARY_PING_PONG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(INPROC_SYNC_UNARY_PING_PONG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/inproc_sync_unary_ping_pong_test + $(Q) $(LDXX) $(LDFLAGS) $(INPROC_SYNC_UNARY_PING_PONG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/inproc_sync_unary_ping_pong_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/qps/inproc_sync_unary_ping_pong_test.o: $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/qps/inproc_sync_unary_ping_pong_test.o: $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_inproc_sync_unary_ping_pong_test: $(INPROC_SYNC_UNARY_PING_PONG_TEST_OBJS:.o=.dep) @@ -18830,10 +17602,10 @@ $(BINDIR)/$(CONFIG)/interop_client: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/interop_client: $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/interop_client: $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/interop_client + $(Q) $(LDXX) $(LDFLAGS) $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/interop_client endif @@ -18861,10 +17633,10 @@ $(BINDIR)/$(CONFIG)/interop_server: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/interop_server: $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_lib.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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/interop_server: $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_lib.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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/interop_server + $(Q) $(LDXX) $(LDFLAGS) $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/interop_server endif @@ -18896,16 +17668,16 @@ $(BINDIR)/$(CONFIG)/interop_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/interop_test: $(PROTOBUF_DEP) $(INTEROP_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/interop_test: $(PROTOBUF_DEP) $(INTEROP_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(INTEROP_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.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)/interop_test + $(Q) $(LDXX) $(LDFLAGS) $(INTEROP_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/interop_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/interop/interop_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/interop/interop_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_interop_test: $(INTEROP_TEST_OBJS:.o=.dep) @@ -18939,16 +17711,16 @@ $(BINDIR)/$(CONFIG)/json_run_localhost: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/json_run_localhost: $(PROTOBUF_DEP) $(JSON_RUN_LOCALHOST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/json_run_localhost: $(PROTOBUF_DEP) $(JSON_RUN_LOCALHOST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(JSON_RUN_LOCALHOST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/json_run_localhost + $(Q) $(LDXX) $(LDFLAGS) $(JSON_RUN_LOCALHOST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/json_run_localhost endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/qps/json_run_localhost.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/qps/json_run_localhost.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_json_run_localhost: $(JSON_RUN_LOCALHOST_OBJS:.o=.dep) @@ -18982,16 +17754,16 @@ $(BINDIR)/$(CONFIG)/memory_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/memory_test: $(PROTOBUF_DEP) $(MEMORY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/memory_test: $(PROTOBUF_DEP) $(MEMORY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(MEMORY_TEST_OBJS) $(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)/memory_test + $(Q) $(LDXX) $(LDFLAGS) $(MEMORY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/memory_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/gprpp/memory_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gprpp/memory_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_memory_test: $(MEMORY_TEST_OBJS:.o=.dep) @@ -19002,6 +17774,49 @@ endif endif +MESSAGE_ALLOCATOR_END2END_TEST_SRC = \ + test/cpp/end2end/message_allocator_end2end_test.cc \ + +MESSAGE_ALLOCATOR_END2END_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(MESSAGE_ALLOCATOR_END2END_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/message_allocator_end2end_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)/message_allocator_end2end_test: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/message_allocator_end2end_test: $(PROTOBUF_DEP) $(MESSAGE_ALLOCATOR_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) $(MESSAGE_ALLOCATOR_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/message_allocator_end2end_test + +endif + +endif + +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/message_allocator_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_message_allocator_end2end_test: $(MESSAGE_ALLOCATOR_END2END_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(MESSAGE_ALLOCATOR_END2END_TEST_OBJS:.o=.dep) +endif +endif + + METRICS_CLIENT_SRC = \ $(GENDIR)/src/proto/grpc/testing/metrics.pb.cc $(GENDIR)/src/proto/grpc/testing/metrics.grpc.pb.cc \ test/cpp/interop/metrics_client.cc \ @@ -19072,16 +17887,16 @@ $(BINDIR)/$(CONFIG)/mock_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/mock_test: $(PROTOBUF_DEP) $(MOCK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/mock_test: $(PROTOBUF_DEP) $(MOCK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(MOCK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/mock_test + $(Q) $(LDXX) $(LDFLAGS) $(MOCK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/mock_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/mock_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/mock_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_mock_test: $(MOCK_TEST_OBJS:.o=.dep) @@ -19115,16 +17930,16 @@ $(BINDIR)/$(CONFIG)/nonblocking_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/nonblocking_test: $(PROTOBUF_DEP) $(NONBLOCKING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/nonblocking_test: $(PROTOBUF_DEP) $(NONBLOCKING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(NONBLOCKING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/nonblocking_test + $(Q) $(LDXX) $(LDFLAGS) $(NONBLOCKING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/nonblocking_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/nonblocking_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/nonblocking_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_nonblocking_test: $(NONBLOCKING_TEST_OBJS:.o=.dep) @@ -19179,6 +17994,49 @@ endif endif +OPTIONAL_TEST_SRC = \ + test/core/gprpp/optional_test.cc \ + +OPTIONAL_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(OPTIONAL_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/optional_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)/optional_test: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/optional_test: $(PROTOBUF_DEP) $(OPTIONAL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) $(OPTIONAL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/optional_test + +endif + +endif + +$(OBJDIR)/$(CONFIG)/test/core/gprpp/optional_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_optional_test: $(OPTIONAL_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(OPTIONAL_TEST_OBJS:.o=.dep) +endif +endif + + ORPHANABLE_TEST_SRC = \ test/core/gprpp/orphanable_test.cc \ @@ -19202,16 +18060,16 @@ $(BINDIR)/$(CONFIG)/orphanable_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/orphanable_test: $(PROTOBUF_DEP) $(ORPHANABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/orphanable_test: $(PROTOBUF_DEP) $(ORPHANABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(ORPHANABLE_TEST_OBJS) $(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)/orphanable_test + $(Q) $(LDXX) $(LDFLAGS) $(ORPHANABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/orphanable_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/gprpp/orphanable_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gprpp/orphanable_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_orphanable_test: $(ORPHANABLE_TEST_OBJS:.o=.dep) @@ -19245,16 +18103,16 @@ $(BINDIR)/$(CONFIG)/proto_server_reflection_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/proto_server_reflection_test: $(PROTOBUF_DEP) $(PROTO_SERVER_REFLECTION_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/proto_server_reflection_test: $(PROTOBUF_DEP) $(PROTO_SERVER_REFLECTION_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(PROTO_SERVER_REFLECTION_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.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)/proto_server_reflection_test + $(Q) $(LDXX) $(LDFLAGS) $(PROTO_SERVER_REFLECTION_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/proto_server_reflection_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/proto_server_reflection_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/proto_server_reflection_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_proto_server_reflection_test: $(PROTO_SERVER_REFLECTION_TEST_OBJS:.o=.dep) @@ -19331,16 +18189,16 @@ $(BINDIR)/$(CONFIG)/qps_interarrival_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/qps_interarrival_test: $(PROTOBUF_DEP) $(QPS_INTERARRIVAL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/qps_interarrival_test: $(PROTOBUF_DEP) $(QPS_INTERARRIVAL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(QPS_INTERARRIVAL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/qps_interarrival_test + $(Q) $(LDXX) $(LDFLAGS) $(QPS_INTERARRIVAL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/qps_interarrival_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/qps/qps_interarrival_test.o: $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/qps/qps_interarrival_test.o: $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_qps_interarrival_test: $(QPS_INTERARRIVAL_TEST_OBJS:.o=.dep) @@ -19374,16 +18232,16 @@ $(BINDIR)/$(CONFIG)/qps_json_driver: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/qps_json_driver: $(PROTOBUF_DEP) $(QPS_JSON_DRIVER_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/qps_json_driver: $(PROTOBUF_DEP) $(QPS_JSON_DRIVER_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(QPS_JSON_DRIVER_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/qps_json_driver + $(Q) $(LDXX) $(LDFLAGS) $(QPS_JSON_DRIVER_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/qps_json_driver endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/qps/qps_json_driver.o: $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/qps/qps_json_driver.o: $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_qps_json_driver: $(QPS_JSON_DRIVER_OBJS:.o=.dep) @@ -19417,16 +18275,16 @@ $(BINDIR)/$(CONFIG)/qps_openloop_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/qps_openloop_test: $(PROTOBUF_DEP) $(QPS_OPENLOOP_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/qps_openloop_test: $(PROTOBUF_DEP) $(QPS_OPENLOOP_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(QPS_OPENLOOP_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/qps_openloop_test + $(Q) $(LDXX) $(LDFLAGS) $(QPS_OPENLOOP_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/qps_openloop_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/qps/qps_openloop_test.o: $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/qps/qps_openloop_test.o: $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_qps_openloop_test: $(QPS_OPENLOOP_TEST_OBJS:.o=.dep) @@ -19460,16 +18318,16 @@ $(BINDIR)/$(CONFIG)/qps_worker: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/qps_worker: $(PROTOBUF_DEP) $(QPS_WORKER_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/qps_worker: $(PROTOBUF_DEP) $(QPS_WORKER_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(QPS_WORKER_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/qps_worker + $(Q) $(LDXX) $(LDFLAGS) $(QPS_WORKER_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/qps_worker endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/qps/worker.o: $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/qps/worker.o: $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_qps_worker: $(QPS_WORKER_OBJS:.o=.dep) @@ -19503,16 +18361,16 @@ $(BINDIR)/$(CONFIG)/raw_end2end_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/raw_end2end_test: $(PROTOBUF_DEP) $(RAW_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/raw_end2end_test: $(PROTOBUF_DEP) $(RAW_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(RAW_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/raw_end2end_test + $(Q) $(LDXX) $(LDFLAGS) $(RAW_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/raw_end2end_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/raw_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/raw_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_raw_end2end_test: $(RAW_END2END_TEST_OBJS:.o=.dep) @@ -19549,22 +18407,22 @@ $(BINDIR)/$(CONFIG)/reconnect_interop_client: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/reconnect_interop_client: $(PROTOBUF_DEP) $(RECONNECT_INTEROP_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/reconnect_interop_client: $(PROTOBUF_DEP) $(RECONNECT_INTEROP_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(RECONNECT_INTEROP_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/reconnect_interop_client + $(Q) $(LDXX) $(LDFLAGS) $(RECONNECT_INTEROP_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/reconnect_interop_client endif endif -$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/empty.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/empty.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a -$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/messages.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/messages.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a -$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a -$(OBJDIR)/$(CONFIG)/test/cpp/interop/reconnect_interop_client.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/interop/reconnect_interop_client.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_reconnect_interop_client: $(RECONNECT_INTEROP_CLIENT_OBJS:.o=.dep) @@ -19602,22 +18460,22 @@ $(BINDIR)/$(CONFIG)/reconnect_interop_server: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/reconnect_interop_server: $(PROTOBUF_DEP) $(RECONNECT_INTEROP_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBDIR)/$(CONFIG)/libtest_tcp_server.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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/reconnect_interop_server: $(PROTOBUF_DEP) $(RECONNECT_INTEROP_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(RECONNECT_INTEROP_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBDIR)/$(CONFIG)/libtest_tcp_server.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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/reconnect_interop_server + $(Q) $(LDXX) $(LDFLAGS) $(RECONNECT_INTEROP_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/reconnect_interop_server endif endif -$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/empty.o: $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBDIR)/$(CONFIG)/libtest_tcp_server.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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/empty.o: $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a -$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/messages.o: $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBDIR)/$(CONFIG)/libtest_tcp_server.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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/messages.o: $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a -$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/test.o: $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBDIR)/$(CONFIG)/libtest_tcp_server.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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/test.o: $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a -$(OBJDIR)/$(CONFIG)/test/cpp/interop/reconnect_interop_server.o: $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBDIR)/$(CONFIG)/libtest_tcp_server.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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/interop/reconnect_interop_server.o: $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_reconnect_interop_server: $(RECONNECT_INTEROP_SERVER_OBJS:.o=.dep) @@ -19652,16 +18510,16 @@ $(BINDIR)/$(CONFIG)/ref_counted_ptr_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/ref_counted_ptr_test: $(PROTOBUF_DEP) $(REF_COUNTED_PTR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/ref_counted_ptr_test: $(PROTOBUF_DEP) $(REF_COUNTED_PTR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(REF_COUNTED_PTR_TEST_OBJS) $(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)/ref_counted_ptr_test + $(Q) $(LDXX) $(LDFLAGS) $(REF_COUNTED_PTR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/ref_counted_ptr_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/gprpp/ref_counted_ptr_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gprpp/ref_counted_ptr_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_ref_counted_ptr_test: $(REF_COUNTED_PTR_TEST_OBJS:.o=.dep) @@ -19695,16 +18553,16 @@ $(BINDIR)/$(CONFIG)/ref_counted_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/ref_counted_test: $(PROTOBUF_DEP) $(REF_COUNTED_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/ref_counted_test: $(PROTOBUF_DEP) $(REF_COUNTED_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(REF_COUNTED_TEST_OBJS) $(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)/ref_counted_test + $(Q) $(LDXX) $(LDFLAGS) $(REF_COUNTED_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/ref_counted_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/gprpp/ref_counted_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/gprpp/ref_counted_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_ref_counted_test: $(REF_COUNTED_TEST_OBJS:.o=.dep) @@ -19738,16 +18596,16 @@ $(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 +$(BINDIR)/$(CONFIG)/retry_throttle_test: $(PROTOBUF_DEP) $(RETRY_THROTTLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.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 + $(Q) $(LDXX) $(LDFLAGS) $(RETRY_THROTTLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.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 +$(OBJDIR)/$(CONFIG)/test/core/client_channel/retry_throttle_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_retry_throttle_test: $(RETRY_THROTTLE_TEST_OBJS:.o=.dep) @@ -19781,16 +18639,16 @@ $(BINDIR)/$(CONFIG)/secure_auth_context_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/secure_auth_context_test: $(PROTOBUF_DEP) $(SECURE_AUTH_CONTEXT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/secure_auth_context_test: $(PROTOBUF_DEP) $(SECURE_AUTH_CONTEXT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(SECURE_AUTH_CONTEXT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/secure_auth_context_test + $(Q) $(LDXX) $(LDFLAGS) $(SECURE_AUTH_CONTEXT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/secure_auth_context_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/common/secure_auth_context_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/common/secure_auth_context_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_secure_auth_context_test: $(SECURE_AUTH_CONTEXT_TEST_OBJS:.o=.dep) @@ -19824,16 +18682,16 @@ $(BINDIR)/$(CONFIG)/secure_sync_unary_ping_pong_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/secure_sync_unary_ping_pong_test: $(PROTOBUF_DEP) $(SECURE_SYNC_UNARY_PING_PONG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/secure_sync_unary_ping_pong_test: $(PROTOBUF_DEP) $(SECURE_SYNC_UNARY_PING_PONG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(SECURE_SYNC_UNARY_PING_PONG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/secure_sync_unary_ping_pong_test + $(Q) $(LDXX) $(LDFLAGS) $(SECURE_SYNC_UNARY_PING_PONG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/secure_sync_unary_ping_pong_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/qps/secure_sync_unary_ping_pong_test.o: $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/qps/secure_sync_unary_ping_pong_test.o: $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_secure_sync_unary_ping_pong_test: $(SECURE_SYNC_UNARY_PING_PONG_TEST_OBJS:.o=.dep) @@ -19867,16 +18725,16 @@ $(BINDIR)/$(CONFIG)/server_builder_plugin_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/server_builder_plugin_test: $(PROTOBUF_DEP) $(SERVER_BUILDER_PLUGIN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/server_builder_plugin_test: $(PROTOBUF_DEP) $(SERVER_BUILDER_PLUGIN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(SERVER_BUILDER_PLUGIN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/server_builder_plugin_test + $(Q) $(LDXX) $(LDFLAGS) $(SERVER_BUILDER_PLUGIN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/server_builder_plugin_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/server_builder_plugin_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/server_builder_plugin_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_server_builder_plugin_test: $(SERVER_BUILDER_PLUGIN_TEST_OBJS:.o=.dep) @@ -19912,20 +18770,20 @@ $(BINDIR)/$(CONFIG)/server_builder_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/server_builder_test: $(PROTOBUF_DEP) $(SERVER_BUILDER_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 +$(BINDIR)/$(CONFIG)/server_builder_test: $(PROTOBUF_DEP) $(SERVER_BUILDER_TEST_OBJS) $(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.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(SERVER_BUILDER_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_test + $(Q) $(LDXX) $(LDFLAGS) $(SERVER_BUILDER_TEST_OBJS) $(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.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/server_builder_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_messages.o: $(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.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)/src/proto/grpc/testing/echo.o: $(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.a -$(OBJDIR)/$(CONFIG)/test/cpp/server/server_builder_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 +$(OBJDIR)/$(CONFIG)/test/cpp/server/server_builder_test.o: $(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.a deps_server_builder_test: $(SERVER_BUILDER_TEST_OBJS:.o=.dep) @@ -19962,20 +18820,20 @@ $(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 +$(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)/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 + $(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)/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_messages.o: $(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.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)/src/proto/grpc/testing/echo.o: $(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.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 +$(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)/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) @@ -20010,16 +18868,16 @@ $(BINDIR)/$(CONFIG)/server_context_test_spouse_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/server_context_test_spouse_test: $(PROTOBUF_DEP) $(SERVER_CONTEXT_TEST_SPOUSE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/server_context_test_spouse_test: $(PROTOBUF_DEP) $(SERVER_CONTEXT_TEST_SPOUSE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(SERVER_CONTEXT_TEST_SPOUSE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/server_context_test_spouse_test + $(Q) $(LDXX) $(LDFLAGS) $(SERVER_CONTEXT_TEST_SPOUSE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/server_context_test_spouse_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/test/server_context_test_spouse_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/test/server_context_test_spouse_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_server_context_test_spouse_test: $(SERVER_CONTEXT_TEST_SPOUSE_TEST_OBJS:.o=.dep) @@ -20053,16 +18911,16 @@ $(BINDIR)/$(CONFIG)/server_crash_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/server_crash_test: $(PROTOBUF_DEP) $(SERVER_CRASH_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/server_crash_test: $(PROTOBUF_DEP) $(SERVER_CRASH_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(SERVER_CRASH_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/server_crash_test + $(Q) $(LDXX) $(LDFLAGS) $(SERVER_CRASH_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/server_crash_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/server_crash_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/server_crash_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_server_crash_test: $(SERVER_CRASH_TEST_OBJS:.o=.dep) @@ -20096,16 +18954,16 @@ $(BINDIR)/$(CONFIG)/server_crash_test_client: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/server_crash_test_client: $(PROTOBUF_DEP) $(SERVER_CRASH_TEST_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/server_crash_test_client: $(PROTOBUF_DEP) $(SERVER_CRASH_TEST_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(SERVER_CRASH_TEST_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/server_crash_test_client + $(Q) $(LDXX) $(LDFLAGS) $(SERVER_CRASH_TEST_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/server_crash_test_client endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/server_crash_test_client.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/server_crash_test_client.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_server_crash_test_client: $(SERVER_CRASH_TEST_CLIENT_OBJS:.o=.dep) @@ -20139,16 +18997,16 @@ $(BINDIR)/$(CONFIG)/server_early_return_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/server_early_return_test: $(PROTOBUF_DEP) $(SERVER_EARLY_RETURN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/server_early_return_test: $(PROTOBUF_DEP) $(SERVER_EARLY_RETURN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(SERVER_EARLY_RETURN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/server_early_return_test + $(Q) $(LDXX) $(LDFLAGS) $(SERVER_EARLY_RETURN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/server_early_return_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/server_early_return_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/server_early_return_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_server_early_return_test: $(SERVER_EARLY_RETURN_TEST_OBJS:.o=.dep) @@ -20183,18 +19041,18 @@ $(BINDIR)/$(CONFIG)/server_interceptors_end2end_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/server_interceptors_end2end_test: $(PROTOBUF_DEP) $(SERVER_INTERCEPTORS_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/server_interceptors_end2end_test: $(PROTOBUF_DEP) $(SERVER_INTERCEPTORS_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(SERVER_INTERCEPTORS_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/server_interceptors_end2end_test + $(Q) $(LDXX) $(LDFLAGS) $(SERVER_INTERCEPTORS_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/server_interceptors_end2end_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/interceptors_util.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/interceptors_util.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/server_interceptors_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/server_interceptors_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_server_interceptors_end2end_test: $(SERVER_INTERCEPTORS_END2END_TEST_OBJS:.o=.dep) @@ -20230,20 +19088,20 @@ $(BINDIR)/$(CONFIG)/server_request_call_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/server_request_call_test: $(PROTOBUF_DEP) $(SERVER_REQUEST_CALL_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 +$(BINDIR)/$(CONFIG)/server_request_call_test: $(PROTOBUF_DEP) $(SERVER_REQUEST_CALL_TEST_OBJS) $(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.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(SERVER_REQUEST_CALL_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_request_call_test + $(Q) $(LDXX) $(LDFLAGS) $(SERVER_REQUEST_CALL_TEST_OBJS) $(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.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/server_request_call_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_messages.o: $(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.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)/src/proto/grpc/testing/echo.o: $(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.a -$(OBJDIR)/$(CONFIG)/test/cpp/server/server_request_call_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 +$(OBJDIR)/$(CONFIG)/test/cpp/server/server_request_call_test.o: $(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.a deps_server_request_call_test: $(SERVER_REQUEST_CALL_TEST_OBJS:.o=.dep) @@ -20255,6 +19113,92 @@ endif $(OBJDIR)/$(CONFIG)/test/cpp/server/server_request_call_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 +SERVICE_CONFIG_END2END_TEST_SRC = \ + test/cpp/end2end/service_config_end2end_test.cc \ + +SERVICE_CONFIG_END2END_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(SERVICE_CONFIG_END2END_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/service_config_end2end_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)/service_config_end2end_test: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/service_config_end2end_test: $(PROTOBUF_DEP) $(SERVICE_CONFIG_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) $(SERVICE_CONFIG_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/service_config_end2end_test + +endif + +endif + +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/service_config_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_service_config_end2end_test: $(SERVICE_CONFIG_END2END_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(SERVICE_CONFIG_END2END_TEST_OBJS:.o=.dep) +endif +endif + + +SERVICE_CONFIG_TEST_SRC = \ + test/core/client_channel/service_config_test.cc \ + +SERVICE_CONFIG_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(SERVICE_CONFIG_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/service_config_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)/service_config_test: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/service_config_test: $(PROTOBUF_DEP) $(SERVICE_CONFIG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) $(SERVICE_CONFIG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/service_config_test + +endif + +endif + +$(OBJDIR)/$(CONFIG)/test/core/client_channel/service_config_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_service_config_test: $(SERVICE_CONFIG_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(SERVICE_CONFIG_TEST_OBJS:.o=.dep) +endif +endif + + SHUTDOWN_TEST_SRC = \ test/cpp/end2end/shutdown_test.cc \ @@ -20278,16 +19222,16 @@ $(BINDIR)/$(CONFIG)/shutdown_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/shutdown_test: $(PROTOBUF_DEP) $(SHUTDOWN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/shutdown_test: $(PROTOBUF_DEP) $(SHUTDOWN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(SHUTDOWN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/shutdown_test + $(Q) $(LDXX) $(LDFLAGS) $(SHUTDOWN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/shutdown_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/shutdown_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/shutdown_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_shutdown_test: $(SHUTDOWN_TEST_OBJS:.o=.dep) @@ -20321,16 +19265,16 @@ $(BINDIR)/$(CONFIG)/slice_hash_table_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/slice_hash_table_test: $(PROTOBUF_DEP) $(SLICE_HASH_TABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/slice_hash_table_test: $(PROTOBUF_DEP) $(SLICE_HASH_TABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(SLICE_HASH_TABLE_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)/slice_hash_table_test + $(Q) $(LDXX) $(LDFLAGS) $(SLICE_HASH_TABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/slice_hash_table_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/slice/slice_hash_table_test.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/slice/slice_hash_table_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_slice_hash_table_test: $(SLICE_HASH_TABLE_TEST_OBJS:.o=.dep) @@ -20364,16 +19308,16 @@ $(BINDIR)/$(CONFIG)/slice_weak_hash_table_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/slice_weak_hash_table_test: $(PROTOBUF_DEP) $(SLICE_WEAK_HASH_TABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/slice_weak_hash_table_test: $(PROTOBUF_DEP) $(SLICE_WEAK_HASH_TABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(SLICE_WEAK_HASH_TABLE_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)/slice_weak_hash_table_test + $(Q) $(LDXX) $(LDFLAGS) $(SLICE_WEAK_HASH_TABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/slice_weak_hash_table_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/slice/slice_weak_hash_table_test.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/slice/slice_weak_hash_table_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_slice_weak_hash_table_test: $(SLICE_WEAK_HASH_TABLE_TEST_OBJS:.o=.dep) @@ -20407,16 +19351,16 @@ $(BINDIR)/$(CONFIG)/stats_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/stats_test: $(PROTOBUF_DEP) $(STATS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/stats_test: $(PROTOBUF_DEP) $(STATS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(STATS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(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)/stats_test + $(Q) $(LDXX) $(LDFLAGS) $(STATS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/stats_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/debug/stats_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/debug/stats_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_stats_test: $(STATS_TEST_OBJS:.o=.dep) @@ -20536,16 +19480,16 @@ $(BINDIR)/$(CONFIG)/streaming_throughput_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/streaming_throughput_test: $(PROTOBUF_DEP) $(STREAMING_THROUGHPUT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/streaming_throughput_test: $(PROTOBUF_DEP) $(STREAMING_THROUGHPUT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(STREAMING_THROUGHPUT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/streaming_throughput_test + $(Q) $(LDXX) $(LDFLAGS) $(STREAMING_THROUGHPUT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/streaming_throughput_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/streaming_throughput_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/streaming_throughput_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_streaming_throughput_test: $(STREAMING_THROUGHPUT_TEST_OBJS:.o=.dep) @@ -20586,30 +19530,30 @@ $(BINDIR)/$(CONFIG)/stress_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/stress_test: $(PROTOBUF_DEP) $(STRESS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/stress_test: $(PROTOBUF_DEP) $(STRESS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(STRESS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/stress_test + $(Q) $(LDXX) $(LDFLAGS) $(STRESS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/stress_test endif endif -$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/empty.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/empty.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a -$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/messages.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/messages.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a -$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/metrics.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/metrics.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a -$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a -$(OBJDIR)/$(CONFIG)/test/cpp/interop/interop_client.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/interop/interop_client.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a -$(OBJDIR)/$(CONFIG)/test/cpp/interop/stress_interop_client.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/interop/stress_interop_client.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a -$(OBJDIR)/$(CONFIG)/test/cpp/interop/stress_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/interop/stress_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a -$(OBJDIR)/$(CONFIG)/test/cpp/util/metrics_server.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/util/metrics_server.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_stress_test: $(STRESS_TEST_OBJS:.o=.dep) @@ -20690,16 +19634,16 @@ $(BINDIR)/$(CONFIG)/thread_stress_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/thread_stress_test: $(PROTOBUF_DEP) $(THREAD_STRESS_TEST_OBJS) $(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)/thread_stress_test: $(PROTOBUF_DEP) $(THREAD_STRESS_TEST_OBJS) $(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.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(THREAD_STRESS_TEST_OBJS) $(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)/thread_stress_test + $(Q) $(LDXX) $(LDFLAGS) $(THREAD_STRESS_TEST_OBJS) $(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.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/thread_stress_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/thread_stress_test.o: $(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/end2end/thread_stress_test.o: $(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.a deps_thread_stress_test: $(THREAD_STRESS_TEST_OBJS:.o=.dep) @@ -20710,6 +19654,49 @@ endif endif +TIME_CHANGE_TEST_SRC = \ + test/cpp/end2end/time_change_test.cc \ + +TIME_CHANGE_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(TIME_CHANGE_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/time_change_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)/time_change_test: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/time_change_test: $(PROTOBUF_DEP) $(TIME_CHANGE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) $(TIME_CHANGE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/time_change_test + +endif + +endif + +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/time_change_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_time_change_test: $(TIME_CHANGE_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(TIME_CHANGE_TEST_OBJS:.o=.dep) +endif +endif + + TRANSPORT_PID_CONTROLLER_TEST_SRC = \ test/core/transport/pid_controller_test.cc \ @@ -20733,16 +19720,16 @@ $(BINDIR)/$(CONFIG)/transport_pid_controller_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/transport_pid_controller_test: $(PROTOBUF_DEP) $(TRANSPORT_PID_CONTROLLER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/transport_pid_controller_test: $(PROTOBUF_DEP) $(TRANSPORT_PID_CONTROLLER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(TRANSPORT_PID_CONTROLLER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(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)/transport_pid_controller_test + $(Q) $(LDXX) $(LDFLAGS) $(TRANSPORT_PID_CONTROLLER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/transport_pid_controller_test endif endif -$(OBJDIR)/$(CONFIG)/test/core/transport/pid_controller_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/transport/pid_controller_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_transport_pid_controller_test: $(TRANSPORT_PID_CONTROLLER_TEST_OBJS:.o=.dep) @@ -20819,16 +19806,16 @@ $(BINDIR)/$(CONFIG)/writes_per_rpc_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/writes_per_rpc_test: $(PROTOBUF_DEP) $(WRITES_PER_RPC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/writes_per_rpc_test: $(PROTOBUF_DEP) $(WRITES_PER_RPC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(WRITES_PER_RPC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/writes_per_rpc_test + $(Q) $(LDXX) $(LDFLAGS) $(WRITES_PER_RPC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/writes_per_rpc_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/performance/writes_per_rpc_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/performance/writes_per_rpc_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_writes_per_rpc_test: $(WRITES_PER_RPC_TEST_OBJS:.o=.dep) @@ -20839,6 +19826,53 @@ endif endif +XDS_END2END_TEST_SRC = \ + $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.pb.cc $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.grpc.pb.cc \ + test/cpp/end2end/xds_end2end_test.cc \ + +XDS_END2END_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(XDS_END2END_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/xds_end2end_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)/xds_end2end_test: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/xds_end2end_test: $(PROTOBUF_DEP) $(XDS_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) $(XDS_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/xds_end2end_test + +endif + +endif + +$(OBJDIR)/$(CONFIG)/src/proto/grpc/lb/v1/load_balancer.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/xds_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_xds_end2end_test: $(XDS_END2END_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(XDS_END2END_TEST_OBJS:.o=.dep) +endif +endif +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/xds_end2end_test.o: $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.pb.cc $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.grpc.pb.cc + + PUBLIC_HEADERS_MUST_BE_C89_SRC = \ test/core/surface/public_headers_must_be_c89.c \ @@ -20971,2008 +20005,10 @@ endif endif -BORINGSSL_CRYPTO_TEST_DATA_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_CRYPTO_TEST_DATA_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_CRYPTO_TEST_DATA_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_CRYPTO_TEST_DATA_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_CRYPTO_TEST_DATA_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_CRYPTO_TEST_DATA_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -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)/boringssl_crypto_test_data: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_crypto_test_data: $(PROTOBUF_DEP) $(BORINGSSL_CRYPTO_TEST_DATA_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_crypto_test_data_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_CRYPTO_TEST_DATA_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_crypto_test_data_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_crypto_test_data - -endif - -$(BORINGSSL_CRYPTO_TEST_DATA_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_CRYPTO_TEST_DATA_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_CRYPTO_TEST_DATA_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_crypto_test_data_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_crypto_test_data: $(BORINGSSL_CRYPTO_TEST_DATA_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_CRYPTO_TEST_DATA_OBJS:.o=.dep) -endif - - -BORINGSSL_ASN1_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_ASN1_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_ASN1_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_ASN1_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_ASN1_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_ASN1_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -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)/boringssl_asn1_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_asn1_test: $(PROTOBUF_DEP) $(BORINGSSL_ASN1_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_asn1_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_ASN1_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_asn1_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_asn1_test - -endif - -$(BORINGSSL_ASN1_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_ASN1_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_ASN1_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_asn1_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_asn1_test: $(BORINGSSL_ASN1_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_ASN1_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_BASE64_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_BASE64_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_BASE64_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_BASE64_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_BASE64_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_BASE64_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -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)/boringssl_base64_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_base64_test: $(PROTOBUF_DEP) $(BORINGSSL_BASE64_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_base64_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_BASE64_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_base64_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_base64_test - -endif - -$(BORINGSSL_BASE64_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_BASE64_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_BASE64_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_base64_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_base64_test: $(BORINGSSL_BASE64_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_BASE64_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_BIO_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_BIO_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_BIO_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_BIO_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_BIO_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_BIO_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -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)/boringssl_bio_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_bio_test: $(PROTOBUF_DEP) $(BORINGSSL_BIO_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_bio_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_BIO_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_bio_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_bio_test - -endif - -$(BORINGSSL_BIO_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_BIO_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_BIO_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_bio_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_bio_test: $(BORINGSSL_BIO_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_BIO_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_BUF_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_BUF_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_BUF_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_BUF_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_BUF_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_BUF_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -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)/boringssl_buf_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_buf_test: $(PROTOBUF_DEP) $(BORINGSSL_BUF_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_buf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_BUF_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_buf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_buf_test - -endif - -$(BORINGSSL_BUF_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_BUF_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_BUF_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_buf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_buf_test: $(BORINGSSL_BUF_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_BUF_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_BYTESTRING_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_BYTESTRING_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_BYTESTRING_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_BYTESTRING_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_BYTESTRING_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_BYTESTRING_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -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)/boringssl_bytestring_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_bytestring_test: $(PROTOBUF_DEP) $(BORINGSSL_BYTESTRING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_bytestring_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_BYTESTRING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_bytestring_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_bytestring_test - -endif - -$(BORINGSSL_BYTESTRING_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_BYTESTRING_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_BYTESTRING_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_bytestring_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_bytestring_test: $(BORINGSSL_BYTESTRING_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_BYTESTRING_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_CHACHA_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_CHACHA_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_CHACHA_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_CHACHA_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_CHACHA_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_CHACHA_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -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)/boringssl_chacha_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_chacha_test: $(PROTOBUF_DEP) $(BORINGSSL_CHACHA_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_chacha_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_CHACHA_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_chacha_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_chacha_test - -endif - -$(BORINGSSL_CHACHA_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_CHACHA_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_CHACHA_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_chacha_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_chacha_test: $(BORINGSSL_CHACHA_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_CHACHA_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_AEAD_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_AEAD_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_AEAD_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_AEAD_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_AEAD_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_AEAD_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -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)/boringssl_aead_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_aead_test: $(PROTOBUF_DEP) $(BORINGSSL_AEAD_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_aead_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_AEAD_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_aead_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_aead_test - -endif - -$(BORINGSSL_AEAD_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_AEAD_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_AEAD_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_aead_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_aead_test: $(BORINGSSL_AEAD_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_AEAD_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_CIPHER_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_CIPHER_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_CIPHER_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_CIPHER_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_CIPHER_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_CIPHER_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -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)/boringssl_cipher_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_cipher_test: $(PROTOBUF_DEP) $(BORINGSSL_CIPHER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_cipher_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_CIPHER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_cipher_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_cipher_test - -endif - -$(BORINGSSL_CIPHER_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_CIPHER_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_CIPHER_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_cipher_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_cipher_test: $(BORINGSSL_CIPHER_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_CIPHER_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_CMAC_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_CMAC_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_CMAC_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_CMAC_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_CMAC_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_CMAC_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -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)/boringssl_cmac_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_cmac_test: $(PROTOBUF_DEP) $(BORINGSSL_CMAC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_cmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_CMAC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_cmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_cmac_test - -endif - -$(BORINGSSL_CMAC_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_CMAC_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_CMAC_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_cmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_cmac_test: $(BORINGSSL_CMAC_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_CMAC_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_COMPILER_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_COMPILER_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_COMPILER_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_COMPILER_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_COMPILER_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_COMPILER_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -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)/boringssl_compiler_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_compiler_test: $(PROTOBUF_DEP) $(BORINGSSL_COMPILER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_compiler_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_COMPILER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_compiler_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_compiler_test - -endif - -$(BORINGSSL_COMPILER_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_COMPILER_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_COMPILER_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_compiler_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_compiler_test: $(BORINGSSL_COMPILER_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_COMPILER_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_CONSTANT_TIME_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_CONSTANT_TIME_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_CONSTANT_TIME_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_CONSTANT_TIME_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_CONSTANT_TIME_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_CONSTANT_TIME_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -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)/boringssl_constant_time_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_constant_time_test: $(PROTOBUF_DEP) $(BORINGSSL_CONSTANT_TIME_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_constant_time_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_CONSTANT_TIME_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_constant_time_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_constant_time_test - -endif - -$(BORINGSSL_CONSTANT_TIME_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_CONSTANT_TIME_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_CONSTANT_TIME_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_constant_time_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_constant_time_test: $(BORINGSSL_CONSTANT_TIME_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_CONSTANT_TIME_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_ED25519_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_ED25519_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_ED25519_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_ED25519_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_ED25519_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_ED25519_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -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)/boringssl_ed25519_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_ed25519_test: $(PROTOBUF_DEP) $(BORINGSSL_ED25519_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_ed25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_ED25519_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_ed25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_ed25519_test - -endif - -$(BORINGSSL_ED25519_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_ED25519_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_ED25519_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_ed25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_ed25519_test: $(BORINGSSL_ED25519_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_ED25519_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_SPAKE25519_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_SPAKE25519_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_SPAKE25519_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_SPAKE25519_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_SPAKE25519_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_SPAKE25519_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -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)/boringssl_spake25519_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_spake25519_test: $(PROTOBUF_DEP) $(BORINGSSL_SPAKE25519_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_spake25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_SPAKE25519_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_spake25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_spake25519_test - -endif - -$(BORINGSSL_SPAKE25519_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_SPAKE25519_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_SPAKE25519_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_spake25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_spake25519_test: $(BORINGSSL_SPAKE25519_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_SPAKE25519_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_X25519_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_X25519_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_X25519_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_X25519_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_X25519_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_X25519_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -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)/boringssl_x25519_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_x25519_test: $(PROTOBUF_DEP) $(BORINGSSL_X25519_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_x25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_X25519_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_x25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_x25519_test - -endif - -$(BORINGSSL_X25519_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_X25519_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_X25519_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_x25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_x25519_test: $(BORINGSSL_X25519_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_X25519_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_DH_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_DH_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_DH_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_DH_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_DH_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_DH_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -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)/boringssl_dh_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_dh_test: $(PROTOBUF_DEP) $(BORINGSSL_DH_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_dh_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_DH_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_dh_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_dh_test - -endif - -$(BORINGSSL_DH_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_DH_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_DH_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_dh_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_dh_test: $(BORINGSSL_DH_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_DH_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_DIGEST_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_DIGEST_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_DIGEST_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_DIGEST_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_DIGEST_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_DIGEST_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -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)/boringssl_digest_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_digest_test: $(PROTOBUF_DEP) $(BORINGSSL_DIGEST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_digest_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_DIGEST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_digest_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_digest_test - -endif - -$(BORINGSSL_DIGEST_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_DIGEST_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_DIGEST_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_digest_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_digest_test: $(BORINGSSL_DIGEST_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_DIGEST_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_DSA_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_DSA_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_DSA_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_DSA_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_DSA_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_DSA_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -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)/boringssl_dsa_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_dsa_test: $(PROTOBUF_DEP) $(BORINGSSL_DSA_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_dsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_DSA_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_dsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_dsa_test - -endif - -$(BORINGSSL_DSA_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_DSA_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_DSA_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_dsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_dsa_test: $(BORINGSSL_DSA_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_DSA_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_ECDH_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_ECDH_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_ECDH_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_ECDH_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_ECDH_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_ECDH_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -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)/boringssl_ecdh_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_ecdh_test: $(PROTOBUF_DEP) $(BORINGSSL_ECDH_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_ecdh_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_ECDH_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_ecdh_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_ecdh_test - -endif - -$(BORINGSSL_ECDH_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_ECDH_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_ECDH_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_ecdh_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_ecdh_test: $(BORINGSSL_ECDH_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_ECDH_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_ERR_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_ERR_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_ERR_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_ERR_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_ERR_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_ERR_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -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)/boringssl_err_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_err_test: $(PROTOBUF_DEP) $(BORINGSSL_ERR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_err_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_ERR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_err_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_err_test - -endif - -$(BORINGSSL_ERR_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_ERR_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_ERR_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_err_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_err_test: $(BORINGSSL_ERR_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_ERR_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_EVP_EXTRA_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_EVP_EXTRA_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_EVP_EXTRA_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_EVP_EXTRA_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_EVP_EXTRA_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_EVP_EXTRA_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -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)/boringssl_evp_extra_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_evp_extra_test: $(PROTOBUF_DEP) $(BORINGSSL_EVP_EXTRA_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_evp_extra_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_EVP_EXTRA_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_evp_extra_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_evp_extra_test - -endif - -$(BORINGSSL_EVP_EXTRA_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_EVP_EXTRA_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_EVP_EXTRA_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_evp_extra_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_evp_extra_test: $(BORINGSSL_EVP_EXTRA_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_EVP_EXTRA_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_EVP_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_EVP_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_EVP_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_EVP_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_EVP_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_EVP_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -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)/boringssl_evp_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_evp_test: $(PROTOBUF_DEP) $(BORINGSSL_EVP_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_evp_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_EVP_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_evp_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_evp_test - -endif - -$(BORINGSSL_EVP_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_EVP_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_EVP_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_evp_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_evp_test: $(BORINGSSL_EVP_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_EVP_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_PBKDF_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_PBKDF_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_PBKDF_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_PBKDF_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_PBKDF_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_PBKDF_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -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)/boringssl_pbkdf_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_pbkdf_test: $(PROTOBUF_DEP) $(BORINGSSL_PBKDF_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_pbkdf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_PBKDF_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_pbkdf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_pbkdf_test - -endif - -$(BORINGSSL_PBKDF_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_PBKDF_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_PBKDF_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_pbkdf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_pbkdf_test: $(BORINGSSL_PBKDF_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_PBKDF_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_SCRYPT_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_SCRYPT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_SCRYPT_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_SCRYPT_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_SCRYPT_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_SCRYPT_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -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)/boringssl_scrypt_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_scrypt_test: $(PROTOBUF_DEP) $(BORINGSSL_SCRYPT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_scrypt_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_SCRYPT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_scrypt_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_scrypt_test - -endif - -$(BORINGSSL_SCRYPT_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_SCRYPT_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_SCRYPT_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_scrypt_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_scrypt_test: $(BORINGSSL_SCRYPT_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_SCRYPT_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_AES_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_AES_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_AES_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_AES_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_AES_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_AES_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -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)/boringssl_aes_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_aes_test: $(PROTOBUF_DEP) $(BORINGSSL_AES_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_aes_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_AES_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_aes_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_aes_test - -endif - -$(BORINGSSL_AES_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_AES_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_AES_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_aes_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_aes_test: $(BORINGSSL_AES_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_AES_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_BN_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_BN_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_BN_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_BN_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_BN_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_BN_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -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)/boringssl_bn_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_bn_test: $(PROTOBUF_DEP) $(BORINGSSL_BN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_bn_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_BN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_bn_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_bn_test - -endif - -$(BORINGSSL_BN_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_BN_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_BN_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_bn_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_bn_test: $(BORINGSSL_BN_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_BN_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_EC_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_EC_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_EC_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_EC_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_EC_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_EC_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -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)/boringssl_ec_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_ec_test: $(PROTOBUF_DEP) $(BORINGSSL_EC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_ec_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_EC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_ec_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_ec_test - -endif - -$(BORINGSSL_EC_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_EC_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_EC_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_ec_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_ec_test: $(BORINGSSL_EC_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_EC_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_P256-X86_64_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_P256-X86_64_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_P256-X86_64_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_P256-X86_64_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_P256-X86_64_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_P256-X86_64_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -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)/boringssl_p256-x86_64_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_p256-x86_64_test: $(PROTOBUF_DEP) $(BORINGSSL_P256-X86_64_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_p256-x86_64_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_P256-X86_64_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_p256-x86_64_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_p256-x86_64_test - -endif - -$(BORINGSSL_P256-X86_64_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_P256-X86_64_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_P256-X86_64_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_p256-x86_64_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_p256-x86_64_test: $(BORINGSSL_P256-X86_64_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_P256-X86_64_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_ECDSA_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_ECDSA_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_ECDSA_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_ECDSA_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_ECDSA_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_ECDSA_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -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)/boringssl_ecdsa_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_ecdsa_test: $(PROTOBUF_DEP) $(BORINGSSL_ECDSA_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_ECDSA_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_ecdsa_test - -endif - -$(BORINGSSL_ECDSA_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_ECDSA_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_ECDSA_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_ecdsa_test: $(BORINGSSL_ECDSA_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_ECDSA_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_GCM_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_GCM_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_GCM_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_GCM_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_GCM_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_GCM_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -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)/boringssl_gcm_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_gcm_test: $(PROTOBUF_DEP) $(BORINGSSL_GCM_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_gcm_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_GCM_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_gcm_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_gcm_test - -endif - -$(BORINGSSL_GCM_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_GCM_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_GCM_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_gcm_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_gcm_test: $(BORINGSSL_GCM_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_GCM_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_CTRDRBG_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_CTRDRBG_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_CTRDRBG_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_CTRDRBG_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_CTRDRBG_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_CTRDRBG_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -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)/boringssl_ctrdrbg_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_ctrdrbg_test: $(PROTOBUF_DEP) $(BORINGSSL_CTRDRBG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_ctrdrbg_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_CTRDRBG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_ctrdrbg_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_ctrdrbg_test - -endif - -$(BORINGSSL_CTRDRBG_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_CTRDRBG_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_CTRDRBG_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_ctrdrbg_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_ctrdrbg_test: $(BORINGSSL_CTRDRBG_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_CTRDRBG_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_HKDF_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_HKDF_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_HKDF_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_HKDF_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_HKDF_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_HKDF_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -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)/boringssl_hkdf_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_hkdf_test: $(PROTOBUF_DEP) $(BORINGSSL_HKDF_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_hkdf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_HKDF_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_hkdf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_hkdf_test - -endif - -$(BORINGSSL_HKDF_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_HKDF_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_HKDF_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_hkdf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_hkdf_test: $(BORINGSSL_HKDF_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_HKDF_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_HMAC_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_HMAC_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_HMAC_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_HMAC_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_HMAC_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_HMAC_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -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)/boringssl_hmac_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_hmac_test: $(PROTOBUF_DEP) $(BORINGSSL_HMAC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_hmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_HMAC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_hmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_hmac_test - -endif - -$(BORINGSSL_HMAC_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_HMAC_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_HMAC_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_hmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_hmac_test: $(BORINGSSL_HMAC_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_HMAC_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_LHASH_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_LHASH_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_LHASH_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_LHASH_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_LHASH_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_LHASH_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -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)/boringssl_lhash_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_lhash_test: $(PROTOBUF_DEP) $(BORINGSSL_LHASH_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_lhash_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_LHASH_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_lhash_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_lhash_test - -endif - -$(BORINGSSL_LHASH_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_LHASH_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_LHASH_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_lhash_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_lhash_test: $(BORINGSSL_LHASH_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_LHASH_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_OBJ_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_OBJ_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_OBJ_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_OBJ_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_OBJ_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_OBJ_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -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)/boringssl_obj_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_obj_test: $(PROTOBUF_DEP) $(BORINGSSL_OBJ_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_obj_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_OBJ_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_obj_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_obj_test - -endif - -$(BORINGSSL_OBJ_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_OBJ_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_OBJ_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_obj_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_obj_test: $(BORINGSSL_OBJ_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_OBJ_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_PKCS7_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_PKCS7_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_PKCS7_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_PKCS7_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_PKCS7_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_PKCS7_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -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)/boringssl_pkcs7_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_pkcs7_test: $(PROTOBUF_DEP) $(BORINGSSL_PKCS7_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_pkcs7_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_PKCS7_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_pkcs7_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_pkcs7_test - -endif - -$(BORINGSSL_PKCS7_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_PKCS7_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_PKCS7_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_pkcs7_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_pkcs7_test: $(BORINGSSL_PKCS7_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_PKCS7_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_PKCS12_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_PKCS12_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_PKCS12_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_PKCS12_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_PKCS12_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_PKCS12_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -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)/boringssl_pkcs12_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_pkcs12_test: $(PROTOBUF_DEP) $(BORINGSSL_PKCS12_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_pkcs12_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_PKCS12_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_pkcs12_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_pkcs12_test - -endif - -$(BORINGSSL_PKCS12_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_PKCS12_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_PKCS12_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_pkcs12_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_pkcs12_test: $(BORINGSSL_PKCS12_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_PKCS12_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_PKCS8_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_PKCS8_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_PKCS8_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_PKCS8_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_PKCS8_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_PKCS8_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -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)/boringssl_pkcs8_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_pkcs8_test: $(PROTOBUF_DEP) $(BORINGSSL_PKCS8_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_pkcs8_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_PKCS8_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_pkcs8_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_pkcs8_test - -endif - -$(BORINGSSL_PKCS8_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_PKCS8_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_PKCS8_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_pkcs8_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_pkcs8_test: $(BORINGSSL_PKCS8_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_PKCS8_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_POLY1305_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_POLY1305_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_POLY1305_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_POLY1305_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_POLY1305_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_POLY1305_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -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)/boringssl_poly1305_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_poly1305_test: $(PROTOBUF_DEP) $(BORINGSSL_POLY1305_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_poly1305_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_POLY1305_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_poly1305_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_poly1305_test - -endif - -$(BORINGSSL_POLY1305_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_POLY1305_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_POLY1305_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_poly1305_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_poly1305_test: $(BORINGSSL_POLY1305_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_POLY1305_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_POOL_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_POOL_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_POOL_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_POOL_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_POOL_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_POOL_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -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)/boringssl_pool_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_pool_test: $(PROTOBUF_DEP) $(BORINGSSL_POOL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_pool_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_POOL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_pool_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_pool_test - -endif - -$(BORINGSSL_POOL_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_POOL_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_POOL_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_pool_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_pool_test: $(BORINGSSL_POOL_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_POOL_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_REFCOUNT_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_REFCOUNT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_REFCOUNT_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_REFCOUNT_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_REFCOUNT_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_REFCOUNT_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -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)/boringssl_refcount_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_refcount_test: $(PROTOBUF_DEP) $(BORINGSSL_REFCOUNT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_refcount_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_REFCOUNT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_refcount_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_refcount_test - -endif - -$(BORINGSSL_REFCOUNT_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_REFCOUNT_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_REFCOUNT_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_refcount_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_refcount_test: $(BORINGSSL_REFCOUNT_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_REFCOUNT_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_RSA_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_RSA_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_RSA_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_RSA_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_RSA_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_RSA_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -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)/boringssl_rsa_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_rsa_test: $(PROTOBUF_DEP) $(BORINGSSL_RSA_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_rsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_RSA_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_rsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_rsa_test - -endif - -$(BORINGSSL_RSA_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_RSA_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_RSA_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_rsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_rsa_test: $(BORINGSSL_RSA_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_RSA_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_SELF_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_SELF_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_SELF_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_SELF_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_SELF_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_SELF_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -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)/boringssl_self_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_self_test: $(PROTOBUF_DEP) $(BORINGSSL_SELF_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_self_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_SELF_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_self_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_self_test - -endif - -$(BORINGSSL_SELF_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_SELF_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_SELF_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_self_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_self_test: $(BORINGSSL_SELF_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_SELF_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_FILE_TEST_GTEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_FILE_TEST_GTEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_FILE_TEST_GTEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_FILE_TEST_GTEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_FILE_TEST_GTEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_FILE_TEST_GTEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -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)/boringssl_file_test_gtest: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_file_test_gtest: $(PROTOBUF_DEP) $(BORINGSSL_FILE_TEST_GTEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_file_test_gtest_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_FILE_TEST_GTEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_file_test_gtest_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_file_test_gtest - -endif - -$(BORINGSSL_FILE_TEST_GTEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_FILE_TEST_GTEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_FILE_TEST_GTEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_file_test_gtest_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_file_test_gtest: $(BORINGSSL_FILE_TEST_GTEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_FILE_TEST_GTEST_OBJS:.o=.dep) -endif - - -BORINGSSL_GTEST_MAIN_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_GTEST_MAIN_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_GTEST_MAIN_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_GTEST_MAIN_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_GTEST_MAIN_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_GTEST_MAIN_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -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)/boringssl_gtest_main: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_gtest_main: $(PROTOBUF_DEP) $(BORINGSSL_GTEST_MAIN_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_gtest_main_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_GTEST_MAIN_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_gtest_main_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_gtest_main - -endif - -$(BORINGSSL_GTEST_MAIN_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_GTEST_MAIN_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_GTEST_MAIN_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_gtest_main_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_gtest_main: $(BORINGSSL_GTEST_MAIN_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_GTEST_MAIN_OBJS:.o=.dep) -endif - - -BORINGSSL_THREAD_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_THREAD_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_THREAD_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_THREAD_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_THREAD_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_THREAD_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -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)/boringssl_thread_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_thread_test: $(PROTOBUF_DEP) $(BORINGSSL_THREAD_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_thread_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_THREAD_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_thread_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_thread_test - -endif - -$(BORINGSSL_THREAD_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_THREAD_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_THREAD_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_thread_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_thread_test: $(BORINGSSL_THREAD_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_THREAD_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_X509_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_X509_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_X509_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_X509_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_X509_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_X509_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -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)/boringssl_x509_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_x509_test: $(PROTOBUF_DEP) $(BORINGSSL_X509_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_x509_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_X509_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_x509_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_x509_test - -endif - -$(BORINGSSL_X509_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_X509_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_X509_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_x509_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_x509_test: $(BORINGSSL_X509_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_X509_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_TAB_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_TAB_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_TAB_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_TAB_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_TAB_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_TAB_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -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)/boringssl_tab_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_tab_test: $(PROTOBUF_DEP) $(BORINGSSL_TAB_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_tab_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_TAB_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_tab_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_tab_test - -endif - -$(BORINGSSL_TAB_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_TAB_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_TAB_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_tab_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_tab_test: $(BORINGSSL_TAB_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_TAB_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_V3NAME_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_V3NAME_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_V3NAME_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_V3NAME_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_V3NAME_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_V3NAME_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -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)/boringssl_v3name_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_v3name_test: $(PROTOBUF_DEP) $(BORINGSSL_V3NAME_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_v3name_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_V3NAME_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_v3name_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_v3name_test - -endif - -$(BORINGSSL_V3NAME_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_V3NAME_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_V3NAME_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_v3name_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_v3name_test: $(BORINGSSL_V3NAME_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_V3NAME_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_SPAN_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_SPAN_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_SPAN_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_SPAN_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_SPAN_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_SPAN_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -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)/boringssl_span_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_span_test: $(PROTOBUF_DEP) $(BORINGSSL_SPAN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_span_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_SPAN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_span_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_span_test - -endif - -$(BORINGSSL_SPAN_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_SPAN_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_SPAN_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_span_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_span_test: $(BORINGSSL_SPAN_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_SPAN_TEST_OBJS:.o=.dep) -endif - - BORINGSSL_SSL_TEST_SRC = \ third_party/boringssl/crypto/test/gtest_main.cc \ + third_party/boringssl/ssl/span_test.cc \ + third_party/boringssl/ssl/ssl_test.cc \ BORINGSSL_SSL_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_SSL_TEST_SRC)))) @@ -22992,17 +20028,21 @@ $(BINDIR)/$(CONFIG)/boringssl_ssl_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/boringssl_ssl_test: $(PROTOBUF_DEP) $(BORINGSSL_SSL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_ssl_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a +$(BINDIR)/$(CONFIG)/boringssl_ssl_test: $(PROTOBUF_DEP) $(BORINGSSL_SSL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_SSL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_ssl_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_ssl_test + $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_SSL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_ssl_test endif $(BORINGSSL_SSL_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX $(BORINGSSL_SSL_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions $(BORINGSSL_SSL_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_ssl_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/ssl/span_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/ssl/ssl_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a deps_boringssl_ssl_test: $(BORINGSSL_SSL_TEST_OBJS:.o=.dep) @@ -23011,18 +20051,202 @@ ifneq ($(NO_DEPS),true) endif +BORINGSSL_CRYPTO_TEST_SRC = \ + src/boringssl/crypto_test_data.cc \ + third_party/boringssl/crypto/asn1/asn1_test.cc \ + third_party/boringssl/crypto/base64/base64_test.cc \ + third_party/boringssl/crypto/bio/bio_test.cc \ + third_party/boringssl/crypto/buf/buf_test.cc \ + third_party/boringssl/crypto/bytestring/bytestring_test.cc \ + third_party/boringssl/crypto/chacha/chacha_test.cc \ + third_party/boringssl/crypto/cipher_extra/aead_test.cc \ + third_party/boringssl/crypto/cipher_extra/cipher_test.cc \ + third_party/boringssl/crypto/cmac/cmac_test.cc \ + third_party/boringssl/crypto/compiler_test.cc \ + third_party/boringssl/crypto/constant_time_test.cc \ + third_party/boringssl/crypto/curve25519/ed25519_test.cc \ + third_party/boringssl/crypto/curve25519/spake25519_test.cc \ + third_party/boringssl/crypto/curve25519/x25519_test.cc \ + third_party/boringssl/crypto/dh/dh_test.cc \ + third_party/boringssl/crypto/digest_extra/digest_test.cc \ + third_party/boringssl/crypto/dsa/dsa_test.cc \ + third_party/boringssl/crypto/ecdh/ecdh_test.cc \ + third_party/boringssl/crypto/err/err_test.cc \ + third_party/boringssl/crypto/evp/evp_extra_test.cc \ + third_party/boringssl/crypto/evp/evp_test.cc \ + third_party/boringssl/crypto/evp/pbkdf_test.cc \ + third_party/boringssl/crypto/evp/scrypt_test.cc \ + third_party/boringssl/crypto/fipsmodule/aes/aes_test.cc \ + third_party/boringssl/crypto/fipsmodule/bn/bn_test.cc \ + third_party/boringssl/crypto/fipsmodule/ec/ec_test.cc \ + third_party/boringssl/crypto/fipsmodule/ec/p256-x86_64_test.cc \ + third_party/boringssl/crypto/fipsmodule/ecdsa/ecdsa_test.cc \ + third_party/boringssl/crypto/fipsmodule/modes/gcm_test.cc \ + third_party/boringssl/crypto/fipsmodule/rand/ctrdrbg_test.cc \ + third_party/boringssl/crypto/hkdf/hkdf_test.cc \ + third_party/boringssl/crypto/hmac_extra/hmac_test.cc \ + third_party/boringssl/crypto/lhash/lhash_test.cc \ + third_party/boringssl/crypto/obj/obj_test.cc \ + third_party/boringssl/crypto/pkcs7/pkcs7_test.cc \ + third_party/boringssl/crypto/pkcs8/pkcs12_test.cc \ + third_party/boringssl/crypto/pkcs8/pkcs8_test.cc \ + third_party/boringssl/crypto/poly1305/poly1305_test.cc \ + third_party/boringssl/crypto/pool/pool_test.cc \ + third_party/boringssl/crypto/refcount_test.cc \ + third_party/boringssl/crypto/rsa_extra/rsa_test.cc \ + third_party/boringssl/crypto/self_test.cc \ + third_party/boringssl/crypto/test/file_test_gtest.cc \ + third_party/boringssl/crypto/test/gtest_main.cc \ + third_party/boringssl/crypto/thread_test.cc \ + third_party/boringssl/crypto/x509/x509_test.cc \ + third_party/boringssl/crypto/x509v3/tab_test.cc \ + third_party/boringssl/crypto/x509v3/v3name_test.cc \ + +BORINGSSL_CRYPTO_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_CRYPTO_TEST_SRC)))) + +# boringssl needs an override to ensure that it does not include +# system openssl headers regardless of other configuration +# we do so here with a target specific variable assignment +$(BORINGSSL_CRYPTO_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) +$(BORINGSSL_CRYPTO_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) +$(BORINGSSL_CRYPTO_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE + + +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)/boringssl_crypto_test: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/boringssl_crypto_test: $(PROTOBUF_DEP) $(BORINGSSL_CRYPTO_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_CRYPTO_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_crypto_test + +endif + +$(BORINGSSL_CRYPTO_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX +$(BORINGSSL_CRYPTO_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions +$(BORINGSSL_CRYPTO_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) +$(OBJDIR)/$(CONFIG)/src/boringssl/crypto_test_data.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/asn1/asn1_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/base64/base64_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/bio/bio_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/buf/buf_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/bytestring/bytestring_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/chacha/chacha_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/cipher_extra/aead_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/cipher_extra/cipher_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/cmac/cmac_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/compiler_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/constant_time_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/curve25519/ed25519_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/curve25519/spake25519_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/curve25519/x25519_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/dh/dh_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/digest_extra/digest_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/dsa/dsa_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/ecdh/ecdh_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/err/err_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/evp/evp_extra_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/evp/evp_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/evp/pbkdf_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/evp/scrypt_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/fipsmodule/aes/aes_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/fipsmodule/bn/bn_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/fipsmodule/ec/ec_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/fipsmodule/ec/p256-x86_64_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/fipsmodule/ecdsa/ecdsa_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/fipsmodule/modes/gcm_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/fipsmodule/rand/ctrdrbg_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/hkdf/hkdf_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/hmac_extra/hmac_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/lhash/lhash_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/obj/obj_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/pkcs7/pkcs7_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/pkcs8/pkcs12_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/pkcs8/pkcs8_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/poly1305/poly1305_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/pool/pool_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/refcount_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/rsa_extra/rsa_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/self_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/file_test_gtest.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/thread_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/x509/x509_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/x509v3/tab_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/x509v3/v3name_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +deps_boringssl_crypto_test: $(BORINGSSL_CRYPTO_TEST_OBJS:.o=.dep) + +ifneq ($(NO_DEPS),true) +-include $(BORINGSSL_CRYPTO_TEST_OBJS:.o=.dep) +endif + + BADREQ_BAD_CLIENT_TEST_SRC = \ test/core/bad_client/tests/badreq.cc \ BADREQ_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BADREQ_BAD_CLIENT_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/badreq_bad_client_test: $(BADREQ_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/badreq_bad_client_test: $(BADREQ_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(BADREQ_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/badreq_bad_client_test + $(Q) $(LD) $(LDFLAGS) $(BADREQ_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/badreq_bad_client_test -$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/badreq.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/badreq.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_badreq_bad_client_test: $(BADREQ_BAD_CLIENT_TEST_OBJS:.o=.dep) @@ -23037,12 +20261,12 @@ CONNECTION_PREFIX_BAD_CLIENT_TEST_SRC = \ CONNECTION_PREFIX_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(CONNECTION_PREFIX_BAD_CLIENT_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test: $(CONNECTION_PREFIX_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test: $(CONNECTION_PREFIX_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(CONNECTION_PREFIX_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test + $(Q) $(LD) $(LDFLAGS) $(CONNECTION_PREFIX_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test -$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/connection_prefix.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/connection_prefix.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_connection_prefix_bad_client_test: $(CONNECTION_PREFIX_BAD_CLIENT_TEST_OBJS:.o=.dep) @@ -23057,12 +20281,12 @@ DUPLICATE_HEADER_BAD_CLIENT_TEST_SRC = \ DUPLICATE_HEADER_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(DUPLICATE_HEADER_BAD_CLIENT_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/duplicate_header_bad_client_test: $(DUPLICATE_HEADER_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/duplicate_header_bad_client_test: $(DUPLICATE_HEADER_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(DUPLICATE_HEADER_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/duplicate_header_bad_client_test + $(Q) $(LD) $(LDFLAGS) $(DUPLICATE_HEADER_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/duplicate_header_bad_client_test -$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/duplicate_header.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/duplicate_header.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_duplicate_header_bad_client_test: $(DUPLICATE_HEADER_BAD_CLIENT_TEST_OBJS:.o=.dep) @@ -23077,12 +20301,12 @@ HEAD_OF_LINE_BLOCKING_BAD_CLIENT_TEST_SRC = \ HEAD_OF_LINE_BLOCKING_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(HEAD_OF_LINE_BLOCKING_BAD_CLIENT_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/head_of_line_blocking_bad_client_test: $(HEAD_OF_LINE_BLOCKING_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/head_of_line_blocking_bad_client_test: $(HEAD_OF_LINE_BLOCKING_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(HEAD_OF_LINE_BLOCKING_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/head_of_line_blocking_bad_client_test + $(Q) $(LD) $(LDFLAGS) $(HEAD_OF_LINE_BLOCKING_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/head_of_line_blocking_bad_client_test -$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/head_of_line_blocking.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/head_of_line_blocking.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_head_of_line_blocking_bad_client_test: $(HEAD_OF_LINE_BLOCKING_BAD_CLIENT_TEST_OBJS:.o=.dep) @@ -23097,12 +20321,12 @@ HEADERS_BAD_CLIENT_TEST_SRC = \ HEADERS_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(HEADERS_BAD_CLIENT_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/headers_bad_client_test: $(HEADERS_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/headers_bad_client_test: $(HEADERS_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(HEADERS_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/headers_bad_client_test + $(Q) $(LD) $(LDFLAGS) $(HEADERS_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/headers_bad_client_test -$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/headers.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/headers.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_headers_bad_client_test: $(HEADERS_BAD_CLIENT_TEST_OBJS:.o=.dep) @@ -23117,12 +20341,12 @@ INITIAL_SETTINGS_FRAME_BAD_CLIENT_TEST_SRC = \ INITIAL_SETTINGS_FRAME_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(INITIAL_SETTINGS_FRAME_BAD_CLIENT_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/initial_settings_frame_bad_client_test: $(INITIAL_SETTINGS_FRAME_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/initial_settings_frame_bad_client_test: $(INITIAL_SETTINGS_FRAME_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(INITIAL_SETTINGS_FRAME_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/initial_settings_frame_bad_client_test + $(Q) $(LD) $(LDFLAGS) $(INITIAL_SETTINGS_FRAME_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/initial_settings_frame_bad_client_test -$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/initial_settings_frame.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/initial_settings_frame.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_initial_settings_frame_bad_client_test: $(INITIAL_SETTINGS_FRAME_BAD_CLIENT_TEST_OBJS:.o=.dep) @@ -23137,12 +20361,12 @@ LARGE_METADATA_BAD_CLIENT_TEST_SRC = \ LARGE_METADATA_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LARGE_METADATA_BAD_CLIENT_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/large_metadata_bad_client_test: $(LARGE_METADATA_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/large_metadata_bad_client_test: $(LARGE_METADATA_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(LARGE_METADATA_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/large_metadata_bad_client_test + $(Q) $(LD) $(LDFLAGS) $(LARGE_METADATA_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/large_metadata_bad_client_test -$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/large_metadata.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/large_metadata.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_large_metadata_bad_client_test: $(LARGE_METADATA_BAD_CLIENT_TEST_OBJS:.o=.dep) @@ -23157,12 +20381,12 @@ SERVER_REGISTERED_METHOD_BAD_CLIENT_TEST_SRC = \ SERVER_REGISTERED_METHOD_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(SERVER_REGISTERED_METHOD_BAD_CLIENT_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/server_registered_method_bad_client_test: $(SERVER_REGISTERED_METHOD_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/server_registered_method_bad_client_test: $(SERVER_REGISTERED_METHOD_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(SERVER_REGISTERED_METHOD_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/server_registered_method_bad_client_test + $(Q) $(LD) $(LDFLAGS) $(SERVER_REGISTERED_METHOD_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/server_registered_method_bad_client_test -$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/server_registered_method.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/server_registered_method.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_server_registered_method_bad_client_test: $(SERVER_REGISTERED_METHOD_BAD_CLIENT_TEST_OBJS:.o=.dep) @@ -23177,12 +20401,12 @@ SIMPLE_REQUEST_BAD_CLIENT_TEST_SRC = \ SIMPLE_REQUEST_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(SIMPLE_REQUEST_BAD_CLIENT_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/simple_request_bad_client_test: $(SIMPLE_REQUEST_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/simple_request_bad_client_test: $(SIMPLE_REQUEST_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(SIMPLE_REQUEST_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/simple_request_bad_client_test + $(Q) $(LD) $(LDFLAGS) $(SIMPLE_REQUEST_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/simple_request_bad_client_test -$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/simple_request.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/simple_request.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_simple_request_bad_client_test: $(SIMPLE_REQUEST_BAD_CLIENT_TEST_OBJS:.o=.dep) @@ -23197,12 +20421,12 @@ UNKNOWN_FRAME_BAD_CLIENT_TEST_SRC = \ UNKNOWN_FRAME_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(UNKNOWN_FRAME_BAD_CLIENT_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/unknown_frame_bad_client_test: $(UNKNOWN_FRAME_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/unknown_frame_bad_client_test: $(UNKNOWN_FRAME_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(UNKNOWN_FRAME_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/unknown_frame_bad_client_test + $(Q) $(LD) $(LDFLAGS) $(UNKNOWN_FRAME_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/unknown_frame_bad_client_test -$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/unknown_frame.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/unknown_frame.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_unknown_frame_bad_client_test: $(UNKNOWN_FRAME_BAD_CLIENT_TEST_OBJS:.o=.dep) @@ -23217,12 +20441,12 @@ WINDOW_OVERFLOW_BAD_CLIENT_TEST_SRC = \ WINDOW_OVERFLOW_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(WINDOW_OVERFLOW_BAD_CLIENT_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/window_overflow_bad_client_test: $(WINDOW_OVERFLOW_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/window_overflow_bad_client_test: $(WINDOW_OVERFLOW_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(WINDOW_OVERFLOW_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/window_overflow_bad_client_test + $(Q) $(LD) $(LDFLAGS) $(WINDOW_OVERFLOW_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/window_overflow_bad_client_test -$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/window_overflow.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/window_overflow.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_window_overflow_bad_client_test: $(WINDOW_OVERFLOW_BAD_CLIENT_TEST_OBJS:.o=.dep) @@ -23245,14 +20469,14 @@ else -$(BINDIR)/$(CONFIG)/bad_ssl_cert_server: $(BAD_SSL_CERT_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/bad_ssl_cert_server: $(BAD_SSL_CERT_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(BAD_SSL_CERT_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a $(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)/bad_ssl_cert_server + $(Q) $(LD) $(LDFLAGS) $(BAD_SSL_CERT_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/bad_ssl_cert_server endif -$(OBJDIR)/$(CONFIG)/test/core/bad_ssl/servers/cert.o: $(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/bad_ssl/servers/cert.o: $(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_bad_ssl_cert_server: $(BAD_SSL_CERT_SERVER_OBJS:.o=.dep) @@ -23277,14 +20501,14 @@ else -$(BINDIR)/$(CONFIG)/bad_ssl_cert_test: $(BAD_SSL_CERT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/bad_ssl_cert_test: $(BAD_SSL_CERT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(BAD_SSL_CERT_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)/bad_ssl_cert_test + $(Q) $(LD) $(LDFLAGS) $(BAD_SSL_CERT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/bad_ssl_cert_test endif -$(OBJDIR)/$(CONFIG)/test/core/bad_ssl/bad_ssl_test.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/bad_ssl/bad_ssl_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_bad_ssl_cert_test: $(BAD_SSL_CERT_TEST_OBJS:.o=.dep) @@ -23309,14 +20533,14 @@ else -$(BINDIR)/$(CONFIG)/h2_census_test: $(H2_CENSUS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_census_test: $(H2_CENSUS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_CENSUS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(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)/h2_census_test + $(Q) $(LD) $(LDFLAGS) $(H2_CENSUS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_census_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_census.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_census.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_census_test: $(H2_CENSUS_TEST_OBJS:.o=.dep) @@ -23341,14 +20565,14 @@ else -$(BINDIR)/$(CONFIG)/h2_compress_test: $(H2_COMPRESS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_compress_test: $(H2_COMPRESS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_COMPRESS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(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)/h2_compress_test + $(Q) $(LD) $(LDFLAGS) $(H2_COMPRESS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_compress_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_compress.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_compress.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_compress_test: $(H2_COMPRESS_TEST_OBJS:.o=.dep) @@ -23373,14 +20597,14 @@ else -$(BINDIR)/$(CONFIG)/h2_fakesec_test: $(H2_FAKESEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_fakesec_test: $(H2_FAKESEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_FAKESEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(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)/h2_fakesec_test + $(Q) $(LD) $(LDFLAGS) $(H2_FAKESEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_fakesec_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_fakesec.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_fakesec.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_fakesec_test: $(H2_FAKESEC_TEST_OBJS:.o=.dep) @@ -23405,14 +20629,14 @@ else -$(BINDIR)/$(CONFIG)/h2_fd_test: $(H2_FD_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_fd_test: $(H2_FD_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_FD_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(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)/h2_fd_test + $(Q) $(LD) $(LDFLAGS) $(H2_FD_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_fd_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_fd.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_fd.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_fd_test: $(H2_FD_TEST_OBJS:.o=.dep) @@ -23437,14 +20661,14 @@ else -$(BINDIR)/$(CONFIG)/h2_full_test: $(H2_FULL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_full_test: $(H2_FULL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_FULL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(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)/h2_full_test + $(Q) $(LD) $(LDFLAGS) $(H2_FULL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_full_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_full.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_full.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_full_test: $(H2_FULL_TEST_OBJS:.o=.dep) @@ -23469,14 +20693,14 @@ else -$(BINDIR)/$(CONFIG)/h2_full+pipe_test: $(H2_FULL+PIPE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_full+pipe_test: $(H2_FULL+PIPE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_FULL+PIPE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(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)/h2_full+pipe_test + $(Q) $(LD) $(LDFLAGS) $(H2_FULL+PIPE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_full+pipe_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_full+pipe.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_full+pipe.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_full+pipe_test: $(H2_FULL+PIPE_TEST_OBJS:.o=.dep) @@ -23501,14 +20725,14 @@ else -$(BINDIR)/$(CONFIG)/h2_full+trace_test: $(H2_FULL+TRACE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_full+trace_test: $(H2_FULL+TRACE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_FULL+TRACE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(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)/h2_full+trace_test + $(Q) $(LD) $(LDFLAGS) $(H2_FULL+TRACE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_full+trace_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_full+trace.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_full+trace.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_full+trace_test: $(H2_FULL+TRACE_TEST_OBJS:.o=.dep) @@ -23533,14 +20757,14 @@ else -$(BINDIR)/$(CONFIG)/h2_full+workarounds_test: $(H2_FULL+WORKAROUNDS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_full+workarounds_test: $(H2_FULL+WORKAROUNDS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_FULL+WORKAROUNDS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(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)/h2_full+workarounds_test + $(Q) $(LD) $(LDFLAGS) $(H2_FULL+WORKAROUNDS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_full+workarounds_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_full+workarounds.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_full+workarounds.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_full+workarounds_test: $(H2_FULL+WORKAROUNDS_TEST_OBJS:.o=.dep) @@ -23565,14 +20789,14 @@ else -$(BINDIR)/$(CONFIG)/h2_http_proxy_test: $(H2_HTTP_PROXY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_http_proxy_test: $(H2_HTTP_PROXY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_HTTP_PROXY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(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)/h2_http_proxy_test + $(Q) $(LD) $(LDFLAGS) $(H2_HTTP_PROXY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_http_proxy_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_http_proxy.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_http_proxy.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_http_proxy_test: $(H2_HTTP_PROXY_TEST_OBJS:.o=.dep) @@ -23583,34 +20807,98 @@ endif endif -H2_LOCAL_TEST_SRC = \ - test/core/end2end/fixtures/h2_local.cc \ +H2_LOCAL_IPV4_TEST_SRC = \ + test/core/end2end/fixtures/h2_local_ipv4.cc \ -H2_LOCAL_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_LOCAL_TEST_SRC)))) +H2_LOCAL_IPV4_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_LOCAL_IPV4_TEST_SRC)))) ifeq ($(NO_SECURE),true) # You can't build secure targets if you don't have OpenSSL. -$(BINDIR)/$(CONFIG)/h2_local_test: openssl_dep_error +$(BINDIR)/$(CONFIG)/h2_local_ipv4_test: openssl_dep_error else -$(BINDIR)/$(CONFIG)/h2_local_test: $(H2_LOCAL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_local_ipv4_test: $(H2_LOCAL_IPV4_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_LOCAL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(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)/h2_local_test + $(Q) $(LD) $(LDFLAGS) $(H2_LOCAL_IPV4_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_local_ipv4_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_local.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_local_ipv4.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a -deps_h2_local_test: $(H2_LOCAL_TEST_OBJS:.o=.dep) +deps_h2_local_ipv4_test: $(H2_LOCAL_IPV4_TEST_OBJS:.o=.dep) ifneq ($(NO_SECURE),true) ifneq ($(NO_DEPS),true) --include $(H2_LOCAL_TEST_OBJS:.o=.dep) +-include $(H2_LOCAL_IPV4_TEST_OBJS:.o=.dep) +endif +endif + + +H2_LOCAL_IPV6_TEST_SRC = \ + test/core/end2end/fixtures/h2_local_ipv6.cc \ + +H2_LOCAL_IPV6_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_LOCAL_IPV6_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/h2_local_ipv6_test: openssl_dep_error + +else + + + +$(BINDIR)/$(CONFIG)/h2_local_ipv6_test: $(H2_LOCAL_IPV6_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LD) $(LDFLAGS) $(H2_LOCAL_IPV6_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_local_ipv6_test + +endif + +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_local_ipv6.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_h2_local_ipv6_test: $(H2_LOCAL_IPV6_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(H2_LOCAL_IPV6_TEST_OBJS:.o=.dep) +endif +endif + + +H2_LOCAL_UDS_TEST_SRC = \ + test/core/end2end/fixtures/h2_local_uds.cc \ + +H2_LOCAL_UDS_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_LOCAL_UDS_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/h2_local_uds_test: openssl_dep_error + +else + + + +$(BINDIR)/$(CONFIG)/h2_local_uds_test: $(H2_LOCAL_UDS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LD) $(LDFLAGS) $(H2_LOCAL_UDS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_local_uds_test + +endif + +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_local_uds.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_h2_local_uds_test: $(H2_LOCAL_UDS_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(H2_LOCAL_UDS_TEST_OBJS:.o=.dep) endif endif @@ -23629,14 +20917,14 @@ else -$(BINDIR)/$(CONFIG)/h2_oauth2_test: $(H2_OAUTH2_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_oauth2_test: $(H2_OAUTH2_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_OAUTH2_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(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)/h2_oauth2_test + $(Q) $(LD) $(LDFLAGS) $(H2_OAUTH2_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_oauth2_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_oauth2.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_oauth2.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_oauth2_test: $(H2_OAUTH2_TEST_OBJS:.o=.dep) @@ -23661,14 +20949,14 @@ else -$(BINDIR)/$(CONFIG)/h2_proxy_test: $(H2_PROXY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_proxy_test: $(H2_PROXY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_PROXY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(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)/h2_proxy_test + $(Q) $(LD) $(LDFLAGS) $(H2_PROXY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_proxy_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_proxy.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_proxy.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_proxy_test: $(H2_PROXY_TEST_OBJS:.o=.dep) @@ -23693,14 +20981,14 @@ else -$(BINDIR)/$(CONFIG)/h2_sockpair_test: $(H2_SOCKPAIR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_sockpair_test: $(H2_SOCKPAIR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_SOCKPAIR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(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)/h2_sockpair_test + $(Q) $(LD) $(LDFLAGS) $(H2_SOCKPAIR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_sockpair_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_sockpair.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_sockpair.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_sockpair_test: $(H2_SOCKPAIR_TEST_OBJS:.o=.dep) @@ -23725,14 +21013,14 @@ else -$(BINDIR)/$(CONFIG)/h2_sockpair+trace_test: $(H2_SOCKPAIR+TRACE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_sockpair+trace_test: $(H2_SOCKPAIR+TRACE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_SOCKPAIR+TRACE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(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)/h2_sockpair+trace_test + $(Q) $(LD) $(LDFLAGS) $(H2_SOCKPAIR+TRACE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_sockpair+trace_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_sockpair+trace.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_sockpair+trace.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_sockpair+trace_test: $(H2_SOCKPAIR+TRACE_TEST_OBJS:.o=.dep) @@ -23757,14 +21045,14 @@ else -$(BINDIR)/$(CONFIG)/h2_sockpair_1byte_test: $(H2_SOCKPAIR_1BYTE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_sockpair_1byte_test: $(H2_SOCKPAIR_1BYTE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_SOCKPAIR_1BYTE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(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)/h2_sockpair_1byte_test + $(Q) $(LD) $(LDFLAGS) $(H2_SOCKPAIR_1BYTE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_sockpair_1byte.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_sockpair_1byte.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_sockpair_1byte_test: $(H2_SOCKPAIR_1BYTE_TEST_OBJS:.o=.dep) @@ -23775,6 +21063,38 @@ endif endif +H2_SPIFFE_TEST_SRC = \ + test/core/end2end/fixtures/h2_spiffe.cc \ + +H2_SPIFFE_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_SPIFFE_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/h2_spiffe_test: openssl_dep_error + +else + + + +$(BINDIR)/$(CONFIG)/h2_spiffe_test: $(H2_SPIFFE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LD) $(LDFLAGS) $(H2_SPIFFE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_spiffe_test + +endif + +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_spiffe.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_h2_spiffe_test: $(H2_SPIFFE_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(H2_SPIFFE_TEST_OBJS:.o=.dep) +endif +endif + + H2_SSL_TEST_SRC = \ test/core/end2end/fixtures/h2_ssl.cc \ @@ -23789,14 +21109,14 @@ else -$(BINDIR)/$(CONFIG)/h2_ssl_test: $(H2_SSL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_ssl_test: $(H2_SSL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_SSL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(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)/h2_ssl_test + $(Q) $(LD) $(LDFLAGS) $(H2_SSL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_ssl_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_ssl.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_ssl.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_ssl_test: $(H2_SSL_TEST_OBJS:.o=.dep) @@ -23807,6 +21127,38 @@ endif endif +H2_SSL_CRED_RELOAD_TEST_SRC = \ + test/core/end2end/fixtures/h2_ssl_cred_reload.cc \ + +H2_SSL_CRED_RELOAD_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_SSL_CRED_RELOAD_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/h2_ssl_cred_reload_test: openssl_dep_error + +else + + + +$(BINDIR)/$(CONFIG)/h2_ssl_cred_reload_test: $(H2_SSL_CRED_RELOAD_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LD) $(LDFLAGS) $(H2_SSL_CRED_RELOAD_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_ssl_cred_reload_test + +endif + +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_ssl_cred_reload.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_h2_ssl_cred_reload_test: $(H2_SSL_CRED_RELOAD_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(H2_SSL_CRED_RELOAD_TEST_OBJS:.o=.dep) +endif +endif + + H2_SSL_PROXY_TEST_SRC = \ test/core/end2end/fixtures/h2_ssl_proxy.cc \ @@ -23821,14 +21173,14 @@ else -$(BINDIR)/$(CONFIG)/h2_ssl_proxy_test: $(H2_SSL_PROXY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_ssl_proxy_test: $(H2_SSL_PROXY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_SSL_PROXY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(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)/h2_ssl_proxy_test + $(Q) $(LD) $(LDFLAGS) $(H2_SSL_PROXY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_ssl_proxy_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_ssl_proxy.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_ssl_proxy.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_ssl_proxy_test: $(H2_SSL_PROXY_TEST_OBJS:.o=.dep) @@ -23853,14 +21205,14 @@ else -$(BINDIR)/$(CONFIG)/h2_uds_test: $(H2_UDS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_uds_test: $(H2_UDS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_UDS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(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)/h2_uds_test + $(Q) $(LD) $(LDFLAGS) $(H2_UDS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_uds_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_uds.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_uds.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_uds_test: $(H2_UDS_TEST_OBJS:.o=.dep) @@ -23885,14 +21237,14 @@ else -$(BINDIR)/$(CONFIG)/inproc_test: $(INPROC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/inproc_test: $(INPROC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(INPROC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(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)/inproc_test + $(Q) $(LD) $(LDFLAGS) $(INPROC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/inproc_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/inproc.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/inproc.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_inproc_test: $(INPROC_TEST_OBJS:.o=.dep) @@ -23909,12 +21261,12 @@ H2_CENSUS_NOSEC_TEST_SRC = \ H2_CENSUS_NOSEC_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_CENSUS_NOSEC_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/h2_census_nosec_test: $(H2_CENSUS_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_census_nosec_test: $(H2_CENSUS_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_CENSUS_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_census_nosec_test + $(Q) $(LD) $(LDFLAGS) $(H2_CENSUS_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_census_nosec_test -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_census.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_census.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_census_nosec_test: $(H2_CENSUS_NOSEC_TEST_OBJS:.o=.dep) @@ -23929,12 +21281,12 @@ H2_COMPRESS_NOSEC_TEST_SRC = \ H2_COMPRESS_NOSEC_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_COMPRESS_NOSEC_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/h2_compress_nosec_test: $(H2_COMPRESS_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_compress_nosec_test: $(H2_COMPRESS_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_COMPRESS_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_compress_nosec_test + $(Q) $(LD) $(LDFLAGS) $(H2_COMPRESS_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_compress_nosec_test -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_compress.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_compress.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_compress_nosec_test: $(H2_COMPRESS_NOSEC_TEST_OBJS:.o=.dep) @@ -23949,12 +21301,12 @@ H2_FD_NOSEC_TEST_SRC = \ H2_FD_NOSEC_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_FD_NOSEC_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/h2_fd_nosec_test: $(H2_FD_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_fd_nosec_test: $(H2_FD_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_FD_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_fd_nosec_test + $(Q) $(LD) $(LDFLAGS) $(H2_FD_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_fd_nosec_test -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_fd.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_fd.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_fd_nosec_test: $(H2_FD_NOSEC_TEST_OBJS:.o=.dep) @@ -23969,12 +21321,12 @@ H2_FULL_NOSEC_TEST_SRC = \ H2_FULL_NOSEC_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_FULL_NOSEC_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/h2_full_nosec_test: $(H2_FULL_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_full_nosec_test: $(H2_FULL_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_FULL_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_full_nosec_test + $(Q) $(LD) $(LDFLAGS) $(H2_FULL_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_full_nosec_test -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_full.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_full.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_full_nosec_test: $(H2_FULL_NOSEC_TEST_OBJS:.o=.dep) @@ -23989,12 +21341,12 @@ H2_FULL+PIPE_NOSEC_TEST_SRC = \ H2_FULL+PIPE_NOSEC_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_FULL+PIPE_NOSEC_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/h2_full+pipe_nosec_test: $(H2_FULL+PIPE_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_full+pipe_nosec_test: $(H2_FULL+PIPE_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_FULL+PIPE_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_full+pipe_nosec_test + $(Q) $(LD) $(LDFLAGS) $(H2_FULL+PIPE_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_full+pipe_nosec_test -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_full+pipe.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_full+pipe.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_full+pipe_nosec_test: $(H2_FULL+PIPE_NOSEC_TEST_OBJS:.o=.dep) @@ -24009,12 +21361,12 @@ H2_FULL+TRACE_NOSEC_TEST_SRC = \ H2_FULL+TRACE_NOSEC_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_FULL+TRACE_NOSEC_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/h2_full+trace_nosec_test: $(H2_FULL+TRACE_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_full+trace_nosec_test: $(H2_FULL+TRACE_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_FULL+TRACE_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_full+trace_nosec_test + $(Q) $(LD) $(LDFLAGS) $(H2_FULL+TRACE_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_full+trace_nosec_test -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_full+trace.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_full+trace.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_full+trace_nosec_test: $(H2_FULL+TRACE_NOSEC_TEST_OBJS:.o=.dep) @@ -24029,12 +21381,12 @@ H2_FULL+WORKAROUNDS_NOSEC_TEST_SRC = \ H2_FULL+WORKAROUNDS_NOSEC_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_FULL+WORKAROUNDS_NOSEC_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/h2_full+workarounds_nosec_test: $(H2_FULL+WORKAROUNDS_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_full+workarounds_nosec_test: $(H2_FULL+WORKAROUNDS_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_FULL+WORKAROUNDS_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_full+workarounds_nosec_test + $(Q) $(LD) $(LDFLAGS) $(H2_FULL+WORKAROUNDS_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_full+workarounds_nosec_test -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_full+workarounds.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_full+workarounds.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_full+workarounds_nosec_test: $(H2_FULL+WORKAROUNDS_NOSEC_TEST_OBJS:.o=.dep) @@ -24049,12 +21401,12 @@ H2_HTTP_PROXY_NOSEC_TEST_SRC = \ H2_HTTP_PROXY_NOSEC_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_HTTP_PROXY_NOSEC_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/h2_http_proxy_nosec_test: $(H2_HTTP_PROXY_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_http_proxy_nosec_test: $(H2_HTTP_PROXY_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_HTTP_PROXY_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_http_proxy_nosec_test + $(Q) $(LD) $(LDFLAGS) $(H2_HTTP_PROXY_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_http_proxy_nosec_test -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_http_proxy.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_http_proxy.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_http_proxy_nosec_test: $(H2_HTTP_PROXY_NOSEC_TEST_OBJS:.o=.dep) @@ -24069,12 +21421,12 @@ H2_PROXY_NOSEC_TEST_SRC = \ H2_PROXY_NOSEC_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_PROXY_NOSEC_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/h2_proxy_nosec_test: $(H2_PROXY_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_proxy_nosec_test: $(H2_PROXY_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_PROXY_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_proxy_nosec_test + $(Q) $(LD) $(LDFLAGS) $(H2_PROXY_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_proxy_nosec_test -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_proxy.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_proxy.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_proxy_nosec_test: $(H2_PROXY_NOSEC_TEST_OBJS:.o=.dep) @@ -24089,12 +21441,12 @@ H2_SOCKPAIR_NOSEC_TEST_SRC = \ H2_SOCKPAIR_NOSEC_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_SOCKPAIR_NOSEC_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/h2_sockpair_nosec_test: $(H2_SOCKPAIR_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_sockpair_nosec_test: $(H2_SOCKPAIR_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_SOCKPAIR_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_sockpair_nosec_test + $(Q) $(LD) $(LDFLAGS) $(H2_SOCKPAIR_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_sockpair_nosec_test -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_sockpair.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_sockpair.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_sockpair_nosec_test: $(H2_SOCKPAIR_NOSEC_TEST_OBJS:.o=.dep) @@ -24109,12 +21461,12 @@ H2_SOCKPAIR+TRACE_NOSEC_TEST_SRC = \ H2_SOCKPAIR+TRACE_NOSEC_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_SOCKPAIR+TRACE_NOSEC_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/h2_sockpair+trace_nosec_test: $(H2_SOCKPAIR+TRACE_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_sockpair+trace_nosec_test: $(H2_SOCKPAIR+TRACE_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_SOCKPAIR+TRACE_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_sockpair+trace_nosec_test + $(Q) $(LD) $(LDFLAGS) $(H2_SOCKPAIR+TRACE_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_sockpair+trace_nosec_test -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_sockpair+trace.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_sockpair+trace.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_sockpair+trace_nosec_test: $(H2_SOCKPAIR+TRACE_NOSEC_TEST_OBJS:.o=.dep) @@ -24129,12 +21481,12 @@ H2_SOCKPAIR_1BYTE_NOSEC_TEST_SRC = \ H2_SOCKPAIR_1BYTE_NOSEC_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_SOCKPAIR_1BYTE_NOSEC_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/h2_sockpair_1byte_nosec_test: $(H2_SOCKPAIR_1BYTE_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_sockpair_1byte_nosec_test: $(H2_SOCKPAIR_1BYTE_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_SOCKPAIR_1BYTE_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_nosec_test + $(Q) $(LD) $(LDFLAGS) $(H2_SOCKPAIR_1BYTE_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_nosec_test -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_sockpair_1byte.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_sockpair_1byte.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_sockpair_1byte_nosec_test: $(H2_SOCKPAIR_1BYTE_NOSEC_TEST_OBJS:.o=.dep) @@ -24149,12 +21501,12 @@ H2_UDS_NOSEC_TEST_SRC = \ H2_UDS_NOSEC_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_UDS_NOSEC_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/h2_uds_nosec_test: $(H2_UDS_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_uds_nosec_test: $(H2_UDS_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_UDS_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_uds_nosec_test + $(Q) $(LD) $(LDFLAGS) $(H2_UDS_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_uds_nosec_test -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_uds.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_uds.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_h2_uds_nosec_test: $(H2_UDS_NOSEC_TEST_OBJS:.o=.dep) @@ -24186,16 +21538,16 @@ $(BINDIR)/$(CONFIG)/resolver_component_test_unsecure: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/resolver_component_test_unsecure: $(PROTOBUF_DEP) $(RESOLVER_COMPONENT_TEST_UNSECURE_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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/resolver_component_test_unsecure: $(PROTOBUF_DEP) $(RESOLVER_COMPONENT_TEST_UNSECURE_OBJS) $(LIBDIR)/$(CONFIG)/libdns_test_util.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.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(RESOLVER_COMPONENT_TEST_UNSECURE_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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/resolver_component_test_unsecure + $(Q) $(LDXX) $(LDFLAGS) $(RESOLVER_COMPONENT_TEST_UNSECURE_OBJS) $(LIBDIR)/$(CONFIG)/libdns_test_util.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.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/resolver_component_test_unsecure endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/naming/resolver_component_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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/naming/resolver_component_test.o: $(LIBDIR)/$(CONFIG)/libdns_test_util.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.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_resolver_component_test_unsecure: $(RESOLVER_COMPONENT_TEST_UNSECURE_OBJS:.o=.dep) @@ -24229,16 +21581,16 @@ $(BINDIR)/$(CONFIG)/resolver_component_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/resolver_component_test: $(PROTOBUF_DEP) $(RESOLVER_COMPONENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/resolver_component_test: $(PROTOBUF_DEP) $(RESOLVER_COMPONENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libdns_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(RESOLVER_COMPONENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/resolver_component_test + $(Q) $(LDXX) $(LDFLAGS) $(RESOLVER_COMPONENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libdns_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/resolver_component_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/naming/resolver_component_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/naming/resolver_component_test.o: $(LIBDIR)/$(CONFIG)/libdns_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_resolver_component_test: $(RESOLVER_COMPONENT_TEST_OBJS:.o=.dep) @@ -24272,16 +21624,16 @@ $(BINDIR)/$(CONFIG)/resolver_component_tests_runner_invoker_unsecure: protobuf_d else -$(BINDIR)/$(CONFIG)/resolver_component_tests_runner_invoker_unsecure: $(PROTOBUF_DEP) $(RESOLVER_COMPONENT_TESTS_RUNNER_INVOKER_UNSECURE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/resolver_component_tests_runner_invoker_unsecure: $(PROTOBUF_DEP) $(RESOLVER_COMPONENT_TESTS_RUNNER_INVOKER_UNSECURE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(RESOLVER_COMPONENT_TESTS_RUNNER_INVOKER_UNSECURE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/resolver_component_tests_runner_invoker_unsecure + $(Q) $(LDXX) $(LDFLAGS) $(RESOLVER_COMPONENT_TESTS_RUNNER_INVOKER_UNSECURE_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/resolver_component_tests_runner_invoker_unsecure endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/naming/resolver_component_tests_runner_invoker.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/naming/resolver_component_tests_runner_invoker.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_resolver_component_tests_runner_invoker_unsecure: $(RESOLVER_COMPONENT_TESTS_RUNNER_INVOKER_UNSECURE_OBJS:.o=.dep) @@ -24315,16 +21667,16 @@ $(BINDIR)/$(CONFIG)/resolver_component_tests_runner_invoker: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/resolver_component_tests_runner_invoker: $(PROTOBUF_DEP) $(RESOLVER_COMPONENT_TESTS_RUNNER_INVOKER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/resolver_component_tests_runner_invoker: $(PROTOBUF_DEP) $(RESOLVER_COMPONENT_TESTS_RUNNER_INVOKER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(RESOLVER_COMPONENT_TESTS_RUNNER_INVOKER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/resolver_component_tests_runner_invoker + $(Q) $(LDXX) $(LDFLAGS) $(RESOLVER_COMPONENT_TESTS_RUNNER_INVOKER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/resolver_component_tests_runner_invoker endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/naming/resolver_component_tests_runner_invoker.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/naming/resolver_component_tests_runner_invoker.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_resolver_component_tests_runner_invoker: $(RESOLVER_COMPONENT_TESTS_RUNNER_INVOKER_OBJS:.o=.dep) @@ -24358,16 +21710,16 @@ $(BINDIR)/$(CONFIG)/address_sorting_test_unsecure: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/address_sorting_test_unsecure: $(PROTOBUF_DEP) $(ADDRESS_SORTING_TEST_UNSECURE_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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/address_sorting_test_unsecure: $(PROTOBUF_DEP) $(ADDRESS_SORTING_TEST_UNSECURE_OBJS) $(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.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(ADDRESS_SORTING_TEST_UNSECURE_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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/address_sorting_test_unsecure + $(Q) $(LDXX) $(LDFLAGS) $(ADDRESS_SORTING_TEST_UNSECURE_OBJS) $(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.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/address_sorting_test_unsecure endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/naming/address_sorting_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 $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/naming/address_sorting_test.o: $(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.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_address_sorting_test_unsecure: $(ADDRESS_SORTING_TEST_UNSECURE_OBJS:.o=.dep) @@ -24401,16 +21753,16 @@ $(BINDIR)/$(CONFIG)/address_sorting_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/address_sorting_test: $(PROTOBUF_DEP) $(ADDRESS_SORTING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/address_sorting_test: $(PROTOBUF_DEP) $(ADDRESS_SORTING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(ADDRESS_SORTING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/address_sorting_test + $(Q) $(LDXX) $(LDFLAGS) $(ADDRESS_SORTING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/address_sorting_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/naming/address_sorting_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/naming/address_sorting_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_address_sorting_test: $(ADDRESS_SORTING_TEST_OBJS:.o=.dep) @@ -24444,16 +21796,16 @@ $(BINDIR)/$(CONFIG)/cancel_ares_query_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/cancel_ares_query_test: $(PROTOBUF_DEP) $(CANCEL_ARES_QUERY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/cancel_ares_query_test: $(PROTOBUF_DEP) $(CANCEL_ARES_QUERY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libdns_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(CANCEL_ARES_QUERY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/cancel_ares_query_test + $(Q) $(LDXX) $(LDFLAGS) $(CANCEL_ARES_QUERY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libdns_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/cancel_ares_query_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/naming/cancel_ares_query_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/naming/cancel_ares_query_test.o: $(LIBDIR)/$(CONFIG)/libdns_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_cancel_ares_query_test: $(CANCEL_ARES_QUERY_TEST_OBJS:.o=.dep) @@ -24479,16 +21831,16 @@ 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 +$(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.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 + $(Q) $(LD) $(LDFLAGS) $(ALTS_CREDENTIALS_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.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/security/alts_credentials_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.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 +$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_alts_credentials_fuzzer_one_entry: $(ALTS_CREDENTIALS_FUZZER_ONE_ENTRY_OBJS:.o=.dep) @@ -24514,16 +21866,16 @@ else -$(BINDIR)/$(CONFIG)/api_fuzzer_one_entry: $(API_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/api_fuzzer_one_entry: $(API_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(API_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)/api_fuzzer_one_entry + $(Q) $(LD) $(LDFLAGS) $(API_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/api_fuzzer_one_entry endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fuzzers/api_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/end2end/fuzzers/api_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.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 +$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_api_fuzzer_one_entry: $(API_FUZZER_ONE_ENTRY_OBJS:.o=.dep) @@ -24549,16 +21901,16 @@ else -$(BINDIR)/$(CONFIG)/client_fuzzer_one_entry: $(CLIENT_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/client_fuzzer_one_entry: $(CLIENT_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(CLIENT_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)/client_fuzzer_one_entry + $(Q) $(LD) $(LDFLAGS) $(CLIENT_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/client_fuzzer_one_entry endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fuzzers/client_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/end2end/fuzzers/client_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.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 +$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_client_fuzzer_one_entry: $(CLIENT_FUZZER_ONE_ENTRY_OBJS:.o=.dep) @@ -24584,16 +21936,16 @@ else -$(BINDIR)/$(CONFIG)/hpack_parser_fuzzer_test_one_entry: $(HPACK_PARSER_FUZZER_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/hpack_parser_fuzzer_test_one_entry: $(HPACK_PARSER_FUZZER_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(HPACK_PARSER_FUZZER_TEST_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)/hpack_parser_fuzzer_test_one_entry + $(Q) $(LD) $(LDFLAGS) $(HPACK_PARSER_FUZZER_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/hpack_parser_fuzzer_test_one_entry endif -$(OBJDIR)/$(CONFIG)/test/core/transport/chttp2/hpack_parser_fuzzer_test.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/transport/chttp2/hpack_parser_fuzzer_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.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 +$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_hpack_parser_fuzzer_test_one_entry: $(HPACK_PARSER_FUZZER_TEST_ONE_ENTRY_OBJS:.o=.dep) @@ -24619,16 +21971,16 @@ else -$(BINDIR)/$(CONFIG)/http_request_fuzzer_test_one_entry: $(HTTP_REQUEST_FUZZER_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/http_request_fuzzer_test_one_entry: $(HTTP_REQUEST_FUZZER_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(HTTP_REQUEST_FUZZER_TEST_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)/http_request_fuzzer_test_one_entry + $(Q) $(LD) $(LDFLAGS) $(HTTP_REQUEST_FUZZER_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/http_request_fuzzer_test_one_entry endif -$(OBJDIR)/$(CONFIG)/test/core/http/request_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/http/request_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.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 +$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_http_request_fuzzer_test_one_entry: $(HTTP_REQUEST_FUZZER_TEST_ONE_ENTRY_OBJS:.o=.dep) @@ -24654,16 +22006,16 @@ else -$(BINDIR)/$(CONFIG)/http_response_fuzzer_test_one_entry: $(HTTP_RESPONSE_FUZZER_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/http_response_fuzzer_test_one_entry: $(HTTP_RESPONSE_FUZZER_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(HTTP_RESPONSE_FUZZER_TEST_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)/http_response_fuzzer_test_one_entry + $(Q) $(LD) $(LDFLAGS) $(HTTP_RESPONSE_FUZZER_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/http_response_fuzzer_test_one_entry endif -$(OBJDIR)/$(CONFIG)/test/core/http/response_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/http/response_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.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 +$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_http_response_fuzzer_test_one_entry: $(HTTP_RESPONSE_FUZZER_TEST_ONE_ENTRY_OBJS:.o=.dep) @@ -24689,16 +22041,16 @@ else -$(BINDIR)/$(CONFIG)/json_fuzzer_test_one_entry: $(JSON_FUZZER_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/json_fuzzer_test_one_entry: $(JSON_FUZZER_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(JSON_FUZZER_TEST_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)/json_fuzzer_test_one_entry + $(Q) $(LD) $(LDFLAGS) $(JSON_FUZZER_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/json_fuzzer_test_one_entry endif -$(OBJDIR)/$(CONFIG)/test/core/json/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/json/fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.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 +$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_json_fuzzer_test_one_entry: $(JSON_FUZZER_TEST_ONE_ENTRY_OBJS:.o=.dep) @@ -24724,16 +22076,16 @@ else -$(BINDIR)/$(CONFIG)/nanopb_fuzzer_response_test_one_entry: $(NANOPB_FUZZER_RESPONSE_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/nanopb_fuzzer_response_test_one_entry: $(NANOPB_FUZZER_RESPONSE_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(NANOPB_FUZZER_RESPONSE_TEST_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)/nanopb_fuzzer_response_test_one_entry + $(Q) $(LD) $(LDFLAGS) $(NANOPB_FUZZER_RESPONSE_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/nanopb_fuzzer_response_test_one_entry endif -$(OBJDIR)/$(CONFIG)/test/core/nanopb/fuzzer_response.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/nanopb/fuzzer_response.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.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 +$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_nanopb_fuzzer_response_test_one_entry: $(NANOPB_FUZZER_RESPONSE_TEST_ONE_ENTRY_OBJS:.o=.dep) @@ -24759,16 +22111,16 @@ else -$(BINDIR)/$(CONFIG)/nanopb_fuzzer_serverlist_test_one_entry: $(NANOPB_FUZZER_SERVERLIST_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/nanopb_fuzzer_serverlist_test_one_entry: $(NANOPB_FUZZER_SERVERLIST_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(NANOPB_FUZZER_SERVERLIST_TEST_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)/nanopb_fuzzer_serverlist_test_one_entry + $(Q) $(LD) $(LDFLAGS) $(NANOPB_FUZZER_SERVERLIST_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/nanopb_fuzzer_serverlist_test_one_entry endif -$(OBJDIR)/$(CONFIG)/test/core/nanopb/fuzzer_serverlist.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/nanopb/fuzzer_serverlist.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.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 +$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_nanopb_fuzzer_serverlist_test_one_entry: $(NANOPB_FUZZER_SERVERLIST_TEST_ONE_ENTRY_OBJS:.o=.dep) @@ -24794,16 +22146,16 @@ else -$(BINDIR)/$(CONFIG)/percent_decode_fuzzer_one_entry: $(PERCENT_DECODE_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/percent_decode_fuzzer_one_entry: $(PERCENT_DECODE_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(PERCENT_DECODE_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)/percent_decode_fuzzer_one_entry + $(Q) $(LD) $(LDFLAGS) $(PERCENT_DECODE_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/percent_decode_fuzzer_one_entry endif -$(OBJDIR)/$(CONFIG)/test/core/slice/percent_decode_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/slice/percent_decode_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.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 +$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_percent_decode_fuzzer_one_entry: $(PERCENT_DECODE_FUZZER_ONE_ENTRY_OBJS:.o=.dep) @@ -24829,16 +22181,16 @@ else -$(BINDIR)/$(CONFIG)/percent_encode_fuzzer_one_entry: $(PERCENT_ENCODE_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/percent_encode_fuzzer_one_entry: $(PERCENT_ENCODE_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(PERCENT_ENCODE_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)/percent_encode_fuzzer_one_entry + $(Q) $(LD) $(LDFLAGS) $(PERCENT_ENCODE_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/percent_encode_fuzzer_one_entry endif -$(OBJDIR)/$(CONFIG)/test/core/slice/percent_encode_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/slice/percent_encode_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.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 +$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_percent_encode_fuzzer_one_entry: $(PERCENT_ENCODE_FUZZER_ONE_ENTRY_OBJS:.o=.dep) @@ -24864,16 +22216,16 @@ else -$(BINDIR)/$(CONFIG)/server_fuzzer_one_entry: $(SERVER_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/server_fuzzer_one_entry: $(SERVER_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(SERVER_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)/server_fuzzer_one_entry + $(Q) $(LD) $(LDFLAGS) $(SERVER_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/server_fuzzer_one_entry endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fuzzers/server_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/end2end/fuzzers/server_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.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 +$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_server_fuzzer_one_entry: $(SERVER_FUZZER_ONE_ENTRY_OBJS:.o=.dep) @@ -24899,16 +22251,16 @@ else -$(BINDIR)/$(CONFIG)/ssl_server_fuzzer_one_entry: $(SSL_SERVER_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/ssl_server_fuzzer_one_entry: $(SSL_SERVER_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(SSL_SERVER_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)/ssl_server_fuzzer_one_entry + $(Q) $(LD) $(LDFLAGS) $(SSL_SERVER_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/ssl_server_fuzzer_one_entry endif -$(OBJDIR)/$(CONFIG)/test/core/security/ssl_server_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/security/ssl_server_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.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 +$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_ssl_server_fuzzer_one_entry: $(SSL_SERVER_FUZZER_ONE_ENTRY_OBJS:.o=.dep) @@ -24934,16 +22286,16 @@ else -$(BINDIR)/$(CONFIG)/uri_fuzzer_test_one_entry: $(URI_FUZZER_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/uri_fuzzer_test_one_entry: $(URI_FUZZER_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(URI_FUZZER_TEST_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)/uri_fuzzer_test_one_entry + $(Q) $(LD) $(LDFLAGS) $(URI_FUZZER_TEST_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/uri_fuzzer_test_one_entry endif -$(OBJDIR)/$(CONFIG)/test/core/client_channel/uri_fuzzer_test.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/client_channel/uri_fuzzer_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.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 +$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_uri_fuzzer_test_one_entry: $(URI_FUZZER_TEST_ONE_ENTRY_OBJS:.o=.dep) @@ -24993,6 +22345,8 @@ src/core/lib/security/credentials/local/local_credentials.cc: $(OPENSSL_DEP) src/core/lib/security/credentials/oauth2/oauth2_credentials.cc: $(OPENSSL_DEP) src/core/lib/security/credentials/plugin/plugin_credentials.cc: $(OPENSSL_DEP) src/core/lib/security/credentials/ssl/ssl_credentials.cc: $(OPENSSL_DEP) +src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc: $(OPENSSL_DEP) +src/core/lib/security/credentials/tls/spiffe_credentials.cc: $(OPENSSL_DEP) src/core/lib/security/security_connector/alts/alts_security_connector.cc: $(OPENSSL_DEP) src/core/lib/security/security_connector/fake/fake_security_connector.cc: $(OPENSSL_DEP) src/core/lib/security/security_connector/load_system_roots_fallback.cc: $(OPENSSL_DEP) @@ -25001,6 +22355,7 @@ src/core/lib/security/security_connector/local/local_security_connector.cc: $(OP src/core/lib/security/security_connector/security_connector.cc: $(OPENSSL_DEP) src/core/lib/security/security_connector/ssl/ssl_security_connector.cc: $(OPENSSL_DEP) src/core/lib/security/security_connector/ssl_utils.cc: $(OPENSSL_DEP) +src/core/lib/security/security_connector/tls/spiffe_security_connector.cc: $(OPENSSL_DEP) src/core/lib/security/transport/client_auth_filter.cc: $(OPENSSL_DEP) src/core/lib/security/transport/secure_endpoint.cc: $(OPENSSL_DEP) src/core/lib/security/transport/security_handshaker.cc: $(OPENSSL_DEP) @@ -25070,6 +22425,7 @@ test/core/tsi/alts/crypt/gsec_test_util.cc: $(OPENSSL_DEP) test/core/tsi/alts/handshaker/alts_handshaker_service_api_test_lib.cc: $(OPENSSL_DEP) test/core/util/reconnect_server.cc: $(OPENSSL_DEP) test/core/util/test_tcp_server.cc: $(OPENSSL_DEP) +test/cpp/end2end/test_health_check_service_impl.cc: $(OPENSSL_DEP) test/cpp/end2end/test_service_impl.cc: $(OPENSSL_DEP) test/cpp/interop/client.cc: $(OPENSSL_DEP) test/cpp/interop/client_helper.cc: $(OPENSSL_DEP) @@ -25078,7 +22434,9 @@ test/cpp/interop/interop_client.cc: $(OPENSSL_DEP) test/cpp/interop/interop_server.cc: $(OPENSSL_DEP) test/cpp/interop/interop_server_bootstrap.cc: $(OPENSSL_DEP) test/cpp/interop/server_helper.cc: $(OPENSSL_DEP) +test/cpp/microbenchmarks/callback_test_service.cc: $(OPENSSL_DEP) test/cpp/microbenchmarks/helpers.cc: $(OPENSSL_DEP) +test/cpp/naming/dns_test_util.cc: $(OPENSSL_DEP) test/cpp/qps/benchmark_config.cc: $(OPENSSL_DEP) test/cpp/qps/client_async.cc: $(OPENSSL_DEP) test/cpp/qps/client_callback.cc: $(OPENSSL_DEP) diff --git a/PYTHON-MANIFEST.in b/PYTHON-MANIFEST.in index c0de5289ee2..544fefbc487 100644 --- a/PYTHON-MANIFEST.in +++ b/PYTHON-MANIFEST.in @@ -20,3 +20,4 @@ include src/python/grpcio/README.rst include requirements.txt include etc/roots.pem include Makefile +include LICENSE diff --git a/Rakefile b/Rakefile index 0068a3b8e4f..d604f7935b1 100755 --- a/Rakefile +++ b/Rakefile @@ -105,7 +105,7 @@ task 'dlls' do env_comp = "CC=#{opt[:cross]}-gcc " env_comp += "CXX=#{opt[:cross]}-g++ " env_comp += "LD=#{opt[:cross]}-gcc " - docker_for_windows "gem update --system --no-ri --no-doc && #{env} #{env_comp} make -j #{out} && #{opt[:cross]}-strip -x -S #{out} && cp #{out} #{opt[:out]}" + docker_for_windows "gem update --system --no-document && #{env} #{env_comp} make -j #{out} && #{opt[:cross]}-strip -x -S #{out} && cp #{out} #{opt[:out]}" end end @@ -124,10 +124,10 @@ task 'gem:native' do "invoked on macos with ruby #{RUBY_VERSION}. The ruby macos artifact " \ "build should be running on ruby 2.5." end - system "rake cross native gem RUBY_CC_VERSION=2.5.0:2.4.0:2.3.0:2.2.2:2.1.6:2.0.0 V=#{verbose} GRPC_CONFIG=#{grpc_config}" + system "rake cross native gem RUBY_CC_VERSION=2.6.0:2.5.0:2.4.0:2.3.0:2.2.2 V=#{verbose} GRPC_CONFIG=#{grpc_config}" else Rake::Task['dlls'].execute - docker_for_windows "gem update --system --no-ri --no-doc && bundle && rake cross native gem RUBY_CC_VERSION=2.5.0:2.4.0:2.3.0:2.2.2:2.1.6:2.0.0 V=#{verbose} GRPC_CONFIG=#{grpc_config}" + docker_for_windows "gem update --system --no-document && bundle && rake cross native gem RUBY_CC_VERSION=2.6.0:2.5.0:2.4.0:2.3.0:2.2.2 V=#{verbose} GRPC_CONFIG=#{grpc_config}" end end diff --git a/WORKSPACE b/WORKSPACE index a547c24cbe2..2db3c5db2ff 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -1,45 +1,67 @@ -workspace(name="com_github_grpc_grpc") +workspace(name = "com_github_grpc_grpc") +load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") load("//bazel:grpc_deps.bzl", "grpc_deps", "grpc_test_only_deps") +load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository") + grpc_deps() + grpc_test_only_deps() -new_http_archive( - name="cython", - sha256="d68138a2381afbdd0876c3cb2a22389043fa01c4badede1228ee073032b07a27", - urls=[ - "https://github.com/cython/cython/archive/c2b80d87658a8525ce091cbe146cb7eaa29fed5c.tar.gz", - ], - strip_prefix="cython-c2b80d87658a8525ce091cbe146cb7eaa29fed5c", - build_file="//third_party:cython.BUILD", +register_execution_platforms( + "//third_party/toolchains:local", + "//third_party/toolchains:local_large", + "//third_party/toolchains:rbe_windows", ) -load("//third_party/py:python_configure.bzl", "python_configure") -python_configure(name="local_config_python") +register_toolchains( + "//third_party/toolchains/bazel_0.23.2_rbe_windows:cc-toolchain-x64_windows", +) git_repository( - name="io_bazel_rules_python", - remote="https://github.com/bazelbuild/rules_python.git", - commit="8b5d0683a7d878b28fffe464779c8a53659fc645", + name = "io_bazel_rules_python", + commit = "8b5d0683a7d878b28fffe464779c8a53659fc645", + remote = "https://github.com/bazelbuild/rules_python.git", ) load("@io_bazel_rules_python//python:pip.bzl", "pip_repositories", "pip_import") -pip_repositories() pip_import( - name="grpc_python_dependencies", - requirements="//:requirements.bazel.txt", + name = "grpc_python_dependencies", + requirements = "//:requirements.bazel.txt", ) -load("@grpc_python_dependencies//:requirements.bzl", "pip_install") -pip_install() - -# NOTE(https://github.com/pubref/rules_protobuf/pull/196): Switch to upstream repo after this gets merged. -git_repository( - name="org_pubref_rules_protobuf", - remote="https://github.com/ghostwriternr/rules_protobuf", - tag="v0.8.2.1-alpha", +http_archive( + name = "cython", + build_file = "//third_party:cython.BUILD", + sha256 = "d68138a2381afbdd0876c3cb2a22389043fa01c4badede1228ee073032b07a27", + strip_prefix = "cython-c2b80d87658a8525ce091cbe146cb7eaa29fed5c", + urls = [ + "https://github.com/cython/cython/archive/c2b80d87658a8525ce091cbe146cb7eaa29fed5c.tar.gz", + ], ) -load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_repositories") -py_proto_repositories() +load("//bazel:grpc_python_deps.bzl", "grpc_python_deps") + +grpc_python_deps() + +load("@bazel_toolchains//rules:rbe_repo.bzl", "rbe_autoconfig") + +# Create toolchain configuration for remote execution. +rbe_autoconfig( + name = "rbe_default", +) + +load("@bazel_toolchains//rules:environments.bzl", "clang_env") +load("@bazel_skylib//lib:dicts.bzl", "dicts") + +# Create msan toolchain configuration for remote execution. +rbe_autoconfig( + name = "rbe_msan", + env = dicts.add( + clang_env(), + { + "BAZEL_LINKOPTS": "-lc++:-lc++abi:-lm", + }, + ), +) diff --git a/bazel/BUILD b/bazel/BUILD index 32402892cc3..c3c82c9c0c7 100644 --- a/bazel/BUILD +++ b/bazel/BUILD @@ -17,15 +17,3 @@ licenses(["notice"]) # Apache v2 package(default_visibility = ["//:__subpackages__"]) load(":cc_grpc_library.bzl", "cc_grpc_library") - -proto_library( - name = "well_known_protos_list", - srcs = ["@com_google_protobuf//:well_known_protos"], -) - -cc_grpc_library( - name = "well_known_protos", - srcs = "well_known_protos_list", - proto_only = True, - deps = [], -) diff --git a/bazel/cc_grpc_library.bzl b/bazel/cc_grpc_library.bzl index 32885657141..572af756176 100644 --- a/bazel/cc_grpc_library.bzl +++ b/bazel/cc_grpc_library.bzl @@ -1,71 +1,105 @@ """Generates and compiles C++ grpc stubs from proto_library rules.""" -load("//:bazel/generate_cc.bzl", "generate_cc") +load("//bazel:generate_cc.bzl", "generate_cc") +load("//bazel:protobuf.bzl", "well_known_proto_libs") -def cc_grpc_library(name, srcs, deps, proto_only, well_known_protos, generate_mocks = False, use_external = False, **kwargs): - """Generates C++ grpc classes from a .proto file. +def cc_grpc_library( + name, + srcs, + deps, + proto_only = False, + well_known_protos = False, + generate_mocks = False, + use_external = False, + grpc_only = False, + **kwargs): + """Generates C++ grpc classes for services defined in a proto file. - Assumes the generated classes will be used in cc_api_version = 2. + If grpc_only is True, this rule is compatible with proto_library and + cc_proto_library native rules such that it expects proto_library target + as srcs argument and generates only grpc library classes, expecting + protobuf messages classes library (cc_proto_library target) to be passed in + deps argument. By default grpc_only is False which makes this rule to behave + in a backwards-compatible mode (trying to generate both proto and grpc + classes). - Arguments: - name: name of rule. - srcs: a single proto_library, which wraps the .proto files with services. - deps: a list of C++ proto_library (or cc_proto_library) which provides - the compiled code of any message that the services depend on. - well_known_protos: Should this library additionally depend on well known - protos - use_external: When True the grpc deps are prefixed with //external. This - allows grpc to be used as a dependency in other bazel projects. - generate_mocks: When True, Google Mock code for client stub is generated. - **kwargs: rest of arguments, e.g., compatible_with and visibility. - """ - if len(srcs) > 1: - fail("Only one srcs value supported", "srcs") + Assumes the generated classes will be used in cc_api_version = 2. - proto_target = "_" + name + "_only" - codegen_target = "_" + name + "_codegen" - codegen_grpc_target = "_" + name + "_grpc_codegen" - proto_deps = ["_" + dep + "_only" for dep in deps if dep.find(':') == -1] - proto_deps += [dep.split(':')[0] + ':' + "_" + dep.split(':')[1] + "_only" for dep in deps if dep.find(':') != -1] + Args: + name (str): Name of rule. + srcs (list): A single .proto file which contains services definitions, + or if grpc_only parameter is True, a single proto_library which + contains services descriptors. + deps (list): A list of C++ proto_library (or cc_proto_library) which + provides the compiled code of any message that the services depend on. + proto_only (bool): If True, create only C++ proto classes library, + avoid creating C++ grpc classes library (expect it in deps). + Deprecated, use native cc_proto_library instead. False by default. + well_known_protos (bool): Should this library additionally depend on + well known protos. Deprecated, the well known protos should be + specified as explicit dependencies of the proto_library target + (passed in srcs parameter) instead. False by default. + generate_mocks (bool): when True, Google Mock code for client stub is + generated. False by default. + use_external (bool): Not used. + grpc_only (bool): if True, generate only grpc library, expecting + protobuf messages library (cc_proto_library target) to be passed as + deps. False by default (will become True by default eventually). + **kwargs: rest of arguments, e.g., compatible_with and visibility + """ + if len(srcs) > 1: + fail("Only one srcs value supported", "srcs") + if grpc_only and proto_only: + fail("A mutualy exclusive configuration is specified: grpc_only = True and proto_only = True") - native.proto_library( - name = proto_target, - srcs = srcs, - deps = proto_deps, - **kwargs - ) + extra_deps = [] + proto_targets = [] - generate_cc( - name = codegen_target, - srcs = [proto_target], - well_known_protos = well_known_protos, - **kwargs - ) + if not grpc_only: + proto_target = "_" + name + "_only" + cc_proto_target = name if proto_only else "_" + name + "_cc_proto" - if not proto_only: - plugin = "@com_github_grpc_grpc//:grpc_cpp_plugin" - generate_cc( - name = codegen_grpc_target, - srcs = [proto_target], - plugin = plugin, - well_known_protos = well_known_protos, - generate_mocks = generate_mocks, - **kwargs - ) - grpc_deps = ["@com_github_grpc_grpc//:grpc++_codegen_proto", - "//external:protobuf"] - native.cc_library( - name = name, - srcs = [":" + codegen_grpc_target, ":" + codegen_target], - hdrs = [":" + codegen_grpc_target, ":" + codegen_target], - deps = deps + grpc_deps, - **kwargs - ) - else: - native.cc_library( - name = name, - srcs = [":" + codegen_target], - hdrs = [":" + codegen_target], - deps = deps + ["//external:protobuf"], - **kwargs - ) + proto_deps = ["_" + dep + "_only" for dep in deps if dep.find(":") == -1] + proto_deps += [dep.split(":")[0] + ":" + "_" + dep.split(":")[1] + "_only" for dep in deps if dep.find(":") != -1] + if well_known_protos: + proto_deps += well_known_proto_libs() + + native.proto_library( + name = proto_target, + srcs = srcs, + deps = proto_deps, + **kwargs + ) + + native.cc_proto_library( + name = cc_proto_target, + deps = [":" + proto_target], + **kwargs + ) + extra_deps.append(":" + cc_proto_target) + proto_targets.append(proto_target) + else: + if not srcs: + fail("srcs cannot be empty", "srcs") + proto_targets += srcs + + if not proto_only: + codegen_grpc_target = "_" + name + "_grpc_codegen" + generate_cc( + name = codegen_grpc_target, + srcs = proto_targets, + plugin = "@com_github_grpc_grpc//:grpc_cpp_plugin", + well_known_protos = well_known_protos, + generate_mocks = generate_mocks, + **kwargs + ) + + native.cc_library( + name = name, + srcs = [":" + codegen_grpc_target], + hdrs = [":" + codegen_grpc_target], + deps = deps + + extra_deps + + ["@com_github_grpc_grpc//:grpc++_codegen_proto"], + **kwargs + ) diff --git a/bazel/generate_cc.bzl b/bazel/generate_cc.bzl index ae747aa42ca..29a888f608f 100644 --- a/bazel/generate_cc.bzl +++ b/bazel/generate_cc.bzl @@ -4,86 +4,148 @@ This is an internal rule used by cc_grpc_library, and shouldn't be used directly. """ +load( + "//bazel:protobuf.bzl", + "get_include_protoc_args", + "get_plugin_args", + "get_proto_root", + "proto_path_to_generated_filename", +) + +_GRPC_PROTO_HEADER_FMT = "{}.grpc.pb.h" +_GRPC_PROTO_SRC_FMT = "{}.grpc.pb.cc" +_GRPC_PROTO_MOCK_HEADER_FMT = "{}_mock.grpc.pb.h" +_PROTO_HEADER_FMT = "{}.pb.h" +_PROTO_SRC_FMT = "{}.pb.cc" + +def _strip_package_from_path(label_package, file): + prefix_len = 0 + if not file.is_source and file.path.startswith(file.root.path): + prefix_len = len(file.root.path) + 1 + + path = file.path + if len(label_package) == 0: + return path + if not path.startswith(label_package + "/", prefix_len): + fail("'{}' does not lie within '{}'.".format(path, label_package)) + return path[prefix_len + len(label_package + "/"):] + +def _get_srcs_file_path(file): + if not file.is_source and file.path.startswith(file.root.path): + return file.path[len(file.root.path) + 1:] + return file.path + +def _join_directories(directories): + massaged_directories = [directory for directory in directories if len(directory) != 0] + return "/".join(massaged_directories) + def generate_cc_impl(ctx): - """Implementation of the generate_cc rule.""" - protos = [f for src in ctx.attr.srcs for f in src.proto.direct_sources] - 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 = 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 + """Implementation of the generate_cc rule.""" + protos = [f for src in ctx.attr.srcs for f in src.proto.check_deps_sources] + includes = [ + f + for src in ctx.attr.srcs + for f in src.proto.transitive_imports + ] + outs = [] + proto_root = get_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] - if ctx.attr.generate_mocks: - outs += [proto.path[label_len:-len(".proto")] + "_mock.grpc.pb.h" for proto in protos] - else: - 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 + proto_root) - - arguments = [] - if ctx.executable.plugin: - arguments += ["--plugin=protoc-gen-PLUGIN=" + ctx.executable.plugin.path] - flags = list(ctx.attr.flags) - if ctx.attr.generate_mocks: - flags.append("generate_mock_code=true") - arguments += ["--PLUGIN_out=" + ",".join(flags) + ":" + dir_out] - additional_input = [ctx.executable.plugin] - else: - arguments += ["--cpp_out=" + ",".join(ctx.attr.flags) + ":" + dir_out] - additional_input = [] - - # 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]] + label_package = _join_directories([ctx.label.workspace_root, ctx.label.package]) + if ctx.executable.plugin: + outs += [ + proto_path_to_generated_filename( + _strip_package_from_path(label_package, proto), + _GRPC_PROTO_HEADER_FMT, + ) + for proto in protos + ] + outs += [ + proto_path_to_generated_filename( + _strip_package_from_path(label_package, proto), + _GRPC_PROTO_SRC_FMT, + ) + for proto in protos + ] + if ctx.attr.generate_mocks: + outs += [ + proto_path_to_generated_filename( + _strip_package_from_path(label_package, proto), + _GRPC_PROTO_MOCK_HEADER_FMT, + ) + for proto in protos + ] 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] + outs += [ + proto_path_to_generated_filename( + _strip_package_from_path(label_package, proto), + _PROTO_HEADER_FMT, + ) + for proto in protos + ] + outs += [ + proto_path_to_generated_filename( + _strip_package_from_path(label_package, proto), + _PROTO_SRC_FMT, + ) + for proto in protos + ] + out_files = [ctx.actions.declare_file(out) for out in outs] + dir_out = str(ctx.genfiles_dir.path + proto_root) - # create a list of well known proto files if the argument is non-None - well_known_proto_files = [] - if ctx.attr.well_known_protos: - f = ctx.attr.well_known_protos.files.to_list()[0].dirname - if f != "external/com_google_protobuf/src/google/protobuf": - print("Error: Only @com_google_protobuf//:well_known_protos is supported") + arguments = [] + if ctx.executable.plugin: + arguments += get_plugin_args( + ctx.executable.plugin, + ctx.attr.flags, + dir_out, + ctx.attr.generate_mocks, + ) + tools = [ctx.executable.plugin] else: - # f points to "external/com_google_protobuf/src/google/protobuf" - # add -I argument to protoc so it knows where to look for the proto files. - arguments += ["-I{0}".format(f + "/../..")] - well_known_proto_files = [f for f in ctx.attr.well_known_protos.files] + arguments += ["--cpp_out=" + ",".join(ctx.attr.flags) + ":" + dir_out] + tools = [] - ctx.action( - inputs = protos + includes + additional_input + well_known_proto_files, - outputs = out_files, - executable = ctx.executable._protoc, - arguments = arguments, - ) + arguments += get_include_protoc_args(includes) - return struct(files=depset(out_files)) + # 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 += [_get_srcs_file_path(proto) for proto in protos] + + # create a list of well known proto files if the argument is non-None + well_known_proto_files = [] + if ctx.attr.well_known_protos: + f = ctx.attr.well_known_protos.files.to_list()[0].dirname + if f != "external/com_google_protobuf/src/google/protobuf": + print( + "Error: Only @com_google_protobuf//:well_known_protos is supported", + ) + else: + # f points to "external/com_google_protobuf/src/google/protobuf" + # add -I argument to protoc so it knows where to look for the proto files. + arguments += ["-I{0}".format(f + "/../..")] + well_known_proto_files = [ + f + for f in ctx.attr.well_known_protos.files + ] + + ctx.actions.run( + inputs = protos + includes + well_known_proto_files, + tools = tools, + outputs = out_files, + executable = ctx.executable._protoc, + arguments = arguments, + ) + + return struct(files = depset(out_files)) _generate_cc = rule( attrs = { "srcs": attr.label_list( mandatory = True, - non_empty = True, + allow_empty = False, providers = ["proto"], ), "plugin": attr.label( @@ -95,10 +157,8 @@ _generate_cc = rule( mandatory = False, allow_empty = True, ), - "well_known_protos" : attr.label( - mandatory = False, - ), - "generate_mocks" : attr.bool( + "well_known_protos": attr.label(mandatory = False), + "generate_mocks": attr.bool( default = False, mandatory = False, ), @@ -114,7 +174,10 @@ _generate_cc = rule( ) def generate_cc(well_known_protos, **kwargs): - if well_known_protos: - _generate_cc(well_known_protos="@com_google_protobuf//:well_known_protos", **kwargs) - else: - _generate_cc(**kwargs) + if well_known_protos: + _generate_cc( + well_known_protos = "@com_google_protobuf//:well_known_protos", + **kwargs + ) + else: + _generate_cc(**kwargs) diff --git a/bazel/grpc_build_system.bzl b/bazel/grpc_build_system.bzl index 159ebd5d1fe..5f8477d7325 100644 --- a/bazel/grpc_build_system.bzl +++ b/bazel/grpc_build_system.bzl @@ -23,8 +23,10 @@ # each change must be ported from one to the other. # +load("//bazel:cc_grpc_library.bzl", "cc_grpc_library") + # The set of pollers to test against if a test exercises polling -POLLERS = ["epollex", "epoll1", "poll", "poll-cv"] +POLLERS = ["epollex", "epoll1", "poll"] def if_not_windows(a): return select({ @@ -33,6 +35,12 @@ def if_not_windows(a): "//conditions:default": a, }) +def if_mac(a): + return select({ + "//:mac_x86_64": a, + "//conditions:default": [], + }) + def _get_external_deps(external_deps): ret = [] for dep in external_deps: @@ -71,10 +79,17 @@ def grpc_cc_library( testonly = False, visibility = None, alwayslink = 0, - data = []): + data = [], + use_cfstream = False, + tags = []): copts = [] + if use_cfstream: + copts = if_mac(["-DGRPC_CFSTREAM"]) if language.upper() == "C": - copts = if_not_windows(["-std=c99"]) + copts = copts + if_not_windows(["-std=c99"]) + linkopts = if_not_windows(["-pthread"]) + if use_cfstream: + linkopts = linkopts + if_mac(["-framework CoreFoundation"]) native.cc_library( name = name, srcs = srcs, @@ -96,12 +111,11 @@ def grpc_cc_library( copts = copts, visibility = visibility, testonly = testonly, - linkopts = if_not_windows(["-pthread"]), - includes = [ - "include", - ], + linkopts = linkopts, + includes = ["include"] + if_not_windows(["src/core/ext/upb-generated"]), alwayslink = alwayslink, data = data, + tags = tags, ) def grpc_proto_plugin(name, srcs = [], deps = []): @@ -111,8 +125,6 @@ def grpc_proto_plugin(name, srcs = [], deps = []): deps = deps, ) -load("//:bazel/cc_grpc_library.bzl", "cc_grpc_library") - def grpc_proto_library( name, srcs = [], @@ -131,12 +143,11 @@ def grpc_proto_library( generate_mocks = generate_mocks, ) -def grpc_cc_test(name, srcs = [], deps = [], external_deps = [], args = [], data = [], uses_polling = True, language = "C++", size = "medium", timeout = "moderate", tags = []): - copts = [] +def grpc_cc_test(name, srcs = [], deps = [], external_deps = [], args = [], data = [], uses_polling = True, language = "C++", size = "medium", timeout = None, tags = [], exec_compatible_with = []): + copts = if_mac(["-DGRPC_CFSTREAM"]) if language.upper() == "C": - copts = if_not_windows(["-std=c99"]) + copts = copts + if_not_windows(["-std=c99"]) args = { - "name": name, "srcs": srcs, "args": args, "data": data, @@ -145,9 +156,20 @@ def grpc_cc_test(name, srcs = [], deps = [], external_deps = [], args = [], data "linkopts": if_not_windows(["-pthread"]), "size": size, "timeout": timeout, + "exec_compatible_with": exec_compatible_with, } if uses_polling: - native.cc_test(testonly = True, tags = ["manual"], **args) + # Only run targets with pollers for non-MSVC + # TODO(yfen): Enable MSVC for poller-enabled targets without pollers + native.cc_test( + name = name, + testonly = True, + tags = [ + "manual", + "no_windows", + ], + **args + ) for poller in POLLERS: native.sh_test( name = name + "@poller=" + poller, @@ -161,12 +183,13 @@ def grpc_cc_test(name, srcs = [], deps = [], external_deps = [], args = [], data poller, "$(location %s)" % name, ] + args["args"], - tags = tags, + tags = (tags + ["no_windows"]), + exec_compatible_with = exec_compatible_with, ) else: - native.cc_test(**args) + native.cc_test(tags = tags, **args) -def grpc_cc_binary(name, srcs = [], deps = [], external_deps = [], args = [], data = [], language = "C++", testonly = False, linkshared = False, linkopts = []): +def grpc_cc_binary(name, srcs = [], deps = [], external_deps = [], args = [], data = [], language = "C++", testonly = False, linkshared = False, linkopts = [], tags = []): copts = [] if language.upper() == "C": copts = ["-std=c99"] @@ -180,6 +203,7 @@ def grpc_cc_binary(name, srcs = [], deps = [], external_deps = [], args = [], da deps = deps + _get_external_deps(external_deps), copts = copts, linkopts = if_not_windows(["-pthread"]) + linkopts, + tags = tags, ) def grpc_generate_one_off_targets(): diff --git a/bazel/grpc_deps.bzl b/bazel/grpc_deps.bzl index 86268178554..a4e6509782d 100644 --- a/bazel/grpc_deps.bzl +++ b/bazel/grpc_deps.bzl @@ -1,5 +1,8 @@ """Load dependencies needed to compile and test the grpc library as a 3rd-party consumer.""" +load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository") +load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") + def grpc_deps(): """Loads dependencies need to compile and test the grpc library.""" @@ -8,6 +11,11 @@ def grpc_deps(): actual = "@com_github_nanopb_nanopb//:nanopb", ) + native.bind( + name = "upb_lib", + actual = "@upb//:upb", + ) + native.bind( name = "absl-base", actual = "@com_google_absl//absl/base", @@ -85,105 +93,130 @@ def grpc_deps(): native.bind( name = "opencensus-trace", - actual = "@io_opencensus_cpp//opencensus/trace:trace" + actual = "@io_opencensus_cpp//opencensus/trace:trace", ) native.bind( name = "opencensus-stats", - actual = "@io_opencensus_cpp//opencensus/stats:stats" + actual = "@io_opencensus_cpp//opencensus/stats:stats", ) native.bind( name = "opencensus-stats-test", - actual = "@io_opencensus_cpp//opencensus/stats:test_utils" + actual = "@io_opencensus_cpp//opencensus/stats:test_utils", ) if "boringssl" not in native.existing_rules(): - native.http_archive( + http_archive( name = "boringssl", # on the chromium-stable-with-bazel branch + # NOTE: This URL generates a tarball containing dynamic date + # information, so the sha256 is not consistent. url = "https://boringssl.googlesource.com/boringssl/+archive/afc30d43eef92979b05776ec0963c9cede5fb80f.tar.gz", ) if "com_github_madler_zlib" not in native.existing_rules(): - native.new_http_archive( + http_archive( name = "com_github_madler_zlib", build_file = "@com_github_grpc_grpc//third_party:zlib.BUILD", + sha256 = "6d4d6640ca3121620995ee255945161821218752b551a1a180f4215f7d124d45", strip_prefix = "zlib-cacf7f1d4e3d44d871b605da3b647f07d718623f", url = "https://github.com/madler/zlib/archive/cacf7f1d4e3d44d871b605da3b647f07d718623f.tar.gz", ) if "com_google_protobuf" not in native.existing_rules(): - native.http_archive( + http_archive( name = "com_google_protobuf", - strip_prefix = "protobuf-48cb18e5c419ddd23d9badcfe4e9df7bde1979b2", - url = "https://github.com/google/protobuf/archive/48cb18e5c419ddd23d9badcfe4e9df7bde1979b2.tar.gz", + sha256 = "cf9e2fb1d2cd30ec9d51ff1749045208bd641f290f64b85046485934b0e03783", + strip_prefix = "protobuf-582743bf40c5d3639a70f98f183914a2c0cd0680", + url = "https://github.com/google/protobuf/archive/582743bf40c5d3639a70f98f183914a2c0cd0680.tar.gz", ) if "com_github_nanopb_nanopb" not in native.existing_rules(): - native.new_http_archive( + http_archive( name = "com_github_nanopb_nanopb", build_file = "@com_github_grpc_grpc//third_party:nanopb.BUILD", + sha256 = "8bbbb1e78d4ddb0a1919276924ab10d11b631df48b657d960e0c795a25515735", strip_prefix = "nanopb-f8ac463766281625ad710900479130c7fcb4d63b", url = "https://github.com/nanopb/nanopb/archive/f8ac463766281625ad710900479130c7fcb4d63b.tar.gz", ) if "com_github_google_googletest" not in native.existing_rules(): - native.new_http_archive( + http_archive( name = "com_github_google_googletest", build_file = "@com_github_grpc_grpc//third_party:gtest.BUILD", + sha256 = "175a22300b3450e27e5f2e6f95cc9abca74617cbc21a1e0ed19bdfbd22ea0305", strip_prefix = "googletest-ec44c6c1675c25b9827aacd08c02433cccde7780", url = "https://github.com/google/googletest/archive/ec44c6c1675c25b9827aacd08c02433cccde7780.tar.gz", ) if "com_github_gflags_gflags" not in native.existing_rules(): - native.http_archive( + http_archive( name = "com_github_gflags_gflags", - strip_prefix = "gflags-30dbc81fb5ffdc98ea9b14b1918bfe4e8779b26e", - url = "https://github.com/gflags/gflags/archive/30dbc81fb5ffdc98ea9b14b1918bfe4e8779b26e.tar.gz", + sha256 = "63ae70ea3e05780f7547d03503a53de3a7d2d83ad1caaa443a31cb20aea28654", + strip_prefix = "gflags-28f50e0fed19872e0fd50dd23ce2ee8cd759338e", + url = "https://github.com/gflags/gflags/archive/28f50e0fed19872e0fd50dd23ce2ee8cd759338e.tar.gz", ) if "com_github_google_benchmark" not in native.existing_rules(): - native.new_http_archive( + http_archive( name = "com_github_google_benchmark", - build_file = "@com_github_grpc_grpc//third_party:benchmark.BUILD", - strip_prefix = "benchmark-9913418d323e64a0111ca0da81388260c2bbe1e9", - url = "https://github.com/google/benchmark/archive/9913418d323e64a0111ca0da81388260c2bbe1e9.tar.gz", + sha256 = "c7682e9007ddfd94072647abab3e89ffd9084089460ae47d67060974467b58bf", + strip_prefix = "benchmark-e776aa0275e293707b6a0901e0e8d8a8a3679508", + url = "https://github.com/google/benchmark/archive/e776aa0275e293707b6a0901e0e8d8a8a3679508.tar.gz", ) if "com_github_cares_cares" not in native.existing_rules(): - native.new_http_archive( + http_archive( name = "com_github_cares_cares", build_file = "@com_github_grpc_grpc//third_party:cares/cares.BUILD", - strip_prefix = "c-ares-3be1924221e1326df520f8498d704a5c4c8d0cce", - url = "https://github.com/c-ares/c-ares/archive/3be1924221e1326df520f8498d704a5c4c8d0cce.tar.gz", + sha256 = "e8c2751ddc70fed9dc6f999acd92e232d5846f009ee1674f8aee81f19b2b915a", + strip_prefix = "c-ares-e982924acee7f7313b4baa4ee5ec000c5e373c30", + url = "https://github.com/c-ares/c-ares/archive/e982924acee7f7313b4baa4ee5ec000c5e373c30.tar.gz", ) if "com_google_absl" not in native.existing_rules(): - native.http_archive( + http_archive( name = "com_google_absl", - strip_prefix = "abseil-cpp-cd95e71df6eaf8f2a282b1da556c2cf1c9b09207", - url = "https://github.com/abseil/abseil-cpp/archive/cd95e71df6eaf8f2a282b1da556c2cf1c9b09207.tar.gz", + sha256 = "5fe2a3a8f8378e81d4d3db6541f48030e04233ccd2d6c7e9d981ed577b314ae8", + strip_prefix = "abseil-cpp-308ce31528a7edfa39f5f6d36142278a0ae1bf45", + url = "https://github.com/abseil/abseil-cpp/archive/308ce31528a7edfa39f5f6d36142278a0ae1bf45.tar.gz", ) - if "com_github_bazelbuild_bazeltoolchains" not in native.existing_rules(): - native.http_archive( - name = "com_github_bazelbuild_bazeltoolchains", - strip_prefix = "bazel-toolchains-280edaa6f93623074513d2b426068de42e62ea4d", + if "bazel_toolchains" not in native.existing_rules(): + http_archive( + name = "bazel_toolchains", + sha256 = "67335b3563d9b67dc2550b8f27cc689b64fadac491e69ce78763d9ba894cc5cc", + strip_prefix = "bazel-toolchains-cddc376d428ada2927ad359211c3e356bd9c9fbb", urls = [ - "https://mirror.bazel.build/github.com/bazelbuild/bazel-toolchains/archive/280edaa6f93623074513d2b426068de42e62ea4d.tar.gz", - "https://github.com/bazelbuild/bazel-toolchains/archive/280edaa6f93623074513d2b426068de42e62ea4d.tar.gz", + "https://mirror.bazel.build/github.com/bazelbuild/bazel-toolchains/archive/cddc376d428ada2927ad359211c3e356bd9c9fbb.tar.gz", + "https://github.com/bazelbuild/bazel-toolchains/archive/cddc376d428ada2927ad359211c3e356bd9c9fbb.tar.gz", ], - sha256 = "50c9df51f80cdf9ff8f2bc27620c155526b9ba67be95e8a686f32ff8898a06e2", + ) + + if "bazel_skylib" not in native.existing_rules(): + http_archive( + name = "bazel_skylib", + sha256 = "ba5d15ca230efca96320085d8e4d58da826d1f81b444ef8afccd8b23e0799b52", + strip_prefix = "bazel-skylib-f83cb8dd6f5658bc574ccd873e25197055265d1c", + url = "https://github.com/bazelbuild/bazel-skylib/archive/f83cb8dd6f5658bc574ccd873e25197055265d1c.tar.gz", ) if "io_opencensus_cpp" not in native.existing_rules(): - native.http_archive( + http_archive( name = "io_opencensus_cpp", - strip_prefix = "opencensus-cpp-fdf0f308b1631bb4a942e32ba5d22536a6170274", - url = "https://github.com/census-instrumentation/opencensus-cpp/archive/fdf0f308b1631bb4a942e32ba5d22536a6170274.tar.gz", + sha256 = "3436ca23dc1b3345186defd0f46d64244079ba3d3234a0c5d6ef5e8d5d06c8b5", + strip_prefix = "opencensus-cpp-9b1e354e89bf3d92aedc00af45b418ce870f3d77", + url = "https://github.com/census-instrumentation/opencensus-cpp/archive/9b1e354e89bf3d92aedc00af45b418ce870f3d77.tar.gz", ) + if "upb" not in native.existing_rules(): + http_archive( + name = "upb", + sha256 = "0e749a8973968397f849a3b42e28ee9c85dc418c2477954c2a6a4495f323241d", + strip_prefix = "upb-ed9faae0993704b033c594b072d65e1bf19207fa", + url = "https://github.com/google/upb/archive/ed9faae0993704b033c594b072d65e1bf19207fa.tar.gz", + ) # TODO: move some dependencies from "grpc_deps" here? def grpc_test_only_deps(): @@ -200,40 +233,45 @@ def grpc_test_only_deps(): ) if "com_github_twisted_twisted" not in native.existing_rules(): - native.new_http_archive( + http_archive( name = "com_github_twisted_twisted", + sha256 = "ca17699d0d62eafc5c28daf2c7d0a18e62ae77b4137300b6c7d7868b39b06139", strip_prefix = "twisted-twisted-17.5.0", url = "https://github.com/twisted/twisted/archive/twisted-17.5.0.zip", build_file = "@com_github_grpc_grpc//third_party:twisted.BUILD", ) if "com_github_yaml_pyyaml" not in native.existing_rules(): - native.new_http_archive( + http_archive( name = "com_github_yaml_pyyaml", + sha256 = "6b4314b1b2051ddb9d4fcd1634e1fa9c1bb4012954273c9ff3ef689f6ec6c93e", strip_prefix = "pyyaml-3.12", url = "https://github.com/yaml/pyyaml/archive/3.12.zip", build_file = "@com_github_grpc_grpc//third_party:yaml.BUILD", ) if "com_github_twisted_incremental" not in native.existing_rules(): - native.new_http_archive( + http_archive( name = "com_github_twisted_incremental", + sha256 = "f0ca93359ee70243ff7fbf2d904a6291810bd88cb80ed4aca6fa77f318a41a36", strip_prefix = "incremental-incremental-17.5.0", url = "https://github.com/twisted/incremental/archive/incremental-17.5.0.zip", build_file = "@com_github_grpc_grpc//third_party:incremental.BUILD", ) if "com_github_zopefoundation_zope_interface" not in native.existing_rules(): - native.new_http_archive( + http_archive( name = "com_github_zopefoundation_zope_interface", + sha256 = "e9579fc6149294339897be3aa9ecd8a29217c0b013fe6f44fcdae00e3204198a", strip_prefix = "zope.interface-4.4.3", url = "https://github.com/zopefoundation/zope.interface/archive/4.4.3.zip", build_file = "@com_github_grpc_grpc//third_party:zope_interface.BUILD", ) if "com_github_twisted_constantly" not in native.existing_rules(): - native.new_http_archive( + http_archive( name = "com_github_twisted_constantly", + sha256 = "2702cd322161a579d2c0dbf94af4e57712eedc7bd7bbbdc554a230544f7d346c", strip_prefix = "constantly-15.1.0", url = "https://github.com/twisted/constantly/archive/15.1.0.zip", build_file = "@com_github_grpc_grpc//third_party:constantly.BUILD", diff --git a/bazel/grpc_python_deps.bzl b/bazel/grpc_python_deps.bzl new file mode 100644 index 00000000000..91438f3927b --- /dev/null +++ b/bazel/grpc_python_deps.bzl @@ -0,0 +1,8 @@ +load("//third_party/py:python_configure.bzl", "python_configure") +load("@io_bazel_rules_python//python:pip.bzl", "pip_repositories") +load("@grpc_python_dependencies//:requirements.bzl", "pip_install") + +def grpc_python_deps(): + python_configure(name = "local_config_python") + pip_repositories() + pip_install() diff --git a/bazel/protobuf.bzl b/bazel/protobuf.bzl new file mode 100644 index 00000000000..f2df7bd87b2 --- /dev/null +++ b/bazel/protobuf.bzl @@ -0,0 +1,104 @@ +"""Utility functions for generating protobuf code.""" + +_PROTO_EXTENSION = ".proto" + +def well_known_proto_libs(): + return [ + "@com_google_protobuf//:any_proto", + "@com_google_protobuf//:api_proto", + "@com_google_protobuf//:compiler_plugin_proto", + "@com_google_protobuf//:descriptor_proto", + "@com_google_protobuf//:duration_proto", + "@com_google_protobuf//:empty_proto", + "@com_google_protobuf//:field_mask_proto", + "@com_google_protobuf//:source_context_proto", + "@com_google_protobuf//:struct_proto", + "@com_google_protobuf//:timestamp_proto", + "@com_google_protobuf//:type_proto", + "@com_google_protobuf//:wrappers_proto", + ] + +def get_proto_root(workspace_root): + """Gets the root protobuf directory. + + Args: + workspace_root: context.label.workspace_root + + Returns: + The directory relative to which generated include paths should be. + """ + if workspace_root: + return "/{}".format(workspace_root) + else: + return "" + +def _strip_proto_extension(proto_filename): + if not proto_filename.endswith(_PROTO_EXTENSION): + fail('"{}" does not end with "{}"'.format( + proto_filename, + _PROTO_EXTENSION, + )) + return proto_filename[:-len(_PROTO_EXTENSION)] + +def proto_path_to_generated_filename(proto_path, fmt_str): + """Calculates the name of a generated file for a protobuf path. + + For example, "examples/protos/helloworld.proto" might map to + "helloworld.pb.h". + + Args: + proto_path: The path to the .proto file. + fmt_str: A format string used to calculate the generated filename. For + example, "{}.pb.h" might be used to calculate a C++ header filename. + + Returns: + The generated filename. + """ + return fmt_str.format(_strip_proto_extension(proto_path)) + +def _get_include_directory(include): + directory = include.path + prefix_len = 0 + if not include.is_source and directory.startswith(include.root.path): + prefix_len = len(include.root.path) + 1 + + if directory.startswith("external", prefix_len): + external_separator = directory.find("/", prefix_len) + repository_separator = directory.find("/", external_separator + 1) + return directory[:repository_separator] + else: + return include.root.path if include.root.path else "." + +def get_include_protoc_args(includes): + """Returns protoc args that imports protos relative to their import root. + + Args: + includes: A list of included proto files. + + Returns: + A list of arguments to be passed to protoc. For example, ["--proto_path=."]. + """ + return [ + "--proto_path={}".format(_get_include_directory(include)) + for include in includes + ] + +def get_plugin_args(plugin, flags, dir_out, generate_mocks): + """Returns arguments configuring protoc to use a plugin for a language. + + Args: + plugin: An executable file to run as the protoc plugin. + flags: The plugin flags to be passed to protoc. + dir_out: The output directory for the plugin. + generate_mocks: A bool indicating whether to generate mocks. + + Returns: + A list of protoc arguments configuring the plugin. + """ + augmented_flags = list(flags) + if generate_mocks: + augmented_flags.append("generate_mock_code=true") + return [ + "--plugin=protoc-gen-PLUGIN=" + plugin.path, + "--PLUGIN_out=" + ",".join(augmented_flags) + ":" + dir_out, + ] diff --git a/bazel/python_rules.bzl b/bazel/python_rules.bzl new file mode 100644 index 00000000000..2f3b38af002 --- /dev/null +++ b/bazel/python_rules.bzl @@ -0,0 +1,186 @@ +"""Generates and compiles Python gRPC stubs from proto_library rules.""" + +load("@grpc_python_dependencies//:requirements.bzl", "requirement") +load( + "//bazel:protobuf.bzl", + "get_include_protoc_args", + "get_plugin_args", + "get_proto_root", + "proto_path_to_generated_filename", +) + +_GENERATED_PROTO_FORMAT = "{}_pb2.py" +_GENERATED_GRPC_PROTO_FORMAT = "{}_pb2_grpc.py" + +def _get_staged_proto_file(context, source_file): + if source_file.dirname == context.label.package: + return source_file + else: + copied_proto = context.actions.declare_file(source_file.basename) + context.actions.run_shell( + inputs = [source_file], + outputs = [copied_proto], + command = "cp {} {}".format(source_file.path, copied_proto.path), + mnemonic = "CopySourceProto", + ) + return copied_proto + +def _generate_py_impl(context): + protos = [] + for src in context.attr.deps: + for file in src.proto.direct_sources: + protos.append(_get_staged_proto_file(context, file)) + includes = [ + file + for src in context.attr.deps + for file in src.proto.transitive_imports + ] + proto_root = get_proto_root(context.label.workspace_root) + format_str = (_GENERATED_GRPC_PROTO_FORMAT if context.executable.plugin else _GENERATED_PROTO_FORMAT) + out_files = [ + context.actions.declare_file( + proto_path_to_generated_filename( + proto.basename, + format_str, + ), + ) + for proto in protos + ] + + arguments = [] + tools = [context.executable._protoc] + if context.executable.plugin: + arguments += get_plugin_args( + context.executable.plugin, + context.attr.flags, + context.genfiles_dir.path, + False, + ) + tools += [context.executable.plugin] + else: + arguments += [ + "--python_out={}:{}".format( + ",".join(context.attr.flags), + context.genfiles_dir.path, + ), + ] + + arguments += get_include_protoc_args(includes) + arguments += [ + "--proto_path={}".format(context.genfiles_dir.path) + for proto in protos + ] + for proto in protos: + massaged_path = proto.path + if massaged_path.startswith(context.genfiles_dir.path): + massaged_path = proto.path[len(context.genfiles_dir.path) + 1:] + arguments.append(massaged_path) + + well_known_proto_files = [] + if context.attr.well_known_protos: + well_known_proto_directory = context.attr.well_known_protos.files.to_list( + )[0].dirname + + arguments += ["-I{}".format(well_known_proto_directory + "/../..")] + well_known_proto_files = context.attr.well_known_protos.files.to_list() + + context.actions.run( + inputs = protos + includes + well_known_proto_files, + tools = tools, + outputs = out_files, + executable = context.executable._protoc, + arguments = arguments, + mnemonic = "ProtocInvocation", + ) + return struct(files = depset(out_files)) + +__generate_py = rule( + attrs = { + "deps": attr.label_list( + mandatory = True, + allow_empty = False, + providers = ["proto"], + ), + "plugin": attr.label( + executable = True, + providers = ["files_to_run"], + cfg = "host", + ), + "flags": attr.string_list( + mandatory = False, + allow_empty = True, + ), + "well_known_protos": attr.label(mandatory = False), + "_protoc": attr.label( + default = Label("//external:protocol_compiler"), + executable = True, + cfg = "host", + ), + }, + output_to_genfiles = True, + implementation = _generate_py_impl, +) + +def _generate_py(well_known_protos, **kwargs): + if well_known_protos: + __generate_py( + well_known_protos = "@com_google_protobuf//:well_known_protos", + **kwargs + ) + else: + __generate_py(**kwargs) + +def py_proto_library( + name, + deps, + well_known_protos = True, + proto_only = False, + **kwargs): + """Generate python code for a protobuf. + + Args: + name: The name of the target. + deps: A list of dependencies. Must contain a single element. + well_known_protos: A bool indicating whether or not to include well-known + protos. + proto_only: A bool indicating whether to generate vanilla protobuf code + or to also generate gRPC code. + """ + if len(deps) > 1: + fail("The supported length of 'deps' is 1.") + + codegen_target = "_{}_codegen".format(name) + codegen_grpc_target = "_{}_grpc_codegen".format(name) + + _generate_py( + name = codegen_target, + deps = deps, + well_known_protos = well_known_protos, + **kwargs + ) + + if not proto_only: + _generate_py( + name = codegen_grpc_target, + deps = deps, + plugin = "//:grpc_python_plugin", + well_known_protos = well_known_protos, + **kwargs + ) + + native.py_library( + name = name, + srcs = [ + ":{}".format(codegen_grpc_target), + ":{}".format(codegen_target), + ], + deps = [requirement("protobuf")], + **kwargs + ) + else: + native.py_library( + name = name, + srcs = [":{}".format(codegen_target), ":{}".format(codegen_target)], + deps = [requirement("protobuf")], + **kwargs + ) diff --git a/build.yaml b/build.yaml index 09acdbe6f17..65abbc469e6 100644 --- a/build.yaml +++ b/build.yaml @@ -12,9 +12,9 @@ settings: '#08': Use "-preN" suffixes to identify pre-release versions '#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: 7.0.0-dev - g_stands_for: gizmo - version: 1.17.0-dev + core_version: 7.0.0 + g_stands_for: gale + version: 1.22.0-dev filegroups: - name: alts_proto headers: @@ -114,7 +114,6 @@ filegroups: - name: gpr_base src: - 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 @@ -147,7 +146,9 @@ filegroups: - 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/arena.cc - src/core/lib/gprpp/fork.cc + - src/core/lib/gprpp/global_config_env.cc - src/core/lib/gprpp/thd_posix.cc - src/core/lib/gprpp/thd_windows.cc - src/core/lib/profiling/basic_timers.cc @@ -191,13 +192,18 @@ filegroups: - src/core/lib/gpr/tmpfile.h - src/core/lib/gpr/useful.h - src/core/lib/gprpp/abstract.h + - src/core/lib/gprpp/arena.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/fork.h + - src/core/lib/gprpp/global_config.h + - src/core/lib/gprpp/global_config_custom.h + - src/core/lib/gprpp/global_config_env.h + - src/core/lib/gprpp/global_config_generic.h - src/core/lib/gprpp/manual_constructor.h + - src/core/lib/gprpp/map.h - src/core/lib/gprpp/memory.h - - src/core/lib/gprpp/mutex_lock.h + - src/core/lib/gprpp/pair.h + - src/core/lib/gprpp/sync.h - src/core/lib/gprpp/thd.h - src/core/lib/profiling/timers.h uses: @@ -242,10 +248,10 @@ filegroups: - src/core/lib/channel/channelz_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_args.cc - src/core/lib/compression/compression_internal.cc - src/core/lib/compression/message_compress.cc - src/core/lib/compression/stream_compression.cc @@ -258,12 +264,15 @@ filegroups: - src/core/lib/http/parser.cc - src/core/lib/iomgr/buffer_list.cc - src/core/lib/iomgr/call_combiner.cc + - src/core/lib/iomgr/cfstream_handle.cc - src/core/lib/iomgr/combiner.cc - src/core/lib/iomgr/endpoint.cc + - src/core/lib/iomgr/endpoint_cfstream.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/error_cfstream.cc - src/core/lib/iomgr/ev_epoll1_linux.cc - src/core/lib/iomgr/ev_epollex_linux.cc - src/core/lib/iomgr/ev_poll_posix.cc @@ -276,18 +285,20 @@ filegroups: - 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/grpc_if_nametoindex_posix.cc + - src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc - src/core/lib/iomgr/internal_errqueue.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_posix_cfstream.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 @@ -311,6 +322,7 @@ filegroups: - 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_cfstream.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 @@ -335,7 +347,6 @@ filegroups: - 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 @@ -375,7 +386,6 @@ filegroups: - 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 @@ -420,6 +430,7 @@ filegroups: - 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_args.h - src/core/lib/compression/compression_internal.h - src/core/lib/compression/message_compress.h - src/core/lib/compression/stream_compression.h @@ -429,6 +440,7 @@ filegroups: - 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/optional.h - src/core/lib/gprpp/orphanable.h - src/core/lib/gprpp/ref_counted.h - src/core/lib/gprpp/ref_counted_ptr.h @@ -438,11 +450,15 @@ filegroups: - src/core/lib/iomgr/block_annotate.h - src/core/lib/iomgr/buffer_list.h - src/core/lib/iomgr/call_combiner.h + - src/core/lib/iomgr/cfstream_handle.h - src/core/lib/iomgr/closure.h - src/core/lib/iomgr/combiner.h + - src/core/lib/iomgr/dynamic_annotations.h - src/core/lib/iomgr/endpoint.h + - src/core/lib/iomgr/endpoint_cfstream.h - src/core/lib/iomgr/endpoint_pair.h - src/core/lib/iomgr/error.h + - src/core/lib/iomgr/error_cfstream.h - src/core/lib/iomgr/error_internal.h - src/core/lib/iomgr/ev_epoll1_linux.h - src/core/lib/iomgr/ev_epollex_linux.h @@ -451,6 +467,7 @@ filegroups: - src/core/lib/iomgr/exec_ctx.h - src/core/lib/iomgr/executor.h - src/core/lib/iomgr/gethostname.h + - src/core/lib/iomgr/grpc_if_nametoindex.h - src/core/lib/iomgr/internal_errqueue.h - src/core/lib/iomgr/iocp_windows.h - src/core/lib/iomgr/iomgr.h @@ -461,7 +478,6 @@ filegroups: - 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 @@ -498,7 +514,6 @@ filegroups: - 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 @@ -510,6 +525,7 @@ filegroups: - 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_utils.h - src/core/lib/slice/slice_weak_hash_table.h - src/core/lib/surface/api_trace.h - src/core/lib/surface/call.h @@ -532,7 +548,6 @@ filegroups: - 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 @@ -545,20 +560,6 @@ filegroups: uses: - grpc_codegen - grpc_trace_headers -- name: grpc_cfstream - headers: - - src/core/lib/iomgr/cfstream_handle.h - - src/core/lib/iomgr/endpoint_cfstream.h - - src/core/lib/iomgr/error_cfstream.h - src: - - src/core/lib/iomgr/cfstream_handle.cc - - src/core/lib/iomgr/endpoint_cfstream.cc - - src/core/lib/iomgr/error_cfstream.cc - - src/core/lib/iomgr/iomgr_posix_cfstream.cc - - src/core/lib/iomgr/tcp_client_cfstream.cc - uses: - - grpc_base_headers - - gpr_base_headers - name: grpc_client_authority_filter headers: - src/core/ext/filters/http/client_authority_filter.h @@ -574,12 +575,14 @@ filegroups: - src/core/ext/filters/client_channel/client_channel_channelz.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/global_subchannel_pool.h - src/core/ext/filters/client_channel/health/health_check_client.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/local_subchannel_pool.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 @@ -587,9 +590,12 @@ filegroups: - src/core/ext/filters/client_channel/resolver_factory.h - src/core/ext/filters/client_channel/resolver_registry.h - src/core/ext/filters/client_channel/resolver_result_parsing.h + - src/core/ext/filters/client_channel/resolving_lb_policy.h - src/core/ext/filters/client_channel/retry_throttle.h + - src/core/ext/filters/client_channel/server_address.h + - src/core/ext/filters/client_channel/service_config.h - src/core/ext/filters/client_channel/subchannel.h - - src/core/ext/filters/client_channel/subchannel_index.h + - src/core/ext/filters/client_channel/subchannel_pool_interface.h src: - src/core/ext/filters/client_channel/backup_poller.cc - src/core/ext/filters/client_channel/channel_connectivity.cc @@ -598,21 +604,25 @@ filegroups: - 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/global_subchannel_pool.cc - src/core/ext/filters/client_channel/health/health_check_client.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/local_subchannel_pool.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/resolver_result_parsing.cc + - src/core/ext/filters/client_channel/resolving_lb_policy.cc - src/core/ext/filters/client_channel/retry_throttle.cc + - src/core/ext/filters/client_channel/server_address.cc + - src/core/ext/filters/client_channel/service_config.cc - src/core/ext/filters/client_channel/subchannel.cc - - src/core/ext/filters/client_channel/subchannel_index.cc + - src/core/ext/filters/client_channel/subchannel_pool_interface.cc plugin: grpc_client_channel uses: - grpc_base @@ -771,13 +781,17 @@ filegroups: headers: - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h + - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h src: - 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.cc + - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc + - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc + - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc plugin: grpc_resolver_dns_ares @@ -827,6 +841,8 @@ filegroups: - 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/tls/grpc_tls_credentials_options.h + - src/core/lib/security/credentials/tls/spiffe_credentials.h - src/core/lib/security/security_connector/alts/alts_security_connector.h - src/core/lib/security/security_connector/fake/fake_security_connector.h - src/core/lib/security/security_connector/load_system_roots.h @@ -835,6 +851,7 @@ filegroups: - src/core/lib/security/security_connector/security_connector.h - src/core/lib/security/security_connector/ssl/ssl_security_connector.h - src/core/lib/security/security_connector/ssl_utils.h + - src/core/lib/security/security_connector/tls/spiffe_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 @@ -859,6 +876,8 @@ filegroups: - 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/tls/grpc_tls_credentials_options.cc + - src/core/lib/security/credentials/tls/spiffe_credentials.cc - src/core/lib/security/security_connector/alts/alts_security_connector.cc - src/core/lib/security/security_connector/fake/fake_security_connector.cc - src/core/lib/security/security_connector/load_system_roots_fallback.cc @@ -867,6 +886,7 @@ filegroups: - src/core/lib/security/security_connector/security_connector.cc - src/core/lib/security/security_connector/ssl/ssl_security_connector.cc - src/core/lib/security/security_connector/ssl_utils.cc + - src/core/lib/security/security_connector/tls/spiffe_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 @@ -898,6 +918,7 @@ filegroups: - src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h - test/core/end2end/cq_verifier.h - test/core/end2end/fixtures/http_proxy_fixture.h + - test/core/end2end/fixtures/local_util.h - test/core/end2end/fixtures/proxy.h - test/core/iomgr/endpoint_tests.h - test/core/util/debugger_macros.h @@ -912,12 +933,15 @@ filegroups: - test/core/util/port_server_client.h - test/core/util/slice_splitter.h - test/core/util/subprocess.h + - test/core/util/test_config.h + - test/core/util/test_lb_policies.h - test/core/util/tracer_util.h - test/core/util/trickle_endpoint.h src: - src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc - test/core/end2end/cq_verifier.cc - test/core/end2end/fixtures/http_proxy_fixture.cc + - test/core/end2end/fixtures/local_util.cc - test/core/end2end/fixtures/proxy.cc - test/core/iomgr/endpoint_tests.cc - test/core/util/debugger_macros.cc @@ -934,10 +958,11 @@ filegroups: - test/core/util/slice_splitter.cc - test/core/util/subprocess_posix.cc - test/core/util/subprocess_windows.cc + - test/core/util/test_config.cc + - test/core/util/test_lb_policies.cc - test/core/util/tracer_util.cc - test/core/util/trickle_endpoint.cc deps: - - gpr_test_util - gpr uses: - cmdline @@ -962,6 +987,7 @@ filegroups: - 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/context_list.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 @@ -984,6 +1010,7 @@ filegroups: - 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/context_list.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 @@ -1228,6 +1255,7 @@ filegroups: - include/grpcpp/impl/codegen/client_interceptor.h - include/grpcpp/impl/codegen/client_unary_call.h - include/grpcpp/impl/codegen/completion_queue.h + - include/grpcpp/impl/codegen/completion_queue_impl.h - include/grpcpp/impl/codegen/completion_queue_tag.h - include/grpcpp/impl/codegen/config.h - include/grpcpp/impl/codegen/core_codegen_interface.h @@ -1236,6 +1264,7 @@ filegroups: - include/grpcpp/impl/codegen/intercepted_channel.h - include/grpcpp/impl/codegen/interceptor.h - include/grpcpp/impl/codegen/interceptor_common.h + - include/grpcpp/impl/codegen/message_allocator.h - include/grpcpp/impl/codegen/metadata_map.h - include/grpcpp/impl/codegen/method_handler_impl.h - include/grpcpp/impl/codegen/rpc_method.h @@ -1256,6 +1285,7 @@ filegroups: - include/grpcpp/impl/codegen/time.h uses: - grpc_codegen + - grpc++_internal_hdrs_only - name: grpc++_codegen_base_src language: c++ src: @@ -1321,16 +1351,22 @@ filegroups: - include/grpc++/support/sync_stream.h - include/grpc++/support/time.h - include/grpcpp/alarm.h + - include/grpcpp/alarm_impl.h - include/grpcpp/channel.h + - include/grpcpp/channel_impl.h - include/grpcpp/client_context.h - include/grpcpp/completion_queue.h - include/grpcpp/create_channel.h + - include/grpcpp/create_channel_impl.h - include/grpcpp/create_channel_posix.h + - include/grpcpp/create_channel_posix_impl.h - include/grpcpp/ext/health_check_service_server_builder_option.h - include/grpcpp/generic/async_generic_service.h - include/grpcpp/generic/generic_stub.h + - include/grpcpp/generic/generic_stub_impl.h - include/grpcpp/grpcpp.h - include/grpcpp/health_check_service_interface.h + - include/grpcpp/health_check_service_interface_impl.h - include/grpcpp/impl/call.h - include/grpcpp/impl/channel_argument_option.h - include/grpcpp/impl/client_unary_call.h @@ -1341,27 +1377,41 @@ filegroups: - include/grpcpp/impl/rpc_service_method.h - include/grpcpp/impl/serialization_traits.h - include/grpcpp/impl/server_builder_option.h + - include/grpcpp/impl/server_builder_option_impl.h - include/grpcpp/impl/server_builder_plugin.h - include/grpcpp/impl/server_initializer.h + - include/grpcpp/impl/server_initializer_impl.h - include/grpcpp/impl/service_type.h - include/grpcpp/resource_quota.h + - include/grpcpp/resource_quota_impl.h - include/grpcpp/security/auth_context.h - include/grpcpp/security/auth_metadata_processor.h + - include/grpcpp/security/auth_metadata_processor_impl.h - include/grpcpp/security/credentials.h + - include/grpcpp/security/credentials_impl.h - include/grpcpp/security/server_credentials.h + - include/grpcpp/security/server_credentials_impl.h - include/grpcpp/server.h - include/grpcpp/server_builder.h + - include/grpcpp/server_builder_impl.h - include/grpcpp/server_context.h + - include/grpcpp/server_impl.h - include/grpcpp/server_posix.h + - include/grpcpp/server_posix_impl.h - include/grpcpp/support/async_stream.h - include/grpcpp/support/async_unary_call.h - include/grpcpp/support/byte_buffer.h - include/grpcpp/support/channel_arguments.h + - include/grpcpp/support/channel_arguments_impl.h - include/grpcpp/support/client_callback.h + - include/grpcpp/support/client_interceptor.h - include/grpcpp/support/config.h + - include/grpcpp/support/interceptor.h + - include/grpcpp/support/message_allocator.h - include/grpcpp/support/proto_buffer_reader.h - include/grpcpp/support/proto_buffer_writer.h - include/grpcpp/support/server_callback.h + - include/grpcpp/support/server_interceptor.h - include/grpcpp/support/slice.h - include/grpcpp/support/status.h - include/grpcpp/support/status_code_enum.h @@ -1415,6 +1465,7 @@ filegroups: - grpc_base_headers - grpc_transport_inproc_headers - grpc++_codegen_base + - grpc++_internal_hdrs_only - nanopb_headers - health_proto - name: grpc++_config_proto @@ -1422,6 +1473,10 @@ filegroups: public_headers: - include/grpc++/impl/codegen/config_protobuf.h - include/grpcpp/impl/codegen/config_protobuf.h +- name: grpc++_internal_hdrs_only + language: c++ + public_headers: + - include/grpcpp/impl/codegen/sync.h - name: grpc++_reflection_proto language: c++ src: @@ -1496,16 +1551,6 @@ libs: filegroups: - gpr_base secure: false -- name: gpr_test_util - build: private - language: c - headers: - - test/core/util/test_config.h - src: - - test/core/util/test_config.cc - deps: - - gpr - secure: false - name: grpc build: all language: c @@ -1568,7 +1613,6 @@ libs: - test/core/end2end/data/test_root_cert.cc - test/core/security/oauth2_utils.cc deps: - - gpr_test_util - gpr - grpc filegroups: @@ -1578,7 +1622,6 @@ libs: language: c deps: - gpr - - gpr_test_util - grpc_unsecure filegroups: - grpc_test_util_base @@ -1625,7 +1668,6 @@ libs: - test_tcp_server - grpc_test_util - grpc - - gpr_test_util - gpr - name: test_tcp_server build: private @@ -1637,8 +1679,32 @@ libs: deps: - grpc_test_util - grpc - - gpr_test_util - gpr +- name: bm_callback_test_service_impl + build: test + language: c++ + headers: + - test/cpp/microbenchmarks/callback_test_service.h + src: + - src/proto/grpc/testing/echo.proto + - test/cpp/microbenchmarks/callback_test_service.cc + deps: + - grpc_benchmark + - benchmark + - grpc++_test_util_unsecure + - grpc_test_util_unsecure + - grpc++_unsecure + - grpc_unsecure + - gpr + - grpc++_test_config + defaults: benchmark +- name: dns_test_util + build: private + language: c++ + headers: + - test/cpp/naming/dns_test_util.h + src: + - test/cpp/naming/dns_test_util.cc - name: grpc++ build: all language: c++ @@ -1706,6 +1772,7 @@ libs: public_headers: - include/grpc++/support/error_details.h - include/grpcpp/support/error_details.h + - include/grpcpp/support/error_details_impl.h src: - src/proto/grpc/status/status.proto - src/cpp/util/error_details.cc @@ -1731,6 +1798,7 @@ libs: public_headers: - include/grpc++/ext/proto_server_reflection_plugin.h - include/grpcpp/ext/proto_server_reflection_plugin.h + - include/grpcpp/ext/proto_server_reflection_plugin_impl.h headers: - src/cpp/ext/proto_server_reflection.h src: @@ -1752,6 +1820,7 @@ libs: build: private language: c++ headers: + - test/cpp/end2end/test_health_check_service_impl.h - test/cpp/end2end/test_service_impl.h - test/cpp/util/byte_buffer_proto_helper.h - test/cpp/util/channel_trace_proto_helper.h @@ -1765,6 +1834,8 @@ libs: - src/proto/grpc/testing/echo_messages.proto - src/proto/grpc/testing/echo.proto - src/proto/grpc/testing/duplicate/echo_duplicate.proto + - src/proto/grpc/testing/simple_messages.proto + - test/cpp/end2end/test_health_check_service_impl.cc - test/cpp/end2end/test_service_impl.cc - test/cpp/util/byte_buffer_proto_helper.cc - test/cpp/util/channel_trace_proto_helper.cc @@ -1785,6 +1856,7 @@ libs: build: private language: c++ headers: + - test/cpp/end2end/test_health_check_service_impl.h - test/cpp/end2end/test_service_impl.h - test/cpp/util/byte_buffer_proto_helper.h - test/cpp/util/string_ref_helper.h @@ -1794,6 +1866,8 @@ libs: - src/proto/grpc/testing/echo_messages.proto - src/proto/grpc/testing/echo.proto - src/proto/grpc/testing/duplicate/echo_duplicate.proto + - src/proto/grpc/testing/simple_messages.proto + - test/cpp/end2end/test_health_check_service_impl.cc - test/cpp/end2end/test_service_impl.cc - test/cpp/util/byte_buffer_proto_helper.cc - test/cpp/util/string_ref_helper.cc @@ -1903,6 +1977,7 @@ libs: language: c++ public_headers: - include/grpcpp/ext/channelz_service_plugin.h + - include/grpcpp/ext/channelz_service_plugin_impl.h headers: - src/cpp/server/channelz/channelz_service.h src: @@ -1960,7 +2035,6 @@ libs: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - grpc++_test_config - name: interop_server_helper @@ -1990,7 +2064,6 @@ libs: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - grpc++_test_config - name: interop_server_main @@ -2063,7 +2136,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: alloc_test @@ -2072,8 +2144,9 @@ targets: src: - test/core/gpr/alloc_test.cc deps: - - gpr_test_util - gpr + - grpc_test_util_unsecure + - grpc_unsecure uses_polling: false - name: alpn_test build: test @@ -2083,7 +2156,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: alts_credentials_fuzzer build: fuzzer @@ -2093,7 +2165,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr corpus_dirs: - test/core/security/corpus/alts_credentials_corpus @@ -2106,7 +2177,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr corpus_dirs: - test/core/end2end/fuzzers/api_fuzzer_corpus @@ -2119,8 +2189,9 @@ targets: src: - test/core/gpr/arena_test.cc deps: - - gpr_test_util - gpr + - grpc_test_util_unsecure + - grpc_unsecure uses_polling: false - name: avl_test build: test @@ -2128,8 +2199,8 @@ targets: src: - test/core/avl/avl_test.cc deps: - - gpr_test_util - gpr + - grpc_test_util - grpc uses_polling: false - name: bad_server_response_test @@ -2141,7 +2212,6 @@ targets: - test_tcp_server - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -2171,7 +2241,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -2185,7 +2254,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: check_epollexclusive build: tool @@ -2203,7 +2271,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: chttp2_stream_map_test @@ -2214,7 +2281,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: chttp2_varint_test @@ -2225,7 +2291,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: client_fuzzer @@ -2236,12 +2301,26 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr corpus_dirs: - test/core/end2end/fuzzers/client_fuzzer_corpus dict: test/core/end2end/fuzzers/hpack.dictionary maxlen: 2048 +- name: close_fd_test + build: test + language: c + src: + - test/core/bad_connection/close_fd_test.cc + deps: + - grpc_test_util + - grpc + - gpr + exclude_configs: + - tsan + platforms: + - mac + - linux + - posix - name: cmdline_test build: test language: c @@ -2249,8 +2328,8 @@ targets: - test/core/util/cmdline_test.cc deps: - gpr - - gpr_test_util - grpc_test_util + - grpc uses_polling: false - name: combiner_test cpu_cost: 10 @@ -2261,7 +2340,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: compression_test build: test @@ -2271,7 +2349,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: concurrent_connectivity_test @@ -2283,7 +2360,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -2296,7 +2372,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: dns_resolver_connectivity_test cpu_cost: 0.1 @@ -2307,7 +2382,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -2319,7 +2393,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: dns_resolver_test build: test @@ -2329,7 +2402,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: dualstack_socket_test cpu_cost: 0.1 @@ -2340,7 +2412,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -2356,7 +2427,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -2369,7 +2439,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: ev_epollex_linux_test @@ -2381,7 +2450,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -2395,7 +2463,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: fake_transport_security_test build: test @@ -2403,8 +2470,8 @@ targets: src: - test/core/tsi/fake_transport_security_test.cc deps: - - gpr_test_util - gpr + - grpc_test_util - grpc filegroups: - transport_security_test_lib @@ -2420,7 +2487,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -2436,7 +2502,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -2453,7 +2518,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: fling_server build: test @@ -2464,7 +2528,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: fling_stream_test cpu_cost: 1.5 @@ -2475,7 +2538,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr platforms: - mac @@ -2490,7 +2552,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr platforms: - mac @@ -2502,8 +2563,9 @@ targets: src: - test/core/gprpp/fork_test.cc deps: - - gpr_test_util - gpr + - grpc_test_util_unsecure + - grpc_unsecure platforms: - mac - linux @@ -2517,7 +2579,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -2532,8 +2593,9 @@ targets: src: - test/core/gpr/cpu_test.cc deps: - - gpr_test_util - gpr + - grpc_test_util_unsecure + - grpc_unsecure uses_polling: false - name: gpr_env_test build: test @@ -2541,8 +2603,9 @@ targets: src: - test/core/gpr/env_test.cc deps: - - gpr_test_util - gpr + - grpc_test_util_unsecure + - grpc_unsecure uses_polling: false - name: gpr_host_port_test build: test @@ -2550,8 +2613,9 @@ targets: src: - test/core/gpr/host_port_test.cc deps: - - gpr_test_util - gpr + - grpc_test_util_unsecure + - grpc_unsecure uses_polling: false - name: gpr_log_test build: test @@ -2559,8 +2623,9 @@ targets: src: - test/core/gpr/log_test.cc deps: - - gpr_test_util - gpr + - grpc_test_util_unsecure + - grpc_unsecure uses_polling: false - name: gpr_manual_constructor_test cpu_cost: 3 @@ -2569,8 +2634,9 @@ targets: src: - test/core/gprpp/manual_constructor_test.cc deps: - - gpr_test_util - gpr + - grpc_test_util_unsecure + - grpc_unsecure uses_polling: false - name: gpr_mpscq_test cpu_cost: 30 @@ -2579,8 +2645,9 @@ targets: src: - test/core/gpr/mpscq_test.cc deps: - - gpr_test_util - gpr + - grpc_test_util_unsecure + - grpc_unsecure uses_polling: false - name: gpr_spinlock_test cpu_cost: 3 @@ -2589,8 +2656,9 @@ targets: src: - test/core/gpr/spinlock_test.cc deps: - - gpr_test_util - gpr + - grpc_test_util_unsecure + - grpc_unsecure uses_polling: false - name: gpr_string_test build: test @@ -2598,8 +2666,9 @@ targets: src: - test/core/gpr/string_test.cc deps: - - gpr_test_util - gpr + - grpc_test_util_unsecure + - grpc_unsecure uses_polling: false - name: gpr_sync_test cpu_cost: 10 @@ -2608,8 +2677,9 @@ targets: src: - test/core/gpr/sync_test.cc deps: - - gpr_test_util - gpr + - grpc_test_util_unsecure + - grpc_unsecure uses_polling: false - name: gpr_thd_test cpu_cost: 10 @@ -2618,8 +2688,9 @@ targets: src: - test/core/gprpp/thd_test.cc deps: - - gpr_test_util - gpr + - grpc_test_util_unsecure + - grpc_unsecure uses_polling: false - name: gpr_time_test build: test @@ -2627,8 +2698,9 @@ targets: src: - test/core/gpr/time_test.cc deps: - - gpr_test_util - gpr + - grpc_test_util_unsecure + - grpc_unsecure uses_polling: false - name: gpr_tls_test build: test @@ -2636,8 +2708,9 @@ targets: src: - test/core/gpr/tls_test.cc deps: - - gpr_test_util - gpr + - grpc_test_util_unsecure + - grpc_unsecure uses_polling: false - name: gpr_useful_test build: test @@ -2645,8 +2718,9 @@ targets: src: - test/core/gpr/useful_test.cc deps: - - gpr_test_util - gpr + - grpc_test_util_unsecure + - grpc_unsecure uses_polling: false - name: grpc_auth_context_test build: test @@ -2656,7 +2730,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: grpc_b64_test @@ -2667,7 +2740,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: grpc_byte_buffer_reader_test @@ -2678,7 +2750,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: grpc_channel_args_test @@ -2689,7 +2760,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: grpc_channel_stack_builder_test @@ -2700,7 +2770,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: grpc_channel_stack_test build: test @@ -2710,7 +2779,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: grpc_completion_queue_test @@ -2721,7 +2789,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: grpc_completion_queue_threading_test build: test @@ -2731,7 +2798,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -2755,7 +2821,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: grpc_fetch_oauth2 build: test @@ -2766,7 +2831,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: grpc_ipv6_loopback_available_test build: test @@ -2776,7 +2840,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -2788,7 +2851,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr platforms: - linux @@ -2803,7 +2865,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: grpc_print_google_default_creds_token @@ -2825,7 +2886,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: grpc_ssl_credentials_test build: test @@ -2835,7 +2895,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: grpc_verify_jwt build: tool @@ -2856,7 +2915,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -2874,7 +2932,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -2892,7 +2949,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -2907,7 +2963,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -2931,7 +2986,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr corpus_dirs: - test/core/transport/chttp2/hpack_parser_corpus @@ -2945,7 +2999,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: hpack_table_test @@ -2956,7 +3009,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: http_parser_test @@ -2967,7 +3019,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: http_request_fuzzer_test @@ -2978,7 +3029,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr corpus_dirs: - test/core/http/request_corpus @@ -2991,7 +3041,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr corpus_dirs: - test/core/http/response_corpus @@ -3004,7 +3053,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: httpcli_test cpu_cost: 0.5 @@ -3015,7 +3063,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr platforms: - mac @@ -3030,7 +3077,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr platforms: - linux @@ -3042,7 +3088,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: inproc_callback_test @@ -3055,7 +3100,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: invalid_call_argument_test @@ -3067,7 +3111,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: json_fuzzer_test build: fuzzer @@ -3077,7 +3120,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr corpus_dirs: - test/core/json/corpus @@ -3091,7 +3133,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: json_rewrite_test @@ -3102,7 +3143,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: json_stream_error_test @@ -3113,7 +3153,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: json_test @@ -3124,7 +3163,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: lame_client_test @@ -3135,7 +3173,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: load_file_test build: test @@ -3145,7 +3182,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: low_level_ping_pong_benchmark @@ -3156,7 +3192,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr platforms: - mac @@ -3171,7 +3206,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: memory_usage_server @@ -3183,7 +3217,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: memory_usage_test cpu_cost: 1.5 @@ -3194,7 +3227,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr platforms: - mac @@ -3208,7 +3240,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: minimal_stack_is_minimal_test @@ -3219,7 +3250,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: multiple_server_queues_test @@ -3230,7 +3260,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: murmur_hash_test build: test @@ -3238,8 +3267,9 @@ targets: src: - test/core/gpr/murmur_hash_test.cc deps: - - gpr_test_util - gpr + - grpc_test_util_unsecure + - grpc_unsecure uses_polling: false - name: nanopb_fuzzer_response_test build: fuzzer @@ -3249,7 +3279,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr corpus_dirs: - test/core/nanopb/corpus_response @@ -3262,7 +3291,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr corpus_dirs: - test/core/nanopb/corpus_serverlist @@ -3276,7 +3304,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: num_external_connectivity_watchers_test build: test @@ -3286,7 +3313,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -3298,9 +3324,22 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false +- name: parse_address_with_named_scope_id_test + build: test + language: c + src: + - test/core/client_channel/parse_address_with_named_scope_id_test.cc + deps: + - grpc_test_util + - grpc + - gpr + platforms: + - mac + - linux + - posix + uses_polling: false - name: percent_decode_fuzzer build: fuzzer language: c @@ -3309,7 +3348,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr corpus_dirs: - test/core/slice/percent_decode_corpus @@ -3322,7 +3360,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr corpus_dirs: - test/core/slice/percent_encode_corpus @@ -3335,10 +3372,9 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false -- name: resolve_address_posix_test +- name: resolve_address_using_ares_resolver_posix_test build: test language: c src: @@ -3346,8 +3382,9 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr + args: + - --resolver=ares exclude_iomgrs: - uv platforms: @@ -3362,10 +3399,26 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr args: - --resolver=ares +- name: resolve_address_using_native_resolver_posix_test + build: test + language: c + src: + - test/core/iomgr/resolve_address_posix_test.cc + deps: + - grpc_test_util + - grpc + - gpr + args: + - --resolver=native + exclude_iomgrs: + - uv + platforms: + - mac + - linux + - posix - name: resolve_address_using_native_resolver_test build: test language: c @@ -3374,7 +3427,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr args: - --resolver=native @@ -3387,7 +3439,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: secure_channel_create_test build: test @@ -3397,7 +3448,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: secure_endpoint_test build: test @@ -3407,7 +3457,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -3419,7 +3468,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -3431,7 +3479,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: server_fuzzer build: fuzzer @@ -3441,7 +3488,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr corpus_dirs: - test/core/end2end/fuzzers/server_fuzzer_corpus @@ -3455,7 +3501,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: slice_buffer_test build: test @@ -3465,7 +3510,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: slice_string_helpers_test @@ -3476,7 +3520,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: slice_test @@ -3487,7 +3530,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: sockaddr_resolver_test @@ -3498,7 +3540,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: sockaddr_utils_test build: test @@ -3508,7 +3549,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: socket_utils_test build: test @@ -3518,7 +3558,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -3534,7 +3573,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr corpus_dirs: - test/core/security/corpus/ssl_server_corpus @@ -3545,8 +3583,8 @@ targets: src: - test/core/tsi/ssl_transport_security_test.cc deps: - - gpr_test_util - gpr + - grpc_test_util - grpc filegroups: - transport_security_test_lib @@ -3562,7 +3600,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: stream_compression_test @@ -3573,7 +3610,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: stream_owned_slice_test @@ -3584,7 +3620,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: tcp_client_posix_test @@ -3596,7 +3631,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -3613,7 +3647,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - native @@ -3626,7 +3659,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -3642,7 +3674,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -3658,7 +3689,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - native @@ -3670,7 +3700,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: timeout_encoding_test @@ -3681,7 +3710,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: timer_heap_test @@ -3692,7 +3720,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -3705,7 +3732,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -3718,7 +3744,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: transport_metadata_test build: test @@ -3728,7 +3753,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: transport_security_test build: test @@ -3738,7 +3762,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr platforms: - linux @@ -3752,7 +3775,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr exclude_iomgrs: - uv @@ -3768,7 +3790,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr corpus_dirs: - test/core/client_channel/uri_corpus @@ -3781,24 +3802,7 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr -- name: wakeup_fd_cv_test - build: test - language: c - src: - - test/core/iomgr/wakeup_fd_cv_test.cc - deps: - - grpc_test_util - - grpc - - gpr_test_util - - gpr - exclude_iomgrs: - - uv - platforms: - - mac - - linux - - posix - name: alarm_test gtest: true build: test @@ -3810,7 +3814,6 @@ targets: - grpc_test_util_unsecure - grpc++_unsecure - grpc_unsecure - - gpr_test_util - gpr - name: alts_counter_test build: test @@ -3828,8 +3831,8 @@ targets: - test/core/tsi/alts/crypt/aes_gcm_test.cc deps: - alts_test_util - - gpr_test_util - gpr + - grpc_test_util - grpc - name: alts_crypter_test build: test @@ -3942,7 +3945,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: auth_property_iterator_test gtest: true @@ -3955,7 +3957,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr uses_polling: false - name: backoff_test @@ -3966,7 +3967,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: bdp_estimator_test @@ -3979,9 +3979,28 @@ targets: - grpc++ - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false +- name: bm_alarm + build: test + language: c++ + src: + - test/cpp/microbenchmarks/bm_alarm.cc + deps: + - grpc_benchmark + - benchmark + - grpc++_test_util_unsecure + - grpc_test_util_unsecure + - grpc++_unsecure + - grpc_unsecure + - gpr + - grpc++_test_config + benchmark: true + defaults: benchmark + platforms: + - mac + - linux + - posix - name: bm_arena build: test language: c++ @@ -3994,7 +4013,27 @@ targets: - grpc_test_util_unsecure - grpc++_unsecure - grpc_unsecure - - gpr_test_util + - gpr + - grpc++_test_config + benchmark: true + defaults: benchmark + platforms: + - mac + - linux + - posix + uses_polling: false +- name: bm_byte_buffer + build: test + language: c++ + src: + - test/cpp/microbenchmarks/bm_byte_buffer.cc + deps: + - grpc_benchmark + - benchmark + - grpc++_test_util_unsecure + - grpc_test_util_unsecure + - grpc++_unsecure + - grpc_unsecure - gpr - grpc++_test_config benchmark: true @@ -4016,7 +4055,6 @@ targets: - grpc_test_util_unsecure - grpc++_unsecure - grpc_unsecure - - gpr_test_util - gpr - grpc++_test_config benchmark: true @@ -4026,6 +4064,52 @@ targets: - linux - posix uses_polling: false +- name: bm_callback_streaming_ping_pong + build: test + language: c++ + headers: + - test/cpp/microbenchmarks/callback_streaming_ping_pong.h + src: + - test/cpp/microbenchmarks/bm_callback_streaming_ping_pong.cc + deps: + - grpc_benchmark + - benchmark + - grpc++_test_util_unsecure + - grpc_test_util_unsecure + - grpc++_unsecure + - grpc_unsecure + - gpr + - grpc++_test_config + - bm_callback_test_service_impl + benchmark: true + defaults: benchmark + platforms: + - mac + - linux + - posix +- name: bm_callback_unary_ping_pong + build: test + language: c++ + headers: + - test/cpp/microbenchmarks/callback_unary_ping_pong.h + src: + - test/cpp/microbenchmarks/bm_callback_unary_ping_pong.cc + deps: + - grpc_benchmark + - benchmark + - grpc++_test_util_unsecure + - grpc_test_util_unsecure + - grpc++_unsecure + - grpc_unsecure + - gpr + - grpc++_test_config + - bm_callback_test_service_impl + benchmark: true + defaults: benchmark + platforms: + - mac + - linux + - posix - name: bm_channel build: test language: c++ @@ -4038,7 +4122,6 @@ targets: - grpc_test_util_unsecure - grpc++_unsecure - grpc_unsecure - - gpr_test_util - gpr - grpc++_test_config benchmark: true @@ -4060,7 +4143,6 @@ targets: - grpc_test_util_unsecure - grpc++_unsecure - grpc_unsecure - - gpr_test_util - gpr - grpc++_test_config benchmark: true @@ -4082,7 +4164,6 @@ targets: - grpc_test_util_unsecure - grpc++_unsecure - grpc_unsecure - - gpr_test_util - gpr - grpc++_test_config benchmark: true @@ -4103,7 +4184,6 @@ targets: - grpc_test_util_unsecure - grpc++_unsecure - grpc_unsecure - - gpr_test_util - gpr - grpc++_test_config benchmark: true @@ -4124,7 +4204,6 @@ targets: - grpc_test_util_unsecure - grpc++_unsecure - grpc_unsecure - - gpr_test_util - gpr - grpc++_test_config benchmark: true @@ -4145,7 +4224,6 @@ targets: - grpc_test_util_unsecure - grpc++_unsecure - grpc_unsecure - - gpr_test_util - gpr - grpc++_test_config benchmark: true @@ -4167,7 +4245,6 @@ targets: - grpc_test_util_unsecure - grpc++_unsecure - grpc_unsecure - - gpr_test_util - gpr - grpc++_test_config benchmark: true @@ -4191,14 +4268,12 @@ targets: - grpc_test_util_unsecure - grpc++_unsecure - grpc_unsecure - - gpr_test_util - gpr - grpc++_test_config benchmark: true defaults: benchmark excluded_poll_engines: - poll - - poll-cv platforms: - mac - linux @@ -4218,14 +4293,12 @@ targets: - grpc_test_util_unsecure - grpc++_unsecure - grpc_unsecure - - gpr_test_util - gpr - grpc++_test_config benchmark: true defaults: benchmark excluded_poll_engines: - poll - - poll-cv platforms: - mac - linux @@ -4243,7 +4316,6 @@ targets: - grpc_test_util_unsecure - grpc++_unsecure - grpc_unsecure - - gpr_test_util - gpr - grpc++_test_config benchmark: true @@ -4252,7 +4324,6 @@ targets: - tsan excluded_poll_engines: - poll - - poll-cv platforms: - mac - linux @@ -4272,14 +4343,12 @@ targets: - grpc_test_util_unsecure - grpc++_unsecure - grpc_unsecure - - gpr_test_util - gpr - grpc++_test_config benchmark: true defaults: benchmark excluded_poll_engines: - poll - - poll-cv platforms: - mac - linux @@ -4297,7 +4366,6 @@ targets: - grpc_test_util_unsecure - grpc++_unsecure - grpc_unsecure - - gpr_test_util - gpr - grpc++_test_config benchmark: true @@ -4319,7 +4387,6 @@ targets: - grpc_test_util_unsecure - grpc++_unsecure - grpc_unsecure - - gpr_test_util - gpr - grpc++_test_config benchmark: true @@ -4328,6 +4395,27 @@ targets: - mac - linux - posix +- name: bm_timer + build: test + language: c++ + src: + - test/cpp/microbenchmarks/bm_timer.cc + deps: + - grpc_benchmark + - benchmark + - grpc++_test_util_unsecure + - grpc_test_util_unsecure + - grpc++_unsecure + - grpc_unsecure + - gpr + - grpc++_test_config + benchmark: true + defaults: benchmark + platforms: + - mac + - linux + - posix + uses_polling: false - name: byte_stream_test gtest: true build: test @@ -4337,7 +4425,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: channel_arguments_test @@ -4373,7 +4460,6 @@ targets: - grpc++_test_util - grpc++ - grpc - - gpr_test_util - gpr filegroups: - grpcpp_channelz_proto @@ -4390,7 +4476,6 @@ targets: - grpc++_test_util - grpc++ - grpc - - gpr_test_util - gpr uses: - grpc++_test @@ -4407,7 +4492,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr filegroups: - grpcpp_channelz_proto @@ -4422,7 +4506,6 @@ targets: - grpc++_test_util - grpc++ - grpc - - gpr_test_util - gpr filegroups: - grpcpp_channelz_proto @@ -4453,7 +4536,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: true - name: cli_call_test @@ -4468,7 +4550,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: client_callback_end2end_test gtest: true @@ -4477,12 +4558,12 @@ targets: language: c++ src: - test/cpp/end2end/client_callback_end2end_test.cc + - test/cpp/end2end/interceptors_util.cc deps: - grpc++_test_util - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: client_channel_stress_test gtest: false @@ -4497,7 +4578,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: client_crash_test gtest: true @@ -4511,7 +4591,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr platforms: - mac @@ -4524,11 +4603,11 @@ targets: src: - test/cpp/end2end/client_crash_test_server.cc deps: + - grpc++_test_config - grpc++_test_util - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: client_interceptors_end2end_test gtest: true @@ -4545,7 +4624,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: client_lb_end2end_test gtest: true @@ -4558,7 +4636,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: codegen_test_full gtest: true @@ -4602,6 +4679,17 @@ targets: - grpc++_codegen_base - grpc++_codegen_base_src uses_polling: false +- name: context_list_test + gtest: true + build: test + language: c++ + src: + - test/core/transport/chttp2/context_list_test.cc + deps: + - grpc_test_util + - grpc + - gpr + uses_polling: false - name: credentials_test gtest: true build: test @@ -4622,7 +4710,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr uses_polling: false - name: cxx_slice_test @@ -4635,7 +4722,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr uses_polling: false - name: cxx_string_ref_test @@ -4658,7 +4744,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr uses_polling: false - name: end2end_test @@ -4676,7 +4761,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: error_details_test gtest: true @@ -4699,7 +4783,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: filter_end2end_test gtest: true @@ -4712,7 +4795,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: generic_end2end_test gtest: true @@ -4725,8 +4807,25 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr +- name: global_config_env_test + build: test + language: c++ + src: + - test/core/gprpp/global_config_env_test.cc + deps: + - gpr + - grpc_test_util_unsecure + uses_polling: false +- name: global_config_test + build: test + language: c++ + src: + - test/core/gprpp/global_config_test.cc + deps: + - gpr + - grpc_test_util_unsecure + uses_polling: false - name: golden_file_test gtest: true build: test @@ -4735,6 +4834,7 @@ targets: - src/proto/grpc/testing/compiler_test.proto - test/cpp/codegen/golden_file_test.cc deps: + - grpc++_test_config - grpc++ - grpc - gpr @@ -4762,6 +4862,22 @@ targets: - grpc - gpr - grpc++_test_config +- name: grpc_core_map_test + gtest: true + build: test + language: c++ + headers: + - test/core/gprpp/map_tester.h + src: + - test/core/gprpp/map_test.cc + deps: + - grpc_test_util + - grpc++ + - grpc + - gpr + uses: + - grpc++_test + uses_polling: false - name: grpc_cpp_plugin build: protoc language: c++ @@ -4787,7 +4903,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - name: grpc_node_plugin build: protoc @@ -4845,7 +4960,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr filegroups: - grpc++_codegen_proto @@ -4873,7 +4987,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: h2_ssl_cert_test gtest: true @@ -4887,7 +5000,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr uses: - grpc++_test @@ -4903,7 +5015,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr uses: - grpc++_test @@ -4918,7 +5029,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: http2_client build: test @@ -4947,7 +5057,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: inlined_vector_test gtest: true @@ -4959,7 +5068,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr uses: - grpc++_test @@ -4975,7 +5083,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - grpc++_test_config platforms: @@ -4994,7 +5101,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - grpc++_test_config platforms: @@ -5014,7 +5120,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - grpc++_test_config platforms: @@ -5030,7 +5135,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr - grpc++_test_config platforms: @@ -5048,7 +5152,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - grpc++_test_config platforms: @@ -5065,11 +5168,23 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr uses: - grpc++_test uses_polling: false +- name: message_allocator_end2end_test + gtest: true + cpu_cost: 0.5 + build: test + language: c++ + src: + - test/cpp/end2end/message_allocator_end2end_test.cc + deps: + - grpc++_test_util + - grpc_test_util + - grpc++ + - grpc + - gpr - name: metrics_client build: test run: false @@ -5098,7 +5213,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: nonblocking_test gtest: true @@ -5111,7 +5225,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: noop-benchmark build: test @@ -5121,6 +5234,19 @@ targets: deps: - benchmark defaults: benchmark +- name: optional_test + gtest: true + build: test + language: c++ + src: + - test/core/gprpp/optional_test.cc + deps: + - grpc_test_util + - grpc++ + - grpc + - gpr + uses: + - grpc++_test - name: orphanable_test gtest: true build: test @@ -5131,7 +5257,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr uses: - grpc++_test @@ -5148,7 +5273,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: proto_utils_test gtest: true @@ -5175,7 +5299,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - grpc++_test_config platforms: @@ -5196,7 +5319,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - grpc++_test_config - name: qps_openloop_test @@ -5212,7 +5334,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - grpc++_test_config platforms: @@ -5235,7 +5356,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - grpc++_test_config - name: raw_end2end_test @@ -5249,7 +5369,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: reconnect_interop_client build: test @@ -5265,7 +5384,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - grpc++_test_config - name: reconnect_interop_server @@ -5284,7 +5402,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - grpc++_test_config - name: ref_counted_ptr_test @@ -5297,7 +5414,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr uses: - grpc++_test @@ -5311,7 +5427,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr uses: - grpc++_test @@ -5324,7 +5439,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: secure_auth_context_test @@ -5338,7 +5452,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: secure_sync_unary_ping_pong_test build: test @@ -5352,7 +5465,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - grpc++_test_config platforms: @@ -5370,7 +5482,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: server_builder_test gtest: true @@ -5383,7 +5494,6 @@ targets: deps: - grpc++_test_util_unsecure - grpc_test_util_unsecure - - gpr_test_util - grpc++_unsecure - grpc_unsecure - gpr @@ -5398,7 +5508,6 @@ targets: deps: - grpc++_test_util_unsecure - grpc_test_util_unsecure - - gpr_test_util - grpc++_unsecure - grpc_unsecure - gpr @@ -5414,7 +5523,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr uses: - grpc++_test @@ -5430,7 +5538,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr platforms: - mac @@ -5443,11 +5550,11 @@ targets: src: - test/cpp/end2end/server_crash_test_client.cc deps: + - grpc++_test_config - grpc++_test_util - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: server_early_return_test gtest: true @@ -5460,7 +5567,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: server_interceptors_end2end_test gtest: true @@ -5477,7 +5583,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: server_request_call_test gtest: true @@ -5490,10 +5595,34 @@ targets: deps: - grpc++_test_util_unsecure - grpc_test_util_unsecure - - gpr_test_util - grpc++_unsecure - grpc_unsecure - gpr +- name: service_config_end2end_test + gtest: true + build: test + language: c++ + src: + - test/cpp/end2end/service_config_end2end_test.cc + deps: + - grpc++_test_util + - grpc_test_util + - grpc++ + - grpc + - gpr +- name: service_config_test + gtest: true + build: test + language: c++ + src: + - test/core/client_channel/service_config_test.cc + deps: + - grpc_test_util + - grpc++ + - grpc + - gpr + uses: + - grpc++_test - name: shutdown_test gtest: true build: test @@ -5505,7 +5634,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - name: slice_hash_table_test gtest: true @@ -5516,7 +5644,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: slice_weak_hash_table_test @@ -5528,7 +5655,6 @@ targets: deps: - grpc_test_util - grpc - - gpr_test_util - gpr uses_polling: false - name: stats_test @@ -5541,7 +5667,6 @@ targets: - grpc++_test_util - grpc_test_util - grpc - - gpr_test_util - gpr exclude_configs: - tsan @@ -5577,7 +5702,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr platforms: - mac @@ -5607,7 +5731,6 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr - grpc++_test_config - name: thread_manager_test @@ -5632,8 +5755,23 @@ targets: - grpc_test_util_unsecure - grpc++_unsecure - grpc_unsecure - - gpr_test_util - gpr +- name: time_change_test + gtest: true + build: test + language: c++ + src: + - test/cpp/end2end/time_change_test.cc + deps: + - grpc++_test_util + - grpc_test_util + - grpc++ + - grpc + - gpr + platforms: + - mac + - linux + - posix - name: transport_pid_controller_test build: test language: c++ @@ -5644,7 +5782,6 @@ targets: - grpc++ - grpc_test_util - grpc - - gpr_test_util - gpr - name: transport_security_common_api_test build: test @@ -5667,12 +5804,24 @@ targets: - grpc_test_util - grpc++ - grpc - - gpr_test_util - gpr platforms: - mac - linux - posix +- name: xds_end2end_test + gtest: true + build: test + language: c++ + src: + - src/proto/grpc/lb/v1/load_balancer.proto + - test/cpp/end2end/xds_end2end_test.cc + deps: + - grpc++_test_util + - grpc_test_util + - grpc++ + - grpc + - gpr - name: public_headers_must_be_c89 build: test language: c89 @@ -5874,6 +6023,9 @@ defaults: -Wno-deprecated-declarations -Ithird_party/nanopb -DPB_FIELD_32BIT CXXFLAGS: -Wnon-virtual-dtor LDFLAGS: -g + upb: + CFLAGS: -Ithird_party/upb -Wno-sign-conversion -Wno-shadow -Wno-conversion -Wno-implicit-fallthrough + -Wno-sign-compare -Wno-missing-field-initializers zlib: CFLAGS: -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-implicit-function-declaration -Wno-implicit-fallthrough $(W_NO_SHIFT_NEGATIVE_VALUE) -fvisibility=hidden diff --git a/cmake/benchmark.cmake b/cmake/benchmark.cmake index 2b4c20f2db4..99148b52adf 100644 --- a/cmake/benchmark.cmake +++ b/cmake/benchmark.cmake @@ -13,6 +13,7 @@ # limitations under the License. if("${gRPC_BENCHMARK_PROVIDER}" STREQUAL "module") + set(BENCHMARK_ENABLE_GTEST_TESTS OFF CACHE BOOL "Turn off gTest in gBenchmark") if(NOT BENCHMARK_ROOT_DIR) set(BENCHMARK_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/third_party/benchmark) endif() @@ -35,3 +36,4 @@ elseif("${gRPC_BENCHMARK_PROVIDER}" STREQUAL "package") endif() set(_gRPC_FIND_BENCHMARK "if(NOT benchmark_FOUND)\n find_package(benchmark CONFIG)\nendif()") endif() + diff --git a/cmake/cares.cmake b/cmake/cares.cmake index 3d4a0cae765..4ea0d8725d0 100644 --- a/cmake/cares.cmake +++ b/cmake/cares.cmake @@ -18,6 +18,10 @@ if("${gRPC_CARES_PROVIDER}" STREQUAL "module") endif() set(CARES_SHARED OFF CACHE BOOL "disable shared library") set(CARES_STATIC ON CACHE BOOL "link cares statically") + if(gRPC_BACKWARDS_COMPATIBILITY_MODE) + # See https://github.com/grpc/grpc/issues/17255 + set(HAVE_LIBNSL OFF CACHE BOOL "avoid cares dependency on libnsl") + endif() add_subdirectory(third_party/cares/cares) if(TARGET c-ares) diff --git a/cmake/gflags.cmake b/cmake/gflags.cmake index c301b1cdb6d..52c054ca762 100644 --- a/cmake/gflags.cmake +++ b/cmake/gflags.cmake @@ -18,19 +18,18 @@ if("${gRPC_GFLAGS_PROVIDER}" STREQUAL "module") endif() if(EXISTS "${GFLAGS_ROOT_DIR}/CMakeLists.txt") add_subdirectory(${GFLAGS_ROOT_DIR} third_party/gflags) - if(TARGET gflags_static) - set(_gRPC_GFLAGS_LIBRARIES gflags_static) - set(_gRPC_GFLAGS_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include") - endif() + set(_gRPC_GFLAGS_LIBRARIES gflags::gflags) + set(_gRPC_GFLAGS_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include") else() message(WARNING "gRPC_GFLAGS_PROVIDER is \"module\" but GFLAGS_ROOT_DIR is wrong") endif() elseif("${gRPC_GFLAGS_PROVIDER}" STREQUAL "package") # Use "CONFIG" as there is no built-in cmake module for gflags. find_package(gflags REQUIRED CONFIG) - if(TARGET gflags) - set(_gRPC_GFLAGS_LIBRARIES gflags) + if(TARGET gflags::gflags) + set(_gRPC_GFLAGS_LIBRARIES gflags::gflags) set(_gRPC_GFLAGS_INCLUDE_DIR ${GFLAGS_INCLUDE_DIR}) endif() set(_gRPC_FIND_GFLAGS "if(NOT gflags_FOUND)\n find_package(gflags CONFIG)\nendif()") endif() + diff --git a/config.m4 b/config.m4 index a087a6b48b3..c5ecf7cfd6a 100644 --- a/config.m4 +++ b/config.m4 @@ -45,7 +45,6 @@ if test "$PHP_GRPC" != "no"; then third_party/address_sorting/address_sorting_posix.c \ third_party/address_sorting/address_sorting_windows.c \ 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 \ @@ -78,7 +77,9 @@ if test "$PHP_GRPC" != "no"; then 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/arena.cc \ src/core/lib/gprpp/fork.cc \ + src/core/lib/gprpp/global_config_env.cc \ src/core/lib/gprpp/thd_posix.cc \ src/core/lib/gprpp/thd_windows.cc \ src/core/lib/profiling/basic_timers.cc \ @@ -94,10 +95,10 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/channel/channelz_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_args.cc \ src/core/lib/compression/compression_internal.cc \ src/core/lib/compression/message_compress.cc \ src/core/lib/compression/stream_compression.cc \ @@ -110,12 +111,15 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/http/parser.cc \ src/core/lib/iomgr/buffer_list.cc \ src/core/lib/iomgr/call_combiner.cc \ + src/core/lib/iomgr/cfstream_handle.cc \ src/core/lib/iomgr/combiner.cc \ src/core/lib/iomgr/endpoint.cc \ + src/core/lib/iomgr/endpoint_cfstream.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/error_cfstream.cc \ src/core/lib/iomgr/ev_epoll1_linux.cc \ src/core/lib/iomgr/ev_epollex_linux.cc \ src/core/lib/iomgr/ev_poll_posix.cc \ @@ -128,18 +132,20 @@ if test "$PHP_GRPC" != "no"; then 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/grpc_if_nametoindex_posix.cc \ + src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc \ src/core/lib/iomgr/internal_errqueue.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_posix_cfstream.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 \ @@ -163,6 +169,7 @@ if test "$PHP_GRPC" != "no"; then 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_cfstream.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 \ @@ -187,7 +194,6 @@ if test "$PHP_GRPC" != "no"; then 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 \ @@ -227,7 +233,6 @@ if test "$PHP_GRPC" != "no"; then 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 \ @@ -241,6 +246,7 @@ if test "$PHP_GRPC" != "no"; then 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/context_list.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 \ @@ -281,6 +287,8 @@ if test "$PHP_GRPC" != "no"; then 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/tls/grpc_tls_credentials_options.cc \ + src/core/lib/security/credentials/tls/spiffe_credentials.cc \ src/core/lib/security/security_connector/alts/alts_security_connector.cc \ src/core/lib/security/security_connector/fake/fake_security_connector.cc \ src/core/lib/security/security_connector/load_system_roots_fallback.cc \ @@ -289,6 +297,7 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/security/security_connector/security_connector.cc \ src/core/lib/security/security_connector/ssl/ssl_security_connector.cc \ src/core/lib/security/security_connector/ssl_utils.cc \ + src/core/lib/security/security_connector/tls/spiffe_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 \ @@ -343,21 +352,25 @@ if test "$PHP_GRPC" != "no"; then 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/global_subchannel_pool.cc \ src/core/ext/filters/client_channel/health/health_check_client.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/local_subchannel_pool.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/resolver_result_parsing.cc \ + src/core/ext/filters/client_channel/resolving_lb_policy.cc \ src/core/ext/filters/client_channel/retry_throttle.cc \ + src/core/ext/filters/client_channel/server_address.cc \ + src/core/ext/filters/client_channel/service_config.cc \ src/core/ext/filters/client_channel/subchannel.cc \ - src/core/ext/filters/client_channel/subchannel_index.cc \ + src/core/ext/filters/client_channel/subchannel_pool_interface.cc \ src/core/ext/filters/deadline/deadline_filter.cc \ src/core/ext/filters/client_channel/health/health.pb.c \ src/core/tsi/fake_transport_security.cc \ @@ -390,10 +403,13 @@ if test "$PHP_GRPC" != "no"; then 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.cc \ + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc \ + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc \ + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc \ src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc \ @@ -723,11 +739,13 @@ if test "$PHP_GRPC" != "no"; then PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/credentials/oauth2) PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/credentials/plugin) PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/credentials/ssl) + PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/credentials/tls) PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/security_connector) PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/security_connector/alts) PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/security_connector/fake) PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/security_connector/local) PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/security_connector/ssl) + PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/security_connector/tls) PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/transport) PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/util) PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/slice) diff --git a/config.w32 b/config.w32 index 12520fef3b4..6bcc54f6630 100644 --- a/config.w32 +++ b/config.w32 @@ -20,7 +20,6 @@ if (PHP_GRPC != "no") { "third_party\\address_sorting\\address_sorting_posix.c " + "third_party\\address_sorting\\address_sorting_windows.c " + "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 " + @@ -53,7 +52,9 @@ if (PHP_GRPC != "no") { "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\\arena.cc " + "src\\core\\lib\\gprpp\\fork.cc " + + "src\\core\\lib\\gprpp\\global_config_env.cc " + "src\\core\\lib\\gprpp\\thd_posix.cc " + "src\\core\\lib\\gprpp\\thd_windows.cc " + "src\\core\\lib\\profiling\\basic_timers.cc " + @@ -69,10 +70,10 @@ if (PHP_GRPC != "no") { "src\\core\\lib\\channel\\channelz_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_args.cc " + "src\\core\\lib\\compression\\compression_internal.cc " + "src\\core\\lib\\compression\\message_compress.cc " + "src\\core\\lib\\compression\\stream_compression.cc " + @@ -85,12 +86,15 @@ if (PHP_GRPC != "no") { "src\\core\\lib\\http\\parser.cc " + "src\\core\\lib\\iomgr\\buffer_list.cc " + "src\\core\\lib\\iomgr\\call_combiner.cc " + + "src\\core\\lib\\iomgr\\cfstream_handle.cc " + "src\\core\\lib\\iomgr\\combiner.cc " + "src\\core\\lib\\iomgr\\endpoint.cc " + + "src\\core\\lib\\iomgr\\endpoint_cfstream.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\\error_cfstream.cc " + "src\\core\\lib\\iomgr\\ev_epoll1_linux.cc " + "src\\core\\lib\\iomgr\\ev_epollex_linux.cc " + "src\\core\\lib\\iomgr\\ev_poll_posix.cc " + @@ -103,18 +107,20 @@ if (PHP_GRPC != "no") { "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\\grpc_if_nametoindex_posix.cc " + + "src\\core\\lib\\iomgr\\grpc_if_nametoindex_unsupported.cc " + "src\\core\\lib\\iomgr\\internal_errqueue.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_posix_cfstream.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 " + @@ -138,6 +144,7 @@ if (PHP_GRPC != "no") { "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_cfstream.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 " + @@ -162,7 +169,6 @@ if (PHP_GRPC != "no") { "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 " + @@ -202,7 +208,6 @@ if (PHP_GRPC != "no") { "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 " + @@ -216,6 +221,7 @@ if (PHP_GRPC != "no") { "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\\context_list.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 " + @@ -256,6 +262,8 @@ if (PHP_GRPC != "no") { "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\\tls\\grpc_tls_credentials_options.cc " + + "src\\core\\lib\\security\\credentials\\tls\\spiffe_credentials.cc " + "src\\core\\lib\\security\\security_connector\\alts\\alts_security_connector.cc " + "src\\core\\lib\\security\\security_connector\\fake\\fake_security_connector.cc " + "src\\core\\lib\\security\\security_connector\\load_system_roots_fallback.cc " + @@ -264,6 +272,7 @@ if (PHP_GRPC != "no") { "src\\core\\lib\\security\\security_connector\\security_connector.cc " + "src\\core\\lib\\security\\security_connector\\ssl\\ssl_security_connector.cc " + "src\\core\\lib\\security\\security_connector\\ssl_utils.cc " + + "src\\core\\lib\\security\\security_connector\\tls\\spiffe_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 " + @@ -318,21 +327,25 @@ if (PHP_GRPC != "no") { "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\\global_subchannel_pool.cc " + "src\\core\\ext\\filters\\client_channel\\health\\health_check_client.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\\local_subchannel_pool.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\\resolver_result_parsing.cc " + + "src\\core\\ext\\filters\\client_channel\\resolving_lb_policy.cc " + "src\\core\\ext\\filters\\client_channel\\retry_throttle.cc " + + "src\\core\\ext\\filters\\client_channel\\server_address.cc " + + "src\\core\\ext\\filters\\client_channel\\service_config.cc " + "src\\core\\ext\\filters\\client_channel\\subchannel.cc " + - "src\\core\\ext\\filters\\client_channel\\subchannel_index.cc " + + "src\\core\\ext\\filters\\client_channel\\subchannel_pool_interface.cc " + "src\\core\\ext\\filters\\deadline\\deadline_filter.cc " + "src\\core\\ext\\filters\\client_channel\\health\\health.pb.c " + "src\\core\\tsi\\fake_transport_security.cc " + @@ -365,10 +378,13 @@ if (PHP_GRPC != "no") { "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.cc " + + "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_ev_driver_libuv.cc " + "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_ev_driver_posix.cc " + "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_ev_driver_windows.cc " + "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper.cc " + "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper_fallback.cc " + + "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper_libuv.cc " + + "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper_libuv_windows.cc " + "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper_posix.cc " + "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper_windows.cc " + "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\native\\dns_resolver.cc " + @@ -738,11 +754,13 @@ if (PHP_GRPC != "no") { FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\credentials\\oauth2"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\credentials\\plugin"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\credentials\\ssl"); + FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\credentials\\tls"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\security_connector"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\security_connector\\alts"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\security_connector\\fake"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\security_connector\\local"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\security_connector\\ssl"); + FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\security_connector\\tls"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\transport"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\util"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\slice"); diff --git a/doc/PROTOCOL-HTTP2.md b/doc/PROTOCOL-HTTP2.md index a354dad8636..e73e682bbe3 100644 --- a/doc/PROTOCOL-HTTP2.md +++ b/doc/PROTOCOL-HTTP2.md @@ -61,6 +61,8 @@ the form shown above. If **Timeout** is omitted a server should assume an infinite timeout. Client implementations are free to send a default minimum timeout based on their deployment requirements. +If **Content-Type** does not begin with "application/grpc", gRPC servers SHOULD respond with HTTP status of 415 (Unsupported Media Type). This will prevent other HTTP/2 clients from interpreting a gRPC error response, which uses status 200 (OK), as successful. + **Custom-Metadata** is an arbitrary set of key-value pairs defined by the application layer. Header names starting with "grpc-" but not listed here are reserved for future GRPC use and should not be used by applications as **Custom-Metadata**. Note that HTTP2 does not allow arbitrary octet sequences for header values so binary header values must be encoded using Base64 as per https://tools.ietf.org/html/rfc4648#section-4. Implementations MUST accept padded and un-padded values and should emit un-padded values. Applications define binary headers by having their names end with "-bin". Runtime libraries use this suffix to detect binary headers and properly apply base64 encoding & decoding as headers are sent and received. @@ -255,5 +257,3 @@ to be used. * **Service-Name** → ?( {_proto package name_} "." ) {_service name_} * **Message-Type** → {_fully qualified proto message name_} * **Content-Type** → "application/grpc+proto" - - diff --git a/doc/PROTOCOL-WEB.md b/doc/PROTOCOL-WEB.md index a06dfb1b54d..66544543804 100644 --- a/doc/PROTOCOL-WEB.md +++ b/doc/PROTOCOL-WEB.md @@ -132,7 +132,7 @@ finalized and implemented in modern browsers Versioning -* Special headers may be introduced to support features that may break compatiblity. +* Special headers may be introduced to support features that may break compatibility. --- diff --git a/doc/compression.md b/doc/compression.md index b8cdfb30485..15e35ae350c 100644 --- a/doc/compression.md +++ b/doc/compression.md @@ -30,7 +30,7 @@ configured: therefore the compression that SHALL be used in the absence of per-RPC compression configuration. + At response time, via: - + For unary RPCs, the {Client,Server}Context instance. + + For unary RPCs, the {Client,Server}Context instance. + For streaming RPCs, the {Client,Server}Writer instance. In this case, configuration is reduced to disabling compression altogether. @@ -41,14 +41,14 @@ of the request, including not performing any compression, regardless of channel and RPC settings (for example, if compression would result in small or negative gains). -When a message from a client compressed with an unsupported algorithm is -processed by a server, it WILL result in an `UNIMPLEMENTED` error status on the -server. The server will then include in its response a `grpc-accept-encoding` -header specifying the algorithms it does accept. If an `UNIMPLEMENTED` error -status is returned from the server despite having used one of the algorithms -from the `grpc-accept-encoding` header, the cause MUST NOT be related to -compression. Data sent from a server compressed with an algorithm not supported -by the client WILL result in an `INTERNAL` error status on the client side. +If a client message is compressed by an algorithm that is not supported +by a server, the message WILL result in an `UNIMPLEMENTED` error status on the +server. The server will then include a `grpc-accept-encoding` response +header which specifies the algorithms that the server accepts. If the client +message is compressed using one of the algorithms from the `grpc-accept-encoding` header +and an `UNIMPLEMENTED` error status is returned from the server, the cause of the error +MUST NOT be related to compression. If a server sent data which is compressed by an algorithm +that is not supported by the client, an `INTERNAL` error status will occur on the client side. Note that a peer MAY choose to not disclose all the encodings it supports. However, if it receives a message compressed in an undisclosed but supported @@ -57,7 +57,7 @@ header. For every message a server is requested to compress using an algorithm it knows the client doesn't support (as indicated by the last `grpc-accept-encoding` -header received from the client), it SHALL send the message uncompressed. +header received from the client), it SHALL send the message uncompressed. ### Specific Disabling of Compression diff --git a/doc/connection-backoff-interop-test-description.md b/doc/connection-backoff-interop-test-description.md index 4778efe4530..7675059d9a3 100644 --- a/doc/connection-backoff-interop-test-description.md +++ b/doc/connection-backoff-interop-test-description.md @@ -40,7 +40,7 @@ Procedure of client: 1. Calls Start on server control port with a large deadline or no deadline, waits for its finish and checks it succeeded. 2. Initiates a channel connection to server retry port, which should perform -reconnections with proper backoffs. A convienent way to achieve this is to +reconnections with proper backoffs. A convenient way to achieve this is to call Start with a deadline of 540s. The rpc should fail with deadline exceeded. 3. Calls Stop on server control port and checks it succeeded. 4. Checks the response to see whether the server thinks the backoffs passed the diff --git a/doc/connectivity-semantics-and-api.md b/doc/connectivity-semantics-and-api.md index 44fdf050c65..48a847670ce 100644 --- a/doc/connectivity-semantics-and-api.md +++ b/doc/connectivity-semantics-and-api.md @@ -43,7 +43,7 @@ connection because of a lack of new or pending RPCs. New RPCs MAY be created in this state. Any attempt to start an RPC on the channel will push the channel out of this state to connecting. When there has been no RPC activity on a channel for a specified IDLE_TIMEOUT, i.e., no new or pending (active) RPCs for this -period, channels that are READY or CONNECTING switch to IDLE. Additionaly, +period, channels that are READY or CONNECTING switch to IDLE. Additionally, channels that receive a GOAWAY when there are no active or pending RPCs should also switch to IDLE to avoid connection overload at servers that are attempting to shed connections. We will use a default IDLE_TIMEOUT of 300 seconds (5 minutes). diff --git a/doc/core/epoll-polling-engine.md b/doc/core/epoll-polling-engine.md index 1f5d855743a..e660a709384 100644 --- a/doc/core/epoll-polling-engine.md +++ b/doc/core/epoll-polling-engine.md @@ -85,16 +85,16 @@ There are two cases to check here: * This is straightforward and nothing really needs to be done here * **Case 2:** The `fd `and `pollset` point to different `polling_islands`: In this case we _merge_ both the polling islands i.e: * Add all the `fds` from the smaller `polling_island `to the larger `polling_island` and update the `merged_to` pointer on the smaller island to point to the larger island. - * Wake up all the threads waiting on the smaller `polling_island`'s `epoll_fd` (by signalling the `event_fd` on that island) and make them now wait on the larger `polling_island`'s `epoll_fd` + * Wake up all the threads waiting on the smaller `polling_island`'s `epoll_fd` (by signaling the `event_fd` on that island) and make them now wait on the larger `polling_island`'s `epoll_fd` * Update `fd` and `pollset` to now point to the larger `polling_island` ### 4.3 Directed wakeups: The new implementation, just like the current implementation, does not provide us any guarantees that the thread that is woken up is the thread that is actually interested in the event. So the thread that woke up executes the callbacks and finally has to 'kick' the appropriate polling thread interested in the event. -In the current implementation, every polling thread also had a `event_fd` on which it was listening to and hence waking it up was as simple as signalling that `event_fd`. However, using an `event_fd` also meant that every thread has to use a `poll()` (on `event_fd` and `epoll_fd`) instead of doing an `epoll_wait()` and this resulted in the thundering herd problems described above. +In the current implementation, every polling thread also had a `event_fd` on which it was listening to and hence waking it up was as simple as signaling that `event_fd`. However, using an `event_fd` also meant that every thread has to use a `poll()` (on `event_fd` and `epoll_fd`) instead of doing an `epoll_wait()` and this resulted in the thundering herd problems described above. -The proposal here is to use signals and kicking a thread would just be sending a signal to that thread. Unfortunately there are only a few signals available on posix systems and most of them have pre-determined behavior leaving only a few signals `SIGUSR1`, `SIGUSR2` and `SIGRTx (SIGRTMIN to SIGRTMAX)` for custom use. +The proposal here is to use signals and kicking a thread would just be sending a signal to that thread. Unfortunately there are only a few signals available on POSIX systems and most of them have pre-determined behavior leaving only a few signals `SIGUSR1`, `SIGUSR2` and `SIGRTx (SIGRTMIN to SIGRTMAX)` for custom use. The calling application might have registered other signal handlers for these signals. `We will provide a new API where the applications can "give a signal number" to gRPC library to use for this purpose. diff --git a/doc/core/grpc-client-server-polling-engine-usage.md b/doc/core/grpc-client-server-polling-engine-usage.md index 3a560e71a81..f66dcf09caa 100644 --- a/doc/core/grpc-client-server-polling-engine-usage.md +++ b/doc/core/grpc-client-server-polling-engine-usage.md @@ -17,7 +17,7 @@ This document talks about how polling engine is used in gRPC core (both on clien ### Making progress on Async `connect()` on sub-channels (`grpc_pollset_set` usecase) - A gRPC channel is created between a client and a 'target'. The 'target' may resolve in to one or more backend servers. - A sub-channel is the 'connection' from a client to the backend server -- While establishing sub-cannels (i.e connections) to the backends, gRPC issues async [`connect()`](https://github.com/grpc/grpc/blob/v1.15.1/src/core/lib/iomgr/tcp_client_posix.cc#L296) calls which may not complete right away. When the `connect()` eventually succeeds, the socket fd is make 'writable' +- While establishing sub-channels (i.e connections) to the backends, gRPC issues async [`connect()`](https://github.com/grpc/grpc/blob/v1.15.1/src/core/lib/iomgr/tcp_client_posix.cc#L296) calls which may not complete right away. When the `connect()` eventually succeeds, the socket fd is make 'writable' - This means that the polling engine must be monitoring all these sub-channel `fd`s for writable events and we need to make sure there is a polling thread that monitors all these fds - To accomplish this, the `grpc_pollset_set` is used the following way (see picture below) diff --git a/doc/core/grpc-polling-engines.md b/doc/core/grpc-polling-engines.md index f273913b1e4..f93f72be405 100644 --- a/doc/core/grpc-polling-engines.md +++ b/doc/core/grpc-polling-engines.md @@ -23,11 +23,9 @@ There are multiple polling engine implementations depending on the OS and the OS - **`epollex`** (default but requires kernel version >= 4.5), - `epoll1` (If `epollex` is not available and glibc version >= 2.9) - `poll` (If kernel does not have epoll support) - - `poll-cv` (If explicitly configured) -- Mac: **`poll`** (default), `poll-cv` (If explicitly configured) +- Mac: **`poll`** (default) - Windows: (no name) - One-off polling engines: - - AppEngine platform: **`poll-cv`** (default) - NodeJS : `libuv` polling engine implementation (requires different compile `#define`s) ## Polling Engine Interface @@ -87,7 +85,7 @@ Add/Remove fd to the `grpc_pollset_set` - **grpc\_pollset\_set_[add|del]\_pollset** - Signature: `grpc_pollset_set_[add|del]_pollset(grpc_pollset_set* pss, grpc_pollset* ps)` - What does adding a pollset to a pollset_set mean ? - - It means that calling `grpc_pollset_work()` on the pollset will also poll all the fds in the pollset_set i.e semantically, it is similar to adding all the fds inside pollset_set to the pollset. + - It means that calling `grpc_pollset_work()` on the pollset will also poll all the fds in the pollset_set i.e semantically, it is similar to adding all the fds inside pollset_set to the pollset. - This guarantee is no longer true once the pollset is removed from the pollset_set - **grpc\_pollset\_set_[add|del]\_pollset\_set** @@ -137,7 +135,7 @@ Code at `src/core/lib/iomgr/ev_epollex_posix.cc` - The same FD can be in multiple `Pollable`s (even if one of the `Pollable`s is of type PO_FD) - There cannot be two `Pollable`s of type PO_FD for the same fd -- Why do we need `Pollable` of type PO_FD and PO_EMTPY ? +- Why do we need `Pollable` of type PO_FD and PO_EMPTY ? - The main reason is the Sync client API - We create one new completion queue per call. If we didn’t have PO_EMPTY and PO_FD type pollables, then every call on a given channel will effectively have to create a `Pollable` and hence an epollset. This is because every completion queue automatically creates a pollset and the channel fd will have to be put in that pollset. This clearly requires an epollset to put that fd. Creating an epollset per call (even if we delete the epollset once the call is completed) would mean a lot of sys calls to create/delete epoll fds. This is clearly not a good idea. - With these new types of `Pollable`s, all pollsets (corresponding to the new per-call completion queue) will initially point to PO_EMPTY global epollset. Then once the channel fd is added to the pollset, the pollset will point to the `Pollable` of type PO_FD containing just that fd (i.e it will reuse the existing `Pollable`). This way, the epoll fd creation/deletion churn is avoided. diff --git a/doc/core/pending_api_cleanups.md b/doc/core/pending_api_cleanups.md index 67d587deadc..970bcd08300 100644 --- a/doc/core/pending_api_cleanups.md +++ b/doc/core/pending_api_cleanups.md @@ -15,3 +15,4 @@ number: `include/grpc/impl/codegen/grpc_types.h` (commit `af00d8b`) (cannot be done until after next grpc release, so that TensorFlow can use the same code both internally and externally) +- require a C++ runtime for all languages wrapping core. diff --git a/doc/core/transport_explainer.md b/doc/core/transport_explainer.md index f48fa0f3b1f..cc4cab1eae9 100644 --- a/doc/core/transport_explainer.md +++ b/doc/core/transport_explainer.md @@ -28,7 +28,7 @@ synonymously since all RPCs are actually streams internally.) The ops in a batch can include: * send\_initial\_metadata - - Client: initate an RPC + - Client: initiate an RPC - Server: supply response headers * recv\_initial\_metadata - Client: get response headers @@ -110,7 +110,7 @@ There are other possible sample timelines. For example, for client-side streamin - These correspond to a client issuing `WritesDone` which causes the server's `Read` to fail 1. Server: send\_message, send\_trailing\_metadata - - These correpond to the server doing `Finish` + - These correspond to the server doing `Finish` The sends on one side will call their own callbacks when complete, and they will in turn trigger actions that cause the other side's recv operations to diff --git a/doc/environment_variables.md b/doc/environment_variables.md index d1172e62f45..778560d4273 100644 --- a/doc/environment_variables.md +++ b/doc/environment_variables.md @@ -41,11 +41,16 @@ some configuration as environment variables that can be set. - bdp_estimator - traces behavior of bdp estimation logic - call_combiner - traces call combiner state - call_error - traces the possible errors contributing to final call status + - cares_resolver - traces operations of the c-ares based DNS resolver + - cares_address_sorting - traces operations of the c-ares based DNS + resolver's resolved address sorter - channel - traces operations on the C core channel stack - - client_channel - traces client channel activity, including resolver - and load balancing policy interaction + - client_channel_call - traces client channel call batch activity + - client_channel_routing - traces client channel call routing, including + resolver and load balancing policy interaction - compression - traces compression operations - connectivity_state - traces connectivity state changes to channels + - cronet - traces state in the cronet transport engine - executor - traces grpc's internal thread pool ('the executor') - fd_trace - traces fd create(), shutdown() and close() calls for channel fds. Also traces epoll fd create()/close() calls in epollex polling engine @@ -114,15 +119,16 @@ some configuration as environment variables that can be set. - ERROR - log only errors * GRPC_TRACE_FUZZER - if set, the fuzzers will output trace (it is usually supressed). + if set, the fuzzers will output trace (it is usually suppressed). * GRPC_DNS_RESOLVER Declares which DNS resolver to use. The default is ares if gRPC is built with c-ares support. Otherwise, the value of this environment variable is ignored. Available DNS resolver include: - - native (default)- a DNS resolver based around getaddrinfo(), creates a new thread to + - ares (default on most platforms except iOS, Android or Node)- a DNS + resolver based around the c-ares library + - native - a DNS resolver based around getaddrinfo(), creates a new thread to perform name resolution - - ares - a DNS resolver based around the c-ares library * GRPC_CLIENT_CHANNEL_BACKUP_POLL_INTERVAL_MS Default: 5000 @@ -140,13 +146,3 @@ some configuration as environment variables that can be set. * grpc_cfstream set to 1 to turn on CFStream experiment. With this experiment gRPC uses CFStream API to make TCP connections. The option is only available on iOS platform and when macro GRPC_CFSTREAM is defined. - -* GRPC_ARENA_INIT_STRATEGY - Selects the initialization strategy for blocks allocated in the arena. Valid - values are: - - no_init (default): Do not inialize the arena block. - - zero_init: Initialize the arena blocks with 0. - - non_zero_init: Initialize the arena blocks with a non-zero value. - - NOTE: This environment variable is experimental and will be removed. Thus, it - should not be relied upon. diff --git a/doc/g_stands_for.md b/doc/g_stands_for.md index a5a8efb21c7..90202b1b880 100644 --- a/doc/g_stands_for.md +++ b/doc/g_stands_for.md @@ -16,4 +16,9 @@ - 1.14 'g' stands for ['gladiolus'](https://github.com/grpc/grpc/tree/v1.14.x) - 1.15 'g' stands for ['glider'](https://github.com/grpc/grpc/tree/v1.15.x) - 1.16 'g' stands for ['gao'](https://github.com/grpc/grpc/tree/v1.16.x) -- 1.17 'g' stands for ['gizmo'](https://github.com/grpc/grpc/tree/master) +- 1.17 'g' stands for ['gizmo'](https://github.com/grpc/grpc/tree/v1.17.x) +- 1.18 'g' stands for ['goose'](https://github.com/grpc/grpc/tree/v1.18.x) +- 1.19 'g' stands for ['gold'](https://github.com/grpc/grpc/tree/v1.19.x) +- 1.20 'g' stands for ['godric'](https://github.com/grpc/grpc/tree/v1.20.x) +- 1.21 'g' stands for ['gandalf'](https://github.com/grpc/grpc/tree/v1.21.x) +- 1.22 'g' stands for ['gale'](https://github.com/grpc/grpc/tree/master) diff --git a/doc/grpc_release_schedule.md b/doc/grpc_release_schedule.md new file mode 100644 index 00000000000..bacd3758593 --- /dev/null +++ b/doc/grpc_release_schedule.md @@ -0,0 +1,22 @@ +# gRPC Release Schedule + +Below is the release schedule for gRPC [Java](https://github.com/grpc/grpc-java/releases), [Go](https://github.com/grpc/grpc-go/releases) and [Core](https://github.com/grpc/grpc/releases) and its dependent languages C++, C#, Objective-C, PHP, Python and Ruby. + +Releases are scheduled every six weeks on Tuesdays on a best effort basis. In some unavoidable situations a release may be delayed or a language may skip a release altogether and do the next release to catch up with other languages. See the past releases in the links above. A six-week cycle gives us a good balance between delivering new features/fixes quickly and keeping the release overhead low. + +Releases are cut from release branches. For Core and Java repos, the release branch is cut two weeks before the scheduled release date. For Go, the branch is cut just before the release. An RC (release candidate) is published for Core and its dependent languages just after the branch cut. This RC is later promoted to release version if no further changes are made to the release branch. We do our best to keep head of master branch stable at all times regardless of release schedule. Daily build packages from master branch for C#, PHP, Python, Ruby and Protoc plugins are published on [packages.grpc.io](https://packages.grpc.io/). If you depend on gRPC in production we recommend to set up your CI system to test the RCs and, if possible, the daily builds. + +Names of gRPC releases are [here](https://github.com/grpc/grpc/blob/master/doc/g_stands_for.md). + +Release |Scheduled Branch Cut|Scheduled Release Date +--------|--------------------|------------- +v1.17.0 |Nov 19, 2018 |Dec 4, 2018 +v1.18.0 |Jan 2, 2019 |Jan 15, 2019 +v1.19.0 |Feb 12, 2019 |Feb 26, 2019 +v1.20.0 |Mar 26, 2019 |Apr 9, 2019 +v1.21.0 |May 7, 2019 |May 21, 2019 +v1.22.0 |Jun 18, 2019 |Jul 2, 2019 +v1.23.0 |Jul 30, 2019 |Aug 13, 2019 +v1.24.0 |Sept 10, 2019 |Sept 24, 2019 +v1.25.0 |Oct 22, 2019 |Nov 5, 2019 +v1.26.0 |Dec 3, 2019 |Dec 17, 2019 diff --git a/doc/interop-test-descriptions.md b/doc/interop-test-descriptions.md old mode 100644 new mode 100755 index 1d6535d7ea0..f210da0b0b3 --- a/doc/interop-test-descriptions.md +++ b/doc/interop-test-descriptions.md @@ -652,7 +652,7 @@ The test downloaded from https://console.developers.google.com. Alternately, if using a usable auth implementation, it may specify the file location in the environment variable GOOGLE_APPLICATION_CREDENTIALS -- optionally uses the flag `--oauth_scope` for the oauth scope if implementator +- optionally uses the flag `--oauth_scope` for the oauth scope if implementer wishes to use service account credential instead of JWT credential. For testing against grpc-test.sandbox.googleapis.com, oauth scope "https://www.googleapis.com/auth/xapi.zoo" should be used. @@ -679,6 +679,81 @@ Client asserts: by the auth library. The client can optionally check the username matches the email address in the key file. +### google_default_credentials + +Similar to the other auth tests, this test should only be run against prod +servers. Different from some of the other auth tests however, this test +may be also run from outside of GCP. + +This test verifies unary calls succeed when the client uses +GoogleDefaultCredentials. The path to a service account key file in the +GOOGLE_APPLICATION_CREDENTIALS environment variable may or may not be +provided by the test runner. For example, the test runner might set +this environment when outside of GCP but keep it unset when on GCP. + +The test uses `--default_service_account` with GCE service account email. + +Server features: +* [UnaryCall][] +* [Echo Authenticated Username][] + +Procedure: + 1. Client configures the channel to use GoogleDefaultCredentials + * Note: the term `GoogleDefaultCredentials` within the context + of this test description refers to an API which encapsulates + both "transport credentials" and "call credentials" and which + is capable of transport creds auto-selection (including ALTS). + Similar APIs involving only auto-selection of OAuth mechanisms + might work for this test but aren't the intended subjects. + 2. Client calls UnaryCall with: + + ``` + { + fill_username: true + } + ``` + +Client asserts: +* call was successful +* received SimpleResponse.username matches the value of + `--default_service_account` + +### compute_engine_channel_credentials + +Similar to the other auth tests, this test should only be run against prod +servers. Note that this test may only be ran on GCP. + +This test verifies unary calls succeed when the client uses +ComputeEngineChannelCredentials. All that is needed by the test environment +is for the client to be running on GCP. + +The test uses `--default_service_account` with GCE service account email. This +email must identify the default service account of the GCP VM that the test +is running on. + +Server features: +* [UnaryCall][] +* [Echo Authenticated Username][] + +Procedure: + 1. Client configures the channel to use ComputeEngineChannelCredentials + * Note: the term `ComputeEngineChannelCredentials` within the context + of this test description refers to an API which encapsulates + both "transport credentials" and "call credentials" and which + is capable of transport creds auto-selection (including ALTS). + The exact name of the API may vary per language. + 2. Client calls UnaryCall with: + + ``` + { + fill_username: true + } + ``` + +Client asserts: +* call was successful +* received SimpleResponse.username matches the value of + `--default_service_account` ### custom_metadata diff --git a/doc/keepalive.md b/doc/keepalive.md index 2f9c8bfc9e4..20449fc273b 100644 --- a/doc/keepalive.md +++ b/doc/keepalive.md @@ -5,12 +5,14 @@ The keepalive ping is a way to check if a channel is currently working by sendin This guide documents the knobs within gRPC core to control the current behavior of the keepalive ping. The keepalive ping is controlled by two important channel arguments - + * **GRPC_ARG_KEEPALIVE_TIME_MS** * This channel argument controls the period (in milliseconds) after which a keepalive ping is sent on the transport. * **GRPC_ARG_KEEPALIVE_TIMEOUT_MS** - * This channel argument controls the amount of time (in milliseconds), the sender of the keepalive ping waits for an acknowledgement. If it does not receive an acknowledgement within this time, it will close the connection. + * This channel argument controls the amount of time (in milliseconds) the sender of the keepalive ping waits for an acknowledgement. If it does not receive an acknowledgment within this time, it will close the connection. The above two channel arguments should be sufficient for most users, but the following arguments can also be useful in certain use cases. + * **GRPC_ARG_KEEPALIVE_PERMIT_WITHOUT_CALLS** * This channel argument if set to 1 (0 : false; 1 : true), allows keepalive pings to be sent even if there are no calls in flight. * **GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA** @@ -39,12 +41,12 @@ GRPC_ARG_HTTP2_MAX_PING_STRIKES|N/A|2 * When is the keepalive timer started? * The keepalive timer is started when a transport is done connecting (after handshake). * What happens when the keepalive timer fires? - * When the keepalive timer fires, gRPC Core would try to send a keepalive ping on the transport. This ping can be blocked if - + * When the keepalive timer fires, gRPC Core will try to send a keepalive ping on the transport. This ping can be blocked if - * there is no active call on that transport and GRPC_ARG_KEEPALIVE_PERMIT_WITHOUT_CALLS is false. * the number of pings already sent on the transport without any data has already exceeded GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA. - * the time expired since the previous ping is less than GRPC_ARG_HTTP2_MIN_SENT_PING_INTERVAL_WITHOUT_DATA_MS. - * If a keepalive ping is not blocked and is sent on the transport, then the keepalive watchdog timer is started which would close the transport if the ping is not acknowledged before it fires. + * the time elapsed since the previous ping is less than GRPC_ARG_HTTP2_MIN_SENT_PING_INTERVAL_WITHOUT_DATA_MS. + * If a keepalive ping is not blocked and is sent on the transport, then the keepalive watchdog timer is started which will close the transport if the ping is not acknowledged before it fires. * Why am I receiving a GOAWAY with error code ENHANCE_YOUR_CALM? * A server sends a GOAWAY with ENHANCE_YOUR_CALM if the client sends too many misbehaving pings. For example - - * if a server has GRPC_ARG_KEEPALIVE_PERMIT_WITHOUT_CALLS set to false, and the client sends pings without there being any call in flight. + * if a server has GRPC_ARG_KEEPALIVE_PERMIT_WITHOUT_CALLS set to false and the client sends pings without there being any call in flight. * if the client's GRPC_ARG_HTTP2_MIN_SENT_PING_INTERVAL_WITHOUT_DATA_MS setting is lower than the server's GRPC_ARG_HTTP2_MIN_RECV_PING_INTERVAL_WITHOUT_DATA_MS. diff --git a/doc/naming.md b/doc/naming.md index 581c550567f..42045fd8337 100644 --- a/doc/naming.md +++ b/doc/naming.md @@ -51,7 +51,9 @@ but may not be supported in other languages: - `ipv6:address[:port][,address[:port],...]` -- IPv6 addresses - Can specify multiple comma-delimited addresses of the form `address[:port]`: - - `address` is the IPv6 address to use. + - `address` is the IPv6 address to use. To use with a `port` the `address` + must enclosed in literal square brackets (`[` and `]`). Example: + `ipv6:[2607:f8b0:400e:c00::ef]:443` or `ipv6:[::]:1234` - `port` is the port to use. If not specified, 443 is used. In the future, additional schemes such as `etcd` could be added. @@ -65,14 +67,10 @@ Resolvers should be able to contact the authority and get a resolution that they return back to the gRPC client library. The returned contents include: -- A list of resolved addresses, each of which has three attributes: - - The address itself, including both IP address and port. - - A boolean indicating whether the address is a backend address (i.e., - the address to use to contact the server directly) or a balancer - address (for cases where [external load balancing](load-balancing.md) - is in use). - - The name of the balancer, if the address is a balancer address. - This will be used to perform peer authorization. +- A list of resolved addresses (both IP address and port). Each address + may have a set of arbitrary attributes (key/value pairs) associated with + it, which can be used to communicate information from the resolver to the + [load balancing](load-balancing.md) policy. - A [service config](service_config.md). The plugin API allows the resolvers to continuously watch an endpoint diff --git a/doc/python/sphinx/conf.py b/doc/python/sphinx/conf.py index 1eb3a5de7fd..7cb5ee4d66e 100644 --- a/doc/python/sphinx/conf.py +++ b/doc/python/sphinx/conf.py @@ -19,8 +19,10 @@ import sys PYTHON_FOLDER = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', '..', '..', 'src', 'python') sys.path.insert(0, os.path.join(PYTHON_FOLDER, 'grpcio')) +sys.path.insert(0, os.path.join(PYTHON_FOLDER, 'grpcio_channelz')) sys.path.insert(0, os.path.join(PYTHON_FOLDER, 'grpcio_health_checking')) sys.path.insert(0, os.path.join(PYTHON_FOLDER, 'grpcio_reflection')) +sys.path.insert(0, os.path.join(PYTHON_FOLDER, 'grpcio_status')) sys.path.insert(0, os.path.join(PYTHON_FOLDER, 'grpcio_testing')) # -- Project information ----------------------------------------------------- @@ -63,6 +65,8 @@ autodoc_default_options = { autodoc_mock_imports = [ 'grpc._cython', + 'grpc_channelz.v1.channelz_pb2', + 'grpc_channelz.v1.channelz_pb2_grpc', 'grpc_health.v1.health_pb2', 'grpc_health.v1.health_pb2_grpc', 'grpc_reflection.v1alpha.reflection_pb2', diff --git a/doc/python/sphinx/grpc.rst b/doc/python/sphinx/grpc.rst index bd2df9596b0..0934db7188b 100644 --- a/doc/python/sphinx/grpc.rst +++ b/doc/python/sphinx/grpc.rst @@ -19,6 +19,11 @@ Go to `gRPC Python Examples `_ + +Module Contents +--------------- + +.. automodule:: grpc_channelz.v1.channelz diff --git a/doc/python/sphinx/grpc_status.rst b/doc/python/sphinx/grpc_status.rst new file mode 100644 index 00000000000..2b9a324e3a4 --- /dev/null +++ b/doc/python/sphinx/grpc_status.rst @@ -0,0 +1,7 @@ +gRPC Status +==================== + +Module Contents +--------------- + +.. automodule:: grpc_status.rpc_status diff --git a/doc/python/sphinx/index.rst b/doc/python/sphinx/index.rst index 322ca33e157..bb671e75603 100644 --- a/doc/python/sphinx/index.rst +++ b/doc/python/sphinx/index.rst @@ -10,8 +10,10 @@ API Reference :caption: Contents: grpc + grpc_channelz grpc_health_checking grpc_reflection + grpc_status grpc_testing glossary diff --git a/doc/server_reflection_tutorial.md b/doc/server_reflection_tutorial.md index 06a257c1e87..acbb4a6ab2d 100644 --- a/doc/server_reflection_tutorial.md +++ b/doc/server_reflection_tutorial.md @@ -15,8 +15,8 @@ server reflection, you can link this library to your server binary. Some platforms (e.g. Ubuntu 11.10 onwards) only link in libraries that directly contain symbols used by the application. On these platforms, LD flag -`--no-as-needed` is needed for for dynamic linking and `--whole-archive` is -needed for for static linking. +`--no-as-needed` is needed for dynamic linking and `--whole-archive` is +needed for static linking. This [Makefile](../examples/cpp/helloworld/Makefile#L37#L45) demonstrates enabling c++ server reflection on Linux and MacOS. diff --git a/doc/service_config.md b/doc/service_config.md index dd1cbc56300..4cef4567d19 100644 --- a/doc/service_config.md +++ b/doc/service_config.md @@ -12,11 +12,13 @@ The service config is a JSON string of the following form: ``` { - // Load balancing policy name (case insensitive). + // [deprecated] Load balancing policy name (case insensitive). // Currently, the only selectable client-side policy provided with gRPC // is 'round_robin', but third parties may add their own policies. // This field is optional; if unset, the default behavior is to pick - // the first available backend. + // the first available backend. If set, the load balancing policy should be + // supported by the client, otherwise the service config is considered + // invalid. // If the policy name is set via the client API, that value overrides // the value specified here. // @@ -61,10 +63,11 @@ The service config is a JSON string of the following form: } ], - // Whether RPCs sent to this method should wait until the connection is - // ready by default. If false, the RPC will abort immediately if there - // is a transient failure connecting to the server. Otherwise, gRPC will - // attempt to connect until the deadline is exceeded. + // Optional. Whether RPCs sent to this method should wait until the + // connection is ready by default. If false, the RPC will abort + // immediately if there is a transient failure connecting to the server. + // Otherwise, gRPC will attempt to connect until the deadline is + // exceeded. // // The value specified via the gRPC client API will override the value // set here. However, note that setting the value in the client API will @@ -73,10 +76,10 @@ The service config is a JSON string of the following form: // is obtained by the gRPC client via name resolution. 'waitForReady': bool, - // The default timeout in seconds for RPCs sent to this method. This can - // be overridden in code. If no reply is received in the specified amount - // of time, the request is aborted and a deadline-exceeded error status - // is returned to the caller. + // Optional. The default timeout in seconds for RPCs sent to this method. + // This can be overridden in code. If no reply is received in the + // specified amount of time, the request is aborted and a + // deadline-exceeded error status is returned to the caller. // // The actual deadline used will be the minimum of the value specified // here and the value set by the application via the gRPC client API. @@ -87,10 +90,10 @@ The service config is a JSON string of the following form: // https://developers.google.com/protocol-buffers/docs/proto3#json 'timeout': string, - // The maximum allowed payload size for an individual request or object - // in a stream (client->server) in bytes. The size which is measured is - // the serialized, uncompressed payload in bytes. This applies both - // to streaming and non-streaming requests. + // Optional. The maximum allowed payload size for an individual request + // or object in a stream (client->server) in bytes. The size which is + // measured is the serialized, uncompressed payload in bytes. This + // applies both to streaming and non-streaming requests. // // The actual value used is the minimum of the value specified here and // the value set by the application via the gRPC client API. @@ -103,10 +106,10 @@ The service config is a JSON string of the following form: // be empty. 'maxRequestMessageBytes': number, - // The maximum allowed payload size for an individual response or object - // in a stream (server->client) in bytes. The size which is measured is - // the serialized, uncompressed payload in bytes. This applies both - // to streaming and non-streaming requests. + // Optional. The maximum allowed payload size for an individual response + // or object in a stream (server->client) in bytes. The size which is + // measured is the serialized, uncompressed payload in bytes. This + // applies both to streaming and non-streaming requests. // // The actual value used is the minimum of the value specified here and // the value set by the application via the gRPC client API. diff --git a/doc/statuscodes.md b/doc/statuscodes.md index 547da054951..61e0d820b48 100644 --- a/doc/statuscodes.md +++ b/doc/statuscodes.md @@ -1,13 +1,35 @@ # Status codes and their use in gRPC -gRPC uses a set of well defined status codes as part of the RPC API. All -RPCs started at a client return a `status` object composed of an integer +gRPC uses a set of well defined status codes as part of the RPC API. These +statuses are defined as such: + +| Code | Number | Description | Closest HTTP Mapping | +|------------------|--------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------| +| OK | 0 | Not an error; returned on success. | 200 OK | +| CANCELLED | 1 | The operation was cancelled, typically by the caller. | 499 Client Closed Request | +| UNKNOWN | 2 | Unknown error. For example, this error may be returned when a `Status` value received from another address space belongs to an error space that is not known in this address space. Also errors raised by APIs that do not return enough error information may be converted to this error. | 500 Internal Server Error | +| INVALID_ARGUMENT | 3 | The client specified an invalid argument. Note that this differs from `FAILED_PRECONDITION`. `INVALID_ARGUMENT` indicates arguments that are problematic regardless of the state of the system (e.g., a malformed file name). | 400 Bad Request | +| DEADLINE_EXCEEDED | 4 | The deadline expired before the operation could complete. For operations that change the state of the system, this error may be returned even if the operation has completed successfully. For example, a successful response from a server could have been delayed long | 504 Gateway Timeout | +| NOT_FOUND | 5 | Some requested entity (e.g., file or directory) was not found. Note to server developers: if a request is denied for an entire class of users, such as gradual feature rollout or undocumented whitelist, `NOT_FOUND` may be used. If a request is denied for some users within a class of users, such as user-based access control, `PERMISSION_DENIED` must be used. | 404 Not Found | +| ALREADY_EXISTS | 6 | The entity that a client attempted to create (e.g., file or directory) already exists. | 409 Conflict | +| PERMISSION_DENIED | 7 | The caller does not have permission to execute the specified operation. `PERMISSION_DENIED` must not be used for rejections caused by exhausting some resource (use `RESOURCE_EXHAUSTED` instead for those errors). `PERMISSION_DENIED` must not be used if the caller can not be identified (use `UNAUTHENTICATED` instead for those errors). This error code does not imply the request is valid or the requested entity exists or satisfies other pre-conditions. | 403 Forbidden | +| UNAUTHENTICATED | 16 | The request does not have valid authentication credentials for the operation. | 401 Unauthorized | +| RESOURCE_EXHAUSTED | 8 | Some resource has been exhausted, perhaps a per-user quota, or perhaps the entire file system is out of space. | 429 Too Many Requests | +| FAILED_PRECONDITION | 9 | The operation was rejected because the system is not in a state required for the operation's execution. For example, the directory to be deleted is non-empty, an rmdir operation is applied to a non-directory, etc. Service implementors can use the following guidelines to decide between `FAILED_PRECONDITION`, `ABORTED`, and `UNAVAILABLE`: (a) Use `UNAVAILABLE` if the client can retry just the failing call. (b) Use `ABORTED` if the client should retry at a higher level (e.g., when a client-specified test-and-set fails, indicating the client should restart a read-modify-write sequence). (c) Use `FAILED_PRECONDITION` if the client should not retry until the system state has been explicitly fixed. E.g., if an "rmdir" fails because the directory is non-empty, `FAILED_PRECONDITION` should be returned since the client should not retry unless the files are deleted from the directory. | 400 Bad Request | +| ABORTED | 10 | The operation was aborted, typically due to a concurrency issue such as a sequencer check failure or transaction abort. See the guidelines above for deciding between `FAILED_PRECONDITION`, `ABORTED`, and `UNAVAILABLE`. | 409 Conflict | +| OUT_OF_RANGE | 11 | The operation was attempted past the valid range. E.g., seeking or reading past end-of-file. Unlike `INVALID_ARGUMENT`, this error indicates a problem that may be fixed if the system state changes. For example, a 32-bit file system will generate `INVALID_ARGUMENT` if asked to read at an offset that is not in the range [0,2^32-1], but it will generate `OUT_OF_RANGE` if asked to read from an offset past the current file size. There is a fair bit of overlap between `FAILED_PRECONDITION` and `OUT_OF_RANGE`. We recommend using `OUT_OF_RANGE` (the more specific error) when it applies so that callers who are iterating through a space can easily look for an `OUT_OF_RANGE` error to detect when they are done. | 400 Bad Request | +| UNIMPLEMENTED | 12 | The operation is not implemented or is not supported/enabled in this service. | 501 Not Implemented | +| INTERNAL | 13 | Internal errors. This means that some invariants expected by the underlying system have been broken. This error code is reserved for serious errors. | 500 Internal Server Error | +| UNAVAILABLE | 14 | The service is currently unavailable. This is most likely a transient condition, which can be corrected by retrying with a backoff. Note that it is not always safe to retry non-idempotent operations. | 503 Service Unavailable | +| DATA_LOSS | 15 | Unrecoverable data loss or corruption. | 500 Internal Server Error | + +All RPCs started at a client return a `status` object composed of an integer `code` and a string `message`. The server-side can choose the status it returns for a given RPC. The gRPC client and server-side implementations may also generate and -return `status` on their own when errors happen. Only a subset of -the pre-defined status codes are generated by the gRPC libraries. This +return `status` on their own when errors happen. Only a subset of +the pre-defined status codes are generated by the gRPC libraries. This allows applications to be sure that any other code it sees was actually returned by the application (although it is also possible for the server-side to return one of the codes generated by the gRPC libraries). @@ -49,4 +71,4 @@ The following status codes are never generated by the library: - OUT_OF_RANGE - DATA_LOSS -Applications that may wish to [retry](https://github.com/grpc/proposal/blob/master/A6-client-retries.md) failed RPCs must decide which status codes on which to retry. As shown in the table above, the gRPC library can generate the same status code for different cases. Server applications can also return those same status codes. Therefore, there is no fixed list of status codes on which it is appropriate to retry in all applications. As a result, individual applications must make their own determination as to which status codes should cause an RPC to be retried. +Applications that may wish to [retry](https:github.com/grpc/proposal/blob/master/A6-client-retries.md) failed RPCs must decide which status codes on which to retry. As shown in the table above, the gRPC library can generate the same status code for different cases. Server applications can also return those same status codes. Therefore, there is no fixed list of status codes on which it is appropriate to retry in all applications. As a result, individual applications must make their own determination as to which status codes should cause an RPC to be retried. diff --git a/doc/wait-for-ready.md b/doc/wait-for-ready.md index fd426042693..c08f20c14ae 100644 --- a/doc/wait-for-ready.md +++ b/doc/wait-for-ready.md @@ -2,7 +2,7 @@ gRPC Wait for Ready Semantics ============================= If an RPC is issued but the channel is in `TRANSIENT_FAILURE` or `SHUTDOWN` -states, the RPC is unable to be transmited promptly. By default, gRPC +states, the RPC is unable to be transmitted promptly. By default, gRPC implementations SHOULD fail such RPCs immediately. This is known as "fail fast," but usage of the term is historical. RPCs SHOULD NOT fail as a result of the channel being in other states (`CONNECTING`, `READY`, or `IDLE`). diff --git a/etc/roots.pem b/etc/roots.pem index 3e6bbcd76ea..22bd2ab88dd 100644 --- a/etc/roots.pem +++ b/etc/roots.pem @@ -329,36 +329,6 @@ OCiNUW7dFGdTbHFcJoRNdVq2fmBWqU2t+5sel/MN2dKXVHfaPRK34B7vCAas+YWH 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" @@ -4340,3 +4310,391 @@ rYy0UGYwEAYJKwYBBAGCNxUBBAMCAQAwCgYIKoZIzj0EAwMDaAAwZQIwJsdpW9zV 57LnyAyMjMPdeYwbY9XJUpROTYJKcx6ygISpJcBMWm1JKWB4E+J+SOtkAjEA2zQg Mgj/mkkCtojeFK9dbJlxjRo/i9fgojaGHAeCOnZT/cKi7e97sIBPWA9LUzm9 -----END CERTIFICATE----- + +# Issuer: CN=GTS Root R1 O=Google Trust Services LLC +# Subject: CN=GTS Root R1 O=Google Trust Services LLC +# Label: "GTS Root R1" +# Serial: 146587175971765017618439757810265552097 +# MD5 Fingerprint: 82:1a:ef:d4:d2:4a:f2:9f:e2:3d:97:06:14:70:72:85 +# SHA1 Fingerprint: e1:c9:50:e6:ef:22:f8:4c:56:45:72:8b:92:20:60:d7:d5:a7:a3:e8 +# SHA256 Fingerprint: 2a:57:54:71:e3:13:40:bc:21:58:1c:bd:2c:f1:3e:15:84:63:20:3e:ce:94:bc:f9:d3:cc:19:6b:f0:9a:54:72 +-----BEGIN CERTIFICATE----- +MIIFWjCCA0KgAwIBAgIQbkepxUtHDA3sM9CJuRz04TANBgkqhkiG9w0BAQwFADBH +MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM +QzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIy +MDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNl +cnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaM +f/vo27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vX +mX7wCl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7 +zUjwTcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0P +fyblqAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtc +vfaHszVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4 +Zor8Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUsp +zBmkMiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOO +Rc92wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYW +k70paDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+ +DVrNVjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgF +lQIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV +HQ4EFgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBADiW +Cu49tJYeX++dnAsznyvgyv3SjgofQXSlfKqE1OXyHuY3UjKcC9FhHb8owbZEKTV1 +d5iyfNm9dKyKaOOpMQkpAWBz40d8U6iQSifvS9efk+eCNs6aaAyC58/UEBZvXw6Z +XPYfcX3v73svfuo21pdwCxXu11xWajOl40k4DLh9+42FpLFZXvRq4d2h9mREruZR +gyFmxhE+885H7pwoHyXa/6xmld01D1zvICxi/ZG6qcz8WpyTgYMpl0p8WnK0OdC3 +d8t5/Wk6kjftbjhlRn7pYL15iJdfOBL07q9bgsiG1eGZbYwE8na6SfZu6W0eX6Dv +J4J2QPim01hcDyxC2kLGe4g0x8HYRZvBPsVhHdljUEn2NIVq4BjFbkerQUIpm/Zg +DdIx02OYI5NaAIFItO/Nis3Jz5nu2Z6qNuFoS3FJFDYoOj0dzpqPJeaAcWErtXvM ++SUWgeExX6GjfhaknBZqlxi9dnKlC54dNuYvoS++cJEPqOba+MSSQGwlfnuzCdyy +F62ARPBopY+Udf90WuioAnwMCeKpSwughQtiue+hMZL77/ZRBIls6Kl0obsXs7X9 +SQ98POyDGCBDTtWTurQ0sR8WNh8M5mQ5Fkzc4P4dyKliPUDqysU0ArSuiYgzNdws +E3PYJ/HQcu51OyLemGhmW/HGY0dVHLqlCFF1pkgl +-----END CERTIFICATE----- + +# Issuer: CN=GTS Root R2 O=Google Trust Services LLC +# Subject: CN=GTS Root R2 O=Google Trust Services LLC +# Label: "GTS Root R2" +# Serial: 146587176055767053814479386953112547951 +# MD5 Fingerprint: 44:ed:9a:0e:a4:09:3b:00:f2:ae:4c:a3:c6:61:b0:8b +# SHA1 Fingerprint: d2:73:96:2a:2a:5e:39:9f:73:3f:e1:c7:1e:64:3f:03:38:34:fc:4d +# SHA256 Fingerprint: c4:5d:7b:b0:8e:6d:67:e6:2e:42:35:11:0b:56:4e:5f:78:fd:92:ef:05:8c:84:0a:ea:4e:64:55:d7:58:5c:60 +-----BEGIN CERTIFICATE----- +MIIFWjCCA0KgAwIBAgIQbkepxlqz5yDFMJo/aFLybzANBgkqhkiG9w0BAQwFADBH +MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM +QzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIy +MDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNl +cnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQDO3v2m++zsFDQ8BwZabFn3GTXd98GdVarTzTukk3Lv +CvptnfbwhYBboUhSnznFt+4orO/LdmgUud+tAWyZH8QiHZ/+cnfgLFuv5AS/T3Kg +GjSY6Dlo7JUle3ah5mm5hRm9iYz+re026nO8/4Piy33B0s5Ks40FnotJk9/BW9Bu +XvAuMC6C/Pq8tBcKSOWIm8Wba96wyrQD8Nr0kLhlZPdcTK3ofmZemde4wj7I0BOd +re7kRXuJVfeKH2JShBKzwkCX44ofR5GmdFrS+LFjKBC4swm4VndAoiaYecb+3yXu +PuWgf9RhD1FLPD+M2uFwdNjCaKH5wQzpoeJ/u1U8dgbuak7MkogwTZq9TwtImoS1 +mKPV+3PBV2HdKFZ1E66HjucMUQkQdYhMvI35ezzUIkgfKtzra7tEscszcTJGr61K +8YzodDqs5xoic4DSMPclQsciOzsSrZYuxsN2B6ogtzVJV+mSSeh2FnIxZyuWfoqj +x5RWIr9qS34BIbIjMt/kmkRtWVtd9QCgHJvGeJeNkP+byKq0rxFROV7Z+2et1VsR +nTKaG73VululycslaVNVJ1zgyjbLiGH7HrfQy+4W+9OmTN6SpdTi3/UGVN4unUu0 +kzCqgc7dGtxRcw1PcOnlthYhGXmy5okLdWTK1au8CcEYof/UVKGFPP0UJAOyh9Ok +twIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV +HQ4EFgQUu//KjiOfT5nK2+JopqUVJxce2Q4wDQYJKoZIhvcNAQEMBQADggIBALZp +8KZ3/p7uC4Gt4cCpx/k1HUCCq+YEtN/L9x0Pg/B+E02NjO7jMyLDOfxA325BS0JT +vhaI8dI4XsRomRyYUpOM52jtG2pzegVATX9lO9ZY8c6DR2Dj/5epnGB3GFW1fgiT +z9D2PGcDFWEJ+YF59exTpJ/JjwGLc8R3dtyDovUMSRqodt6Sm2T4syzFJ9MHwAiA +pJiS4wGWAqoC7o87xdFtCjMwc3i5T1QWvwsHoaRc5svJXISPD+AVdyx+Jn7axEvb +pxZ3B7DNdehyQtaVhJ2Gg/LkkM0JR9SLA3DaWsYDQvTtN6LwG1BUSw7YhN4ZKJmB +R64JGz9I0cNv4rBgF/XuIwKl2gBbbZCr7qLpGzvpx0QnRY5rn/WkhLx3+WuXrD5R +RaIRpsyF7gpo8j5QOHokYh4XIDdtak23CZvJ/KRY9bb7nE4Yu5UC56GtmwfuNmsk +0jmGwZODUNKBRqhfYlcsu2xkiAhu7xNUX90txGdj08+JN7+dIPT7eoOboB6BAFDC +5AwiWVIQ7UNWhwD4FFKnHYuTjKJNRn8nxnGbJN7k2oaLDX5rIMHAnuFl2GqjpuiF +izoHCBy69Y9Vmhh1fuXsgWbRIXOhNUQLgD1bnF5vKheW0YMjiGZt5obicDIvUiLn +yOd/xCxgXS/Dr55FBcOEArf9LAhST4Ldo/DUhgkC +-----END CERTIFICATE----- + +# Issuer: CN=GTS Root R3 O=Google Trust Services LLC +# Subject: CN=GTS Root R3 O=Google Trust Services LLC +# Label: "GTS Root R3" +# Serial: 146587176140553309517047991083707763997 +# MD5 Fingerprint: 1a:79:5b:6b:04:52:9c:5d:c7:74:33:1b:25:9a:f9:25 +# SHA1 Fingerprint: 30:d4:24:6f:07:ff:db:91:89:8a:0b:e9:49:66:11:eb:8c:5e:46:e5 +# SHA256 Fingerprint: 15:d5:b8:77:46:19:ea:7d:54:ce:1c:a6:d0:b0:c4:03:e0:37:a9:17:f1:31:e8:a0:4e:1e:6b:7a:71:ba:bc:e5 +-----BEGIN CERTIFICATE----- +MIICDDCCAZGgAwIBAgIQbkepx2ypcyRAiQ8DVd2NHTAKBggqhkjOPQQDAzBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjMwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw +MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjMwdjAQBgcqhkjOPQIBBgUrgQQA +IgNiAAQfTzOHMymKoYTey8chWEGJ6ladK0uFxh1MJ7x/JlFyb+Kf1qPKzEUURout +736GjOyxfi//qXGdGIRFBEFVbivqJn+7kAHjSxm65FSWRQmx1WyRRK2EE46ajA2A +DDL24CejQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud +DgQWBBTB8Sa6oC2uhYHP0/EqEr24Cmf9vDAKBggqhkjOPQQDAwNpADBmAjEAgFuk +fCPAlaUs3L6JbyO5o91lAFJekazInXJ0glMLfalAvWhgxeG4VDvBNhcl2MG9AjEA +njWSdIUlUfUk7GRSJFClH9voy8l27OyCbvWFGFPouOOaKaqW04MjyaR7YbPMAuhd +-----END CERTIFICATE----- + +# Issuer: CN=GTS Root R4 O=Google Trust Services LLC +# Subject: CN=GTS Root R4 O=Google Trust Services LLC +# Label: "GTS Root R4" +# Serial: 146587176229350439916519468929765261721 +# MD5 Fingerprint: 5d:b6:6a:c4:60:17:24:6a:1a:99:a8:4b:ee:5e:b4:26 +# SHA1 Fingerprint: 2a:1d:60:27:d9:4a:b1:0a:1c:4d:91:5c:cd:33:a0:cb:3e:2d:54:cb +# SHA256 Fingerprint: 71:cc:a5:39:1f:9e:79:4b:04:80:25:30:b3:63:e1:21:da:8a:30:43:bb:26:66:2f:ea:4d:ca:7f:c9:51:a4:bd +-----BEGIN CERTIFICATE----- +MIICCjCCAZGgAwIBAgIQbkepyIuUtui7OyrYorLBmTAKBggqhkjOPQQDAzBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjQwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw +MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQwdjAQBgcqhkjOPQIBBgUrgQQA +IgNiAATzdHOnaItgrkO4NcWBMHtLSZ37wWHO5t5GvWvVYRg1rkDdc/eJkTBa6zzu +hXyiQHY7qca4R9gq55KRanPpsXI5nymfopjTX15YhmUPoYRlBtHci8nHc8iMai/l +xKvRHYqjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud +DgQWBBSATNbrdP9JNqPV2Py1PsVq8JQdjDAKBggqhkjOPQQDAwNnADBkAjBqUFJ0 +CMRw3J5QdCHojXohw0+WbhXRIjVhLfoIN+4Zba3bssx9BzT1YBkstTTZbyACMANx +sbqjYAuG7ZoIapVon+Kz4ZNkfF6Tpt95LY2F45TPI11xzPKwTdb+mciUqXWi4w== +-----END CERTIFICATE----- + +# Issuer: CN=UCA Global G2 Root O=UniTrust +# Subject: CN=UCA Global G2 Root O=UniTrust +# Label: "UCA Global G2 Root" +# Serial: 124779693093741543919145257850076631279 +# MD5 Fingerprint: 80:fe:f0:c4:4a:f0:5c:62:32:9f:1c:ba:78:a9:50:f8 +# SHA1 Fingerprint: 28:f9:78:16:19:7a:ff:18:25:18:aa:44:fe:c1:a0:ce:5c:b6:4c:8a +# SHA256 Fingerprint: 9b:ea:11:c9:76:fe:01:47:64:c1:be:56:a6:f9:14:b5:a5:60:31:7a:bd:99:88:39:33:82:e5:16:1a:a0:49:3c +-----BEGIN CERTIFICATE----- +MIIFRjCCAy6gAwIBAgIQXd+x2lqj7V2+WmUgZQOQ7zANBgkqhkiG9w0BAQsFADA9 +MQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxGzAZBgNVBAMMElVDQSBH +bG9iYWwgRzIgUm9vdDAeFw0xNjAzMTEwMDAwMDBaFw00MDEyMzEwMDAwMDBaMD0x +CzAJBgNVBAYTAkNOMREwDwYDVQQKDAhVbmlUcnVzdDEbMBkGA1UEAwwSVUNBIEds +b2JhbCBHMiBSb290MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxeYr +b3zvJgUno4Ek2m/LAfmZmqkywiKHYUGRO8vDaBsGxUypK8FnFyIdK+35KYmToni9 +kmugow2ifsqTs6bRjDXVdfkX9s9FxeV67HeToI8jrg4aA3++1NDtLnurRiNb/yzm +VHqUwCoV8MmNsHo7JOHXaOIxPAYzRrZUEaalLyJUKlgNAQLx+hVRZ2zA+te2G3/R +VogvGjqNO7uCEeBHANBSh6v7hn4PJGtAnTRnvI3HLYZveT6OqTwXS3+wmeOwcWDc +C/Vkw85DvG1xudLeJ1uK6NjGruFZfc8oLTW4lVYa8bJYS7cSN8h8s+1LgOGN+jIj +tm+3SJUIsUROhYw6AlQgL9+/V087OpAh18EmNVQg7Mc/R+zvWr9LesGtOxdQXGLY +D0tK3Cv6brxzks3sx1DoQZbXqX5t2Okdj4q1uViSukqSKwxW/YDrCPBeKW4bHAyv +j5OJrdu9o54hyokZ7N+1wxrrFv54NkzWbtA+FxyQF2smuvt6L78RHBgOLXMDj6Dl +NaBa4kx1HXHhOThTeEDMg5PXCp6dW4+K5OXgSORIskfNTip1KnvyIvbJvgmRlld6 +iIis7nCs+dwp4wwcOxJORNanTrAmyPPZGpeRaOrvjUYG0lZFWJo8DA+DuAUlwznP +O6Q0ibd5Ei9Hxeepl2n8pndntd978XplFeRhVmUCAwEAAaNCMEAwDgYDVR0PAQH/ +BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFIHEjMz15DD/pQwIX4wV +ZyF0Ad/fMA0GCSqGSIb3DQEBCwUAA4ICAQATZSL1jiutROTL/7lo5sOASD0Ee/oj +L3rtNtqyzm325p7lX1iPyzcyochltq44PTUbPrw7tgTQvPlJ9Zv3hcU2tsu8+Mg5 +1eRfB70VVJd0ysrtT7q6ZHafgbiERUlMjW+i67HM0cOU2kTC5uLqGOiiHycFutfl +1qnN3e92mI0ADs0b+gO3joBYDic/UvuUospeZcnWhNq5NXHzJsBPd+aBJ9J3O5oU +b3n09tDh05S60FdRvScFDcH9yBIw7m+NESsIndTUv4BFFJqIRNow6rSn4+7vW4LV +PtateJLbXDzz2K36uGt/xDYotgIVilQsnLAXc47QN6MUPJiVAAwpBVueSUmxX8fj +y88nZY41F7dXyDDZQVu5FLbowg+UMaeUmMxq67XhJ/UQqAHojhJi6IjMtX9Gl8Cb +EGY4GjZGXyJoPd/JxhMnq1MGrKI8hgZlb7F+sSlEmqO6SWkoaY/X5V+tBIZkbxqg +DMUIYs6Ao9Dz7GjevjPHF1t/gMRMTLGmhIrDO7gJzRSBuhjjVFc2/tsvfEehOjPI ++Vg7RE+xygKJBJYoaMVLuCaJu9YzL1DV/pqJuhgyklTGW+Cd+V7lDSKb9triyCGy +YiGqhkCyLmTTX8jjfhFnRR8F/uOi77Oos/N9j/gMHyIfLXC0uAE0djAA5SN4p1bX +UB+K+wb1whnw0A== +-----END CERTIFICATE----- + +# Issuer: CN=UCA Extended Validation Root O=UniTrust +# Subject: CN=UCA Extended Validation Root O=UniTrust +# Label: "UCA Extended Validation Root" +# Serial: 106100277556486529736699587978573607008 +# MD5 Fingerprint: a1:f3:5f:43:c6:34:9b:da:bf:8c:7e:05:53:ad:96:e2 +# SHA1 Fingerprint: a3:a1:b0:6f:24:61:23:4a:e3:36:a5:c2:37:fc:a6:ff:dd:f0:d7:3a +# SHA256 Fingerprint: d4:3a:f9:b3:54:73:75:5c:96:84:fc:06:d7:d8:cb:70:ee:5c:28:e7:73:fb:29:4e:b4:1e:e7:17:22:92:4d:24 +-----BEGIN CERTIFICATE----- +MIIFWjCCA0KgAwIBAgIQT9Irj/VkyDOeTzRYZiNwYDANBgkqhkiG9w0BAQsFADBH +MQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNVBAMMHFVDQSBF +eHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwHhcNMTUwMzEzMDAwMDAwWhcNMzgxMjMx +MDAwMDAwWjBHMQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNV +BAMMHFVDQSBFeHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQCpCQcoEwKwmeBkqh5DFnpzsZGgdT6o+uM4AHrsiWog +D4vFsJszA1qGxliG1cGFu0/GnEBNyr7uaZa4rYEwmnySBesFK5pI0Lh2PpbIILvS +sPGP2KxFRv+qZ2C0d35qHzwaUnoEPQc8hQ2E0B92CvdqFN9y4zR8V05WAT558aop +O2z6+I9tTcg1367r3CTueUWnhbYFiN6IXSV8l2RnCdm/WhUFhvMJHuxYMjMR83dk +sHYf5BA1FxvyDrFspCqjc/wJHx4yGVMR59mzLC52LqGj3n5qiAno8geK+LLNEOfi +c0CTuwjRP+H8C5SzJe98ptfRr5//lpr1kXuYC3fUfugH0mK1lTnj8/FtDw5lhIpj +VMWAtuCeS31HJqcBCF3RiJ7XwzJE+oJKCmhUfzhTA8ykADNkUVkLo4KRel7sFsLz +KuZi2irbWWIQJUoqgQtHB0MGcIfS+pMRKXpITeuUx3BNr2fVUbGAIAEBtHoIppB/ +TuDvB0GHr2qlXov7z1CymlSvw4m6WC31MJixNnI5fkkE/SmnTHnkBVfblLkWU41G +sx2VYVdWf6/wFlthWG82UBEL2KwrlRYaDh8IzTY0ZRBiZtWAXxQgXy0MoHgKaNYs +1+lvK9JKBZP8nm9rZ/+I8U6laUpSNwXqxhaN0sSZ0YIrO7o1dfdRUVjzyAfd5LQD +fwIDAQABo0IwQDAdBgNVHQ4EFgQU2XQ65DA9DfcS3H5aBZ8eNJr34RQwDwYDVR0T +AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQADggIBADaN +l8xCFWQpN5smLNb7rhVpLGsaGvdftvkHTFnq88nIua7Mui563MD1sC3AO6+fcAUR +ap8lTwEpcOPlDOHqWnzcSbvBHiqB9RZLcpHIojG5qtr8nR/zXUACE/xOHAbKsxSQ +VBcZEhrxH9cMaVr2cXj0lH2RC47skFSOvG+hTKv8dGT9cZr4QQehzZHkPJrgmzI5 +c6sq1WnIeJEmMX3ixzDx/BR4dxIOE/TdFpS/S2d7cFOFyrC78zhNLJA5wA3CXWvp +4uXViI3WLL+rG761KIcSF3Ru/H38j9CHJrAb+7lsq+KePRXBOy5nAliRn+/4Qh8s +t2j1da3Ptfb/EX3C8CSlrdP6oDyp+l3cpaDvRKS+1ujl5BOWF3sGPjLtx7dCvHaj +2GU4Kzg1USEODm8uNBNA4StnDG1KQTAYI1oyVZnJF+A83vbsea0rWBmirSwiGpWO +vpaQXUJXxPkUAzUrHC1RVwinOt4/5Mi0A3PCwSaAuwtCH60NryZy2sy+s6ODWA2C +xR9GUeOcGMyNm43sSet1UNWMKFnKdDTajAshqx7qG+XH/RU+wBeq+yNuJkbL+vmx +cmtpzyKEC2IPrNkZAJSidjzULZrtBJ4tBmIQN1IchXIbJ+XMxjHsN+xjWZsLHXbM +fjKaiJUINlK73nZfdklJrX+9ZSCyycErdhh2n1ax +-----END CERTIFICATE----- + +# Issuer: CN=Certigna Root CA O=Dhimyotis OU=0002 48146308100036 +# Subject: CN=Certigna Root CA O=Dhimyotis OU=0002 48146308100036 +# Label: "Certigna Root CA" +# Serial: 269714418870597844693661054334862075617 +# MD5 Fingerprint: 0e:5c:30:62:27:eb:5b:bc:d7:ae:62:ba:e9:d5:df:77 +# SHA1 Fingerprint: 2d:0d:52:14:ff:9e:ad:99:24:01:74:20:47:6e:6c:85:27:27:f5:43 +# SHA256 Fingerprint: d4:8d:3d:23:ee:db:50:a4:59:e5:51:97:60:1c:27:77:4b:9d:7b:18:c9:4d:5a:05:95:11:a1:02:50:b9:31:68 +-----BEGIN CERTIFICATE----- +MIIGWzCCBEOgAwIBAgIRAMrpG4nxVQMNo+ZBbcTjpuEwDQYJKoZIhvcNAQELBQAw +WjELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczEcMBoGA1UECwwTMDAw +MiA0ODE0NjMwODEwMDAzNjEZMBcGA1UEAwwQQ2VydGlnbmEgUm9vdCBDQTAeFw0x +MzEwMDEwODMyMjdaFw0zMzEwMDEwODMyMjdaMFoxCzAJBgNVBAYTAkZSMRIwEAYD +VQQKDAlEaGlteW90aXMxHDAaBgNVBAsMEzAwMDIgNDgxNDYzMDgxMDAwMzYxGTAX +BgNVBAMMEENlcnRpZ25hIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw +ggIKAoICAQDNGDllGlmx6mQWDoyUJJV8g9PFOSbcDO8WV43X2KyjQn+Cyu3NW9sO +ty3tRQgXstmzy9YXUnIo245Onoq2C/mehJpNdt4iKVzSs9IGPjA5qXSjklYcoW9M +CiBtnyN6tMbaLOQdLNyzKNAT8kxOAkmhVECe5uUFoC2EyP+YbNDrihqECB63aCPu +I9Vwzm1RaRDuoXrC0SIxwoKF0vJVdlB8JXrJhFwLrN1CTivngqIkicuQstDuI7pm +TLtipPlTWmR7fJj6o0ieD5Wupxj0auwuA0Wv8HT4Ks16XdG+RCYyKfHx9WzMfgIh +C59vpD++nVPiz32pLHxYGpfhPTc3GGYo0kDFUYqMwy3OU4gkWGQwFsWq4NYKpkDf +ePb1BHxpE4S80dGnBs8B92jAqFe7OmGtBIyT46388NtEbVncSVmurJqZNjBBe3Yz +IoejwpKGbvlw7q6Hh5UbxHq9MfPU0uWZ/75I7HX1eBYdpnDBfzwboZL7z8g81sWT +Co/1VTp2lc5ZmIoJlXcymoO6LAQ6l73UL77XbJuiyn1tJslV1c/DeVIICZkHJC1k +JWumIWmbat10TWuXekG9qxf5kBdIjzb5LdXF2+6qhUVB+s06RbFo5jZMm5BX7CO5 +hwjCxAnxl4YqKE3idMDaxIzb3+KhF1nOJFl0Mdp//TBt2dzhauH8XwIDAQABo4IB +GjCCARYwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE +FBiHVuBud+4kNTxOc5of1uHieX4rMB8GA1UdIwQYMBaAFBiHVuBud+4kNTxOc5of +1uHieX4rMEQGA1UdIAQ9MDswOQYEVR0gADAxMC8GCCsGAQUFBwIBFiNodHRwczov +L3d3d3cuY2VydGlnbmEuZnIvYXV0b3JpdGVzLzBtBgNVHR8EZjBkMC+gLaArhilo +dHRwOi8vY3JsLmNlcnRpZ25hLmZyL2NlcnRpZ25hcm9vdGNhLmNybDAxoC+gLYYr +aHR0cDovL2NybC5kaGlteW90aXMuY29tL2NlcnRpZ25hcm9vdGNhLmNybDANBgkq +hkiG9w0BAQsFAAOCAgEAlLieT/DjlQgi581oQfccVdV8AOItOoldaDgvUSILSo3L +6btdPrtcPbEo/uRTVRPPoZAbAh1fZkYJMyjhDSSXcNMQH+pkV5a7XdrnxIxPTGRG +HVyH41neQtGbqH6mid2PHMkwgu07nM3A6RngatgCdTer9zQoKJHyBApPNeNgJgH6 +0BGM+RFq7q89w1DTj18zeTyGqHNFkIwgtnJzFyO+B2XleJINugHA64wcZr+shncB +lA2c5uk5jR+mUYyZDDl34bSb+hxnV29qao6pK0xXeXpXIs/NX2NGjVxZOob4Mkdi +o2cNGJHc+6Zr9UhhcyNZjgKnvETq9Emd8VRY+WCv2hikLyhF3HqgiIZd8zvn/yk1 +gPxkQ5Tm4xxvvq0OKmOZK8l+hfZx6AYDlf7ej0gcWtSS6Cvu5zHbugRqh5jnxV/v +faci9wHYTfmJ0A6aBVmknpjZbyvKcL5kwlWj9Omvw5Ip3IgWJJk8jSaYtlu3zM63 +Nwf9JtmYhST/WSMDmu2dnajkXjjO11INb9I/bbEFa0nOipFGc/T2L/Coc3cOZayh +jWZSaX5LaAzHHjcng6WMxwLkFM1JAbBzs/3GkDpv0mztO+7skb6iQ12LAEpmJURw +3kAP+HwV96LOPNdeE4yBFxgX0b3xdxA61GU5wSesVywlVP+i2k+KYTlerj1KjL0= +-----END CERTIFICATE----- + +# Issuer: CN=emSign Root CA - G1 O=eMudhra Technologies Limited OU=emSign PKI +# Subject: CN=emSign Root CA - G1 O=eMudhra Technologies Limited OU=emSign PKI +# Label: "emSign Root CA - G1" +# Serial: 235931866688319308814040 +# MD5 Fingerprint: 9c:42:84:57:dd:cb:0b:a7:2e:95:ad:b6:f3:da:bc:ac +# SHA1 Fingerprint: 8a:c7:ad:8f:73:ac:4e:c1:b5:75:4d:a5:40:f4:fc:cf:7c:b5:8e:8c +# SHA256 Fingerprint: 40:f6:af:03:46:a9:9a:a1:cd:1d:55:5a:4e:9c:ce:62:c7:f9:63:46:03:ee:40:66:15:83:3d:c8:c8:d0:03:67 +-----BEGIN CERTIFICATE----- +MIIDlDCCAnygAwIBAgIKMfXkYgxsWO3W2DANBgkqhkiG9w0BAQsFADBnMQswCQYD +VQQGEwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBU +ZWNobm9sb2dpZXMgTGltaXRlZDEcMBoGA1UEAxMTZW1TaWduIFJvb3QgQ0EgLSBH +MTAeFw0xODAyMTgxODMwMDBaFw00MzAyMTgxODMwMDBaMGcxCzAJBgNVBAYTAklO +MRMwEQYDVQQLEwplbVNpZ24gUEtJMSUwIwYDVQQKExxlTXVkaHJhIFRlY2hub2xv +Z2llcyBMaW1pdGVkMRwwGgYDVQQDExNlbVNpZ24gUm9vdCBDQSAtIEcxMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAk0u76WaK7p1b1TST0Bsew+eeuGQz +f2N4aLTNLnF115sgxk0pvLZoYIr3IZpWNVrzdr3YzZr/k1ZLpVkGoZM0Kd0WNHVO +8oG0x5ZOrRkVUkr+PHB1cM2vK6sVmjM8qrOLqs1D/fXqcP/tzxE7lM5OMhbTI0Aq +d7OvPAEsbO2ZLIvZTmmYsvePQbAyeGHWDV/D+qJAkh1cF+ZwPjXnorfCYuKrpDhM +tTk1b+oDafo6VGiFbdbyL0NVHpENDtjVaqSW0RM8LHhQ6DqS0hdW5TUaQBw+jSzt +Od9C4INBdN+jzcKGYEho42kLVACL5HZpIQ15TjQIXhTCzLG3rdd8cIrHhQIDAQAB +o0IwQDAdBgNVHQ4EFgQU++8Nhp6w492pufEhF38+/PB3KxowDgYDVR0PAQH/BAQD +AgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAFn/8oz1h31x +PaOfG1vR2vjTnGs2vZupYeveFix0PZ7mddrXuqe8QhfnPZHr5X3dPpzxz5KsbEjM +wiI/aTvFthUvozXGaCocV685743QNcMYDHsAVhzNixl03r4PEuDQqqE/AjSxcM6d +GNYIAwlG7mDgfrbESQRRfXBgvKqy/3lyeqYdPV8q+Mri/Tm3R7nrft8EI6/6nAYH +6ftjk4BAtcZsCjEozgyfz7MjNYBBjWzEN3uBL4ChQEKF6dk4jeihU80Bv2noWgby +RQuQ+q7hv53yrlc8pa6yVvSLZUDp/TGBLPQ5Cdjua6e0ph0VpZj3AYHYhX3zUVxx +iN66zB+Afko= +-----END CERTIFICATE----- + +# Issuer: CN=emSign ECC Root CA - G3 O=eMudhra Technologies Limited OU=emSign PKI +# Subject: CN=emSign ECC Root CA - G3 O=eMudhra Technologies Limited OU=emSign PKI +# Label: "emSign ECC Root CA - G3" +# Serial: 287880440101571086945156 +# MD5 Fingerprint: ce:0b:72:d1:9f:88:8e:d0:50:03:e8:e3:b8:8b:67:40 +# SHA1 Fingerprint: 30:43:fa:4f:f2:57:dc:a0:c3:80:ee:2e:58:ea:78:b2:3f:e6:bb:c1 +# SHA256 Fingerprint: 86:a1:ec:ba:08:9c:4a:8d:3b:be:27:34:c6:12:ba:34:1d:81:3e:04:3c:f9:e8:a8:62:cd:5c:57:a3:6b:be:6b +-----BEGIN CERTIFICATE----- +MIICTjCCAdOgAwIBAgIKPPYHqWhwDtqLhDAKBggqhkjOPQQDAzBrMQswCQYDVQQG +EwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNo +bm9sb2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0g +RzMwHhcNMTgwMjE4MTgzMDAwWhcNNDMwMjE4MTgzMDAwWjBrMQswCQYDVQQGEwJJ +TjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNobm9s +b2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0gRzMw +djAQBgcqhkjOPQIBBgUrgQQAIgNiAAQjpQy4LRL1KPOxst3iAhKAnjlfSU2fySU0 +WXTsuwYc58Byr+iuL+FBVIcUqEqy6HyC5ltqtdyzdc6LBtCGI79G1Y4PPwT01xyS +fvalY8L1X44uT6EYGQIrMgqCZH0Wk9GjQjBAMB0GA1UdDgQWBBR8XQKEE9TMipuB +zhccLikenEhjQjAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggq +hkjOPQQDAwNpADBmAjEAvvNhzwIQHWSVB7gYboiFBS+DCBeQyh+KTOgNG3qxrdWB +CUfvO6wIBHxcmbHtRwfSAjEAnbpV/KlK6O3t5nYBQnvI+GDZjVGLVTv7jHvrZQnD ++JbNR6iC8hZVdyR+EhCVBCyj +-----END CERTIFICATE----- + +# Issuer: CN=emSign Root CA - C1 O=eMudhra Inc OU=emSign PKI +# Subject: CN=emSign Root CA - C1 O=eMudhra Inc OU=emSign PKI +# Label: "emSign Root CA - C1" +# Serial: 825510296613316004955058 +# MD5 Fingerprint: d8:e3:5d:01:21:fa:78:5a:b0:df:ba:d2:ee:2a:5f:68 +# SHA1 Fingerprint: e7:2e:f1:df:fc:b2:09:28:cf:5d:d4:d5:67:37:b1:51:cb:86:4f:01 +# SHA256 Fingerprint: 12:56:09:aa:30:1d:a0:a2:49:b9:7a:82:39:cb:6a:34:21:6f:44:dc:ac:9f:39:54:b1:42:92:f2:e8:c8:60:8f +-----BEGIN CERTIFICATE----- +MIIDczCCAlugAwIBAgILAK7PALrEzzL4Q7IwDQYJKoZIhvcNAQELBQAwVjELMAkG +A1UEBhMCVVMxEzARBgNVBAsTCmVtU2lnbiBQS0kxFDASBgNVBAoTC2VNdWRocmEg +SW5jMRwwGgYDVQQDExNlbVNpZ24gUm9vdCBDQSAtIEMxMB4XDTE4MDIxODE4MzAw +MFoXDTQzMDIxODE4MzAwMFowVjELMAkGA1UEBhMCVVMxEzARBgNVBAsTCmVtU2ln +biBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMRwwGgYDVQQDExNlbVNpZ24gUm9v +dCBDQSAtIEMxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAz+upufGZ +BczYKCFK83M0UYRWEPWgTywS4/oTmifQz/l5GnRfHXk5/Fv4cI7gklL35CX5VIPZ +HdPIWoU/Xse2B+4+wM6ar6xWQio5JXDWv7V7Nq2s9nPczdcdioOl+yuQFTdrHCZH +3DspVpNqs8FqOp099cGXOFgFixwR4+S0uF2FHYP+eF8LRWgYSKVGczQ7/g/IdrvH +GPMF0Ybzhe3nudkyrVWIzqa2kbBPrH4VI5b2P/AgNBbeCsbEBEV5f6f9vtKppa+c +xSMq9zwhbL2vj07FOrLzNBL834AaSaTUqZX3noleoomslMuoaJuvimUnzYnu3Yy1 +aylwQ6BpC+S5DwIDAQABo0IwQDAdBgNVHQ4EFgQU/qHgcB4qAzlSWkK+XJGFehiq +TbUwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL +BQADggEBAMJKVvoVIXsoounlHfv4LcQ5lkFMOycsxGwYFYDGrK9HWS8mC+M2sO87 +/kOXSTKZEhVb3xEp/6tT+LvBeA+snFOvV71ojD1pM/CjoCNjO2RnIkSt1XHLVip4 +kqNPEjE2NuLe/gDEo2APJ62gsIq1NnpSob0n9CAnYuhNlCQT5AoE6TyrLshDCUrG +YQTlSTR+08TI9Q/Aqum6VF7zYytPT1DU/rl7mYw9wC68AivTxEDkigcxHpvOJpkT ++xHqmiIMERnHXhuBUDDIlhJu58tBf5E7oke3VIAb3ADMmpDqw8NQBmIMMMAVSKeo +WXzhriKi4gp6D/piq1JM4fHfyr6DDUI= +-----END CERTIFICATE----- + +# Issuer: CN=emSign ECC Root CA - C3 O=eMudhra Inc OU=emSign PKI +# Subject: CN=emSign ECC Root CA - C3 O=eMudhra Inc OU=emSign PKI +# Label: "emSign ECC Root CA - C3" +# Serial: 582948710642506000014504 +# MD5 Fingerprint: 3e:53:b3:a3:81:ee:d7:10:f8:d3:b0:1d:17:92:f5:d5 +# SHA1 Fingerprint: b6:af:43:c2:9b:81:53:7d:f6:ef:6b:c3:1f:1f:60:15:0c:ee:48:66 +# SHA256 Fingerprint: bc:4d:80:9b:15:18:9d:78:db:3e:1d:8c:f4:f9:72:6a:79:5d:a1:64:3c:a5:f1:35:8e:1d:db:0e:dc:0d:7e:b3 +-----BEGIN CERTIFICATE----- +MIICKzCCAbGgAwIBAgIKe3G2gla4EnycqDAKBggqhkjOPQQDAzBaMQswCQYDVQQG +EwJVUzETMBEGA1UECxMKZW1TaWduIFBLSTEUMBIGA1UEChMLZU11ZGhyYSBJbmMx +IDAeBgNVBAMTF2VtU2lnbiBFQ0MgUm9vdCBDQSAtIEMzMB4XDTE4MDIxODE4MzAw +MFoXDTQzMDIxODE4MzAwMFowWjELMAkGA1UEBhMCVVMxEzARBgNVBAsTCmVtU2ln +biBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMSAwHgYDVQQDExdlbVNpZ24gRUND +IFJvb3QgQ0EgLSBDMzB2MBAGByqGSM49AgEGBSuBBAAiA2IABP2lYa57JhAd6bci +MK4G9IGzsUJxlTm801Ljr6/58pc1kjZGDoeVjbk5Wum739D+yAdBPLtVb4Ojavti +sIGJAnB9SMVK4+kiVCJNk7tCDK93nCOmfddhEc5lx/h//vXyqaNCMEAwHQYDVR0O +BBYEFPtaSNCAIEDyqOkAB2kZd6fmw/TPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMB +Af8EBTADAQH/MAoGCCqGSM49BAMDA2gAMGUCMQC02C8Cif22TGK6Q04ThHK1rt0c +3ta13FaPWEBaLd4gTCKDypOofu4SQMfWh0/434UCMBwUZOR8loMRnLDRWmFLpg9J +0wD8ofzkpf9/rdcw0Md3f76BB1UwUCAU9Vc4CqgxUQ== +-----END CERTIFICATE----- + +# Issuer: CN=Hongkong Post Root CA 3 O=Hongkong Post +# Subject: CN=Hongkong Post Root CA 3 O=Hongkong Post +# Label: "Hongkong Post Root CA 3" +# Serial: 46170865288971385588281144162979347873371282084 +# MD5 Fingerprint: 11:fc:9f:bd:73:30:02:8a:fd:3f:f3:58:b9:cb:20:f0 +# SHA1 Fingerprint: 58:a2:d0:ec:20:52:81:5b:c1:f3:f8:64:02:24:4e:c2:8e:02:4b:02 +# SHA256 Fingerprint: 5a:2f:c0:3f:0c:83:b0:90:bb:fa:40:60:4b:09:88:44:6c:76:36:18:3d:f9:84:6e:17:10:1a:44:7f:b8:ef:d6 +-----BEGIN CERTIFICATE----- +MIIFzzCCA7egAwIBAgIUCBZfikyl7ADJk0DfxMauI7gcWqQwDQYJKoZIhvcNAQEL +BQAwbzELMAkGA1UEBhMCSEsxEjAQBgNVBAgTCUhvbmcgS29uZzESMBAGA1UEBxMJ +SG9uZyBLb25nMRYwFAYDVQQKEw1Ib25na29uZyBQb3N0MSAwHgYDVQQDExdIb25n +a29uZyBQb3N0IFJvb3QgQ0EgMzAeFw0xNzA2MDMwMjI5NDZaFw00MjA2MDMwMjI5 +NDZaMG8xCzAJBgNVBAYTAkhLMRIwEAYDVQQIEwlIb25nIEtvbmcxEjAQBgNVBAcT +CUhvbmcgS29uZzEWMBQGA1UEChMNSG9uZ2tvbmcgUG9zdDEgMB4GA1UEAxMXSG9u +Z2tvbmcgUG9zdCBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK +AoICAQCziNfqzg8gTr7m1gNt7ln8wlffKWihgw4+aMdoWJwcYEuJQwy51BWy7sFO +dem1p+/l6TWZ5Mwc50tfjTMwIDNT2aa71T4Tjukfh0mtUC1Qyhi+AViiE3CWu4mI +VoBc+L0sPOFMV4i707mV78vH9toxdCim5lSJ9UExyuUmGs2C4HDaOym71QP1mbpV +9WTRYA6ziUm4ii8F0oRFKHyPaFASePwLtVPLwpgchKOesL4jpNrcyCse2m5FHomY +2vkALgbpDDtw1VAliJnLzXNg99X/NWfFobxeq81KuEXryGgeDQ0URhLj0mRiikKY +vLTGCAj4/ahMZJx2Ab0vqWwzD9g/KLg8aQFChn5pwckGyuV6RmXpwtZQQS4/t+Tt +bNe/JgERohYpSms0BpDsE9K2+2p20jzt8NYt3eEV7KObLyzJPivkaTv/ciWxNoZb +x39ri1UbSsUgYT2uy1DhCDq+sI9jQVMwCFk8mB13umOResoQUGC/8Ne8lYePl8X+ +l2oBlKN8W4UdKjk60FSh0Tlxnf0h+bV78OLgAo9uliQlLKAeLKjEiafv7ZkGL7YK +TE/bosw3Gq9HhS2KX8Q0NEwA/RiTZxPRN+ZItIsGxVd7GYYKecsAyVKvQv83j+Gj +Hno9UKtjBucVtT+2RTeUN7F+8kjDf8V1/peNRY8apxpyKBpADwIDAQABo2MwYTAP +BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBQXnc0e +i9Y5K3DTXNSguB+wAPzFYTAdBgNVHQ4EFgQUF53NHovWOStw01zUoLgfsAD8xWEw +DQYJKoZIhvcNAQELBQADggIBAFbVe27mIgHSQpsY1Q7XZiNc4/6gx5LS6ZStS6LG +7BJ8dNVI0lkUmcDrudHr9EgwW62nV3OZqdPlt9EuWSRY3GguLmLYauRwCy0gUCCk +MpXRAJi70/33MvJJrsZ64Ee+bs7Lo3I6LWldy8joRTnU+kLBEUx3XZL7av9YROXr +gZ6voJmtvqkBZss4HTzfQx/0TW60uhdG/H39h4F5ag0zD/ov+BS5gLNdTaqX4fnk +GMX41TiMJjz98iji7lpJiCzfeT2OnpA8vUFKOt1b9pq0zj8lMH8yfaIDlNDceqFS +3m6TjRgm/VWsvY+b0s+v54Ysyx8Jb6NvqYTUc79NoXQbTiNg8swOqn+knEwlqLJm +Ozj/2ZQw9nKEvmhVEA/GcywWaZMH/rFF7buiVWqw2rVKAiUnhde3t4ZEFolsgCs+ +l6mc1X5VTMbeRRAc6uk7nwNT7u56AQIWeNTowr5GdogTPyK7SBIdUgC0An4hGh6c +JfTzPV4e0hz5sy229zdcxsshTrD3mUcYhcErulWuBurQB7Lcq9CClnXO0lD+mefP +L5/ndtFhKvshuzHQqp9HpLIiyhY6UFfEW0NnxWViA0kB60PZ2Pierc+xYw5F9KBa +LJstxabArahH9CdMOA0uG0k7UvToiIMrVCjU8jVStDKDYmlkDJGcn5fqdBb9HxEG +mpv0 +-----END CERTIFICATE----- diff --git a/examples/BUILD b/examples/BUILD index 0f18cfa9ba7..a9dd94902a4 100644 --- a/examples/BUILD +++ b/examples/BUILD @@ -17,6 +17,8 @@ licenses(["notice"]) # 3-clause BSD package(default_visibility = ["//visibility:public"]) load("//bazel:grpc_build_system.bzl", "grpc_proto_library") +load("//bazel:cc_grpc_library.bzl", "cc_grpc_library") +load("//bazel:python_rules.bzl", "py_proto_library") grpc_proto_library( name = "auth_sample", @@ -28,26 +30,204 @@ grpc_proto_library( srcs = ["protos/hellostreamingworld.proto"], ) -grpc_proto_library( - name = "helloworld", +# The following three rules demonstrate the usage of the cc_grpc_library rule in +# in a mode compatible with the native proto_library and cc_proto_library rules. +proto_library( + name = "helloworld_proto", srcs = ["protos/helloworld.proto"], ) +cc_proto_library( + name = "helloworld_cc_proto", + deps = [":helloworld_proto"], +) + +cc_grpc_library( + name = "helloworld_cc_grpc", + srcs = [":helloworld_proto"], + grpc_only = True, + deps = [":helloworld_cc_proto"], +) + grpc_proto_library( name = "route_guide", srcs = ["protos/route_guide.proto"], ) +grpc_proto_library( + name = "keyvaluestore", + srcs = ["protos/keyvaluestore.proto"], +) + +proto_library( + name = "helloworld_proto_descriptor", + srcs = ["protos/helloworld.proto"], +) + +py_proto_library( + name = "py_helloworld", + deps = [":helloworld_proto_descriptor"], +) + cc_binary( name = "greeter_client", srcs = ["cpp/helloworld/greeter_client.cc"], defines = ["BAZEL_BUILD"], - deps = [":helloworld", "//:grpc++"], + deps = [ + ":helloworld_cc_grpc", + "//:grpc++", + ], +) + +cc_binary( + name = "greeter_async_client", + srcs = ["cpp/helloworld/greeter_async_client.cc"], + defines = ["BAZEL_BUILD"], + deps = [ + ":helloworld_cc_grpc", + "//:grpc++", + ], +) + +cc_binary( + name = "greeter_async_client2", + srcs = ["cpp/helloworld/greeter_async_client2.cc"], + defines = ["BAZEL_BUILD"], + deps = [ + ":helloworld_cc_grpc", + "//:grpc++", + ], ) cc_binary( name = "greeter_server", srcs = ["cpp/helloworld/greeter_server.cc"], defines = ["BAZEL_BUILD"], - deps = [":helloworld", "//:grpc++"], + deps = [ + ":helloworld_cc_grpc", + "//:grpc++", + ], +) + +cc_binary( + name = "greeter_async_server", + srcs = ["cpp/helloworld/greeter_async_server.cc"], + defines = ["BAZEL_BUILD"], + deps = [ + ":helloworld_cc_grpc", + "//:grpc++", + ], +) + +cc_binary( + name = "metadata_client", + srcs = ["cpp/metadata/greeter_client.cc"], + defines = ["BAZEL_BUILD"], + deps = [ + ":helloworld_cc_grpc", + "//:grpc++", + ], +) + +cc_binary( + name = "metadata_server", + srcs = ["cpp/metadata/greeter_server.cc"], + defines = ["BAZEL_BUILD"], + deps = [ + ":helloworld_cc_grpc", + "//:grpc++", + ], +) + +cc_binary( + name = "lb_client", + srcs = ["cpp/load_balancing/greeter_client.cc"], + defines = ["BAZEL_BUILD"], + deps = [ + ":helloworld_cc_grpc", + "//:grpc++", + ], +) + +cc_binary( + name = "lb_server", + srcs = ["cpp/load_balancing/greeter_server.cc"], + defines = ["BAZEL_BUILD"], + deps = [ + ":helloworld_cc_grpc", + "//:grpc++", + ], +) + +cc_binary( + name = "compression_client", + srcs = ["cpp/compression/greeter_client.cc"], + defines = ["BAZEL_BUILD"], + deps = [ + ":helloworld_cc_grpc", + "//:grpc++", + ], +) + +cc_binary( + name = "compression_server", + srcs = ["cpp/compression/greeter_server.cc"], + defines = ["BAZEL_BUILD"], + deps = [ + ":helloworld_cc_grpc", + "//:grpc++", + ], +) + +cc_binary( + name = "keyvaluestore_client", + srcs = [ + "cpp/keyvaluestore/caching_interceptor.h", + "cpp/keyvaluestore/client.cc", + ], + defines = ["BAZEL_BUILD"], + deps = [ + ":keyvaluestore", + "//:grpc++", + ], +) + +cc_binary( + name = "keyvaluestore_server", + srcs = ["cpp/keyvaluestore/server.cc"], + defines = ["BAZEL_BUILD"], + deps = [ + ":keyvaluestore", + "//:grpc++", + ], +) + +cc_binary( + name = "route_guide_client", + srcs = [ + "cpp/route_guide/helper.cc", + "cpp/route_guide/helper.h", + "cpp/route_guide/route_guide_client.cc", + ], + data = ["cpp/route_guide/route_guide_db.json"], + defines = ["BAZEL_BUILD"], + deps = [ + ":route_guide", + "//:grpc++", + ], +) + +cc_binary( + name = "route_guide_server", + srcs = [ + "cpp/route_guide/helper.cc", + "cpp/route_guide/helper.h", + "cpp/route_guide/route_guide_server.cc", + ], + data = ["cpp/route_guide/route_guide_db.json"], + defines = ["BAZEL_BUILD"], + deps = [ + ":route_guide", + "//:grpc++", + ], ) diff --git a/examples/cpp/compression/Makefile b/examples/cpp/compression/Makefile new file mode 100644 index 00000000000..47211886ff6 --- /dev/null +++ b/examples/cpp/compression/Makefile @@ -0,0 +1,110 @@ +# +# 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. +# + +HOST_SYSTEM = $(shell uname | cut -f 1 -d_) +SYSTEM ?= $(HOST_SYSTEM) +CXX = g++ +CPPFLAGS += `pkg-config --cflags protobuf grpc` +CXXFLAGS += -std=c++11 +ifeq ($(SYSTEM),Darwin) +LDFLAGS += -L/usr/local/lib `pkg-config --libs protobuf grpc++ grpc`\ + -lgrpc++_reflection\ + -ldl +else +LDFLAGS += -L/usr/local/lib `pkg-config --libs protobuf grpc++ grpc`\ + -Wl,--no-as-needed -lgrpc++_reflection -Wl,--as-needed\ + -ldl +endif +PROTOC = protoc +GRPC_CPP_PLUGIN = grpc_cpp_plugin +GRPC_CPP_PLUGIN_PATH ?= `which $(GRPC_CPP_PLUGIN)` + +PROTOS_PATH = ../../protos + +vpath %.proto $(PROTOS_PATH) + +all: system-check greeter_client greeter_server + +greeter_client: helloworld.pb.o helloworld.grpc.pb.o greeter_client.o + $(CXX) $^ $(LDFLAGS) -o $@ + +greeter_server: helloworld.pb.o helloworld.grpc.pb.o greeter_server.o + $(CXX) $^ $(LDFLAGS) -o $@ + +.PRECIOUS: %.grpc.pb.cc +%.grpc.pb.cc: %.proto + $(PROTOC) -I $(PROTOS_PATH) --grpc_out=. --plugin=protoc-gen-grpc=$(GRPC_CPP_PLUGIN_PATH) $< + +.PRECIOUS: %.pb.cc +%.pb.cc: %.proto + $(PROTOC) -I $(PROTOS_PATH) --cpp_out=. $< + +clean: + rm -f *.o *.pb.cc *.pb.h greeter_client greeter_server + + +# The following is to test your system and ensure a smoother experience. +# They are by no means necessary to actually compile a grpc-enabled software. + +PROTOC_CMD = which $(PROTOC) +PROTOC_CHECK_CMD = $(PROTOC) --version | grep -q libprotoc.3 +PLUGIN_CHECK_CMD = which $(GRPC_CPP_PLUGIN) +HAS_PROTOC = $(shell $(PROTOC_CMD) > /dev/null && echo true || echo false) +ifeq ($(HAS_PROTOC),true) +HAS_VALID_PROTOC = $(shell $(PROTOC_CHECK_CMD) 2> /dev/null && echo true || echo false) +endif +HAS_PLUGIN = $(shell $(PLUGIN_CHECK_CMD) > /dev/null && echo true || echo false) + +SYSTEM_OK = false +ifeq ($(HAS_VALID_PROTOC),true) +ifeq ($(HAS_PLUGIN),true) +SYSTEM_OK = true +endif +endif + +system-check: +ifneq ($(HAS_VALID_PROTOC),true) + @echo " DEPENDENCY ERROR" + @echo + @echo "You don't have protoc 3.0.0 installed in your path." + @echo "Please install Google protocol buffers 3.0.0 and its compiler." + @echo "You can find it here:" + @echo + @echo " https://github.com/google/protobuf/releases/tag/v3.0.0" + @echo + @echo "Here is what I get when trying to evaluate your version of protoc:" + @echo + -$(PROTOC) --version + @echo + @echo +endif +ifneq ($(HAS_PLUGIN),true) + @echo " DEPENDENCY ERROR" + @echo + @echo "You don't have the grpc c++ protobuf plugin installed in your path." + @echo "Please install grpc. You can find it here:" + @echo + @echo " https://github.com/grpc/grpc" + @echo + @echo "Here is what I get when trying to detect if you have the plugin:" + @echo + -which $(GRPC_CPP_PLUGIN) + @echo + @echo +endif +ifneq ($(SYSTEM_OK),true) + @false +endif diff --git a/examples/cpp/compression/README.md b/examples/cpp/compression/README.md new file mode 100644 index 00000000000..13988f2c0c5 --- /dev/null +++ b/examples/cpp/compression/README.md @@ -0,0 +1,84 @@ +# gRPC C++ Message Compression Tutorial + +### Prerequisite +Make sure you have run the [hello world example](../helloworld) or understood the basics of gRPC. We will not dive into the details that have been discussed in the hello world example. + +### Get the tutorial source code + +The example code for this and our other examples lives in the `examples` directory. Clone this repository to your local machine by running the following command: + + +```sh +$ git clone -b $(curl -L https://grpc.io/release) https://github.com/grpc/grpc +``` + +Change your current directory to examples/cpp/compression + +```sh +$ cd examples/cpp/compression/ +``` + +### Generating gRPC code + +To generate the client and server side interfaces: + +```sh +$ make helloworld.grpc.pb.cc helloworld.pb.cc +``` +Which internally invokes the proto-compiler as: + +```sh +$ protoc -I ../../protos/ --grpc_out=. --plugin=protoc-gen-grpc=grpc_cpp_plugin ../../protos/helloworld.proto +$ protoc -I ../../protos/ --cpp_out=. ../../protos/helloworld.proto +``` + +### Writing a client and a server + +The client and the server can be based on the hello world example. + +Additionally, we can configure the compression settings. + +In the client, set the default compression algorithm of the channel via the channel arg. + +```cpp + ChannelArguments args; + // Set the default compression algorithm for the channel. + args.SetCompressionAlgorithm(GRPC_COMPRESS_GZIP); + GreeterClient greeter(grpc::CreateCustomChannel( + "localhost:50051", grpc::InsecureChannelCredentials(), args)); +``` + +Each call's compression configuration can be overwritten by client context. + +```cpp + // Overwrite the call's compression algorithm to DEFLATE. + context.set_compression_algorithm(GRPC_COMPRESS_DEFLATE); +``` + +In the server, set the default compression algorithm via the server builder. + +```cpp + ServerBuilder builder; + // Set the default compression algorithm for the server. + builder.SetDefaultCompressionAlgorithm(GRPC_COMPRESS_GZIP); +``` + +Each call's compression configuration can be overwritten by server context. + +```cpp + // Overwrite the call's compression algorithm to DEFLATE. + context->set_compression_algorithm(GRPC_COMPRESS_DEFLATE); +``` + +For a working example, refer to [greeter_client.cc](greeter_client.cc) and [greeter_server.cc](greeter_server.cc). + +Build and run the (compressing) client and the server by the following commands. + +```sh +make +./greeter_server +``` + +```sh +./greeter_client +``` diff --git a/examples/cpp/compression/greeter_client.cc b/examples/cpp/compression/greeter_client.cc new file mode 100644 index 00000000000..a8428174644 --- /dev/null +++ b/examples/cpp/compression/greeter_client.cc @@ -0,0 +1,93 @@ +/* + * + * 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 +#include +#include + +#include + +#ifdef BAZEL_BUILD +#include "examples/protos/helloworld.grpc.pb.h" +#else +#include "helloworld.grpc.pb.h" +#endif + +using grpc::Channel; +using grpc::ChannelArguments; +using grpc::ClientContext; +using grpc::Status; +using helloworld::HelloRequest; +using helloworld::HelloReply; +using helloworld::Greeter; + +class GreeterClient { + public: + GreeterClient(std::shared_ptr channel) + : stub_(Greeter::NewStub(channel)) {} + + // Assembles the client's payload, sends it and presents the response back + // from the server. + std::string SayHello(const std::string& user) { + // Data we are sending to the server. + HelloRequest request; + request.set_name(user); + + // Container for the data we expect from the server. + HelloReply reply; + + // Context for the client. It could be used to convey extra information to + // the server and/or tweak certain RPC behaviors. + ClientContext context; + + // Overwrite the call's compression algorithm to DEFLATE. + context.set_compression_algorithm(GRPC_COMPRESS_DEFLATE); + + // The actual RPC. + Status status = stub_->SayHello(&context, request, &reply); + + // Act upon its status. + if (status.ok()) { + return reply.message(); + } else { + std::cout << status.error_code() << ": " << status.error_message() + << std::endl; + return "RPC failed"; + } + } + + private: + std::unique_ptr stub_; +}; + +int main(int argc, char** argv) { + // Instantiate the client. It requires a channel, out of which the actual RPCs + // are created. This channel models a connection to an endpoint (in this case, + // localhost at port 50051). We indicate that the channel isn't authenticated + // (use of InsecureChannelCredentials()). + ChannelArguments args; + // Set the default compression algorithm for the channel. + args.SetCompressionAlgorithm(GRPC_COMPRESS_GZIP); + GreeterClient greeter(grpc::CreateCustomChannel( + "localhost:50051", grpc::InsecureChannelCredentials(), args)); + std::string user("world"); + std::string reply = greeter.SayHello(user); + std::cout << "Greeter received: " << reply << std::endl; + + return 0; +} diff --git a/examples/cpp/compression/greeter_server.cc b/examples/cpp/compression/greeter_server.cc new file mode 100644 index 00000000000..7399017afb7 --- /dev/null +++ b/examples/cpp/compression/greeter_server.cc @@ -0,0 +1,76 @@ +/* + * + * 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 +#include +#include + +#include + +#ifdef BAZEL_BUILD +#include "examples/protos/helloworld.grpc.pb.h" +#else +#include "helloworld.grpc.pb.h" +#endif + +using grpc::Server; +using grpc::ServerBuilder; +using grpc::ServerContext; +using grpc::Status; +using helloworld::HelloRequest; +using helloworld::HelloReply; +using helloworld::Greeter; + +// Logic and data behind the server's behavior. +class GreeterServiceImpl final : public Greeter::Service { + Status SayHello(ServerContext* context, const HelloRequest* request, + HelloReply* reply) override { + // Overwrite the call's compression algorithm to DEFLATE. + context->set_compression_algorithm(GRPC_COMPRESS_DEFLATE); + std::string prefix("Hello "); + reply->set_message(prefix + request->name()); + return Status::OK; + } +}; + +void RunServer() { + std::string server_address("0.0.0.0:50051"); + GreeterServiceImpl service; + + ServerBuilder builder; + // Set the default compression algorithm for the server. + builder.SetDefaultCompressionAlgorithm(GRPC_COMPRESS_GZIP); + // Listen on the given address without any authentication mechanism. + builder.AddListeningPort(server_address, grpc::InsecureServerCredentials()); + // Register "service" as the instance through which we'll communicate with + // clients. In this case it corresponds to an *synchronous* service. + builder.RegisterService(&service); + // Finally assemble the server. + std::unique_ptr server(builder.BuildAndStart()); + std::cout << "Server listening on " << server_address << std::endl; + + // Wait for the server to shutdown. Note that some other thread must be + // responsible for shutting down the server for this call to ever return. + server->Wait(); +} + +int main(int argc, char** argv) { + RunServer(); + + return 0; +} diff --git a/examples/cpp/helloworld/README.md b/examples/cpp/helloworld/README.md index c598658b1d7..813a80f288f 100644 --- a/examples/cpp/helloworld/README.md +++ b/examples/cpp/helloworld/README.md @@ -98,7 +98,7 @@ $ protoc -I ../../protos/ --cpp_out=. ../../protos/helloworld.proto ``` - Create a stub. A stub implements the rpc methods of a service and in the - generated code, a method is provided to created a stub with a channel: + generated code, a method is provided to create a stub with a channel: ```cpp auto stub = helloworld::Greeter::NewStub(channel); diff --git a/examples/cpp/helloworld/greeter_async_client.cc b/examples/cpp/helloworld/greeter_async_client.cc index d7a9d52836c..9b1def6d1da 100644 --- a/examples/cpp/helloworld/greeter_async_client.cc +++ b/examples/cpp/helloworld/greeter_async_client.cc @@ -23,7 +23,11 @@ #include #include +#ifdef BAZEL_BUILD +#include "examples/protos/helloworld.grpc.pb.h" +#else #include "helloworld.grpc.pb.h" +#endif using grpc::Channel; using grpc::ClientAsyncResponseReader; diff --git a/examples/cpp/helloworld/greeter_async_client2.cc b/examples/cpp/helloworld/greeter_async_client2.cc index d5098b9fc3f..97631f38889 100644 --- a/examples/cpp/helloworld/greeter_async_client2.cc +++ b/examples/cpp/helloworld/greeter_async_client2.cc @@ -24,7 +24,11 @@ #include #include +#ifdef BAZEL_BUILD +#include "examples/protos/helloworld.grpc.pb.h" +#else #include "helloworld.grpc.pb.h" +#endif using grpc::Channel; using grpc::ClientAsyncResponseReader; diff --git a/examples/cpp/helloworld/greeter_async_server.cc b/examples/cpp/helloworld/greeter_async_server.cc index a74673d8035..d4d1594c72b 100644 --- a/examples/cpp/helloworld/greeter_async_server.cc +++ b/examples/cpp/helloworld/greeter_async_server.cc @@ -24,7 +24,11 @@ #include #include +#ifdef BAZEL_BUILD +#include "examples/protos/helloworld.grpc.pb.h" +#else #include "helloworld.grpc.pb.h" +#endif using grpc::Server; using grpc::ServerAsyncResponseWriter; diff --git a/examples/cpp/keyvaluestore/caching_interceptor.h b/examples/cpp/keyvaluestore/caching_interceptor.h new file mode 100644 index 00000000000..5a31afe0f01 --- /dev/null +++ b/examples/cpp/keyvaluestore/caching_interceptor.h @@ -0,0 +1,134 @@ +/* + * + * 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 + +#include + +#ifdef BAZEL_BUILD +#include "examples/protos/keyvaluestore.grpc.pb.h" +#else +#include "keyvaluestore.grpc.pb.h" +#endif + +// This is a naive implementation of a cache. A new cache is for each call. For +// each new key request, the key is first searched in the map and if found, the +// interceptor fills in the return value without making a request to the server. +// Only if the key is not found in the cache do we make a request. +class CachingInterceptor : public grpc::experimental::Interceptor { + public: + CachingInterceptor(grpc::experimental::ClientRpcInfo* info) {} + + void Intercept( + ::grpc::experimental::InterceptorBatchMethods* methods) override { + bool hijack = false; + if (methods->QueryInterceptionHookPoint( + grpc::experimental::InterceptionHookPoints:: + PRE_SEND_INITIAL_METADATA)) { + // Hijack all calls + hijack = true; + // Create a stream on which this interceptor can make requests + stub_ = keyvaluestore::KeyValueStore::NewStub( + methods->GetInterceptedChannel()); + stream_ = stub_->GetValues(&context_); + } + if (methods->QueryInterceptionHookPoint( + grpc::experimental::InterceptionHookPoints::PRE_SEND_MESSAGE)) { + // We know that clients perform a Read and a Write in a loop, so we don't + // need to maintain a list of the responses. + std::string requested_key; + const keyvaluestore::Request* req_msg = + static_cast(methods->GetSendMessage()); + if (req_msg != nullptr) { + requested_key = req_msg->key(); + } else { + // The non-serialized form would not be available in certain scenarios, + // so add a fallback + keyvaluestore::Request req_msg; + auto* buffer = methods->GetSerializedSendMessage(); + auto copied_buffer = *buffer; + GPR_ASSERT( + grpc::SerializationTraits::Deserialize( + &copied_buffer, &req_msg) + .ok()); + requested_key = req_msg.key(); + } + + // Check if the key is present in the map + auto search = cached_map_.find(requested_key); + if (search != cached_map_.end()) { + std::cout << "Key " << requested_key << "found in map"; + response_ = search->second; + } else { + std::cout << "Key " << requested_key << "not found in cache"; + // Key was not found in the cache, so make a request + keyvaluestore::Request req; + req.set_key(requested_key); + stream_->Write(req); + keyvaluestore::Response resp; + stream_->Read(&resp); + response_ = resp.value(); + // Insert the pair in the cache for future requests + cached_map_.insert({requested_key, response_}); + } + } + if (methods->QueryInterceptionHookPoint( + grpc::experimental::InterceptionHookPoints::PRE_SEND_CLOSE)) { + stream_->WritesDone(); + } + if (methods->QueryInterceptionHookPoint( + grpc::experimental::InterceptionHookPoints::PRE_RECV_MESSAGE)) { + keyvaluestore::Response* resp = + static_cast(methods->GetRecvMessage()); + resp->set_value(response_); + } + if (methods->QueryInterceptionHookPoint( + grpc::experimental::InterceptionHookPoints::PRE_RECV_STATUS)) { + auto* status = methods->GetRecvStatus(); + *status = grpc::Status::OK; + } + // One of Hijack or Proceed always needs to be called to make progress. + if (hijack) { + // Hijack is called only once when PRE_SEND_INITIAL_METADATA is present in + // the hook points + methods->Hijack(); + } else { + // Proceed is an indicator that the interceptor is done intercepting the + // batch. + methods->Proceed(); + } + } + + private: + grpc::ClientContext context_; + std::unique_ptr stub_; + std::unique_ptr< + grpc::ClientReaderWriter> + stream_; + std::map cached_map_; + std::string response_; +}; + +class CachingInterceptorFactory + : public grpc::experimental::ClientInterceptorFactoryInterface { + public: + grpc::experimental::Interceptor* CreateClientInterceptor( + grpc::experimental::ClientRpcInfo* info) override { + return new CachingInterceptor(info); + } +}; diff --git a/examples/cpp/keyvaluestore/client.cc b/examples/cpp/keyvaluestore/client.cc new file mode 100644 index 00000000000..57c451cadf3 --- /dev/null +++ b/examples/cpp/keyvaluestore/client.cc @@ -0,0 +1,99 @@ +/* + * + * 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 +#include +#include +#include + +#include + +#include "caching_interceptor.h" + +#ifdef BAZEL_BUILD +#include "examples/protos/keyvaluestore.grpc.pb.h" +#else +#include "keyvaluestore.grpc.pb.h" +#endif + +using grpc::Channel; +using grpc::ClientContext; +using grpc::Status; +using keyvaluestore::KeyValueStore; +using keyvaluestore::Request; +using keyvaluestore::Response; + +class KeyValueStoreClient { + public: + KeyValueStoreClient(std::shared_ptr channel) + : stub_(KeyValueStore::NewStub(channel)) {} + + // Requests each key in the vector and displays the key and its corresponding + // value as a pair + void GetValues(const std::vector& keys) { + // Context for the client. It could be used to convey extra information to + // the server and/or tweak certain RPC behaviors. + ClientContext context; + auto stream = stub_->GetValues(&context); + for (const auto& key : keys) { + // Key we are sending to the server. + Request request; + request.set_key(key); + stream->Write(request); + + // Get the value for the sent key + Response response; + stream->Read(&response); + std::cout << key << " : " << response.value() << "\n"; + } + stream->WritesDone(); + Status status = stream->Finish(); + if (!status.ok()) { + std::cout << status.error_code() << ": " << status.error_message() + << std::endl; + std::cout << "RPC failed"; + } + } + + private: + std::unique_ptr stub_; +}; + +int main(int argc, char** argv) { + // Instantiate the client. It requires a channel, out of which the actual RPCs + // are created. This channel models a connection to an endpoint (in this case, + // localhost at port 50051). We indicate that the channel isn't authenticated + // (use of InsecureChannelCredentials()). + // In this example, we are using a cache which has been added in as an + // interceptor. + grpc::ChannelArguments args; + std::vector< + std::unique_ptr> + interceptor_creators; + interceptor_creators.push_back(std::unique_ptr( + new CachingInterceptorFactory())); + auto channel = grpc::experimental::CreateCustomChannelWithInterceptors( + "localhost:50051", grpc::InsecureChannelCredentials(), args, + std::move(interceptor_creators)); + KeyValueStoreClient client(channel); + std::vector keys = {"key1", "key2", "key3", "key4", + "key5", "key1", "key2", "key4"}; + client.GetValues(keys); + + return 0; +} diff --git a/examples/cpp/keyvaluestore/server.cc b/examples/cpp/keyvaluestore/server.cc new file mode 100644 index 00000000000..e75da9c62d1 --- /dev/null +++ b/examples/cpp/keyvaluestore/server.cc @@ -0,0 +1,97 @@ +/* + * + * 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 +#include +#include +#include + +#include + +#ifdef BAZEL_BUILD +#include "examples/protos/keyvaluestore.grpc.pb.h" +#else +#include "keyvaluestore.grpc.pb.h" +#endif + +using grpc::Server; +using grpc::ServerBuilder; +using grpc::ServerContext; +using grpc::ServerReaderWriter; +using grpc::Status; +using keyvaluestore::KeyValueStore; +using keyvaluestore::Request; +using keyvaluestore::Response; + +struct kv_pair { + const char* key; + const char* value; +}; + +static const kv_pair kvs_map[] = { + {"key1", "value1"}, {"key2", "value2"}, {"key3", "value3"}, + {"key4", "value4"}, {"key5", "value5"}, +}; + +const char* get_value_from_map(const char* key) { + for (size_t i = 0; i < sizeof(kvs_map) / sizeof(kv_pair); ++i) { + if (strcmp(key, kvs_map[i].key) == 0) { + return kvs_map[i].value; + } + } + return ""; +} + +// Logic and data behind the server's behavior. +class KeyValueStoreServiceImpl final : public KeyValueStore::Service { + Status GetValues(ServerContext* context, + ServerReaderWriter* stream) override { + Request request; + while (stream->Read(&request)) { + Response response; + response.set_value(get_value_from_map(request.key().c_str())); + stream->Write(response); + } + return Status::OK; + } +}; + +void RunServer() { + std::string server_address("0.0.0.0:50051"); + KeyValueStoreServiceImpl service; + + ServerBuilder builder; + // Listen on the given address without any authentication mechanism. + builder.AddListeningPort(server_address, grpc::InsecureServerCredentials()); + // Register "service" as the instance through which we'll communicate with + // clients. In this case, it corresponds to an *synchronous* service. + builder.RegisterService(&service); + // Finally assemble the server. + std::unique_ptr server(builder.BuildAndStart()); + std::cout << "Server listening on " << server_address << std::endl; + + // Wait for the server to shutdown. Note that some other thread must be + // responsible for shutting down the server for this call to ever return. + server->Wait(); +} + +int main(int argc, char** argv) { + RunServer(); + + return 0; +} diff --git a/examples/cpp/load_balancing/Makefile b/examples/cpp/load_balancing/Makefile new file mode 100644 index 00000000000..7c8d0727705 --- /dev/null +++ b/examples/cpp/load_balancing/Makefile @@ -0,0 +1,110 @@ +# +# 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. +# + +HOST_SYSTEM = $(shell uname | cut -f 1 -d_) +SYSTEM ?= $(HOST_SYSTEM) +CXX = g++ +CPPFLAGS += `pkg-config --cflags protobuf grpc` +CXXFLAGS += -std=c++11 +ifeq ($(SYSTEM),Darwin) +LDFLAGS += -L/usr/local/lib `pkg-config --libs protobuf grpc++ grpc`\ + -lgrpc++_reflection\ + -ldl +else +LDFLAGS += -L/usr/local/lib `pkg-config --libs protobuf grpc++ grpc`\ + -Wl,--no-as-needed -lgrpc++_reflection -Wl,--as-needed\ + -ldl +endif +PROTOC = protoc +GRPC_CPP_PLUGIN = grpc_cpp_plugin +GRPC_CPP_PLUGIN_PATH ?= `which $(GRPC_CPP_PLUGIN)` + +PROTOS_PATH = ../../protos + +vpath %.proto $(PROTOS_PATH) + +all: system-check greeter_client greeter_server + +greeter_client: helloworld.pb.o helloworld.grpc.pb.o greeter_client.o + $(CXX) $^ $(LDFLAGS) -o $@ + +greeter_server: helloworld.pb.o helloworld.grpc.pb.o greeter_server.o + $(CXX) $^ $(LDFLAGS) -o $@ + +.PRECIOUS: %.grpc.pb.cc +%.grpc.pb.cc: %.proto + $(PROTOC) -I $(PROTOS_PATH) --grpc_out=. --plugin=protoc-gen-grpc=$(GRPC_CPP_PLUGIN_PATH) $< + +.PRECIOUS: %.pb.cc +%.pb.cc: %.proto + $(PROTOC) -I $(PROTOS_PATH) --cpp_out=. $< + +clean: + rm -f *.o *.pb.cc *.pb.h greeter_client greeter_server + + +# The following is to test your system and ensure a smoother experience. +# They are by no means necessary to actually compile a grpc-enabled software. + +PROTOC_CMD = which $(PROTOC) +PROTOC_CHECK_CMD = $(PROTOC) --version | grep -q libprotoc.3 +PLUGIN_CHECK_CMD = which $(GRPC_CPP_PLUGIN) +HAS_PROTOC = $(shell $(PROTOC_CMD) > /dev/null && echo true || echo false) +ifeq ($(HAS_PROTOC),true) +HAS_VALID_PROTOC = $(shell $(PROTOC_CHECK_CMD) 2> /dev/null && echo true || echo false) +endif +HAS_PLUGIN = $(shell $(PLUGIN_CHECK_CMD) > /dev/null && echo true || echo false) + +SYSTEM_OK = false +ifeq ($(HAS_VALID_PROTOC),true) +ifeq ($(HAS_PLUGIN),true) +SYSTEM_OK = true +endif +endif + +system-check: +ifneq ($(HAS_VALID_PROTOC),true) + @echo " DEPENDENCY ERROR" + @echo + @echo "You don't have protoc 3.0.0 installed in your path." + @echo "Please install Google protocol buffers 3.0.0 and its compiler." + @echo "You can find it here:" + @echo + @echo " https://github.com/google/protobuf/releases/tag/v3.0.0" + @echo + @echo "Here is what I get when trying to evaluate your version of protoc:" + @echo + -$(PROTOC) --version + @echo + @echo +endif +ifneq ($(HAS_PLUGIN),true) + @echo " DEPENDENCY ERROR" + @echo + @echo "You don't have the grpc c++ protobuf plugin installed in your path." + @echo "Please install grpc. You can find it here:" + @echo + @echo " https://github.com/grpc/grpc" + @echo + @echo "Here is what I get when trying to detect if you have the plugin:" + @echo + -which $(GRPC_CPP_PLUGIN) + @echo + @echo +endif +ifneq ($(SYSTEM_OK),true) + @false +endif \ No newline at end of file diff --git a/examples/cpp/load_balancing/README.md b/examples/cpp/load_balancing/README.md new file mode 100644 index 00000000000..f48aca5307f --- /dev/null +++ b/examples/cpp/load_balancing/README.md @@ -0,0 +1,64 @@ +# gRPC C++ Load Balancing Tutorial + +### Prerequisite +Make sure you have run the [hello world example](../helloworld) or understood the basics of gRPC. We will not dive into the details that have been discussed in the hello world example. + +### Get the tutorial source code + +The example code for this and our other examples lives in the `examples` directory. Clone this repository to your local machine by running the following command: + + +```sh +$ git clone -b $(curl -L https://grpc.io/release) https://github.com/grpc/grpc +``` + +Change your current directory to examples/cpp/load_balancing + +```sh +$ cd examples/cpp/load_balancing/ +``` + +### Generating gRPC code + +To generate the client and server side interfaces: + +```sh +$ make helloworld.grpc.pb.cc helloworld.pb.cc +``` +Which internally invokes the proto-compiler as: + +```sh +$ protoc -I ../../protos/ --grpc_out=. --plugin=protoc-gen-grpc=grpc_cpp_plugin ../../protos/helloworld.proto +$ protoc -I ../../protos/ --cpp_out=. ../../protos/helloworld.proto +``` + +### Writing a client and a server + +The client and the server can be based on the hello world example. + +Additionally, we can configure the load balancing policy. (To see what load balancing policies are available, check out [this folder](https://github.com/grpc/grpc/tree/master/src/core/ext/filters/client_channel/lb_policy).) + +In the client, set the load balancing policy of the channel via the channel arg (to, for example, Round Robin). + +```cpp + ChannelArguments args; + // Set the load balancing policy for the channel. + args.SetLoadBalancingPolicyName("round_robin"); + GreeterClient greeter(grpc::CreateCustomChannel( + "localhost:50051", grpc::InsecureChannelCredentials(), args)); +``` + +For a working example, refer to [greeter_client.cc](greeter_client.cc) and [greeter_server.cc](greeter_server.cc). + +Build and run the client and the server with the following commands. + +```sh +make +./greeter_server +``` + +```sh +./greeter_client +``` + +(Note that the case in this example is trivial because there is only one server resolved from the name.) \ No newline at end of file diff --git a/examples/cpp/load_balancing/greeter_client.cc b/examples/cpp/load_balancing/greeter_client.cc new file mode 100644 index 00000000000..5b08204a96b --- /dev/null +++ b/examples/cpp/load_balancing/greeter_client.cc @@ -0,0 +1,90 @@ +/* + * + * 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 +#include +#include + +#include + +#ifdef BAZEL_BUILD +#include "examples/protos/helloworld.grpc.pb.h" +#else +#include "helloworld.grpc.pb.h" +#endif + +using grpc::Channel; +using grpc::ChannelArguments; +using grpc::ClientContext; +using grpc::Status; +using helloworld::HelloRequest; +using helloworld::HelloReply; +using helloworld::Greeter; + +class GreeterClient { + public: + GreeterClient(std::shared_ptr channel) + : stub_(Greeter::NewStub(channel)) {} + + // Assembles the client's payload, sends it and presents the response back + // from the server. + std::string SayHello(const std::string& user) { + // Data we are sending to the server. + HelloRequest request; + request.set_name(user); + + // Container for the data we expect from the server. + HelloReply reply; + + // Context for the client. It could be used to convey extra information to + // the server and/or tweak certain RPC behaviors. + ClientContext context; + + // The actual RPC. + Status status = stub_->SayHello(&context, request, &reply); + + // Act upon its status. + if (status.ok()) { + return reply.message(); + } else { + std::cout << status.error_code() << ": " << status.error_message() + << std::endl; + return "RPC failed"; + } + } + + private: + std::unique_ptr stub_; +}; + +int main(int argc, char** argv) { + // Instantiate the client. It requires a channel, out of which the actual RPCs + // are created. This channel models a connection to an endpoint (in this case, + // localhost at port 50051). We indicate that the channel isn't authenticated + // (use of InsecureChannelCredentials()). + ChannelArguments args; + // Set the load balancing policy for the channel. + args.SetLoadBalancingPolicyName("round_robin"); + GreeterClient greeter(grpc::CreateCustomChannel( + "localhost:50051", grpc::InsecureChannelCredentials(), args)); + std::string user("world"); + std::string reply = greeter.SayHello(user); + std::cout << "Greeter received: " << reply << std::endl; + + return 0; +} diff --git a/examples/cpp/load_balancing/greeter_server.cc b/examples/cpp/load_balancing/greeter_server.cc new file mode 100644 index 00000000000..f36ad906a29 --- /dev/null +++ b/examples/cpp/load_balancing/greeter_server.cc @@ -0,0 +1,72 @@ +/* + * + * 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 +#include +#include + +#include + +#ifdef BAZEL_BUILD +#include "examples/protos/helloworld.grpc.pb.h" +#else +#include "helloworld.grpc.pb.h" +#endif + +using grpc::Server; +using grpc::ServerBuilder; +using grpc::ServerContext; +using grpc::Status; +using helloworld::HelloRequest; +using helloworld::HelloReply; +using helloworld::Greeter; + +// Logic and data behind the server's behavior. +class GreeterServiceImpl final : public Greeter::Service { + Status SayHello(ServerContext* context, const HelloRequest* request, + HelloReply* reply) override { + std::string prefix("Hello "); + reply->set_message(prefix + request->name()); + return Status::OK; + } +}; + +void RunServer() { + std::string server_address("0.0.0.0:50051"); + GreeterServiceImpl service; + + ServerBuilder builder; + // Listen on the given address without any authentication mechanism. + builder.AddListeningPort(server_address, grpc::InsecureServerCredentials()); + // Register "service" as the instance through which we'll communicate with + // clients. In this case it corresponds to an *synchronous* service. + builder.RegisterService(&service); + // Finally assemble the server. + std::unique_ptr server(builder.BuildAndStart()); + std::cout << "Server listening on " << server_address << std::endl; + + // Wait for the server to shutdown. Note that some other thread must be + // responsible for shutting down the server for this call to ever return. + server->Wait(); +} + +int main(int argc, char** argv) { + RunServer(); + + return 0; +} diff --git a/examples/cpp/metadata/Makefile b/examples/cpp/metadata/Makefile new file mode 100644 index 00000000000..46be8bfaa3c --- /dev/null +++ b/examples/cpp/metadata/Makefile @@ -0,0 +1,96 @@ +# +# 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. +# + HOST_SYSTEM = $(shell uname | cut -f 1 -d_) +SYSTEM ?= $(HOST_SYSTEM) +CXX = g++ +CPPFLAGS += `pkg-config --cflags protobuf grpc` +CXXFLAGS += -std=c++11 +ifeq ($(SYSTEM),Darwin) +LDFLAGS += -L/usr/local/lib `pkg-config --libs protobuf grpc++ grpc`\ + -lgrpc++_reflection\ + -ldl +else +LDFLAGS += -L/usr/local/lib `pkg-config --libs protobuf grpc++ grpc`\ + -Wl,--no-as-needed -lgrpc++_reflection -Wl,--as-needed\ + -ldl +endif +PROTOC = protoc +GRPC_CPP_PLUGIN = grpc_cpp_plugin +GRPC_CPP_PLUGIN_PATH ?= `which $(GRPC_CPP_PLUGIN)` + PROTOS_PATH = ../../protos + vpath %.proto $(PROTOS_PATH) + all: system-check greeter_client greeter_server + greeter_client: helloworld.pb.o helloworld.grpc.pb.o greeter_client.o + $(CXX) $^ $(LDFLAGS) -o $@ + greeter_server: helloworld.pb.o helloworld.grpc.pb.o greeter_server.o + $(CXX) $^ $(LDFLAGS) -o $@ + .PRECIOUS: %.grpc.pb.cc +%.grpc.pb.cc: %.proto + $(PROTOC) -I $(PROTOS_PATH) --grpc_out=. --plugin=protoc-gen-grpc=$(GRPC_CPP_PLUGIN_PATH) $< + .PRECIOUS: %.pb.cc +%.pb.cc: %.proto + $(PROTOC) -I $(PROTOS_PATH) --cpp_out=. $< + clean: + rm -f *.o *.pb.cc *.pb.h greeter_client greeter_server + # The following is to test your system and ensure a smoother experience. +# They are by no means necessary to actually compile a grpc-enabled software. + PROTOC_CMD = which $(PROTOC) +PROTOC_CHECK_CMD = $(PROTOC) --version | grep -q libprotoc.3 +PLUGIN_CHECK_CMD = which $(GRPC_CPP_PLUGIN) +HAS_PROTOC = $(shell $(PROTOC_CMD) > /dev/null && echo true || echo false) +ifeq ($(HAS_PROTOC),true) +HAS_VALID_PROTOC = $(shell $(PROTOC_CHECK_CMD) 2> /dev/null && echo true || echo false) +endif +HAS_PLUGIN = $(shell $(PLUGIN_CHECK_CMD) > /dev/null && echo true || echo false) + SYSTEM_OK = false +ifeq ($(HAS_VALID_PROTOC),true) +ifeq ($(HAS_PLUGIN),true) +SYSTEM_OK = true +endif +endif + system-check: +ifneq ($(HAS_VALID_PROTOC),true) + @echo " DEPENDENCY ERROR" + @echo + @echo "You don't have protoc 3.0.0 installed in your path." + @echo "Please install Google protocol buffers 3.0.0 and its compiler." + @echo "You can find it here:" + @echo + @echo " https://github.com/google/protobuf/releases/tag/v3.0.0" + @echo + @echo "Here is what I get when trying to evaluate your version of protoc:" + @echo + -$(PROTOC) --version + @echo + @echo +endif +ifneq ($(HAS_PLUGIN),true) + @echo " DEPENDENCY ERROR" + @echo + @echo "You don't have the grpc c++ protobuf plugin installed in your path." + @echo "Please install grpc. You can find it here:" + @echo + @echo " https://github.com/grpc/grpc" + @echo + @echo "Here is what I get when trying to detect if you have the plugin:" + @echo + -which $(GRPC_CPP_PLUGIN) + @echo + @echo +endif +ifneq ($(SYSTEM_OK),true) + @false +endif diff --git a/examples/cpp/metadata/README.md b/examples/cpp/metadata/README.md new file mode 100644 index 00000000000..96ad3d19bdb --- /dev/null +++ b/examples/cpp/metadata/README.md @@ -0,0 +1,66 @@ +# Metadata Example + +## Overview + +This example shows you how to add custom headers on the client and server and +how to access them. + +Custom metadata must follow the "Custom-Metadata" format listed in +https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md, with the +exception of binary headers, which don't have to be base64 encoded. + +### Get the tutorial source code + The example code for this and our other examples lives in the `examples` directory. Clone this repository to your local machine by running the following command: + ```sh +$ git clone -b $(curl -L https://grpc.io/release) https://github.com/grpc/grpc +``` + Change your current directory to examples/cpp/metadata + ```sh +$ cd examples/cpp/metadata +``` + +### Generating gRPC code + To generate the client and server side interfaces: + ```sh +$ make helloworld.grpc.pb.cc helloworld.pb.cc +``` +Which internally invokes the proto-compiler as: + ```sh +$ protoc -I ../../protos/ --grpc_out=. --plugin=protoc-gen-grpc=grpc_cpp_plugin ../../protos/helloworld.proto +$ protoc -I ../../protos/ --cpp_out=. ../../protos/helloworld.proto +``` +### Try it! +Build client and server: + +```sh +$ make +``` + +Run the server, which will listen on port 50051: + +```sh +$ ./greeter_server +``` + +Run the client (in a different terminal): + +```sh +$ ./greeter_client +``` + +If things go smoothly, you will see in the client terminal: + +"Client received initial metadata from server: initial metadata value" +"Client received trailing metadata from server: trailing metadata value" +"Client received message: Hello World" + + +And in the server terminal: + +"Header key: custom-bin , value: 01234567" +"Header key: custom-header , value: Custom Value" +"Header key: user-agent , value: grpc-c++/1.16.0-dev grpc-c/6.0.0-dev (linux; chttp2; gao)" + +We did not add the user-agent metadata as a custom header. This shows how +the gRPC framework adds some headers under the hood that may show up in the +metadata map. diff --git a/examples/cpp/metadata/greeter_client.cc b/examples/cpp/metadata/greeter_client.cc new file mode 100644 index 00000000000..80494389937 --- /dev/null +++ b/examples/cpp/metadata/greeter_client.cc @@ -0,0 +1,95 @@ +/* + * + * 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 +#include +#include + +#include + +#ifdef BAZEL_BUILD +#include "examples/protos/helloworld.grpc.pb.h" +#else +#include "helloworld.grpc.pb.h" +#endif + +using grpc::Channel; +using grpc::ClientContext; +using grpc::Status; +using helloworld::HelloRequest; +using helloworld::HelloReply; +using helloworld::Greeter; + +class CustomHeaderClient { + public: + CustomHeaderClient(std::shared_ptr channel) + : stub_(Greeter::NewStub(channel)) {} + + // Assembles the client's payload, sends it and presents the response back + // from the server. + std::string SayHello(const std::string& user) { + // Data we are sending to the server. + HelloRequest request; + request.set_name(user); + + // Container for the data we expect from the server. + HelloReply reply; + + // Context for the client. It could be used to convey extra information to + // the server and/or tweak certain RPC behaviors. + ClientContext context; + + // Setting custom metadata to be sent to the server + context.AddMetadata("custom-header", "Custom Value"); + + // Setting custom binary metadata + char bytes[8] = {'\0', '\1', '\2', '\3', + '\4', '\5', '\6', '\7'}; + context.AddMetadata("custom-bin", grpc::string(bytes, 8)); + + // The actual RPC. + Status status = stub_->SayHello(&context, request, &reply); + + // Act upon its status. + if (status.ok()) { + std::cout << "Client received initial metadata from server: " << context.GetServerInitialMetadata().find("custom-server-metadata")->second << std::endl; + std::cout << "Client received trailing metadata from server: " << context.GetServerTrailingMetadata().find("custom-trailing-metadata")->second << std::endl; + return reply.message(); + } else { + std::cout << status.error_code() << ": " << status.error_message() + << std::endl; + return "RPC failed"; + } + } + + private: + std::unique_ptr stub_; +}; + +int main(int argc, char** argv) { + // Instantiate the client. It requires a channel, out of which the actual RPCs + // are created. This channel models a connection to an endpoint (in this case, + // localhost at port 50051). We indicate that the channel isn't authenticated + // (use of InsecureChannelCredentials()). + CustomHeaderClient greeter(grpc::CreateChannel( + "localhost:50051", grpc::InsecureChannelCredentials())); + std::string user("world"); + std::string reply = greeter.SayHello(user); + std::cout << "Client received message: " << reply << std::endl; + return 0; +} diff --git a/examples/cpp/metadata/greeter_server.cc b/examples/cpp/metadata/greeter_server.cc new file mode 100644 index 00000000000..a9a4f33cb0b --- /dev/null +++ b/examples/cpp/metadata/greeter_server.cc @@ -0,0 +1,94 @@ +/* + * + * 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 +#include +#include + +#include + +#ifdef BAZEL_BUILD +#include "examples/protos/helloworld.grpc.pb.h" +#else +#include "helloworld.grpc.pb.h" +#endif + +using grpc::Server; +using grpc::ServerBuilder; +using grpc::ServerContext; +using grpc::Status; +using helloworld::HelloRequest; +using helloworld::HelloReply; +using helloworld::Greeter; + +// Logic and data behind the server's behavior. +class GreeterServiceImpl final : public Greeter::Service { + Status SayHello(ServerContext* context, const HelloRequest* request, + HelloReply* reply) override { + std::string prefix("Hello "); + + // Get the client's initial metadata + std::cout << "Client metadata: " << std::endl; + const std::multimap metadata = context->client_metadata(); + for (auto iter = metadata.begin(); iter != metadata.end(); ++iter) { + std::cout << "Header key: " << iter->first << ", value: "; + // Check for binary value + size_t isbin = iter->first.find("-bin"); + if ((isbin != std::string::npos) && (isbin + 4 == iter->first.size())) { + std::cout << std::hex; + for (auto c : iter->second) { + std::cout << static_cast(c); + } + std::cout << std::dec; + } else { + std::cout << iter->second; + } + std::cout << std::endl; + } + + context->AddInitialMetadata("custom-server-metadata", "initial metadata value"); + context->AddTrailingMetadata("custom-trailing-metadata", "trailing metadata value"); + reply->set_message(prefix + request->name()); + return Status::OK; + } +}; + +void RunServer() { + std::string server_address("0.0.0.0:50051"); + GreeterServiceImpl service; + + ServerBuilder builder; + // Listen on the given address without any authentication mechanism. + builder.AddListeningPort(server_address, grpc::InsecureServerCredentials()); + // Register "service" as the instance through which we'll communicate with + // clients. In this case it corresponds to an *synchronous* service. + builder.RegisterService(&service); + // Finally assemble the server. + std::unique_ptr server(builder.BuildAndStart()); + std::cout << "Server listening on " << server_address << std::endl; + + // Wait for the server to shutdown. Note that some other thread must be + // responsible for shutting down the server for this call to ever return. + server->Wait(); +} + +int main(int argc, char** argv) { + RunServer(); + + return 0; +} diff --git a/examples/cpp/route_guide/helper.cc b/examples/cpp/route_guide/helper.cc index 266f754b940..cd889f6a4ba 100644 --- a/examples/cpp/route_guide/helper.cc +++ b/examples/cpp/route_guide/helper.cc @@ -23,7 +23,11 @@ #include #include #include +#ifdef BAZEL_BUILD +#include "examples/protos/route_guide.grpc.pb.h" +#else #include "route_guide.grpc.pb.h" +#endif namespace routeguide { @@ -35,13 +39,16 @@ std::string GetDbFileContent(int argc, char** argv) { size_t start_position = argv_1.find(arg_str); if (start_position != std::string::npos) { start_position += arg_str.size(); - if (argv_1[start_position] == ' ' || - argv_1[start_position] == '=') { + if (argv_1[start_position] == ' ' || argv_1[start_position] == '=') { db_path = argv_1.substr(start_position + 1); } } } else { +#ifdef BAZEL_BUILD + db_path = "cpp/route_guide/route_guide_db.json"; +#else db_path = "route_guide_db.json"; +#endif } std::ifstream db_file(db_path); if (!db_file.is_open()) { @@ -60,17 +67,13 @@ class Parser { public: explicit Parser(const std::string& db) : db_(db) { // Remove all spaces. - db_.erase( - std::remove_if(db_.begin(), db_.end(), isspace), - db_.end()); + db_.erase(std::remove_if(db_.begin(), db_.end(), isspace), db_.end()); if (!Match("[")) { SetFailedAndReturnFalse(); } } - bool Finished() { - return current_ >= db_.size(); - } + bool Finished() { return current_ >= db_.size(); } bool TryParseOne(Feature* feature) { if (failed_ || Finished() || !Match("{")) { @@ -96,7 +99,7 @@ class Parser { if (current_ == db_.size()) { return SetFailedAndReturnFalse(); } - feature->set_name(db_.substr(name_start, current_-name_start-1)); + feature->set_name(db_.substr(name_start, current_ - name_start - 1)); if (!Match("},")) { if (db_[current_ - 1] == ']' && current_ == db_.size()) { return true; @@ -107,7 +110,6 @@ class Parser { } private: - bool SetFailedAndReturnFalse() { failed_ = true; return false; @@ -121,7 +123,8 @@ class Parser { void ReadLong(long* l) { size_t start = current_; - while (current_ != db_.size() && db_[current_] != ',' && db_[current_] != '}') { + while (current_ != db_.size() && db_[current_] != ',' && + db_[current_] != '}') { current_++; } // It will throw an exception if fails. @@ -154,10 +157,8 @@ void ParseDb(const std::string& db, std::vector* feature_list) { break; } } - std::cout << "DB parsed, loaded " << feature_list->size() - << " features." << std::endl; + std::cout << "DB parsed, loaded " << feature_list->size() << " features." + << std::endl; } - } // namespace routeguide - diff --git a/examples/cpp/route_guide/route_guide_client.cc b/examples/cpp/route_guide/route_guide_client.cc index a89ec164c62..439edb0dbdf 100644 --- a/examples/cpp/route_guide/route_guide_client.cc +++ b/examples/cpp/route_guide/route_guide_client.cc @@ -29,7 +29,11 @@ #include #include #include "helper.h" +#ifdef BAZEL_BUILD +#include "examples/protos/route_guide.grpc.pb.h" +#else #include "route_guide.grpc.pb.h" +#endif using grpc::Channel; using grpc::ClientContext; diff --git a/examples/cpp/route_guide/route_guide_server.cc b/examples/cpp/route_guide/route_guide_server.cc index 5867c167128..49239665179 100644 --- a/examples/cpp/route_guide/route_guide_server.cc +++ b/examples/cpp/route_guide/route_guide_server.cc @@ -29,7 +29,11 @@ #include #include #include "helper.h" +#ifdef BAZEL_BUILD +#include "examples/protos/route_guide.grpc.pb.h" +#else #include "route_guide.grpc.pb.h" +#endif using grpc::Server; using grpc::ServerBuilder; @@ -147,24 +151,25 @@ class RouteGuideImpl final : public RouteGuide::Service { Status RouteChat(ServerContext* context, ServerReaderWriter* stream) override { - std::vector received_notes; RouteNote note; while (stream->Read(¬e)) { - for (const RouteNote& n : received_notes) { + std::unique_lock lock(mu_); + for (const RouteNote& n : received_notes_) { if (n.location().latitude() == note.location().latitude() && n.location().longitude() == note.location().longitude()) { stream->Write(n); } } - received_notes.push_back(note); + received_notes_.push_back(note); } return Status::OK; } private: - std::vector feature_list_; + std::mutex mu_; + std::vector received_notes_; }; void RunServer(const std::string& db_path) { diff --git a/examples/csharp/.gitignore b/examples/csharp/.gitignore index 585000ea2d5..11f758f5c81 100644 --- a/examples/csharp/.gitignore +++ b/examples/csharp/.gitignore @@ -1,5 +1,7 @@ +.vs/ bin/ obj/ packages/ *.suo +*.user *.userprefs diff --git a/examples/csharp/Helloworld/Greeter.sln b/examples/csharp/Helloworld/Greeter.sln index ca50470e664..a5ba98d0bed 100644 --- a/examples/csharp/Helloworld/Greeter.sln +++ b/examples/csharp/Helloworld/Greeter.sln @@ -1,4 +1,4 @@ - + Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 VisualStudioVersion = 15.0.26228.4 diff --git a/examples/csharp/Helloworld/Greeter/Greeter.csproj b/examples/csharp/Helloworld/Greeter/Greeter.csproj index eba262565d7..7989f795418 100644 --- a/examples/csharp/Helloworld/Greeter/Greeter.csproj +++ b/examples/csharp/Helloworld/Greeter/Greeter.csproj @@ -1,18 +1,17 @@ - + - Greeter - netcoreapp2.1 - portable - Greeter - Greeter + netstandard1.5 - - - + + + + + + diff --git a/examples/csharp/Helloworld/Greeter/Helloworld.cs b/examples/csharp/Helloworld/Greeter/Helloworld.cs deleted file mode 100644 index e008ec27e54..00000000000 --- a/examples/csharp/Helloworld/Greeter/Helloworld.cs +++ /dev/null @@ -1,312 +0,0 @@ -// -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: helloworld.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 Helloworld { - - /// Holder for reflection information generated from helloworld.proto - public static partial class HelloworldReflection { - - #region Descriptor - /// File descriptor for helloworld.proto - public static pbr::FileDescriptor Descriptor { - get { return descriptor; } - } - private static pbr::FileDescriptor descriptor; - - static HelloworldReflection() { - byte[] descriptorData = global::System.Convert.FromBase64String( - string.Concat( - "ChBoZWxsb3dvcmxkLnByb3RvEgpoZWxsb3dvcmxkIhwKDEhlbGxvUmVxdWVz", - "dBIMCgRuYW1lGAEgASgJIh0KCkhlbGxvUmVwbHkSDwoHbWVzc2FnZRgBIAEo", - "CTJJCgdHcmVldGVyEj4KCFNheUhlbGxvEhguaGVsbG93b3JsZC5IZWxsb1Jl", - "cXVlc3QaFi5oZWxsb3dvcmxkLkhlbGxvUmVwbHkiAEI2Chtpby5ncnBjLmV4", - "YW1wbGVzLmhlbGxvd29ybGRCD0hlbGxvV29ybGRQcm90b1ABogIDSExXYgZw", - "cm90bzM=")); - descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, - new pbr::FileDescriptor[] { }, - new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] { - new pbr::GeneratedClrTypeInfo(typeof(global::Helloworld.HelloRequest), global::Helloworld.HelloRequest.Parser, new[]{ "Name" }, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Helloworld.HelloReply), global::Helloworld.HelloReply.Parser, new[]{ "Message" }, null, null, null) - })); - } - #endregion - - } - #region Messages - /// - /// The request message containing the user's name. - /// - public sealed partial class HelloRequest : pb::IMessage { - private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new HelloRequest()); - private pb::UnknownFieldSet _unknownFields; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public static pb::MessageParser Parser { get { return _parser; } } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public static pbr::MessageDescriptor Descriptor { - get { return global::Helloworld.HelloworldReflection.Descriptor.MessageTypes[0]; } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - pbr::MessageDescriptor pb::IMessage.Descriptor { - get { return Descriptor; } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public HelloRequest() { - OnConstruction(); - } - - partial void OnConstruction(); - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public HelloRequest(HelloRequest other) : this() { - name_ = other.name_; - _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public HelloRequest Clone() { - return new HelloRequest(this); - } - - /// Field number for the "name" field. - public const int NameFieldNumber = 1; - private string name_ = ""; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public string Name { - get { return name_; } - set { - name_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); - } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public override bool Equals(object other) { - return Equals(other as HelloRequest); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool Equals(HelloRequest other) { - if (ReferenceEquals(other, null)) { - return false; - } - if (ReferenceEquals(other, this)) { - return true; - } - if (Name != other.Name) return false; - 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; - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public override string ToString() { - return pb::JsonFormatter.ToDiagnosticString(this); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void WriteTo(pb::CodedOutputStream output) { - if (Name.Length != 0) { - output.WriteRawTag(10); - output.WriteString(Name); - } - if (_unknownFields != null) { - _unknownFields.WriteTo(output); - } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public int CalculateSize() { - int size = 0; - if (Name.Length != 0) { - size += 1 + pb::CodedOutputStream.ComputeStringSize(Name); - } - if (_unknownFields != null) { - size += _unknownFields.CalculateSize(); - } - return size; - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void MergeFrom(HelloRequest other) { - if (other == null) { - return; - } - if (other.Name.Length != 0) { - Name = other.Name; - } - _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void MergeFrom(pb::CodedInputStream input) { - uint tag; - while ((tag = input.ReadTag()) != 0) { - switch(tag) { - default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); - break; - case 10: { - Name = input.ReadString(); - break; - } - } - } - } - - } - - /// - /// The response message containing the greetings - /// - public sealed partial class HelloReply : pb::IMessage { - private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new HelloReply()); - private pb::UnknownFieldSet _unknownFields; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public static pb::MessageParser Parser { get { return _parser; } } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public static pbr::MessageDescriptor Descriptor { - get { return global::Helloworld.HelloworldReflection.Descriptor.MessageTypes[1]; } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - pbr::MessageDescriptor pb::IMessage.Descriptor { - get { return Descriptor; } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public HelloReply() { - OnConstruction(); - } - - partial void OnConstruction(); - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public HelloReply(HelloReply other) : this() { - message_ = other.message_; - _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public HelloReply Clone() { - return new HelloReply(this); - } - - /// Field number for the "message" field. - public const int MessageFieldNumber = 1; - private string message_ = ""; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public string Message { - get { return message_; } - set { - message_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); - } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public override bool Equals(object other) { - return Equals(other as HelloReply); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool Equals(HelloReply other) { - if (ReferenceEquals(other, null)) { - return false; - } - if (ReferenceEquals(other, this)) { - return true; - } - if (Message != other.Message) return false; - return Equals(_unknownFields, other._unknownFields); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public override int GetHashCode() { - int hash = 1; - if (Message.Length != 0) hash ^= Message.GetHashCode(); - if (_unknownFields != null) { - hash ^= _unknownFields.GetHashCode(); - } - return hash; - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public override string ToString() { - return pb::JsonFormatter.ToDiagnosticString(this); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void WriteTo(pb::CodedOutputStream output) { - if (Message.Length != 0) { - output.WriteRawTag(10); - output.WriteString(Message); - } - if (_unknownFields != null) { - _unknownFields.WriteTo(output); - } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public int CalculateSize() { - int size = 0; - if (Message.Length != 0) { - size += 1 + pb::CodedOutputStream.ComputeStringSize(Message); - } - if (_unknownFields != null) { - size += _unknownFields.CalculateSize(); - } - return size; - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void MergeFrom(HelloReply other) { - if (other == null) { - return; - } - if (other.Message.Length != 0) { - Message = other.Message; - } - _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void MergeFrom(pb::CodedInputStream input) { - uint tag; - while ((tag = input.ReadTag()) != 0) { - switch(tag) { - default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); - break; - case 10: { - Message = input.ReadString(); - break; - } - } - } - } - - } - - #endregion - -} - -#endregion Designer generated code diff --git a/examples/csharp/Helloworld/GreeterClient/GreeterClient.csproj b/examples/csharp/Helloworld/GreeterClient/GreeterClient.csproj index 24a89d58c55..ac10d854972 100644 --- a/examples/csharp/Helloworld/GreeterClient/GreeterClient.csproj +++ b/examples/csharp/Helloworld/GreeterClient/GreeterClient.csproj @@ -1,12 +1,8 @@ - + - GreeterClient - netcoreapp2.1 - portable - GreeterClient + netcoreapp2.1 Exe - GreeterClient diff --git a/examples/csharp/Helloworld/GreeterServer/GreeterServer.csproj b/examples/csharp/Helloworld/GreeterServer/GreeterServer.csproj index 9ea1fa3817c..ac10d854972 100644 --- a/examples/csharp/Helloworld/GreeterServer/GreeterServer.csproj +++ b/examples/csharp/Helloworld/GreeterServer/GreeterServer.csproj @@ -1,12 +1,8 @@ - + - GreeterServer - netcoreapp2.1 - portable - GreeterServer + netcoreapp2.1 Exe - GreeterServer diff --git a/examples/csharp/Helloworld/README.md b/examples/csharp/Helloworld/README.md index 48711324262..e4771ee91a1 100644 --- a/examples/csharp/Helloworld/README.md +++ b/examples/csharp/Helloworld/README.md @@ -3,41 +3,31 @@ gRPC in 3 minutes (C#) BACKGROUND ------------- -For this sample, we've already generated the server and client stubs from [helloworld.proto][]. - -Example projects in this directory depend on the [Grpc](https://www.nuget.org/packages/Grpc/) -and [Google.Protobuf](https://www.nuget.org/packages/Google.Protobuf/) NuGet packages -which have been already added to the project for you. +This is a version of the helloworld example using the dotnet SDK +tools to compile [helloworld.proto][] in a common library, build the server +and the client, and run them. PREREQUISITES ------------- - The [.NET Core SDK 2.1+](https://www.microsoft.com/net/core) -You can also build the example directly using Visual Studio 2017, but it's not a requirement. +You can also build the solution `Greeter.sln` using Visual Studio 2017, +but it's not a requirement. -BUILD -------- +BUILD AND RUN +------------- -From the `examples/csharp/Helloworld` directory: - -- `dotnet build Greeter.sln` - -Try it! -------- - -- Run the server +- Build and run the server ``` - > cd GreeterServer - > dotnet run -f netcoreapp2.1 + > dotnet run -p GreeterServer ``` -- Run the client +- Build and run the client ``` - > cd GreeterClient - > dotnet run -f netcoreapp2.1 + > dotnet run -p GreeterClient ``` Tutorial diff --git a/examples/csharp/Helloworld/generate_protos.bat b/examples/csharp/Helloworld/generate_protos.bat deleted file mode 100644 index ab0c0eb46a4..00000000000 --- a/examples/csharp/Helloworld/generate_protos.bat +++ /dev/null @@ -1,28 +0,0 @@ -@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 Generate the C# code for .proto files - -setlocal - -@rem enter this directory -cd /d %~dp0 - -@rem packages will be available in nuget cache directory once the project is built or after "dotnet restore" -set PROTOC=%UserProfile%\.nuget\packages\Google.Protobuf.Tools\3.6.1\tools\windows_x64\protoc.exe -set PLUGIN=%UserProfile%\.nuget\packages\Grpc.Tools\1.14.1\tools\windows_x64\grpc_csharp_plugin.exe - -%PROTOC% -I../../protos --csharp_out Greeter ../../protos/helloworld.proto --grpc_out Greeter --plugin=protoc-gen-grpc=%PLUGIN% - -endlocal diff --git a/examples/csharp/HelloworldLegacyCsproj/Greeter.sln b/examples/csharp/HelloworldLegacyCsproj/Greeter.sln index 49e364d91c0..26cae7a727e 100644 --- a/examples/csharp/HelloworldLegacyCsproj/Greeter.sln +++ b/examples/csharp/HelloworldLegacyCsproj/Greeter.sln @@ -1,4 +1,4 @@ - + Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2013 VisualStudioVersion = 12.0.31101.0 diff --git a/examples/csharp/HelloworldLegacyCsproj/Greeter/Greeter.csproj b/examples/csharp/HelloworldLegacyCsproj/Greeter/Greeter.csproj index 197a9fb6257..da15ba3954b 100644 --- a/examples/csharp/HelloworldLegacyCsproj/Greeter/Greeter.csproj +++ b/examples/csharp/HelloworldLegacyCsproj/Greeter/Greeter.csproj @@ -1,5 +1,6 @@ - + + Debug AnyCPU @@ -36,7 +37,7 @@ ..\packages\Google.Protobuf.3.6.1\lib\net45\Google.Protobuf.dll - ..\packages\Grpc.Core.1.14.1\lib\net45\Grpc.Core.dll + ..\packages\Grpc.Core.1.17.0\lib\net45\Grpc.Core.dll @@ -47,25 +48,23 @@ - - - + protos\helloworld.proto - - - generate_protos.bat - + - + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + + + - \ No newline at end of file + + diff --git a/examples/csharp/HelloworldLegacyCsproj/Greeter/HelloworldGrpc.cs b/examples/csharp/HelloworldLegacyCsproj/Greeter/HelloworldGrpc.cs deleted file mode 100644 index d6b959adc64..00000000000 --- a/examples/csharp/HelloworldLegacyCsproj/Greeter/HelloworldGrpc.cs +++ /dev/null @@ -1,149 +0,0 @@ -// -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: helloworld.proto -// -// 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. -// -#pragma warning disable 0414, 1591 -#region Designer generated code - -using grpc = global::Grpc.Core; - -namespace Helloworld { - /// - /// The greeting service definition. - /// - public static partial class Greeter - { - static readonly string __ServiceName = "helloworld.Greeter"; - - static readonly grpc::Marshaller __Marshaller_helloworld_HelloRequest = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Helloworld.HelloRequest.Parser.ParseFrom); - static readonly grpc::Marshaller __Marshaller_helloworld_HelloReply = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Helloworld.HelloReply.Parser.ParseFrom); - - static readonly grpc::Method __Method_SayHello = new grpc::Method( - grpc::MethodType.Unary, - __ServiceName, - "SayHello", - __Marshaller_helloworld_HelloRequest, - __Marshaller_helloworld_HelloReply); - - /// Service descriptor - public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor - { - get { return global::Helloworld.HelloworldReflection.Descriptor.Services[0]; } - } - - /// Base class for server-side implementations of Greeter - public abstract partial class GreeterBase - { - /// - /// Sends a greeting - /// - /// The request received from the client. - /// The context of the server-side call handler being invoked. - /// The response to send back to the client (wrapped by a task). - public virtual global::System.Threading.Tasks.Task SayHello(global::Helloworld.HelloRequest request, grpc::ServerCallContext context) - { - throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, "")); - } - - } - - /// Client for Greeter - public partial class GreeterClient : grpc::ClientBase - { - /// Creates a new client for Greeter - /// The channel to use to make remote calls. - public GreeterClient(grpc::Channel channel) : base(channel) - { - } - /// Creates a new client for Greeter that uses a custom CallInvoker. - /// The callInvoker to use to make remote calls. - public GreeterClient(grpc::CallInvoker callInvoker) : base(callInvoker) - { - } - /// Protected parameterless constructor to allow creation of test doubles. - protected GreeterClient() : base() - { - } - /// Protected constructor to allow creation of configured clients. - /// The client configuration. - protected GreeterClient(ClientBaseConfiguration configuration) : base(configuration) - { - } - - /// - /// Sends a greeting - /// - /// The request to send to the server. - /// The initial metadata to send with the call. This parameter is optional. - /// An optional deadline for the call. The call will be cancelled if deadline is hit. - /// An optional token for canceling the call. - /// The response received from the server. - public virtual global::Helloworld.HelloReply SayHello(global::Helloworld.HelloRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken)) - { - return SayHello(request, new grpc::CallOptions(headers, deadline, cancellationToken)); - } - /// - /// Sends a greeting - /// - /// The request to send to the server. - /// The options for the call. - /// The response received from the server. - public virtual global::Helloworld.HelloReply SayHello(global::Helloworld.HelloRequest request, grpc::CallOptions options) - { - return CallInvoker.BlockingUnaryCall(__Method_SayHello, null, options, request); - } - /// - /// Sends a greeting - /// - /// The request to send to the server. - /// The initial metadata to send with the call. This parameter is optional. - /// An optional deadline for the call. The call will be cancelled if deadline is hit. - /// An optional token for canceling the call. - /// The call object. - public virtual grpc::AsyncUnaryCall SayHelloAsync(global::Helloworld.HelloRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken)) - { - return SayHelloAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken)); - } - /// - /// Sends a greeting - /// - /// The request to send to the server. - /// The options for the call. - /// The call object. - public virtual grpc::AsyncUnaryCall SayHelloAsync(global::Helloworld.HelloRequest request, grpc::CallOptions options) - { - return CallInvoker.AsyncUnaryCall(__Method_SayHello, null, options, request); - } - /// Creates a new instance of client from given ClientBaseConfiguration. - protected override GreeterClient NewInstance(ClientBaseConfiguration configuration) - { - return new GreeterClient(configuration); - } - } - - /// Creates service definition that can be registered with a server - /// An object implementing the server-side handling logic. - public static grpc::ServerServiceDefinition BindService(GreeterBase serviceImpl) - { - return grpc::ServerServiceDefinition.CreateBuilder() - .AddMethod(__Method_SayHello, serviceImpl.SayHello).Build(); - } - - } -} -#endregion diff --git a/examples/csharp/HelloworldLegacyCsproj/Greeter/packages.config b/examples/csharp/HelloworldLegacyCsproj/Greeter/packages.config index 23857be22fa..154b5993213 100644 --- a/examples/csharp/HelloworldLegacyCsproj/Greeter/packages.config +++ b/examples/csharp/HelloworldLegacyCsproj/Greeter/packages.config @@ -1,8 +1,8 @@ - + - - - + + + - \ No newline at end of file + diff --git a/examples/csharp/HelloworldLegacyCsproj/GreeterClient/GreeterClient.csproj b/examples/csharp/HelloworldLegacyCsproj/GreeterClient/GreeterClient.csproj index 3bb7ff1ee13..31a3a90345b 100644 --- a/examples/csharp/HelloworldLegacyCsproj/GreeterClient/GreeterClient.csproj +++ b/examples/csharp/HelloworldLegacyCsproj/GreeterClient/GreeterClient.csproj @@ -1,4 +1,4 @@ - + Debug @@ -36,7 +36,7 @@ ..\packages\Google.Protobuf.3.6.1\lib\net45\Google.Protobuf.dll - ..\packages\Grpc.Core.1.14.1\lib\net45\Grpc.Core.dll + ..\packages\Grpc.Core.1.17.0\lib\net45\Grpc.Core.dll @@ -59,11 +59,11 @@ - + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + \ No newline at end of file diff --git a/examples/csharp/HelloworldLegacyCsproj/GreeterClient/packages.config b/examples/csharp/HelloworldLegacyCsproj/GreeterClient/packages.config index df4df8282c4..2fd8228689d 100644 --- a/examples/csharp/HelloworldLegacyCsproj/GreeterClient/packages.config +++ b/examples/csharp/HelloworldLegacyCsproj/GreeterClient/packages.config @@ -1,7 +1,7 @@ - + - - + + \ No newline at end of file diff --git a/examples/csharp/HelloworldLegacyCsproj/GreeterServer/GreeterServer.csproj b/examples/csharp/HelloworldLegacyCsproj/GreeterServer/GreeterServer.csproj index 4396b04efeb..27ca9630401 100644 --- a/examples/csharp/HelloworldLegacyCsproj/GreeterServer/GreeterServer.csproj +++ b/examples/csharp/HelloworldLegacyCsproj/GreeterServer/GreeterServer.csproj @@ -1,4 +1,4 @@ - + Debug @@ -36,7 +36,7 @@ ..\packages\Google.Protobuf.3.6.1\lib\net45\Google.Protobuf.dll - ..\packages\Grpc.Core.1.14.1\lib\net45\Grpc.Core.dll + ..\packages\Grpc.Core.1.17.0\lib\net45\Grpc.Core.dll @@ -59,11 +59,11 @@ - + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + \ No newline at end of file diff --git a/examples/csharp/HelloworldLegacyCsproj/GreeterServer/packages.config b/examples/csharp/HelloworldLegacyCsproj/GreeterServer/packages.config index df4df8282c4..2fd8228689d 100644 --- a/examples/csharp/HelloworldLegacyCsproj/GreeterServer/packages.config +++ b/examples/csharp/HelloworldLegacyCsproj/GreeterServer/packages.config @@ -1,7 +1,7 @@ - + - - + + \ No newline at end of file diff --git a/examples/csharp/HelloworldLegacyCsproj/README.md b/examples/csharp/HelloworldLegacyCsproj/README.md index 6d42c5ef258..4435faeb086 100644 --- a/examples/csharp/HelloworldLegacyCsproj/README.md +++ b/examples/csharp/HelloworldLegacyCsproj/README.md @@ -3,21 +3,21 @@ gRPC in 3 minutes (C#) BACKGROUND ------------- -This is a different version of the helloworld example, using the old-style .csproj -files supported by VS2013 and VS2015 (and older versions of mono). -You can still use gRPC with the old-style .csproj files, but [using the new-style -.csproj projects](../helloworld/README.md) (supported by VS2017 and dotnet SDK) is recommended. +This is a different version of the helloworld example, using the "classic" .csproj +files, the only format supported by VS2013 (and older versions of mono). +You can still use gRPC with the classic .csproj files, but [using the new-style +.csproj projects](../Helloworld/README.md) (supported by VS2017 v15.3 and above, +and dotnet SDK) is recommended. -For this sample, we've already generated the server and client stubs from [helloworld.proto][]. - -Example projects depend on the [Grpc](https://www.nuget.org/packages/Grpc/), [Grpc.Tools](https://www.nuget.org/packages/Grpc.Tools/) +Example projects depend on the [Grpc](https://www.nuget.org/packages/Grpc/), +[Grpc.Tools](https://www.nuget.org/packages/Grpc.Tools/) and [Google.Protobuf](https://www.nuget.org/packages/Google.Protobuf/) NuGet packages which have been already added to the project for you. PREREQUISITES ------------- -- Windows: .NET Framework 4.5+, Visual Studio 2013 or 2015 +- Windows: .NET Framework 4.5+, Visual Studio 2013 or higher - Linux: Mono 4+, MonoDevelop 5.9+ - Mac OS X: Xamarin Studio 5.9+ @@ -28,12 +28,15 @@ BUILD # Using Visual Studio -* Build the solution (this will automatically download NuGet dependencies) +* Select "Restore NuGet Packages" from the solution context menu. It is recommended + to close and re-open the solution after the packages have been restored from + Visual Studio. +* Build the solution. # Using Monodevelop or Xamarin Studio -The nuget add-in available for Xamarin Studio and Monodevelop IDEs is too old to -download all of the nuget dependencies of gRPC. +The NuGet add-in available for Xamarin Studio and Monodevelop IDEs is too old to +download all of the NuGet dependencies of gRPC. Using these IDEs, a workaround is as follows: * Obtain a nuget executable for your platform and update it with diff --git a/examples/csharp/HelloworldLegacyCsproj/generate_protos.bat b/examples/csharp/HelloworldLegacyCsproj/generate_protos.bat deleted file mode 100644 index d1e7160f91e..00000000000 --- a/examples/csharp/HelloworldLegacyCsproj/generate_protos.bat +++ /dev/null @@ -1,26 +0,0 @@ -@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 Generate the C# code for .proto files - -setlocal - -@rem enter this directory -cd /d %~dp0 - -set TOOLS_PATH=packages\Grpc.Tools.1.14.1\tools\windows_x86 - -%TOOLS_PATH%\protoc.exe -I../../protos --csharp_out Greeter ../../protos/helloworld.proto --grpc_out Greeter --plugin=protoc-gen-grpc=%TOOLS_PATH%\grpc_csharp_plugin.exe - -endlocal diff --git a/examples/csharp/HelloworldUnity/.gitignore b/examples/csharp/HelloworldUnity/.gitignore new file mode 100644 index 00000000000..6245af922f6 --- /dev/null +++ b/examples/csharp/HelloworldUnity/.gitignore @@ -0,0 +1,52 @@ +[Ll]ibrary/ +[Tt]emp/ +[Oo]bj/ +[Bb]uild/ +[Bb]uilds/ +[Ll]ogs/ + +# Never ignore Asset meta data +![Aa]ssets/**/*.meta + +# Uncomment this line if you wish to ignore the asset store tools plugin +# [Aa]ssets/AssetStoreTools* + +# Visual Studio cache directory +.vs/ + +# Gradle cache directory +.gradle/ + +# Autogenerated VS/MD/Consulo solution and project files +ExportedObj/ +.consulo/ +*.csproj +*.unityproj +*.sln +*.suo +*.tmp +*.user +*.userprefs +*.pidb +*.booproj +*.svd +*.pdb +*.mdb +*.opendb +*.VC.db + +# Unity3D generated meta files +*.pidb.meta +*.pdb.meta +*.mdb.meta + +# Unity3D generated file on crash reports +sysinfo.txt + +# Builds +*.apk +*.unitypackage + +# Crashlytics generated file +crashlytics-build.properties + diff --git a/examples/csharp/HelloworldUnity/Assets/Plugins.meta b/examples/csharp/HelloworldUnity/Assets/Plugins.meta new file mode 100644 index 00000000000..31c915a8752 --- /dev/null +++ b/examples/csharp/HelloworldUnity/Assets/Plugins.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 9e39cea189b0245c4a39113ff6459d24 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/examples/csharp/HelloworldUnity/Assets/Scenes.meta b/examples/csharp/HelloworldUnity/Assets/Scenes.meta new file mode 100644 index 00000000000..7fe8e109da3 --- /dev/null +++ b/examples/csharp/HelloworldUnity/Assets/Scenes.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 131a6b21c8605f84396be9f6751fb6e3 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/examples/csharp/HelloworldUnity/Assets/Scenes/SampleScene.unity b/examples/csharp/HelloworldUnity/Assets/Scenes/SampleScene.unity new file mode 100644 index 00000000000..8c5947d0f7b --- /dev/null +++ b/examples/csharp/HelloworldUnity/Assets/Scenes/SampleScene.unity @@ -0,0 +1,586 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!29 &1 +OcclusionCullingSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_OcclusionBakeSettings: + smallestOccluder: 5 + smallestHole: 0.25 + backfaceThreshold: 100 + m_SceneGUID: 00000000000000000000000000000000 + m_OcclusionCullingData: {fileID: 0} +--- !u!104 &2 +RenderSettings: + m_ObjectHideFlags: 0 + serializedVersion: 9 + m_Fog: 0 + m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} + m_FogMode: 3 + m_FogDensity: 0.01 + m_LinearFogStart: 0 + m_LinearFogEnd: 300 + m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} + m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} + m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} + m_AmbientIntensity: 1 + m_AmbientMode: 3 + m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} + m_SkyboxMaterial: {fileID: 0} + m_HaloStrength: 0.5 + m_FlareStrength: 1 + m_FlareFadeSpeed: 3 + m_HaloTexture: {fileID: 0} + m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} + m_DefaultReflectionMode: 0 + m_DefaultReflectionResolution: 128 + m_ReflectionBounces: 1 + m_ReflectionIntensity: 1 + m_CustomReflection: {fileID: 0} + m_Sun: {fileID: 0} + m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1} + m_UseRadianceAmbientProbe: 0 +--- !u!157 &3 +LightmapSettings: + m_ObjectHideFlags: 0 + serializedVersion: 11 + m_GIWorkflowMode: 1 + m_GISettings: + serializedVersion: 2 + m_BounceScale: 1 + m_IndirectOutputScale: 1 + m_AlbedoBoost: 1 + m_TemporalCoherenceThreshold: 1 + m_EnvironmentLightingMode: 0 + m_EnableBakedLightmaps: 0 + m_EnableRealtimeLightmaps: 0 + m_LightmapEditorSettings: + serializedVersion: 10 + m_Resolution: 2 + m_BakeResolution: 40 + m_AtlasSize: 1024 + m_AO: 0 + m_AOMaxDistance: 1 + m_CompAOExponent: 1 + m_CompAOExponentDirect: 0 + m_Padding: 2 + m_LightmapParameters: {fileID: 0} + m_LightmapsBakeMode: 1 + m_TextureCompression: 1 + m_FinalGather: 0 + m_FinalGatherFiltering: 1 + m_FinalGatherRayCount: 256 + m_ReflectionCompression: 2 + m_MixedBakeMode: 2 + m_BakeBackend: 0 + m_PVRSampling: 1 + m_PVRDirectSampleCount: 32 + m_PVRSampleCount: 500 + m_PVRBounces: 2 + m_PVRFilterTypeDirect: 0 + m_PVRFilterTypeIndirect: 0 + m_PVRFilterTypeAO: 0 + m_PVRFilteringMode: 1 + m_PVRCulling: 1 + m_PVRFilteringGaussRadiusDirect: 1 + m_PVRFilteringGaussRadiusIndirect: 5 + m_PVRFilteringGaussRadiusAO: 2 + m_PVRFilteringAtrousPositionSigmaDirect: 0.5 + m_PVRFilteringAtrousPositionSigmaIndirect: 2 + m_PVRFilteringAtrousPositionSigmaAO: 1 + m_ShowResolutionOverlay: 1 + m_LightingDataAsset: {fileID: 0} + m_UseShadowmask: 1 +--- !u!196 &4 +NavMeshSettings: + serializedVersion: 2 + m_ObjectHideFlags: 0 + m_BuildSettings: + serializedVersion: 2 + agentTypeID: 0 + agentRadius: 0.5 + agentHeight: 2 + agentSlope: 45 + agentClimb: 0.4 + ledgeDropHeight: 0 + maxJumpAcrossDistance: 0 + minRegionArea: 2 + manualCellSize: 0 + cellSize: 0.16666667 + manualTileSize: 0 + tileSize: 256 + accuratePlacement: 0 + debug: + m_Flags: 0 + m_NavMeshData: {fileID: 0} +--- !u!1 &519420028 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 519420032} + - component: {fileID: 519420031} + - component: {fileID: 519420029} + m_Layer: 0 + m_Name: Main Camera + m_TagString: MainCamera + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!81 &519420029 +AudioListener: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 519420028} + m_Enabled: 1 +--- !u!20 &519420031 +Camera: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 519420028} + m_Enabled: 1 + serializedVersion: 2 + m_ClearFlags: 2 + m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} + m_projectionMatrixMode: 1 + m_SensorSize: {x: 36, y: 24} + m_LensShift: {x: 0, y: 0} + m_FocalLength: 50 + m_NormalizedViewPortRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + near clip plane: 0.3 + far clip plane: 1000 + field of view: 60 + orthographic: 1 + orthographic size: 5 + m_Depth: -1 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingPath: -1 + m_TargetTexture: {fileID: 0} + m_TargetDisplay: 0 + m_TargetEye: 0 + m_HDR: 1 + m_AllowMSAA: 0 + m_AllowDynamicResolution: 0 + m_ForceIntoRT: 0 + m_OcclusionCulling: 0 + m_StereoConvergence: 10 + m_StereoSeparation: 0.022 +--- !u!4 &519420032 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 519420028} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: -10} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &785253852 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 785253855} + - component: {fileID: 785253854} + - component: {fileID: 785253853} + m_Layer: 0 + m_Name: EventSystem + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &785253853 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 785253852} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 1077351063, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_HorizontalAxis: Horizontal + m_VerticalAxis: Vertical + m_SubmitButton: Submit + m_CancelButton: Cancel + m_InputActionsPerSecond: 10 + m_RepeatDelay: 0.5 + m_ForceModuleActive: 0 +--- !u!114 &785253854 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 785253852} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: -619905303, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_FirstSelected: {fileID: 0} + m_sendNavigationEvents: 1 + m_DragThreshold: 10 +--- !u!4 &785253855 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 785253852} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1639505844 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1639505846} + - component: {fileID: 1639505845} + m_Layer: 0 + m_Name: UIManager + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1639505845 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1639505844} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d62381e23356a4203b3e54cc6c2e3a4f, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!4 &1639505846 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1639505844} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 3 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1729899994 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1729899995} + - component: {fileID: 1729899997} + - component: {fileID: 1729899996} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1729899995 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1729899994} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 2040475500} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1729899996 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1729899994} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_RaycastTarget: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, + Version=1.0.0.0, Culture=neutral, PublicKeyToken=null + m_FontData: + m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} + m_FontSize: 14 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 10 + m_MaxSize: 40 + m_Alignment: 4 + m_AlignByGeometry: 0 + m_RichText: 1 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: Hello gRPC!!! +--- !u!222 &1729899997 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1729899994} + m_CullTransparentMesh: 0 +--- !u!1 &2040475499 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2040475500} + - component: {fileID: 2040475503} + - component: {fileID: 2040475502} + - component: {fileID: 2040475501} + m_Layer: 5 + m_Name: Button + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &2040475500 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 2040475499} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 1729899995} + m_Father: {fileID: 2066701619} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 500, y: 150} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &2040475501 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 2040475499} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 1392445389, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 2040475502} + m_OnClick: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 1639505845} + m_MethodName: RunHelloWorld + m_Mode: 2 + m_Arguments: + m_ObjectArgument: {fileID: 1729899996} + m_ObjectArgumentAssemblyTypeName: UnityEngine.UI.Text, UnityEngine.UI + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 + m_TypeName: UnityEngine.UI.Button+ButtonClickedEvent, UnityEngine.UI, Version=1.0.0.0, + Culture=neutral, PublicKeyToken=null +--- !u!114 &2040475502 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 2040475499} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.34157702, g: 0.6037736, b: 0.093983635, a: 1} + m_RaycastTarget: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, + Version=1.0.0.0, Culture=neutral, PublicKeyToken=null + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 +--- !u!222 &2040475503 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 2040475499} + m_CullTransparentMesh: 0 +--- !u!1 &2066701615 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2066701619} + - component: {fileID: 2066701618} + - component: {fileID: 2066701617} + - component: {fileID: 2066701616} + m_Layer: 5 + m_Name: Canvas + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &2066701616 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 2066701615} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 1301386320, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_IgnoreReversedGraphics: 1 + m_BlockingObjects: 0 + m_BlockingMask: + serializedVersion: 2 + m_Bits: 4294967295 +--- !u!114 &2066701617 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 2066701615} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 1980459831, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_UiScaleMode: 0 + m_ReferencePixelsPerUnit: 100 + m_ScaleFactor: 1 + m_ReferenceResolution: {x: 800, y: 600} + m_ScreenMatchMode: 0 + m_MatchWidthOrHeight: 0 + m_PhysicalUnit: 3 + m_FallbackScreenDPI: 96 + m_DefaultSpriteDPI: 96 + m_DynamicPixelsPerUnit: 1 +--- !u!223 &2066701618 +Canvas: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 2066701615} + m_Enabled: 1 + serializedVersion: 3 + m_RenderMode: 0 + m_Camera: {fileID: 0} + m_PlaneDistance: 100 + m_PixelPerfect: 0 + m_ReceivesEvents: 1 + m_OverrideSorting: 0 + m_OverridePixelPerfect: 0 + m_SortingBucketNormalizedSize: 0 + m_AdditionalShaderChannelsFlag: 0 + m_SortingLayerID: 0 + m_SortingOrder: 0 + m_TargetDisplay: 0 +--- !u!224 &2066701619 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 2066701615} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 0, y: 0, z: 0} + m_Children: + - {fileID: 2040475500} + m_Father: {fileID: 0} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0, y: 0} diff --git a/examples/csharp/HelloworldUnity/Assets/Scenes/SampleScene.unity.meta b/examples/csharp/HelloworldUnity/Assets/Scenes/SampleScene.unity.meta new file mode 100644 index 00000000000..c1e3c88e1cf --- /dev/null +++ b/examples/csharp/HelloworldUnity/Assets/Scenes/SampleScene.unity.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 2cda990e2423bbf4892e6590ba056729 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/examples/csharp/HelloworldUnity/Assets/Scripts.meta b/examples/csharp/HelloworldUnity/Assets/Scripts.meta new file mode 100644 index 00000000000..49e35f97956 --- /dev/null +++ b/examples/csharp/HelloworldUnity/Assets/Scripts.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 55598493aa3774a6dad4b7a4974826ff +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/examples/csharp/HelloworldUnity/Assets/Scripts/HelloWorldScript.cs b/examples/csharp/HelloworldUnity/Assets/Scripts/HelloWorldScript.cs new file mode 100644 index 00000000000..0dad0f6a5ad --- /dev/null +++ b/examples/csharp/HelloworldUnity/Assets/Scripts/HelloWorldScript.cs @@ -0,0 +1,38 @@ +#region Copyright notice and license + +// Copyright 2019 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. +// 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 UnityEngine; +using UnityEngine.UI; + +public class HelloWorldScript : MonoBehaviour { + int counter = 1; + + // Use this for initialization + void Start () {} + + // Update is called once per frame + void Update() {} + + // Ran when button is clicked + public void RunHelloWorld(Text text) + { + var reply = HelloWorldTest.Greet("Unity " + counter); + text.text = "Greeting: " + reply.Message; + counter++; + } +} diff --git a/examples/csharp/HelloworldUnity/Assets/Scripts/HelloWorldScript.cs.meta b/examples/csharp/HelloworldUnity/Assets/Scripts/HelloWorldScript.cs.meta new file mode 100644 index 00000000000..60b0ea38c08 --- /dev/null +++ b/examples/csharp/HelloworldUnity/Assets/Scripts/HelloWorldScript.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d62381e23356a4203b3e54cc6c2e3a4f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/examples/csharp/HelloworldUnity/Assets/Scripts/HelloWorldTest.cs b/examples/csharp/HelloworldUnity/Assets/Scripts/HelloWorldTest.cs new file mode 100644 index 00000000000..2c10f10a144 --- /dev/null +++ b/examples/csharp/HelloworldUnity/Assets/Scripts/HelloWorldTest.cs @@ -0,0 +1,81 @@ +#region Copyright notice and license + +// Copyright 2019 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. +// 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 UnityEngine; +using System.Threading.Tasks; +using System; +using Grpc.Core; +using Helloworld; + +class HelloWorldTest +{ + // Can be run from commandline. + // Example command: + // "/Applications/Unity/Unity.app/Contents/MacOS/Unity -quit -batchmode -nographics -executeMethod HelloWorldTest.RunHelloWorld -logfile" + public static void RunHelloWorld() + { + Application.SetStackTraceLogType(LogType.Log, StackTraceLogType.None); + + Debug.Log("=============================================================="); + Debug.Log("Starting tests"); + Debug.Log("=============================================================="); + + Debug.Log("Application.platform: " + Application.platform); + Debug.Log("Environment.OSVersion: " + Environment.OSVersion); + + var reply = Greet("Unity"); + Debug.Log("Greeting: " + reply.Message); + + Debug.Log("=============================================================="); + Debug.Log("Tests finished successfully."); + Debug.Log("=============================================================="); + } + + public static HelloReply Greet(string greeting) + { + const int Port = 50051; + + Server server = new Server + { + Services = { Greeter.BindService(new GreeterImpl()) }, + Ports = { new ServerPort("localhost", Port, ServerCredentials.Insecure) } + }; + server.Start(); + + Channel channel = new Channel("127.0.0.1:50051", ChannelCredentials.Insecure); + + var client = new Greeter.GreeterClient(channel); + + var reply = client.SayHello(new HelloRequest { Name = greeting }); + + channel.ShutdownAsync().Wait(); + + server.ShutdownAsync().Wait(); + + return reply; + } + + class GreeterImpl : Greeter.GreeterBase + { + // Server side handler of the SayHello RPC + public override Task SayHello(HelloRequest request, ServerCallContext context) + { + return Task.FromResult(new HelloReply { Message = "Hello " + request.Name }); + } + } +} diff --git a/examples/csharp/HelloworldUnity/Assets/Scripts/HelloWorldTest.cs.meta b/examples/csharp/HelloworldUnity/Assets/Scripts/HelloWorldTest.cs.meta new file mode 100644 index 00000000000..f511815254a --- /dev/null +++ b/examples/csharp/HelloworldUnity/Assets/Scripts/HelloWorldTest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8c088e5dee11c45fc95e41b9281d55e2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/examples/csharp/HelloworldLegacyCsproj/Greeter/Helloworld.cs b/examples/csharp/HelloworldUnity/Assets/Scripts/Helloworld.cs similarity index 86% rename from examples/csharp/HelloworldLegacyCsproj/Greeter/Helloworld.cs rename to examples/csharp/HelloworldUnity/Assets/Scripts/Helloworld.cs index e008ec27e54..ecfc8e131cb 100644 --- a/examples/csharp/HelloworldLegacyCsproj/Greeter/Helloworld.cs +++ b/examples/csharp/HelloworldUnity/Assets/Scripts/Helloworld.cs @@ -1,7 +1,5 @@ -// -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: helloworld.proto -// +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: helloworld.proto #pragma warning disable 1591, 0612, 3021 #region Designer generated code @@ -46,7 +44,6 @@ namespace Helloworld { /// public sealed partial class HelloRequest : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new HelloRequest()); - private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } @@ -70,7 +67,6 @@ namespace Helloworld { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public HelloRequest(HelloRequest other) : this() { name_ = other.name_; - _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -103,16 +99,13 @@ namespace Helloworld { return true; } if (Name != other.Name) return false; - return Equals(_unknownFields, other._unknownFields); + return true; } [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; } @@ -127,9 +120,6 @@ namespace Helloworld { output.WriteRawTag(10); output.WriteString(Name); } - if (_unknownFields != null) { - _unknownFields.WriteTo(output); - } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -138,9 +128,6 @@ namespace Helloworld { if (Name.Length != 0) { size += 1 + pb::CodedOutputStream.ComputeStringSize(Name); } - if (_unknownFields != null) { - size += _unknownFields.CalculateSize(); - } return size; } @@ -152,7 +139,6 @@ namespace Helloworld { if (other.Name.Length != 0) { Name = other.Name; } - _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -161,7 +147,7 @@ namespace Helloworld { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + input.SkipLastField(); break; case 10: { Name = input.ReadString(); @@ -178,7 +164,6 @@ namespace Helloworld { /// public sealed partial class HelloReply : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new HelloReply()); - private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } @@ -202,7 +187,6 @@ namespace Helloworld { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public HelloReply(HelloReply other) : this() { message_ = other.message_; - _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -235,16 +219,13 @@ namespace Helloworld { return true; } if (Message != other.Message) return false; - return Equals(_unknownFields, other._unknownFields); + return true; } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; if (Message.Length != 0) hash ^= Message.GetHashCode(); - if (_unknownFields != null) { - hash ^= _unknownFields.GetHashCode(); - } return hash; } @@ -259,9 +240,6 @@ namespace Helloworld { output.WriteRawTag(10); output.WriteString(Message); } - if (_unknownFields != null) { - _unknownFields.WriteTo(output); - } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -270,9 +248,6 @@ namespace Helloworld { if (Message.Length != 0) { size += 1 + pb::CodedOutputStream.ComputeStringSize(Message); } - if (_unknownFields != null) { - size += _unknownFields.CalculateSize(); - } return size; } @@ -284,7 +259,6 @@ namespace Helloworld { if (other.Message.Length != 0) { Message = other.Message; } - _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -293,7 +267,7 @@ namespace Helloworld { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + input.SkipLastField(); break; case 10: { Message = input.ReadString(); diff --git a/examples/csharp/HelloworldUnity/Assets/Scripts/Helloworld.cs.meta b/examples/csharp/HelloworldUnity/Assets/Scripts/Helloworld.cs.meta new file mode 100644 index 00000000000..7a43df02a17 --- /dev/null +++ b/examples/csharp/HelloworldUnity/Assets/Scripts/Helloworld.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8bfcdd9a5979d4cc7b76d17be585e778 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/examples/csharp/Helloworld/Greeter/HelloworldGrpc.cs b/examples/csharp/HelloworldUnity/Assets/Scripts/HelloworldGrpc.cs similarity index 86% rename from examples/csharp/Helloworld/Greeter/HelloworldGrpc.cs rename to examples/csharp/HelloworldUnity/Assets/Scripts/HelloworldGrpc.cs index d6b959adc64..c808884e579 100644 --- a/examples/csharp/Helloworld/Greeter/HelloworldGrpc.cs +++ b/examples/csharp/HelloworldUnity/Assets/Scripts/HelloworldGrpc.cs @@ -1,7 +1,5 @@ -// -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: helloworld.proto -// +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: helloworld.proto // Original file comments: // Copyright 2015 gRPC authors. // @@ -17,9 +15,12 @@ // See the License for the specific language governing permissions and // limitations under the License. // -#pragma warning disable 0414, 1591 +#pragma warning disable 1591 #region Designer generated code +using System; +using System.Threading; +using System.Threading.Tasks; using grpc = global::Grpc.Core; namespace Helloworld { @@ -30,15 +31,15 @@ namespace Helloworld { { static readonly string __ServiceName = "helloworld.Greeter"; - static readonly grpc::Marshaller __Marshaller_helloworld_HelloRequest = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Helloworld.HelloRequest.Parser.ParseFrom); - static readonly grpc::Marshaller __Marshaller_helloworld_HelloReply = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Helloworld.HelloReply.Parser.ParseFrom); + static readonly grpc::Marshaller __Marshaller_HelloRequest = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Helloworld.HelloRequest.Parser.ParseFrom); + static readonly grpc::Marshaller __Marshaller_HelloReply = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Helloworld.HelloReply.Parser.ParseFrom); static readonly grpc::Method __Method_SayHello = new grpc::Method( grpc::MethodType.Unary, __ServiceName, "SayHello", - __Marshaller_helloworld_HelloRequest, - __Marshaller_helloworld_HelloReply); + __Marshaller_HelloRequest, + __Marshaller_HelloReply); /// Service descriptor public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor @@ -93,7 +94,7 @@ namespace Helloworld { /// An optional deadline for the call. The call will be cancelled if deadline is hit. /// An optional token for canceling the call. /// The response received from the server. - public virtual global::Helloworld.HelloReply SayHello(global::Helloworld.HelloRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken)) + public virtual global::Helloworld.HelloReply SayHello(global::Helloworld.HelloRequest request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken)) { return SayHello(request, new grpc::CallOptions(headers, deadline, cancellationToken)); } @@ -115,7 +116,7 @@ namespace Helloworld { /// An optional deadline for the call. The call will be cancelled if deadline is hit. /// An optional token for canceling the call. /// The call object. - public virtual grpc::AsyncUnaryCall SayHelloAsync(global::Helloworld.HelloRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken)) + public virtual grpc::AsyncUnaryCall SayHelloAsync(global::Helloworld.HelloRequest request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken)) { return SayHelloAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken)); } diff --git a/examples/csharp/HelloworldUnity/Assets/Scripts/HelloworldGrpc.cs.meta b/examples/csharp/HelloworldUnity/Assets/Scripts/HelloworldGrpc.cs.meta new file mode 100644 index 00000000000..e6a26fca3dc --- /dev/null +++ b/examples/csharp/HelloworldUnity/Assets/Scripts/HelloworldGrpc.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cf9b820c371a143ce96df8edaebb3fe2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/examples/csharp/HelloworldUnity/ProjectSettings/AudioManager.asset b/examples/csharp/HelloworldUnity/ProjectSettings/AudioManager.asset new file mode 100644 index 00000000000..304925ebde5 --- /dev/null +++ b/examples/csharp/HelloworldUnity/ProjectSettings/AudioManager.asset @@ -0,0 +1,17 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!11 &1 +AudioManager: + m_ObjectHideFlags: 0 + m_Volume: 1 + Rolloff Scale: 1 + Doppler Factor: 1 + Default Speaker Mode: 2 + m_SampleRate: 0 + m_DSPBufferSize: 1024 + m_VirtualVoiceCount: 512 + m_RealVoiceCount: 32 + m_SpatializerPlugin: + m_AmbisonicDecoderPlugin: + m_DisableAudio: 0 + m_VirtualizeEffects: 1 diff --git a/examples/csharp/HelloworldUnity/ProjectSettings/ClusterInputManager.asset b/examples/csharp/HelloworldUnity/ProjectSettings/ClusterInputManager.asset new file mode 100644 index 00000000000..a84cf4e6fe7 --- /dev/null +++ b/examples/csharp/HelloworldUnity/ProjectSettings/ClusterInputManager.asset @@ -0,0 +1,6 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!236 &1 +ClusterInputManager: + m_ObjectHideFlags: 0 + m_Inputs: [] diff --git a/examples/csharp/HelloworldUnity/ProjectSettings/DynamicsManager.asset b/examples/csharp/HelloworldUnity/ProjectSettings/DynamicsManager.asset new file mode 100644 index 00000000000..78992f08c7a --- /dev/null +++ b/examples/csharp/HelloworldUnity/ProjectSettings/DynamicsManager.asset @@ -0,0 +1,29 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!55 &1 +PhysicsManager: + m_ObjectHideFlags: 0 + serializedVersion: 7 + m_Gravity: {x: 0, y: -9.81, z: 0} + m_DefaultMaterial: {fileID: 0} + m_BounceThreshold: 2 + m_SleepThreshold: 0.005 + m_DefaultContactOffset: 0.01 + m_DefaultSolverIterations: 6 + m_DefaultSolverVelocityIterations: 1 + m_QueriesHitBackfaces: 0 + m_QueriesHitTriggers: 1 + m_EnableAdaptiveForce: 0 + m_ClothInterCollisionDistance: 0 + m_ClothInterCollisionStiffness: 0 + m_ContactsGeneration: 1 + m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + m_AutoSimulation: 1 + m_AutoSyncTransforms: 1 + m_ClothInterCollisionSettingsToggle: 0 + m_ContactPairsMode: 0 + m_BroadphaseType: 0 + m_WorldBounds: + m_Center: {x: 0, y: 0, z: 0} + m_Extent: {x: 250, y: 250, z: 250} + m_WorldSubdivisions: 8 diff --git a/examples/csharp/HelloworldUnity/ProjectSettings/EditorBuildSettings.asset b/examples/csharp/HelloworldUnity/ProjectSettings/EditorBuildSettings.asset new file mode 100644 index 00000000000..62c5a75b293 --- /dev/null +++ b/examples/csharp/HelloworldUnity/ProjectSettings/EditorBuildSettings.asset @@ -0,0 +1,11 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1045 &1 +EditorBuildSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Scenes: + - enabled: 1 + path: Assets/Scenes/SampleScene.unity + guid: 2cda990e2423bbf4892e6590ba056729 + m_configObjects: {} diff --git a/examples/csharp/HelloworldUnity/ProjectSettings/EditorSettings.asset b/examples/csharp/HelloworldUnity/ProjectSettings/EditorSettings.asset new file mode 100644 index 00000000000..3376fd8b501 --- /dev/null +++ b/examples/csharp/HelloworldUnity/ProjectSettings/EditorSettings.asset @@ -0,0 +1,21 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!159 &1 +EditorSettings: + m_ObjectHideFlags: 0 + serializedVersion: 7 + m_ExternalVersionControlSupport: Visible Meta Files + m_SerializationMode: 2 + m_LineEndingsForNewScripts: 2 + m_DefaultBehaviorMode: 1 + m_SpritePackerMode: 4 + m_SpritePackerPaddingPower: 1 + m_EtcTextureCompressorBehavior: 1 + m_EtcTextureFastCompressor: 1 + m_EtcTextureNormalCompressor: 2 + m_EtcTextureBestCompressor: 4 + m_ProjectGenerationIncludedExtensions: txt;xml;fnt;cd + m_ProjectGenerationRootNamespace: + m_UserGeneratedProjectSuffix: + m_CollabEditorSettings: + inProgressEnabled: 1 diff --git a/examples/csharp/HelloworldUnity/ProjectSettings/GraphicsSettings.asset b/examples/csharp/HelloworldUnity/ProjectSettings/GraphicsSettings.asset new file mode 100644 index 00000000000..b35e28eaf0f --- /dev/null +++ b/examples/csharp/HelloworldUnity/ProjectSettings/GraphicsSettings.asset @@ -0,0 +1,60 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!30 &1 +GraphicsSettings: + m_ObjectHideFlags: 0 + serializedVersion: 12 + m_Deferred: + m_Mode: 1 + m_Shader: {fileID: 69, guid: 0000000000000000f000000000000000, type: 0} + m_DeferredReflections: + m_Mode: 1 + m_Shader: {fileID: 74, guid: 0000000000000000f000000000000000, type: 0} + m_ScreenSpaceShadows: + m_Mode: 1 + m_Shader: {fileID: 64, guid: 0000000000000000f000000000000000, type: 0} + m_LegacyDeferred: + m_Mode: 1 + m_Shader: {fileID: 63, guid: 0000000000000000f000000000000000, type: 0} + m_DepthNormals: + m_Mode: 1 + m_Shader: {fileID: 62, guid: 0000000000000000f000000000000000, type: 0} + m_MotionVectors: + m_Mode: 1 + m_Shader: {fileID: 75, guid: 0000000000000000f000000000000000, type: 0} + m_LightHalo: + m_Mode: 1 + m_Shader: {fileID: 105, guid: 0000000000000000f000000000000000, type: 0} + m_LensFlare: + m_Mode: 1 + m_Shader: {fileID: 102, guid: 0000000000000000f000000000000000, type: 0} + m_AlwaysIncludedShaders: + - {fileID: 10753, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 10770, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 17000, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 16000, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 16002, guid: 0000000000000000f000000000000000, type: 0} + m_PreloadedShaders: [] + m_SpritesDefaultMaterial: {fileID: 10754, guid: 0000000000000000f000000000000000, + type: 0} + m_CustomRenderPipeline: {fileID: 0} + m_TransparencySortMode: 0 + m_TransparencySortAxis: {x: 0, y: 0, z: 1} + m_DefaultRenderingPath: 1 + m_DefaultMobileRenderingPath: 1 + m_TierSettings: [] + m_LightmapStripping: 0 + m_FogStripping: 0 + m_InstancingStripping: 0 + m_LightmapKeepPlain: 1 + m_LightmapKeepDirCombined: 1 + m_LightmapKeepDynamicPlain: 1 + m_LightmapKeepDynamicDirCombined: 1 + m_LightmapKeepShadowMask: 1 + m_LightmapKeepSubtractive: 1 + m_FogKeepLinear: 1 + m_FogKeepExp: 1 + m_FogKeepExp2: 1 + m_AlbedoSwatchInfos: [] + m_LightsUseLinearIntensity: 0 + m_LightsUseColorTemperature: 0 diff --git a/examples/csharp/HelloworldUnity/ProjectSettings/InputManager.asset b/examples/csharp/HelloworldUnity/ProjectSettings/InputManager.asset new file mode 100644 index 00000000000..25966468fff --- /dev/null +++ b/examples/csharp/HelloworldUnity/ProjectSettings/InputManager.asset @@ -0,0 +1,295 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!13 &1 +InputManager: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Axes: + - serializedVersion: 3 + m_Name: Horizontal + descriptiveName: + descriptiveNegativeName: + negativeButton: left + positiveButton: right + altNegativeButton: a + altPositiveButton: d + gravity: 3 + dead: 0.001 + sensitivity: 3 + snap: 1 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Vertical + descriptiveName: + descriptiveNegativeName: + negativeButton: down + positiveButton: up + altNegativeButton: s + altPositiveButton: w + gravity: 3 + dead: 0.001 + sensitivity: 3 + snap: 1 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire1 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: left ctrl + altNegativeButton: + altPositiveButton: mouse 0 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire2 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: left alt + altNegativeButton: + altPositiveButton: mouse 1 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire3 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: left shift + altNegativeButton: + altPositiveButton: mouse 2 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Jump + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: space + altNegativeButton: + altPositiveButton: + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Mouse X + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0 + sensitivity: 0.1 + snap: 0 + invert: 0 + type: 1 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Mouse Y + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0 + sensitivity: 0.1 + snap: 0 + invert: 0 + type: 1 + axis: 1 + joyNum: 0 + - serializedVersion: 3 + m_Name: Mouse ScrollWheel + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0 + sensitivity: 0.1 + snap: 0 + invert: 0 + type: 1 + axis: 2 + joyNum: 0 + - serializedVersion: 3 + m_Name: Horizontal + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0.19 + sensitivity: 1 + snap: 0 + invert: 0 + type: 2 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Vertical + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0.19 + sensitivity: 1 + snap: 0 + invert: 1 + type: 2 + axis: 1 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire1 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: joystick button 0 + altNegativeButton: + altPositiveButton: + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire2 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: joystick button 1 + altNegativeButton: + altPositiveButton: + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire3 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: joystick button 2 + altNegativeButton: + altPositiveButton: + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Jump + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: joystick button 3 + altNegativeButton: + altPositiveButton: + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Submit + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: return + altNegativeButton: + altPositiveButton: joystick button 0 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Submit + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: enter + altNegativeButton: + altPositiveButton: space + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Cancel + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: escape + altNegativeButton: + altPositiveButton: joystick button 1 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 diff --git a/examples/csharp/HelloworldUnity/ProjectSettings/NavMeshAreas.asset b/examples/csharp/HelloworldUnity/ProjectSettings/NavMeshAreas.asset new file mode 100644 index 00000000000..c8fa1b5bd1e --- /dev/null +++ b/examples/csharp/HelloworldUnity/ProjectSettings/NavMeshAreas.asset @@ -0,0 +1,91 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!126 &1 +NavMeshProjectSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + areas: + - name: Walkable + cost: 1 + - name: Not Walkable + cost: 1 + - name: Jump + cost: 2 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + m_LastAgentTypeID: -887442657 + m_Settings: + - serializedVersion: 2 + agentTypeID: 0 + agentRadius: 0.5 + agentHeight: 2 + agentSlope: 45 + agentClimb: 0.75 + ledgeDropHeight: 0 + maxJumpAcrossDistance: 0 + minRegionArea: 2 + manualCellSize: 0 + cellSize: 0.16666667 + manualTileSize: 0 + tileSize: 256 + accuratePlacement: 0 + debug: + m_Flags: 0 + m_SettingNames: + - Humanoid diff --git a/examples/csharp/HelloworldUnity/ProjectSettings/NetworkManager.asset b/examples/csharp/HelloworldUnity/ProjectSettings/NetworkManager.asset new file mode 100644 index 00000000000..e9cd5781b1a --- /dev/null +++ b/examples/csharp/HelloworldUnity/ProjectSettings/NetworkManager.asset @@ -0,0 +1,8 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!149 &1 +NetworkManager: + m_ObjectHideFlags: 0 + m_DebugLevel: 0 + m_Sendrate: 15 + m_AssetToPrefab: {} diff --git a/examples/csharp/HelloworldUnity/ProjectSettings/Physics2DSettings.asset b/examples/csharp/HelloworldUnity/ProjectSettings/Physics2DSettings.asset new file mode 100644 index 00000000000..8e9e0210986 --- /dev/null +++ b/examples/csharp/HelloworldUnity/ProjectSettings/Physics2DSettings.asset @@ -0,0 +1,55 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!19 &1 +Physics2DSettings: + m_ObjectHideFlags: 0 + serializedVersion: 3 + m_Gravity: {x: 0, y: -9.81} + m_DefaultMaterial: {fileID: 0} + m_VelocityIterations: 8 + m_PositionIterations: 3 + m_VelocityThreshold: 1 + m_MaxLinearCorrection: 0.2 + m_MaxAngularCorrection: 8 + m_MaxTranslationSpeed: 100 + m_MaxRotationSpeed: 360 + m_BaumgarteScale: 0.2 + m_BaumgarteTimeOfImpactScale: 0.75 + m_TimeToSleep: 0.5 + m_LinearSleepTolerance: 0.01 + m_AngularSleepTolerance: 2 + m_DefaultContactOffset: 0.01 + m_JobOptions: + serializedVersion: 2 + useMultithreading: 0 + useConsistencySorting: 0 + m_InterpolationPosesPerJob: 100 + m_NewContactsPerJob: 30 + m_CollideContactsPerJob: 100 + m_ClearFlagsPerJob: 200 + m_ClearBodyForcesPerJob: 200 + m_SyncDiscreteFixturesPerJob: 50 + m_SyncContinuousFixturesPerJob: 50 + m_FindNearestContactsPerJob: 100 + m_UpdateTriggerContactsPerJob: 100 + m_IslandSolverCostThreshold: 100 + m_IslandSolverBodyCostScale: 1 + m_IslandSolverContactCostScale: 10 + m_IslandSolverJointCostScale: 10 + m_IslandSolverBodiesPerJob: 50 + m_IslandSolverContactsPerJob: 50 + m_AutoSimulation: 1 + m_QueriesHitTriggers: 1 + m_QueriesStartInColliders: 1 + m_CallbacksOnDisable: 1 + m_AutoSyncTransforms: 1 + m_AlwaysShowColliders: 0 + m_ShowColliderSleep: 1 + m_ShowColliderContacts: 0 + m_ShowColliderAABB: 0 + m_ContactArrowScale: 0.2 + m_ColliderAwakeColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.7529412} + m_ColliderAsleepColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.36078432} + m_ColliderContactColor: {r: 1, g: 0, b: 1, a: 0.6862745} + m_ColliderAABBColor: {r: 1, g: 1, b: 0, a: 0.2509804} + m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff diff --git a/examples/csharp/HelloworldUnity/ProjectSettings/PresetManager.asset b/examples/csharp/HelloworldUnity/ProjectSettings/PresetManager.asset new file mode 100644 index 00000000000..0832099de85 --- /dev/null +++ b/examples/csharp/HelloworldUnity/ProjectSettings/PresetManager.asset @@ -0,0 +1,13 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1386491679 &1 +PresetManager: + m_ObjectHideFlags: 0 + m_DefaultList: + - type: + m_NativeTypeID: 20 + m_ManagedTypePPtr: {fileID: 0} + m_ManagedTypeFallback: + defaultPresets: + - m_Preset: {fileID: 2655988077585873504, guid: bfcfc320427f8224bbb7a96f3d3aebad, + type: 2} diff --git a/examples/csharp/HelloworldUnity/ProjectSettings/ProjectSettings.asset b/examples/csharp/HelloworldUnity/ProjectSettings/ProjectSettings.asset new file mode 100644 index 00000000000..b1e2fb0a430 --- /dev/null +++ b/examples/csharp/HelloworldUnity/ProjectSettings/ProjectSettings.asset @@ -0,0 +1,656 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!129 &1 +PlayerSettings: + m_ObjectHideFlags: 0 + serializedVersion: 15 + productGUID: 2ed9f077cb8c7421b9d7c7fa18f3c25d + AndroidProfiler: 0 + AndroidFilterTouchesWhenObscured: 0 + AndroidEnableSustainedPerformanceMode: 0 + defaultScreenOrientation: 4 + targetDevice: 2 + useOnDemandResources: 0 + accelerometerFrequency: 60 + companyName: com.grpc.examples + productName: HelloworldUnity + defaultCursor: {fileID: 0} + cursorHotspot: {x: 0, y: 0} + m_SplashScreenBackgroundColor: {r: 0.13725491, g: 0.12156863, b: 0.1254902, a: 1} + m_ShowUnitySplashScreen: 1 + m_ShowUnitySplashLogo: 1 + m_SplashScreenOverlayOpacity: 1 + m_SplashScreenAnimation: 1 + m_SplashScreenLogoStyle: 1 + m_SplashScreenDrawMode: 0 + m_SplashScreenBackgroundAnimationZoom: 1 + m_SplashScreenLogoAnimationZoom: 1 + m_SplashScreenBackgroundLandscapeAspect: 1 + m_SplashScreenBackgroundPortraitAspect: 1 + m_SplashScreenBackgroundLandscapeUvs: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + m_SplashScreenBackgroundPortraitUvs: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + m_SplashScreenLogos: [] + m_VirtualRealitySplashScreen: {fileID: 0} + m_HolographicTrackingLossScreen: {fileID: 0} + defaultScreenWidth: 1024 + defaultScreenHeight: 768 + defaultScreenWidthWeb: 960 + defaultScreenHeightWeb: 600 + m_StereoRenderingPath: 0 + m_ActiveColorSpace: 0 + m_MTRendering: 1 + m_StackTraceTypes: 010000000100000001000000010000000100000001000000 + iosShowActivityIndicatorOnLoading: -1 + androidShowActivityIndicatorOnLoading: -1 + iosAppInBackgroundBehavior: 0 + displayResolutionDialog: 1 + iosAllowHTTPDownload: 1 + allowedAutorotateToPortrait: 1 + allowedAutorotateToPortraitUpsideDown: 1 + allowedAutorotateToLandscapeRight: 1 + allowedAutorotateToLandscapeLeft: 1 + useOSAutorotation: 1 + use32BitDisplayBuffer: 1 + preserveFramebufferAlpha: 0 + disableDepthAndStencilBuffers: 0 + androidStartInFullscreen: 1 + androidRenderOutsideSafeArea: 0 + androidBlitType: 0 + defaultIsNativeResolution: 1 + macRetinaSupport: 1 + runInBackground: 1 + captureSingleScreen: 0 + muteOtherAudioSources: 0 + Prepare IOS For Recording: 0 + Force IOS Speakers When Recording: 0 + deferSystemGesturesMode: 0 + hideHomeButton: 0 + submitAnalytics: 1 + usePlayerLog: 1 + bakeCollisionMeshes: 0 + forceSingleInstance: 0 + resizableWindow: 0 + useMacAppStoreValidation: 0 + macAppStoreCategory: public.app-category.games + gpuSkinning: 0 + graphicsJobs: 0 + xboxPIXTextureCapture: 0 + xboxEnableAvatar: 0 + xboxEnableKinect: 0 + xboxEnableKinectAutoTracking: 0 + xboxEnableFitness: 0 + visibleInBackground: 1 + allowFullscreenSwitch: 1 + graphicsJobMode: 0 + fullscreenMode: 1 + xboxSpeechDB: 0 + xboxEnableHeadOrientation: 0 + xboxEnableGuest: 0 + xboxEnablePIXSampling: 0 + metalFramebufferOnly: 0 + xboxOneResolution: 0 + xboxOneSResolution: 0 + xboxOneXResolution: 3 + xboxOneMonoLoggingLevel: 0 + xboxOneLoggingLevel: 1 + xboxOneDisableEsram: 0 + xboxOnePresentImmediateThreshold: 0 + switchQueueCommandMemory: 0 + vulkanEnableSetSRGBWrite: 0 + m_SupportedAspectRatios: + 4:3: 1 + 5:4: 1 + 16:10: 1 + 16:9: 1 + Others: 1 + bundleVersion: 0.1 + preloadedAssets: [] + metroInputSource: 0 + wsaTransparentSwapchain: 0 + m_HolographicPauseOnTrackingLoss: 1 + xboxOneDisableKinectGpuReservation: 0 + xboxOneEnable7thCore: 0 + isWsaHolographicRemotingEnabled: 0 + vrSettings: + cardboard: + depthFormat: 0 + enableTransitionView: 0 + daydream: + depthFormat: 0 + useSustainedPerformanceMode: 0 + enableVideoLayer: 0 + useProtectedVideoMemory: 0 + minimumSupportedHeadTracking: 0 + maximumSupportedHeadTracking: 1 + hololens: + depthFormat: 1 + depthBufferSharingEnabled: 0 + oculus: + sharedDepthBuffer: 0 + dashSupport: 0 + enable360StereoCapture: 0 + protectGraphicsMemory: 0 + enableFrameTimingStats: 0 + useHDRDisplay: 0 + m_ColorGamuts: 00000000 + targetPixelDensity: 30 + resolutionScalingMode: 0 + androidSupportedAspectRatio: 1 + androidMaxAspectRatio: 2.1 + applicationIdentifier: + Android: com.grpc.examples + Standalone: com.Company.ProductName + iOS: com.jattermusch.grpc.example + buildNumber: {} + AndroidBundleVersionCode: 1 + AndroidMinSdkVersion: 16 + AndroidTargetSdkVersion: 0 + AndroidPreferredInstallLocation: 1 + aotOptions: + stripEngineCode: 1 + iPhoneStrippingLevel: 0 + iPhoneScriptCallOptimization: 0 + ForceInternetPermission: 0 + ForceSDCardPermission: 0 + CreateWallpaper: 0 + APKExpansionFiles: 0 + keepLoadedShadersAlive: 0 + StripUnusedMeshComponents: 1 + VertexChannelCompressionMask: 4054 + iPhoneSdkVersion: 989 + iOSTargetOSVersionString: 9.0 + tvOSSdkVersion: 0 + tvOSRequireExtendedGameController: 0 + tvOSTargetOSVersionString: 9.0 + uIPrerenderedIcon: 0 + uIRequiresPersistentWiFi: 0 + uIRequiresFullScreen: 1 + uIStatusBarHidden: 1 + uIExitOnSuspend: 0 + uIStatusBarStyle: 0 + iPhoneSplashScreen: {fileID: 0} + iPhoneHighResSplashScreen: {fileID: 0} + iPhoneTallHighResSplashScreen: {fileID: 0} + iPhone47inSplashScreen: {fileID: 0} + iPhone55inPortraitSplashScreen: {fileID: 0} + iPhone55inLandscapeSplashScreen: {fileID: 0} + iPhone58inPortraitSplashScreen: {fileID: 0} + iPhone58inLandscapeSplashScreen: {fileID: 0} + iPadPortraitSplashScreen: {fileID: 0} + iPadHighResPortraitSplashScreen: {fileID: 0} + iPadLandscapeSplashScreen: {fileID: 0} + iPadHighResLandscapeSplashScreen: {fileID: 0} + appleTVSplashScreen: {fileID: 0} + appleTVSplashScreen2x: {fileID: 0} + tvOSSmallIconLayers: [] + tvOSSmallIconLayers2x: [] + tvOSLargeIconLayers: [] + tvOSLargeIconLayers2x: [] + tvOSTopShelfImageLayers: [] + tvOSTopShelfImageLayers2x: [] + tvOSTopShelfImageWideLayers: [] + tvOSTopShelfImageWideLayers2x: [] + iOSLaunchScreenType: 0 + iOSLaunchScreenPortrait: {fileID: 0} + iOSLaunchScreenLandscape: {fileID: 0} + iOSLaunchScreenBackgroundColor: + serializedVersion: 2 + rgba: 0 + iOSLaunchScreenFillPct: 100 + iOSLaunchScreenSize: 100 + iOSLaunchScreenCustomXibPath: + iOSLaunchScreeniPadType: 0 + iOSLaunchScreeniPadImage: {fileID: 0} + iOSLaunchScreeniPadBackgroundColor: + serializedVersion: 2 + rgba: 0 + iOSLaunchScreeniPadFillPct: 100 + iOSLaunchScreeniPadSize: 100 + iOSLaunchScreeniPadCustomXibPath: + iOSUseLaunchScreenStoryboard: 0 + iOSLaunchScreenCustomStoryboardPath: + iOSDeviceRequirements: [] + iOSURLSchemes: [] + iOSBackgroundModes: 0 + iOSMetalForceHardShadows: 0 + metalEditorSupport: 1 + metalAPIValidation: 1 + iOSRenderExtraFrameOnPause: 0 + appleDeveloperTeamID: + iOSManualSigningProvisioningProfileID: + tvOSManualSigningProvisioningProfileID: + iOSManualSigningProvisioningProfileType: 0 + tvOSManualSigningProvisioningProfileType: 0 + appleEnableAutomaticSigning: 0 + iOSRequireARKit: 0 + appleEnableProMotion: 0 + clonedFromGUID: 5f34be1353de5cf4398729fda238591b + templatePackageId: com.unity.template.2d@1.0.1 + templateDefaultScene: Assets/Scenes/SampleScene.unity + AndroidTargetArchitectures: 5 + AndroidSplashScreenScale: 0 + androidSplashScreen: {fileID: 0} + AndroidKeystoreName: + AndroidKeyaliasName: + AndroidBuildApkPerCpuArchitecture: 0 + AndroidTVCompatibility: 1 + AndroidIsGame: 1 + AndroidEnableTango: 0 + androidEnableBanner: 1 + androidUseLowAccuracyLocation: 0 + m_AndroidBanners: + - width: 320 + height: 180 + banner: {fileID: 0} + androidGamepadSupportLevel: 0 + resolutionDialogBanner: {fileID: 0} + m_BuildTargetIcons: [] + m_BuildTargetPlatformIcons: + - m_BuildTarget: Android + m_Icons: + - m_Textures: [] + m_Width: 432 + m_Height: 432 + m_Kind: 2 + m_SubKind: + - m_Textures: [] + m_Width: 324 + m_Height: 324 + m_Kind: 2 + m_SubKind: + - m_Textures: [] + m_Width: 216 + m_Height: 216 + m_Kind: 2 + m_SubKind: + - m_Textures: [] + m_Width: 162 + m_Height: 162 + m_Kind: 2 + m_SubKind: + - m_Textures: [] + m_Width: 108 + m_Height: 108 + m_Kind: 2 + m_SubKind: + - m_Textures: [] + m_Width: 81 + m_Height: 81 + m_Kind: 2 + m_SubKind: + - m_Textures: [] + m_Width: 192 + m_Height: 192 + m_Kind: 1 + m_SubKind: + - m_Textures: [] + m_Width: 144 + m_Height: 144 + m_Kind: 1 + m_SubKind: + - m_Textures: [] + m_Width: 96 + m_Height: 96 + m_Kind: 1 + m_SubKind: + - m_Textures: [] + m_Width: 72 + m_Height: 72 + m_Kind: 1 + m_SubKind: + - m_Textures: [] + m_Width: 48 + m_Height: 48 + m_Kind: 1 + m_SubKind: + - m_Textures: [] + m_Width: 36 + m_Height: 36 + m_Kind: 1 + m_SubKind: + m_BuildTargetBatching: [] + m_BuildTargetGraphicsAPIs: [] + m_BuildTargetVRSettings: [] + m_BuildTargetEnableVuforiaSettings: [] + openGLRequireES31: 0 + openGLRequireES31AEP: 0 + m_TemplateCustomTags: {} + mobileMTRendering: + Android: 1 + iPhone: 1 + tvOS: 1 + m_BuildTargetGroupLightmapEncodingQuality: [] + m_BuildTargetGroupLightmapSettings: [] + playModeTestRunnerEnabled: 0 + runPlayModeTestAsEditModeTest: 0 + actionOnDotNetUnhandledException: 1 + enableInternalProfiler: 0 + logObjCUncaughtExceptions: 1 + enableCrashReportAPI: 0 + cameraUsageDescription: + locationUsageDescription: + microphoneUsageDescription: + switchNetLibKey: + switchSocketMemoryPoolSize: 6144 + switchSocketAllocatorPoolSize: 128 + switchSocketConcurrencyLimit: 14 + switchScreenResolutionBehavior: 2 + switchUseCPUProfiler: 0 + switchApplicationID: 0x01004b9000490000 + switchNSODependencies: + switchTitleNames_0: + switchTitleNames_1: + switchTitleNames_2: + switchTitleNames_3: + switchTitleNames_4: + switchTitleNames_5: + switchTitleNames_6: + switchTitleNames_7: + switchTitleNames_8: + switchTitleNames_9: + switchTitleNames_10: + switchTitleNames_11: + switchTitleNames_12: + switchTitleNames_13: + switchTitleNames_14: + switchPublisherNames_0: + switchPublisherNames_1: + switchPublisherNames_2: + switchPublisherNames_3: + switchPublisherNames_4: + switchPublisherNames_5: + switchPublisherNames_6: + switchPublisherNames_7: + switchPublisherNames_8: + switchPublisherNames_9: + switchPublisherNames_10: + switchPublisherNames_11: + switchPublisherNames_12: + switchPublisherNames_13: + switchPublisherNames_14: + switchIcons_0: {fileID: 0} + switchIcons_1: {fileID: 0} + switchIcons_2: {fileID: 0} + switchIcons_3: {fileID: 0} + switchIcons_4: {fileID: 0} + switchIcons_5: {fileID: 0} + switchIcons_6: {fileID: 0} + switchIcons_7: {fileID: 0} + switchIcons_8: {fileID: 0} + switchIcons_9: {fileID: 0} + switchIcons_10: {fileID: 0} + switchIcons_11: {fileID: 0} + switchIcons_12: {fileID: 0} + switchIcons_13: {fileID: 0} + switchIcons_14: {fileID: 0} + switchSmallIcons_0: {fileID: 0} + switchSmallIcons_1: {fileID: 0} + switchSmallIcons_2: {fileID: 0} + switchSmallIcons_3: {fileID: 0} + switchSmallIcons_4: {fileID: 0} + switchSmallIcons_5: {fileID: 0} + switchSmallIcons_6: {fileID: 0} + switchSmallIcons_7: {fileID: 0} + switchSmallIcons_8: {fileID: 0} + switchSmallIcons_9: {fileID: 0} + switchSmallIcons_10: {fileID: 0} + switchSmallIcons_11: {fileID: 0} + switchSmallIcons_12: {fileID: 0} + switchSmallIcons_13: {fileID: 0} + switchSmallIcons_14: {fileID: 0} + switchManualHTML: + switchAccessibleURLs: + switchLegalInformation: + switchMainThreadStackSize: 1048576 + switchPresenceGroupId: + switchLogoHandling: 0 + switchReleaseVersion: 0 + switchDisplayVersion: 1.0.0 + switchStartupUserAccount: 0 + switchTouchScreenUsage: 0 + switchSupportedLanguagesMask: 0 + switchLogoType: 0 + switchApplicationErrorCodeCategory: + switchUserAccountSaveDataSize: 0 + switchUserAccountSaveDataJournalSize: 0 + switchApplicationAttribute: 0 + switchCardSpecSize: -1 + switchCardSpecClock: -1 + switchRatingsMask: 0 + switchRatingsInt_0: 0 + switchRatingsInt_1: 0 + switchRatingsInt_2: 0 + switchRatingsInt_3: 0 + switchRatingsInt_4: 0 + switchRatingsInt_5: 0 + switchRatingsInt_6: 0 + switchRatingsInt_7: 0 + switchRatingsInt_8: 0 + switchRatingsInt_9: 0 + switchRatingsInt_10: 0 + switchRatingsInt_11: 0 + switchLocalCommunicationIds_0: + switchLocalCommunicationIds_1: + switchLocalCommunicationIds_2: + switchLocalCommunicationIds_3: + switchLocalCommunicationIds_4: + switchLocalCommunicationIds_5: + switchLocalCommunicationIds_6: + switchLocalCommunicationIds_7: + switchParentalControl: 0 + switchAllowsScreenshot: 1 + switchAllowsVideoCapturing: 1 + switchAllowsRuntimeAddOnContentInstall: 0 + switchDataLossConfirmation: 0 + switchUserAccountLockEnabled: 0 + switchSupportedNpadStyles: 3 + switchNativeFsCacheSize: 32 + switchIsHoldTypeHorizontal: 0 + switchSupportedNpadCount: 8 + switchSocketConfigEnabled: 0 + switchTcpInitialSendBufferSize: 32 + switchTcpInitialReceiveBufferSize: 64 + switchTcpAutoSendBufferSizeMax: 256 + switchTcpAutoReceiveBufferSizeMax: 256 + switchUdpSendBufferSize: 9 + switchUdpReceiveBufferSize: 42 + switchSocketBufferEfficiency: 4 + switchSocketInitializeEnabled: 1 + switchNetworkInterfaceManagerInitializeEnabled: 1 + switchPlayerConnectionEnabled: 1 + ps4NPAgeRating: 12 + ps4NPTitleSecret: + ps4NPTrophyPackPath: + ps4ParentalLevel: 11 + ps4ContentID: ED1633-NPXX51362_00-0000000000000000 + ps4Category: 0 + ps4MasterVersion: 01.00 + ps4AppVersion: 01.00 + ps4AppType: 0 + ps4ParamSfxPath: + ps4VideoOutPixelFormat: 0 + ps4VideoOutInitialWidth: 1920 + ps4VideoOutBaseModeInitialWidth: 1920 + ps4VideoOutReprojectionRate: 60 + ps4PronunciationXMLPath: + ps4PronunciationSIGPath: + ps4BackgroundImagePath: + ps4StartupImagePath: + ps4StartupImagesFolder: + ps4IconImagesFolder: + ps4SaveDataImagePath: + ps4SdkOverride: + ps4BGMPath: + ps4ShareFilePath: + ps4ShareOverlayImagePath: + ps4PrivacyGuardImagePath: + ps4NPtitleDatPath: + ps4RemotePlayKeyAssignment: -1 + ps4RemotePlayKeyMappingDir: + ps4PlayTogetherPlayerCount: 0 + ps4EnterButtonAssignment: 1 + ps4ApplicationParam1: 0 + ps4ApplicationParam2: 0 + ps4ApplicationParam3: 0 + ps4ApplicationParam4: 0 + ps4DownloadDataSize: 0 + ps4GarlicHeapSize: 2048 + ps4ProGarlicHeapSize: 2560 + ps4Passcode: frAQBc8Wsa1xVPfvJcrgRYwTiizs2trQ + ps4pnSessions: 1 + ps4pnPresence: 1 + ps4pnFriends: 1 + ps4pnGameCustomData: 1 + playerPrefsSupport: 0 + enableApplicationExit: 0 + resetTempFolder: 1 + restrictedAudioUsageRights: 0 + ps4UseResolutionFallback: 0 + ps4ReprojectionSupport: 0 + ps4UseAudio3dBackend: 0 + ps4SocialScreenEnabled: 0 + ps4ScriptOptimizationLevel: 0 + ps4Audio3dVirtualSpeakerCount: 14 + ps4attribCpuUsage: 0 + ps4PatchPkgPath: + ps4PatchLatestPkgPath: + ps4PatchChangeinfoPath: + ps4PatchDayOne: 0 + ps4attribUserManagement: 0 + ps4attribMoveSupport: 0 + ps4attrib3DSupport: 0 + ps4attribShareSupport: 0 + ps4attribExclusiveVR: 0 + ps4disableAutoHideSplash: 0 + ps4videoRecordingFeaturesUsed: 0 + ps4contentSearchFeaturesUsed: 0 + ps4attribEyeToEyeDistanceSettingVR: 0 + ps4IncludedModules: [] + monoEnv: + splashScreenBackgroundSourceLandscape: {fileID: 0} + splashScreenBackgroundSourcePortrait: {fileID: 0} + spritePackerPolicy: + webGLMemorySize: 256 + webGLExceptionSupport: 1 + webGLNameFilesAsHashes: 0 + webGLDataCaching: 1 + webGLDebugSymbols: 0 + webGLEmscriptenArgs: + webGLModulesDirectory: + webGLTemplate: APPLICATION:Default + webGLAnalyzeBuildSize: 0 + webGLUseEmbeddedResources: 0 + webGLCompressionFormat: 1 + webGLLinkerTarget: 1 + webGLThreadsSupport: 0 + scriptingDefineSymbols: {} + platformArchitecture: {} + scriptingBackend: + Android: 1 + il2cppCompilerConfiguration: {} + managedStrippingLevel: {} + incrementalIl2cppBuild: {} + allowUnsafeCode: 0 + additionalIl2CppArgs: + scriptingRuntimeVersion: 1 + apiCompatibilityLevelPerPlatform: + Android: 3 + m_RenderingPath: 1 + m_MobileRenderingPath: 1 + metroPackageName: Template_2D + metroPackageVersion: + metroCertificatePath: + metroCertificatePassword: + metroCertificateSubject: + metroCertificateIssuer: + metroCertificateNotAfter: 0000000000000000 + metroApplicationDescription: Template_2D + wsaImages: {} + metroTileShortName: + metroTileShowName: 0 + metroMediumTileShowName: 0 + metroLargeTileShowName: 0 + metroWideTileShowName: 0 + metroSupportStreamingInstall: 0 + metroLastRequiredScene: 0 + metroDefaultTileSize: 1 + metroTileForegroundText: 2 + metroTileBackgroundColor: {r: 0.13333334, g: 0.17254902, b: 0.21568628, a: 0} + metroSplashScreenBackgroundColor: {r: 0.12941177, g: 0.17254902, b: 0.21568628, + a: 1} + metroSplashScreenUseBackgroundColor: 0 + platformCapabilities: {} + metroTargetDeviceFamilies: {} + metroFTAName: + metroFTAFileTypes: [] + metroProtocolName: + metroCompilationOverrides: 1 + XboxOneProductId: + XboxOneUpdateKey: + XboxOneSandboxId: + XboxOneContentId: + XboxOneTitleId: + XboxOneSCId: + XboxOneGameOsOverridePath: + XboxOnePackagingOverridePath: + XboxOneAppManifestOverridePath: + XboxOneVersion: 1.0.0.0 + XboxOnePackageEncryption: 0 + XboxOnePackageUpdateGranularity: 2 + XboxOneDescription: + XboxOneLanguage: + - enus + XboxOneCapability: [] + XboxOneGameRating: {} + XboxOneIsContentPackage: 0 + XboxOneEnableGPUVariability: 0 + XboxOneSockets: {} + XboxOneSplashScreen: {fileID: 0} + XboxOneAllowedProductIds: [] + XboxOnePersistentLocalStorageSize: 0 + XboxOneXTitleMemory: 8 + xboxOneScriptCompiler: 0 + XboxOneOverrideIdentityName: + vrEditorSettings: + daydream: + daydreamIconForeground: {fileID: 0} + daydreamIconBackground: {fileID: 0} + cloudServicesEnabled: + UNet: 1 + luminIcon: + m_Name: + m_ModelFolderPath: + m_PortalFolderPath: + luminCert: + m_CertPath: + m_PrivateKeyPath: + luminIsChannelApp: 0 + luminVersion: + m_VersionCode: 1 + m_VersionName: + facebookSdkVersion: 7.9.4 + facebookAppId: + facebookCookies: 1 + facebookLogging: 1 + facebookStatus: 1 + facebookXfbml: 0 + facebookFrictionlessRequests: 1 + apiCompatibilityLevel: 3 + cloudProjectId: + framebufferDepthMemorylessMode: 0 + projectName: + organizationId: + cloudEnabled: 0 + enableNativePlatformBackendsForNewInputSystem: 0 + disableOldInputManagerSupport: 0 + legacyClampBlendShapeWeights: 1 diff --git a/examples/csharp/HelloworldUnity/ProjectSettings/ProjectVersion.txt b/examples/csharp/HelloworldUnity/ProjectSettings/ProjectVersion.txt new file mode 100644 index 00000000000..6128d74131b --- /dev/null +++ b/examples/csharp/HelloworldUnity/ProjectSettings/ProjectVersion.txt @@ -0,0 +1 @@ +m_EditorVersion: 2018.3.5f1 diff --git a/examples/csharp/HelloworldUnity/ProjectSettings/QualitySettings.asset b/examples/csharp/HelloworldUnity/ProjectSettings/QualitySettings.asset new file mode 100644 index 00000000000..b055962bcac --- /dev/null +++ b/examples/csharp/HelloworldUnity/ProjectSettings/QualitySettings.asset @@ -0,0 +1,191 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!47 &1 +QualitySettings: + m_ObjectHideFlags: 0 + serializedVersion: 5 + m_CurrentQuality: 3 + m_QualitySettings: + - serializedVersion: 2 + name: Very Low + pixelLightCount: 0 + shadows: 0 + shadowResolution: 0 + shadowProjection: 1 + shadowCascades: 1 + shadowDistance: 15 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 0 + blendWeights: 1 + textureQuality: 1 + anisotropicTextures: 0 + antiAliasing: 0 + softParticles: 0 + softVegetation: 0 + realtimeReflectionProbes: 0 + billboardsFaceCameraPosition: 0 + vSyncCount: 0 + lodBias: 0.3 + maximumLODLevel: 0 + particleRaycastBudget: 4 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 4 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + - serializedVersion: 2 + name: Low + pixelLightCount: 0 + shadows: 0 + shadowResolution: 0 + shadowProjection: 1 + shadowCascades: 1 + shadowDistance: 20 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 0 + blendWeights: 2 + textureQuality: 0 + anisotropicTextures: 0 + antiAliasing: 0 + softParticles: 0 + softVegetation: 0 + realtimeReflectionProbes: 0 + billboardsFaceCameraPosition: 0 + vSyncCount: 0 + lodBias: 0.4 + maximumLODLevel: 0 + particleRaycastBudget: 16 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 4 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + - serializedVersion: 2 + name: Medium + pixelLightCount: 1 + shadows: 0 + shadowResolution: 0 + shadowProjection: 1 + shadowCascades: 1 + shadowDistance: 20 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 0 + blendWeights: 2 + textureQuality: 0 + anisotropicTextures: 0 + antiAliasing: 0 + softParticles: 0 + softVegetation: 0 + realtimeReflectionProbes: 0 + billboardsFaceCameraPosition: 0 + vSyncCount: 1 + lodBias: 0.7 + maximumLODLevel: 0 + particleRaycastBudget: 64 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 4 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + - serializedVersion: 2 + name: High + pixelLightCount: 2 + shadows: 0 + shadowResolution: 1 + shadowProjection: 1 + shadowCascades: 2 + shadowDistance: 40 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 1 + blendWeights: 2 + textureQuality: 0 + anisotropicTextures: 0 + antiAliasing: 0 + softParticles: 0 + softVegetation: 1 + realtimeReflectionProbes: 0 + billboardsFaceCameraPosition: 0 + vSyncCount: 1 + lodBias: 1 + maximumLODLevel: 0 + particleRaycastBudget: 256 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 4 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + - serializedVersion: 2 + name: Very High + pixelLightCount: 3 + shadows: 0 + shadowResolution: 2 + shadowProjection: 1 + shadowCascades: 2 + shadowDistance: 70 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 1 + blendWeights: 4 + textureQuality: 0 + anisotropicTextures: 0 + antiAliasing: 0 + softParticles: 0 + softVegetation: 1 + realtimeReflectionProbes: 0 + billboardsFaceCameraPosition: 0 + vSyncCount: 1 + lodBias: 1.5 + maximumLODLevel: 0 + particleRaycastBudget: 1024 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 4 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + - serializedVersion: 2 + name: Ultra + pixelLightCount: 4 + shadows: 0 + shadowResolution: 0 + shadowProjection: 1 + shadowCascades: 4 + shadowDistance: 150 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 1 + blendWeights: 4 + textureQuality: 0 + anisotropicTextures: 0 + antiAliasing: 0 + softParticles: 0 + softVegetation: 1 + realtimeReflectionProbes: 0 + billboardsFaceCameraPosition: 0 + vSyncCount: 1 + lodBias: 2 + maximumLODLevel: 0 + particleRaycastBudget: 4096 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 4 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + m_PerPlatformDefaultQuality: + Android: 2 + Nintendo 3DS: 5 + Nintendo Switch: 5 + PS4: 5 + PSM: 5 + PSP2: 2 + Standalone: 5 + Tizen: 2 + WebGL: 3 + WiiU: 5 + Windows Store Apps: 5 + XboxOne: 5 + iPhone: 2 + tvOS: 2 diff --git a/examples/csharp/HelloworldUnity/ProjectSettings/TagManager.asset b/examples/csharp/HelloworldUnity/ProjectSettings/TagManager.asset new file mode 100644 index 00000000000..3281f1b528b --- /dev/null +++ b/examples/csharp/HelloworldUnity/ProjectSettings/TagManager.asset @@ -0,0 +1,43 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!78 &1 +TagManager: + serializedVersion: 2 + tags: [] + layers: + - Default + - TransparentFX + - Ignore Raycast + - + - Water + - UI + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + m_SortingLayers: + - name: Default + uniqueID: 0 + locked: 0 diff --git a/examples/csharp/HelloworldUnity/ProjectSettings/TimeManager.asset b/examples/csharp/HelloworldUnity/ProjectSettings/TimeManager.asset new file mode 100644 index 00000000000..06bcc6d2953 --- /dev/null +++ b/examples/csharp/HelloworldUnity/ProjectSettings/TimeManager.asset @@ -0,0 +1,9 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!5 &1 +TimeManager: + m_ObjectHideFlags: 0 + Fixed Timestep: 0.02 + Maximum Allowed Timestep: 0.1 + m_TimeScale: 1 + Maximum Particle Timestep: 0.03 diff --git a/examples/csharp/HelloworldUnity/ProjectSettings/UnityConnectSettings.asset b/examples/csharp/HelloworldUnity/ProjectSettings/UnityConnectSettings.asset new file mode 100644 index 00000000000..06db74a9444 --- /dev/null +++ b/examples/csharp/HelloworldUnity/ProjectSettings/UnityConnectSettings.asset @@ -0,0 +1,34 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!310 &1 +UnityConnectSettings: + m_ObjectHideFlags: 0 + serializedVersion: 1 + m_Enabled: 1 + m_TestMode: 0 + m_EventOldUrl: https://api.uca.cloud.unity3d.com/v1/events + m_EventUrl: https://cdp.cloud.unity3d.com/v1/events + m_ConfigUrl: https://config.uca.cloud.unity3d.com + m_TestInitMode: 0 + CrashReportingSettings: + m_EventUrl: https://perf-events.cloud.unity3d.com + m_Enabled: 0 + m_LogBufferSize: 10 + m_CaptureEditorExceptions: 1 + UnityPurchasingSettings: + m_Enabled: 0 + m_TestMode: 0 + UnityAnalyticsSettings: + m_Enabled: 1 + m_TestMode: 0 + m_InitializeOnStartup: 1 + UnityAdsSettings: + m_Enabled: 0 + m_InitializeOnStartup: 1 + m_TestMode: 0 + m_IosGameId: + m_AndroidGameId: + m_GameIds: {} + m_GameId: + PerformanceReportingSettings: + m_Enabled: 0 diff --git a/examples/csharp/HelloworldUnity/ProjectSettings/VFXManager.asset b/examples/csharp/HelloworldUnity/ProjectSettings/VFXManager.asset new file mode 100644 index 00000000000..6e0eaca40d5 --- /dev/null +++ b/examples/csharp/HelloworldUnity/ProjectSettings/VFXManager.asset @@ -0,0 +1,11 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!937362698 &1 +VFXManager: + m_ObjectHideFlags: 0 + m_IndirectShader: {fileID: 0} + m_CopyBufferShader: {fileID: 0} + m_SortShader: {fileID: 0} + m_RenderPipeSettingsPath: + m_FixedTimeStep: 0.016666668 + m_MaxDeltaTime: 0.05 diff --git a/examples/csharp/HelloworldUnity/README.md b/examples/csharp/HelloworldUnity/README.md new file mode 100644 index 00000000000..ec489e94998 --- /dev/null +++ b/examples/csharp/HelloworldUnity/README.md @@ -0,0 +1,19 @@ +gRPC C# on Unity +======================== + +EXPERIMENTAL ONLY +------------- +Support of the Unity platform is currently experimental. + +PREREQUISITES +------------- + +- Unity 2018.3.5f1 + +BUILD +------- + +- Follow instructions in https://github.com/grpc/grpc/tree/master/src/csharp/experimental#unity to obtain the grpc_csharp_unity.zip + that contains gRPC C# for Unity. Unzip it under `Assets/Plugins` directory. +- Open the `HelloworldUnity.sln` in Unity Editor. +- Build using Unity Editor. diff --git a/examples/csharp/HelloworldUnity/UIElementsSchema/UIElements.xsd b/examples/csharp/HelloworldUnity/UIElementsSchema/UIElements.xsd new file mode 100644 index 00000000000..1131a5105bf --- /dev/null +++ b/examples/csharp/HelloworldUnity/UIElementsSchema/UIElements.xsd @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/examples/csharp/HelloworldUnity/UIElementsSchema/UnityEditor.Experimental.UIElements.xsd b/examples/csharp/HelloworldUnity/UIElementsSchema/UnityEditor.Experimental.UIElements.xsd new file mode 100644 index 00000000000..f2374e87007 --- /dev/null +++ b/examples/csharp/HelloworldUnity/UIElementsSchema/UnityEditor.Experimental.UIElements.xsd @@ -0,0 +1,228 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/csharp/HelloworldUnity/UIElementsSchema/UnityEditor.PackageManager.UI.xsd b/examples/csharp/HelloworldUnity/UIElementsSchema/UnityEditor.PackageManager.UI.xsd new file mode 100644 index 00000000000..117194aa38a --- /dev/null +++ b/examples/csharp/HelloworldUnity/UIElementsSchema/UnityEditor.PackageManager.UI.xsd @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/csharp/HelloworldUnity/UIElementsSchema/UnityEngine.Experimental.UIElements.xsd b/examples/csharp/HelloworldUnity/UIElementsSchema/UnityEngine.Experimental.UIElements.xsd new file mode 100644 index 00000000000..0c074b23ba9 --- /dev/null +++ b/examples/csharp/HelloworldUnity/UIElementsSchema/UnityEngine.Experimental.UIElements.xsd @@ -0,0 +1,269 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/csharp/HelloworldXamarin/Droid/HelloworldXamarin.Droid.csproj b/examples/csharp/HelloworldXamarin/Droid/HelloworldXamarin.Droid.csproj index b5ca8490a48..991fa0c9bcc 100644 --- a/examples/csharp/HelloworldXamarin/Droid/HelloworldXamarin.Droid.csproj +++ b/examples/csharp/HelloworldXamarin/Droid/HelloworldXamarin.Droid.csproj @@ -50,12 +50,12 @@ ..\packages\System.Interactive.Async.3.1.1\lib\netstandard1.3\System.Interactive.Async.dll - - ..\packages\Grpc.Core.1.15.0-dev\lib\netstandard1.5\Grpc.Core.dll - ..\packages\Google.Protobuf.3.6.0\lib\netstandard1.0\Google.Protobuf.dll + + ..\packages\Grpc.Core.1.18.0\lib\netstandard1.5\Grpc.Core.dll + @@ -79,5 +79,5 @@ - + \ No newline at end of file diff --git a/examples/csharp/HelloworldXamarin/Droid/packages.config b/examples/csharp/HelloworldXamarin/Droid/packages.config index 3574b6782b3..29201117298 100644 --- a/examples/csharp/HelloworldXamarin/Droid/packages.config +++ b/examples/csharp/HelloworldXamarin/Droid/packages.config @@ -1,7 +1,7 @@  - + diff --git a/examples/csharp/HelloworldXamarin/README.md b/examples/csharp/HelloworldXamarin/README.md index e47855de5e1..153a4f1b4dc 100644 --- a/examples/csharp/HelloworldXamarin/README.md +++ b/examples/csharp/HelloworldXamarin/README.md @@ -4,11 +4,6 @@ gRPC C# on Xamarin EXPERIMENTAL ONLY ------------- Support of the Xamarin platform is currently experimental. -The example depends on experimental Grpc.Core nuget package that hasn't -been officially released and is only available via the [daily builds](https://packages.grpc.io/) -source. - -HINT: To download the package, please manually download the latest `.nupkg` packages from "Daily Builds" in [packages.grpc.io](https://packages.grpc.io/) into a local directory. Then add a nuget source that points to that directory (That can be [done in Visual Studio](https://docs.microsoft.com/en-us/nuget/tools/package-manager-ui#package-sources) or Visual Studio for Mac via "Configure nuget sources"). After that, nuget will also explore that directory when looking for packages. BACKGROUND ------------- diff --git a/examples/csharp/HelloworldXamarin/iOS/AppDelegate.cs b/examples/csharp/HelloworldXamarin/iOS/AppDelegate.cs index e7620f91a21..16a071c4d60 100644 --- a/examples/csharp/HelloworldXamarin/iOS/AppDelegate.cs +++ b/examples/csharp/HelloworldXamarin/iOS/AppDelegate.cs @@ -53,7 +53,7 @@ namespace HelloworldXamarin.iOS public override void DidEnterBackground(UIApplication application) { // Use this method to release shared resources, save user data, invalidate timers and store the application state. - // If your application supports background exection this method is called instead of WillTerminate when the user quits. + // If your application supports background execution this method is called instead of WillTerminate when the user quits. } public override void WillEnterForeground(UIApplication application) diff --git a/examples/csharp/HelloworldXamarin/iOS/HelloworldXamarin.iOS.csproj b/examples/csharp/HelloworldXamarin/iOS/HelloworldXamarin.iOS.csproj index b5c0d1d1192..9154bf33527 100644 --- a/examples/csharp/HelloworldXamarin/iOS/HelloworldXamarin.iOS.csproj +++ b/examples/csharp/HelloworldXamarin/iOS/HelloworldXamarin.iOS.csproj @@ -89,12 +89,12 @@ ..\packages\System.Interactive.Async.3.1.1\lib\netstandard1.3\System.Interactive.Async.dll - - ..\packages\Grpc.Core.1.15.0-dev\lib\netstandard1.5\Grpc.Core.dll - ..\packages\Google.Protobuf.3.6.0\lib\netstandard1.0\Google.Protobuf.dll + + ..\packages\Grpc.Core.1.18.0\lib\netstandard1.5\Grpc.Core.dll + @@ -122,5 +122,5 @@ - + \ No newline at end of file diff --git a/examples/csharp/HelloworldXamarin/iOS/packages.config b/examples/csharp/HelloworldXamarin/iOS/packages.config index ce4bceb62a8..055222ba48f 100644 --- a/examples/csharp/HelloworldXamarin/iOS/packages.config +++ b/examples/csharp/HelloworldXamarin/iOS/packages.config @@ -1,7 +1,7 @@  - + diff --git a/examples/csharp/RouteGuide/RouteGuide.sln b/examples/csharp/RouteGuide/RouteGuide.sln index 73e6e306b16..5e103294a56 100644 --- a/examples/csharp/RouteGuide/RouteGuide.sln +++ b/examples/csharp/RouteGuide/RouteGuide.sln @@ -1,4 +1,4 @@ - + Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 VisualStudioVersion = 15.0.26228.4 diff --git a/examples/csharp/RouteGuide/RouteGuide/RouteGuide.cs b/examples/csharp/RouteGuide/RouteGuide/RouteGuide.cs deleted file mode 100644 index 10c9aec5f80..00000000000 --- a/examples/csharp/RouteGuide/RouteGuide/RouteGuide.cs +++ /dev/null @@ -1,981 +0,0 @@ -// -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: route_guide.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 Routeguide { - - /// Holder for reflection information generated from route_guide.proto - public static partial class RouteGuideReflection { - - #region Descriptor - /// File descriptor for route_guide.proto - public static pbr::FileDescriptor Descriptor { - get { return descriptor; } - } - private static pbr::FileDescriptor descriptor; - - static RouteGuideReflection() { - byte[] descriptorData = global::System.Convert.FromBase64String( - string.Concat( - "ChFyb3V0ZV9ndWlkZS5wcm90bxIKcm91dGVndWlkZSIsCgVQb2ludBIQCghs", - "YXRpdHVkZRgBIAEoBRIRCglsb25naXR1ZGUYAiABKAUiSQoJUmVjdGFuZ2xl", - "Eh0KAmxvGAEgASgLMhEucm91dGVndWlkZS5Qb2ludBIdCgJoaRgCIAEoCzIR", - "LnJvdXRlZ3VpZGUuUG9pbnQiPAoHRmVhdHVyZRIMCgRuYW1lGAEgASgJEiMK", - "CGxvY2F0aW9uGAIgASgLMhEucm91dGVndWlkZS5Qb2ludCJBCglSb3V0ZU5v", - "dGUSIwoIbG9jYXRpb24YASABKAsyES5yb3V0ZWd1aWRlLlBvaW50Eg8KB21l", - "c3NhZ2UYAiABKAkiYgoMUm91dGVTdW1tYXJ5EhMKC3BvaW50X2NvdW50GAEg", - "ASgFEhUKDWZlYXR1cmVfY291bnQYAiABKAUSEAoIZGlzdGFuY2UYAyABKAUS", - "FAoMZWxhcHNlZF90aW1lGAQgASgFMoUCCgpSb3V0ZUd1aWRlEjYKCkdldEZl", - "YXR1cmUSES5yb3V0ZWd1aWRlLlBvaW50GhMucm91dGVndWlkZS5GZWF0dXJl", - "IgASPgoMTGlzdEZlYXR1cmVzEhUucm91dGVndWlkZS5SZWN0YW5nbGUaEy5y", - "b3V0ZWd1aWRlLkZlYXR1cmUiADABEj4KC1JlY29yZFJvdXRlEhEucm91dGVn", - "dWlkZS5Qb2ludBoYLnJvdXRlZ3VpZGUuUm91dGVTdW1tYXJ5IgAoARI/CglS", - "b3V0ZUNoYXQSFS5yb3V0ZWd1aWRlLlJvdXRlTm90ZRoVLnJvdXRlZ3VpZGUu", - "Um91dGVOb3RlIgAoATABQjYKG2lvLmdycGMuZXhhbXBsZXMucm91dGVndWlk", - "ZUIPUm91dGVHdWlkZVByb3RvUAGiAgNSVEdiBnByb3RvMw==")); - descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, - new pbr::FileDescriptor[] { }, - new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] { - new pbr::GeneratedClrTypeInfo(typeof(global::Routeguide.Point), global::Routeguide.Point.Parser, new[]{ "Latitude", "Longitude" }, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Routeguide.Rectangle), global::Routeguide.Rectangle.Parser, new[]{ "Lo", "Hi" }, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Routeguide.Feature), global::Routeguide.Feature.Parser, new[]{ "Name", "Location" }, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Routeguide.RouteNote), global::Routeguide.RouteNote.Parser, new[]{ "Location", "Message" }, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Routeguide.RouteSummary), global::Routeguide.RouteSummary.Parser, new[]{ "PointCount", "FeatureCount", "Distance", "ElapsedTime" }, null, null, null) - })); - } - #endregion - - } - #region Messages - /// - /// Points are represented as latitude-longitude pairs in the E7 representation - /// (degrees multiplied by 10**7 and rounded to the nearest integer). - /// Latitudes should be in the range +/- 90 degrees and longitude should be in - /// the range +/- 180 degrees (inclusive). - /// - public sealed partial class Point : pb::IMessage { - private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Point()); - private pb::UnknownFieldSet _unknownFields; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public static pb::MessageParser Parser { get { return _parser; } } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public static pbr::MessageDescriptor Descriptor { - get { return global::Routeguide.RouteGuideReflection.Descriptor.MessageTypes[0]; } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - pbr::MessageDescriptor pb::IMessage.Descriptor { - get { return Descriptor; } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public Point() { - OnConstruction(); - } - - partial void OnConstruction(); - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public Point(Point other) : this() { - latitude_ = other.latitude_; - longitude_ = other.longitude_; - _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public Point Clone() { - return new Point(this); - } - - /// Field number for the "latitude" field. - public const int LatitudeFieldNumber = 1; - private int latitude_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public int Latitude { - get { return latitude_; } - set { - latitude_ = value; - } - } - - /// Field number for the "longitude" field. - public const int LongitudeFieldNumber = 2; - private int longitude_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public int Longitude { - get { return longitude_; } - set { - longitude_ = value; - } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public override bool Equals(object other) { - return Equals(other as Point); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool Equals(Point other) { - if (ReferenceEquals(other, null)) { - return false; - } - if (ReferenceEquals(other, this)) { - return true; - } - if (Latitude != other.Latitude) return false; - if (Longitude != other.Longitude) return false; - return Equals(_unknownFields, other._unknownFields); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public override int GetHashCode() { - int hash = 1; - if (Latitude != 0) hash ^= Latitude.GetHashCode(); - if (Longitude != 0) hash ^= Longitude.GetHashCode(); - if (_unknownFields != null) { - hash ^= _unknownFields.GetHashCode(); - } - return hash; - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public override string ToString() { - return pb::JsonFormatter.ToDiagnosticString(this); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void WriteTo(pb::CodedOutputStream output) { - if (Latitude != 0) { - output.WriteRawTag(8); - output.WriteInt32(Latitude); - } - if (Longitude != 0) { - output.WriteRawTag(16); - output.WriteInt32(Longitude); - } - if (_unknownFields != null) { - _unknownFields.WriteTo(output); - } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public int CalculateSize() { - int size = 0; - if (Latitude != 0) { - size += 1 + pb::CodedOutputStream.ComputeInt32Size(Latitude); - } - if (Longitude != 0) { - size += 1 + pb::CodedOutputStream.ComputeInt32Size(Longitude); - } - if (_unknownFields != null) { - size += _unknownFields.CalculateSize(); - } - return size; - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void MergeFrom(Point other) { - if (other == null) { - return; - } - if (other.Latitude != 0) { - Latitude = other.Latitude; - } - if (other.Longitude != 0) { - Longitude = other.Longitude; - } - _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void MergeFrom(pb::CodedInputStream input) { - uint tag; - while ((tag = input.ReadTag()) != 0) { - switch(tag) { - default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); - break; - case 8: { - Latitude = input.ReadInt32(); - break; - } - case 16: { - Longitude = input.ReadInt32(); - break; - } - } - } - } - - } - - /// - /// A latitude-longitude rectangle, represented as two diagonally opposite - /// points "lo" and "hi". - /// - public sealed partial class Rectangle : pb::IMessage { - private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Rectangle()); - private pb::UnknownFieldSet _unknownFields; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public static pb::MessageParser Parser { get { return _parser; } } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public static pbr::MessageDescriptor Descriptor { - get { return global::Routeguide.RouteGuideReflection.Descriptor.MessageTypes[1]; } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - pbr::MessageDescriptor pb::IMessage.Descriptor { - get { return Descriptor; } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public Rectangle() { - OnConstruction(); - } - - partial void OnConstruction(); - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public Rectangle(Rectangle other) : this() { - lo_ = other.lo_ != null ? other.lo_.Clone() : null; - hi_ = other.hi_ != null ? other.hi_.Clone() : null; - _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public Rectangle Clone() { - return new Rectangle(this); - } - - /// Field number for the "lo" field. - public const int LoFieldNumber = 1; - private global::Routeguide.Point lo_; - /// - /// One corner of the rectangle. - /// - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public global::Routeguide.Point Lo { - get { return lo_; } - set { - lo_ = value; - } - } - - /// Field number for the "hi" field. - public const int HiFieldNumber = 2; - private global::Routeguide.Point hi_; - /// - /// The other corner of the rectangle. - /// - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public global::Routeguide.Point Hi { - get { return hi_; } - set { - hi_ = value; - } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public override bool Equals(object other) { - return Equals(other as Rectangle); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool Equals(Rectangle other) { - if (ReferenceEquals(other, null)) { - return false; - } - if (ReferenceEquals(other, this)) { - return true; - } - if (!object.Equals(Lo, other.Lo)) return false; - if (!object.Equals(Hi, other.Hi)) return false; - return Equals(_unknownFields, other._unknownFields); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public override int GetHashCode() { - int hash = 1; - if (lo_ != null) hash ^= Lo.GetHashCode(); - if (hi_ != null) hash ^= Hi.GetHashCode(); - if (_unknownFields != null) { - hash ^= _unknownFields.GetHashCode(); - } - return hash; - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public override string ToString() { - return pb::JsonFormatter.ToDiagnosticString(this); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void WriteTo(pb::CodedOutputStream output) { - if (lo_ != null) { - output.WriteRawTag(10); - output.WriteMessage(Lo); - } - if (hi_ != null) { - output.WriteRawTag(18); - output.WriteMessage(Hi); - } - if (_unknownFields != null) { - _unknownFields.WriteTo(output); - } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public int CalculateSize() { - int size = 0; - if (lo_ != null) { - size += 1 + pb::CodedOutputStream.ComputeMessageSize(Lo); - } - if (hi_ != null) { - size += 1 + pb::CodedOutputStream.ComputeMessageSize(Hi); - } - if (_unknownFields != null) { - size += _unknownFields.CalculateSize(); - } - return size; - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void MergeFrom(Rectangle other) { - if (other == null) { - return; - } - if (other.lo_ != null) { - if (lo_ == null) { - lo_ = new global::Routeguide.Point(); - } - Lo.MergeFrom(other.Lo); - } - if (other.hi_ != null) { - if (hi_ == null) { - hi_ = new global::Routeguide.Point(); - } - Hi.MergeFrom(other.Hi); - } - _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void MergeFrom(pb::CodedInputStream input) { - uint tag; - while ((tag = input.ReadTag()) != 0) { - switch(tag) { - default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); - break; - case 10: { - if (lo_ == null) { - lo_ = new global::Routeguide.Point(); - } - input.ReadMessage(lo_); - break; - } - case 18: { - if (hi_ == null) { - hi_ = new global::Routeguide.Point(); - } - input.ReadMessage(hi_); - break; - } - } - } - } - - } - - /// - /// A feature names something at a given point. - /// - /// If a feature could not be named, the name is empty. - /// - public sealed partial class Feature : pb::IMessage { - private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Feature()); - private pb::UnknownFieldSet _unknownFields; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public static pb::MessageParser Parser { get { return _parser; } } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public static pbr::MessageDescriptor Descriptor { - get { return global::Routeguide.RouteGuideReflection.Descriptor.MessageTypes[2]; } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - pbr::MessageDescriptor pb::IMessage.Descriptor { - get { return Descriptor; } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public Feature() { - OnConstruction(); - } - - partial void OnConstruction(); - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public Feature(Feature other) : this() { - name_ = other.name_; - location_ = other.location_ != null ? other.location_.Clone() : null; - _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public Feature Clone() { - return new Feature(this); - } - - /// Field number for the "name" field. - public const int NameFieldNumber = 1; - private string name_ = ""; - /// - /// The name of the feature. - /// - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public string Name { - get { return name_; } - set { - name_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); - } - } - - /// Field number for the "location" field. - public const int LocationFieldNumber = 2; - private global::Routeguide.Point location_; - /// - /// The point where the feature is detected. - /// - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public global::Routeguide.Point Location { - get { return location_; } - set { - location_ = value; - } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public override bool Equals(object other) { - return Equals(other as Feature); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool Equals(Feature other) { - if (ReferenceEquals(other, null)) { - return false; - } - if (ReferenceEquals(other, this)) { - return true; - } - if (Name != other.Name) return false; - if (!object.Equals(Location, other.Location)) return false; - return Equals(_unknownFields, other._unknownFields); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public override int GetHashCode() { - int hash = 1; - if (Name.Length != 0) hash ^= Name.GetHashCode(); - if (location_ != null) hash ^= Location.GetHashCode(); - if (_unknownFields != null) { - hash ^= _unknownFields.GetHashCode(); - } - return hash; - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public override string ToString() { - return pb::JsonFormatter.ToDiagnosticString(this); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void WriteTo(pb::CodedOutputStream output) { - if (Name.Length != 0) { - output.WriteRawTag(10); - output.WriteString(Name); - } - if (location_ != null) { - output.WriteRawTag(18); - output.WriteMessage(Location); - } - if (_unknownFields != null) { - _unknownFields.WriteTo(output); - } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public int CalculateSize() { - int size = 0; - if (Name.Length != 0) { - size += 1 + pb::CodedOutputStream.ComputeStringSize(Name); - } - if (location_ != null) { - size += 1 + pb::CodedOutputStream.ComputeMessageSize(Location); - } - if (_unknownFields != null) { - size += _unknownFields.CalculateSize(); - } - return size; - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void MergeFrom(Feature other) { - if (other == null) { - return; - } - if (other.Name.Length != 0) { - Name = other.Name; - } - if (other.location_ != null) { - if (location_ == null) { - location_ = new global::Routeguide.Point(); - } - Location.MergeFrom(other.Location); - } - _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void MergeFrom(pb::CodedInputStream input) { - uint tag; - while ((tag = input.ReadTag()) != 0) { - switch(tag) { - default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); - break; - case 10: { - Name = input.ReadString(); - break; - } - case 18: { - if (location_ == null) { - location_ = new global::Routeguide.Point(); - } - input.ReadMessage(location_); - break; - } - } - } - } - - } - - /// - /// A RouteNote is a message sent while at a given point. - /// - public sealed partial class RouteNote : pb::IMessage { - private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new RouteNote()); - private pb::UnknownFieldSet _unknownFields; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public static pb::MessageParser Parser { get { return _parser; } } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public static pbr::MessageDescriptor Descriptor { - get { return global::Routeguide.RouteGuideReflection.Descriptor.MessageTypes[3]; } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - pbr::MessageDescriptor pb::IMessage.Descriptor { - get { return Descriptor; } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public RouteNote() { - OnConstruction(); - } - - partial void OnConstruction(); - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public RouteNote(RouteNote other) : this() { - location_ = other.location_ != null ? other.location_.Clone() : null; - message_ = other.message_; - _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public RouteNote Clone() { - return new RouteNote(this); - } - - /// Field number for the "location" field. - public const int LocationFieldNumber = 1; - private global::Routeguide.Point location_; - /// - /// The location from which the message is sent. - /// - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public global::Routeguide.Point Location { - get { return location_; } - set { - location_ = value; - } - } - - /// Field number for the "message" field. - public const int MessageFieldNumber = 2; - private string message_ = ""; - /// - /// The message to be sent. - /// - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public string Message { - get { return message_; } - set { - message_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); - } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public override bool Equals(object other) { - return Equals(other as RouteNote); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool Equals(RouteNote other) { - if (ReferenceEquals(other, null)) { - return false; - } - if (ReferenceEquals(other, this)) { - return true; - } - if (!object.Equals(Location, other.Location)) return false; - if (Message != other.Message) return false; - return Equals(_unknownFields, other._unknownFields); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public override int GetHashCode() { - int hash = 1; - if (location_ != null) hash ^= Location.GetHashCode(); - if (Message.Length != 0) hash ^= Message.GetHashCode(); - if (_unknownFields != null) { - hash ^= _unknownFields.GetHashCode(); - } - return hash; - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public override string ToString() { - return pb::JsonFormatter.ToDiagnosticString(this); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void WriteTo(pb::CodedOutputStream output) { - if (location_ != null) { - output.WriteRawTag(10); - output.WriteMessage(Location); - } - if (Message.Length != 0) { - output.WriteRawTag(18); - output.WriteString(Message); - } - if (_unknownFields != null) { - _unknownFields.WriteTo(output); - } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public int CalculateSize() { - int size = 0; - if (location_ != null) { - size += 1 + pb::CodedOutputStream.ComputeMessageSize(Location); - } - if (Message.Length != 0) { - size += 1 + pb::CodedOutputStream.ComputeStringSize(Message); - } - if (_unknownFields != null) { - size += _unknownFields.CalculateSize(); - } - return size; - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void MergeFrom(RouteNote other) { - if (other == null) { - return; - } - if (other.location_ != null) { - if (location_ == null) { - location_ = new global::Routeguide.Point(); - } - Location.MergeFrom(other.Location); - } - if (other.Message.Length != 0) { - Message = other.Message; - } - _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void MergeFrom(pb::CodedInputStream input) { - uint tag; - while ((tag = input.ReadTag()) != 0) { - switch(tag) { - default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); - break; - case 10: { - if (location_ == null) { - location_ = new global::Routeguide.Point(); - } - input.ReadMessage(location_); - break; - } - case 18: { - Message = input.ReadString(); - break; - } - } - } - } - - } - - /// - /// A RouteSummary is received in response to a RecordRoute rpc. - /// - /// It contains the number of individual points received, the number of - /// detected features, and the total distance covered as the cumulative sum of - /// the distance between each point. - /// - public sealed partial class RouteSummary : pb::IMessage { - private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new RouteSummary()); - private pb::UnknownFieldSet _unknownFields; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public static pb::MessageParser Parser { get { return _parser; } } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public static pbr::MessageDescriptor Descriptor { - get { return global::Routeguide.RouteGuideReflection.Descriptor.MessageTypes[4]; } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - pbr::MessageDescriptor pb::IMessage.Descriptor { - get { return Descriptor; } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public RouteSummary() { - OnConstruction(); - } - - partial void OnConstruction(); - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public RouteSummary(RouteSummary other) : this() { - pointCount_ = other.pointCount_; - featureCount_ = other.featureCount_; - distance_ = other.distance_; - elapsedTime_ = other.elapsedTime_; - _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public RouteSummary Clone() { - return new RouteSummary(this); - } - - /// Field number for the "point_count" field. - public const int PointCountFieldNumber = 1; - private int pointCount_; - /// - /// The number of points received. - /// - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public int PointCount { - get { return pointCount_; } - set { - pointCount_ = value; - } - } - - /// Field number for the "feature_count" field. - public const int FeatureCountFieldNumber = 2; - private int featureCount_; - /// - /// The number of known features passed while traversing the route. - /// - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public int FeatureCount { - get { return featureCount_; } - set { - featureCount_ = value; - } - } - - /// Field number for the "distance" field. - public const int DistanceFieldNumber = 3; - private int distance_; - /// - /// The distance covered in metres. - /// - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public int Distance { - get { return distance_; } - set { - distance_ = value; - } - } - - /// Field number for the "elapsed_time" field. - public const int ElapsedTimeFieldNumber = 4; - private int elapsedTime_; - /// - /// The duration of the traversal in seconds. - /// - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public int ElapsedTime { - get { return elapsedTime_; } - set { - elapsedTime_ = value; - } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public override bool Equals(object other) { - return Equals(other as RouteSummary); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool Equals(RouteSummary other) { - if (ReferenceEquals(other, null)) { - return false; - } - if (ReferenceEquals(other, this)) { - return true; - } - if (PointCount != other.PointCount) return false; - if (FeatureCount != other.FeatureCount) return false; - if (Distance != other.Distance) return false; - if (ElapsedTime != other.ElapsedTime) return false; - return Equals(_unknownFields, other._unknownFields); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public override int GetHashCode() { - int hash = 1; - if (PointCount != 0) hash ^= PointCount.GetHashCode(); - if (FeatureCount != 0) hash ^= FeatureCount.GetHashCode(); - if (Distance != 0) hash ^= Distance.GetHashCode(); - if (ElapsedTime != 0) hash ^= ElapsedTime.GetHashCode(); - if (_unknownFields != null) { - hash ^= _unknownFields.GetHashCode(); - } - return hash; - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public override string ToString() { - return pb::JsonFormatter.ToDiagnosticString(this); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void WriteTo(pb::CodedOutputStream output) { - if (PointCount != 0) { - output.WriteRawTag(8); - output.WriteInt32(PointCount); - } - if (FeatureCount != 0) { - output.WriteRawTag(16); - output.WriteInt32(FeatureCount); - } - if (Distance != 0) { - output.WriteRawTag(24); - output.WriteInt32(Distance); - } - if (ElapsedTime != 0) { - output.WriteRawTag(32); - output.WriteInt32(ElapsedTime); - } - if (_unknownFields != null) { - _unknownFields.WriteTo(output); - } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public int CalculateSize() { - int size = 0; - if (PointCount != 0) { - size += 1 + pb::CodedOutputStream.ComputeInt32Size(PointCount); - } - if (FeatureCount != 0) { - size += 1 + pb::CodedOutputStream.ComputeInt32Size(FeatureCount); - } - if (Distance != 0) { - size += 1 + pb::CodedOutputStream.ComputeInt32Size(Distance); - } - if (ElapsedTime != 0) { - size += 1 + pb::CodedOutputStream.ComputeInt32Size(ElapsedTime); - } - if (_unknownFields != null) { - size += _unknownFields.CalculateSize(); - } - return size; - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void MergeFrom(RouteSummary other) { - if (other == null) { - return; - } - if (other.PointCount != 0) { - PointCount = other.PointCount; - } - if (other.FeatureCount != 0) { - FeatureCount = other.FeatureCount; - } - if (other.Distance != 0) { - Distance = other.Distance; - } - if (other.ElapsedTime != 0) { - ElapsedTime = other.ElapsedTime; - } - _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void MergeFrom(pb::CodedInputStream input) { - uint tag; - while ((tag = input.ReadTag()) != 0) { - switch(tag) { - default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); - break; - case 8: { - PointCount = input.ReadInt32(); - break; - } - case 16: { - FeatureCount = input.ReadInt32(); - break; - } - case 24: { - Distance = input.ReadInt32(); - break; - } - case 32: { - ElapsedTime = input.ReadInt32(); - break; - } - } - } - } - - } - - #endregion - -} - -#endregion Designer generated code diff --git a/examples/csharp/RouteGuide/RouteGuide/RouteGuide.csproj b/examples/csharp/RouteGuide/RouteGuide/RouteGuide.csproj index 86346d1e149..4c6949488c7 100644 --- a/examples/csharp/RouteGuide/RouteGuide/RouteGuide.csproj +++ b/examples/csharp/RouteGuide/RouteGuide/RouteGuide.csproj @@ -1,25 +1,22 @@ - + - RouteGuide - netcoreapp2.1 - portable - RouteGuide - RouteGuide + netstandard1.5 - - - + + - - PreserveNewest - + + + + + diff --git a/examples/csharp/RouteGuide/RouteGuide/RouteGuideGrpc.cs b/examples/csharp/RouteGuide/RouteGuide/RouteGuideGrpc.cs deleted file mode 100644 index 445708e4469..00000000000 --- a/examples/csharp/RouteGuide/RouteGuide/RouteGuideGrpc.cs +++ /dev/null @@ -1,331 +0,0 @@ -// -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: route_guide.proto -// -// 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. -// -#pragma warning disable 0414, 1591 -#region Designer generated code - -using grpc = global::Grpc.Core; - -namespace Routeguide { - /// - /// Interface exported by the server. - /// - public static partial class RouteGuide - { - static readonly string __ServiceName = "routeguide.RouteGuide"; - - static readonly grpc::Marshaller __Marshaller_routeguide_Point = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Routeguide.Point.Parser.ParseFrom); - static readonly grpc::Marshaller __Marshaller_routeguide_Feature = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Routeguide.Feature.Parser.ParseFrom); - static readonly grpc::Marshaller __Marshaller_routeguide_Rectangle = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Routeguide.Rectangle.Parser.ParseFrom); - static readonly grpc::Marshaller __Marshaller_routeguide_RouteSummary = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Routeguide.RouteSummary.Parser.ParseFrom); - static readonly grpc::Marshaller __Marshaller_routeguide_RouteNote = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Routeguide.RouteNote.Parser.ParseFrom); - - static readonly grpc::Method __Method_GetFeature = new grpc::Method( - grpc::MethodType.Unary, - __ServiceName, - "GetFeature", - __Marshaller_routeguide_Point, - __Marshaller_routeguide_Feature); - - static readonly grpc::Method __Method_ListFeatures = new grpc::Method( - grpc::MethodType.ServerStreaming, - __ServiceName, - "ListFeatures", - __Marshaller_routeguide_Rectangle, - __Marshaller_routeguide_Feature); - - static readonly grpc::Method __Method_RecordRoute = new grpc::Method( - grpc::MethodType.ClientStreaming, - __ServiceName, - "RecordRoute", - __Marshaller_routeguide_Point, - __Marshaller_routeguide_RouteSummary); - - static readonly grpc::Method __Method_RouteChat = new grpc::Method( - grpc::MethodType.DuplexStreaming, - __ServiceName, - "RouteChat", - __Marshaller_routeguide_RouteNote, - __Marshaller_routeguide_RouteNote); - - /// Service descriptor - public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor - { - get { return global::Routeguide.RouteGuideReflection.Descriptor.Services[0]; } - } - - /// Base class for server-side implementations of RouteGuide - public abstract partial class RouteGuideBase - { - /// - /// A simple RPC. - /// - /// Obtains the feature at a given position. - /// - /// A feature with an empty name is returned if there's no feature at the given - /// position. - /// - /// The request received from the client. - /// The context of the server-side call handler being invoked. - /// The response to send back to the client (wrapped by a task). - public virtual global::System.Threading.Tasks.Task GetFeature(global::Routeguide.Point request, grpc::ServerCallContext context) - { - throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, "")); - } - - /// - /// A server-to-client streaming RPC. - /// - /// Obtains the Features available within the given Rectangle. Results are - /// streamed rather than returned at once (e.g. in a response message with a - /// repeated field), as the rectangle may cover a large area and contain a - /// huge number of features. - /// - /// The request received from the client. - /// Used for sending responses back to the client. - /// The context of the server-side call handler being invoked. - /// A task indicating completion of the handler. - public virtual global::System.Threading.Tasks.Task ListFeatures(global::Routeguide.Rectangle request, grpc::IServerStreamWriter responseStream, grpc::ServerCallContext context) - { - throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, "")); - } - - /// - /// A client-to-server streaming RPC. - /// - /// Accepts a stream of Points on a route being traversed, returning a - /// RouteSummary when traversal is completed. - /// - /// Used for reading requests from the client. - /// The context of the server-side call handler being invoked. - /// The response to send back to the client (wrapped by a task). - public virtual global::System.Threading.Tasks.Task RecordRoute(grpc::IAsyncStreamReader requestStream, grpc::ServerCallContext context) - { - throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, "")); - } - - /// - /// A Bidirectional streaming RPC. - /// - /// Accepts a stream of RouteNotes sent while a route is being traversed, - /// while receiving other RouteNotes (e.g. from other users). - /// - /// Used for reading requests from the client. - /// Used for sending responses back to the client. - /// The context of the server-side call handler being invoked. - /// A task indicating completion of the handler. - public virtual global::System.Threading.Tasks.Task RouteChat(grpc::IAsyncStreamReader requestStream, grpc::IServerStreamWriter responseStream, grpc::ServerCallContext context) - { - throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, "")); - } - - } - - /// Client for RouteGuide - public partial class RouteGuideClient : grpc::ClientBase - { - /// Creates a new client for RouteGuide - /// The channel to use to make remote calls. - public RouteGuideClient(grpc::Channel channel) : base(channel) - { - } - /// Creates a new client for RouteGuide that uses a custom CallInvoker. - /// The callInvoker to use to make remote calls. - public RouteGuideClient(grpc::CallInvoker callInvoker) : base(callInvoker) - { - } - /// Protected parameterless constructor to allow creation of test doubles. - protected RouteGuideClient() : base() - { - } - /// Protected constructor to allow creation of configured clients. - /// The client configuration. - protected RouteGuideClient(ClientBaseConfiguration configuration) : base(configuration) - { - } - - /// - /// A simple RPC. - /// - /// Obtains the feature at a given position. - /// - /// A feature with an empty name is returned if there's no feature at the given - /// position. - /// - /// The request to send to the server. - /// The initial metadata to send with the call. This parameter is optional. - /// An optional deadline for the call. The call will be cancelled if deadline is hit. - /// An optional token for canceling the call. - /// The response received from the server. - public virtual global::Routeguide.Feature GetFeature(global::Routeguide.Point request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken)) - { - return GetFeature(request, new grpc::CallOptions(headers, deadline, cancellationToken)); - } - /// - /// A simple RPC. - /// - /// Obtains the feature at a given position. - /// - /// A feature with an empty name is returned if there's no feature at the given - /// position. - /// - /// The request to send to the server. - /// The options for the call. - /// The response received from the server. - public virtual global::Routeguide.Feature GetFeature(global::Routeguide.Point request, grpc::CallOptions options) - { - return CallInvoker.BlockingUnaryCall(__Method_GetFeature, null, options, request); - } - /// - /// A simple RPC. - /// - /// Obtains the feature at a given position. - /// - /// A feature with an empty name is returned if there's no feature at the given - /// position. - /// - /// The request to send to the server. - /// The initial metadata to send with the call. This parameter is optional. - /// An optional deadline for the call. The call will be cancelled if deadline is hit. - /// An optional token for canceling the call. - /// The call object. - public virtual grpc::AsyncUnaryCall GetFeatureAsync(global::Routeguide.Point request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken)) - { - return GetFeatureAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken)); - } - /// - /// A simple RPC. - /// - /// Obtains the feature at a given position. - /// - /// A feature with an empty name is returned if there's no feature at the given - /// position. - /// - /// The request to send to the server. - /// The options for the call. - /// The call object. - public virtual grpc::AsyncUnaryCall GetFeatureAsync(global::Routeguide.Point request, grpc::CallOptions options) - { - return CallInvoker.AsyncUnaryCall(__Method_GetFeature, null, options, request); - } - /// - /// A server-to-client streaming RPC. - /// - /// Obtains the Features available within the given Rectangle. Results are - /// streamed rather than returned at once (e.g. in a response message with a - /// repeated field), as the rectangle may cover a large area and contain a - /// huge number of features. - /// - /// The request to send to the server. - /// The initial metadata to send with the call. This parameter is optional. - /// An optional deadline for the call. The call will be cancelled if deadline is hit. - /// An optional token for canceling the call. - /// The call object. - public virtual grpc::AsyncServerStreamingCall ListFeatures(global::Routeguide.Rectangle request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken)) - { - return ListFeatures(request, new grpc::CallOptions(headers, deadline, cancellationToken)); - } - /// - /// A server-to-client streaming RPC. - /// - /// Obtains the Features available within the given Rectangle. Results are - /// streamed rather than returned at once (e.g. in a response message with a - /// repeated field), as the rectangle may cover a large area and contain a - /// huge number of features. - /// - /// The request to send to the server. - /// The options for the call. - /// The call object. - public virtual grpc::AsyncServerStreamingCall ListFeatures(global::Routeguide.Rectangle request, grpc::CallOptions options) - { - return CallInvoker.AsyncServerStreamingCall(__Method_ListFeatures, null, options, request); - } - /// - /// A client-to-server streaming RPC. - /// - /// Accepts a stream of Points on a route being traversed, returning a - /// RouteSummary when traversal is completed. - /// - /// The initial metadata to send with the call. This parameter is optional. - /// An optional deadline for the call. The call will be cancelled if deadline is hit. - /// An optional token for canceling the call. - /// The call object. - public virtual grpc::AsyncClientStreamingCall RecordRoute(grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken)) - { - return RecordRoute(new grpc::CallOptions(headers, deadline, cancellationToken)); - } - /// - /// A client-to-server streaming RPC. - /// - /// Accepts a stream of Points on a route being traversed, returning a - /// RouteSummary when traversal is completed. - /// - /// The options for the call. - /// The call object. - public virtual grpc::AsyncClientStreamingCall RecordRoute(grpc::CallOptions options) - { - return CallInvoker.AsyncClientStreamingCall(__Method_RecordRoute, null, options); - } - /// - /// A Bidirectional streaming RPC. - /// - /// Accepts a stream of RouteNotes sent while a route is being traversed, - /// while receiving other RouteNotes (e.g. from other users). - /// - /// The initial metadata to send with the call. This parameter is optional. - /// An optional deadline for the call. The call will be cancelled if deadline is hit. - /// An optional token for canceling the call. - /// The call object. - public virtual grpc::AsyncDuplexStreamingCall RouteChat(grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken)) - { - return RouteChat(new grpc::CallOptions(headers, deadline, cancellationToken)); - } - /// - /// A Bidirectional streaming RPC. - /// - /// Accepts a stream of RouteNotes sent while a route is being traversed, - /// while receiving other RouteNotes (e.g. from other users). - /// - /// The options for the call. - /// The call object. - public virtual grpc::AsyncDuplexStreamingCall RouteChat(grpc::CallOptions options) - { - return CallInvoker.AsyncDuplexStreamingCall(__Method_RouteChat, null, options); - } - /// Creates a new instance of client from given ClientBaseConfiguration. - protected override RouteGuideClient NewInstance(ClientBaseConfiguration configuration) - { - return new RouteGuideClient(configuration); - } - } - - /// Creates service definition that can be registered with a server - /// An object implementing the server-side handling logic. - public static grpc::ServerServiceDefinition BindService(RouteGuideBase serviceImpl) - { - return grpc::ServerServiceDefinition.CreateBuilder() - .AddMethod(__Method_GetFeature, serviceImpl.GetFeature) - .AddMethod(__Method_ListFeatures, serviceImpl.ListFeatures) - .AddMethod(__Method_RecordRoute, serviceImpl.RecordRoute) - .AddMethod(__Method_RouteChat, serviceImpl.RouteChat).Build(); - } - - } -} -#endregion diff --git a/examples/csharp/RouteGuide/RouteGuide/RouteGuideUtil.cs b/examples/csharp/RouteGuide/RouteGuide/RouteGuideUtil.cs index f9af1908880..96bd8ca09b9 100644 --- a/examples/csharp/RouteGuide/RouteGuide/RouteGuideUtil.cs +++ b/examples/csharp/RouteGuide/RouteGuide/RouteGuideUtil.cs @@ -108,6 +108,7 @@ namespace Routeguide return features; } +#pragma warning disable 0649 // Suppresses "Field 'x' is never assigned to". private class JsonFeature { public string name; @@ -119,5 +120,6 @@ namespace Routeguide public int longitude; public int latitude; } +#pragma warning restore 0649 } } diff --git a/examples/csharp/RouteGuide/RouteGuideClient/RouteGuideClient.csproj b/examples/csharp/RouteGuide/RouteGuideClient/RouteGuideClient.csproj index c6dadf082b8..b773dd0923c 100644 --- a/examples/csharp/RouteGuide/RouteGuideClient/RouteGuideClient.csproj +++ b/examples/csharp/RouteGuide/RouteGuideClient/RouteGuideClient.csproj @@ -1,12 +1,8 @@ - + - RouteGuideClient - netcoreapp2.1 - portable - RouteGuideClient + netcoreapp2.1 Exe - RouteGuideClient diff --git a/examples/csharp/RouteGuide/RouteGuideServer/RouteGuideServer.csproj b/examples/csharp/RouteGuide/RouteGuideServer/RouteGuideServer.csproj index 005c87ca0c2..b773dd0923c 100644 --- a/examples/csharp/RouteGuide/RouteGuideServer/RouteGuideServer.csproj +++ b/examples/csharp/RouteGuide/RouteGuideServer/RouteGuideServer.csproj @@ -1,12 +1,8 @@ - + - RouteGuideServer - netcoreapp2.1 - portable - RouteGuideServer + netcoreapp2.1 Exe - RouteGuideServer diff --git a/examples/csharp/RouteGuide/generate_protos.bat b/examples/csharp/RouteGuide/generate_protos.bat deleted file mode 100644 index f3a4382cf19..00000000000 --- a/examples/csharp/RouteGuide/generate_protos.bat +++ /dev/null @@ -1,28 +0,0 @@ -@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 Generate the C# code for .proto files - -setlocal - -@rem enter this directory -cd /d %~dp0 - -@rem packages will be available in nuget cache directory once the project is built or after "dotnet restore" -set PROTOC=%UserProfile%\.nuget\packages\Google.Protobuf.Tools\3.6.1\tools\windows_x64\protoc.exe -set PLUGIN=%UserProfile%\.nuget\packages\Grpc.Tools\1.14.1\tools\windows_x64\grpc_csharp_plugin.exe - -%PROTOC% -I../../protos --csharp_out RouteGuide ../../protos/route_guide.proto --grpc_out RouteGuide --plugin=protoc-gen-grpc=%PLUGIN% - -endlocal diff --git a/examples/objective-c/auth_sample/MakeRPCViewController.m b/examples/objective-c/auth_sample/MakeRPCViewController.m index 545deb5fcad..648bbab7cec 100644 --- a/examples/objective-c/auth_sample/MakeRPCViewController.m +++ b/examples/objective-c/auth_sample/MakeRPCViewController.m @@ -46,8 +46,16 @@ static NSString * const kTestHostAddress = @"grpc-test.sandbox.googleapis.com"; } @end +@interface MakeRPCViewController () + +@end + @implementation MakeRPCViewController +- (dispatch_queue_t)dispatchQueue { + return dispatch_get_main_queue(); +} + - (void)viewWillAppear:(BOOL)animated { // Create a service client and a proto request as usual. @@ -57,28 +65,30 @@ static NSString * const kTestHostAddress = @"grpc-test.sandbox.googleapis.com"; request.fillUsername = YES; request.fillOauthScope = YES; - // Create a not-yet-started RPC. We want to set the request headers on this object before starting - // it. - ProtoRPC *call = - [client RPCToUnaryCallWithRequest:request handler:^(AUTHResponse *response, NSError *error) { - if (response) { - // This test server responds with the email and scope of the access token it receives. - self.mainLabel.text = [NSString stringWithFormat:@"Used scope: %@ on behalf of user %@", - response.oauthScope, response.username]; - - } else { - self.mainLabel.text = error.UIDescription; - } - }]; - - // Set the access token to be used. - NSString *accessToken = GIDSignIn.sharedInstance.currentUser.authentication.accessToken; - call.requestHeaders[@"Authorization"] = [@"Bearer " stringByAppendingString:accessToken]; - - // Start the RPC. + // Set the request header with call options + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.oauth2AccessToken = GIDSignIn.sharedInstance.currentUser.authentication.accessToken; + GRPCUnaryProtoCall *call = [client unaryCallWithMessage:request + responseHandler:self + callOptions:options]; [call start]; self.mainLabel.text = @"Waiting for RPC to complete..."; } +- (void)didReceiveProtoMessage:(GPBMessage *)message { + AUTHResponse *response = (AUTHResponse *)message; + if (response) { + // This test server responds with the email and scope of the access token it receives. + self.mainLabel.text = [NSString stringWithFormat:@"Used scope: %@ on behalf of user %@", + response.oauthScope, response.username]; + } +} + +- (void)didCloseWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { + if (error) { + self.mainLabel.text = error.UIDescription; + } +} + @end diff --git a/examples/objective-c/helloworld/HelloWorld.xcodeproj/project.pbxproj b/examples/objective-c/helloworld/HelloWorld.xcodeproj/project.pbxproj index df5c40cda20..e067e82b3de 100644 --- a/examples/objective-c/helloworld/HelloWorld.xcodeproj/project.pbxproj +++ b/examples/objective-c/helloworld/HelloWorld.xcodeproj/project.pbxproj @@ -132,6 +132,8 @@ TargetAttributes = { 5E36905F1B2A23800040F884 = { CreatedOnToolsVersion = 6.2; + DevelopmentTeam = EQHXZ8M8AV; + ProvisioningStyle = Manual; }; }; }; @@ -321,9 +323,12 @@ baseConfigurationReference = DBDE3E48389499064CD664B8 /* Pods-HelloWorld.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Manual; + DEVELOPMENT_TEAM = EQHXZ8M8AV; INFOPLIST_FILE = HelloWorld/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = "Google Development"; }; name = Debug; }; @@ -332,9 +337,12 @@ baseConfigurationReference = 0C432EF610DB15C0F47A66BB /* Pods-HelloWorld.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Manual; + DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = HelloWorld/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Release; }; diff --git a/examples/objective-c/helloworld/main.m b/examples/objective-c/helloworld/main.m index c771375d803..649e65bb5b2 100644 --- a/examples/objective-c/helloworld/main.m +++ b/examples/objective-c/helloworld/main.m @@ -25,20 +25,41 @@ static NSString * const kHostAddress = @"localhost:50051"; +@interface HLWResponseHandler : NSObject + +@end + +// A response handler object dispatching messages to main queue +@implementation HLWResponseHandler + +- (dispatch_queue_t)dispatchQueue { + return dispatch_get_main_queue(); +} + +- (void)didReceiveProtoMessage:(GPBMessage *)message { + NSLog(@"%@", message); +} + +@end + int main(int argc, char * argv[]) { @autoreleasepool { - [GRPCCall useInsecureConnectionsForHost:kHostAddress]; - [GRPCCall setUserAgentPrefix:@"HelloWorld/1.0" forHost:kHostAddress]; - HLWGreeter *client = [[HLWGreeter alloc] initWithHost:kHostAddress]; HLWHelloRequest *request = [HLWHelloRequest message]; request.name = @"Objective-C"; - [client sayHelloWithRequest:request handler:^(HLWHelloReply *response, NSError *error) { - NSLog(@"%@", response.message); - }]; - + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + // this example does not use TLS (secure channel); use insecure channel instead + options.transportType = GRPCTransportTypeInsecure; + options.userAgentPrefix = @"HelloWorld/1.0"; + + GRPCUnaryProtoCall *call = [client sayHelloWithMessage:request + responseHandler:[[HLWResponseHandler alloc] init] + callOptions:options]; + + [call start]; + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); } } diff --git a/examples/objective-c/helloworld_macos/main.m b/examples/objective-c/helloworld_macos/main.m index 2a98ec4966c..ce24a9b1466 100644 --- a/examples/objective-c/helloworld_macos/main.m +++ b/examples/objective-c/helloworld_macos/main.m @@ -24,19 +24,40 @@ static NSString * const kHostAddress = @"localhost:50051"; +@interface HLWResponseHandler : NSObject + +@end + +// A response handler object dispatching messages to main queue +@implementation HLWResponseHandler + +- (dispatch_queue_t)dispatchQueue { + return dispatch_get_main_queue(); +} + +- (void)didReceiveProtoMessage:(GPBMessage *)message { + NSLog(@"%@", message); +} + +@end + int main(int argc, const char * argv[]) { @autoreleasepool { - [GRPCCall useInsecureConnectionsForHost:kHostAddress]; - [GRPCCall setUserAgentPrefix:@"HelloWorld/1.0" forHost:kHostAddress]; - HLWGreeter *client = [[HLWGreeter alloc] initWithHost:kHostAddress]; HLWHelloRequest *request = [HLWHelloRequest message]; request.name = @"Objective-C"; - [client sayHelloWithRequest:request handler:^(HLWHelloReply *response, NSError *error) { - NSLog(@"%@", response.message); - }]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + // this example does not use TLS (secure channel); use insecure channel instead + options.transportType = GRPCTransportTypeInsecure; + options.userAgentPrefix = @"HelloWorld/1.0"; + + GRPCUnaryProtoCall *call = [client sayHelloWithMessage:request + responseHandler:[[HLWResponseHandler alloc] init] + callOptions:options]; + + [call start]; } return NSApplicationMain(argc, argv); diff --git a/examples/objective-c/route_guide/ViewControllers.m b/examples/objective-c/route_guide/ViewControllers.m index 0f116f3a235..43d2082f585 100644 --- a/examples/objective-c/route_guide/ViewControllers.m +++ b/examples/objective-c/route_guide/ViewControllers.m @@ -17,10 +17,7 @@ */ #import -#import #import -#import -#import static NSString * const kHostAddress = @"localhost:50051"; @@ -65,7 +62,7 @@ static NSString * const kHostAddress = @"localhost:50051"; * Run the getFeature demo. Calls getFeature with a point known to have a feature and a point known * not to have a feature. */ -@interface GetFeatureViewController : UIViewController +@interface GetFeatureViewController : UIViewController @property (weak, nonatomic) IBOutlet UILabel *outputLabel; @@ -75,39 +72,56 @@ static NSString * const kHostAddress = @"localhost:50051"; RTGRouteGuide *_service; } -- (void)execRequest { - void (^handler)(RTGFeature *response, NSError *error) = ^(RTGFeature *response, NSError *error) { - // TODO(makdharma): Remove boilerplate by consolidating into one log function. - if (response.name.length) { - NSString *str =[NSString stringWithFormat:@"%@\nFound feature called %@ at %@.", self.outputLabel.text, response.location, response.name]; - self.outputLabel.text = str; - NSLog(@"Found feature called %@ at %@.", response.name, response.location); - } else if (response) { - NSString *str =[NSString stringWithFormat:@"%@\nFound no features at %@", self.outputLabel.text,response.location]; - self.outputLabel.text = str; - NSLog(@"Found no features at %@", response.location); - } else { - NSString *str =[NSString stringWithFormat:@"%@\nRPC error: %@", self.outputLabel.text, error]; - self.outputLabel.text = str; - NSLog(@"RPC error: %@", error); - } - }; +- (dispatch_queue_t)dispatchQueue { + return dispatch_get_main_queue(); +} +- (void)didReceiveProtoMessage:(GPBMessage *)message { + RTGFeature *response = (RTGFeature *)message; + + // TODO(makdharma): Remove boilerplate by consolidating into one log function. + if (response.name.length != 0) { + NSString *str =[NSString stringWithFormat:@"%@\nFound feature called %@ at %@.", self.outputLabel.text, response.location, response.name]; + self.outputLabel.text = str; + NSLog(@"Found feature called %@ at %@.", response.name, response.location); + } else if (response) { + NSString *str =[NSString stringWithFormat:@"%@\nFound no features at %@", self.outputLabel.text,response.location]; + self.outputLabel.text = str; + NSLog(@"Found no features at %@", response.location); + } +} + +- (void)didCloseWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { + if (error) { + NSString *str =[NSString stringWithFormat:@"%@\nRPC error: %@", self.outputLabel.text, error]; + self.outputLabel.text = str; + NSLog(@"RPC error: %@", error); + } +} + +- (void)execRequest { RTGPoint *point = [RTGPoint message]; point.latitude = 409146138; point.longitude = -746188906; - [_service getFeatureWithRequest:point handler:handler]; - [_service getFeatureWithRequest:[RTGPoint message] handler:handler]; + GRPCUnaryProtoCall *call = [_service getFeatureWithMessage:point + responseHandler:self + callOptions:nil]; + [call start]; + call = [_service getFeatureWithMessage:[RTGPoint message] + responseHandler:self + callOptions:nil]; + [call start]; + } - (void)viewDidLoad { [super viewDidLoad]; - // This only needs to be done once per host, before creating service objects for that host. - [GRPCCall useInsecureConnectionsForHost:kHostAddress]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = GRPCTransportTypeInsecure; - _service = [[RTGRouteGuide alloc] initWithHost:kHostAddress]; + _service = [[RTGRouteGuide alloc] initWithHost:kHostAddress callOptions:options]; } - (void)viewDidAppear:(BOOL)animated { @@ -126,7 +140,7 @@ static NSString * const kHostAddress = @"localhost:50051"; * Run the listFeatures demo. Calls listFeatures with a rectangle containing all of the features in * the pre-generated database. Prints each response as it comes in. */ -@interface ListFeaturesViewController : UIViewController +@interface ListFeaturesViewController : UIViewController @property (weak, nonatomic) IBOutlet UILabel *outputLabel; @@ -136,6 +150,10 @@ static NSString * const kHostAddress = @"localhost:50051"; RTGRouteGuide *_service; } +- (dispatch_queue_t)dispatchQueue { + return dispatch_get_main_queue(); +} + - (void)execRequest { RTGRectangle *rectangle = [RTGRectangle message]; rectangle.lo.latitude = 405E6; @@ -144,24 +162,36 @@ static NSString * const kHostAddress = @"localhost:50051"; rectangle.hi.longitude = -745E6; NSLog(@"Looking for features between %@ and %@", rectangle.lo, rectangle.hi); - [_service listFeaturesWithRequest:rectangle - eventHandler:^(BOOL done, RTGFeature *response, NSError *error) { - if (response) { - NSString *str =[NSString stringWithFormat:@"%@\nFound feature at %@ called %@.", self.outputLabel.text, response.location, response.name]; - self.outputLabel.text = str; - NSLog(@"Found feature at %@ called %@.", response.location, response.name); - } else if (error) { - NSString *str =[NSString stringWithFormat:@"%@\nRPC error: %@", self.outputLabel.text, error]; - self.outputLabel.text = str; - NSLog(@"RPC error: %@", error); - } - }]; + GRPCUnaryProtoCall *call = [_service listFeaturesWithMessage:rectangle + responseHandler:self + callOptions:nil]; + [call start]; +} + +- (void)didReceiveProtoMessage:(GPBMessage *)message { + RTGFeature *response = (RTGFeature *)message; + if (response) { + NSString *str =[NSString stringWithFormat:@"%@\nFound feature at %@ called %@.", self.outputLabel.text, response.location, response.name]; + self.outputLabel.text = str; + NSLog(@"Found feature at %@ called %@.", response.location, response.name); + } +} + +- (void)didCloseWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { + if (error) { + NSString *str =[NSString stringWithFormat:@"%@\nRPC error: %@", self.outputLabel.text, error]; + self.outputLabel.text = str; + NSLog(@"RPC error: %@", error); + } } - (void)viewDidLoad { [super viewDidLoad]; - _service = [[RTGRouteGuide alloc] initWithHost:kHostAddress]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = GRPCTransportTypeInsecure; + + _service = [[RTGRouteGuide alloc] initWithHost:kHostAddress callOptions:options]; } - (void)viewDidAppear:(BOOL)animated { @@ -173,7 +203,6 @@ static NSString * const kHostAddress = @"localhost:50051"; @end - #pragma mark Demo: Record Route /** @@ -181,7 +210,7 @@ static NSString * const kHostAddress = @"localhost:50051"; * database with a variable delay in between. Prints the statistics when they are sent from the * server. */ -@interface RecordRouteViewController : UIViewController +@interface RecordRouteViewController : UIViewController @property (weak, nonatomic) IBOutlet UILabel *outputLabel; @@ -191,47 +220,71 @@ static NSString * const kHostAddress = @"localhost:50051"; RTGRouteGuide *_service; } +- (dispatch_queue_t)dispatchQueue { + return dispatch_get_main_queue(); +} + - (void)execRequest { NSString *dataBasePath = [NSBundle.mainBundle pathForResource:@"route_guide_db" ofType:@"json"]; NSData *dataBaseContent = [NSData dataWithContentsOfFile:dataBasePath]; - NSArray *features = [NSJSONSerialization JSONObjectWithData:dataBaseContent options:0 error:NULL]; + NSError *error; + NSArray *features = [NSJSONSerialization JSONObjectWithData:dataBaseContent options:0 error:&error]; - GRXWriter *locations = [[GRXWriter writerWithContainer:features] map:^id(id feature) { + if (error) { + NSLog(@"Error reading database."); + NSString *str = @"Error reading database."; + self.outputLabel.text = str; + return; + } + + GRPCStreamingProtoCall *call = [_service recordRouteWithResponseHandler:self + callOptions:nil]; + [call start]; + for (id feature in features) { RTGPoint *location = [RTGPoint message]; location.longitude = [((NSNumber *) feature[@"location"][@"longitude"]) intValue]; location.latitude = [((NSNumber *) feature[@"location"][@"latitude"]) intValue]; NSString *str =[NSString stringWithFormat:@"%@\nVisiting point %@", self.outputLabel.text, location]; self.outputLabel.text = str; NSLog(@"Visiting point %@", location); - return location; - }]; + [call writeMessage:location]; + } + [call finish]; +} - [_service recordRouteWithRequestsWriter:locations - handler:^(RTGRouteSummary *response, NSError *error) { - if (response) { - NSString *str =[NSString stringWithFormat: - @"%@\nFinished trip with %i points\nPassed %i features\n" - "Travelled %i meters\nIt took %i seconds", - self.outputLabel.text, response.pointCount, response.featureCount, - response.distance, response.elapsedTime]; - self.outputLabel.text = str; - NSLog(@"Finished trip with %i points", response.pointCount); - NSLog(@"Passed %i features", response.featureCount); - NSLog(@"Travelled %i meters", response.distance); - NSLog(@"It took %i seconds", response.elapsedTime); - } else { - NSString *str =[NSString stringWithFormat:@"%@\nRPC error: %@", self.outputLabel.text, error]; - self.outputLabel.text = str; - NSLog(@"RPC error: %@", error); - } - }]; +- (void)didReceiveProtoMessage:(GPBMessage *)message { + RTGRouteSummary *response = (RTGRouteSummary *)message; + + if (response) { + NSString *str =[NSString stringWithFormat: + @"%@\nFinished trip with %i points\nPassed %i features\n" + "Travelled %i meters\nIt took %i seconds", + self.outputLabel.text, response.pointCount, response.featureCount, + response.distance, response.elapsedTime]; + self.outputLabel.text = str; + NSLog(@"Finished trip with %i points", response.pointCount); + NSLog(@"Passed %i features", response.featureCount); + NSLog(@"Travelled %i meters", response.distance); + NSLog(@"It took %i seconds", response.elapsedTime); + } +} + +- (void)didCloseWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { + if (error) { + NSString *str =[NSString stringWithFormat:@"%@\nRPC error: %@", self.outputLabel.text, error]; + self.outputLabel.text = str; + NSLog(@"RPC error: %@", error); + } } - (void)viewDidLoad { [super viewDidLoad]; - _service = [[RTGRouteGuide alloc] initWithHost:kHostAddress]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = GRPCTransportTypeInsecure; + + _service = [[RTGRouteGuide alloc] initWithHost:kHostAddress callOptions:options]; } - (void)viewDidAppear:(BOOL)animated { @@ -250,7 +303,7 @@ static NSString * const kHostAddress = @"localhost:50051"; * Run the routeChat demo. Send some chat messages, and print any chat messages that are sent from * the server. */ -@interface RouteChatViewController : UIViewController +@interface RouteChatViewController : UIViewController @property (weak, nonatomic) IBOutlet UILabel *outputLabel; @@ -260,38 +313,52 @@ static NSString * const kHostAddress = @"localhost:50051"; RTGRouteGuide *_service; } +- (dispatch_queue_t)dispatchQueue { + return dispatch_get_main_queue(); +} + - (void)execRequest { NSArray *notes = @[[RTGRouteNote noteWithMessage:@"First message" latitude:0 longitude:0], [RTGRouteNote noteWithMessage:@"Second message" latitude:0 longitude:1], [RTGRouteNote noteWithMessage:@"Third message" latitude:1 longitude:0], [RTGRouteNote noteWithMessage:@"Fourth message" latitude:0 longitude:0]]; - GRXWriter *notesWriter = [[GRXWriter writerWithContainer:notes] map:^id(RTGRouteNote *note) { - NSLog(@"Sending message %@ at %@", note.message, note.location); - return note; - }]; - [_service routeChatWithRequestsWriter:notesWriter - eventHandler:^(BOOL done, RTGRouteNote *note, NSError *error) { - if (note) { - NSString *str =[NSString stringWithFormat:@"%@\nGot message %@ at %@", - self.outputLabel.text, note.message, note.location]; - self.outputLabel.text = str; - NSLog(@"Got message %@ at %@", note.message, note.location); - } else if (error) { - NSString *str =[NSString stringWithFormat:@"%@\nRPC error: %@", self.outputLabel.text, error]; - self.outputLabel.text = str; - NSLog(@"RPC error: %@", error); - } - if (done) { - NSLog(@"Chat ended."); - } - }]; + GRPCStreamingProtoCall *call = [_service routeChatWithResponseHandler:self + callOptions:nil]; + [call start]; + for (RTGRouteNote *note in notes) { + [call writeMessage:note]; + } + [call finish]; +} + +- (void)didReceiveProtoMessage:(GPBMessage *)message { + RTGRouteNote *note = (RTGRouteNote *)message; + if (note) { + NSString *str =[NSString stringWithFormat:@"%@\nGot message %@ at %@", + self.outputLabel.text, note.message, note.location]; + self.outputLabel.text = str; + NSLog(@"Got message %@ at %@", note.message, note.location); + } +} + +- (void)didCloseWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { + if (!error) { + NSLog(@"Chat ended."); + } else { + NSString *str =[NSString stringWithFormat:@"%@\nRPC error: %@", self.outputLabel.text, error]; + self.outputLabel.text = str; + NSLog(@"RPC error: %@", error); + } } - (void)viewDidLoad { [super viewDidLoad]; - _service = [[RTGRouteGuide alloc] initWithHost:kHostAddress]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = GRPCTransportTypeInsecure; + + _service = [[RTGRouteGuide alloc] initWithHost:kHostAddress callOptions:options]; } - (void)viewDidAppear:(BOOL)animated { diff --git a/examples/protos/keyvaluestore.proto b/examples/protos/keyvaluestore.proto new file mode 100644 index 00000000000..74ad57e0297 --- /dev/null +++ b/examples/protos/keyvaluestore.proto @@ -0,0 +1,33 @@ +// 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 keyvaluestore; + +// A simple key-value storage service +service KeyValueStore { + // Provides a value for each key request + rpc GetValues (stream Request) returns (stream Response) {} +} + +// The request message containing the key +message Request { + string key = 1; +} + +// The response message containing the value associated with the key +message Response { + string value = 1; +} diff --git a/examples/python/errors/BUILD.bazel b/examples/python/errors/BUILD.bazel new file mode 100644 index 00000000000..b07dd12ebd3 --- /dev/null +++ b/examples/python/errors/BUILD.bazel @@ -0,0 +1,56 @@ +# Copyright 2019 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. +# 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. + +load("@grpc_python_dependencies//:requirements.bzl", "requirement") + +py_library( + name = "client", + testonly = 1, + srcs = ["client.py"], + deps = [ + "//src/python/grpcio/grpc:grpcio", + "//src/python/grpcio_status/grpc_status:grpc_status", + "//examples:py_helloworld", + requirement('googleapis-common-protos'), + ], +) + +py_library( + name = "server", + testonly = 1, + srcs = ["server.py"], + deps = [ + "//src/python/grpcio/grpc:grpcio", + "//src/python/grpcio_status/grpc_status:grpc_status", + "//examples:py_helloworld", + ] + select({ + "//conditions:default": [requirement("futures")], + "//:python3": [], + }), +) + +py_test( + name = "test/_error_handling_example_test", + srcs = ["test/_error_handling_example_test.py"], + deps = [ + ":client", + ":server", + "//src/python/grpcio_tests/tests:bazel_namespace_package_hack", + ], + size = "small", + imports = [ + "../../../src/python/grpcio_status", + "../../../src/python/grpcio_tests", + ], +) diff --git a/examples/python/errors/README.md b/examples/python/errors/README.md new file mode 100644 index 00000000000..2cfc26a93b0 --- /dev/null +++ b/examples/python/errors/README.md @@ -0,0 +1,107 @@ +# gRPC Python Error Handling Example + +The goal of this example is sending error status from server that is more complicated than a code and detail string. + +The definition for an RPC method in proto files contains request message and response message. There are many error states that can be shared across RPC methods (e.g. stack trace, insufficient quota). Using a different path to handle error will make the code more maintainable. + +Ideally, the final status of an RPC should be described in the trailing headers of HTTP2, and gRPC Python provides helper functions in `grpcio-status` package to assist the packing and unpacking of error status. + + +### Requirement +``` +grpcio>=1.18.0 +grpcio-status>=1.18.0 +googleapis-common-protos>=1.5.5 +``` + + +### Error Detail Proto + +You may provide any custom proto message as error detail in your implementation. Here are protos are defined by Google Cloud Library Team: + +* [code.proto]([https://github.com/googleapis/api-common-protos/blob/master/google/rpc/code.proto](https://github.com/googleapis/api-common-protos/blob/87185dfffad4afa5a33a8c153f0e1ea53b4f85dc/google/rpc/code.proto)) contains definition of RPC error codes. +* [error_details.proto]([https://github.com/googleapis/api-common-protos/blob/master/google/rpc/error_details.proto](https://github.com/googleapis/api-common-protos/blob/87185dfffad4afa5a33a8c153f0e1ea53b4f85dc/google/rpc/error_details.proto)) contains definitions of common error details. + + +### Definition of Status Proto + +Here is the definition of Status proto. For full text, please see [status.proto](https://github.com/googleapis/api-common-protos/blob/87185dfffad4afa5a33a8c153f0e1ea53b4f85dc/google/rpc/status.proto). + +```proto +// The `Status` type defines a logical error model that is suitable for different +// programming environments, including REST APIs and RPC APIs. It is used by +// [gRPC](https://github.com/grpc). The error model is designed to be: +// +// - Simple to use and understand for most users +// - Flexible enough to meet unexpected needs +// +// # Overview +// +// The `Status` message contains three pieces of data: error code, error message, +// and error details. The error code should be an enum value of +// [google.rpc.Code][google.rpc.Code], but it may accept additional error codes if needed. The +// error message should be a developer-facing English message that helps +// developers *understand* and *resolve* the error. If a localized user-facing +// error message is needed, put the localized message in the error details or +// localize it in the client. The optional error details may contain arbitrary +// information about the error. There is a predefined set of error detail types +// in the package `google.rpc` that can be used for common error conditions. +// +// # Language mapping +// +// The `Status` message is the logical representation of the error model, but it +// is not necessarily the actual wire format. When the `Status` message is +// exposed in different client libraries and different wire protocols, it can be +// mapped differently. For example, it will likely be mapped to some exceptions +// in Java, but more likely mapped to some error codes in C. +// +// # Other uses +// +// The error model and the `Status` message can be used in a variety of +// environments, either with or without APIs, to provide a +// consistent developer experience across different environments. +// +// Example uses of this error model include: +// +// - Partial errors. If a service needs to return partial errors to the client, +// it may embed the `Status` in the normal response to indicate the partial +// errors. +// +// - Workflow errors. A typical workflow has multiple steps. Each step may +// have a `Status` message for error reporting. +// +// - Batch operations. If a client uses batch request and batch response, the +// `Status` message should be used directly inside batch response, one for +// each error sub-response. +// +// - Asynchronous operations. If an API call embeds asynchronous operation +// results in its response, the status of those operations should be +// represented directly using the `Status` message. +// +// - Logging. If some API errors are stored in logs, the message `Status` could +// be used directly after any stripping needed for security/privacy reasons. +message Status { + // The status code, which should be an enum value of [google.rpc.Code][google.rpc.Code]. + int32 code = 1; + + // A developer-facing error message, which should be in English. Any + // user-facing error message should be localized and sent in the + // [google.rpc.Status.details][google.rpc.Status.details] field, or localized by the client. + string message = 2; + + // A list of messages that carry the error details. There is a common set of + // message types for APIs to use. + repeated google.protobuf.Any details = 3; +} +``` + + +### Usage of Well-Known-Proto `Any` + +Please check [ProtoBuf Document: Any](https://developers.google.com/protocol-buffers/docs/reference/python-generated#any) + +```Python +any_message.Pack(message) +any_message.Unpack(message) +assert any_message.Is(message.DESCRIPTOR) +``` diff --git a/examples/python/errors/client.py b/examples/python/errors/client.py new file mode 100644 index 00000000000..c762d798dc2 --- /dev/null +++ b/examples/python/errors/client.py @@ -0,0 +1,56 @@ +# Copyright 2019 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. +# 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 example handles rich error status in client-side.""" + +from __future__ import print_function +import logging + +import grpc +from grpc_status import rpc_status +from google.rpc import error_details_pb2 + +from examples import helloworld_pb2 +from examples import helloworld_pb2_grpc + +_LOGGER = logging.getLogger(__name__) + + +def process(stub): + try: + response = stub.SayHello(helloworld_pb2.HelloRequest(name='Alice')) + _LOGGER.info('Call success: %s', response.message) + except grpc.RpcError as rpc_error: + _LOGGER.error('Call failure: %s', rpc_error) + status = rpc_status.from_call(rpc_error) + for detail in status.details: + if detail.Is(error_details_pb2.QuotaFailure.DESCRIPTOR): + info = error_details_pb2.QuotaFailure() + detail.Unpack(info) + _LOGGER.error('Quota failure: %s', info) + else: + raise RuntimeError('Unexpected failure: %s' % detail) + + +def main(): + # NOTE(gRPC Python Team): .close() is possible on a channel and should be + # used in circumstances in which the with statement does not fit the needs + # of the code. + with grpc.insecure_channel('localhost:50051') as channel: + stub = helloworld_pb2_grpc.GreeterStub(channel) + process(stub) + + +if __name__ == '__main__': + logging.basicConfig() + main() diff --git a/examples/python/errors/server.py b/examples/python/errors/server.py new file mode 100644 index 00000000000..50d4a2ac671 --- /dev/null +++ b/examples/python/errors/server.py @@ -0,0 +1,90 @@ +# Copyright 2019 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. +# 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 example sends out rich error status from server-side.""" + +from concurrent import futures +import time +import logging +import threading + +import grpc +from grpc_status import rpc_status + +from google.protobuf import any_pb2 +from google.rpc import code_pb2, status_pb2, error_details_pb2 + +from examples import helloworld_pb2 +from examples import helloworld_pb2_grpc + +_ONE_DAY_IN_SECONDS = 60 * 60 * 24 + + +def create_greet_limit_exceed_error_status(name): + detail = any_pb2.Any() + detail.Pack( + error_details_pb2.QuotaFailure( + violations=[ + error_details_pb2.QuotaFailure.Violation( + subject="name: %s" % name, + description="Limit one greeting per person", + ) + ],)) + return status_pb2.Status( + code=code_pb2.RESOURCE_EXHAUSTED, + message='Request limit exceeded.', + details=[detail], + ) + + +class LimitedGreeter(helloworld_pb2_grpc.GreeterServicer): + + def __init__(self): + self._lock = threading.RLock() + self._greeted = set() + + def SayHello(self, request, context): + with self._lock: + if request.name in self._greeted: + rich_status = create_greet_limit_exceed_error_status( + request.name) + context.abort_with_status(rpc_status.to_status(rich_status)) + else: + self._greeted.add(request.name) + return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name) + + +def create_server(server_address): + server = grpc.server(futures.ThreadPoolExecutor()) + helloworld_pb2_grpc.add_GreeterServicer_to_server(LimitedGreeter(), server) + port = server.add_insecure_port(server_address) + return server, port + + +def serve(server): + server.start() + try: + while True: + time.sleep(_ONE_DAY_IN_SECONDS) + except KeyboardInterrupt: + server.stop(None) + + +def main(): + server, unused_port = create_server('[::]:50051') + serve(server) + + +if __name__ == '__main__': + logging.basicConfig() + main() diff --git a/examples/python/errors/test/_error_handling_example_test.py b/examples/python/errors/test/_error_handling_example_test.py new file mode 100644 index 00000000000..9eb81ba3742 --- /dev/null +++ b/examples/python/errors/test/_error_handling_example_test.py @@ -0,0 +1,54 @@ +# Copyright 2019 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. +# 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 of the error handling example.""" + +# NOTE(lidiz) This module only exists in Bazel BUILD file, for more details +# please refer to comments in the "bazel_namespace_package_hack" module. +try: + from tests import bazel_namespace_package_hack + bazel_namespace_package_hack.sys_path_to_site_dir_hack() +except ImportError: + pass + +import unittest +import logging + +import grpc + +from examples import helloworld_pb2_grpc +from examples.python.errors import client as error_handling_client +from examples.python.errors import server as error_handling_server + + +class ErrorHandlingExampleTest(unittest.TestCase): + + def setUp(self): + self._server, port = error_handling_server.create_server('[::]:0') + self._server.start() + self._channel = grpc.insecure_channel('localhost:%d' % port) + + def tearDown(self): + self._channel.close() + self._server.stop(None) + + def test_error_handling_example(self): + stub = helloworld_pb2_grpc.GreeterStub(self._channel) + error_handling_client.process(stub) + error_handling_client.process(stub) + # No unhandled exception raised, test passed! + + +if __name__ == '__main__': + logging.basicConfig() + unittest.main(verbosity=2) diff --git a/examples/python/helloworld/greeter_client.py b/examples/python/helloworld/greeter_client.py index 24b49ac2336..ee2032a9e6e 100644 --- a/examples/python/helloworld/greeter_client.py +++ b/examples/python/helloworld/greeter_client.py @@ -14,6 +14,7 @@ """The Python implementation of the GRPC helloworld.Greeter client.""" from __future__ import print_function +import logging import grpc @@ -32,4 +33,5 @@ def run(): if __name__ == '__main__': + logging.basicConfig() run() diff --git a/examples/python/helloworld/greeter_client_with_options.py b/examples/python/helloworld/greeter_client_with_options.py index 7eda8c9066f..e9ab5508ddd 100644 --- a/examples/python/helloworld/greeter_client_with_options.py +++ b/examples/python/helloworld/greeter_client_with_options.py @@ -11,9 +11,10 @@ # 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. -"""The Python implementation of the GRPC helloworld.Greeter client with channel options and call timeout parameters.""" +"""gRPC Python helloworld.Greeter client with channel options and call timeout parameters.""" from __future__ import print_function +import logging import grpc @@ -41,4 +42,5 @@ def run(): if __name__ == '__main__': + logging.basicConfig() run() diff --git a/examples/python/helloworld/greeter_server.py b/examples/python/helloworld/greeter_server.py index c355662ef86..e3b4f2c1ff9 100644 --- a/examples/python/helloworld/greeter_server.py +++ b/examples/python/helloworld/greeter_server.py @@ -15,6 +15,7 @@ from concurrent import futures import time +import logging import grpc @@ -43,4 +44,5 @@ def serve(): if __name__ == '__main__': + logging.basicConfig() serve() diff --git a/examples/python/helloworld/greeter_server_with_reflection.py b/examples/python/helloworld/greeter_server_with_reflection.py index 5ba8782dfca..5acedbcb71f 100644 --- a/examples/python/helloworld/greeter_server_with_reflection.py +++ b/examples/python/helloworld/greeter_server_with_reflection.py @@ -15,6 +15,7 @@ from concurrent import futures import time +import logging import grpc from grpc_reflection.v1alpha import reflection @@ -49,4 +50,5 @@ def serve(): if __name__ == '__main__': + logging.basicConfig() serve() diff --git a/examples/python/interceptors/default_value/greeter_client.py b/examples/python/interceptors/default_value/greeter_client.py index da21ac68ec5..25834c2bbdd 100644 --- a/examples/python/interceptors/default_value/greeter_client.py +++ b/examples/python/interceptors/default_value/greeter_client.py @@ -14,6 +14,7 @@ """The Python implementation of the gRPC helloworld.Greeter client.""" from __future__ import print_function +import logging import grpc @@ -39,4 +40,5 @@ def run(): if __name__ == '__main__': + logging.basicConfig() run() diff --git a/examples/python/interceptors/headers/greeter_client.py b/examples/python/interceptors/headers/greeter_client.py index 6a09a3b9c50..712539850d3 100644 --- a/examples/python/interceptors/headers/greeter_client.py +++ b/examples/python/interceptors/headers/greeter_client.py @@ -14,6 +14,7 @@ """The Python implementation of the GRPC helloworld.Greeter client.""" from __future__ import print_function +import logging import grpc @@ -37,4 +38,5 @@ def run(): if __name__ == '__main__': + logging.basicConfig() run() diff --git a/examples/python/interceptors/headers/greeter_server.py b/examples/python/interceptors/headers/greeter_server.py index 01968609b53..6b0f4058bcd 100644 --- a/examples/python/interceptors/headers/greeter_server.py +++ b/examples/python/interceptors/headers/greeter_server.py @@ -15,6 +15,7 @@ from concurrent import futures import time +import logging import grpc @@ -49,4 +50,5 @@ def serve(): if __name__ == '__main__': + logging.basicConfig() serve() diff --git a/examples/python/metadata/README.md b/examples/python/metadata/README.md new file mode 100644 index 00000000000..5aa75d504a8 --- /dev/null +++ b/examples/python/metadata/README.md @@ -0,0 +1,6 @@ +An example showing how to add custom HTTP2 headers (or [metadata](https://grpc.io/grpc/python/glossary.html) in gRPC glossary) + +HTTP2 supports initial headers and trailing headers, which gRPC utilizes both of them ([learn more](https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md)). + +More complete documentation lives at [grpc.io](https://grpc.io/docs/tutorials/basic/python.html). +For API reference please see [API](https://grpc.io/grpc/python/grpc.html). diff --git a/examples/python/metadata/helloworld_pb2.py b/examples/python/metadata/helloworld_pb2.py new file mode 100644 index 00000000000..e18ab9acc7a --- /dev/null +++ b/examples/python/metadata/helloworld_pb2.py @@ -0,0 +1,134 @@ +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: helloworld.proto + +import sys +_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database +from google.protobuf import descriptor_pb2 +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor.FileDescriptor( + name='helloworld.proto', + package='helloworld', + syntax='proto3', + serialized_pb=_b('\n\x10helloworld.proto\x12\nhelloworld\"\x1c\n\x0cHelloRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\"\x1d\n\nHelloReply\x12\x0f\n\x07message\x18\x01 \x01(\t2I\n\x07Greeter\x12>\n\x08SayHello\x12\x18.helloworld.HelloRequest\x1a\x16.helloworld.HelloReply\"\x00\x42\x36\n\x1bio.grpc.examples.helloworldB\x0fHelloWorldProtoP\x01\xa2\x02\x03HLWb\x06proto3') +) + + + + +_HELLOREQUEST = _descriptor.Descriptor( + name='HelloRequest', + full_name='helloworld.HelloRequest', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='name', full_name='helloworld.HelloRequest.name', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=32, + serialized_end=60, +) + + +_HELLOREPLY = _descriptor.Descriptor( + name='HelloReply', + full_name='helloworld.HelloReply', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='message', full_name='helloworld.HelloReply.message', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=62, + serialized_end=91, +) + +DESCRIPTOR.message_types_by_name['HelloRequest'] = _HELLOREQUEST +DESCRIPTOR.message_types_by_name['HelloReply'] = _HELLOREPLY +_sym_db.RegisterFileDescriptor(DESCRIPTOR) + +HelloRequest = _reflection.GeneratedProtocolMessageType('HelloRequest', (_message.Message,), dict( + DESCRIPTOR = _HELLOREQUEST, + __module__ = 'helloworld_pb2' + # @@protoc_insertion_point(class_scope:helloworld.HelloRequest) + )) +_sym_db.RegisterMessage(HelloRequest) + +HelloReply = _reflection.GeneratedProtocolMessageType('HelloReply', (_message.Message,), dict( + DESCRIPTOR = _HELLOREPLY, + __module__ = 'helloworld_pb2' + # @@protoc_insertion_point(class_scope:helloworld.HelloReply) + )) +_sym_db.RegisterMessage(HelloReply) + + +DESCRIPTOR.has_options = True +DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\033io.grpc.examples.helloworldB\017HelloWorldProtoP\001\242\002\003HLW')) + +_GREETER = _descriptor.ServiceDescriptor( + name='Greeter', + full_name='helloworld.Greeter', + file=DESCRIPTOR, + index=0, + options=None, + serialized_start=93, + serialized_end=166, + methods=[ + _descriptor.MethodDescriptor( + name='SayHello', + full_name='helloworld.Greeter.SayHello', + index=0, + containing_service=None, + input_type=_HELLOREQUEST, + output_type=_HELLOREPLY, + options=None, + ), +]) +_sym_db.RegisterServiceDescriptor(_GREETER) + +DESCRIPTOR.services_by_name['Greeter'] = _GREETER + +# @@protoc_insertion_point(module_scope) diff --git a/examples/python/metadata/helloworld_pb2_grpc.py b/examples/python/metadata/helloworld_pb2_grpc.py new file mode 100644 index 00000000000..18e07d16797 --- /dev/null +++ b/examples/python/metadata/helloworld_pb2_grpc.py @@ -0,0 +1,46 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +import grpc + +import helloworld_pb2 as helloworld__pb2 + + +class GreeterStub(object): + """The greeting service definition. + """ + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.SayHello = channel.unary_unary( + '/helloworld.Greeter/SayHello', + request_serializer=helloworld__pb2.HelloRequest.SerializeToString, + response_deserializer=helloworld__pb2.HelloReply.FromString, + ) + + +class GreeterServicer(object): + """The greeting service definition. + """ + + def SayHello(self, request, context): + """Sends a greeting + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + +def add_GreeterServicer_to_server(servicer, server): + rpc_method_handlers = { + 'SayHello': grpc.unary_unary_rpc_method_handler( + servicer.SayHello, + request_deserializer=helloworld__pb2.HelloRequest.FromString, + response_serializer=helloworld__pb2.HelloReply.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + 'helloworld.Greeter', rpc_method_handlers) + server.add_generic_rpc_handlers((generic_handler,)) diff --git a/examples/python/metadata/metadata_client.py b/examples/python/metadata/metadata_client.py new file mode 100644 index 00000000000..f2a8e37cc21 --- /dev/null +++ b/examples/python/metadata/metadata_client.py @@ -0,0 +1,48 @@ +# Copyright 2018 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. +# 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. +"""Example gRPC client that gets/sets metadata (HTTP2 headers)""" + +from __future__ import print_function +import logging + +import grpc + +import helloworld_pb2 +import helloworld_pb2_grpc + + +def run(): + # NOTE(gRPC Python Team): .close() is possible on a channel and should be + # used in circumstances in which the with statement does not fit the needs + # of the code. + with grpc.insecure_channel('localhost:50051') as channel: + stub = helloworld_pb2_grpc.GreeterStub(channel) + response, call = stub.SayHello.with_call( + helloworld_pb2.HelloRequest(name='you'), + metadata=( + ('initial-metadata-1', 'The value should be str'), + ('binary-metadata-bin', + b'With -bin surffix, the value can be bytes'), + ('accesstoken', 'gRPC Python is great'), + )) + + print("Greeter client received: " + response.message) + for key, value in call.trailing_metadata(): + print('Greeter client received trailing metadata: key=%s value=%s' % + (key, value)) + + +if __name__ == '__main__': + logging.basicConfig() + run() diff --git a/examples/python/metadata/metadata_server.py b/examples/python/metadata/metadata_server.py new file mode 100644 index 00000000000..a4329df79aa --- /dev/null +++ b/examples/python/metadata/metadata_server.py @@ -0,0 +1,56 @@ +# Copyright 2018 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. +# 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. +"""Example gRPC server that gets/sets metadata (HTTP2 headers)""" + +from __future__ import print_function +from concurrent import futures +import time +import logging + +import grpc + +import helloworld_pb2 +import helloworld_pb2_grpc + +_ONE_DAY_IN_SECONDS = 60 * 60 * 24 + + +class Greeter(helloworld_pb2_grpc.GreeterServicer): + + def SayHello(self, request, context): + for key, value in context.invocation_metadata(): + print('Received initial metadata: key=%s value=%s' % (key, value)) + + context.set_trailing_metadata(( + ('checksum-bin', b'I agree'), + ('retry', 'false'), + )) + return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name) + + +def serve(): + server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) + helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server) + server.add_insecure_port('[::]:50051') + server.start() + try: + while True: + time.sleep(_ONE_DAY_IN_SECONDS) + except KeyboardInterrupt: + server.stop(0) + + +if __name__ == '__main__': + logging.basicConfig() + serve() diff --git a/examples/python/multiplex/multiplex_client.py b/examples/python/multiplex/multiplex_client.py index 19d39ce66eb..155f85c4b0c 100644 --- a/examples/python/multiplex/multiplex_client.py +++ b/examples/python/multiplex/multiplex_client.py @@ -17,6 +17,7 @@ from __future__ import print_function import random import time +import logging import grpc @@ -126,4 +127,5 @@ def run(): if __name__ == '__main__': + logging.basicConfig() run() diff --git a/examples/python/multiplex/multiplex_server.py b/examples/python/multiplex/multiplex_server.py index 70dec3c9390..c01824b3a97 100644 --- a/examples/python/multiplex/multiplex_server.py +++ b/examples/python/multiplex/multiplex_server.py @@ -16,6 +16,7 @@ from concurrent import futures import time import math +import logging import grpc @@ -136,4 +137,5 @@ def serve(): if __name__ == '__main__': + logging.basicConfig() serve() diff --git a/examples/python/multiprocessing/BUILD b/examples/python/multiprocessing/BUILD new file mode 100644 index 00000000000..0e135f471f2 --- /dev/null +++ b/examples/python/multiprocessing/BUILD @@ -0,0 +1,64 @@ +# gRPC Bazel BUILD file. +# +# Copyright 2019 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. +# 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. + +load("@grpc_python_dependencies//:requirements.bzl", "requirement") +load("//bazel:python_rules.bzl", "py_proto_library") + +proto_library( + name = "prime_proto", + srcs = ["prime.proto"] +) + +py_proto_library( + name = "prime_proto_pb2", + deps = [":prime_proto"], + well_known_protos = False, +) + +py_binary( + name = "client", + testonly = 1, + srcs = ["client.py"], + deps = [ + "//src/python/grpcio/grpc:grpcio", + ":prime_proto_pb2", + ], + default_python_version = "PY3", +) + +py_binary( + name = "server", + testonly = 1, + srcs = ["server.py"], + deps = [ + "//src/python/grpcio/grpc:grpcio", + ":prime_proto_pb2" + ] + select({ + "//conditions:default": [requirement("futures")], + "//:python3": [], + }), + default_python_version = "PY3", +) + +py_test( + name = "test/_multiprocessing_example_test", + srcs = ["test/_multiprocessing_example_test.py"], + data = [ + ":client", + ":server" + ], + size = "small", +) diff --git a/examples/python/multiprocessing/README.md b/examples/python/multiprocessing/README.md new file mode 100644 index 00000000000..709a815aca5 --- /dev/null +++ b/examples/python/multiprocessing/README.md @@ -0,0 +1,67 @@ +## Multiprocessing with gRPC Python + +Multiprocessing allows application developers to sidestep the Python global +interpreter lock and achieve true concurrency on multicore systems. +Unfortunately, using multiprocessing and gRPC Python is not yet as simple as +instantiating your server with a `futures.ProcessPoolExecutor`. + +The library is implemented as a C extension, maintaining much of the state that +drives the system in native code. As such, upon calling +[`fork`](http://man7.org/linux/man-pages/man2/fork.2.html), much of the +state copied into the child process is invalid, leading to hangs and crashes. + +However, calling `fork` without `exec` in your python process is supported +*before* any gRPC servers have been instantiated. Application developers can +take advantage of this to parallelize their CPU-intensive operations. + +## Calculating Prime Numbers with Multiple Processes + +This example calculates the first 10,000 prime numbers as an RPC. We instantiate +one server per subprocess, balancing requests between the servers using the +[`SO_REUSEPORT`](https://lwn.net/Articles/542629/) socket option. Note that this +option is not available in `manylinux1` distributions, which are, as of the time +of writing, the only gRPC Python wheels available on PyPI. To take advantage of this +feature, you'll need to build from source, either using bazel (as we do for +these examples) or via pip, using `pip install grpcio --no-binary grpcio`. + +```python +_PROCESS_COUNT = multiprocessing.cpu_count() +``` + +On the server side, we detect the number of CPUs available on the system and +spawn exactly that many child processes. If we spin up fewer, we won't be taking +full advantage of the hardware resources available. + +## Running the Example + +To run the server, +[ensure `bazel` is installed](https://docs.bazel.build/versions/master/install.html) +and run: + +``` +bazel run //examples/python/multiprocessing:server & +``` + +Note the address at which the server is running. For example, + +``` +... +[PID 107153] Binding to '[::]:33915' +[PID 107507] Starting new server. +[PID 107508] Starting new server. +... +``` + +Note that several servers have been started, each with its own PID. + +Now, start the client by running + +``` +bazel run //examples/python/multiprocessing:client -- [SERVER_ADDRESS] +``` + +For example, + +``` +bazel run //examples/python/multiprocessing:client -- [::]:33915 +``` diff --git a/examples/python/multiprocessing/client.py b/examples/python/multiprocessing/client.py new file mode 100644 index 00000000000..6d3bf5d825a --- /dev/null +++ b/examples/python/multiprocessing/client.py @@ -0,0 +1,95 @@ +# Copyright 2019 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 example of multiprocessing concurrency with gRPC.""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import argparse +import atexit +import logging +import multiprocessing +import operator +import sys + +import grpc + +from examples.python.multiprocessing import prime_pb2 +from examples.python.multiprocessing import prime_pb2_grpc + +_PROCESS_COUNT = 8 +_MAXIMUM_CANDIDATE = 10000 + +# Each worker process initializes a single channel after forking. +# It's regrettable, but to ensure that each subprocess only has to instantiate +# a single channel to be reused across all RPCs, we use globals. +_worker_channel_singleton = None +_worker_stub_singleton = None + +_LOGGER = logging.getLogger(__name__) + + +def _shutdown_worker(): + _LOGGER.info('Shutting worker process down.') + if _worker_channel_singleton is not None: + _worker_channel_singleton.stop() + + +def _initialize_worker(server_address): + global _worker_channel_singleton # pylint: disable=global-statement + global _worker_stub_singleton # pylint: disable=global-statement + _LOGGER.info('Initializing worker process.') + _worker_channel_singleton = grpc.insecure_channel(server_address) + _worker_stub_singleton = prime_pb2_grpc.PrimeCheckerStub( + _worker_channel_singleton) + atexit.register(_shutdown_worker) + + +def _run_worker_query(primality_candidate): + _LOGGER.info('Checking primality of %s.', primality_candidate) + return _worker_stub_singleton.check( + prime_pb2.PrimeCandidate(candidate=primality_candidate)) + + +def _calculate_primes(server_address): + worker_pool = multiprocessing.Pool( + processes=_PROCESS_COUNT, + initializer=_initialize_worker, + initargs=(server_address,)) + check_range = range(2, _MAXIMUM_CANDIDATE) + primality = worker_pool.map(_run_worker_query, check_range) + primes = zip(check_range, map(operator.attrgetter('isPrime'), primality)) + return tuple(primes) + + +def main(): + msg = 'Determine the primality of the first {} integers.'.format( + _MAXIMUM_CANDIDATE) + parser = argparse.ArgumentParser(description=msg) + parser.add_argument( + 'server_address', + help='The address of the server (e.g. localhost:50051)') + args = parser.parse_args() + primes = _calculate_primes(args.server_address) + print(primes) + + +if __name__ == '__main__': + handler = logging.StreamHandler(sys.stdout) + formatter = logging.Formatter('[PID %(process)d] %(message)s') + handler.setFormatter(formatter) + _LOGGER.addHandler(handler) + _LOGGER.setLevel(logging.INFO) + main() diff --git a/examples/python/multiprocessing/prime.proto b/examples/python/multiprocessing/prime.proto new file mode 100644 index 00000000000..4ef232f86cb --- /dev/null +++ b/examples/python/multiprocessing/prime.proto @@ -0,0 +1,35 @@ +// Copyright 2019 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 prime; + +// A candidate integer for primality testing. +message PrimeCandidate { + // The candidate. + int64 candidate = 1; +} + +// The primality of the requested integer candidate. +message Primality { + // Is the candidate prime? + bool isPrime = 1; +} + +// Service to check primality. +service PrimeChecker { + // Determines the primality of an integer. + rpc check (PrimeCandidate) returns (Primality) {} +} diff --git a/examples/python/multiprocessing/server.py b/examples/python/multiprocessing/server.py new file mode 100644 index 00000000000..a05eb9edda0 --- /dev/null +++ b/examples/python/multiprocessing/server.py @@ -0,0 +1,123 @@ +# Copyright 2019 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 example of multiprocess concurrency with gRPC.""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +from concurrent import futures +import contextlib +import datetime +import logging +import math +import multiprocessing +import time +import socket +import sys + +import grpc + +from examples.python.multiprocessing import prime_pb2 +from examples.python.multiprocessing import prime_pb2_grpc + +_LOGGER = logging.getLogger(__name__) + +_ONE_DAY = datetime.timedelta(days=1) +_PROCESS_COUNT = multiprocessing.cpu_count() +_THREAD_CONCURRENCY = _PROCESS_COUNT + + +def is_prime(n): + for i in range(2, int(math.ceil(math.sqrt(n)))): + if n % i == 0: + return False + else: + return True + + +class PrimeChecker(prime_pb2_grpc.PrimeCheckerServicer): + + def check(self, request, context): + _LOGGER.info('Determining primality of %s', request.candidate) + return prime_pb2.Primality(isPrime=is_prime(request.candidate)) + + +def _wait_forever(server): + try: + while True: + time.sleep(_ONE_DAY.total_seconds()) + except KeyboardInterrupt: + server.stop(None) + + +def _run_server(bind_address): + """Start a server in a subprocess.""" + _LOGGER.info('Starting new server.') + options = (('grpc.so_reuseport', 1),) + + # WARNING: This example takes advantage of SO_REUSEPORT. Due to the + # limitations of manylinux1, none of our precompiled Linux wheels currently + # support this option. (https://github.com/grpc/grpc/issues/18210). To take + # advantage of this feature, install from source with + # `pip install grpcio --no-binary grpcio`. + + server = grpc.server( + futures.ThreadPoolExecutor(max_workers=_THREAD_CONCURRENCY,), + options=options) + prime_pb2_grpc.add_PrimeCheckerServicer_to_server(PrimeChecker(), server) + server.add_insecure_port(bind_address) + server.start() + _wait_forever(server) + + +@contextlib.contextmanager +def _reserve_port(): + """Find and reserve a port for all subprocesses to use.""" + sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM) + sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) + if sock.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT) != 1: + raise RuntimeError("Failed to set SO_REUSEPORT.") + sock.bind(('', 0)) + try: + yield sock.getsockname()[1] + finally: + sock.close() + + +def main(): + with _reserve_port() as port: + bind_address = 'localhost:{}'.format(port) + _LOGGER.info("Binding to '%s'", bind_address) + sys.stdout.flush() + workers = [] + for _ in range(_PROCESS_COUNT): + # NOTE: It is imperative that the worker subprocesses be forked before + # any gRPC servers start up. See + # https://github.com/grpc/grpc/issues/16001 for more details. + worker = multiprocessing.Process( + target=_run_server, args=(bind_address,)) + worker.start() + workers.append(worker) + for worker in workers: + worker.join() + + +if __name__ == '__main__': + handler = logging.StreamHandler(sys.stdout) + formatter = logging.Formatter('[PID %(process)d] %(message)s') + handler.setFormatter(formatter) + _LOGGER.addHandler(handler) + _LOGGER.setLevel(logging.INFO) + main() diff --git a/examples/python/multiprocessing/test/_multiprocessing_example_test.py b/examples/python/multiprocessing/test/_multiprocessing_example_test.py new file mode 100644 index 00000000000..2d8f8d49db4 --- /dev/null +++ b/examples/python/multiprocessing/test/_multiprocessing_example_test.py @@ -0,0 +1,74 @@ +# Copyright 2019 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. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Test for multiprocessing example.""" + +import ast +import logging +import math +import os +import re +import subprocess +import tempfile +import unittest + +_BINARY_DIR = os.path.realpath( + os.path.join(os.path.dirname(os.path.abspath(__file__)), '..')) +_SERVER_PATH = os.path.join(_BINARY_DIR, 'server') +_CLIENT_PATH = os.path.join(_BINARY_DIR, 'client') + + +def is_prime(n): + for i in range(2, int(math.ceil(math.sqrt(n)))): + if n % i == 0: + return False + else: + return True + + +def _get_server_address(server_stream): + while True: + server_stream.seek(0) + line = server_stream.readline() + while line: + matches = re.search('Binding to \'(.+)\'', line) + if matches is not None: + return matches.groups()[0] + line = server_stream.readline() + + +class MultiprocessingExampleTest(unittest.TestCase): + + def test_multiprocessing_example(self): + server_stdout = tempfile.TemporaryFile(mode='r') + server_process = subprocess.Popen((_SERVER_PATH,), stdout=server_stdout) + server_address = _get_server_address(server_stdout) + client_stdout = tempfile.TemporaryFile(mode='r') + client_process = subprocess.Popen( + ( + _CLIENT_PATH, + server_address, + ), stdout=client_stdout) + client_process.wait() + server_process.terminate() + client_stdout.seek(0) + results = ast.literal_eval(client_stdout.read().strip().split('\n')[-1]) + values = tuple(result[0] for result in results) + self.assertSequenceEqual(range(2, 10000), values) + for result in results: + self.assertEqual(is_prime(result[0]), result[1]) + + +if __name__ == '__main__': + logging.basicConfig() + unittest.main(verbosity=2) diff --git a/examples/python/route_guide/route_guide_client.py b/examples/python/route_guide/route_guide_client.py index b4ff3239ba8..dc93fb44379 100644 --- a/examples/python/route_guide/route_guide_client.py +++ b/examples/python/route_guide/route_guide_client.py @@ -16,6 +16,7 @@ from __future__ import print_function import random +import logging import grpc @@ -116,4 +117,5 @@ def run(): if __name__ == '__main__': + logging.basicConfig() run() diff --git a/examples/python/route_guide/route_guide_server.py b/examples/python/route_guide/route_guide_server.py index 1969fdd378d..e00cb699084 100644 --- a/examples/python/route_guide/route_guide_server.py +++ b/examples/python/route_guide/route_guide_server.py @@ -16,6 +16,7 @@ from concurrent import futures import time import math +import logging import grpc @@ -126,4 +127,5 @@ def serve(): if __name__ == '__main__': + logging.basicConfig() serve() diff --git a/examples/python/wait_for_ready/BUILD.bazel b/examples/python/wait_for_ready/BUILD.bazel new file mode 100644 index 00000000000..70daf83d334 --- /dev/null +++ b/examples/python/wait_for_ready/BUILD.bazel @@ -0,0 +1,32 @@ +# Copyright 2019 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. +# 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. + +load("@grpc_python_dependencies//:requirements.bzl", "requirement") + +py_library( + name = "wait_for_ready_example", + testonly = 1, + srcs = ["wait_for_ready_example.py"], + deps = [ + "//src/python/grpcio/grpc:grpcio", + "//examples:py_helloworld", + ], +) + +py_test( + name = "test/_wait_for_ready_example_test", + srcs = ["test/_wait_for_ready_example_test.py"], + deps = [":wait_for_ready_example",], + size = "small", +) diff --git a/examples/python/wait_for_ready/README.md b/examples/python/wait_for_ready/README.md new file mode 100644 index 00000000000..6e873d2222d --- /dev/null +++ b/examples/python/wait_for_ready/README.md @@ -0,0 +1,32 @@ +# gRPC Python Example for Wait-for-ready + +The default behavior of an RPC is to fail instantly if the server is not ready yet. This example demonstrates how to change that behavior. + + +### Definition of 'wait-for-ready' semantics +> If an RPC is issued but the channel is in TRANSIENT_FAILURE or SHUTDOWN states, the RPC is unable to be transmitted promptly. By default, gRPC implementations SHOULD fail such RPCs immediately. This is known as "fail fast," but the usage of the term is historical. RPCs SHOULD NOT fail as a result of the channel being in other states (CONNECTING, READY, or IDLE). +> +> gRPC implementations MAY provide a per-RPC option to not fail RPCs as a result of the channel being in TRANSIENT_FAILURE state. Instead, the implementation queues the RPCs until the channel is READY. This is known as "wait for ready." The RPCs SHOULD still fail before READY if there are unrelated reasons, such as the channel is SHUTDOWN or the RPC's deadline is reached. +> +> From https://github.com/grpc/grpc/blob/master/doc/wait-for-ready.md + + +### Use cases for 'wait-for-ready' + +When developers spin up gRPC clients and servers at the same time, it is very like to fail first couple RPC calls due to unavailability of the server. If developers failed to prepare for this situation, the result can be catastrophic. But with 'wait-for-ready' semantics, developers can initialize the client and server in any order, especially useful in testing. + +Also, developers may ensure the server is up before starting client. But in some cases like transient network failure may result in a temporary unavailability of the server. With 'wait-for-ready' semantics, those RPC calls will automatically wait until the server is ready to accept incoming requests. + + +### DEMO Snippets + +```Python +# Per RPC level +stub = ...Stub(...) + +stub.important_transaction_1(..., wait_for_ready=True) +stub.unimportant_transaction_2(...) +stub.important_transaction_3(..., wait_for_ready=True) +stub.unimportant_transaction_4(...) +# The unimportant transactions can be status report, or health check, etc. +``` diff --git a/examples/python/wait_for_ready/test/_wait_for_ready_example_test.py b/examples/python/wait_for_ready/test/_wait_for_ready_example_test.py new file mode 100644 index 00000000000..03e83a12c56 --- /dev/null +++ b/examples/python/wait_for_ready/test/_wait_for_ready_example_test.py @@ -0,0 +1,31 @@ +# Copyright 2019 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. +# 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 of the wait-for-ready example.""" + +import unittest +import logging + +from examples.python.wait_for_ready import wait_for_ready_example + + +class WaitForReadyExampleTest(unittest.TestCase): + + def test_wait_for_ready_example(self): + wait_for_ready_example.main() + # No unhandled exception raised, no deadlock, test passed! + + +if __name__ == '__main__': + logging.basicConfig() + unittest.main(verbosity=2) diff --git a/examples/python/wait_for_ready/wait_for_ready_example.py b/examples/python/wait_for_ready/wait_for_ready_example.py new file mode 100644 index 00000000000..a0f076e894a --- /dev/null +++ b/examples/python/wait_for_ready/wait_for_ready_example.py @@ -0,0 +1,117 @@ +# Copyright 2019 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. +# 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. +"""The Python example of utilizing wait-for-ready flag.""" + +from __future__ import print_function +import logging +from concurrent import futures +from contextlib import contextmanager +import socket +import threading + +import grpc + +from examples import helloworld_pb2 +from examples import helloworld_pb2_grpc + +_LOGGER = logging.getLogger(__name__) +_LOGGER.setLevel(logging.INFO) + +_ONE_DAY_IN_SECONDS = 60 * 60 * 24 + + +@contextmanager +def get_free_loopback_tcp_port(): + if socket.has_ipv6: + tcp_socket = socket.socket(socket.AF_INET6) + else: + tcp_socket = socket.socket(socket.AF_INET) + tcp_socket.bind(('', 0)) + address_tuple = tcp_socket.getsockname() + yield "localhost:%s" % (address_tuple[1]) + tcp_socket.close() + + +class Greeter(helloworld_pb2_grpc.GreeterServicer): + + def SayHello(self, request, unused_context): + return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name) + + +def create_server(server_address): + server = grpc.server(futures.ThreadPoolExecutor()) + helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server) + bound_port = server.add_insecure_port(server_address) + assert bound_port == int(server_address.split(':')[-1]) + return server + + +def process(stub, wait_for_ready=None): + try: + response = stub.SayHello( + helloworld_pb2.HelloRequest(name='you'), + wait_for_ready=wait_for_ready) + message = response.message + except grpc.RpcError as rpc_error: + assert rpc_error.code() == grpc.StatusCode.UNAVAILABLE + assert not wait_for_ready + message = rpc_error + else: + assert wait_for_ready + _LOGGER.info("Wait-for-ready %s, client received: %s", "enabled" + if wait_for_ready else "disabled", message) + + +def main(): + # Pick a random free port + with get_free_loopback_tcp_port() as server_address: + + # Register connectivity event to notify main thread + transient_failure_event = threading.Event() + + def wait_for_transient_failure(channel_connectivity): + if channel_connectivity == grpc.ChannelConnectivity.TRANSIENT_FAILURE: + transient_failure_event.set() + + # Create gRPC channel + channel = grpc.insecure_channel(server_address) + channel.subscribe(wait_for_transient_failure) + stub = helloworld_pb2_grpc.GreeterStub(channel) + + # Fire an RPC without wait_for_ready + thread_disabled_wait_for_ready = threading.Thread( + target=process, args=(stub, False)) + thread_disabled_wait_for_ready.start() + # Fire an RPC with wait_for_ready + thread_enabled_wait_for_ready = threading.Thread( + target=process, args=(stub, True)) + thread_enabled_wait_for_ready.start() + + # Wait for the channel entering TRANSIENT FAILURE state. + transient_failure_event.wait() + server = create_server(server_address) + server.start() + + # Expected to fail with StatusCode.UNAVAILABLE. + thread_disabled_wait_for_ready.join() + # Expected to success. + thread_enabled_wait_for_ready.join() + + server.stop(None) + channel.close() + + +if __name__ == '__main__': + logging.basicConfig(level=logging.INFO) + main() diff --git a/examples/ruby/greeter_server.rb b/examples/ruby/greeter_server.rb index dca61714b88..52904297426 100755 --- a/examples/ruby/greeter_server.rb +++ b/examples/ruby/greeter_server.rb @@ -39,7 +39,10 @@ def main s = GRPC::RpcServer.new s.add_http2_port('0.0.0.0:50051', :this_port_is_insecure) s.handle(GreeterServer) - s.run_till_terminated + # Runs the server with SIGHUP, SIGINT and SIGQUIT signal handlers to + # gracefully shutdown. + # User could also choose to run server via call to run_till_terminated + s.run_till_terminated_or_interrupted([1, 'int', 'SIGQUIT']) end main diff --git a/examples/ruby/route_guide/route_guide_server.rb b/examples/ruby/route_guide/route_guide_server.rb index 5eb268b5336..ffcebd8418d 100755 --- a/examples/ruby/route_guide/route_guide_server.rb +++ b/examples/ruby/route_guide/route_guide_server.rb @@ -172,7 +172,10 @@ def main s.add_http2_port(port, :this_port_is_insecure) GRPC.logger.info("... running insecurely on #{port}") s.handle(ServerImpl.new(feature_db)) - s.run_till_terminated + # Runs the server with SIGHUP, SIGINT and SIGQUIT signal handlers to + # gracefully shutdown. + # User could also choose to run server via call to run_till_terminated + s.run_till_terminated_or_interrupted([1, 'int', 'SIGQUIT']) end main diff --git a/examples/ruby/without_protobuf/echo_client.rb b/examples/ruby/without_protobuf/echo_client.rb index 79ee54093db..7932aab2307 100755 --- a/examples/ruby/without_protobuf/echo_client.rb +++ b/examples/ruby/without_protobuf/echo_client.rb @@ -28,7 +28,7 @@ def main stub = EchoWithoutProtobuf::Stub.new('localhost:50051', :this_channel_is_insecure) user = ARGV.size > 0 ? ARGV[0] : 'world' message = stub.echo("hello #{user}") - p "Reponse: #{message}" + p "Response: #{message}" end main diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index fae5ce4a6ea..e9cf58438e8 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -23,15 +23,15 @@ Pod::Spec.new do |s| s.name = 'gRPC-C++' # TODO (mxyan): use version that match gRPC version when pod is stabilized - # version = '1.17.0-dev' - version = '0.0.4' + # version = '1.22.0-dev' + version = '0.0.8-dev' s.version = version s.summary = 'gRPC C++ library' s.homepage = 'https://grpc.io' s.license = 'Apache License, Version 2.0' s.authors = { 'The gRPC contributors' => 'grpc-packages@google.com' } - grpc_version = '1.17.0-dev' + grpc_version = '1.22.0-dev' s.source = { :git => 'https://github.com/grpc/grpc.git', @@ -40,6 +40,8 @@ Pod::Spec.new do |s| s.ios.deployment_target = '7.0' s.osx.deployment_target = '10.9' + s.tvos.deployment_target = '10.0' + s.requires_arc = false name = 'grpcpp' @@ -78,16 +80,22 @@ Pod::Spec.new do |s| ss.header_mappings_dir = 'include/grpcpp' ss.source_files = 'include/grpcpp/alarm.h', + 'include/grpcpp/alarm_impl.h', 'include/grpcpp/channel.h', + 'include/grpcpp/channel_impl.h', 'include/grpcpp/client_context.h', 'include/grpcpp/completion_queue.h', 'include/grpcpp/create_channel.h', + 'include/grpcpp/create_channel_impl.h', 'include/grpcpp/create_channel_posix.h', + 'include/grpcpp/create_channel_posix_impl.h', 'include/grpcpp/ext/health_check_service_server_builder_option.h', 'include/grpcpp/generic/async_generic_service.h', 'include/grpcpp/generic/generic_stub.h', + 'include/grpcpp/generic/generic_stub_impl.h', 'include/grpcpp/grpcpp.h', 'include/grpcpp/health_check_service_interface.h', + 'include/grpcpp/health_check_service_interface_impl.h', 'include/grpcpp/impl/call.h', 'include/grpcpp/impl/channel_argument_option.h', 'include/grpcpp/impl/client_unary_call.h', @@ -98,27 +106,41 @@ Pod::Spec.new do |s| 'include/grpcpp/impl/rpc_service_method.h', 'include/grpcpp/impl/serialization_traits.h', 'include/grpcpp/impl/server_builder_option.h', + 'include/grpcpp/impl/server_builder_option_impl.h', 'include/grpcpp/impl/server_builder_plugin.h', 'include/grpcpp/impl/server_initializer.h', + 'include/grpcpp/impl/server_initializer_impl.h', 'include/grpcpp/impl/service_type.h', 'include/grpcpp/resource_quota.h', + 'include/grpcpp/resource_quota_impl.h', 'include/grpcpp/security/auth_context.h', 'include/grpcpp/security/auth_metadata_processor.h', + 'include/grpcpp/security/auth_metadata_processor_impl.h', 'include/grpcpp/security/credentials.h', + 'include/grpcpp/security/credentials_impl.h', 'include/grpcpp/security/server_credentials.h', + 'include/grpcpp/security/server_credentials_impl.h', 'include/grpcpp/server.h', 'include/grpcpp/server_builder.h', + 'include/grpcpp/server_builder_impl.h', 'include/grpcpp/server_context.h', + 'include/grpcpp/server_impl.h', 'include/grpcpp/server_posix.h', + 'include/grpcpp/server_posix_impl.h', 'include/grpcpp/support/async_stream.h', 'include/grpcpp/support/async_unary_call.h', 'include/grpcpp/support/byte_buffer.h', 'include/grpcpp/support/channel_arguments.h', + 'include/grpcpp/support/channel_arguments_impl.h', 'include/grpcpp/support/client_callback.h', + 'include/grpcpp/support/client_interceptor.h', 'include/grpcpp/support/config.h', + 'include/grpcpp/support/interceptor.h', + 'include/grpcpp/support/message_allocator.h', 'include/grpcpp/support/proto_buffer_reader.h', 'include/grpcpp/support/proto_buffer_writer.h', 'include/grpcpp/support/server_callback.h', + 'include/grpcpp/support/server_interceptor.h', 'include/grpcpp/support/slice.h', 'include/grpcpp/support/status.h', 'include/grpcpp/support/status_code_enum.h', @@ -141,6 +163,7 @@ Pod::Spec.new do |s| 'include/grpcpp/impl/codegen/client_interceptor.h', 'include/grpcpp/impl/codegen/client_unary_call.h', 'include/grpcpp/impl/codegen/completion_queue.h', + 'include/grpcpp/impl/codegen/completion_queue_impl.h', 'include/grpcpp/impl/codegen/completion_queue_tag.h', 'include/grpcpp/impl/codegen/config.h', 'include/grpcpp/impl/codegen/core_codegen_interface.h', @@ -149,6 +172,7 @@ Pod::Spec.new do |s| 'include/grpcpp/impl/codegen/intercepted_channel.h', 'include/grpcpp/impl/codegen/interceptor.h', 'include/grpcpp/impl/codegen/interceptor_common.h', + 'include/grpcpp/impl/codegen/message_allocator.h', 'include/grpcpp/impl/codegen/metadata_map.h', 'include/grpcpp/impl/codegen/method_handler_impl.h', 'include/grpcpp/impl/codegen/rpc_method.h', @@ -166,7 +190,8 @@ Pod::Spec.new do |s| 'include/grpcpp/impl/codegen/string_ref.h', 'include/grpcpp/impl/codegen/stub_options.h', 'include/grpcpp/impl/codegen/sync_stream.h', - 'include/grpcpp/impl/codegen/time.h' + 'include/grpcpp/impl/codegen/time.h', + 'include/grpcpp/impl/codegen/sync.h' end s.subspec 'Implementation' do |ss| @@ -244,18 +269,24 @@ Pod::Spec.new do |s| 'src/core/lib/gpr/tmpfile.h', 'src/core/lib/gpr/useful.h', 'src/core/lib/gprpp/abstract.h', + 'src/core/lib/gprpp/arena.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/fork.h', + 'src/core/lib/gprpp/global_config.h', + 'src/core/lib/gprpp/global_config_custom.h', + 'src/core/lib/gprpp/global_config_env.h', + 'src/core/lib/gprpp/global_config_generic.h', 'src/core/lib/gprpp/manual_constructor.h', + 'src/core/lib/gprpp/map.h', 'src/core/lib/gprpp/memory.h', - 'src/core/lib/gprpp/mutex_lock.h', + 'src/core/lib/gprpp/pair.h', + 'src/core/lib/gprpp/sync.h', 'src/core/lib/gprpp/thd.h', 'src/core/lib/profiling/timers.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/context_list.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', @@ -293,6 +324,8 @@ Pod::Spec.new do |s| '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/tls/grpc_tls_credentials_options.h', + 'src/core/lib/security/credentials/tls/spiffe_credentials.h', 'src/core/lib/security/security_connector/alts/alts_security_connector.h', 'src/core/lib/security/security_connector/fake/fake_security_connector.h', 'src/core/lib/security/security_connector/load_system_roots.h', @@ -301,6 +334,7 @@ Pod::Spec.new do |s| 'src/core/lib/security/security_connector/security_connector.h', 'src/core/lib/security/security_connector/ssl/ssl_security_connector.h', 'src/core/lib/security/security_connector/ssl_utils.h', + 'src/core/lib/security/security_connector/tls/spiffe_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', @@ -341,12 +375,14 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/client_channel_channelz.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/global_subchannel_pool.h', 'src/core/ext/filters/client_channel/health/health_check_client.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/local_subchannel_pool.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', @@ -354,9 +390,12 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/resolver_factory.h', 'src/core/ext/filters/client_channel/resolver_registry.h', 'src/core/ext/filters/client_channel/resolver_result_parsing.h', + 'src/core/ext/filters/client_channel/resolving_lb_policy.h', 'src/core/ext/filters/client_channel/retry_throttle.h', + 'src/core/ext/filters/client_channel/server_address.h', + 'src/core/ext/filters/client_channel/service_config.h', 'src/core/ext/filters/client_channel/subchannel.h', - 'src/core/ext/filters/client_channel/subchannel_index.h', + 'src/core/ext/filters/client_channel/subchannel_pool_interface.h', 'src/core/ext/filters/deadline/deadline_filter.h', 'src/core/ext/filters/client_channel/health/health.pb.h', 'src/core/tsi/fake_transport_security.h', @@ -384,6 +423,7 @@ Pod::Spec.new do |s| '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_args.h', 'src/core/lib/compression/compression_internal.h', 'src/core/lib/compression/message_compress.h', 'src/core/lib/compression/stream_compression.h', @@ -393,6 +433,7 @@ Pod::Spec.new do |s| '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/optional.h', 'src/core/lib/gprpp/orphanable.h', 'src/core/lib/gprpp/ref_counted.h', 'src/core/lib/gprpp/ref_counted_ptr.h', @@ -402,11 +443,15 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/block_annotate.h', 'src/core/lib/iomgr/buffer_list.h', 'src/core/lib/iomgr/call_combiner.h', + 'src/core/lib/iomgr/cfstream_handle.h', 'src/core/lib/iomgr/closure.h', 'src/core/lib/iomgr/combiner.h', + 'src/core/lib/iomgr/dynamic_annotations.h', 'src/core/lib/iomgr/endpoint.h', + 'src/core/lib/iomgr/endpoint_cfstream.h', 'src/core/lib/iomgr/endpoint_pair.h', 'src/core/lib/iomgr/error.h', + 'src/core/lib/iomgr/error_cfstream.h', 'src/core/lib/iomgr/error_internal.h', 'src/core/lib/iomgr/ev_epoll1_linux.h', 'src/core/lib/iomgr/ev_epollex_linux.h', @@ -415,6 +460,7 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/exec_ctx.h', 'src/core/lib/iomgr/executor.h', 'src/core/lib/iomgr/gethostname.h', + 'src/core/lib/iomgr/grpc_if_nametoindex.h', 'src/core/lib/iomgr/internal_errqueue.h', 'src/core/lib/iomgr/iocp_windows.h', 'src/core/lib/iomgr/iomgr.h', @@ -425,7 +471,6 @@ Pod::Spec.new do |s| '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', @@ -462,7 +507,6 @@ Pod::Spec.new do |s| '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', @@ -474,6 +518,7 @@ Pod::Spec.new do |s| '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_utils.h', 'src/core/lib/slice/slice_weak_hash_table.h', 'src/core/lib/surface/api_trace.h', 'src/core/lib/surface/call.h', @@ -496,7 +541,6 @@ Pod::Spec.new do |s| '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', @@ -519,6 +563,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/lb_policy/subchannel_list.h', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h', + 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.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', @@ -552,13 +597,18 @@ Pod::Spec.new do |s| 'src/core/lib/gpr/tmpfile.h', 'src/core/lib/gpr/useful.h', 'src/core/lib/gprpp/abstract.h', + 'src/core/lib/gprpp/arena.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/fork.h', + 'src/core/lib/gprpp/global_config.h', + 'src/core/lib/gprpp/global_config_custom.h', + 'src/core/lib/gprpp/global_config_env.h', + 'src/core/lib/gprpp/global_config_generic.h', 'src/core/lib/gprpp/manual_constructor.h', + 'src/core/lib/gprpp/map.h', 'src/core/lib/gprpp/memory.h', - 'src/core/lib/gprpp/mutex_lock.h', + 'src/core/lib/gprpp/pair.h', + 'src/core/lib/gprpp/sync.h', 'src/core/lib/gprpp/thd.h', 'src/core/lib/profiling/timers.h', 'src/core/lib/avl/avl.h', @@ -576,6 +626,7 @@ Pod::Spec.new do |s| '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_args.h', 'src/core/lib/compression/compression_internal.h', 'src/core/lib/compression/message_compress.h', 'src/core/lib/compression/stream_compression.h', @@ -585,6 +636,7 @@ Pod::Spec.new do |s| '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/optional.h', 'src/core/lib/gprpp/orphanable.h', 'src/core/lib/gprpp/ref_counted.h', 'src/core/lib/gprpp/ref_counted_ptr.h', @@ -594,11 +646,15 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/block_annotate.h', 'src/core/lib/iomgr/buffer_list.h', 'src/core/lib/iomgr/call_combiner.h', + 'src/core/lib/iomgr/cfstream_handle.h', 'src/core/lib/iomgr/closure.h', 'src/core/lib/iomgr/combiner.h', + 'src/core/lib/iomgr/dynamic_annotations.h', 'src/core/lib/iomgr/endpoint.h', + 'src/core/lib/iomgr/endpoint_cfstream.h', 'src/core/lib/iomgr/endpoint_pair.h', 'src/core/lib/iomgr/error.h', + 'src/core/lib/iomgr/error_cfstream.h', 'src/core/lib/iomgr/error_internal.h', 'src/core/lib/iomgr/ev_epoll1_linux.h', 'src/core/lib/iomgr/ev_epollex_linux.h', @@ -607,6 +663,7 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/exec_ctx.h', 'src/core/lib/iomgr/executor.h', 'src/core/lib/iomgr/gethostname.h', + 'src/core/lib/iomgr/grpc_if_nametoindex.h', 'src/core/lib/iomgr/internal_errqueue.h', 'src/core/lib/iomgr/iocp_windows.h', 'src/core/lib/iomgr/iomgr.h', @@ -617,7 +674,6 @@ Pod::Spec.new do |s| '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', @@ -654,7 +710,6 @@ Pod::Spec.new do |s| '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', @@ -666,6 +721,7 @@ Pod::Spec.new do |s| '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_utils.h', 'src/core/lib/slice/slice_weak_hash_table.h', 'src/core/lib/surface/api_trace.h', 'src/core/lib/surface/call.h', @@ -688,7 +744,6 @@ Pod::Spec.new do |s| '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', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index f0a715cb585..dd68bbbd609 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -22,7 +22,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-Core' - version = '1.17.0-dev' + version = '1.22.0-dev' s.version = version s.summary = 'Core cross-platform gRPC library, written in C' s.homepage = 'https://grpc.io' @@ -40,6 +40,8 @@ Pod::Spec.new do |s| s.ios.deployment_target = '7.0' s.osx.deployment_target = '10.9' + s.tvos.deployment_target = '10.0' + s.requires_arc = false name = 'grpc' @@ -93,7 +95,7 @@ Pod::Spec.new do |s| } s.default_subspecs = 'Interface', 'Implementation' - s.compiler_flags = '-DGRPC_ARES=0', '-DPB_FIELD_16BIT' + s.compiler_flags = '-DGRPC_ARES=0', '-DPB_FIELD_32BIT' s.libraries = 'c++' # Like many other C libraries, gRPC-Core has its public headers under `include//` and its @@ -181,7 +183,7 @@ Pod::Spec.new do |s| ss.header_mappings_dir = '.' ss.libraries = 'z' ss.dependency "#{s.name}/Interface", version - ss.dependency 'BoringSSL-GRPC', '0.0.2' + ss.dependency 'BoringSSL-GRPC', '0.0.3' ss.dependency 'nanopb', '~> 0.3' ss.compiler_flags = '-DGRPC_SHADOW_BORINGSSL_SYMBOLS' @@ -203,17 +205,21 @@ Pod::Spec.new do |s| 'src/core/lib/gpr/tmpfile.h', 'src/core/lib/gpr/useful.h', 'src/core/lib/gprpp/abstract.h', + 'src/core/lib/gprpp/arena.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/fork.h', + 'src/core/lib/gprpp/global_config.h', + 'src/core/lib/gprpp/global_config_custom.h', + 'src/core/lib/gprpp/global_config_env.h', + 'src/core/lib/gprpp/global_config_generic.h', 'src/core/lib/gprpp/manual_constructor.h', + 'src/core/lib/gprpp/map.h', 'src/core/lib/gprpp/memory.h', - 'src/core/lib/gprpp/mutex_lock.h', + 'src/core/lib/gprpp/pair.h', + 'src/core/lib/gprpp/sync.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', @@ -246,7 +252,9 @@ Pod::Spec.new do |s| '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/arena.cc', 'src/core/lib/gprpp/fork.cc', + 'src/core/lib/gprpp/global_config_env.cc', 'src/core/lib/gprpp/thd_posix.cc', 'src/core/lib/gprpp/thd_windows.cc', 'src/core/lib/profiling/basic_timers.cc', @@ -254,6 +262,7 @@ Pod::Spec.new do |s| '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/context_list.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', @@ -291,6 +300,8 @@ Pod::Spec.new do |s| '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/tls/grpc_tls_credentials_options.h', + 'src/core/lib/security/credentials/tls/spiffe_credentials.h', 'src/core/lib/security/security_connector/alts/alts_security_connector.h', 'src/core/lib/security/security_connector/fake/fake_security_connector.h', 'src/core/lib/security/security_connector/load_system_roots.h', @@ -299,6 +310,7 @@ Pod::Spec.new do |s| 'src/core/lib/security/security_connector/security_connector.h', 'src/core/lib/security/security_connector/ssl/ssl_security_connector.h', 'src/core/lib/security/security_connector/ssl_utils.h', + 'src/core/lib/security/security_connector/tls/spiffe_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', @@ -339,12 +351,14 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/client_channel_channelz.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/global_subchannel_pool.h', 'src/core/ext/filters/client_channel/health/health_check_client.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/local_subchannel_pool.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', @@ -352,9 +366,12 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/resolver_factory.h', 'src/core/ext/filters/client_channel/resolver_registry.h', 'src/core/ext/filters/client_channel/resolver_result_parsing.h', + 'src/core/ext/filters/client_channel/resolving_lb_policy.h', 'src/core/ext/filters/client_channel/retry_throttle.h', + 'src/core/ext/filters/client_channel/server_address.h', + 'src/core/ext/filters/client_channel/service_config.h', 'src/core/ext/filters/client_channel/subchannel.h', - 'src/core/ext/filters/client_channel/subchannel_index.h', + 'src/core/ext/filters/client_channel/subchannel_pool_interface.h', 'src/core/ext/filters/deadline/deadline_filter.h', 'src/core/ext/filters/client_channel/health/health.pb.h', 'src/core/tsi/fake_transport_security.h', @@ -382,6 +399,7 @@ Pod::Spec.new do |s| '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_args.h', 'src/core/lib/compression/compression_internal.h', 'src/core/lib/compression/message_compress.h', 'src/core/lib/compression/stream_compression.h', @@ -391,6 +409,7 @@ Pod::Spec.new do |s| '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/optional.h', 'src/core/lib/gprpp/orphanable.h', 'src/core/lib/gprpp/ref_counted.h', 'src/core/lib/gprpp/ref_counted_ptr.h', @@ -400,11 +419,15 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/block_annotate.h', 'src/core/lib/iomgr/buffer_list.h', 'src/core/lib/iomgr/call_combiner.h', + 'src/core/lib/iomgr/cfstream_handle.h', 'src/core/lib/iomgr/closure.h', 'src/core/lib/iomgr/combiner.h', + 'src/core/lib/iomgr/dynamic_annotations.h', 'src/core/lib/iomgr/endpoint.h', + 'src/core/lib/iomgr/endpoint_cfstream.h', 'src/core/lib/iomgr/endpoint_pair.h', 'src/core/lib/iomgr/error.h', + 'src/core/lib/iomgr/error_cfstream.h', 'src/core/lib/iomgr/error_internal.h', 'src/core/lib/iomgr/ev_epoll1_linux.h', 'src/core/lib/iomgr/ev_epollex_linux.h', @@ -413,6 +436,7 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/exec_ctx.h', 'src/core/lib/iomgr/executor.h', 'src/core/lib/iomgr/gethostname.h', + 'src/core/lib/iomgr/grpc_if_nametoindex.h', 'src/core/lib/iomgr/internal_errqueue.h', 'src/core/lib/iomgr/iocp_windows.h', 'src/core/lib/iomgr/iomgr.h', @@ -423,7 +447,6 @@ Pod::Spec.new do |s| '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', @@ -460,7 +483,6 @@ Pod::Spec.new do |s| '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', @@ -472,6 +494,7 @@ Pod::Spec.new do |s| '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_utils.h', 'src/core/lib/slice/slice_weak_hash_table.h', 'src/core/lib/surface/api_trace.h', 'src/core/lib/surface/call.h', @@ -494,7 +517,6 @@ Pod::Spec.new do |s| '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', @@ -517,6 +539,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/lb_policy/subchannel_list.h', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h', + 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.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', @@ -533,10 +556,10 @@ Pod::Spec.new do |s| 'src/core/lib/channel/channelz_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_args.cc', 'src/core/lib/compression/compression_internal.cc', 'src/core/lib/compression/message_compress.cc', 'src/core/lib/compression/stream_compression.cc', @@ -549,12 +572,15 @@ Pod::Spec.new do |s| 'src/core/lib/http/parser.cc', 'src/core/lib/iomgr/buffer_list.cc', 'src/core/lib/iomgr/call_combiner.cc', + 'src/core/lib/iomgr/cfstream_handle.cc', 'src/core/lib/iomgr/combiner.cc', 'src/core/lib/iomgr/endpoint.cc', + 'src/core/lib/iomgr/endpoint_cfstream.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/error_cfstream.cc', 'src/core/lib/iomgr/ev_epoll1_linux.cc', 'src/core/lib/iomgr/ev_epollex_linux.cc', 'src/core/lib/iomgr/ev_poll_posix.cc', @@ -567,18 +593,20 @@ Pod::Spec.new do |s| '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/grpc_if_nametoindex_posix.cc', + 'src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc', 'src/core/lib/iomgr/internal_errqueue.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_posix_cfstream.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', @@ -602,6 +630,7 @@ Pod::Spec.new do |s| '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_cfstream.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', @@ -626,7 +655,6 @@ Pod::Spec.new do |s| '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', @@ -666,7 +694,6 @@ Pod::Spec.new do |s| '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', @@ -680,6 +707,7 @@ Pod::Spec.new do |s| '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/context_list.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', @@ -720,6 +748,8 @@ Pod::Spec.new do |s| '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/tls/grpc_tls_credentials_options.cc', + 'src/core/lib/security/credentials/tls/spiffe_credentials.cc', 'src/core/lib/security/security_connector/alts/alts_security_connector.cc', 'src/core/lib/security/security_connector/fake/fake_security_connector.cc', 'src/core/lib/security/security_connector/load_system_roots_fallback.cc', @@ -728,6 +758,7 @@ Pod::Spec.new do |s| 'src/core/lib/security/security_connector/security_connector.cc', 'src/core/lib/security/security_connector/ssl/ssl_security_connector.cc', 'src/core/lib/security/security_connector/ssl_utils.cc', + 'src/core/lib/security/security_connector/tls/spiffe_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', @@ -779,21 +810,25 @@ Pod::Spec.new do |s| '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/global_subchannel_pool.cc', 'src/core/ext/filters/client_channel/health/health_check_client.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/local_subchannel_pool.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/resolver_result_parsing.cc', + 'src/core/ext/filters/client_channel/resolving_lb_policy.cc', 'src/core/ext/filters/client_channel/retry_throttle.cc', + 'src/core/ext/filters/client_channel/server_address.cc', + 'src/core/ext/filters/client_channel/service_config.cc', 'src/core/ext/filters/client_channel/subchannel.cc', - 'src/core/ext/filters/client_channel/subchannel_index.cc', + 'src/core/ext/filters/client_channel/subchannel_pool_interface.cc', 'src/core/ext/filters/deadline/deadline_filter.cc', 'src/core/ext/filters/client_channel/health/health.pb.c', 'src/core/tsi/fake_transport_security.cc', @@ -826,10 +861,13 @@ Pod::Spec.new do |s| '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.cc', + 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc', + 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc', + 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc', 'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc', @@ -859,18 +897,24 @@ Pod::Spec.new do |s| 'src/core/lib/gpr/tmpfile.h', 'src/core/lib/gpr/useful.h', 'src/core/lib/gprpp/abstract.h', + 'src/core/lib/gprpp/arena.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/fork.h', + 'src/core/lib/gprpp/global_config.h', + 'src/core/lib/gprpp/global_config_custom.h', + 'src/core/lib/gprpp/global_config_env.h', + 'src/core/lib/gprpp/global_config_generic.h', 'src/core/lib/gprpp/manual_constructor.h', + 'src/core/lib/gprpp/map.h', 'src/core/lib/gprpp/memory.h', - 'src/core/lib/gprpp/mutex_lock.h', + 'src/core/lib/gprpp/pair.h', + 'src/core/lib/gprpp/sync.h', 'src/core/lib/gprpp/thd.h', 'src/core/lib/profiling/timers.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/context_list.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', @@ -908,6 +952,8 @@ Pod::Spec.new do |s| '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/tls/grpc_tls_credentials_options.h', + 'src/core/lib/security/credentials/tls/spiffe_credentials.h', 'src/core/lib/security/security_connector/alts/alts_security_connector.h', 'src/core/lib/security/security_connector/fake/fake_security_connector.h', 'src/core/lib/security/security_connector/load_system_roots.h', @@ -916,6 +962,7 @@ Pod::Spec.new do |s| 'src/core/lib/security/security_connector/security_connector.h', 'src/core/lib/security/security_connector/ssl/ssl_security_connector.h', 'src/core/lib/security/security_connector/ssl_utils.h', + 'src/core/lib/security/security_connector/tls/spiffe_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', @@ -956,12 +1003,14 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/client_channel_channelz.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/global_subchannel_pool.h', 'src/core/ext/filters/client_channel/health/health_check_client.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/local_subchannel_pool.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', @@ -969,9 +1018,12 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/resolver_factory.h', 'src/core/ext/filters/client_channel/resolver_registry.h', 'src/core/ext/filters/client_channel/resolver_result_parsing.h', + 'src/core/ext/filters/client_channel/resolving_lb_policy.h', 'src/core/ext/filters/client_channel/retry_throttle.h', + 'src/core/ext/filters/client_channel/server_address.h', + 'src/core/ext/filters/client_channel/service_config.h', 'src/core/ext/filters/client_channel/subchannel.h', - 'src/core/ext/filters/client_channel/subchannel_index.h', + 'src/core/ext/filters/client_channel/subchannel_pool_interface.h', 'src/core/ext/filters/deadline/deadline_filter.h', 'src/core/ext/filters/client_channel/health/health.pb.h', 'src/core/tsi/fake_transport_security.h', @@ -999,6 +1051,7 @@ Pod::Spec.new do |s| '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_args.h', 'src/core/lib/compression/compression_internal.h', 'src/core/lib/compression/message_compress.h', 'src/core/lib/compression/stream_compression.h', @@ -1008,6 +1061,7 @@ Pod::Spec.new do |s| '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/optional.h', 'src/core/lib/gprpp/orphanable.h', 'src/core/lib/gprpp/ref_counted.h', 'src/core/lib/gprpp/ref_counted_ptr.h', @@ -1017,11 +1071,15 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/block_annotate.h', 'src/core/lib/iomgr/buffer_list.h', 'src/core/lib/iomgr/call_combiner.h', + 'src/core/lib/iomgr/cfstream_handle.h', 'src/core/lib/iomgr/closure.h', 'src/core/lib/iomgr/combiner.h', + 'src/core/lib/iomgr/dynamic_annotations.h', 'src/core/lib/iomgr/endpoint.h', + 'src/core/lib/iomgr/endpoint_cfstream.h', 'src/core/lib/iomgr/endpoint_pair.h', 'src/core/lib/iomgr/error.h', + 'src/core/lib/iomgr/error_cfstream.h', 'src/core/lib/iomgr/error_internal.h', 'src/core/lib/iomgr/ev_epoll1_linux.h', 'src/core/lib/iomgr/ev_epollex_linux.h', @@ -1030,6 +1088,7 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/exec_ctx.h', 'src/core/lib/iomgr/executor.h', 'src/core/lib/iomgr/gethostname.h', + 'src/core/lib/iomgr/grpc_if_nametoindex.h', 'src/core/lib/iomgr/internal_errqueue.h', 'src/core/lib/iomgr/iocp_windows.h', 'src/core/lib/iomgr/iomgr.h', @@ -1040,7 +1099,6 @@ Pod::Spec.new do |s| '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', @@ -1077,7 +1135,6 @@ Pod::Spec.new do |s| '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', @@ -1089,6 +1146,7 @@ Pod::Spec.new do |s| '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_utils.h', 'src/core/lib/slice/slice_weak_hash_table.h', 'src/core/lib/surface/api_trace.h', 'src/core/lib/surface/call.h', @@ -1111,7 +1169,6 @@ Pod::Spec.new do |s| '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', @@ -1134,6 +1191,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/lb_policy/subchannel_list.h', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h', + 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.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', @@ -1141,23 +1199,9 @@ Pod::Spec.new do |s| 'src/core/ext/filters/workarounds/workaround_utils.h' end + # CFStream is now default. Leaving this subspec only for compatibility purpose. s.subspec 'CFStream-Implementation' do |ss| - ss.header_mappings_dir = '.' ss.dependency "#{s.name}/Implementation", version - ss.pod_target_xcconfig = { - 'GCC_PREPROCESSOR_DEFINITIONS' => 'GRPC_CFSTREAM=1' - } - ss.source_files = 'src/core/lib/iomgr/cfstream_handle.cc', - 'src/core/lib/iomgr/endpoint_cfstream.cc', - 'src/core/lib/iomgr/error_cfstream.cc', - 'src/core/lib/iomgr/iomgr_posix_cfstream.cc', - 'src/core/lib/iomgr/tcp_client_cfstream.cc', - 'src/core/lib/iomgr/cfstream_handle.h', - 'src/core/lib/iomgr/endpoint_cfstream.h', - 'src/core/lib/iomgr/error_cfstream.h' - ss.private_header_files = 'src/core/lib/iomgr/cfstream_handle.h', - 'src/core/lib/iomgr/endpoint_cfstream.h', - 'src/core/lib/iomgr/error_cfstream.h' end s.subspec 'Cronet-Interface' do |ss| @@ -1191,15 +1235,14 @@ Pod::Spec.new do |s| 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', - 'test/core/end2end/data/client_certs.cc', + ss.source_files = 'test/core/end2end/data/client_certs.cc', 'test/core/end2end/data/server1_cert.cc', 'test/core/end2end/data/server1_key.cc', 'test/core/end2end/data/test_root_cert.cc', 'test/core/security/oauth2_utils.cc', 'test/core/end2end/cq_verifier.cc', 'test/core/end2end/fixtures/http_proxy_fixture.cc', + 'test/core/end2end/fixtures/local_util.cc', 'test/core/end2end/fixtures/proxy.cc', 'test/core/iomgr/endpoint_tests.cc', 'test/core/util/debugger_macros.cc', @@ -1214,8 +1257,9 @@ Pod::Spec.new do |s| 'test/core/util/port_isolated_runtime_environment.cc', 'test/core/util/port_server_client.cc', 'test/core/util/slice_splitter.cc', - 'test/core/util/subprocess_posix.cc', 'test/core/util/subprocess_windows.cc', + 'test/core/util/test_config.cc', + 'test/core/util/test_lb_policies.cc', 'test/core/util/tracer_util.cc', 'test/core/util/trickle_endpoint.cc', 'test/core/util/cmdline.cc', @@ -1226,6 +1270,7 @@ Pod::Spec.new do |s| 'test/core/security/oauth2_utils.h', 'test/core/end2end/cq_verifier.h', 'test/core/end2end/fixtures/http_proxy_fixture.h', + 'test/core/end2end/fixtures/local_util.h', 'test/core/end2end/fixtures/proxy.h', 'test/core/iomgr/endpoint_tests.h', 'test/core/util/debugger_macros.h', @@ -1240,6 +1285,8 @@ Pod::Spec.new do |s| 'test/core/util/port_server_client.h', 'test/core/util/slice_splitter.h', 'test/core/util/subprocess.h', + 'test/core/util/test_config.h', + 'test/core/util/test_lb_policies.h', 'test/core/util/tracer_util.h', 'test/core/util/trickle_endpoint.h', 'test/core/util/cmdline.h', @@ -1270,6 +1317,7 @@ Pod::Spec.new do |s| 'test/core/end2end/tests/empty_batch.cc', 'test/core/end2end/tests/filter_call_init_fails.cc', 'test/core/end2end/tests/filter_causes_close.cc', + 'test/core/end2end/tests/filter_context.cc', 'test/core/end2end/tests/filter_latency.cc', 'test/core/end2end/tests/filter_status_code.cc', 'test/core/end2end/tests/graceful_server_shutdown.cc', @@ -1284,7 +1332,6 @@ Pod::Spec.new do |s| 'test/core/end2end/tests/max_connection_idle.cc', 'test/core/end2end/tests/max_message_length.cc', 'test/core/end2end/tests/negative_deadline.cc', - 'test/core/end2end/tests/network_status_change.cc', 'test/core/end2end/tests/no_error_on_hotpath.cc', 'test/core/end2end/tests/no_logging.cc', 'test/core/end2end/tests/no_op.cc', diff --git a/gRPC-ProtoRPC.podspec b/gRPC-ProtoRPC.podspec index 693b873d14d..1cac59c6cc4 100644 --- a/gRPC-ProtoRPC.podspec +++ b/gRPC-ProtoRPC.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-ProtoRPC' - version = '1.17.0-dev' + version = '1.22.0-dev' s.version = version s.summary = 'RPC library for Protocol Buffers, based on gRPC' s.homepage = 'https://grpc.io' @@ -35,6 +35,7 @@ Pod::Spec.new do |s| s.ios.deployment_target = '7.0' s.osx.deployment_target = '10.9' + s.tvos.deployment_target = '10.0' name = 'ProtoRPC' s.module_name = name @@ -52,12 +53,10 @@ Pod::Spec.new do |s| ss.source_files = "#{src_dir}/*.{h,m}" end + + # CFStream is now default. Leaving this subspec only for compatibility purpose. s.subspec 'CFStream' do |ss| - ss.dependency 'gRPC/CFStream', version ss.dependency "#{s.name}/Main", version - ss.pod_target_xcconfig = { - 'GCC_PREPROCESSOR_DEFINITIONS' => 'GRPC_CFSTREAM=1' - } end s.pod_target_xcconfig = { diff --git a/gRPC-RxLibrary.podspec b/gRPC-RxLibrary.podspec index fd590023e1a..6f033ea71b7 100644 --- a/gRPC-RxLibrary.podspec +++ b/gRPC-RxLibrary.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-RxLibrary' - version = '1.17.0-dev' + version = '1.22.0-dev' s.version = version s.summary = 'Reactive Extensions library for iOS/OSX.' s.homepage = 'https://grpc.io' @@ -35,6 +35,7 @@ Pod::Spec.new do |s| s.ios.deployment_target = '7.0' s.osx.deployment_target = '10.9' + s.tvos.deployment_target = '10.0' name = 'RxLibrary' s.module_name = name diff --git a/gRPC.podspec b/gRPC.podspec index 5e513cb1276..e9c3fd7bee0 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -20,7 +20,7 @@ Pod::Spec.new do |s| s.name = 'gRPC' - version = '1.17.0-dev' + version = '1.22.0-dev' s.version = version s.summary = 'gRPC client library for iOS/OSX' s.homepage = 'https://grpc.io' @@ -34,6 +34,7 @@ Pod::Spec.new do |s| s.ios.deployment_target = '7.0' s.osx.deployment_target = '10.9' + s.tvos.deployment_target = '10.0' name = 'GRPCClient' s.module_name = name @@ -58,19 +59,14 @@ Pod::Spec.new do |s| ss.source_files = "#{src_dir}/*.{h,m}", "#{src_dir}/**/*.{h,m}" ss.exclude_files = "#{src_dir}/GRPCCall+GID.{h,m}" - ss.private_header_files = "#{src_dir}/private/*.h" + ss.private_header_files = "#{src_dir}/private/*.h", "#{src_dir}/internal/*.h" ss.dependency 'gRPC-Core', version end - # This subspec is mutually exclusive with the `Main` subspec + # CFStream is now default. Leaving this subspec only for compatibility purpose. s.subspec 'CFStream' do |ss| - ss.dependency 'gRPC-Core/CFStream-Implementation', version ss.dependency "#{s.name}/Main", version - - ss.pod_target_xcconfig = { - 'GCC_PREPROCESSOR_DEFINITIONS' => 'GRPC_CFSTREAM=1' - } end s.subspec 'GID' do |ss| diff --git a/grpc.def b/grpc.def index b3466c004d8..922f95383a3 100644 --- a/grpc.def +++ b/grpc.def @@ -16,6 +16,7 @@ EXPORTS grpc_init grpc_shutdown grpc_is_initialized + grpc_shutdown_blocking grpc_version_string grpc_g_stands_for grpc_completion_queue_factory_lookup @@ -131,6 +132,15 @@ EXPORTS grpc_alts_server_credentials_create grpc_local_credentials_create grpc_local_server_credentials_create + grpc_tls_credentials_options_create + grpc_tls_credentials_options_set_cert_request_type + grpc_tls_credentials_options_set_key_materials_config + grpc_tls_credentials_options_set_credential_reload_config + grpc_tls_credentials_options_set_server_authorization_check_config + grpc_tls_key_materials_config_create + grpc_tls_key_materials_config_set_key_materials + grpc_tls_credential_reload_config_create + grpc_tls_server_authorization_check_config_create grpc_raw_byte_buffer_create grpc_raw_compressed_byte_buffer_create grpc_byte_buffer_copy @@ -139,6 +149,7 @@ EXPORTS grpc_byte_buffer_reader_init grpc_byte_buffer_reader_destroy grpc_byte_buffer_reader_next + grpc_byte_buffer_reader_peek grpc_byte_buffer_reader_readall grpc_raw_byte_buffer_from_reader gpr_log_severity_string diff --git a/grpc.gemspec b/grpc.gemspec index 04f3066899a..ecf17e998ac 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -29,8 +29,8 @@ Gem::Specification.new do |s| s.require_paths = %w( src/ruby/lib src/ruby/bin src/ruby/pb ) s.platform = Gem::Platform::RUBY - s.add_dependency 'google-protobuf', '~> 3.1' - s.add_dependency 'googleapis-common-protos-types', '~> 1.0.0' + s.add_dependency 'google-protobuf', '~> 3.7' + s.add_dependency 'googleapis-common-protos-types', '~> 1.0' s.add_development_dependency 'bundler', '~> 1.9' s.add_development_dependency 'facter', '~> 2.4' @@ -41,8 +41,8 @@ Gem::Specification.new do |s| s.add_development_dependency 'rake-compiler-dock', '~> 0.5.1' s.add_development_dependency 'rspec', '~> 3.6' s.add_development_dependency 'rubocop', '~> 0.49.1' - s.add_development_dependency 'signet', '~> 0.7.0' - s.add_development_dependency 'googleauth', '>= 0.5.1', '< 0.7' + s.add_development_dependency 'signet', '~> 0.7' + s.add_development_dependency 'googleauth', '>= 0.5.1', '< 0.10' s.extensions = %w(src/ruby/ext/grpc/extconf.rb) @@ -99,17 +99,21 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/gpr/tmpfile.h ) s.files += %w( src/core/lib/gpr/useful.h ) s.files += %w( src/core/lib/gprpp/abstract.h ) + s.files += %w( src/core/lib/gprpp/arena.h ) s.files += %w( src/core/lib/gprpp/atomic.h ) - s.files += %w( src/core/lib/gprpp/atomic_with_atm.h ) - s.files += %w( src/core/lib/gprpp/atomic_with_std.h ) s.files += %w( src/core/lib/gprpp/fork.h ) + s.files += %w( src/core/lib/gprpp/global_config.h ) + s.files += %w( src/core/lib/gprpp/global_config_custom.h ) + s.files += %w( src/core/lib/gprpp/global_config_env.h ) + s.files += %w( src/core/lib/gprpp/global_config_generic.h ) s.files += %w( src/core/lib/gprpp/manual_constructor.h ) + s.files += %w( src/core/lib/gprpp/map.h ) s.files += %w( src/core/lib/gprpp/memory.h ) - s.files += %w( src/core/lib/gprpp/mutex_lock.h ) + s.files += %w( src/core/lib/gprpp/pair.h ) + s.files += %w( src/core/lib/gprpp/sync.h ) s.files += %w( src/core/lib/gprpp/thd.h ) s.files += %w( src/core/lib/profiling/timers.h ) s.files += %w( src/core/lib/gpr/alloc.cc ) - s.files += %w( src/core/lib/gpr/arena.cc ) s.files += %w( src/core/lib/gpr/atm.cc ) s.files += %w( src/core/lib/gpr/cpu_iphone.cc ) s.files += %w( src/core/lib/gpr/cpu_linux.cc ) @@ -142,7 +146,9 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/gpr/tmpfile_posix.cc ) s.files += %w( src/core/lib/gpr/tmpfile_windows.cc ) s.files += %w( src/core/lib/gpr/wrap_memcpy.cc ) + s.files += %w( src/core/lib/gprpp/arena.cc ) s.files += %w( src/core/lib/gprpp/fork.cc ) + s.files += %w( src/core/lib/gprpp/global_config_env.cc ) s.files += %w( src/core/lib/gprpp/thd_posix.cc ) s.files += %w( src/core/lib/gprpp/thd_windows.cc ) s.files += %w( src/core/lib/profiling/basic_timers.cc ) @@ -186,6 +192,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/transport/chttp2/transport/bin_decoder.h ) s.files += %w( src/core/ext/transport/chttp2/transport/bin_encoder.h ) s.files += %w( src/core/ext/transport/chttp2/transport/chttp2_transport.h ) + s.files += %w( src/core/ext/transport/chttp2/transport/context_list.h ) s.files += %w( src/core/ext/transport/chttp2/transport/flow_control.h ) s.files += %w( src/core/ext/transport/chttp2/transport/frame.h ) s.files += %w( src/core/ext/transport/chttp2/transport/frame_data.h ) @@ -223,6 +230,8 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/security/credentials/oauth2/oauth2_credentials.h ) s.files += %w( src/core/lib/security/credentials/plugin/plugin_credentials.h ) s.files += %w( src/core/lib/security/credentials/ssl/ssl_credentials.h ) + s.files += %w( src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h ) + s.files += %w( src/core/lib/security/credentials/tls/spiffe_credentials.h ) s.files += %w( src/core/lib/security/security_connector/alts/alts_security_connector.h ) s.files += %w( src/core/lib/security/security_connector/fake/fake_security_connector.h ) s.files += %w( src/core/lib/security/security_connector/load_system_roots.h ) @@ -231,6 +240,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/security/security_connector/security_connector.h ) s.files += %w( src/core/lib/security/security_connector/ssl/ssl_security_connector.h ) s.files += %w( src/core/lib/security/security_connector/ssl_utils.h ) + s.files += %w( src/core/lib/security/security_connector/tls/spiffe_security_connector.h ) s.files += %w( src/core/lib/security/transport/auth_filters.h ) s.files += %w( src/core/lib/security/transport/secure_endpoint.h ) s.files += %w( src/core/lib/security/transport/security_handshaker.h ) @@ -275,12 +285,14 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/client_channel_channelz.h ) s.files += %w( src/core/ext/filters/client_channel/client_channel_factory.h ) s.files += %w( src/core/ext/filters/client_channel/connector.h ) + s.files += %w( src/core/ext/filters/client_channel/global_subchannel_pool.h ) s.files += %w( src/core/ext/filters/client_channel/health/health_check_client.h ) s.files += %w( src/core/ext/filters/client_channel/http_connect_handshaker.h ) s.files += %w( src/core/ext/filters/client_channel/http_proxy.h ) s.files += %w( src/core/ext/filters/client_channel/lb_policy.h ) s.files += %w( src/core/ext/filters/client_channel/lb_policy_factory.h ) s.files += %w( src/core/ext/filters/client_channel/lb_policy_registry.h ) + s.files += %w( src/core/ext/filters/client_channel/local_subchannel_pool.h ) s.files += %w( src/core/ext/filters/client_channel/parse_address.h ) s.files += %w( src/core/ext/filters/client_channel/proxy_mapper.h ) s.files += %w( src/core/ext/filters/client_channel/proxy_mapper_registry.h ) @@ -288,9 +300,12 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/resolver_factory.h ) s.files += %w( src/core/ext/filters/client_channel/resolver_registry.h ) s.files += %w( src/core/ext/filters/client_channel/resolver_result_parsing.h ) + s.files += %w( src/core/ext/filters/client_channel/resolving_lb_policy.h ) s.files += %w( src/core/ext/filters/client_channel/retry_throttle.h ) + s.files += %w( src/core/ext/filters/client_channel/server_address.h ) + s.files += %w( src/core/ext/filters/client_channel/service_config.h ) s.files += %w( src/core/ext/filters/client_channel/subchannel.h ) - s.files += %w( src/core/ext/filters/client_channel/subchannel_index.h ) + s.files += %w( src/core/ext/filters/client_channel/subchannel_pool_interface.h ) s.files += %w( src/core/ext/filters/deadline/deadline_filter.h ) s.files += %w( src/core/ext/filters/client_channel/health/health.pb.h ) s.files += %w( src/core/tsi/fake_transport_security.h ) @@ -318,6 +333,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/channel/handshaker_registry.h ) s.files += %w( src/core/lib/channel/status_util.h ) s.files += %w( src/core/lib/compression/algorithm_metadata.h ) + s.files += %w( src/core/lib/compression/compression_args.h ) s.files += %w( src/core/lib/compression/compression_internal.h ) s.files += %w( src/core/lib/compression/message_compress.h ) s.files += %w( src/core/lib/compression/stream_compression.h ) @@ -327,6 +343,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/debug/stats_data.h ) s.files += %w( src/core/lib/gprpp/debug_location.h ) s.files += %w( src/core/lib/gprpp/inlined_vector.h ) + s.files += %w( src/core/lib/gprpp/optional.h ) s.files += %w( src/core/lib/gprpp/orphanable.h ) s.files += %w( src/core/lib/gprpp/ref_counted.h ) s.files += %w( src/core/lib/gprpp/ref_counted_ptr.h ) @@ -336,11 +353,15 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/iomgr/block_annotate.h ) s.files += %w( src/core/lib/iomgr/buffer_list.h ) s.files += %w( src/core/lib/iomgr/call_combiner.h ) + s.files += %w( src/core/lib/iomgr/cfstream_handle.h ) s.files += %w( src/core/lib/iomgr/closure.h ) s.files += %w( src/core/lib/iomgr/combiner.h ) + s.files += %w( src/core/lib/iomgr/dynamic_annotations.h ) s.files += %w( src/core/lib/iomgr/endpoint.h ) + s.files += %w( src/core/lib/iomgr/endpoint_cfstream.h ) s.files += %w( src/core/lib/iomgr/endpoint_pair.h ) s.files += %w( src/core/lib/iomgr/error.h ) + s.files += %w( src/core/lib/iomgr/error_cfstream.h ) s.files += %w( src/core/lib/iomgr/error_internal.h ) s.files += %w( src/core/lib/iomgr/ev_epoll1_linux.h ) s.files += %w( src/core/lib/iomgr/ev_epollex_linux.h ) @@ -349,6 +370,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/iomgr/exec_ctx.h ) s.files += %w( src/core/lib/iomgr/executor.h ) s.files += %w( src/core/lib/iomgr/gethostname.h ) + s.files += %w( src/core/lib/iomgr/grpc_if_nametoindex.h ) s.files += %w( src/core/lib/iomgr/internal_errqueue.h ) s.files += %w( src/core/lib/iomgr/iocp_windows.h ) s.files += %w( src/core/lib/iomgr/iomgr.h ) @@ -359,7 +381,6 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/iomgr/load_file.h ) s.files += %w( src/core/lib/iomgr/lockfree_event.h ) s.files += %w( src/core/lib/iomgr/nameser.h ) - s.files += %w( src/core/lib/iomgr/network_status_tracker.h ) s.files += %w( src/core/lib/iomgr/polling_entity.h ) s.files += %w( src/core/lib/iomgr/pollset.h ) s.files += %w( src/core/lib/iomgr/pollset_custom.h ) @@ -396,7 +417,6 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/iomgr/timer_manager.h ) s.files += %w( src/core/lib/iomgr/udp_server.h ) s.files += %w( src/core/lib/iomgr/unix_sockets_posix.h ) - s.files += %w( src/core/lib/iomgr/wakeup_fd_cv.h ) s.files += %w( src/core/lib/iomgr/wakeup_fd_pipe.h ) s.files += %w( src/core/lib/iomgr/wakeup_fd_posix.h ) s.files += %w( src/core/lib/json/json.h ) @@ -408,6 +428,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/slice/slice_hash_table.h ) s.files += %w( src/core/lib/slice/slice_internal.h ) s.files += %w( src/core/lib/slice/slice_string_helpers.h ) + s.files += %w( src/core/lib/slice/slice_utils.h ) s.files += %w( src/core/lib/slice/slice_weak_hash_table.h ) s.files += %w( src/core/lib/surface/api_trace.h ) s.files += %w( src/core/lib/surface/call.h ) @@ -430,7 +451,6 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/transport/metadata.h ) s.files += %w( src/core/lib/transport/metadata_batch.h ) s.files += %w( src/core/lib/transport/pid_controller.h ) - s.files += %w( src/core/lib/transport/service_config.h ) s.files += %w( src/core/lib/transport/static_metadata.h ) s.files += %w( src/core/lib/transport/status_conversion.h ) s.files += %w( src/core/lib/transport/status_metadata.h ) @@ -453,6 +473,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/lb_policy/subchannel_list.h ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h ) + s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.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 ) @@ -469,10 +490,10 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/channel/channelz_registry.cc ) s.files += %w( src/core/lib/channel/connected_channel.cc ) s.files += %w( src/core/lib/channel/handshaker.cc ) - s.files += %w( src/core/lib/channel/handshaker_factory.cc ) s.files += %w( src/core/lib/channel/handshaker_registry.cc ) s.files += %w( src/core/lib/channel/status_util.cc ) s.files += %w( src/core/lib/compression/compression.cc ) + s.files += %w( src/core/lib/compression/compression_args.cc ) s.files += %w( src/core/lib/compression/compression_internal.cc ) s.files += %w( src/core/lib/compression/message_compress.cc ) s.files += %w( src/core/lib/compression/stream_compression.cc ) @@ -485,12 +506,15 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/http/parser.cc ) s.files += %w( src/core/lib/iomgr/buffer_list.cc ) s.files += %w( src/core/lib/iomgr/call_combiner.cc ) + s.files += %w( src/core/lib/iomgr/cfstream_handle.cc ) s.files += %w( src/core/lib/iomgr/combiner.cc ) s.files += %w( src/core/lib/iomgr/endpoint.cc ) + s.files += %w( src/core/lib/iomgr/endpoint_cfstream.cc ) s.files += %w( src/core/lib/iomgr/endpoint_pair_posix.cc ) s.files += %w( src/core/lib/iomgr/endpoint_pair_uv.cc ) s.files += %w( src/core/lib/iomgr/endpoint_pair_windows.cc ) s.files += %w( src/core/lib/iomgr/error.cc ) + s.files += %w( src/core/lib/iomgr/error_cfstream.cc ) s.files += %w( src/core/lib/iomgr/ev_epoll1_linux.cc ) s.files += %w( src/core/lib/iomgr/ev_epollex_linux.cc ) s.files += %w( src/core/lib/iomgr/ev_poll_posix.cc ) @@ -503,18 +527,20 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/iomgr/gethostname_fallback.cc ) s.files += %w( src/core/lib/iomgr/gethostname_host_name_max.cc ) s.files += %w( src/core/lib/iomgr/gethostname_sysconf.cc ) + s.files += %w( src/core/lib/iomgr/grpc_if_nametoindex_posix.cc ) + s.files += %w( src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc ) s.files += %w( src/core/lib/iomgr/internal_errqueue.cc ) s.files += %w( src/core/lib/iomgr/iocp_windows.cc ) s.files += %w( src/core/lib/iomgr/iomgr.cc ) s.files += %w( src/core/lib/iomgr/iomgr_custom.cc ) s.files += %w( src/core/lib/iomgr/iomgr_internal.cc ) s.files += %w( src/core/lib/iomgr/iomgr_posix.cc ) + s.files += %w( src/core/lib/iomgr/iomgr_posix_cfstream.cc ) s.files += %w( src/core/lib/iomgr/iomgr_uv.cc ) s.files += %w( src/core/lib/iomgr/iomgr_windows.cc ) s.files += %w( src/core/lib/iomgr/is_epollexclusive_available.cc ) s.files += %w( src/core/lib/iomgr/load_file.cc ) s.files += %w( src/core/lib/iomgr/lockfree_event.cc ) - s.files += %w( src/core/lib/iomgr/network_status_tracker.cc ) s.files += %w( src/core/lib/iomgr/polling_entity.cc ) s.files += %w( src/core/lib/iomgr/pollset.cc ) s.files += %w( src/core/lib/iomgr/pollset_custom.cc ) @@ -538,6 +564,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/iomgr/socket_utils_windows.cc ) s.files += %w( src/core/lib/iomgr/socket_windows.cc ) s.files += %w( src/core/lib/iomgr/tcp_client.cc ) + s.files += %w( src/core/lib/iomgr/tcp_client_cfstream.cc ) s.files += %w( src/core/lib/iomgr/tcp_client_custom.cc ) s.files += %w( src/core/lib/iomgr/tcp_client_posix.cc ) s.files += %w( src/core/lib/iomgr/tcp_client_windows.cc ) @@ -562,7 +589,6 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/iomgr/udp_server.cc ) s.files += %w( src/core/lib/iomgr/unix_sockets_posix.cc ) s.files += %w( src/core/lib/iomgr/unix_sockets_posix_noop.cc ) - s.files += %w( src/core/lib/iomgr/wakeup_fd_cv.cc ) s.files += %w( src/core/lib/iomgr/wakeup_fd_eventfd.cc ) s.files += %w( src/core/lib/iomgr/wakeup_fd_nospecial.cc ) s.files += %w( src/core/lib/iomgr/wakeup_fd_pipe.cc ) @@ -602,7 +628,6 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/transport/metadata.cc ) s.files += %w( src/core/lib/transport/metadata_batch.cc ) s.files += %w( src/core/lib/transport/pid_controller.cc ) - s.files += %w( src/core/lib/transport/service_config.cc ) s.files += %w( src/core/lib/transport/static_metadata.cc ) s.files += %w( src/core/lib/transport/status_conversion.cc ) s.files += %w( src/core/lib/transport/status_metadata.cc ) @@ -616,6 +641,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/transport/chttp2/transport/bin_encoder.cc ) s.files += %w( src/core/ext/transport/chttp2/transport/chttp2_plugin.cc ) s.files += %w( src/core/ext/transport/chttp2/transport/chttp2_transport.cc ) + s.files += %w( src/core/ext/transport/chttp2/transport/context_list.cc ) s.files += %w( src/core/ext/transport/chttp2/transport/flow_control.cc ) s.files += %w( src/core/ext/transport/chttp2/transport/frame_data.cc ) s.files += %w( src/core/ext/transport/chttp2/transport/frame_goaway.cc ) @@ -656,6 +682,8 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/security/credentials/oauth2/oauth2_credentials.cc ) s.files += %w( src/core/lib/security/credentials/plugin/plugin_credentials.cc ) s.files += %w( src/core/lib/security/credentials/ssl/ssl_credentials.cc ) + s.files += %w( src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc ) + s.files += %w( src/core/lib/security/credentials/tls/spiffe_credentials.cc ) s.files += %w( src/core/lib/security/security_connector/alts/alts_security_connector.cc ) s.files += %w( src/core/lib/security/security_connector/fake/fake_security_connector.cc ) s.files += %w( src/core/lib/security/security_connector/load_system_roots_fallback.cc ) @@ -664,6 +692,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/security/security_connector/security_connector.cc ) s.files += %w( src/core/lib/security/security_connector/ssl/ssl_security_connector.cc ) s.files += %w( src/core/lib/security/security_connector/ssl_utils.cc ) + s.files += %w( src/core/lib/security/security_connector/tls/spiffe_security_connector.cc ) s.files += %w( src/core/lib/security/transport/client_auth_filter.cc ) s.files += %w( src/core/lib/security/transport/secure_endpoint.cc ) s.files += %w( src/core/lib/security/transport/security_handshaker.cc ) @@ -718,21 +747,25 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/client_channel_factory.cc ) s.files += %w( src/core/ext/filters/client_channel/client_channel_plugin.cc ) s.files += %w( src/core/ext/filters/client_channel/connector.cc ) + s.files += %w( src/core/ext/filters/client_channel/global_subchannel_pool.cc ) s.files += %w( src/core/ext/filters/client_channel/health/health_check_client.cc ) s.files += %w( src/core/ext/filters/client_channel/http_connect_handshaker.cc ) s.files += %w( src/core/ext/filters/client_channel/http_proxy.cc ) s.files += %w( src/core/ext/filters/client_channel/lb_policy.cc ) - s.files += %w( src/core/ext/filters/client_channel/lb_policy_factory.cc ) s.files += %w( src/core/ext/filters/client_channel/lb_policy_registry.cc ) + s.files += %w( src/core/ext/filters/client_channel/local_subchannel_pool.cc ) s.files += %w( src/core/ext/filters/client_channel/parse_address.cc ) s.files += %w( src/core/ext/filters/client_channel/proxy_mapper.cc ) s.files += %w( src/core/ext/filters/client_channel/proxy_mapper_registry.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver_registry.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver_result_parsing.cc ) + s.files += %w( src/core/ext/filters/client_channel/resolving_lb_policy.cc ) s.files += %w( src/core/ext/filters/client_channel/retry_throttle.cc ) + s.files += %w( src/core/ext/filters/client_channel/server_address.cc ) + s.files += %w( src/core/ext/filters/client_channel/service_config.cc ) s.files += %w( src/core/ext/filters/client_channel/subchannel.cc ) - s.files += %w( src/core/ext/filters/client_channel/subchannel_index.cc ) + s.files += %w( src/core/ext/filters/client_channel/subchannel_pool_interface.cc ) s.files += %w( src/core/ext/filters/deadline/deadline_filter.cc ) s.files += %w( src/core/ext/filters/client_channel/health/health.pb.c ) s.files += %w( src/core/tsi/fake_transport_security.cc ) @@ -765,10 +798,13 @@ Gem::Specification.new do |s| 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.cc ) + s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc ) + s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc ) + s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc ) @@ -1253,6 +1289,7 @@ Gem::Specification.new do |s| s.files += %w( third_party/cares/cares/ares_setup.h ) s.files += %w( third_party/cares/cares/ares_strcasecmp.h ) s.files += %w( third_party/cares/cares/ares_strdup.h ) + s.files += %w( third_party/cares/cares/ares_strsplit.h ) s.files += %w( third_party/cares/cares/ares_version.h ) s.files += %w( third_party/cares/cares/bitncmp.h ) s.files += %w( third_party/cares/cares/config-win32.h ) @@ -1304,6 +1341,7 @@ Gem::Specification.new do |s| s.files += %w( third_party/cares/cares/ares_strcasecmp.c ) s.files += %w( third_party/cares/cares/ares_strdup.c ) s.files += %w( third_party/cares/cares/ares_strerror.c ) + s.files += %w( third_party/cares/cares/ares_strsplit.c ) s.files += %w( third_party/cares/cares/ares_timeout.c ) s.files += %w( third_party/cares/cares/ares_version.c ) s.files += %w( third_party/cares/cares/ares_writev.c ) diff --git a/grpc.gyp b/grpc.gyp index b7352f820ae..02342d441bb 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -218,7 +218,6 @@ ], 'sources': [ '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', @@ -251,23 +250,15 @@ '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/arena.cc', 'src/core/lib/gprpp/fork.cc', + 'src/core/lib/gprpp/global_config_env.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', ], }, - { - 'target_name': 'gpr_test_util', - 'type': 'static_library', - 'dependencies': [ - 'gpr', - ], - 'sources': [ - 'test/core/util/test_config.cc', - ], - }, { 'target_name': 'grpc', 'type': 'static_library', @@ -286,10 +277,10 @@ 'src/core/lib/channel/channelz_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_args.cc', 'src/core/lib/compression/compression_internal.cc', 'src/core/lib/compression/message_compress.cc', 'src/core/lib/compression/stream_compression.cc', @@ -302,12 +293,15 @@ 'src/core/lib/http/parser.cc', 'src/core/lib/iomgr/buffer_list.cc', 'src/core/lib/iomgr/call_combiner.cc', + 'src/core/lib/iomgr/cfstream_handle.cc', 'src/core/lib/iomgr/combiner.cc', 'src/core/lib/iomgr/endpoint.cc', + 'src/core/lib/iomgr/endpoint_cfstream.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/error_cfstream.cc', 'src/core/lib/iomgr/ev_epoll1_linux.cc', 'src/core/lib/iomgr/ev_epollex_linux.cc', 'src/core/lib/iomgr/ev_poll_posix.cc', @@ -320,18 +314,20 @@ '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/grpc_if_nametoindex_posix.cc', + 'src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc', 'src/core/lib/iomgr/internal_errqueue.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_posix_cfstream.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', @@ -355,6 +351,7 @@ '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_cfstream.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', @@ -379,7 +376,6 @@ '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', @@ -419,7 +415,6 @@ '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', @@ -433,6 +428,7 @@ '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/context_list.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', @@ -473,6 +469,8 @@ '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/tls/grpc_tls_credentials_options.cc', + 'src/core/lib/security/credentials/tls/spiffe_credentials.cc', 'src/core/lib/security/security_connector/alts/alts_security_connector.cc', 'src/core/lib/security/security_connector/fake/fake_security_connector.cc', 'src/core/lib/security/security_connector/load_system_roots_fallback.cc', @@ -481,6 +479,7 @@ 'src/core/lib/security/security_connector/security_connector.cc', 'src/core/lib/security/security_connector/ssl/ssl_security_connector.cc', 'src/core/lib/security/security_connector/ssl_utils.cc', + 'src/core/lib/security/security_connector/tls/spiffe_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', @@ -535,21 +534,25 @@ '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/global_subchannel_pool.cc', 'src/core/ext/filters/client_channel/health/health_check_client.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/local_subchannel_pool.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/resolver_result_parsing.cc', + 'src/core/ext/filters/client_channel/resolving_lb_policy.cc', 'src/core/ext/filters/client_channel/retry_throttle.cc', + 'src/core/ext/filters/client_channel/server_address.cc', + 'src/core/ext/filters/client_channel/service_config.cc', 'src/core/ext/filters/client_channel/subchannel.cc', - 'src/core/ext/filters/client_channel/subchannel_index.cc', + 'src/core/ext/filters/client_channel/subchannel_pool_interface.cc', 'src/core/ext/filters/deadline/deadline_filter.cc', 'src/core/ext/filters/client_channel/health/health.pb.c', 'src/core/tsi/fake_transport_security.cc', @@ -582,10 +585,13 @@ '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.cc', + 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc', + 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc', + 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc', 'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc', @@ -603,7 +609,6 @@ 'target_name': 'grpc_test_util', 'type': 'static_library', 'dependencies': [ - 'gpr_test_util', 'gpr', 'grpc', ], @@ -616,6 +621,7 @@ 'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc', 'test/core/end2end/cq_verifier.cc', 'test/core/end2end/fixtures/http_proxy_fixture.cc', + 'test/core/end2end/fixtures/local_util.cc', 'test/core/end2end/fixtures/proxy.cc', 'test/core/iomgr/endpoint_tests.cc', 'test/core/util/debugger_macros.cc', @@ -632,6 +638,8 @@ 'test/core/util/slice_splitter.cc', 'test/core/util/subprocess_posix.cc', 'test/core/util/subprocess_windows.cc', + 'test/core/util/test_config.cc', + 'test/core/util/test_lb_policies.cc', 'test/core/util/tracer_util.cc', 'test/core/util/trickle_endpoint.cc', 'test/core/util/cmdline.cc', @@ -645,10 +653,10 @@ 'src/core/lib/channel/channelz_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_args.cc', 'src/core/lib/compression/compression_internal.cc', 'src/core/lib/compression/message_compress.cc', 'src/core/lib/compression/stream_compression.cc', @@ -661,12 +669,15 @@ 'src/core/lib/http/parser.cc', 'src/core/lib/iomgr/buffer_list.cc', 'src/core/lib/iomgr/call_combiner.cc', + 'src/core/lib/iomgr/cfstream_handle.cc', 'src/core/lib/iomgr/combiner.cc', 'src/core/lib/iomgr/endpoint.cc', + 'src/core/lib/iomgr/endpoint_cfstream.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/error_cfstream.cc', 'src/core/lib/iomgr/ev_epoll1_linux.cc', 'src/core/lib/iomgr/ev_epollex_linux.cc', 'src/core/lib/iomgr/ev_poll_posix.cc', @@ -679,18 +690,20 @@ '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/grpc_if_nametoindex_posix.cc', + 'src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc', 'src/core/lib/iomgr/internal_errqueue.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_posix_cfstream.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', @@ -714,6 +727,7 @@ '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_cfstream.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', @@ -738,7 +752,6 @@ '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', @@ -778,7 +791,6 @@ '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', @@ -794,21 +806,25 @@ '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/global_subchannel_pool.cc', 'src/core/ext/filters/client_channel/health/health_check_client.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/local_subchannel_pool.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/resolver_result_parsing.cc', + 'src/core/ext/filters/client_channel/resolving_lb_policy.cc', 'src/core/ext/filters/client_channel/retry_throttle.cc', + 'src/core/ext/filters/client_channel/server_address.cc', + 'src/core/ext/filters/client_channel/service_config.cc', 'src/core/ext/filters/client_channel/subchannel.cc', - 'src/core/ext/filters/client_channel/subchannel_index.cc', + 'src/core/ext/filters/client_channel/subchannel_pool_interface.cc', 'src/core/ext/filters/deadline/deadline_filter.cc', 'src/core/ext/filters/client_channel/health/health.pb.c', 'third_party/nanopb/pb_common.c', @@ -818,6 +834,7 @@ '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/context_list.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', @@ -848,13 +865,13 @@ 'type': 'static_library', 'dependencies': [ 'gpr', - 'gpr_test_util', 'grpc_unsecure', ], 'sources': [ 'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc', 'test/core/end2end/cq_verifier.cc', 'test/core/end2end/fixtures/http_proxy_fixture.cc', + 'test/core/end2end/fixtures/local_util.cc', 'test/core/end2end/fixtures/proxy.cc', 'test/core/iomgr/endpoint_tests.cc', 'test/core/util/debugger_macros.cc', @@ -871,6 +888,8 @@ 'test/core/util/slice_splitter.cc', 'test/core/util/subprocess_posix.cc', 'test/core/util/subprocess_windows.cc', + 'test/core/util/test_config.cc', + 'test/core/util/test_lb_policies.cc', 'test/core/util/tracer_util.cc', 'test/core/util/trickle_endpoint.cc', 'test/core/util/cmdline.cc', @@ -884,10 +903,10 @@ 'src/core/lib/channel/channelz_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_args.cc', 'src/core/lib/compression/compression_internal.cc', 'src/core/lib/compression/message_compress.cc', 'src/core/lib/compression/stream_compression.cc', @@ -900,12 +919,15 @@ 'src/core/lib/http/parser.cc', 'src/core/lib/iomgr/buffer_list.cc', 'src/core/lib/iomgr/call_combiner.cc', + 'src/core/lib/iomgr/cfstream_handle.cc', 'src/core/lib/iomgr/combiner.cc', 'src/core/lib/iomgr/endpoint.cc', + 'src/core/lib/iomgr/endpoint_cfstream.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/error_cfstream.cc', 'src/core/lib/iomgr/ev_epoll1_linux.cc', 'src/core/lib/iomgr/ev_epollex_linux.cc', 'src/core/lib/iomgr/ev_poll_posix.cc', @@ -918,18 +940,20 @@ '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/grpc_if_nametoindex_posix.cc', + 'src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc', 'src/core/lib/iomgr/internal_errqueue.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_posix_cfstream.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', @@ -953,6 +977,7 @@ '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_cfstream.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', @@ -977,7 +1002,6 @@ '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', @@ -1017,7 +1041,6 @@ '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', @@ -1033,21 +1056,25 @@ '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/global_subchannel_pool.cc', 'src/core/ext/filters/client_channel/health/health_check_client.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/local_subchannel_pool.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/resolver_result_parsing.cc', + 'src/core/ext/filters/client_channel/resolving_lb_policy.cc', 'src/core/ext/filters/client_channel/retry_throttle.cc', + 'src/core/ext/filters/client_channel/server_address.cc', + 'src/core/ext/filters/client_channel/service_config.cc', 'src/core/ext/filters/client_channel/subchannel.cc', - 'src/core/ext/filters/client_channel/subchannel_index.cc', + 'src/core/ext/filters/client_channel/subchannel_pool_interface.cc', 'src/core/ext/filters/deadline/deadline_filter.cc', 'src/core/ext/filters/client_channel/health/health.pb.c', 'third_party/nanopb/pb_common.c', @@ -1057,6 +1084,7 @@ '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/context_list.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', @@ -1101,10 +1129,10 @@ 'src/core/lib/channel/channelz_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_args.cc', 'src/core/lib/compression/compression_internal.cc', 'src/core/lib/compression/message_compress.cc', 'src/core/lib/compression/stream_compression.cc', @@ -1117,12 +1145,15 @@ 'src/core/lib/http/parser.cc', 'src/core/lib/iomgr/buffer_list.cc', 'src/core/lib/iomgr/call_combiner.cc', + 'src/core/lib/iomgr/cfstream_handle.cc', 'src/core/lib/iomgr/combiner.cc', 'src/core/lib/iomgr/endpoint.cc', + 'src/core/lib/iomgr/endpoint_cfstream.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/error_cfstream.cc', 'src/core/lib/iomgr/ev_epoll1_linux.cc', 'src/core/lib/iomgr/ev_epollex_linux.cc', 'src/core/lib/iomgr/ev_poll_posix.cc', @@ -1135,18 +1166,20 @@ '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/grpc_if_nametoindex_posix.cc', + 'src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc', 'src/core/lib/iomgr/internal_errqueue.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_posix_cfstream.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', @@ -1170,6 +1203,7 @@ '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_cfstream.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', @@ -1194,7 +1228,6 @@ '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', @@ -1234,7 +1267,6 @@ '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', @@ -1249,6 +1281,7 @@ '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/context_list.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', @@ -1284,21 +1317,25 @@ '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/global_subchannel_pool.cc', 'src/core/ext/filters/client_channel/health/health_check_client.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/local_subchannel_pool.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/resolver_result_parsing.cc', + 'src/core/ext/filters/client_channel/resolving_lb_policy.cc', 'src/core/ext/filters/client_channel/retry_throttle.cc', + 'src/core/ext/filters/client_channel/server_address.cc', + 'src/core/ext/filters/client_channel/service_config.cc', 'src/core/ext/filters/client_channel/subchannel.cc', - 'src/core/ext/filters/client_channel/subchannel_index.cc', + 'src/core/ext/filters/client_channel/subchannel_pool_interface.cc', 'src/core/ext/filters/deadline/deadline_filter.cc', 'src/core/ext/filters/client_channel/health/health.pb.c', 'third_party/nanopb/pb_common.c', @@ -1308,10 +1345,13 @@ 'src/core/ext/transport/inproc/inproc_transport.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.cc', + 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc', + 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc', + 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc', 'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc', @@ -1347,7 +1387,6 @@ 'test_tcp_server', 'grpc_test_util', 'grpc', - 'gpr_test_util', 'gpr', ], 'sources': [ @@ -1360,13 +1399,39 @@ 'dependencies': [ 'grpc_test_util', 'grpc', - 'gpr_test_util', 'gpr', ], 'sources': [ 'test/core/util/test_tcp_server.cc', ], }, + { + 'target_name': 'bm_callback_test_service_impl', + 'type': 'static_library', + 'dependencies': [ + 'grpc_benchmark', + 'benchmark', + 'grpc++_test_util_unsecure', + 'grpc_test_util_unsecure', + 'grpc++_unsecure', + 'grpc_unsecure', + 'gpr', + 'grpc++_test_config', + ], + 'sources': [ + 'src/proto/grpc/testing/echo.proto', + 'test/cpp/microbenchmarks/callback_test_service.cc', + ], + }, + { + 'target_name': 'dns_test_util', + 'type': 'static_library', + 'dependencies': [ + ], + 'sources': [ + 'test/cpp/naming/dns_test_util.cc', + ], + }, { 'target_name': 'grpc++', 'type': 'static_library', @@ -1493,6 +1558,8 @@ 'src/proto/grpc/testing/echo_messages.proto', 'src/proto/grpc/testing/echo.proto', 'src/proto/grpc/testing/duplicate/echo_duplicate.proto', + 'src/proto/grpc/testing/simple_messages.proto', + 'test/cpp/end2end/test_health_check_service_impl.cc', 'test/cpp/end2end/test_service_impl.cc', 'test/cpp/util/byte_buffer_proto_helper.cc', 'test/cpp/util/channel_trace_proto_helper.cc', @@ -1516,6 +1583,8 @@ 'src/proto/grpc/testing/echo_messages.proto', 'src/proto/grpc/testing/echo.proto', 'src/proto/grpc/testing/duplicate/echo_duplicate.proto', + 'src/proto/grpc/testing/simple_messages.proto', + 'test/cpp/end2end/test_health_check_service_impl.cc', 'test/cpp/end2end/test_service_impl.cc', 'test/cpp/util/byte_buffer_proto_helper.cc', 'test/cpp/util/string_ref_helper.cc', @@ -1673,7 +1742,6 @@ 'grpc_test_util', 'grpc++', 'grpc', - 'gpr_test_util', 'gpr', 'grpc++_test_config', ], @@ -1708,7 +1776,6 @@ 'grpc_test_util', 'grpc++', 'grpc', - 'gpr_test_util', 'gpr', 'grpc++_test_config', ], @@ -2049,567 +2116,6 @@ 'third_party/boringssl/crypto/test/test_util.cc', ], }, - { - 'target_name': 'boringssl_crypto_test_data_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'src/boringssl/crypto_test_data.cc', - ], - }, - { - 'target_name': 'boringssl_asn1_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/asn1/asn1_test.cc', - ], - }, - { - 'target_name': 'boringssl_base64_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/base64/base64_test.cc', - ], - }, - { - 'target_name': 'boringssl_bio_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/bio/bio_test.cc', - ], - }, - { - 'target_name': 'boringssl_buf_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/buf/buf_test.cc', - ], - }, - { - 'target_name': 'boringssl_bytestring_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/bytestring/bytestring_test.cc', - ], - }, - { - 'target_name': 'boringssl_chacha_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/chacha/chacha_test.cc', - ], - }, - { - 'target_name': 'boringssl_aead_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/cipher_extra/aead_test.cc', - ], - }, - { - 'target_name': 'boringssl_cipher_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/cipher_extra/cipher_test.cc', - ], - }, - { - 'target_name': 'boringssl_cmac_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/cmac/cmac_test.cc', - ], - }, - { - 'target_name': 'boringssl_compiler_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/compiler_test.cc', - ], - }, - { - 'target_name': 'boringssl_constant_time_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/constant_time_test.cc', - ], - }, - { - 'target_name': 'boringssl_ed25519_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/curve25519/ed25519_test.cc', - ], - }, - { - 'target_name': 'boringssl_spake25519_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/curve25519/spake25519_test.cc', - ], - }, - { - 'target_name': 'boringssl_x25519_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/curve25519/x25519_test.cc', - ], - }, - { - 'target_name': 'boringssl_dh_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/dh/dh_test.cc', - ], - }, - { - 'target_name': 'boringssl_digest_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/digest_extra/digest_test.cc', - ], - }, - { - 'target_name': 'boringssl_dsa_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/dsa/dsa_test.cc', - ], - }, - { - 'target_name': 'boringssl_ecdh_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/ecdh/ecdh_test.cc', - ], - }, - { - 'target_name': 'boringssl_err_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/err/err_test.cc', - ], - }, - { - 'target_name': 'boringssl_evp_extra_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/evp/evp_extra_test.cc', - ], - }, - { - 'target_name': 'boringssl_evp_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/evp/evp_test.cc', - ], - }, - { - 'target_name': 'boringssl_pbkdf_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/evp/pbkdf_test.cc', - ], - }, - { - 'target_name': 'boringssl_scrypt_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/evp/scrypt_test.cc', - ], - }, - { - 'target_name': 'boringssl_aes_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/fipsmodule/aes/aes_test.cc', - ], - }, - { - 'target_name': 'boringssl_bn_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/fipsmodule/bn/bn_test.cc', - ], - }, - { - 'target_name': 'boringssl_ec_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/fipsmodule/ec/ec_test.cc', - ], - }, - { - 'target_name': 'boringssl_p256-x86_64_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/fipsmodule/ec/p256-x86_64_test.cc', - ], - }, - { - 'target_name': 'boringssl_ecdsa_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/fipsmodule/ecdsa/ecdsa_test.cc', - ], - }, - { - 'target_name': 'boringssl_gcm_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/fipsmodule/modes/gcm_test.cc', - ], - }, - { - 'target_name': 'boringssl_ctrdrbg_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/fipsmodule/rand/ctrdrbg_test.cc', - ], - }, - { - 'target_name': 'boringssl_hkdf_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/hkdf/hkdf_test.cc', - ], - }, - { - 'target_name': 'boringssl_hmac_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/hmac_extra/hmac_test.cc', - ], - }, - { - 'target_name': 'boringssl_lhash_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/lhash/lhash_test.cc', - ], - }, - { - 'target_name': 'boringssl_obj_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/obj/obj_test.cc', - ], - }, - { - 'target_name': 'boringssl_pkcs7_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/pkcs7/pkcs7_test.cc', - ], - }, - { - 'target_name': 'boringssl_pkcs12_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/pkcs8/pkcs12_test.cc', - ], - }, - { - 'target_name': 'boringssl_pkcs8_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/pkcs8/pkcs8_test.cc', - ], - }, - { - 'target_name': 'boringssl_poly1305_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/poly1305/poly1305_test.cc', - ], - }, - { - 'target_name': 'boringssl_pool_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/pool/pool_test.cc', - ], - }, - { - 'target_name': 'boringssl_refcount_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/refcount_test.cc', - ], - }, - { - 'target_name': 'boringssl_rsa_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/rsa_extra/rsa_test.cc', - ], - }, - { - 'target_name': 'boringssl_self_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/self_test.cc', - ], - }, - { - 'target_name': 'boringssl_file_test_gtest_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/test/file_test_gtest.cc', - ], - }, - { - 'target_name': 'boringssl_gtest_main_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/test/gtest_main.cc', - ], - }, - { - 'target_name': 'boringssl_thread_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/thread_test.cc', - ], - }, - { - 'target_name': 'boringssl_x509_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/x509/x509_test.cc', - ], - }, - { - 'target_name': 'boringssl_tab_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/x509v3/tab_test.cc', - ], - }, - { - 'target_name': 'boringssl_v3name_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/x509v3/v3name_test.cc', - ], - }, - { - 'target_name': 'boringssl_span_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/ssl/span_test.cc', - ], - }, - { - 'target_name': 'boringssl_ssl_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/ssl/ssl_test.cc', - ], - }, { 'target_name': 'benchmark', 'type': 'static_library', @@ -2617,6 +2123,7 @@ ], 'sources': [ 'third_party/benchmark/src/benchmark.cc', + 'third_party/benchmark/src/benchmark_main.cc', 'third_party/benchmark/src/benchmark_register.cc', 'third_party/benchmark/src/colorprint.cc', 'third_party/benchmark/src/commandlineflags.cc', @@ -2627,11 +2134,30 @@ 'third_party/benchmark/src/json_reporter.cc', 'third_party/benchmark/src/reporter.cc', 'third_party/benchmark/src/sleep.cc', + 'third_party/benchmark/src/statistics.cc', 'third_party/benchmark/src/string_util.cc', 'third_party/benchmark/src/sysinfo.cc', 'third_party/benchmark/src/timers.cc', ], }, + { + 'target_name': 'upb', + 'type': 'static_library', + 'dependencies': [ + ], + 'sources': [ + 'third_party/upb/google/protobuf/descriptor.upb.c', + 'third_party/upb/upb/decode.c', + 'third_party/upb/upb/def.c', + 'third_party/upb/upb/encode.c', + 'third_party/upb/upb/handlers.c', + 'third_party/upb/upb/msg.c', + 'third_party/upb/upb/msgfactory.c', + 'third_party/upb/upb/sink.c', + 'third_party/upb/upb/table.c', + 'third_party/upb/upb/upb.c', + ], + }, { 'target_name': 'z', 'type': 'static_library', @@ -2661,7 +2187,6 @@ 'dependencies': [ 'grpc_test_util_unsecure', 'grpc_unsecure', - 'gpr_test_util', 'gpr', ], 'sources': [ @@ -2674,7 +2199,6 @@ 'dependencies': [ 'grpc_test_util', 'grpc', - 'gpr_test_util', 'gpr', ], 'sources': [ @@ -2701,6 +2225,7 @@ 'test/core/end2end/tests/empty_batch.cc', 'test/core/end2end/tests/filter_call_init_fails.cc', 'test/core/end2end/tests/filter_causes_close.cc', + 'test/core/end2end/tests/filter_context.cc', 'test/core/end2end/tests/filter_latency.cc', 'test/core/end2end/tests/filter_status_code.cc', 'test/core/end2end/tests/graceful_server_shutdown.cc', @@ -2715,7 +2240,6 @@ 'test/core/end2end/tests/max_connection_idle.cc', 'test/core/end2end/tests/max_message_length.cc', 'test/core/end2end/tests/negative_deadline.cc', - 'test/core/end2end/tests/network_status_change.cc', 'test/core/end2end/tests/no_error_on_hotpath.cc', 'test/core/end2end/tests/no_logging.cc', 'test/core/end2end/tests/no_op.cc', @@ -2766,7 +2290,6 @@ 'dependencies': [ 'grpc_test_util_unsecure', 'grpc_unsecure', - 'gpr_test_util', 'gpr', ], 'sources': [ @@ -2792,6 +2315,7 @@ 'test/core/end2end/tests/empty_batch.cc', 'test/core/end2end/tests/filter_call_init_fails.cc', 'test/core/end2end/tests/filter_causes_close.cc', + 'test/core/end2end/tests/filter_context.cc', 'test/core/end2end/tests/filter_latency.cc', 'test/core/end2end/tests/filter_status_code.cc', 'test/core/end2end/tests/graceful_server_shutdown.cc', @@ -2806,7 +2330,6 @@ 'test/core/end2end/tests/max_connection_idle.cc', 'test/core/end2end/tests/max_message_length.cc', 'test/core/end2end/tests/negative_deadline.cc', - 'test/core/end2end/tests/network_status_change.cc', 'test/core/end2end/tests/no_error_on_hotpath.cc', 'test/core/end2end/tests/no_logging.cc', 'test/core/end2end/tests/no_op.cc', diff --git a/include/grpc/grpc.h b/include/grpc/grpc.h index d3b74cabab5..9a99e016a93 100644 --- a/include/grpc/grpc.h +++ b/include/grpc/grpc.h @@ -73,10 +73,11 @@ GRPCAPI void grpc_init(void); Before it's called, there should haven been a matching invocation to grpc_init(). - No memory is used by grpc after this call returns, nor are any instructions - executing within the grpc library. - Prior to calling, all application owned grpc objects must have been - destroyed. */ + The last call to grpc_shutdown will initiate cleaning up of grpc library + internals, which can happen in another thread. Once the clean-up is done, + no memory is used by grpc, nor are any instructions executing within the + grpc library. Prior to calling, all application owned grpc objects must + have been destroyed. */ GRPCAPI void grpc_shutdown(void); /** EXPERIMENTAL. Returns 1 if the grpc library has been initialized. @@ -85,6 +86,10 @@ GRPCAPI void grpc_shutdown(void); https://github.com/grpc/grpc/issues/15334 */ GRPCAPI int grpc_is_initialized(void); +/** EXPERIMENTAL. Blocking shut down grpc library. + This is only for wrapped language to use now. */ +GRPCAPI void grpc_shutdown_blocking(void); + /** Return a string representing the current version of grpc */ GRPCAPI const char* grpc_version_string(void); @@ -318,14 +323,14 @@ GRPCAPI void grpc_channel_destroy(grpc_channel* channel); If a grpc_call fails, it's guaranteed that no change to the call state has been made. */ -/** Called by clients to cancel an RPC on the server. +/** Cancel an RPC. Can be called multiple times, from any thread. THREAD-SAFETY grpc_call_cancel and grpc_call_cancel_with_status are thread-safe, and can be called at any point before grpc_call_unref is called.*/ GRPCAPI grpc_call_error grpc_call_cancel(grpc_call* call, void* reserved); -/** Called by clients to cancel an RPC on the server. +/** Cancel an RPC. Can be called multiple times, from any thread. If a status has not been received for the call, set it to the status code and description passed in. @@ -511,7 +516,8 @@ GRPCAPI char* grpc_channelz_get_server(intptr_t server_id); /* Gets all server sockets that exist in the server. */ GRPCAPI char* grpc_channelz_get_server_sockets(intptr_t server_id, - intptr_t start_socket_id); + intptr_t start_socket_id, + intptr_t max_results); /* Returns a single Channel, or else a NOT_FOUND code. The returned string is allocated and must be freed by the application. */ diff --git a/include/grpc/grpc_security.h b/include/grpc/grpc_security.h index de90971cc55..ebdf86b7d50 100644 --- a/include/grpc/grpc_security.h +++ b/include/grpc/grpc_security.h @@ -191,6 +191,15 @@ typedef struct { try to get the roots set by grpc_override_ssl_default_roots. Eventually, if all these fail, it will try to get the roots from a well-known place on disk (in the grpc install directory). + + gRPC has implemented root cache if the underlying OpenSSL library supports + it. The gRPC root certificates cache is only applicable on the default + root certificates, which is used when this parameter is nullptr. If user + provides their own pem_root_certs, when creating an SSL credential object, + gRPC would not be able to cache it, and each subchannel will generate a + copy of the root store. So it is recommended to avoid providing large room + pem with pem_root_certs parameter to avoid excessive memory consumption, + particularly on mobile platforms such as iOS. - pem_key_cert_pair is a pointer on the object containing client's private key and certificate chain. This parameter can be NULL if the client does not have such a key/cert pair. @@ -255,7 +264,7 @@ GRPCAPI grpc_call_credentials* grpc_google_refresh_token_credentials_create( const char* json_refresh_token, void* reserved); /** Creates an Oauth2 Access Token credentials with an access token that was - aquired by an out of band mechanism. */ + acquired by an out of band mechanism. */ GRPCAPI grpc_call_credentials* grpc_access_token_credentials_create( const char* access_token, void* reserved); @@ -609,6 +618,235 @@ GRPCAPI grpc_channel_credentials* grpc_local_credentials_create( GRPCAPI grpc_server_credentials* grpc_local_server_credentials_create( grpc_local_connect_type type); +/** --- SPIFFE and HTTPS-based TLS channel/server credentials --- + * It is used for experimental purpose for now and subject to change. */ + +/** Config for TLS key materials. It is used for + * experimental purpose for now and subject to change. */ +typedef struct grpc_tls_key_materials_config grpc_tls_key_materials_config; + +/** Config for TLS credential reload. It is used for + * experimental purpose for now and subject to change. */ +typedef struct grpc_tls_credential_reload_config + grpc_tls_credential_reload_config; + +/** Config for TLS server authorization check. It is used for + * experimental purpose for now and subject to change. */ +typedef struct grpc_tls_server_authorization_check_config + grpc_tls_server_authorization_check_config; + +/** TLS credentials options. It is used for + * experimental purpose for now and subject to change. */ +typedef struct grpc_tls_credentials_options grpc_tls_credentials_options; + +/** Create an empty TLS credentials options. It is used for + * experimental purpose for now and subject to change. */ +GRPCAPI grpc_tls_credentials_options* grpc_tls_credentials_options_create(void); + +/** Set grpc_ssl_client_certificate_request_type field in credentials options + with the provided type. options should not be NULL. + It returns 1 on success and 0 on failure. It is used for + experimental purpose for now and subject to change. */ +GRPCAPI int grpc_tls_credentials_options_set_cert_request_type( + grpc_tls_credentials_options* options, + grpc_ssl_client_certificate_request_type type); + +/** Set grpc_tls_key_materials_config field in credentials options + with the provided config struct whose ownership is transferred. + Both parameters should not be NULL. + It returns 1 on success and 0 on failure. It is used for + experimental purpose for now and subject to change. */ +GRPCAPI int grpc_tls_credentials_options_set_key_materials_config( + grpc_tls_credentials_options* options, + grpc_tls_key_materials_config* config); + +/** Set grpc_tls_credential_reload_config field in credentials options + with the provided config struct whose ownership is transferred. + Both parameters should not be NULL. + It returns 1 on success and 0 on failure. It is used for + experimental purpose for now and subject to change. */ +GRPCAPI int grpc_tls_credentials_options_set_credential_reload_config( + grpc_tls_credentials_options* options, + grpc_tls_credential_reload_config* config); + +/** Set grpc_tls_server_authorization_check_config field in credentials options + with the provided config struct whose ownership is transferred. + Both parameters should not be NULL. + It returns 1 on success and 0 on failure. It is used for + experimental purpose for now and subject to change. */ +GRPCAPI int grpc_tls_credentials_options_set_server_authorization_check_config( + grpc_tls_credentials_options* options, + grpc_tls_server_authorization_check_config* config); + +/** --- TLS key materials config. --- + It is used for experimental purpose for now and subject to change. */ + +/** Create an empty grpc_tls_key_materials_config instance. + * It is used for experimental purpose for now and subject to change. */ +GRPCAPI grpc_tls_key_materials_config* grpc_tls_key_materials_config_create( + void); + +/** Set grpc_tls_key_materials_config instance with provided a TLS certificate. + config will take the ownership of pem_root_certs and pem_key_cert_pairs. + It's valid for the caller to provide nullptr pem_root_certs, in which case + the gRPC-provided root cert will be used. pem_key_cert_pairs should not be + NULL. It returns 1 on success and 0 on failure. It is used for + experimental purpose for now and subject to change. + */ +GRPCAPI int grpc_tls_key_materials_config_set_key_materials( + grpc_tls_key_materials_config* config, const char* pem_root_certs, + const grpc_ssl_pem_key_cert_pair** pem_key_cert_pairs, + size_t num_key_cert_pairs); + +/** --- TLS credential reload config. --- + It is used for experimental purpose for now and subject to change.*/ + +typedef struct grpc_tls_credential_reload_arg grpc_tls_credential_reload_arg; + +/** A callback function provided by gRPC to handle the result of credential + reload. It is used when schedule API is implemented asynchronously and + serves to bring the control back to grpc C core. It is used for + experimental purpose for now and subject to change. */ +typedef void (*grpc_tls_on_credential_reload_done_cb)( + grpc_tls_credential_reload_arg* arg); + +/** A struct containing all information necessary to schedule/cancel + a credential reload request. cb and cb_user_data represent a gRPC-provided + callback and an argument passed to it. key_materials is an in/output + parameter containing currently used/newly reloaded credentials. status and + error_details are used to hold information about errors occurred when a + credential reload request is scheduled/cancelled. It is used for + experimental purpose for now and subject to change. */ +struct grpc_tls_credential_reload_arg { + grpc_tls_on_credential_reload_done_cb cb; + void* cb_user_data; + grpc_tls_key_materials_config* key_materials_config; + grpc_ssl_certificate_config_reload_status status; + const char* error_details; +}; + +/** Create a grpc_tls_credential_reload_config instance. + - config_user_data is config-specific, read-only user data + that works for all channels created with a credential using the config. + - schedule is a pointer to an application-provided callback used to invoke + credential reload API. The implementation of this method has to be + non-blocking, but can be performed synchronously or asynchronously. + 1) If processing occurs synchronously, it populates arg->key_materials, + arg->status, and arg->error_details and returns zero. + 2) If processing occurs asynchronously, it returns a non-zero value. + The application then invokes arg->cb when processing is completed. Note + that arg->cb cannot be invoked before schedule API returns. + - cancel is a pointer to an application-provided callback used to cancel + a credential reload request scheduled via an asynchronous schedule API. + arg is used to pinpoint an exact reloading request to be cancelled. + The operation may not have any effect if the request has already been + processed. + - destruct is a pointer to an application-provided callback used to clean up + any data associated with the config. + It is used for experimental purpose for now and subject to change. +*/ +GRPCAPI grpc_tls_credential_reload_config* +grpc_tls_credential_reload_config_create( + const void* config_user_data, + int (*schedule)(void* config_user_data, + grpc_tls_credential_reload_arg* arg), + void (*cancel)(void* config_user_data, grpc_tls_credential_reload_arg* arg), + void (*destruct)(void* config_user_data)); + +/** --- TLS server authorization check config. --- + * It is used for experimental purpose for now and subject to change. */ + +typedef struct grpc_tls_server_authorization_check_arg + grpc_tls_server_authorization_check_arg; + +/** callback function provided by gRPC used to handle the result of server + authorization check. It is used when schedule API is implemented + asynchronously, and serves to bring the control back to gRPC C core. It is + used for experimental purpose for now and subject to change. */ +typedef void (*grpc_tls_on_server_authorization_check_done_cb)( + grpc_tls_server_authorization_check_arg* arg); + +/** A struct containing all information necessary to schedule/cancel a server + authorization check request. cb and cb_user_data represent a gRPC-provided + callback and an argument passed to it. success will store the result of + server authorization check. That is, if success returns a non-zero value, it + means the authorization check passes and if returning zero, it means the + check fails. target_name is the name of an endpoint the channel is connecting + to and certificate represents a complete certificate chain including both + signing and leaf certificates. status and error_details contain information + about errors occurred when a server authorization check request is + scheduled/cancelled. It is used for experimental purpose for now and subject + to change.*/ +struct grpc_tls_server_authorization_check_arg { + grpc_tls_on_server_authorization_check_done_cb cb; + void* cb_user_data; + int success; + const char* target_name; + const char* peer_cert; + grpc_status_code status; + const char* error_details; +}; + +/** Create a grpc_tls_server_authorization_check_config instance. + - config_user_data is config-specific, read-only user data + that works for all channels created with a credential using the config. + - schedule is a pointer to an application-provided callback used to invoke + server authorization check API. The implementation of this method has to + be non-blocking, but can be performed synchronously or asynchronously. + 1)If processing occurs synchronously, it populates arg->result, + arg->status, and arg->error_details and returns zero. + 2) If processing occurs asynchronously, it returns a non-zero value. The + application then invokes arg->cb when processing is completed. Note that + arg->cb cannot be invoked before schedule API returns. + - cancel is a pointer to an application-provided callback used to cancel a + server authorization check request scheduled via an asynchronous schedule + API. arg is used to pinpoint an exact check request to be cancelled. The + operation may not have any effect if the request has already been + processed. + - destruct is a pointer to an application-provided callback used to clean up + any data associated with the config. + It is used for experimental purpose for now and subject to change. +*/ +GRPCAPI grpc_tls_server_authorization_check_config* +grpc_tls_server_authorization_check_config_create( + const void* config_user_data, + int (*schedule)(void* config_user_data, + grpc_tls_server_authorization_check_arg* arg), + void (*cancel)(void* config_user_data, + grpc_tls_server_authorization_check_arg* arg), + void (*destruct)(void* config_user_data)); + +/** --- SPIFFE channel/server credentials --- **/ + +/** + * This method creates a TLS SPIFFE channel credential object. + * It takes ownership of the options parameter. + * + * - options: grpc TLS credentials options instance. + * + * It returns the created credential object. + * + * It is used for experimental purpose for now and subject + * to change. + */ + +grpc_channel_credentials* grpc_tls_spiffe_credentials_create( + grpc_tls_credentials_options* options); + +/** + * This method creates a TLS server credential object. + * It takes ownership of the options parameter. + * + * - options: grpc TLS credentials options instance. + * + * It returns the created credential object. + * + * It is used for experimental purpose for now and subject + * to change. + */ +grpc_server_credentials* grpc_tls_spiffe_server_credentials_create( + grpc_tls_credentials_options* options); + #ifdef __cplusplus } #endif diff --git a/include/grpc/grpc_security_constants.h b/include/grpc/grpc_security_constants.h index f935557f2d4..a082f670107 100644 --- a/include/grpc/grpc_security_constants.h +++ b/include/grpc/grpc_security_constants.h @@ -106,10 +106,10 @@ typedef enum { } grpc_ssl_client_certificate_request_type; /** - * Type of local connection for which local channel/server credentials will be - * applied. It only supports UDS for now. + * Type of local connections for which local channel/server credentials will be + * applied. It supports UDS and local TCP connections. */ -typedef enum { UDS = 0 } grpc_local_connect_type; +typedef enum { UDS = 0, LOCAL_TCP } grpc_local_connect_type; #ifdef __cplusplus } diff --git a/include/grpc/impl/codegen/atm_gcc_sync.h b/include/grpc/impl/codegen/atm_gcc_sync.h index c0010a3469d..728c3d5412f 100644 --- a/include/grpc/impl/codegen/atm_gcc_sync.h +++ b/include/grpc/impl/codegen/atm_gcc_sync.h @@ -26,6 +26,8 @@ typedef intptr_t gpr_atm; #define GPR_ATM_MAX INTPTR_MAX #define GPR_ATM_MIN INTPTR_MIN +#define GPR_ATM_INC_CAS_THEN(blah) blah +#define GPR_ATM_INC_ADD_THEN(blah) blah #define GPR_ATM_COMPILE_BARRIER_() __asm__ __volatile__("" : : : "memory") diff --git a/include/grpc/impl/codegen/atm_windows.h b/include/grpc/impl/codegen/atm_windows.h index f6b27e5df70..c016b90095f 100644 --- a/include/grpc/impl/codegen/atm_windows.h +++ b/include/grpc/impl/codegen/atm_windows.h @@ -25,6 +25,8 @@ typedef intptr_t gpr_atm; #define GPR_ATM_MAX INTPTR_MAX #define GPR_ATM_MIN INTPTR_MIN +#define GPR_ATM_INC_CAS_THEN(blah) blah +#define GPR_ATM_INC_ADD_THEN(blah) blah #define gpr_atm_full_barrier MemoryBarrier diff --git a/include/grpc/impl/codegen/byte_buffer.h b/include/grpc/impl/codegen/byte_buffer.h index 774655ed66f..12479068155 100644 --- a/include/grpc/impl/codegen/byte_buffer.h +++ b/include/grpc/impl/codegen/byte_buffer.h @@ -73,6 +73,19 @@ GRPCAPI void grpc_byte_buffer_reader_destroy(grpc_byte_buffer_reader* reader); GRPCAPI int grpc_byte_buffer_reader_next(grpc_byte_buffer_reader* reader, grpc_slice* slice); +/** EXPERIMENTAL API - This function may be removed and changed, in the future. + * + * Updates \a slice with the next piece of data from from \a reader and returns + * 1. Returns 0 at the end of the stream. Caller is responsible for making sure + * the slice pointer remains valid when accessed. + * + * NOTE: Do not use this function unless the caller can guarantee that the + * underlying grpc_byte_buffer outlasts the use of the slice. This is only + * safe when the underlying grpc_byte_buffer remains immutable while slice + * is being accessed. */ +GRPCAPI int grpc_byte_buffer_reader_peek(grpc_byte_buffer_reader* reader, + grpc_slice** slice); + /** Merge all data from \a reader into single slice */ GRPCAPI grpc_slice grpc_byte_buffer_reader_readall(grpc_byte_buffer_reader* reader); diff --git a/include/grpc/impl/codegen/compression_types.h b/include/grpc/impl/codegen/compression_types.h index e35d8929678..f778b005b9b 100644 --- a/include/grpc/impl/codegen/compression_types.h +++ b/include/grpc/impl/codegen/compression_types.h @@ -52,7 +52,8 @@ extern "C" { "grpc.compression_enabled_algorithms_bitset" /** \} */ -/** The various compression algorithms supported by gRPC */ +/** The various compression algorithms supported by gRPC (not sorted by + * compression level) */ typedef enum { GRPC_COMPRESS_NONE = 0, GRPC_COMPRESS_DEFLATE, diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h index 17a43fab0f1..65582e6e85d 100644 --- a/include/grpc/impl/codegen/grpc_types.h +++ b/include/grpc/impl/codegen/grpc_types.h @@ -163,7 +163,7 @@ typedef struct { /** Maximum time that a channel may exist. Int valued, milliseconds. * INT_MAX means unlimited. */ #define GRPC_ARG_MAX_CONNECTION_AGE_MS "grpc.max_connection_age_ms" -/** Grace period after the chennel reaches its max age. Int valued, +/** Grace period after the channel reaches its max age. Int valued, milliseconds. INT_MAX means unlimited. */ #define GRPC_ARG_MAX_CONNECTION_AGE_GRACE_MS "grpc.max_connection_age_grace_ms" /** Enable/disable support for per-message compression. Defaults to 1, unless @@ -293,7 +293,7 @@ typedef struct { "grpc.max_channel_trace_event_memory_per_node" /** If non-zero, gRPC library will track stats and information at at per channel * level. Disabling channelz naturally disables channel tracing. The default - * is for channelz to be disabled. */ + * is for channelz to be enabled. */ #define GRPC_ARG_ENABLE_CHANNELZ "grpc.enable_channelz" /** If non-zero, Cronet transport will coalesce packets to fewer frames * when possible. */ @@ -315,8 +315,12 @@ typedef struct { #define GRPC_ARG_GRPCLB_CALL_TIMEOUT_MS "grpc.grpclb_call_timeout_ms" /* Timeout in milliseconds to wait for the serverlist from the grpclb load balancer before using fallback backend addresses from the resolver. - If 0, fallback will never be used. Default value is 10000. */ + If 0, enter fallback mode immediately. Default value is 10000. */ #define GRPC_ARG_GRPCLB_FALLBACK_TIMEOUT_MS "grpc.grpclb_fallback_timeout_ms" +/* Timeout in milliseconds to wait for the serverlist from the xDS load + balancer before using fallback backend addresses from the resolver. + If 0, enter fallback mode immediately. Default value is 10000. */ +#define GRPC_ARG_XDS_FALLBACK_TIMEOUT_MS "grpc.xds_fallback_timeout_ms" /** If non-zero, grpc server's cronet compression workaround will be enabled */ #define GRPC_ARG_WORKAROUND_CRONET_COMPRESSION \ "grpc.workaround.cronet_compression" @@ -350,6 +354,25 @@ typedef struct { /** If set, inhibits health checking (which may be enabled via the * service config.) */ #define GRPC_ARG_INHIBIT_HEALTH_CHECKING "grpc.inhibit_health_checking" +/** If set, the channel's resolver is allowed to query for SRV records. + * For example, this is useful as a way to enable the "grpclb" + * load balancing policy. Note that this only works with the "ares" + * DNS resolver, and isn't supported by the "native" DNS resolver. */ +#define GRPC_ARG_DNS_ENABLE_SRV_QUERIES "grpc.dns_enable_srv_queries" +/** If set, determines an upper bound on the number of milliseconds that the + * c-ares based DNS resolver will wait on queries before cancelling them. + * The default value is 120,000. Setting this to "0" will disable the + * overall timeout entirely. Note that this doesn't include internal c-ares + * timeouts/backoff/retry logic, and so the actual DNS resolution may time out + * sooner than the value specified here. */ +#define GRPC_ARG_DNS_ARES_QUERY_TIMEOUT_MS "grpc.dns_ares_query_timeout" +/** If set, uses a local subchannel pool within the channel. Otherwise, uses the + * global subchannel pool. */ +#define GRPC_ARG_USE_LOCAL_SUBCHANNEL_POOL "grpc.use_local_subchannel_pool" +/** gRPC Objective-C channel pooling domain string. */ +#define GRPC_ARG_CHANNEL_POOL_DOMAIN "grpc.channel_pooling_domain" +/** gRPC Objective-C channel pooling id. */ +#define GRPC_ARG_CHANNEL_ID "grpc.channel_id" /** \} */ /** Result of a grpc call. If the caller satisfies the prerequisites of a @@ -473,7 +496,8 @@ typedef struct grpc_event { field is guaranteed to be 0 */ int success; /** The tag passed to grpc_call_start_batch etc to start this operation. - Only GRPC_OP_COMPLETE has a tag. */ + *Only* GRPC_OP_COMPLETE has a tag. For all other grpc_completion_type + values, tag is uninitialized. */ void* tag; } grpc_event; @@ -676,6 +700,10 @@ typedef struct grpc_experimental_completion_queue_functor { pointer to this functor and a boolean that indicates whether the operation succeeded (non-zero) or failed (zero) */ void (*functor_run)(struct grpc_experimental_completion_queue_functor*, int); + + /** The following fields are not API. They are meant for internal use. */ + int internal_success; + struct grpc_experimental_completion_queue_functor* internal_next; } grpc_experimental_completion_queue_functor; /* The upgrade to version 2 is currently experimental. */ diff --git a/include/grpc/impl/codegen/port_platform.h b/include/grpc/impl/codegen/port_platform.h index b2028a63053..d7294d59d41 100644 --- a/include/grpc/impl/codegen/port_platform.h +++ b/include/grpc/impl/codegen/port_platform.h @@ -115,15 +115,21 @@ #define GPR_POSIX_SUBPROCESS 1 #define GPR_POSIX_SYNC 1 #define GPR_POSIX_TIME 1 +#define GPR_HAS_PTHREAD_H 1 #define GPR_GETPID_IN_UNISTD_H 1 #ifdef _LP64 #define GPR_ARCH_64 1 #else /* _LP64 */ #define GPR_ARCH_32 1 #endif /* _LP64 */ +#include #elif defined(ANDROID) || defined(__ANDROID__) #define GPR_PLATFORM_STRING "android" #define GPR_ANDROID 1 +// TODO(apolcyn): re-evaluate support for c-ares +// on android after upgrading our c-ares dependency. +// See https://github.com/grpc/grpc/issues/18038. +#define GRPC_ARES 0 #ifdef _LP64 #define GPR_ARCH_64 1 #else /* _LP64 */ @@ -139,6 +145,7 @@ #define GPR_POSIX_SUBPROCESS 1 #define GPR_POSIX_SYNC 1 #define GPR_POSIX_TIME 1 +#define GPR_HAS_PTHREAD_H 1 #define GPR_GETPID_IN_UNISTD_H 1 #define GPR_SUPPORT_CHANNELS_FROM_FD 1 #elif defined(__linux__) @@ -165,6 +172,7 @@ #define GPR_POSIX_SUBPROCESS 1 #define GPR_POSIX_SYNC 1 #define GPR_POSIX_TIME 1 +#define GPR_HAS_PTHREAD_H 1 #define GPR_GETPID_IN_UNISTD_H 1 #ifdef _LP64 #define GPR_ARCH_64 1 @@ -188,6 +196,9 @@ #define GPR_PLATFORM_STRING "ios" #define GPR_CPU_IPHONE 1 #define GPR_PTHREAD_TLS 1 +#define GRPC_CFSTREAM 1 +/* the c-ares resolver isnt safe to enable on iOS */ +#define GRPC_ARES 0 #else /* TARGET_OS_IPHONE */ #define GPR_PLATFORM_STRING "osx" #ifdef __MAC_OS_X_VERSION_MIN_REQUIRED @@ -227,8 +238,8 @@ #define GPR_POSIX_SUBPROCESS 1 #define GPR_POSIX_SYNC 1 #define GPR_POSIX_TIME 1 +#define GPR_HAS_PTHREAD_H 1 #define GPR_GETPID_IN_UNISTD_H 1 -/* TODO(mxyan): Remove when CFStream becomes default */ #ifndef GRPC_CFSTREAM #define GPR_SUPPORT_CHANNELS_FROM_FD 1 #endif @@ -253,6 +264,7 @@ #define GPR_POSIX_SUBPROCESS 1 #define GPR_POSIX_SYNC 1 #define GPR_POSIX_TIME 1 +#define GPR_HAS_PTHREAD_H 1 #define GPR_GETPID_IN_UNISTD_H 1 #define GPR_SUPPORT_CHANNELS_FROM_FD 1 #ifdef _LP64 @@ -276,6 +288,7 @@ #define GPR_POSIX_SUBPROCESS 1 #define GPR_POSIX_SYNC 1 #define GPR_POSIX_TIME 1 +#define GPR_HAS_PTHREAD_H 1 #define GPR_GETPID_IN_UNISTD_H 1 #define GPR_SUPPORT_CHANNELS_FROM_FD 1 #ifdef _LP64 @@ -296,6 +309,7 @@ #define GPR_POSIX_SUBPROCESS 1 #define GPR_POSIX_SYNC 1 #define GPR_POSIX_TIME 1 +#define GPR_HAS_PTHREAD_H 1 #define GPR_GETPID_IN_UNISTD_H 1 #ifdef _LP64 #define GPR_ARCH_64 1 @@ -318,6 +332,7 @@ #define GPR_POSIX_SUBPROCESS 1 #define GPR_POSIX_SYNC 1 #define GPR_POSIX_TIME 1 +#define GPR_HAS_PTHREAD_H 1 #define GPR_GETPID_IN_UNISTD_H 1 #ifdef _LP64 #define GPR_ARCH_64 1 @@ -346,12 +361,34 @@ #define GPR_POSIX_SUBPROCESS 1 #define GPR_POSIX_SYNC 1 #define GPR_POSIX_TIME 1 +#define GPR_HAS_PTHREAD_H 1 #define GPR_GETPID_IN_UNISTD_H 1 #ifdef _LP64 #define GPR_ARCH_64 1 #else /* _LP64 */ #define GPR_ARCH_32 1 #endif /* _LP64 */ +#elif defined(__Fuchsia__) +#define GPR_FUCHSIA 1 +#define GPR_ARCH_64 1 +#define GPR_PLATFORM_STRING "fuchsia" +#include +// Specifying musl libc affects wrap_memcpy.c. It causes memmove() to be +// invoked. +#define GPR_MUSL_LIBC_COMPAT 1 +#define GPR_CPU_POSIX 1 +#define GPR_GCC_ATOMIC 1 +#define GPR_PTHREAD_TLS 1 +#define GPR_POSIX_LOG 1 +#define GPR_POSIX_SYNC 1 +#define GPR_POSIX_ENV 1 +#define GPR_POSIX_TMPFILE 1 +#define GPR_POSIX_SUBPROCESS 1 +#define GPR_POSIX_SYNC 1 +#define GPR_POSIX_STRING 1 +#define GPR_POSIX_TIME 1 +#define GPR_HAS_PTHREAD_H 1 +#define GPR_GETPID_IN_UNISTD_H 1 #else #error "Could not auto-detect platform" #endif @@ -465,6 +502,10 @@ typedef unsigned __int64 uint64_t; #define GRPC_ARES 1 #endif +#ifndef GRPC_IF_NAMETOINDEX +#define GRPC_IF_NAMETOINDEX 1 +#endif + #ifndef GRPC_MUST_USE_RESULT #if defined(__GNUC__) && !defined(__MINGW32__) #define GRPC_MUST_USE_RESULT __attribute__((warn_unused_result)) @@ -515,17 +556,66 @@ typedef unsigned __int64 uint64_t; #define CENSUSAPI GRPCAPI #endif +#ifndef GPR_HAS_ATTRIBUTE +#ifdef __has_attribute +#define GPR_HAS_ATTRIBUTE(a) __has_attribute(a) +#else +#define GPR_HAS_ATTRIBUTE(a) 0 +#endif +#endif /* GPR_HAS_ATTRIBUTE */ + +#ifndef GPR_HAS_FEATURE +#ifdef __has_feature +#define GPR_HAS_FEATURE(a) __has_feature(a) +#else +#define GPR_HAS_FEATURE(a) 0 +#endif +#endif /* GPR_HAS_FEATURE */ + +#ifndef GPR_ATTRIBUTE_NOINLINE +#if GPR_HAS_ATTRIBUTE(noinline) || (defined(__GNUC__) && !defined(__clang__)) +#define GPR_ATTRIBUTE_NOINLINE __attribute__((noinline)) +#define GPR_HAS_ATTRIBUTE_NOINLINE 1 +#else +#define GPR_ATTRIBUTE_NOINLINE +#endif +#endif /* GPR_ATTRIBUTE_NOINLINE */ + +#ifndef GPR_ATTRIBUTE_WEAK +/* Attribute weak is broken on LLVM/windows: + * https://bugs.llvm.org/show_bug.cgi?id=37598 */ +#if (GPR_HAS_ATTRIBUTE(weak) || (defined(__GNUC__) && !defined(__clang__))) && \ + !(defined(__llvm__) && defined(_WIN32)) +#define GPR_ATTRIBUTE_WEAK __attribute__((weak)) +#define GPR_HAS_ATTRIBUTE_WEAK 1 +#else +#define GPR_ATTRIBUTE_WEAK +#endif +#endif /* GPR_ATTRIBUTE_WEAK */ + #ifndef GPR_ATTRIBUTE_NO_TSAN /* (1) */ -#if defined(__has_feature) -#if __has_feature(thread_sanitizer) +#if GPR_HAS_FEATURE(thread_sanitizer) #define GPR_ATTRIBUTE_NO_TSAN __attribute__((no_sanitize("thread"))) -#endif /* __has_feature(thread_sanitizer) */ -#endif /* defined(__has_feature) */ +#endif /* GPR_HAS_FEATURE */ #ifndef GPR_ATTRIBUTE_NO_TSAN /* (2) */ #define GPR_ATTRIBUTE_NO_TSAN #endif /* GPR_ATTRIBUTE_NO_TSAN (2) */ #endif /* GPR_ATTRIBUTE_NO_TSAN (1) */ +/* GRPC_TSAN_ENABLED will be defined, when compiled with thread sanitizer. */ +#if defined(__SANITIZE_THREAD__) +#define GRPC_TSAN_ENABLED +#elif GPR_HAS_FEATURE(thread_sanitizer) +#define GRPC_TSAN_ENABLED +#endif + +/* GRPC_ASAN_ENABLED will be defined, when compiled with address sanitizer. */ +#if defined(__SANITIZE_ADDRESS__) +#define GRPC_ASAN_ENABLED +#elif GPR_HAS_FEATURE(address_sanitizer) +#define GRPC_ASAN_ENABLED +#endif + /* GRPC_ALLOW_EXCEPTIONS should be 0 or 1 if exceptions are allowed or not */ #ifndef GRPC_ALLOW_EXCEPTIONS /* If not already set, set to 1 on Windows (style guide standard) but to diff --git a/include/grpc/impl/codegen/slice.h b/include/grpc/impl/codegen/slice.h index 90dbfd3b1f8..3567b1e88b3 100644 --- a/include/grpc/impl/codegen/slice.h +++ b/include/grpc/impl/codegen/slice.h @@ -40,27 +40,6 @@ typedef struct grpc_slice grpc_slice; reference ownership semantics (who should call unref?) and mutability constraints (is the callee allowed to modify the slice?) */ -typedef struct grpc_slice_refcount_vtable { - void (*ref)(void*); - void (*unref)(void*); - int (*eq)(grpc_slice a, grpc_slice b); - uint32_t (*hash)(grpc_slice slice); -} grpc_slice_refcount_vtable; - -/** Reference count container for grpc_slice. Contains function pointers to - increment and decrement reference counts. Implementations should cleanup - when the reference count drops to zero. - Typically client code should not touch this, and use grpc_slice_malloc, - grpc_slice_new, or grpc_slice_new_with_len instead. */ -typedef struct grpc_slice_refcount { - const grpc_slice_refcount_vtable* vtable; - /** If a subset of this slice is taken, use this pointer for the refcount. - Typically points back to the refcount itself, however iterning - implementations can use this to avoid a verification step on each hash - or equality check */ - struct grpc_slice_refcount* sub_refcount; -} grpc_slice_refcount; - /* Inlined half of grpc_slice is allowed to expand the size of the overall type by this many bytes */ #define GRPC_SLICE_INLINE_EXTRA_SIZE sizeof(void*) @@ -68,6 +47,7 @@ typedef struct grpc_slice_refcount { #define GRPC_SLICE_INLINED_SIZE \ (sizeof(size_t) + sizeof(uint8_t*) - 1 + GRPC_SLICE_INLINE_EXTRA_SIZE) +struct grpc_slice_refcount; /** A grpc_slice s, if initialized, represents the byte range s.bytes[0..s.length-1]. @@ -81,8 +61,8 @@ struct grpc_slice { struct grpc_slice_refcount* refcount; union grpc_slice_data { struct grpc_slice_refcounted { - uint8_t* bytes; size_t length; + uint8_t* bytes; } refcounted; struct grpc_slice_inlined { uint8_t length; diff --git a/include/grpc/impl/codegen/status.h b/include/grpc/impl/codegen/status.h index 9bc3dc95609..dec3b8f340e 100644 --- a/include/grpc/impl/codegen/status.h +++ b/include/grpc/impl/codegen/status.h @@ -128,7 +128,8 @@ typedef enum { /** The service is currently unavailable. This is a most likely a transient condition and may be corrected by retrying with - a backoff. + a backoff. Note that it is not always safe to retry non-idempotent + operations. WARNING: Although data MIGHT not have been transmitted when this status occurs, there is NOT A GUARANTEE that the server has not seen diff --git a/include/grpc/impl/codegen/sync_posix.h b/include/grpc/impl/codegen/sync_posix.h index d927046c53e..2aec3a3f8d6 100644 --- a/include/grpc/impl/codegen/sync_posix.h +++ b/include/grpc/impl/codegen/sync_posix.h @@ -25,8 +25,26 @@ #include +#ifdef GRPC_ASAN_ENABLED +/* The member |leak_checker| is used to check whether there is a memory leak + * caused by upper layer logic that's missing the |gpr_xx_destroy| call + * to the object before freeing it. + * This issue was reported at https://github.com/grpc/grpc/issues/17563 + * and discussed at https://github.com/grpc/grpc/pull/17586 + */ +typedef struct { + pthread_mutex_t mutex; + int* leak_checker; +} gpr_mu; + +typedef struct { + pthread_cond_t cond_var; + int* leak_checker; +} gpr_cv; +#else typedef pthread_mutex_t gpr_mu; typedef pthread_cond_t gpr_cv; +#endif typedef pthread_once_t gpr_once; #define GPR_ONCE_INIT PTHREAD_ONCE_INIT diff --git a/include/grpc/slice.h b/include/grpc/slice.h index ce482922afa..192a8cfeef4 100644 --- a/include/grpc/slice.h +++ b/include/grpc/slice.h @@ -147,7 +147,7 @@ GPRAPI int grpc_slice_buf_start_eq(grpc_slice a, const void* b, size_t blen); GPRAPI int grpc_slice_rchr(grpc_slice s, char c); GPRAPI int grpc_slice_chr(grpc_slice s, char c); -/** return the index of the first occurance of \a needle in \a haystack, or -1 +/** return the index of the first occurrence of \a needle in \a haystack, or -1 if it's not found */ GPRAPI int grpc_slice_slice(grpc_slice haystack, grpc_slice needle); diff --git a/include/grpcpp/alarm.h b/include/grpcpp/alarm.h index 365feb4eb95..2343c1149c5 100644 --- a/include/grpcpp/alarm.h +++ b/include/grpcpp/alarm.h @@ -1,6 +1,6 @@ /* * - * Copyright 2015 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. @@ -16,99 +16,14 @@ * */ -/// An Alarm posts the user provided tag to its associated completion queue upon -/// expiry or cancellation. #ifndef GRPCPP_ALARM_H #define GRPCPP_ALARM_H -#include - -#include -#include -#include -#include -#include -#include +#include namespace grpc { -/// A thin wrapper around \a grpc_alarm (see / \a / src/core/surface/alarm.h). -class Alarm : private GrpcLibraryCodegen { - public: - /// Create an unset completion queue alarm - Alarm(); - - /// Destroy the given completion queue alarm, cancelling it in the process. - ~Alarm(); - - /// DEPRECATED: Create and set a completion queue alarm instance associated to - /// \a cq. - /// This form is deprecated because it is inherently racy. - /// \internal We rely on the presence of \a cq for grpc initialization. If \a - /// cq were ever to be removed, a reference to a static - /// internal::GrpcLibraryInitializer instance would need to be introduced - /// here. \endinternal. - template - Alarm(CompletionQueue* cq, const T& deadline, void* tag) : Alarm() { - SetInternal(cq, TimePoint(deadline).raw_time(), tag); - } - - /// Trigger an alarm instance on completion queue \a cq at the specified time. - /// Once the alarm expires (at \a deadline) or it's cancelled (see \a Cancel), - /// an event with tag \a tag will be added to \a cq. If the alarm expired, the - /// event's success bit will be true, false otherwise (ie, upon cancellation). - template - void Set(CompletionQueue* cq, const T& deadline, void* tag) { - SetInternal(cq, TimePoint(deadline).raw_time(), tag); - } - - /// Alarms aren't copyable. - Alarm(const Alarm&) = delete; - Alarm& operator=(const Alarm&) = delete; - - /// Alarms are movable. - Alarm(Alarm&& rhs) : alarm_(rhs.alarm_) { rhs.alarm_ = nullptr; } - Alarm& operator=(Alarm&& rhs) { - alarm_ = rhs.alarm_; - rhs.alarm_ = nullptr; - return *this; - } - - /// Cancel a completion queue alarm. Calling this function over an alarm that - /// has already fired has no effect. - void Cancel(); - - /// NOTE: class experimental_type is not part of the public API of this class - /// TODO(vjpai): Move these contents to the public API of Alarm when - /// they are no longer experimental - class experimental_type { - public: - explicit experimental_type(Alarm* alarm) : alarm_(alarm) {} - - /// Set an alarm to invoke callback \a f. The argument to the callback - /// states whether the alarm expired at \a deadline (true) or was cancelled - /// (false) - template - void Set(const T& deadline, std::function f) { - alarm_->SetInternal(TimePoint(deadline).raw_time(), std::move(f)); - } - - private: - Alarm* alarm_; - }; - - /// NOTE: The function experimental() is not stable public API. It is a view - /// to the experimental components of this class. It may be changed or removed - /// at any time. - experimental_type experimental() { return experimental_type(this); } - - private: - void SetInternal(CompletionQueue* cq, gpr_timespec deadline, void* tag); - void SetInternal(gpr_timespec deadline, std::function f); - - internal::CompletionQueueTag* alarm_; -}; - -} // namespace grpc +typedef ::grpc_impl::Alarm Alarm; +} #endif // GRPCPP_ALARM_H diff --git a/include/grpcpp/alarm_impl.h b/include/grpcpp/alarm_impl.h new file mode 100644 index 00000000000..543dcd82a4c --- /dev/null +++ b/include/grpcpp/alarm_impl.h @@ -0,0 +1,115 @@ +/* + * + * 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 Alarm posts the user-provided tag to its associated completion queue or +/// invokes the user-provided function on expiry or cancellation. +#ifndef GRPCPP_ALARM_IMPL_H +#define GRPCPP_ALARM_IMPL_H + +#include + +#include +#include +#include +#include +#include +#include + +namespace grpc_impl { + +class Alarm : private ::grpc::GrpcLibraryCodegen { + public: + /// Create an unset completion queue alarm + Alarm(); + + /// Destroy the given completion queue alarm, cancelling it in the process. + ~Alarm(); + + /// DEPRECATED: Create and set a completion queue alarm instance associated to + /// \a cq. + /// This form is deprecated because it is inherently racy. + /// \internal We rely on the presence of \a cq for grpc initialization. If \a + /// cq were ever to be removed, a reference to a static + /// internal::GrpcLibraryInitializer instance would need to be introduced + /// here. \endinternal. + template + Alarm(::grpc::CompletionQueue* cq, const T& deadline, void* tag) : Alarm() { + SetInternal(cq, ::grpc::TimePoint(deadline).raw_time(), tag); + } + + /// Trigger an alarm instance on completion queue \a cq at the specified time. + /// Once the alarm expires (at \a deadline) or it's cancelled (see \a Cancel), + /// an event with tag \a tag will be added to \a cq. If the alarm expired, the + /// event's success bit will be true, false otherwise (ie, upon cancellation). + template + void Set(::grpc::CompletionQueue* cq, const T& deadline, void* tag) { + SetInternal(cq, ::grpc::TimePoint(deadline).raw_time(), tag); + } + + /// Alarms aren't copyable. + Alarm(const Alarm&) = delete; + Alarm& operator=(const Alarm&) = delete; + + /// Alarms are movable. + Alarm(Alarm&& rhs) : alarm_(rhs.alarm_) { rhs.alarm_ = nullptr; } + Alarm& operator=(Alarm&& rhs) { + alarm_ = rhs.alarm_; + rhs.alarm_ = nullptr; + return *this; + } + + /// Cancel a completion queue alarm. Calling this function over an alarm that + /// has already fired has no effect. + void Cancel(); + + /// NOTE: class experimental_type is not part of the public API of this class + /// TODO(vjpai): Move these contents to the public API of Alarm when + /// they are no longer experimental + class experimental_type { + public: + explicit experimental_type(Alarm* alarm) : alarm_(alarm) {} + + /// Set an alarm to invoke callback \a f. The argument to the callback + /// states whether the alarm expired at \a deadline (true) or was cancelled + /// (false) + template + void Set(const T& deadline, std::function f) { + alarm_->SetInternal(::grpc::TimePoint(deadline).raw_time(), + std::move(f)); + } + + private: + Alarm* alarm_; + }; + + /// NOTE: The function experimental() is not stable public API. It is a view + /// to the experimental components of this class. It may be changed or removed + /// at any time. + experimental_type experimental() { return experimental_type(this); } + + private: + void SetInternal(::grpc::CompletionQueue* cq, gpr_timespec deadline, + void* tag); + void SetInternal(gpr_timespec deadline, std::function f); + + ::grpc::internal::CompletionQueueTag* alarm_; +}; + +} // namespace grpc_impl + +#endif // GRPCPP_ALARM_IMPL_H diff --git a/include/grpcpp/channel.h b/include/grpcpp/channel.h index ee833960698..163c804ffbe 100644 --- a/include/grpcpp/channel.h +++ b/include/grpcpp/channel.h @@ -19,20 +19,12 @@ #ifndef GRPCPP_CHANNEL_H #define GRPCPP_CHANNEL_H -#include -#include - -#include -#include -#include -#include -#include -#include - -struct grpc_channel; +#include namespace grpc { +typedef ::grpc_impl::Channel Channel; + namespace experimental { /// Resets the channel's connection backoff. /// TODO(roth): Once we see whether this proves useful, either create a gRFC @@ -40,75 +32,6 @@ namespace experimental { void ChannelResetConnectionBackoff(Channel* channel); } // namespace experimental -/// Channels represent a connection to an endpoint. Created by \a CreateChannel. -class Channel final : public ChannelInterface, - public internal::CallHook, - public std::enable_shared_from_this, - private GrpcLibraryCodegen { - public: - ~Channel(); - - /// Get the current channel state. If the channel is in IDLE and - /// \a try_to_connect is set to true, try to connect. - grpc_connectivity_state GetState(bool try_to_connect) override; - - /// Returns the LB policy name, or the empty string if not yet available. - grpc::string GetLoadBalancingPolicyName() const; - - /// Returns the service config in JSON form, or the empty string if - /// not available. - grpc::string GetServiceConfigJSON() const; - - private: - template - friend class internal::BlockingUnaryCallImpl; - friend void experimental::ChannelResetConnectionBackoff(Channel* channel); - friend std::shared_ptr CreateChannelInternal( - const grpc::string& host, grpc_channel* c_channel, - std::vector< - std::unique_ptr> - interceptor_creators); - friend class internal::InterceptedChannel; - Channel(const grpc::string& host, grpc_channel* c_channel, - std::vector< - std::unique_ptr> - interceptor_creators); - - internal::Call CreateCall(const internal::RpcMethod& method, - ClientContext* context, - CompletionQueue* cq) override; - void PerformOpsOnCall(internal::CallOpSetInterface* ops, - internal::Call* call) override; - void* RegisterMethod(const char* method) override; - - void NotifyOnStateChangeImpl(grpc_connectivity_state last_observed, - gpr_timespec deadline, CompletionQueue* cq, - void* tag) override; - bool WaitForStateChangeImpl(grpc_connectivity_state last_observed, - gpr_timespec deadline) override; - - CompletionQueue* CallbackCQ() override; - - internal::Call CreateCallInternal(const internal::RpcMethod& method, - ClientContext* context, CompletionQueue* cq, - size_t interceptor_pos) override; - - const grpc::string host_; - grpc_channel* const c_channel_; // owned - - // mu_ protects callback_cq_ (the per-channel callbackable completion queue) - std::mutex mu_; - - // callback_cq_ references the callbackable completion queue associated - // with this channel (if any). It is set on the first call to CallbackCQ(). - // It is _not owned_ by the channel; ownership belongs with its internal - // shutdown callback tag (invoked when the CQ is fully shutdown). - CompletionQueue* callback_cq_ = nullptr; - - std::vector> - interceptor_creators_; -}; - } // namespace grpc #endif // GRPCPP_CHANNEL_H diff --git a/include/grpcpp/channel_impl.h b/include/grpcpp/channel_impl.h new file mode 100644 index 00000000000..39917d2eb74 --- /dev/null +++ b/include/grpcpp/channel_impl.h @@ -0,0 +1,125 @@ +/* + * + * 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_CHANNEL_IMPL_H +#define GRPCPP_CHANNEL_IMPL_H + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +struct grpc_channel; + +namespace grpc { + +std::shared_ptr<::grpc_impl::Channel> CreateChannelInternal( + const grpc::string& host, grpc_channel* c_channel, + std::vector< + std::unique_ptr> + interceptor_creators); +} // namespace grpc +namespace grpc_impl { + +namespace experimental { +/// Resets the channel's connection backoff. +/// TODO(roth): Once we see whether this proves useful, either create a gRFC +/// and change this to be a method of the Channel class, or remove it. +void ChannelResetConnectionBackoff(Channel* channel); +} // namespace experimental + +/// Channels represent a connection to an endpoint. Created by \a CreateChannel. +class Channel final : public ::grpc::ChannelInterface, + public ::grpc::internal::CallHook, + public std::enable_shared_from_this, + private ::grpc::GrpcLibraryCodegen { + public: + ~Channel(); + + /// Get the current channel state. If the channel is in IDLE and + /// \a try_to_connect is set to true, try to connect. + grpc_connectivity_state GetState(bool try_to_connect) override; + + /// Returns the LB policy name, or the empty string if not yet available. + grpc::string GetLoadBalancingPolicyName() const; + + /// Returns the service config in JSON form, or the empty string if + /// not available. + grpc::string GetServiceConfigJSON() const; + + private: + template + friend class ::grpc::internal::BlockingUnaryCallImpl; + friend void experimental::ChannelResetConnectionBackoff(Channel* channel); + friend std::shared_ptr grpc::CreateChannelInternal( + const grpc::string& host, grpc_channel* c_channel, + std::vector> + interceptor_creators); + friend class ::grpc::internal::InterceptedChannel; + Channel(const grpc::string& host, grpc_channel* c_channel, + std::vector> + interceptor_creators); + + ::grpc::internal::Call CreateCall(const ::grpc::internal::RpcMethod& method, + ::grpc::ClientContext* context, + ::grpc::CompletionQueue* cq) override; + void PerformOpsOnCall(::grpc::internal::CallOpSetInterface* ops, + ::grpc::internal::Call* call) override; + void* RegisterMethod(const char* method) override; + + void NotifyOnStateChangeImpl(grpc_connectivity_state last_observed, + gpr_timespec deadline, + ::grpc::CompletionQueue* cq, void* tag) override; + bool WaitForStateChangeImpl(grpc_connectivity_state last_observed, + gpr_timespec deadline) override; + + ::grpc::CompletionQueue* CallbackCQ() override; + + ::grpc::internal::Call CreateCallInternal( + const ::grpc::internal::RpcMethod& method, ::grpc::ClientContext* context, + ::grpc::CompletionQueue* cq, size_t interceptor_pos) override; + + const grpc::string host_; + grpc_channel* const c_channel_; // owned + + // mu_ protects callback_cq_ (the per-channel callbackable completion queue) + grpc::internal::Mutex mu_; + + // callback_cq_ references the callbackable completion queue associated + // with this channel (if any). It is set on the first call to CallbackCQ(). + // It is _not owned_ by the channel; ownership belongs with its internal + // shutdown callback tag (invoked when the CQ is fully shutdown). + ::grpc::CompletionQueue* callback_cq_ = nullptr; + + std::vector< + std::unique_ptr<::grpc::experimental::ClientInterceptorFactoryInterface>> + interceptor_creators_; +}; + +} // namespace grpc_impl + +#endif // GRPCPP_CHANNEL_IMPL_H diff --git a/include/grpcpp/create_channel.h b/include/grpcpp/create_channel.h index e8a2a70581d..9b257ace945 100644 --- a/include/grpcpp/create_channel.h +++ b/include/grpcpp/create_channel.h @@ -1,6 +1,6 @@ /* * - * Copyright 2015 gRPC authors. + * Copyright 2019 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,60 +19,38 @@ #ifndef GRPCPP_CREATE_CHANNEL_H #define GRPCPP_CREATE_CHANNEL_H -#include - -#include -#include -#include +#include #include -#include namespace grpc { -/// Create a new \a Channel pointing to \a target. -/// -/// \param target The URI of the endpoint to connect to. -/// \param creds Credentials to use for the created channel. If it does not -/// hold an object or is invalid, a lame channel (one on which all operations -/// fail) is returned. -std::shared_ptr CreateChannel( +static inline std::shared_ptr<::grpc::Channel> CreateChannel( const grpc::string& target, - const std::shared_ptr& creds); + const std::shared_ptr& creds) { + return ::grpc_impl::CreateChannelImpl(target, creds); +} -/// Create a new \em custom \a Channel pointing to \a target. -/// -/// \warning For advanced use and testing ONLY. Override default channel -/// arguments only if necessary. -/// -/// \param target The URI of the endpoint to connect to. -/// \param creds Credentials to use for the created channel. If it does not -/// hold an object or is invalid, a lame channel (one on which all operations -/// fail) is returned. -/// \param args Options for channel creation. -std::shared_ptr CreateCustomChannel( +static inline std::shared_ptr<::grpc::Channel> CreateCustomChannel( const grpc::string& target, const std::shared_ptr& creds, - const ChannelArguments& args); + const ChannelArguments& args) { + return ::grpc_impl::CreateCustomChannelImpl(target, creds, args); +} namespace experimental { -/// Create a new \em custom \a Channel pointing to \a target with \a -/// interceptors being invoked per call. -/// -/// \warning For advanced use and testing ONLY. Override default channel -/// arguments only if necessary. -/// -/// \param target The URI of the endpoint to connect to. -/// \param creds Credentials to use for the created channel. If it does not -/// hold an object or is invalid, a lame channel (one on which all operations -/// fail) is returned. -/// \param args Options for channel creation. -std::shared_ptr CreateCustomChannelWithInterceptors( + +static inline std::shared_ptr<::grpc::Channel> +CreateCustomChannelWithInterceptors( const grpc::string& target, const std::shared_ptr& creds, const ChannelArguments& args, std::vector< std::unique_ptr> - interceptor_creators); + interceptor_creators) { + return ::grpc_impl::experimental::CreateCustomChannelWithInterceptors( + target, creds, args, std::move(interceptor_creators)); +} + } // namespace experimental } // namespace grpc diff --git a/include/grpcpp/create_channel_impl.h b/include/grpcpp/create_channel_impl.h new file mode 100644 index 00000000000..02896e66444 --- /dev/null +++ b/include/grpcpp/create_channel_impl.h @@ -0,0 +1,78 @@ +/* + * + * 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_CREATE_CHANNEL_IMPL_H +#define GRPCPP_CREATE_CHANNEL_IMPL_H + +#include + +#include +#include +#include +#include +#include + +namespace grpc_impl { +/// Create a new \a Channel pointing to \a target. +/// +/// \param target The URI of the endpoint to connect to. +/// \param creds Credentials to use for the created channel. If it does not +/// hold an object or is invalid, a lame channel (one on which all operations +/// fail) is returned. +std::shared_ptr<::grpc::Channel> CreateChannelImpl( + const grpc::string& target, + const std::shared_ptr<::grpc::ChannelCredentials>& creds); + +/// Create a new \em custom \a Channel pointing to \a target. +/// +/// \warning For advanced use and testing ONLY. Override default channel +/// arguments only if necessary. +/// +/// \param target The URI of the endpoint to connect to. +/// \param creds Credentials to use for the created channel. If it does not +/// hold an object or is invalid, a lame channel (one on which all operations +/// fail) is returned. +/// \param args Options for channel creation. +std::shared_ptr<::grpc::Channel> CreateCustomChannelImpl( + const grpc::string& target, + const std::shared_ptr<::grpc::ChannelCredentials>& creds, + const ::grpc::ChannelArguments& args); + +namespace experimental { +/// Create a new \em custom \a Channel pointing to \a target with \a +/// interceptors being invoked per call. +/// +/// \warning For advanced use and testing ONLY. Override default channel +/// arguments only if necessary. +/// +/// \param target The URI of the endpoint to connect to. +/// \param creds Credentials to use for the created channel. If it does not +/// hold an object or is invalid, a lame channel (one on which all operations +/// fail) is returned. +/// \param args Options for channel creation. +std::shared_ptr<::grpc::Channel> CreateCustomChannelWithInterceptors( + const grpc::string& target, + const std::shared_ptr& creds, + const ::grpc::ChannelArguments& args, + std::vector< + std::unique_ptr> + interceptor_creators); +} // namespace experimental +} // namespace grpc_impl + +#endif // GRPCPP_CREATE_CHANNEL_IMPL_H diff --git a/include/grpcpp/create_channel_posix.h b/include/grpcpp/create_channel_posix.h index 808514041b8..b8a1f5e5c46 100644 --- a/include/grpcpp/create_channel_posix.h +++ b/include/grpcpp/create_channel_posix.h @@ -1,6 +1,6 @@ /* * - * Copyright 2016 gRPC authors. + * Copyright 2019 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,46 +19,34 @@ #ifndef GRPCPP_CREATE_CHANNEL_POSIX_H #define GRPCPP_CREATE_CHANNEL_POSIX_H -#include - -#include -#include -#include +#include namespace grpc { #ifdef GPR_SUPPORT_CHANNELS_FROM_FD -/// Create a new \a Channel communicating over the given file descriptor. -/// -/// \param target The name of the target. -/// \param fd The file descriptor representing a socket. -std::shared_ptr CreateInsecureChannelFromFd(const grpc::string& target, - int fd); +static inline std::shared_ptr CreateInsecureChannelFromFd( + const grpc::string& target, int fd) { + return ::grpc_impl::CreateInsecureChannelFromFd(target, fd); +} -/// Create a new \a Channel communicating over given file descriptor with custom -/// channel arguments. -/// -/// \param target The name of the target. -/// \param fd The file descriptor representing a socket. -/// \param args Options for channel creation. -std::shared_ptr CreateCustomInsecureChannelFromFd( - const grpc::string& target, int fd, const ChannelArguments& args); +static inline std::shared_ptr CreateCustomInsecureChannelFromFd( + const grpc::string& target, int fd, const ChannelArguments& args) { + return ::grpc_impl::CreateCustomInsecureChannelFromFd(target, fd, args); +} namespace experimental { -/// Create a new \a Channel communicating over given file descriptor with custom -/// channel arguments. -/// -/// \param target The name of the target. -/// \param fd The file descriptor representing a socket. -/// \param args Options for channel creation. -/// \param interceptor_creators Vector of interceptor factory objects. -std::shared_ptr CreateCustomInsecureChannelWithInterceptorsFromFd( +static inline std::shared_ptr +CreateCustomInsecureChannelWithInterceptorsFromFd( const grpc::string& target, int fd, const ChannelArguments& args, std::unique_ptr>> - interceptor_creators); + interceptor_creators) { + return ::grpc_impl::experimental:: + CreateCustomInsecureChannelWithInterceptorsFromFd( + target, fd, args, std::move(interceptor_creators)); +} } // namespace experimental diff --git a/include/grpcpp/create_channel_posix_impl.h b/include/grpcpp/create_channel_posix_impl.h new file mode 100644 index 00000000000..5c11120611a --- /dev/null +++ b/include/grpcpp/create_channel_posix_impl.h @@ -0,0 +1,70 @@ +/* + * + * 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. + * + */ + +#ifndef GRPCPP_CREATE_CHANNEL_POSIX_IMPL_H +#define GRPCPP_CREATE_CHANNEL_POSIX_IMPL_H + +#include + +#include +#include +#include + +namespace grpc_impl { + +#ifdef GPR_SUPPORT_CHANNELS_FROM_FD + +/// Create a new \a Channel communicating over the given file descriptor. +/// +/// \param target The name of the target. +/// \param fd The file descriptor representing a socket. +std::shared_ptr CreateInsecureChannelFromFd( + const grpc::string& target, int fd); + +/// Create a new \a Channel communicating over given file descriptor with custom +/// channel arguments. +/// +/// \param target The name of the target. +/// \param fd The file descriptor representing a socket. +/// \param args Options for channel creation. +std::shared_ptr CreateCustomInsecureChannelFromFd( + const grpc::string& target, int fd, const grpc::ChannelArguments& args); + +namespace experimental { + +/// Create a new \a Channel communicating over given file descriptor with custom +/// channel arguments. +/// +/// \param target The name of the target. +/// \param fd The file descriptor representing a socket. +/// \param args Options for channel creation. +/// \param interceptor_creators Vector of interceptor factory objects. +std::shared_ptr +CreateCustomInsecureChannelWithInterceptorsFromFd( + const grpc::string& target, int fd, const grpc::ChannelArguments& args, + std::unique_ptr>> + interceptor_creators); + +} // namespace experimental + +#endif // GPR_SUPPORT_CHANNELS_FROM_FD + +} // namespace grpc_impl + +#endif // GRPCPP_CREATE_CHANNEL_POSIX_IMPL_H diff --git a/include/grpcpp/ext/channelz_service_plugin.h b/include/grpcpp/ext/channelz_service_plugin.h index af3192d4513..95cb93e3216 100644 --- a/include/grpcpp/ext/channelz_service_plugin.h +++ b/include/grpcpp/ext/channelz_service_plugin.h @@ -19,20 +19,15 @@ #ifndef GRPCPP_EXT_CHANNELZ_SERVICE_PLUGIN_H #define GRPCPP_EXT_CHANNELZ_SERVICE_PLUGIN_H -#include - -#include -#include -#include +#include namespace grpc { namespace channelz { namespace experimental { -/// Add channelz server plugin to \a ServerBuilder. This function should -/// be called at static initialization time. This service is experimental -/// for now. Track progress in https://github.com/grpc/grpc/issues/15988. -void InitChannelzService(); +static inline void InitChannelzService() { + ::grpc_impl::channelz::experimental::InitChannelzService(); +} } // namespace experimental } // namespace channelz diff --git a/include/grpcpp/ext/channelz_service_plugin_impl.h b/include/grpcpp/ext/channelz_service_plugin_impl.h new file mode 100644 index 00000000000..3a5f3c4b99e --- /dev/null +++ b/include/grpcpp/ext/channelz_service_plugin_impl.h @@ -0,0 +1,41 @@ +/* + * + * 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_EXT_CHANNELZ_SERVICE_PLUGIN_IMPL_H +#define GRPCPP_EXT_CHANNELZ_SERVICE_PLUGIN_IMPL_H + +#include + +#include +#include +#include + +namespace grpc_impl { +namespace channelz { +namespace experimental { + +/// Add channelz server plugin to \a ServerBuilder. This function should +/// be called at static initialization time. This service is experimental +/// for now. Track progress in https://github.com/grpc/grpc/issues/15988. +void InitChannelzService(); + +} // namespace experimental +} // namespace channelz +} // namespace grpc_impl + +#endif // GRPCPP_EXT_CHANNELZ_SERVICE_PLUGIN_IMPL_H diff --git a/include/grpcpp/ext/proto_server_reflection_plugin.h b/include/grpcpp/ext/proto_server_reflection_plugin.h index 1cfdc1b6ccf..f6f2202ffb3 100644 --- a/include/grpcpp/ext/proto_server_reflection_plugin.h +++ b/include/grpcpp/ext/proto_server_reflection_plugin.h @@ -1,6 +1,6 @@ /* * - * Copyright 2015 gRPC authors. + * Copyright 2019 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,34 +19,17 @@ #ifndef GRPCPP_EXT_PROTO_SERVER_REFLECTION_PLUGIN_H #define GRPCPP_EXT_PROTO_SERVER_REFLECTION_PLUGIN_H -#include -#include - -namespace grpc { -class ServerInitializer; -class ProtoServerReflection; -} // namespace grpc +#include namespace grpc { namespace reflection { -class ProtoServerReflectionPlugin : public ::grpc::ServerBuilderPlugin { - public: - ProtoServerReflectionPlugin(); - ::grpc::string name() override; - void InitServer(::grpc::ServerInitializer* si) override; - void Finish(::grpc::ServerInitializer* si) override; - void ChangeArguments(const ::grpc::string& name, void* value) override; - bool has_async_methods() const override; - bool has_sync_methods() const override; +typedef ::grpc_impl::reflection::ProtoServerReflectionPlugin + ProtoServerReflectionPlugin; - private: - std::shared_ptr reflection_service_; -}; - -/// Add proto reflection plugin to \a ServerBuilder. -/// This function should be called at the static initialization time. -void InitProtoReflectionServerBuilderPlugin(); +static inline void InitProtoReflectionServerBuilderPlugin() { + ::grpc_impl::reflection::InitProtoReflectionServerBuilderPlugin(); +} } // namespace reflection } // namespace grpc diff --git a/include/grpcpp/ext/proto_server_reflection_plugin_impl.h b/include/grpcpp/ext/proto_server_reflection_plugin_impl.h new file mode 100644 index 00000000000..a06fe14cdd7 --- /dev/null +++ b/include/grpcpp/ext/proto_server_reflection_plugin_impl.h @@ -0,0 +1,55 @@ +/* + * + * 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_EXT_PROTO_SERVER_REFLECTION_PLUGIN_IMPL_H +#define GRPCPP_EXT_PROTO_SERVER_REFLECTION_PLUGIN_IMPL_H + +#include +#include + +namespace grpc { +class ProtoServerReflection; +} // namespace grpc + +namespace grpc_impl { +class ServerInitializer; + +namespace reflection { + +class ProtoServerReflectionPlugin : public ::grpc::ServerBuilderPlugin { + public: + ProtoServerReflectionPlugin(); + ::grpc::string name() override; + void InitServer(::grpc_impl::ServerInitializer* si) override; + void Finish(::grpc_impl::ServerInitializer* si) override; + void ChangeArguments(const ::grpc::string& name, void* value) override; + bool has_async_methods() const override; + bool has_sync_methods() const override; + + private: + std::shared_ptr reflection_service_; +}; + +/// Add proto reflection plugin to \a ServerBuilder. +/// This function should be called at the static initialization time. +void InitProtoReflectionServerBuilderPlugin(); + +} // namespace reflection +} // namespace grpc_impl + +#endif // GRPCPP_EXT_PROTO_SERVER_REFLECTION_PLUGIN_IMPL_H diff --git a/include/grpcpp/ext/server_load_reporting.h b/include/grpcpp/ext/server_load_reporting.h index 939569c19aa..0c39a9e9830 100644 --- a/include/grpcpp/ext/server_load_reporting.h +++ b/include/grpcpp/ext/server_load_reporting.h @@ -19,32 +19,22 @@ #ifndef GRPCPP_EXT_SERVER_LOAD_REPORTING_H #define GRPCPP_EXT_SERVER_LOAD_REPORTING_H -#include - -#include -#include -#include -#include +#include namespace grpc { namespace load_reporter { namespace experimental { -// The ServerBuilderOption to enable server-side load reporting feature. To -// enable the feature, please make sure the binary builds with the -// grpcpp_server_load_reporting library and set this option in the -// ServerBuilder. -class LoadReportingServiceServerBuilderOption : public ServerBuilderOption { - public: - void UpdateArguments(::grpc::ChannelArguments* args) override; - void UpdatePlugins(std::vector>* - plugins) override; -}; +typedef ::grpc_impl::load_reporter::experimental:: + LoadReportingServiceServerBuilderOption + LoadReportingServiceServerBuilderOption; -// Adds the load reporting cost with \a cost_name and \a cost_value in the -// trailing metadata of the server context. -void AddLoadReportingCost(grpc::ServerContext* ctx, - const grpc::string& cost_name, double cost_value); +static inline void AddLoadReportingCost(grpc::ServerContext* ctx, + const grpc::string& cost_name, + double cost_value) { + ::grpc_impl::load_reporter::experimental::AddLoadReportingCost(ctx, cost_name, + cost_value); +} } // namespace experimental } // namespace load_reporter diff --git a/include/grpcpp/ext/server_load_reporting_impl.h b/include/grpcpp/ext/server_load_reporting_impl.h new file mode 100644 index 00000000000..1b27e0af6be --- /dev/null +++ b/include/grpcpp/ext/server_load_reporting_impl.h @@ -0,0 +1,54 @@ +/* + * + * 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_EXT_SERVER_LOAD_REPORTING_IMPL_H +#define GRPCPP_EXT_SERVER_LOAD_REPORTING_IMPL_H + +#include + +#include +#include +#include +#include + +namespace grpc_impl { +namespace load_reporter { +namespace experimental { + +// The ServerBuilderOption to enable server-side load reporting feature. To +// enable the feature, please make sure the binary builds with the +// grpcpp_server_load_reporting library and set this option in the +// ServerBuilder. +class LoadReportingServiceServerBuilderOption + : public grpc::ServerBuilderOption { + public: + void UpdateArguments(::grpc::ChannelArguments* args) override; + void UpdatePlugins(std::vector>* + plugins) override; +}; + +// Adds the load reporting cost with \a cost_name and \a cost_value in the +// trailing metadata of the server context. +void AddLoadReportingCost(grpc::ServerContext* ctx, + const grpc::string& cost_name, double cost_value); + +} // namespace experimental +} // namespace load_reporter +} // namespace grpc_impl + +#endif // GRPCPP_EXT_SERVER_LOAD_REPORTING_IMPL_H diff --git a/include/grpcpp/generic/generic_stub.h b/include/grpcpp/generic/generic_stub.h index d509d9a5206..f4c4664f53c 100644 --- a/include/grpcpp/generic/generic_stub.h +++ b/include/grpcpp/generic/generic_stub.h @@ -19,75 +19,11 @@ #ifndef GRPCPP_GENERIC_GENERIC_STUB_H #define GRPCPP_GENERIC_GENERIC_STUB_H -#include - -#include -#include -#include -#include +#include namespace grpc { -class CompletionQueue; -typedef ClientAsyncReaderWriter - GenericClientAsyncReaderWriter; -typedef ClientAsyncResponseReader GenericClientAsyncResponseReader; - -/// Generic stubs provide a type-unsafe interface to call gRPC methods -/// by name. -class GenericStub final { - public: - explicit GenericStub(std::shared_ptr channel) - : channel_(channel) {} - - /// Setup a call to a named method \a method using \a context, but don't - /// start it. Let it be started explicitly with StartCall and a tag. - /// The return value only indicates whether or not registration of the call - /// succeeded (i.e. the call won't proceed if the return value is nullptr). - std::unique_ptr PrepareCall( - ClientContext* context, const grpc::string& method, CompletionQueue* cq); - - /// Setup a unary call to a named method \a method using \a context, and don't - /// start it. Let it be started explicitly with StartCall. - /// The return value only indicates whether or not registration of the call - /// succeeded (i.e. the call won't proceed if the return value is nullptr). - std::unique_ptr PrepareUnaryCall( - ClientContext* context, const grpc::string& method, - const ByteBuffer& request, CompletionQueue* cq); - - /// DEPRECATED for multi-threaded use - /// Begin a call to a named method \a method using \a context. - /// A tag \a tag will be delivered to \a cq when the call has been started - /// (i.e, initial metadata has been sent). - /// The return value only indicates whether or not registration of the call - /// succeeded (i.e. the call won't proceed if the return value is nullptr). - std::unique_ptr Call( - ClientContext* context, const grpc::string& method, CompletionQueue* cq, - void* tag); - - /// NOTE: class experimental_type is not part of the public API of this class - /// TODO(vjpai): Move these contents to the public API of GenericStub when - /// they are no longer experimental - class experimental_type { - public: - explicit experimental_type(GenericStub* stub) : stub_(stub) {} - - void UnaryCall(ClientContext* context, const grpc::string& method, - const ByteBuffer* request, ByteBuffer* response, - std::function on_completion); - - private: - GenericStub* stub_; - }; - - /// NOTE: The function experimental() is not stable public API. It is a view - /// to the experimental components of this class. It may be changed or removed - /// at any time. - experimental_type experimental() { return experimental_type(this); } - - private: - std::shared_ptr channel_; -}; +typedef ::grpc_impl::GenericStub GenericStub; } // namespace grpc diff --git a/include/grpcpp/generic/generic_stub_impl.h b/include/grpcpp/generic/generic_stub_impl.h new file mode 100644 index 00000000000..90414611cbd --- /dev/null +++ b/include/grpcpp/generic/generic_stub_impl.h @@ -0,0 +1,114 @@ +/* + * + * 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_GENERIC_GENERIC_STUB_IMPL_H +#define GRPCPP_GENERIC_GENERIC_STUB_IMPL_H + +#include + +#include +#include +#include +#include +#include + +namespace grpc { + +typedef ClientAsyncReaderWriter + GenericClientAsyncReaderWriter; +typedef ClientAsyncResponseReader GenericClientAsyncResponseReader; +} // namespace grpc +namespace grpc_impl { +class CompletionQueue; + +/// Generic stubs provide a type-unsafe interface to call gRPC methods +/// by name. +class GenericStub final { + public: + explicit GenericStub(std::shared_ptr channel) + : channel_(channel) {} + + /// Setup a call to a named method \a method using \a context, but don't + /// start it. Let it be started explicitly with StartCall and a tag. + /// The return value only indicates whether or not registration of the call + /// succeeded (i.e. the call won't proceed if the return value is nullptr). + std::unique_ptr PrepareCall( + grpc::ClientContext* context, const grpc::string& method, + grpc::CompletionQueue* cq); + + /// Setup a unary call to a named method \a method using \a context, and don't + /// start it. Let it be started explicitly with StartCall. + /// The return value only indicates whether or not registration of the call + /// succeeded (i.e. the call won't proceed if the return value is nullptr). + std::unique_ptr PrepareUnaryCall( + grpc::ClientContext* context, const grpc::string& method, + const grpc::ByteBuffer& request, grpc::CompletionQueue* cq); + + /// DEPRECATED for multi-threaded use + /// Begin a call to a named method \a method using \a context. + /// A tag \a tag will be delivered to \a cq when the call has been started + /// (i.e, initial metadata has been sent). + /// The return value only indicates whether or not registration of the call + /// succeeded (i.e. the call won't proceed if the return value is nullptr). + std::unique_ptr Call( + grpc::ClientContext* context, const grpc::string& method, + grpc::CompletionQueue* cq, void* tag); + + /// NOTE: class experimental_type is not part of the public API of this class + /// TODO(vjpai): Move these contents to the public API of GenericStub when + /// they are no longer experimental + class experimental_type { + public: + explicit experimental_type(GenericStub* stub) : stub_(stub) {} + + /// Setup and start a unary call to a named method \a method using + /// \a context and specifying the \a request and \a response buffers. + void UnaryCall(grpc::ClientContext* context, const grpc::string& method, + const grpc::ByteBuffer* request, grpc::ByteBuffer* response, + std::function on_completion); + + /// Setup and start a unary call to a named method \a method using + /// \a context and specifying the \a request and \a response buffers. + void UnaryCall(grpc::ClientContext* context, const grpc::string& method, + const grpc::ByteBuffer* request, grpc::ByteBuffer* response, + grpc::experimental::ClientUnaryReactor* reactor); + + /// Setup a call to a named method \a method using \a context and tied to + /// \a reactor . Like any other bidi streaming RPC, it will not be activated + /// until StartCall is invoked on its reactor. + void PrepareBidiStreamingCall( + grpc::ClientContext* context, const grpc::string& method, + grpc::experimental::ClientBidiReactor* reactor); + + private: + GenericStub* stub_; + }; + + /// NOTE: The function experimental() is not stable public API. It is a view + /// to the experimental components of this class. It may be changed or removed + /// at any time. + experimental_type experimental() { return experimental_type(this); } + + private: + std::shared_ptr channel_; +}; + +} // namespace grpc_impl + +#endif // GRPCPP_GENERIC_GENERIC_STUB_IMPL_H diff --git a/include/grpcpp/health_check_service_interface.h b/include/grpcpp/health_check_service_interface.h index b45a699bda9..a51b0d18bba 100644 --- a/include/grpcpp/health_check_service_interface.h +++ b/include/grpcpp/health_check_service_interface.h @@ -1,6 +1,6 @@ /* * - * Copyright 2016 gRPC authors. + * Copyright 2019 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,35 +19,22 @@ #ifndef GRPCPP_HEALTH_CHECK_SERVICE_INTERFACE_H #define GRPCPP_HEALTH_CHECK_SERVICE_INTERFACE_H -#include +#include namespace grpc { const char kHealthCheckServiceInterfaceArg[] = "grpc.health_check_service_interface"; -/// The gRPC server uses this interface to expose the health checking service -/// without depending on protobuf. -class HealthCheckServiceInterface { - public: - virtual ~HealthCheckServiceInterface() {} +typedef ::grpc_impl::HealthCheckServiceInterface HealthCheckServiceInterface; - /// Set or change the serving status of the given \a service_name. - virtual void SetServingStatus(const grpc::string& service_name, - bool serving) = 0; - /// Apply to all registered service names. - virtual void SetServingStatus(bool serving) = 0; -}; +static inline void EnableDefaultHealthCheckService(bool enable) { + ::grpc_impl::EnableDefaultHealthCheckService(enable); +} -/// Enable/disable the default health checking service. This applies to all C++ -/// servers created afterwards. For each server, user can override the default -/// with a HealthCheckServiceServerBuilderOption. -/// NOT thread safe. -void EnableDefaultHealthCheckService(bool enable); - -/// Returns whether the default health checking service is enabled. -/// NOT thread safe. -bool DefaultHealthCheckServiceEnabled(); +static inline bool DefaultHealthCheckServiceEnabled() { + return ::grpc_impl::DefaultHealthCheckServiceEnabled(); +} } // namespace grpc diff --git a/include/grpcpp/health_check_service_interface_impl.h b/include/grpcpp/health_check_service_interface_impl.h new file mode 100644 index 00000000000..025dadb4e59 --- /dev/null +++ b/include/grpcpp/health_check_service_interface_impl.h @@ -0,0 +1,55 @@ +/* + * + * 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. + * + */ + +#ifndef GRPCPP_HEALTH_CHECK_SERVICE_INTERFACE_IMPL_H +#define GRPCPP_HEALTH_CHECK_SERVICE_INTERFACE_IMPL_H + +#include + +namespace grpc_impl { + +/// The gRPC server uses this interface to expose the health checking service +/// without depending on protobuf. +class HealthCheckServiceInterface { + public: + virtual ~HealthCheckServiceInterface() {} + + /// Set or change the serving status of the given \a service_name. + virtual void SetServingStatus(const grpc::string& service_name, + bool serving) = 0; + /// Apply to all registered service names. + virtual void SetServingStatus(bool serving) = 0; + + /// Set all registered service names to not serving and prevent future + /// state changes. + virtual void Shutdown() {} +}; + +/// Enable/disable the default health checking service. This applies to all C++ +/// servers created afterwards. For each server, user can override the default +/// with a HealthCheckServiceServerBuilderOption. +/// NOT thread safe. +void EnableDefaultHealthCheckService(bool enable); + +/// Returns whether the default health checking service is enabled. +/// NOT thread safe. +bool DefaultHealthCheckServiceEnabled(); + +} // namespace grpc_impl + +#endif // GRPCPP_HEALTH_CHECK_SERVICE_INTERFACE_IMPL_H diff --git a/include/grpcpp/impl/codegen/async_generic_service.h b/include/grpcpp/impl/codegen/async_generic_service.h index 2a0e1b40881..46d09121a7b 100644 --- a/include/grpcpp/impl/codegen/async_generic_service.h +++ b/include/grpcpp/impl/codegen/async_generic_service.h @@ -21,6 +21,7 @@ #include #include +#include struct grpc_server; @@ -38,9 +39,15 @@ class GenericServerContext final : public ServerContext { const grpc::string& host() const { return host_; } private: - friend class Server; + friend class grpc_impl::Server; friend class ServerInterface; + void Clear() { + method_.clear(); + host_.clear(); + ServerContext::Clear(); + } + grpc::string method_; grpc::string host_; }; @@ -72,10 +79,72 @@ class AsyncGenericService final { ServerCompletionQueue* notification_cq, void* tag); private: - friend class Server; - Server* server_; + friend class grpc_impl::Server; + grpc_impl::Server* server_; }; +namespace experimental { + +/// \a ServerGenericBidiReactor is the reactor class for bidi streaming RPCs +/// invoked on a CallbackGenericService. The API difference relative to +/// ServerBidiReactor is that the argument to OnStarted is a +/// GenericServerContext rather than a ServerContext. All other reaction and +/// operation initiation APIs are the same as ServerBidiReactor. +class ServerGenericBidiReactor + : public ServerBidiReactor { + public: + /// Similar to ServerBidiReactor::OnStarted except for argument type. + /// + /// \param[in] context The context object associated with this RPC. + virtual void OnStarted(GenericServerContext* context) {} + + private: + void OnStarted(ServerContext* ctx) final { + OnStarted(static_cast(ctx)); + } +}; + +} // namespace experimental + +namespace internal { +class UnimplementedGenericBidiReactor + : public experimental::ServerGenericBidiReactor { + public: + void OnDone() override { delete this; } + void OnStarted(GenericServerContext*) override { + this->Finish(Status(StatusCode::UNIMPLEMENTED, "")); + } +}; +} // namespace internal + +namespace experimental { + +/// \a CallbackGenericService is the base class for generic services implemented +/// using the callback API and registered through the ServerBuilder using +/// RegisterCallbackGenericService. +class CallbackGenericService { + public: + CallbackGenericService() {} + virtual ~CallbackGenericService() {} + + /// The "method handler" for the generic API. This function should be + /// overridden to return a ServerGenericBidiReactor that implements the + /// application-level interface for this RPC. + virtual ServerGenericBidiReactor* CreateReactor() { + return new internal::UnimplementedGenericBidiReactor; + } + + private: + friend class ::grpc_impl::Server; + + internal::CallbackBidiHandler* Handler() { + return new internal::CallbackBidiHandler( + [this] { return CreateReactor(); }); + } + + grpc_impl::Server* server_{nullptr}; +}; +} // namespace experimental } // namespace grpc #endif // GRPCPP_IMPL_CODEGEN_ASYNC_GENERIC_SERVICE_H diff --git a/include/grpcpp/impl/codegen/async_stream.h b/include/grpcpp/impl/codegen/async_stream.h index bfb2df4f232..f95772650a2 100644 --- a/include/grpcpp/impl/codegen/async_stream.h +++ b/include/grpcpp/impl/codegen/async_stream.h @@ -28,8 +28,6 @@ namespace grpc { -class CompletionQueue; - namespace internal { /// Common interface for all client side asynchronous streaming. class ClientAsyncStreamingInterface { @@ -661,7 +659,7 @@ class ServerAsyncReaderInterface /// some failure occurred when trying to do so. /// /// gRPC doesn't take ownership or a reference to \a msg or \a status, so it - /// is safe to to deallocate once Finish returns. + /// is safe to deallocate once Finish returns. /// /// \param[in] tag Tag identifying this request. /// \param[in] status To be sent to the client as the result of this call. @@ -735,7 +733,7 @@ class ServerAsyncReader final : public ServerAsyncReaderInterface { /// Note: \a msg is not sent if \a status has a non-OK code. /// /// gRPC doesn't take ownership or a reference to \a msg and \a status, so it - /// is safe to to deallocate once Finish returns. + /// is safe to deallocate once Finish returns. void Finish(const W& msg, const Status& status, void* tag) override { finish_ops_.set_output_tag(tag); if (!ctx_->sent_initial_metadata_) { @@ -830,7 +828,7 @@ class ServerAsyncWriterInterface /// in a single step. /// /// gRPC doesn't take ownership or a reference to \a msg and \a status, so it - /// is safe to to deallocate once WriteAndFinish returns. + /// is safe to deallocate once WriteAndFinish returns. /// /// \param[in] msg The message to be written. /// \param[in] options The WriteOptions to be used to write this message. @@ -897,7 +895,7 @@ class ServerAsyncWriter final : public ServerAsyncWriterInterface { /// Note: \a status must have an OK code. /// /// gRPC doesn't take ownership or a reference to \a msg and \a status, so it - /// is safe to to deallocate once WriteAndFinish returns. + /// is safe to deallocate once WriteAndFinish returns. void WriteAndFinish(const W& msg, WriteOptions options, const Status& status, void* tag) override { write_ops_.set_output_tag(tag); @@ -993,7 +991,7 @@ class ServerAsyncReaderWriterInterface /// single step. /// /// gRPC doesn't take ownership or a reference to \a msg and \a status, so it - /// is safe to to deallocate once WriteAndFinish returns. + /// is safe to deallocate once WriteAndFinish returns. /// /// \param[in] msg The message to be written. /// \param[in] options The WriteOptions to be used to write this message. @@ -1068,7 +1066,7 @@ class ServerAsyncReaderWriter final /// Note: \a status must have an OK code. // /// gRPC doesn't take ownership or a reference to \a msg and \a status, so it - /// is safe to to deallocate once WriteAndFinish returns. + /// is safe to deallocate once WriteAndFinish returns. void WriteAndFinish(const W& msg, WriteOptions options, const Status& status, void* tag) override { write_ops_.set_output_tag(tag); @@ -1099,7 +1097,7 @@ class ServerAsyncReaderWriter final } private: - friend class ::grpc::Server; + friend class ::grpc_impl::Server; void BindCall(::grpc::internal::Call* call) override { call_ = *call; } diff --git a/include/grpcpp/impl/codegen/async_unary_call.h b/include/grpcpp/impl/codegen/async_unary_call.h index 89dcb124189..4b97cf29018 100644 --- a/include/grpcpp/impl/codegen/async_unary_call.h +++ b/include/grpcpp/impl/codegen/async_unary_call.h @@ -29,7 +29,6 @@ namespace grpc { -class CompletionQueue; extern CoreCodegenInterface* g_core_codegen_interface; /// An interface relevant for async client side unary RPCs (which send diff --git a/include/grpcpp/impl/codegen/byte_buffer.h b/include/grpcpp/impl/codegen/byte_buffer.h index abba5549b86..7b82f49a84e 100644 --- a/include/grpcpp/impl/codegen/byte_buffer.h +++ b/include/grpcpp/impl/codegen/byte_buffer.h @@ -45,8 +45,10 @@ template class RpcMethodHandler; template class ServerStreamingHandler; -template +template class CallbackUnaryHandler; +template +class CallbackServerStreamingHandler; template class ErrorMethodHandler; template @@ -91,8 +93,10 @@ class ByteBuffer final { } /// Constuct a byte buffer by referencing elements of existing buffer - /// \a buf. Wrapper of core function grpc_byte_buffer_copy - ByteBuffer(const ByteBuffer& buf); + /// \a buf. Wrapper of core function grpc_byte_buffer_copy . This is not + /// a deep copy; it is just a referencing. As a result, its performance is + /// size-independent. + ByteBuffer(const ByteBuffer& buf) : buffer_(nullptr) { operator=(buf); } ~ByteBuffer() { if (buffer_) { @@ -100,7 +104,19 @@ class ByteBuffer final { } } - ByteBuffer& operator=(const ByteBuffer&); + /// Wrapper of core function grpc_byte_buffer_copy . This is not + /// a deep copy; it is just a referencing. As a result, its performance is + /// size-independent. + ByteBuffer& operator=(const ByteBuffer& buf) { + if (this != &buf) { + Clear(); // first remove existing data + } + if (buf.buffer_) { + // then copy + buffer_ = g_core_codegen_interface->grpc_byte_buffer_copy(buf.buffer_); + } + return *this; + } /// Dump (read) the buffer contents into \a slices. Status Dump(std::vector* slices) const; @@ -115,7 +131,9 @@ class ByteBuffer final { /// Make a duplicate copy of the internals of this byte /// buffer so that we have our own owned version of it. - /// bbuf.Duplicate(); is equivalent to bbuf=bbuf; but is actually readable + /// bbuf.Duplicate(); is equivalent to bbuf=bbuf; but is actually readable. + /// This is not a deep copy; it is a referencing and its performance + /// is size-independent. void Duplicate() { buffer_ = g_core_codegen_interface->grpc_byte_buffer_copy(buffer_); } @@ -156,8 +174,10 @@ class ByteBuffer final { friend class internal::RpcMethodHandler; template friend class internal::ServerStreamingHandler; - template + template friend class internal::CallbackUnaryHandler; + template + friend class ::grpc::internal::CallbackServerStreamingHandler; template friend class internal::ErrorMethodHandler; template @@ -204,7 +224,7 @@ class SerializationTraits { bool* own_buffer) { *buffer = source; *own_buffer = true; - return Status::OK; + return g_core_codegen_interface->ok(); } }; diff --git a/include/grpcpp/impl/codegen/call.h b/include/grpcpp/impl/codegen/call.h index c040c30dd9d..eefa4a7f9cd 100644 --- a/include/grpcpp/impl/codegen/call.h +++ b/include/grpcpp/impl/codegen/call.h @@ -21,9 +21,11 @@ #include #include -namespace grpc { +namespace grpc_impl { class CompletionQueue; +} +namespace grpc { namespace experimental { class ClientRpcInfo; class ServerRpcInfo; @@ -41,13 +43,13 @@ class Call final { call_(nullptr), max_receive_message_size_(-1) {} /** call is owned by the caller */ - Call(grpc_call* call, CallHook* call_hook, CompletionQueue* cq) + Call(grpc_call* call, CallHook* call_hook, ::grpc_impl::CompletionQueue* cq) : call_hook_(call_hook), cq_(cq), call_(call), max_receive_message_size_(-1) {} - Call(grpc_call* call, CallHook* call_hook, CompletionQueue* cq, + Call(grpc_call* call, CallHook* call_hook, ::grpc_impl::CompletionQueue* cq, experimental::ClientRpcInfo* rpc_info) : call_hook_(call_hook), cq_(cq), @@ -55,7 +57,7 @@ class Call final { max_receive_message_size_(-1), client_rpc_info_(rpc_info) {} - Call(grpc_call* call, CallHook* call_hook, CompletionQueue* cq, + Call(grpc_call* call, CallHook* call_hook, ::grpc_impl::CompletionQueue* cq, int max_receive_message_size, experimental::ServerRpcInfo* rpc_info) : call_hook_(call_hook), cq_(cq), @@ -68,7 +70,7 @@ class Call final { } grpc_call* call() const { return call_; } - CompletionQueue* cq() const { return cq_; } + ::grpc_impl::CompletionQueue* cq() const { return cq_; } int max_receive_message_size() const { return max_receive_message_size_; } @@ -82,7 +84,7 @@ class Call final { private: CallHook* call_hook_; - CompletionQueue* cq_; + ::grpc_impl::CompletionQueue* cq_; grpc_call* call_; int max_receive_message_size_; experimental::ClientRpcInfo* client_rpc_info_ = nullptr; diff --git a/include/grpcpp/impl/codegen/call_op_set.h b/include/grpcpp/impl/codegen/call_op_set.h index b4c34a01c9a..d810625b3e4 100644 --- a/include/grpcpp/impl/codegen/call_op_set.h +++ b/include/grpcpp/impl/codegen/call_op_set.h @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -47,7 +48,6 @@ namespace grpc { -class CompletionQueue; extern CoreCodegenInterface* g_core_codegen_interface; namespace internal { @@ -303,9 +303,29 @@ class CallOpSendMessage { template Status SendMessage(const M& message) GRPC_MUST_USE_RESULT; + /// Send \a message using \a options for the write. The \a options are cleared + /// after use. This form of SendMessage allows gRPC to reference \a message + /// beyond the lifetime of SendMessage. + template + Status SendMessagePtr(const M* message, + WriteOptions options) GRPC_MUST_USE_RESULT; + + /// This form of SendMessage allows gRPC to reference \a message beyond the + /// lifetime of SendMessage. + template + Status SendMessagePtr(const M* message) GRPC_MUST_USE_RESULT; + protected: void AddOp(grpc_op* ops, size_t* nops) { - if (!send_buf_.Valid() || hijacked_) return; + if (msg_ == nullptr && !send_buf_.Valid()) return; + if (hijacked_) { + serializer_ = nullptr; + return; + } + if (msg_ != nullptr) { + GPR_CODEGEN_ASSERT(serializer_(msg_).ok()); + } + serializer_ = nullptr; grpc_op* op = &ops[(*nops)++]; op->op = GRPC_OP_SEND_MESSAGE; op->flags = write_options_.flags(); @@ -314,43 +334,77 @@ class CallOpSendMessage { // Flags are per-message: clear them after use. write_options_.Clear(); } - void FinishOp(bool* status) { send_buf_.Clear(); } + void FinishOp(bool* status) { + if (msg_ == nullptr && !send_buf_.Valid()) return; + if (hijacked_ && failed_send_) { + // Hijacking interceptor failed this Op + *status = false; + } else if (!*status) { + // This Op was passed down to core and the Op failed + failed_send_ = true; + } + } void SetInterceptionHookPoint( InterceptorBatchMethodsImpl* interceptor_methods) { - if (!send_buf_.Valid()) return; + if (msg_ == nullptr && !send_buf_.Valid()) return; interceptor_methods->AddInterceptionHookPoint( experimental::InterceptionHookPoints::PRE_SEND_MESSAGE); - interceptor_methods->SetSendMessage(&send_buf_); + interceptor_methods->SetSendMessage(&send_buf_, &msg_, &failed_send_, + serializer_); } void SetFinishInterceptionHookPoint( - InterceptorBatchMethodsImpl* interceptor_methods) {} + InterceptorBatchMethodsImpl* interceptor_methods) { + if (msg_ != nullptr || send_buf_.Valid()) { + interceptor_methods->AddInterceptionHookPoint( + experimental::InterceptionHookPoints::POST_SEND_MESSAGE); + } + send_buf_.Clear(); + msg_ = nullptr; + // The contents of the SendMessage value that was previously set + // has had its references stolen by core's operations + interceptor_methods->SetSendMessage(nullptr, nullptr, &failed_send_, + nullptr); + } void SetHijackingState(InterceptorBatchMethodsImpl* interceptor_methods) { hijacked_ = true; } private: + const void* msg_ = nullptr; // The original non-serialized message bool hijacked_ = false; + bool failed_send_ = false; ByteBuffer send_buf_; WriteOptions write_options_; + std::function serializer_; }; template Status CallOpSendMessage::SendMessage(const M& message, WriteOptions options) { write_options_ = options; - bool own_buf; - // TODO(vjpai): Remove the void below when possible - // The void in the template parameter below should not be needed - // (since it should be implicit) but is needed due to an observed - // difference in behavior between clang and gcc for certain internal users - Status result = SerializationTraits::Serialize( - message, send_buf_.bbuf_ptr(), &own_buf); - if (!own_buf) { - send_buf_.Duplicate(); + serializer_ = [this](const void* message) { + bool own_buf; + send_buf_.Clear(); + // TODO(vjpai): Remove the void below when possible + // The void in the template parameter below should not be needed + // (since it should be implicit) but is needed due to an observed + // difference in behavior between clang and gcc for certain internal users + Status result = SerializationTraits::Serialize( + *static_cast(message), send_buf_.bbuf_ptr(), &own_buf); + if (!own_buf) { + send_buf_.Duplicate(); + } + return result; + }; + // Serialize immediately only if we do not have access to the message pointer + if (msg_ == nullptr) { + Status result = serializer_(&message); + serializer_ = nullptr; + return result; } - return result; + return Status(); } template @@ -358,6 +412,19 @@ Status CallOpSendMessage::SendMessage(const M& message) { return SendMessage(message, WriteOptions()); } +template +Status CallOpSendMessage::SendMessagePtr(const M* message, + WriteOptions options) { + msg_ = message; + return SendMessage(*message, options); +} + +template +Status CallOpSendMessage::SendMessagePtr(const M* message) { + msg_ = message; + return SendMessage(*message, WriteOptions()); +} + template class CallOpRecvMessage { public: @@ -406,14 +473,16 @@ class CallOpRecvMessage { void SetInterceptionHookPoint( InterceptorBatchMethodsImpl* interceptor_methods) { - interceptor_methods->SetRecvMessage(message_); + if (message_ == nullptr) return; + interceptor_methods->SetRecvMessage(message_, &got_message); } void SetFinishInterceptionHookPoint( InterceptorBatchMethodsImpl* interceptor_methods) { - if (!got_message) return; + if (message_ == nullptr) return; interceptor_methods->AddInterceptionHookPoint( experimental::InterceptionHookPoints::POST_RECV_MESSAGE); + if (!got_message) interceptor_methods->SetRecvMessage(nullptr, nullptr); } void SetHijackingState(InterceptorBatchMethodsImpl* interceptor_methods) { hijacked_ = true; @@ -501,20 +570,23 @@ class CallOpGenericRecvMessage { void SetInterceptionHookPoint( InterceptorBatchMethodsImpl* interceptor_methods) { - interceptor_methods->SetRecvMessage(message_); + if (!deserialize_) return; + interceptor_methods->SetRecvMessage(message_, &got_message); } void SetFinishInterceptionHookPoint( InterceptorBatchMethodsImpl* interceptor_methods) { - if (!got_message) return; + if (!deserialize_) return; interceptor_methods->AddInterceptionHookPoint( experimental::InterceptionHookPoints::POST_RECV_MESSAGE); + if (!got_message) interceptor_methods->SetRecvMessage(nullptr, nullptr); } void SetHijackingState(InterceptorBatchMethodsImpl* interceptor_methods) { hijacked_ = true; if (!deserialize_) return; interceptor_methods->AddInterceptionHookPoint( experimental::InterceptionHookPoints::PRE_RECV_MESSAGE); + got_message = true; } private: @@ -805,6 +877,8 @@ class CallOpSet : public CallOpSetInterface, bool FinalizeResult(void** tag, bool* status) override { if (done_intercepting_) { + // Complete the avalanching since we are done with this batch of ops + call_.cq()->CompleteAvalanching(); // We have already finished intercepting and filling in the results. This // round trip from the core needed to be made because interceptors were // run @@ -889,6 +963,12 @@ class CallOpSet : public CallOpSetInterface, this->Op4::SetInterceptionHookPoint(&interceptor_methods_); this->Op5::SetInterceptionHookPoint(&interceptor_methods_); this->Op6::SetInterceptionHookPoint(&interceptor_methods_); + if (interceptor_methods_.InterceptorsListEmpty()) { + return true; + } + // This call will go through interceptors and would need to + // schedule new batches, so delay completion queue shutdown + call_.cq()->RegisterAvalanching(); return interceptor_methods_.RunInterceptors(); } // Returns true if no interceptors need to be run diff --git a/include/grpcpp/impl/codegen/callback_common.h b/include/grpcpp/impl/codegen/callback_common.h index 51367cf550c..a3c8c41246c 100644 --- a/include/grpcpp/impl/codegen/callback_common.h +++ b/include/grpcpp/impl/codegen/callback_common.h @@ -32,6 +32,8 @@ namespace grpc { namespace internal { /// An exception-safe way of invoking a user-specified callback function +// TODO(vjpai): decide whether it is better for this to take a const lvalue +// parameter or an rvalue parameter, or if it even matters template void CatchingCallback(Func&& func, Args&&... args) { #if GRPC_ALLOW_EXCEPTIONS @@ -45,6 +47,20 @@ void CatchingCallback(Func&& func, Args&&... args) { #endif // GRPC_ALLOW_EXCEPTIONS } +template +ReturnType* CatchingReactorCreator(Func&& func, Args&&... args) { +#if GRPC_ALLOW_EXCEPTIONS + try { + return func(std::forward(args)...); + } catch (...) { + // fail the RPC, don't crash the library + return nullptr; + } +#else // GRPC_ALLOW_EXCEPTIONS + return func(std::forward(args)...); +#endif // GRPC_ALLOW_EXCEPTIONS +} + // The contract on these tags is that they are single-shot. They must be // constructed and then fired at exactly one point. There is no expectation // that they can be reused without reconstruction. @@ -145,18 +161,19 @@ class CallbackWithSuccessTag // or on a tag that has been Set before unless the tag has been cleared. void Set(grpc_call* call, std::function f, CompletionQueueTag* ops) { + GPR_CODEGEN_ASSERT(call_ == nullptr); + g_core_codegen_interface->grpc_call_ref(call); call_ = call; func_ = std::move(f); ops_ = ops; - g_core_codegen_interface->grpc_call_ref(call); functor_run = &CallbackWithSuccessTag::StaticRun; } void Clear() { if (call_ != nullptr) { - func_ = nullptr; grpc_call* call = call_; call_ = nullptr; + func_ = nullptr; g_core_codegen_interface->grpc_call_unref(call); } } @@ -182,11 +199,11 @@ class CallbackWithSuccessTag } void Run(bool ok) { void* ignored = ops_; - bool new_ok = ok; // Allow a "false" return value from FinalizeResult to silence the // callback, just as it silences a CQ tag in the async cases - bool do_callback = ops_->FinalizeResult(&ignored, &new_ok); - GPR_CODEGEN_ASSERT(ignored == ops_); + auto* ops = ops_; + bool do_callback = ops_->FinalizeResult(&ignored, &ok); + GPR_CODEGEN_ASSERT(ignored == ops); if (do_callback) { CatchingCallback(func_, ok); diff --git a/include/grpcpp/impl/codegen/channel_interface.h b/include/grpcpp/impl/codegen/channel_interface.h index 6ec1ffb8c7d..9df233b5500 100644 --- a/include/grpcpp/impl/codegen/channel_interface.h +++ b/include/grpcpp/impl/codegen/channel_interface.h @@ -21,14 +21,16 @@ #include #include -#include #include #include +namespace grpc_impl { +class CompletionQueue; +} + namespace grpc { class ChannelInterface; class ClientContext; -class CompletionQueue; template class ClientReader; @@ -53,6 +55,13 @@ template class ClientAsyncReaderWriterFactory; template class ClientAsyncResponseReaderFactory; +template +class ClientCallbackReaderWriterFactory; +template +class ClientCallbackReaderFactory; +template +class ClientCallbackWriterFactory; +class ClientCallbackUnaryFactory; class InterceptedChannel; } // namespace internal @@ -68,7 +77,7 @@ class ChannelInterface { /// deadline expires. \a GetState needs to called to get the current state. template void NotifyOnStateChange(grpc_connectivity_state last_observed, T deadline, - CompletionQueue* cq, void* tag) { + ::grpc_impl::CompletionQueue* cq, void* tag) { TimePoint deadline_tp(deadline); NotifyOnStateChangeImpl(last_observed, deadline_tp.raw_time(), cq, tag); } @@ -106,6 +115,13 @@ class ChannelInterface { friend class ::grpc::internal::ClientAsyncReaderWriterFactory; template friend class ::grpc::internal::ClientAsyncResponseReaderFactory; + template + friend class ::grpc::internal::ClientCallbackReaderWriterFactory; + template + friend class ::grpc::internal::ClientCallbackReaderFactory; + template + friend class ::grpc::internal::ClientCallbackWriterFactory; + friend class ::grpc::internal::ClientCallbackUnaryFactory; template friend class ::grpc::internal::BlockingUnaryCallImpl; template @@ -114,13 +130,14 @@ class ChannelInterface { friend class ::grpc::internal::InterceptedChannel; virtual internal::Call CreateCall(const internal::RpcMethod& method, ClientContext* context, - CompletionQueue* cq) = 0; + ::grpc_impl::CompletionQueue* cq) = 0; virtual void PerformOpsOnCall(internal::CallOpSetInterface* ops, internal::Call* call) = 0; virtual void* RegisterMethod(const char* method) = 0; virtual void NotifyOnStateChangeImpl(grpc_connectivity_state last_observed, gpr_timespec deadline, - CompletionQueue* cq, void* tag) = 0; + ::grpc_impl::CompletionQueue* cq, + void* tag) = 0; virtual bool WaitForStateChangeImpl(grpc_connectivity_state last_observed, gpr_timespec deadline) = 0; @@ -133,7 +150,7 @@ class ChannelInterface { // change (even though this is private and non-API) virtual internal::Call CreateCallInternal(const internal::RpcMethod& method, ClientContext* context, - CompletionQueue* cq, + ::grpc_impl::CompletionQueue* cq, size_t interceptor_pos) { return internal::Call(); } @@ -146,7 +163,7 @@ class ChannelInterface { // Returns nullptr (rather than being pure) since this is a post-1.0 method // and adding a new pure method to an interface would be a breaking change // (even though this is private and non-API) - virtual CompletionQueue* CallbackCQ() { return nullptr; } + virtual ::grpc_impl::CompletionQueue* CallbackCQ() { return nullptr; } }; } // namespace grpc diff --git a/include/grpcpp/impl/codegen/client_callback.h b/include/grpcpp/impl/codegen/client_callback.h index 4baa819091c..dda9aec29f3 100644 --- a/include/grpcpp/impl/codegen/client_callback.h +++ b/include/grpcpp/impl/codegen/client_callback.h @@ -22,17 +22,20 @@ #include #include +#include #include #include #include #include #include +namespace grpc_impl { +class Channel; +} + namespace grpc { -class Channel; class ClientContext; -class CompletionQueue; namespace internal { class RpcMethod; @@ -72,7 +75,7 @@ class CallbackUnaryCallImpl { CallbackWithStatusTag(call.call(), on_completion, ops); // TODO(vjpai): Unify code with sync API as much as possible - Status s = ops->SendMessage(*request); + Status s = ops->SendMessagePtr(request); if (!s.ok()) { tag->force_run(s); return; @@ -88,6 +91,928 @@ class CallbackUnaryCallImpl { call.PerformOps(ops); } }; +} // namespace internal + +namespace experimental { + +// Forward declarations +template +class ClientBidiReactor; +template +class ClientReadReactor; +template +class ClientWriteReactor; +class ClientUnaryReactor; + +// NOTE: The streaming objects are not actually implemented in the public API. +// These interfaces are provided for mocking only. Typical applications +// will interact exclusively with the reactors that they define. +template +class ClientCallbackReaderWriter { + public: + virtual ~ClientCallbackReaderWriter() {} + virtual void StartCall() = 0; + virtual void Write(const Request* req, WriteOptions options) = 0; + virtual void WritesDone() = 0; + virtual void Read(Response* resp) = 0; + virtual void AddHold(int holds) = 0; + virtual void RemoveHold() = 0; + + protected: + void BindReactor(ClientBidiReactor* reactor) { + reactor->BindStream(this); + } +}; + +template +class ClientCallbackReader { + public: + virtual ~ClientCallbackReader() {} + virtual void StartCall() = 0; + virtual void Read(Response* resp) = 0; + virtual void AddHold(int holds) = 0; + virtual void RemoveHold() = 0; + + protected: + void BindReactor(ClientReadReactor* reactor) { + reactor->BindReader(this); + } +}; + +template +class ClientCallbackWriter { + public: + virtual ~ClientCallbackWriter() {} + virtual void StartCall() = 0; + void Write(const Request* req) { Write(req, WriteOptions()); } + virtual void Write(const Request* req, WriteOptions options) = 0; + void WriteLast(const Request* req, WriteOptions options) { + Write(req, options.set_last_message()); + } + virtual void WritesDone() = 0; + + virtual void AddHold(int holds) = 0; + virtual void RemoveHold() = 0; + + protected: + void BindReactor(ClientWriteReactor* reactor) { + reactor->BindWriter(this); + } +}; + +class ClientCallbackUnary { + public: + virtual ~ClientCallbackUnary() {} + virtual void StartCall() = 0; + + protected: + void BindReactor(ClientUnaryReactor* reactor); +}; + +// The following classes are the reactor interfaces that are to be implemented +// by the user. They are passed in to the library as an argument to a call on a +// stub (either a codegen-ed call or a generic call). The streaming RPC is +// activated by calling StartCall, possibly after initiating StartRead, +// StartWrite, or AddHold operations on the streaming object. Note that none of +// the classes are pure; all reactions have a default empty reaction so that the +// user class only needs to override those classes that it cares about. +// The reactor must be passed to the stub invocation before any of the below +// operations can be called. + +/// \a ClientBidiReactor is the interface for a bidirectional streaming RPC. +template +class ClientBidiReactor { + public: + virtual ~ClientBidiReactor() {} + + /// Activate the RPC and initiate any reads or writes that have been Start'ed + /// before this call. All streaming RPCs issued by the client MUST have + /// StartCall invoked on them (even if they are canceled) as this call is the + /// activation of their lifecycle. + void StartCall() { stream_->StartCall(); } + + /// Initiate a read operation (or post it for later initiation if StartCall + /// has not yet been invoked). + /// + /// \param[out] resp Where to eventually store the read message. Valid when + /// the library calls OnReadDone + void StartRead(Response* resp) { stream_->Read(resp); } + + /// Initiate a write operation (or post it for later initiation if StartCall + /// has not yet been invoked). + /// + /// \param[in] req The message to be written. The library takes temporary + /// ownership until OnWriteDone, at which point the application + /// regains ownership of msg. + void StartWrite(const Request* req) { StartWrite(req, WriteOptions()); } + + /// Initiate/post a write operation with specified options. + /// + /// \param[in] req The message to be written. The library takes temporary + /// ownership until OnWriteDone, at which point the application + /// regains ownership of msg. + /// \param[in] options The WriteOptions to use for writing this message + void StartWrite(const Request* req, WriteOptions options) { + stream_->Write(req, std::move(options)); + } + + /// Initiate/post a write operation with specified options and an indication + /// that this is the last write (like StartWrite and StartWritesDone, merged). + /// Note that calling this means that no more calls to StartWrite, + /// StartWriteLast, or StartWritesDone are allowed. + /// + /// \param[in] req The message to be written. The library takes temporary + /// ownership until OnWriteDone, at which point the application + /// regains ownership of msg. + /// \param[in] options The WriteOptions to use for writing this message + void StartWriteLast(const Request* req, WriteOptions options) { + StartWrite(req, std::move(options.set_last_message())); + } + + /// Indicate that the RPC will have no more write operations. This can only be + /// issued once for a given RPC. This is not required or allowed if + /// StartWriteLast is used since that already has the same implication. + /// Note that calling this means that no more calls to StartWrite, + /// StartWriteLast, or StartWritesDone are allowed. + void StartWritesDone() { stream_->WritesDone(); } + + /// Holds are needed if (and only if) this stream has operations that take + /// place on it after StartCall but from outside one of the reactions + /// (OnReadDone, etc). This is _not_ a common use of the streaming API. + /// + /// Holds must be added before calling StartCall. If a stream still has a hold + /// in place, its resources will not be destroyed even if the status has + /// already come in from the wire and there are currently no active callbacks + /// outstanding. Similarly, the stream will not call OnDone if there are still + /// holds on it. + /// + /// For example, if a StartRead or StartWrite operation is going to be + /// initiated from elsewhere in the application, the application should call + /// AddHold or AddMultipleHolds before StartCall. If there is going to be, + /// for example, a read-flow and a write-flow taking place outside the + /// reactions, then call AddMultipleHolds(2) before StartCall. When the + /// application knows that it won't issue any more read operations (such as + /// when a read comes back as not ok), it should issue a RemoveHold(). It + /// should also call RemoveHold() again after it does StartWriteLast or + /// StartWritesDone that indicates that there will be no more write ops. + /// The number of RemoveHold calls must match the total number of AddHold + /// calls plus the number of holds added by AddMultipleHolds. + void AddHold() { AddMultipleHolds(1); } + void AddMultipleHolds(int holds) { stream_->AddHold(holds); } + void RemoveHold() { stream_->RemoveHold(); } + + /// Notifies the application that all operations associated with this RPC + /// have completed and provides the RPC status outcome. + /// + /// \param[in] s The status outcome of this RPC + virtual void OnDone(const Status& s) {} + + /// Notifies the application that a read of initial metadata from the + /// server is done. If the application chooses not to implement this method, + /// it can assume that the initial metadata has been read before the first + /// call of OnReadDone or OnDone. + /// + /// \param[in] ok Was the initial metadata read successfully? If false, no + /// further read-side operation will succeed. + virtual void OnReadInitialMetadataDone(bool ok) {} + + /// Notifies the application that a StartRead operation completed. + /// + /// \param[in] ok Was it successful? If false, no further read-side operation + /// will succeed. + virtual void OnReadDone(bool ok) {} + + /// Notifies the application that a StartWrite operation completed. + /// + /// \param[in] ok Was it successful? If false, no further write-side operation + /// will succeed. + virtual void OnWriteDone(bool ok) {} + + /// Notifies the application that a StartWritesDone operation completed. Note + /// that this is only used on explicit StartWritesDone operations and not for + /// those that are implicitly invoked as part of a StartWriteLast. + /// + /// \param[in] ok Was it successful? If false, the application will later see + /// the failure reflected as a bad status in OnDone. + virtual void OnWritesDoneDone(bool ok) {} + + private: + friend class ClientCallbackReaderWriter; + void BindStream(ClientCallbackReaderWriter* stream) { + stream_ = stream; + } + ClientCallbackReaderWriter* stream_; +}; + +/// \a ClientReadReactor is the interface for a server-streaming RPC. +/// All public methods behave as in ClientBidiReactor. +template +class ClientReadReactor { + public: + virtual ~ClientReadReactor() {} + + void StartCall() { reader_->StartCall(); } + void StartRead(Response* resp) { reader_->Read(resp); } + + void AddHold() { AddMultipleHolds(1); } + void AddMultipleHolds(int holds) { reader_->AddHold(holds); } + void RemoveHold() { reader_->RemoveHold(); } + + virtual void OnDone(const Status& s) {} + virtual void OnReadInitialMetadataDone(bool ok) {} + virtual void OnReadDone(bool ok) {} + + private: + friend class ClientCallbackReader; + void BindReader(ClientCallbackReader* reader) { reader_ = reader; } + ClientCallbackReader* reader_; +}; + +/// \a ClientWriteReactor is the interface for a client-streaming RPC. +/// All public methods behave as in ClientBidiReactor. +template +class ClientWriteReactor { + public: + virtual ~ClientWriteReactor() {} + + void StartCall() { writer_->StartCall(); } + void StartWrite(const Request* req) { StartWrite(req, WriteOptions()); } + void StartWrite(const Request* req, WriteOptions options) { + writer_->Write(req, std::move(options)); + } + void StartWriteLast(const Request* req, WriteOptions options) { + StartWrite(req, std::move(options.set_last_message())); + } + void StartWritesDone() { writer_->WritesDone(); } + + void AddHold() { AddMultipleHolds(1); } + void AddMultipleHolds(int holds) { writer_->AddHold(holds); } + void RemoveHold() { writer_->RemoveHold(); } + + virtual void OnDone(const Status& s) {} + virtual void OnReadInitialMetadataDone(bool ok) {} + virtual void OnWriteDone(bool ok) {} + virtual void OnWritesDoneDone(bool ok) {} + + private: + friend class ClientCallbackWriter; + void BindWriter(ClientCallbackWriter* writer) { writer_ = writer; } + ClientCallbackWriter* writer_; +}; + +/// \a ClientUnaryReactor is a reactor-style interface for a unary RPC. +/// This is _not_ a common way of invoking a unary RPC. In practice, this +/// option should be used only if the unary RPC wants to receive initial +/// metadata without waiting for the response to complete. Most deployments of +/// RPC systems do not use this option, but it is needed for generality. +/// All public methods behave as in ClientBidiReactor. +/// StartCall is included for consistency with the other reactor flavors: even +/// though there are no StartRead or StartWrite operations to queue before the +/// call (that is part of the unary call itself) and there is no reactor object +/// being created as a result of this call, we keep a consistent 2-phase +/// initiation API among all the reactor flavors. +class ClientUnaryReactor { + public: + virtual ~ClientUnaryReactor() {} + + void StartCall() { call_->StartCall(); } + virtual void OnDone(const Status& s) {} + virtual void OnReadInitialMetadataDone(bool ok) {} + + private: + friend class ClientCallbackUnary; + void BindCall(ClientCallbackUnary* call) { call_ = call; } + ClientCallbackUnary* call_; +}; + +// Define function out-of-line from class to avoid forward declaration issue +inline void ClientCallbackUnary::BindReactor(ClientUnaryReactor* reactor) { + reactor->BindCall(this); +} + +} // namespace experimental + +namespace internal { + +// Forward declare factory classes for friendship +template +class ClientCallbackReaderWriterFactory; +template +class ClientCallbackReaderFactory; +template +class ClientCallbackWriterFactory; + +template +class ClientCallbackReaderWriterImpl + : public ::grpc::experimental::ClientCallbackReaderWriter { + public: + // always allocated against a call arena, no memory free required + static void operator delete(void* ptr, std::size_t size) { + assert(size == sizeof(ClientCallbackReaderWriterImpl)); + } + + // This operator should never be called as the memory should be freed as part + // of the arena destruction. It only exists to provide a matching operator + // delete to the operator new so that some compilers will not complain (see + // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this + // there are no tests catching the compiler warning. + static void operator delete(void*, void*) { assert(0); } + + void MaybeFinish() { + if (--callbacks_outstanding_ == 0) { + Status s = std::move(finish_status_); + auto* reactor = reactor_; + auto* call = call_.call(); + this->~ClientCallbackReaderWriterImpl(); + g_core_codegen_interface->grpc_call_unref(call); + reactor->OnDone(s); + } + } + + void StartCall() override { + // This call initiates two batches, plus any backlog, each with a callback + // 1. Send initial metadata (unless corked) + recv initial metadata + // 2. Any read backlog + // 3. Any write backlog + // 4. Recv trailing metadata, on_completion callback + started_ = true; + + start_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnReadInitialMetadataDone(ok); + MaybeFinish(); + }, + &start_ops_); + if (!start_corked_) { + start_ops_.SendInitialMetadata(&context_->send_initial_metadata_, + context_->initial_metadata_flags()); + } + start_ops_.RecvInitialMetadata(context_); + start_ops_.set_core_cq_tag(&start_tag_); + call_.PerformOps(&start_ops_); + + // Also set up the read and write tags so that they don't have to be set up + // each time + write_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnWriteDone(ok); + MaybeFinish(); + }, + &write_ops_); + write_ops_.set_core_cq_tag(&write_tag_); + + read_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnReadDone(ok); + MaybeFinish(); + }, + &read_ops_); + read_ops_.set_core_cq_tag(&read_tag_); + if (read_ops_at_start_) { + call_.PerformOps(&read_ops_); + } + + if (write_ops_at_start_) { + call_.PerformOps(&write_ops_); + } + + if (writes_done_ops_at_start_) { + call_.PerformOps(&writes_done_ops_); + } + + finish_tag_.Set(call_.call(), [this](bool ok) { MaybeFinish(); }, + &finish_ops_); + finish_ops_.ClientRecvStatus(context_, &finish_status_); + finish_ops_.set_core_cq_tag(&finish_tag_); + call_.PerformOps(&finish_ops_); + } + + void Read(Response* msg) override { + read_ops_.RecvMessage(msg); + callbacks_outstanding_++; + if (started_) { + call_.PerformOps(&read_ops_); + } else { + read_ops_at_start_ = true; + } + } + + void Write(const Request* msg, WriteOptions options) override { + if (start_corked_) { + write_ops_.SendInitialMetadata(&context_->send_initial_metadata_, + context_->initial_metadata_flags()); + start_corked_ = false; + } + + if (options.is_last_message()) { + options.set_buffer_hint(); + write_ops_.ClientSendClose(); + } + // TODO(vjpai): don't assert + GPR_CODEGEN_ASSERT(write_ops_.SendMessagePtr(msg, options).ok()); + callbacks_outstanding_++; + if (started_) { + call_.PerformOps(&write_ops_); + } else { + write_ops_at_start_ = true; + } + } + void WritesDone() override { + if (start_corked_) { + writes_done_ops_.SendInitialMetadata(&context_->send_initial_metadata_, + context_->initial_metadata_flags()); + start_corked_ = false; + } + writes_done_ops_.ClientSendClose(); + writes_done_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnWritesDoneDone(ok); + MaybeFinish(); + }, + &writes_done_ops_); + writes_done_ops_.set_core_cq_tag(&writes_done_tag_); + callbacks_outstanding_++; + if (started_) { + call_.PerformOps(&writes_done_ops_); + } else { + writes_done_ops_at_start_ = true; + } + } + + virtual void AddHold(int holds) override { callbacks_outstanding_ += holds; } + virtual void RemoveHold() override { MaybeFinish(); } + + private: + friend class ClientCallbackReaderWriterFactory; + + ClientCallbackReaderWriterImpl( + Call call, ClientContext* context, + ::grpc::experimental::ClientBidiReactor* reactor) + : context_(context), + call_(call), + reactor_(reactor), + start_corked_(context_->initial_metadata_corked_) { + this->BindReactor(reactor); + } + + ClientContext* const context_; + Call call_; + ::grpc::experimental::ClientBidiReactor* const reactor_; + + CallOpSet start_ops_; + CallbackWithSuccessTag start_tag_; + bool start_corked_; + + CallOpSet finish_ops_; + CallbackWithSuccessTag finish_tag_; + Status finish_status_; + + CallOpSet + write_ops_; + CallbackWithSuccessTag write_tag_; + bool write_ops_at_start_{false}; + + CallOpSet writes_done_ops_; + CallbackWithSuccessTag writes_done_tag_; + bool writes_done_ops_at_start_{false}; + + CallOpSet> read_ops_; + CallbackWithSuccessTag read_tag_; + bool read_ops_at_start_{false}; + + // Minimum of 2 callbacks to pre-register for start and finish + std::atomic_int callbacks_outstanding_{2}; + bool started_{false}; +}; + +template +class ClientCallbackReaderWriterFactory { + public: + static void Create( + ChannelInterface* channel, const ::grpc::internal::RpcMethod& method, + ClientContext* context, + ::grpc::experimental::ClientBidiReactor* reactor) { + Call call = channel->CreateCall(method, context, channel->CallbackCQ()); + + g_core_codegen_interface->grpc_call_ref(call.call()); + new (g_core_codegen_interface->grpc_call_arena_alloc( + call.call(), sizeof(ClientCallbackReaderWriterImpl))) + ClientCallbackReaderWriterImpl(call, context, + reactor); + } +}; + +template +class ClientCallbackReaderImpl + : public ::grpc::experimental::ClientCallbackReader { + public: + // always allocated against a call arena, no memory free required + static void operator delete(void* ptr, std::size_t size) { + assert(size == sizeof(ClientCallbackReaderImpl)); + } + + // This operator should never be called as the memory should be freed as part + // of the arena destruction. It only exists to provide a matching operator + // delete to the operator new so that some compilers will not complain (see + // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this + // there are no tests catching the compiler warning. + static void operator delete(void*, void*) { assert(0); } + + void MaybeFinish() { + if (--callbacks_outstanding_ == 0) { + Status s = std::move(finish_status_); + auto* reactor = reactor_; + auto* call = call_.call(); + this->~ClientCallbackReaderImpl(); + g_core_codegen_interface->grpc_call_unref(call); + reactor->OnDone(s); + } + } + + void StartCall() override { + // This call initiates two batches, plus any backlog, each with a callback + // 1. Send initial metadata (unless corked) + recv initial metadata + // 2. Any backlog + // 3. Recv trailing metadata, on_completion callback + started_ = true; + + start_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnReadInitialMetadataDone(ok); + MaybeFinish(); + }, + &start_ops_); + start_ops_.SendInitialMetadata(&context_->send_initial_metadata_, + context_->initial_metadata_flags()); + start_ops_.RecvInitialMetadata(context_); + start_ops_.set_core_cq_tag(&start_tag_); + call_.PerformOps(&start_ops_); + + // Also set up the read tag so it doesn't have to be set up each time + read_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnReadDone(ok); + MaybeFinish(); + }, + &read_ops_); + read_ops_.set_core_cq_tag(&read_tag_); + if (read_ops_at_start_) { + call_.PerformOps(&read_ops_); + } + + finish_tag_.Set(call_.call(), [this](bool ok) { MaybeFinish(); }, + &finish_ops_); + finish_ops_.ClientRecvStatus(context_, &finish_status_); + finish_ops_.set_core_cq_tag(&finish_tag_); + call_.PerformOps(&finish_ops_); + } + + void Read(Response* msg) override { + read_ops_.RecvMessage(msg); + callbacks_outstanding_++; + if (started_) { + call_.PerformOps(&read_ops_); + } else { + read_ops_at_start_ = true; + } + } + + virtual void AddHold(int holds) override { callbacks_outstanding_ += holds; } + virtual void RemoveHold() override { MaybeFinish(); } + + private: + friend class ClientCallbackReaderFactory; + + template + ClientCallbackReaderImpl( + Call call, ClientContext* context, Request* request, + ::grpc::experimental::ClientReadReactor* reactor) + : context_(context), call_(call), reactor_(reactor) { + this->BindReactor(reactor); + // TODO(vjpai): don't assert + GPR_CODEGEN_ASSERT(start_ops_.SendMessagePtr(request).ok()); + start_ops_.ClientSendClose(); + } + + ClientContext* const context_; + Call call_; + ::grpc::experimental::ClientReadReactor* const reactor_; + + CallOpSet + start_ops_; + CallbackWithSuccessTag start_tag_; + + CallOpSet finish_ops_; + CallbackWithSuccessTag finish_tag_; + Status finish_status_; + + CallOpSet> read_ops_; + CallbackWithSuccessTag read_tag_; + bool read_ops_at_start_{false}; + + // Minimum of 2 callbacks to pre-register for start and finish + std::atomic_int callbacks_outstanding_{2}; + bool started_{false}; +}; + +template +class ClientCallbackReaderFactory { + public: + template + static void Create( + ChannelInterface* channel, const ::grpc::internal::RpcMethod& method, + ClientContext* context, const Request* request, + ::grpc::experimental::ClientReadReactor* reactor) { + Call call = channel->CreateCall(method, context, channel->CallbackCQ()); + + g_core_codegen_interface->grpc_call_ref(call.call()); + new (g_core_codegen_interface->grpc_call_arena_alloc( + call.call(), sizeof(ClientCallbackReaderImpl))) + ClientCallbackReaderImpl(call, context, request, reactor); + } +}; + +template +class ClientCallbackWriterImpl + : public ::grpc::experimental::ClientCallbackWriter { + public: + // always allocated against a call arena, no memory free required + static void operator delete(void* ptr, std::size_t size) { + assert(size == sizeof(ClientCallbackWriterImpl)); + } + + // This operator should never be called as the memory should be freed as part + // of the arena destruction. It only exists to provide a matching operator + // delete to the operator new so that some compilers will not complain (see + // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this + // there are no tests catching the compiler warning. + static void operator delete(void*, void*) { assert(0); } + + void MaybeFinish() { + if (--callbacks_outstanding_ == 0) { + Status s = std::move(finish_status_); + auto* reactor = reactor_; + auto* call = call_.call(); + this->~ClientCallbackWriterImpl(); + g_core_codegen_interface->grpc_call_unref(call); + reactor->OnDone(s); + } + } + + void StartCall() override { + // This call initiates two batches, plus any backlog, each with a callback + // 1. Send initial metadata (unless corked) + recv initial metadata + // 2. Any backlog + // 3. Recv trailing metadata, on_completion callback + started_ = true; + + start_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnReadInitialMetadataDone(ok); + MaybeFinish(); + }, + &start_ops_); + if (!start_corked_) { + start_ops_.SendInitialMetadata(&context_->send_initial_metadata_, + context_->initial_metadata_flags()); + } + start_ops_.RecvInitialMetadata(context_); + start_ops_.set_core_cq_tag(&start_tag_); + call_.PerformOps(&start_ops_); + + // Also set up the read and write tags so that they don't have to be set up + // each time + write_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnWriteDone(ok); + MaybeFinish(); + }, + &write_ops_); + write_ops_.set_core_cq_tag(&write_tag_); + + if (write_ops_at_start_) { + call_.PerformOps(&write_ops_); + } + + if (writes_done_ops_at_start_) { + call_.PerformOps(&writes_done_ops_); + } + + finish_tag_.Set(call_.call(), [this](bool ok) { MaybeFinish(); }, + &finish_ops_); + finish_ops_.ClientRecvStatus(context_, &finish_status_); + finish_ops_.set_core_cq_tag(&finish_tag_); + call_.PerformOps(&finish_ops_); + } + + void Write(const Request* msg, WriteOptions options) override { + if (start_corked_) { + write_ops_.SendInitialMetadata(&context_->send_initial_metadata_, + context_->initial_metadata_flags()); + start_corked_ = false; + } + + if (options.is_last_message()) { + options.set_buffer_hint(); + write_ops_.ClientSendClose(); + } + // TODO(vjpai): don't assert + GPR_CODEGEN_ASSERT(write_ops_.SendMessagePtr(msg, options).ok()); + callbacks_outstanding_++; + if (started_) { + call_.PerformOps(&write_ops_); + } else { + write_ops_at_start_ = true; + } + } + void WritesDone() override { + if (start_corked_) { + writes_done_ops_.SendInitialMetadata(&context_->send_initial_metadata_, + context_->initial_metadata_flags()); + start_corked_ = false; + } + writes_done_ops_.ClientSendClose(); + writes_done_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnWritesDoneDone(ok); + MaybeFinish(); + }, + &writes_done_ops_); + writes_done_ops_.set_core_cq_tag(&writes_done_tag_); + callbacks_outstanding_++; + if (started_) { + call_.PerformOps(&writes_done_ops_); + } else { + writes_done_ops_at_start_ = true; + } + } + + virtual void AddHold(int holds) override { callbacks_outstanding_ += holds; } + virtual void RemoveHold() override { MaybeFinish(); } + + private: + friend class ClientCallbackWriterFactory; + + template + ClientCallbackWriterImpl( + Call call, ClientContext* context, Response* response, + ::grpc::experimental::ClientWriteReactor* reactor) + : context_(context), + call_(call), + reactor_(reactor), + start_corked_(context_->initial_metadata_corked_) { + this->BindReactor(reactor); + finish_ops_.RecvMessage(response); + finish_ops_.AllowNoMessage(); + } + + ClientContext* const context_; + Call call_; + ::grpc::experimental::ClientWriteReactor* const reactor_; + + CallOpSet start_ops_; + CallbackWithSuccessTag start_tag_; + bool start_corked_; + + CallOpSet finish_ops_; + CallbackWithSuccessTag finish_tag_; + Status finish_status_; + + CallOpSet + write_ops_; + CallbackWithSuccessTag write_tag_; + bool write_ops_at_start_{false}; + + CallOpSet writes_done_ops_; + CallbackWithSuccessTag writes_done_tag_; + bool writes_done_ops_at_start_{false}; + + // Minimum of 2 callbacks to pre-register for start and finish + std::atomic_int callbacks_outstanding_{2}; + bool started_{false}; +}; + +template +class ClientCallbackWriterFactory { + public: + template + static void Create( + ChannelInterface* channel, const ::grpc::internal::RpcMethod& method, + ClientContext* context, Response* response, + ::grpc::experimental::ClientWriteReactor* reactor) { + Call call = channel->CreateCall(method, context, channel->CallbackCQ()); + + g_core_codegen_interface->grpc_call_ref(call.call()); + new (g_core_codegen_interface->grpc_call_arena_alloc( + call.call(), sizeof(ClientCallbackWriterImpl))) + ClientCallbackWriterImpl(call, context, response, reactor); + } +}; + +class ClientCallbackUnaryImpl final + : public ::grpc::experimental::ClientCallbackUnary { + public: + // always allocated against a call arena, no memory free required + static void operator delete(void* ptr, std::size_t size) { + assert(size == sizeof(ClientCallbackUnaryImpl)); + } + + // This operator should never be called as the memory should be freed as part + // of the arena destruction. It only exists to provide a matching operator + // delete to the operator new so that some compilers will not complain (see + // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this + // there are no tests catching the compiler warning. + static void operator delete(void*, void*) { assert(0); } + + void StartCall() override { + // This call initiates two batches, each with a callback + // 1. Send initial metadata + write + writes done + recv initial metadata + // 2. Read message, recv trailing metadata + started_ = true; + + start_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnReadInitialMetadataDone(ok); + MaybeFinish(); + }, + &start_ops_); + start_ops_.SendInitialMetadata(&context_->send_initial_metadata_, + context_->initial_metadata_flags()); + start_ops_.RecvInitialMetadata(context_); + start_ops_.set_core_cq_tag(&start_tag_); + call_.PerformOps(&start_ops_); + + finish_tag_.Set(call_.call(), [this](bool ok) { MaybeFinish(); }, + &finish_ops_); + finish_ops_.ClientRecvStatus(context_, &finish_status_); + finish_ops_.set_core_cq_tag(&finish_tag_); + call_.PerformOps(&finish_ops_); + } + + void MaybeFinish() { + if (--callbacks_outstanding_ == 0) { + Status s = std::move(finish_status_); + auto* reactor = reactor_; + auto* call = call_.call(); + this->~ClientCallbackUnaryImpl(); + g_core_codegen_interface->grpc_call_unref(call); + reactor->OnDone(s); + } + } + + private: + friend class ClientCallbackUnaryFactory; + + template + ClientCallbackUnaryImpl(Call call, ClientContext* context, Request* request, + Response* response, + ::grpc::experimental::ClientUnaryReactor* reactor) + : context_(context), call_(call), reactor_(reactor) { + this->BindReactor(reactor); + // TODO(vjpai): don't assert + GPR_CODEGEN_ASSERT(start_ops_.SendMessagePtr(request).ok()); + start_ops_.ClientSendClose(); + finish_ops_.RecvMessage(response); + finish_ops_.AllowNoMessage(); + } + + ClientContext* const context_; + Call call_; + ::grpc::experimental::ClientUnaryReactor* const reactor_; + + CallOpSet + start_ops_; + CallbackWithSuccessTag start_tag_; + + CallOpSet finish_ops_; + CallbackWithSuccessTag finish_tag_; + Status finish_status_; + + // This call will have 2 callbacks: start and finish + std::atomic_int callbacks_outstanding_{2}; + bool started_{false}; +}; + +class ClientCallbackUnaryFactory { + public: + template + static void Create(ChannelInterface* channel, + const ::grpc::internal::RpcMethod& method, + ClientContext* context, const Request* request, + Response* response, + ::grpc::experimental::ClientUnaryReactor* reactor) { + Call call = channel->CreateCall(method, context, channel->CallbackCQ()); + + g_core_codegen_interface->grpc_call_ref(call.call()); + + new (g_core_codegen_interface->grpc_call_arena_alloc( + call.call(), sizeof(ClientCallbackUnaryImpl))) + ClientCallbackUnaryImpl(call, context, request, response, reactor); + } +}; } // namespace internal } // namespace grpc diff --git a/include/grpcpp/impl/codegen/client_context.h b/include/grpcpp/impl/codegen/client_context.h index 75b955e7606..999d8fcbfe7 100644 --- a/include/grpcpp/impl/codegen/client_context.h +++ b/include/grpcpp/impl/codegen/client_context.h @@ -46,21 +46,26 @@ #include #include #include +#include #include #include #include #include +#include #include struct census_context; struct grpc_call; +namespace grpc_impl { + +class CallCredentials; +class Channel; +class CompletionQueue; +} // namespace grpc_impl namespace grpc { -class Channel; class ChannelInterface; -class CompletionQueue; -class CallCredentials; class ClientContext; namespace internal { @@ -71,6 +76,13 @@ template class BlockingUnaryCallImpl; template class CallbackUnaryCallImpl; +template +class ClientCallbackReaderWriterImpl; +template +class ClientCallbackReaderImpl; +template +class ClientCallbackWriterImpl; +class ClientCallbackUnaryImpl; } // namespace internal template @@ -162,6 +174,8 @@ class InteropClientContextInspector; /// (see \a grpc::CreateCustomChannel). /// /// \warning ClientContext instances should \em not be reused across rpcs. +/// \warning The ClientContext instance used for creating an rpc must remain +/// alive and valid for the lifetime of the rpc. class ClientContext { public: ClientContext(); @@ -191,6 +205,13 @@ class ClientContext { /// end in "-bin". /// \param meta_value The metadata value. If its value is binary, the key name /// must end in "-bin". + /// + /// Metadata must conform to the following format: + /// Custom-Metadata -> Binary-Header / ASCII-Header + /// Binary-Header -> {Header-Name "-bin" } {binary value} + /// ASCII-Header -> Header-Name ASCII-Value + /// Header-Name -> 1*( %x30-39 / %x61-7A / "_" / "-" / ".") ; 0-9 a-z _ - . + /// ASCII-Value -> 1*( %x20-%x7E ) ; space and printable ASCII void AddMetadata(const grpc::string& meta_key, const grpc::string& meta_value); @@ -288,7 +309,8 @@ class ClientContext { /// call. /// /// \see https://grpc.io/docs/guides/auth.html - void set_credentials(const std::shared_ptr& creds) { + void set_credentials( + const std::shared_ptr& creds) { creds_ = creds; } @@ -375,7 +397,7 @@ class ClientContext { friend class ::grpc::testing::InteropClientContextInspector; friend class ::grpc::internal::CallOpClientRecvStatus; friend class ::grpc::internal::CallOpRecvInitialMetadata; - friend class Channel; + friend class ::grpc_impl::Channel; template friend class ::grpc::ClientReader; template @@ -394,6 +416,13 @@ class ClientContext { friend class ::grpc::internal::BlockingUnaryCallImpl; template friend class ::grpc::internal::CallbackUnaryCallImpl; + template + friend class ::grpc::internal::ClientCallbackReaderWriterImpl; + template + friend class ::grpc::internal::ClientCallbackReaderImpl; + template + friend class ::grpc::internal::ClientCallbackWriterImpl; + friend class ::grpc::internal::ClientCallbackUnaryImpl; // Used by friend class CallOpClientRecvStatus void set_debug_error_string(const grpc::string& debug_error_string) { @@ -401,15 +430,17 @@ class ClientContext { } grpc_call* call() const { return call_; } - void set_call(grpc_call* call, const std::shared_ptr& channel); + void set_call(grpc_call* call, + const std::shared_ptr<::grpc_impl::Channel>& channel); experimental::ClientRpcInfo* set_client_rpc_info( - const char* method, grpc::ChannelInterface* channel, + const char* method, internal::RpcMethod::RpcType type, + grpc::ChannelInterface* channel, const std::vector< std::unique_ptr>& creators, size_t interceptor_pos) { - rpc_info_ = experimental::ClientRpcInfo(this, method, channel); + rpc_info_ = experimental::ClientRpcInfo(this, type, method, channel); rpc_info_.RegisterInterceptors(creators, interceptor_pos); return &rpc_info_; } @@ -433,13 +464,13 @@ class ClientContext { bool wait_for_ready_explicitly_set_; bool idempotent_; bool cacheable_; - std::shared_ptr channel_; - std::mutex mu_; + std::shared_ptr<::grpc_impl::Channel> channel_; + grpc::internal::Mutex mu_; grpc_call* call_; bool call_canceled_; gpr_timespec deadline_; grpc::string authority_; - std::shared_ptr creds_; + std::shared_ptr creds_; mutable std::shared_ptr auth_context_; struct census_context* census_context_; std::multimap send_initial_metadata_; diff --git a/include/grpcpp/impl/codegen/client_interceptor.h b/include/grpcpp/impl/codegen/client_interceptor.h index f69c99ab229..a4c85a76da5 100644 --- a/include/grpcpp/impl/codegen/client_interceptor.h +++ b/include/grpcpp/impl/codegen/client_interceptor.h @@ -23,12 +23,17 @@ #include #include +#include #include +namespace grpc_impl { + +class Channel; +} + namespace grpc { class ClientContext; -class Channel; namespace internal { class InterceptorBatchMethodsImpl; @@ -37,9 +42,17 @@ class InterceptorBatchMethodsImpl; namespace experimental { class ClientRpcInfo; +// A factory interface for creation of client interceptors. A vector of +// factories can be provided at channel creation which will be used to create a +// new vector of client interceptors per RPC. Client interceptor authors should +// create a subclass of ClientInterceptorFactorInterface which creates objects +// of their interceptors. class ClientInterceptorFactoryInterface { public: virtual ~ClientInterceptorFactoryInterface() {} + // Returns a pointer to an Interceptor object on successful creation, nullptr + // otherwise. If nullptr is returned, this server interceptor factory is + // ignored for the purposes of that RPC. virtual Interceptor* CreateClientInterceptor(ClientRpcInfo* info) = 0; }; } // namespace experimental @@ -49,26 +62,74 @@ extern experimental::ClientInterceptorFactoryInterface* g_global_client_interceptor_factory; } +/// ClientRpcInfo represents the state of a particular RPC as it +/// appears to an interceptor. It is created and owned by the library and +/// passed to the CreateClientInterceptor method of the application's +/// ClientInterceptorFactoryInterface implementation namespace experimental { class ClientRpcInfo { public: - ClientRpcInfo() {} + // TODO(yashykt): Stop default-constructing ClientRpcInfo and remove UNKNOWN + // from the list of possible Types. + /// Type categorizes RPCs by unary or streaming type + enum class Type { + UNARY, + CLIENT_STREAMING, + SERVER_STREAMING, + BIDI_STREAMING, + UNKNOWN // UNKNOWN is not API and will be removed later + }; - ~ClientRpcInfo(){}; + ~ClientRpcInfo() {} + // Delete copy constructor but allow default move constructor ClientRpcInfo(const ClientRpcInfo&) = delete; ClientRpcInfo(ClientRpcInfo&&) = default; - ClientRpcInfo& operator=(ClientRpcInfo&&) = default; // Getter methods - const char* method() { return method_; } + + /// Return the fully-specified method name + const char* method() const { return method_; } + + /// Return a pointer to the channel on which the RPC is being sent ChannelInterface* channel() { return channel_; } + + /// Return a pointer to the underlying ClientContext structure associated + /// with the RPC to support features that apply to it grpc::ClientContext* client_context() { return ctx_; } + /// Return the type of the RPC (unary or a streaming flavor) + Type type() const { return type_; } + private: - ClientRpcInfo(grpc::ClientContext* ctx, const char* method, - grpc::ChannelInterface* channel) - : ctx_(ctx), method_(method), channel_(channel) {} + static_assert(Type::UNARY == + static_cast(internal::RpcMethod::NORMAL_RPC), + "violated expectation about Type enum"); + static_assert(Type::CLIENT_STREAMING == + static_cast(internal::RpcMethod::CLIENT_STREAMING), + "violated expectation about Type enum"); + static_assert(Type::SERVER_STREAMING == + static_cast(internal::RpcMethod::SERVER_STREAMING), + "violated expectation about Type enum"); + static_assert(Type::BIDI_STREAMING == + static_cast(internal::RpcMethod::BIDI_STREAMING), + "violated expectation about Type enum"); + + // Default constructor should only be used by ClientContext + ClientRpcInfo() = default; + + // Constructor will only be called from ClientContext + ClientRpcInfo(grpc::ClientContext* ctx, internal::RpcMethod::RpcType type, + const char* method, grpc::ChannelInterface* channel) + : ctx_(ctx), + type_(static_cast(type)), + method_(method), + channel_(channel) {} + + // Move assignment should only be used by ClientContext + // TODO(yashykt): Delete move assignment + ClientRpcInfo& operator=(ClientRpcInfo&&) = default; + // Runs interceptor at pos \a pos. void RunInterceptor( experimental::InterceptorBatchMethods* interceptor_methods, size_t pos) { @@ -86,8 +147,11 @@ class ClientRpcInfo { } for (auto it = creators.begin() + interceptor_pos; it != creators.end(); ++it) { - interceptors_.push_back(std::unique_ptr( - (*it)->CreateClientInterceptor(this))); + auto* interceptor = (*it)->CreateClientInterceptor(this); + if (interceptor != nullptr) { + interceptors_.push_back( + std::unique_ptr(interceptor)); + } } if (internal::g_global_client_interceptor_factory != nullptr) { interceptors_.push_back(std::unique_ptr( @@ -97,6 +161,8 @@ class ClientRpcInfo { } grpc::ClientContext* ctx_ = nullptr; + // TODO(yashykt): make type_ const once move-assignment is deleted + Type type_{Type::UNKNOWN}; const char* method_ = nullptr; grpc::ChannelInterface* channel_ = nullptr; std::vector> interceptors_; @@ -110,17 +176,16 @@ class ClientRpcInfo { // PLEASE DO NOT USE THIS. ALWAYS PREFER PER CHANNEL INTERCEPTORS OVER A GLOBAL // INTERCEPTOR. IF USAGE IS ABSOLUTELY NECESSARY, PLEASE READ THE SAFETY NOTES. // Registers a global client interceptor factory object, which is used for all -// RPCs made in this process. If the argument is nullptr, the global -// interceptor factory is deregistered. The application is responsible for -// maintaining the life of the object while gRPC operations are in progress. It -// is unsafe to try to register/deregister if any gRPC operation is in progress. -// For safety, it is in the best interests of the developer to register the -// global interceptor factory once at the start of the process before any gRPC -// operations have begun. Deregistration is optional since gRPC does not -// maintain any references to the object. +// RPCs made in this process. The application is responsible for maintaining the +// life of the object while gRPC operations are in progress. The global +// interceptor factory should only be registered once at the start of the +// process before any gRPC operations have begun. void RegisterGlobalClientInterceptorFactory( ClientInterceptorFactoryInterface* factory); +// For testing purposes only +void TestOnlyResetGlobalClientInterceptorFactory(); + } // namespace experimental } // namespace grpc diff --git a/include/grpcpp/impl/codegen/client_unary_call.h b/include/grpcpp/impl/codegen/client_unary_call.h index b1c80764f23..e0f692b1783 100644 --- a/include/grpcpp/impl/codegen/client_unary_call.h +++ b/include/grpcpp/impl/codegen/client_unary_call.h @@ -27,9 +27,7 @@ namespace grpc { -class Channel; class ClientContext; -class CompletionQueue; namespace internal { class RpcMethod; @@ -57,7 +55,7 @@ class BlockingUnaryCallImpl { CallOpRecvInitialMetadata, CallOpRecvMessage, CallOpClientSendClose, CallOpClientRecvStatus> ops; - status_ = ops.SendMessage(request); + status_ = ops.SendMessagePtr(&request); if (!status_.ok()) { return; } @@ -69,13 +67,17 @@ class BlockingUnaryCallImpl { ops.ClientSendClose(); ops.ClientRecvStatus(context, &status_); call.PerformOps(&ops); - if (cq.Pluck(&ops)) { - if (!ops.got_message && status_.ok()) { - status_ = Status(StatusCode::UNIMPLEMENTED, - "No message returned for unary request"); - } - } else { - GPR_CODEGEN_ASSERT(!status_.ok()); + cq.Pluck(&ops); + // Some of the ops might fail. If the ops fail in the core layer, status + // would reflect the error. But, if the ops fail in the C++ layer, the + // status would still be the same as the one returned by gRPC Core. This can + // happen if deserialization of the message fails. + // TODO(yashykt): If deserialization fails, but the status received is OK, + // then it might be a good idea to change the status to something better + // than StatusCode::UNIMPLEMENTED to reflect this. + if (!ops.got_message && status_.ok()) { + status_ = Status(StatusCode::UNIMPLEMENTED, + "No message returned for unary request"); } } Status status() { return status_; } diff --git a/include/grpcpp/impl/codegen/completion_queue.h b/include/grpcpp/impl/codegen/completion_queue.h index d603c7c7009..f67a3780979 100644 --- a/include/grpcpp/impl/codegen/completion_queue.h +++ b/include/grpcpp/impl/codegen/completion_queue.h @@ -16,388 +16,15 @@ * */ -/// A completion queue implements a concurrent producer-consumer queue, with -/// two main API-exposed methods: \a Next and \a AsyncNext. These -/// methods are the essential component of the gRPC C++ asynchronous API. -/// There is also a \a Shutdown method to indicate that a given completion queue -/// will no longer have regular events. This must be called before the -/// completion queue is destroyed. -/// All completion queue APIs are thread-safe and may be used concurrently with -/// any other completion queue API invocation; it is acceptable to have -/// multiple threads calling \a Next or \a AsyncNext on the same or different -/// completion queues, or to call these methods concurrently with a \a Shutdown -/// elsewhere. -/// \remark{All other API calls on completion queue should be completed before -/// a completion queue destructor is called.} #ifndef GRPCPP_IMPL_CODEGEN_COMPLETION_QUEUE_H #define GRPCPP_IMPL_CODEGEN_COMPLETION_QUEUE_H -#include -#include -#include -#include -#include -#include - -struct grpc_completion_queue; +#include namespace grpc { -template -class ClientReader; -template -class ClientWriter; -template -class ClientReaderWriter; -template -class ServerReader; -template -class ServerWriter; -namespace internal { -template -class ServerReaderWriterBody; -} // namespace internal - -class Channel; -class ChannelInterface; -class ClientContext; -class CompletionQueue; -class Server; -class ServerBuilder; -class ServerContext; -class ServerInterface; - -namespace internal { -class CompletionQueueTag; -class RpcMethod; -template -class RpcMethodHandler; -template -class ClientStreamingHandler; -template -class ServerStreamingHandler; -template -class BidiStreamingHandler; -template -class TemplatedBidiStreamingHandler; -template -class ErrorMethodHandler; -template -class BlockingUnaryCallImpl; -} // namespace internal - -extern CoreCodegenInterface* g_core_codegen_interface; - -/// A thin wrapper around \ref grpc_completion_queue (see \ref -/// src/core/lib/surface/completion_queue.h). -/// See \ref doc/cpp/perf_notes.md for notes on best practices for high -/// performance servers. -class CompletionQueue : private GrpcLibraryCodegen { - public: - /// Default constructor. Implicitly creates a \a grpc_completion_queue - /// instance. - CompletionQueue() - : CompletionQueue(grpc_completion_queue_attributes{ - GRPC_CQ_CURRENT_VERSION, GRPC_CQ_NEXT, GRPC_CQ_DEFAULT_POLLING, - nullptr}) {} - - /// Wrap \a take, taking ownership of the instance. - /// - /// \param take The completion queue instance to wrap. Ownership is taken. - explicit CompletionQueue(grpc_completion_queue* take); - - /// Destructor. Destroys the owned wrapped completion queue / instance. - ~CompletionQueue() { - g_core_codegen_interface->grpc_completion_queue_destroy(cq_); - } - - /// Tri-state return for AsyncNext: SHUTDOWN, GOT_EVENT, TIMEOUT. - enum NextStatus { - SHUTDOWN, ///< The completion queue has been shutdown and fully-drained - GOT_EVENT, ///< Got a new event; \a tag will be filled in with its - ///< associated value; \a ok indicating its success. - TIMEOUT ///< deadline was reached. - }; - - /// Read from the queue, blocking until an event is available or the queue is - /// shutting down. - /// - /// \param tag [out] Updated to point to the read event's tag. - /// \param ok [out] true if read a successful event, false otherwise. - /// - /// Note that each tag sent to the completion queue (through RPC operations - /// or alarms) will be delivered out of the completion queue by a call to - /// Next (or a related method), regardless of whether the operation succeeded - /// or not. Success here means that this operation completed in the normal - /// valid manner. - /// - /// Server-side RPC request: \a ok indicates that the RPC has indeed - /// been started. If it is false, the server has been Shutdown - /// before this particular call got matched to an incoming RPC. - /// - /// Client-side StartCall/RPC invocation: \a ok indicates that the RPC is - /// going to go to the wire. If it is false, it not going to the wire. This - /// would happen if the channel is either permanently broken or - /// transiently broken but with the fail-fast option. (Note that async unary - /// RPCs don't post a CQ tag at this point, nor do client-streaming - /// or bidi-streaming RPCs that have the initial metadata corked option set.) - /// - /// Client-side Write, Client-side WritesDone, Server-side Write, - /// Server-side Finish, Server-side SendInitialMetadata (which is - /// typically included in Write or Finish when not done explicitly): - /// \a ok means that the data/metadata/status/etc is going to go to the - /// wire. If it is false, it not going to the wire because the call - /// is already dead (i.e., canceled, deadline expired, other side - /// dropped the channel, etc). - /// - /// Client-side Read, Server-side Read, Client-side - /// RecvInitialMetadata (which is typically included in Read if not - /// done explicitly): \a ok indicates whether there is a valid message - /// that got read. If not, you know that there are certainly no more - /// messages that can ever be read from this stream. For the client-side - /// operations, this only happens because the call is dead. For the - /// server-sider operation, though, this could happen because the client - /// has done a WritesDone already. - /// - /// Client-side Finish: \a ok should always be true - /// - /// Server-side AsyncNotifyWhenDone: \a ok should always be true - /// - /// Alarm: \a ok is true if it expired, false if it was canceled - /// - /// \return true if got an event, false if the queue is fully drained and - /// shut down. - bool Next(void** tag, bool* ok) { - return (AsyncNextInternal(tag, ok, - g_core_codegen_interface->gpr_inf_future( - GPR_CLOCK_REALTIME)) != SHUTDOWN); - } - - /// Read from the queue, blocking up to \a deadline (or the queue's shutdown). - /// Both \a tag and \a ok are updated upon success (if an event is available - /// within the \a deadline). A \a tag points to an arbitrary location usually - /// employed to uniquely identify an event. - /// - /// \param tag [out] Upon sucess, updated to point to the event's tag. - /// \param ok [out] Upon sucess, true if a successful event, false otherwise - /// See documentation for CompletionQueue::Next for explanation of ok - /// \param deadline [in] How long to block in wait for an event. - /// - /// \return The type of event read. - template - NextStatus AsyncNext(void** tag, bool* ok, const T& deadline) { - TimePoint deadline_tp(deadline); - return AsyncNextInternal(tag, ok, deadline_tp.raw_time()); - } - - /// EXPERIMENTAL - /// First executes \a F, then reads from the queue, blocking up to - /// \a deadline (or the queue's shutdown). - /// Both \a tag and \a ok are updated upon success (if an event is available - /// within the \a deadline). A \a tag points to an arbitrary location usually - /// employed to uniquely identify an event. - /// - /// \param f [in] Function to execute before calling AsyncNext on this queue. - /// \param tag [out] Upon sucess, updated to point to the event's tag. - /// \param ok [out] Upon sucess, true if read a regular event, false - /// otherwise. - /// \param deadline [in] How long to block in wait for an event. - /// - /// \return The type of event read. - template - NextStatus DoThenAsyncNext(F&& f, void** tag, bool* ok, const T& deadline) { - CompletionQueueTLSCache cache = CompletionQueueTLSCache(this); - f(); - if (cache.Flush(tag, ok)) { - return GOT_EVENT; - } else { - return AsyncNext(tag, ok, deadline); - } - } - - /// Request the shutdown of the queue. - /// - /// \warning This method must be called at some point if this completion queue - /// is accessed with Next or AsyncNext. \a Next will not return false - /// until this method has been called and all pending tags have been drained. - /// (Likewise for \a AsyncNext returning \a NextStatus::SHUTDOWN .) - /// Only once either one of these methods does that (that is, once the queue - /// has been \em drained) can an instance of this class be destroyed. - /// Also note that applications must ensure that no work is enqueued on this - /// completion queue after this method is called. - void Shutdown(); - - /// Returns a \em raw pointer to the underlying \a grpc_completion_queue - /// instance. - /// - /// \warning Remember that the returned instance is owned. No transfer of - /// owership is performed. - grpc_completion_queue* cq() { return cq_; } - - protected: - /// Private constructor of CompletionQueue only visible to friend classes - CompletionQueue(const grpc_completion_queue_attributes& attributes) { - cq_ = g_core_codegen_interface->grpc_completion_queue_create( - g_core_codegen_interface->grpc_completion_queue_factory_lookup( - &attributes), - &attributes, NULL); - InitialAvalanching(); // reserve this for the future shutdown - } - - private: - // Friend synchronous wrappers so that they can access Pluck(), which is - // a semi-private API geared towards the synchronous implementation. - template - friend class ::grpc::ClientReader; - template - friend class ::grpc::ClientWriter; - template - friend class ::grpc::ClientReaderWriter; - template - friend class ::grpc::ServerReader; - template - friend class ::grpc::ServerWriter; - template - friend class ::grpc::internal::ServerReaderWriterBody; - template - friend class ::grpc::internal::RpcMethodHandler; - template - friend class ::grpc::internal::ClientStreamingHandler; - template - friend class ::grpc::internal::ServerStreamingHandler; - template - friend class ::grpc::internal::TemplatedBidiStreamingHandler; - template - friend class ::grpc::internal::ErrorMethodHandler; - friend class ::grpc::Server; - friend class ::grpc::ServerContext; - friend class ::grpc::ServerInterface; - template - friend class ::grpc::internal::BlockingUnaryCallImpl; - - // Friends that need access to constructor for callback CQ - friend class ::grpc::Channel; - - /// EXPERIMENTAL - /// Creates a Thread Local cache to store the first event - /// On this completion queue queued from this thread. Once - /// initialized, it must be flushed on the same thread. - class CompletionQueueTLSCache { - public: - CompletionQueueTLSCache(CompletionQueue* cq); - ~CompletionQueueTLSCache(); - bool Flush(void** tag, bool* ok); - - private: - CompletionQueue* cq_; - bool flushed_; - }; - - NextStatus AsyncNextInternal(void** tag, bool* ok, gpr_timespec deadline); - - /// Wraps \a grpc_completion_queue_pluck. - /// \warning Must not be mixed with calls to \a Next. - bool Pluck(internal::CompletionQueueTag* tag) { - auto deadline = - g_core_codegen_interface->gpr_inf_future(GPR_CLOCK_REALTIME); - while (true) { - auto ev = g_core_codegen_interface->grpc_completion_queue_pluck( - cq_, tag, deadline, nullptr); - bool ok = ev.success != 0; - void* ignored = tag; - if (tag->FinalizeResult(&ignored, &ok)) { - GPR_CODEGEN_ASSERT(ignored == tag); - // Ignore mutations by FinalizeResult: Pluck returns the C API status - return ev.success != 0; - } - } - } - - /// Performs a single polling pluck on \a tag. - /// \warning Must not be mixed with calls to \a Next. - /// - /// TODO: sreek - This calls tag->FinalizeResult() even if the cq_ is already - /// shutdown. This is most likely a bug and if it is a bug, then change this - /// implementation to simple call the other TryPluck function with a zero - /// timeout. i.e: - /// TryPluck(tag, gpr_time_0(GPR_CLOCK_REALTIME)) - void TryPluck(internal::CompletionQueueTag* tag) { - auto deadline = g_core_codegen_interface->gpr_time_0(GPR_CLOCK_REALTIME); - auto ev = g_core_codegen_interface->grpc_completion_queue_pluck( - cq_, tag, deadline, nullptr); - if (ev.type == GRPC_QUEUE_TIMEOUT) return; - bool ok = ev.success != 0; - void* ignored = tag; - // the tag must be swallowed if using TryPluck - GPR_CODEGEN_ASSERT(!tag->FinalizeResult(&ignored, &ok)); - } - - /// Performs a single polling pluck on \a tag. Calls tag->FinalizeResult if - /// the pluck() was successful and returned the tag. - /// - /// This exects tag->FinalizeResult (if called) to return 'false' i.e expects - /// that the tag is internal not something that is returned to the user. - void TryPluck(internal::CompletionQueueTag* tag, gpr_timespec deadline) { - auto ev = g_core_codegen_interface->grpc_completion_queue_pluck( - cq_, tag, deadline, nullptr); - if (ev.type == GRPC_QUEUE_TIMEOUT || ev.type == GRPC_QUEUE_SHUTDOWN) { - return; - } - - bool ok = ev.success != 0; - void* ignored = tag; - GPR_CODEGEN_ASSERT(!tag->FinalizeResult(&ignored, &ok)); - } - - /// Manage state of avalanching operations : completion queue tags that - /// trigger other completion queue operations. The underlying core completion - /// queue should not really shutdown until all avalanching operations have - /// been finalized. Note that we maintain the requirement that an avalanche - /// registration must take place before CQ shutdown (which must be maintained - /// elsehwere) - void InitialAvalanching() { - gpr_atm_rel_store(&avalanches_in_flight_, static_cast(1)); - } - void RegisterAvalanching() { - gpr_atm_no_barrier_fetch_add(&avalanches_in_flight_, - static_cast(1)); - } - void CompleteAvalanching(); - - grpc_completion_queue* cq_; // owned - - gpr_atm avalanches_in_flight_; -}; - -/// A specific type of completion queue used by the processing of notifications -/// by servers. Instantiated by \a ServerBuilder. -class ServerCompletionQueue : public CompletionQueue { - public: - bool IsFrequentlyPolled() { return polling_type_ != GRPC_CQ_NON_LISTENING; } - - protected: - /// Default constructor - ServerCompletionQueue() : polling_type_(GRPC_CQ_DEFAULT_POLLING) {} - - private: - /// \param completion_type indicates whether this is a NEXT or CALLBACK - /// completion queue. - /// \param polling_type Informs the GRPC library about the type of polling - /// allowed on this completion queue. See grpc_cq_polling_type's description - /// in grpc_types.h for more details. - /// \param shutdown_cb is the shutdown callback used for CALLBACK api queues - ServerCompletionQueue(grpc_cq_completion_type completion_type, - grpc_cq_polling_type polling_type, - grpc_experimental_completion_queue_functor* shutdown_cb) - : CompletionQueue(grpc_completion_queue_attributes{ - GRPC_CQ_CURRENT_VERSION, completion_type, polling_type, - shutdown_cb}), - polling_type_(polling_type) {} - - grpc_cq_polling_type polling_type_; - friend class ServerBuilder; - friend class Server; -}; +typedef ::grpc_impl::CompletionQueue CompletionQueue; +typedef ::grpc_impl::ServerCompletionQueue ServerCompletionQueue; } // namespace grpc diff --git a/include/grpcpp/impl/codegen/completion_queue_impl.h b/include/grpcpp/impl/codegen/completion_queue_impl.h new file mode 100644 index 00000000000..5435f2fa165 --- /dev/null +++ b/include/grpcpp/impl/codegen/completion_queue_impl.h @@ -0,0 +1,422 @@ +/* + * + * 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. + * + */ + +/// A completion queue implements a concurrent producer-consumer queue, with +/// two main API-exposed methods: \a Next and \a AsyncNext. These +/// methods are the essential component of the gRPC C++ asynchronous API. +/// There is also a \a Shutdown method to indicate that a given completion queue +/// will no longer have regular events. This must be called before the +/// completion queue is destroyed. +/// All completion queue APIs are thread-safe and may be used concurrently with +/// any other completion queue API invocation; it is acceptable to have +/// multiple threads calling \a Next or \a AsyncNext on the same or different +/// completion queues, or to call these methods concurrently with a \a Shutdown +/// elsewhere. +/// \remark{All other API calls on completion queue should be completed before +/// a completion queue destructor is called.} +#ifndef GRPCPP_IMPL_CODEGEN_COMPLETION_QUEUE_IMPL_H +#define GRPCPP_IMPL_CODEGEN_COMPLETION_QUEUE_IMPL_H + +#include +#include +#include +#include +#include +#include + +struct grpc_completion_queue; + +namespace grpc_impl { + +class Channel; +class Server; +class ServerBuilder; +} // namespace grpc_impl +namespace grpc { + +template +class ClientReader; +template +class ClientWriter; +template +class ClientReaderWriter; +template +class ServerReader; +template +class ServerWriter; +namespace internal { +template +class ServerReaderWriterBody; +} // namespace internal + +class ChannelInterface; +class ClientContext; +class ServerContext; +class ServerInterface; + +namespace internal { +class CompletionQueueTag; +class RpcMethod; +template +class RpcMethodHandler; +template +class ClientStreamingHandler; +template +class ServerStreamingHandler; +template +class BidiStreamingHandler; +template +class TemplatedBidiStreamingHandler; +template +class ErrorMethodHandler; +template +class BlockingUnaryCallImpl; +template +class CallOpSet; +} // namespace internal + +extern CoreCodegenInterface* g_core_codegen_interface; + +} // namespace grpc + +namespace grpc_impl { + +/// A thin wrapper around \ref grpc_completion_queue (see \ref +/// src/core/lib/surface/completion_queue.h). +/// See \ref doc/cpp/perf_notes.md for notes on best practices for high +/// performance servers. +class CompletionQueue : private ::grpc::GrpcLibraryCodegen { + public: + /// Default constructor. Implicitly creates a \a grpc_completion_queue + /// instance. + CompletionQueue() + : CompletionQueue(grpc_completion_queue_attributes{ + GRPC_CQ_CURRENT_VERSION, GRPC_CQ_NEXT, GRPC_CQ_DEFAULT_POLLING, + nullptr}) {} + + /// Wrap \a take, taking ownership of the instance. + /// + /// \param take The completion queue instance to wrap. Ownership is taken. + explicit CompletionQueue(grpc_completion_queue* take); + + /// Destructor. Destroys the owned wrapped completion queue / instance. + ~CompletionQueue() { + ::grpc::g_core_codegen_interface->grpc_completion_queue_destroy(cq_); + } + + /// Tri-state return for AsyncNext: SHUTDOWN, GOT_EVENT, TIMEOUT. + enum NextStatus { + SHUTDOWN, ///< The completion queue has been shutdown and fully-drained + GOT_EVENT, ///< Got a new event; \a tag will be filled in with its + ///< associated value; \a ok indicating its success. + TIMEOUT ///< deadline was reached. + }; + + /// Read from the queue, blocking until an event is available or the queue is + /// shutting down. + /// + /// \param tag [out] Updated to point to the read event's tag. + /// \param ok [out] true if read a successful event, false otherwise. + /// + /// Note that each tag sent to the completion queue (through RPC operations + /// or alarms) will be delivered out of the completion queue by a call to + /// Next (or a related method), regardless of whether the operation succeeded + /// or not. Success here means that this operation completed in the normal + /// valid manner. + /// + /// Server-side RPC request: \a ok indicates that the RPC has indeed + /// been started. If it is false, the server has been Shutdown + /// before this particular call got matched to an incoming RPC. + /// + /// Client-side StartCall/RPC invocation: \a ok indicates that the RPC is + /// going to go to the wire. If it is false, it not going to the wire. This + /// would happen if the channel is either permanently broken or + /// transiently broken but with the fail-fast option. (Note that async unary + /// RPCs don't post a CQ tag at this point, nor do client-streaming + /// or bidi-streaming RPCs that have the initial metadata corked option set.) + /// + /// Client-side Write, Client-side WritesDone, Server-side Write, + /// Server-side Finish, Server-side SendInitialMetadata (which is + /// typically included in Write or Finish when not done explicitly): + /// \a ok means that the data/metadata/status/etc is going to go to the + /// wire. If it is false, it not going to the wire because the call + /// is already dead (i.e., canceled, deadline expired, other side + /// dropped the channel, etc). + /// + /// Client-side Read, Server-side Read, Client-side + /// RecvInitialMetadata (which is typically included in Read if not + /// done explicitly): \a ok indicates whether there is a valid message + /// that got read. If not, you know that there are certainly no more + /// messages that can ever be read from this stream. For the client-side + /// operations, this only happens because the call is dead. For the + /// server-sider operation, though, this could happen because the client + /// has done a WritesDone already. + /// + /// Client-side Finish: \a ok should always be true + /// + /// Server-side AsyncNotifyWhenDone: \a ok should always be true + /// + /// Alarm: \a ok is true if it expired, false if it was canceled + /// + /// \return true if got an event, false if the queue is fully drained and + /// shut down. + bool Next(void** tag, bool* ok) { + return (AsyncNextInternal(tag, ok, + ::grpc::g_core_codegen_interface->gpr_inf_future( + GPR_CLOCK_REALTIME)) != SHUTDOWN); + } + + /// Read from the queue, blocking up to \a deadline (or the queue's shutdown). + /// Both \a tag and \a ok are updated upon success (if an event is available + /// within the \a deadline). A \a tag points to an arbitrary location usually + /// employed to uniquely identify an event. + /// + /// \param tag [out] Upon sucess, updated to point to the event's tag. + /// \param ok [out] Upon sucess, true if a successful event, false otherwise + /// See documentation for CompletionQueue::Next for explanation of ok + /// \param deadline [in] How long to block in wait for an event. + /// + /// \return The type of event read. + template + NextStatus AsyncNext(void** tag, bool* ok, const T& deadline) { + ::grpc::TimePoint deadline_tp(deadline); + return AsyncNextInternal(tag, ok, deadline_tp.raw_time()); + } + + /// EXPERIMENTAL + /// First executes \a F, then reads from the queue, blocking up to + /// \a deadline (or the queue's shutdown). + /// Both \a tag and \a ok are updated upon success (if an event is available + /// within the \a deadline). A \a tag points to an arbitrary location usually + /// employed to uniquely identify an event. + /// + /// \param f [in] Function to execute before calling AsyncNext on this queue. + /// \param tag [out] Upon sucess, updated to point to the event's tag. + /// \param ok [out] Upon sucess, true if read a regular event, false + /// otherwise. + /// \param deadline [in] How long to block in wait for an event. + /// + /// \return The type of event read. + template + NextStatus DoThenAsyncNext(F&& f, void** tag, bool* ok, const T& deadline) { + CompletionQueueTLSCache cache = CompletionQueueTLSCache(this); + f(); + if (cache.Flush(tag, ok)) { + return GOT_EVENT; + } else { + return AsyncNext(tag, ok, deadline); + } + } + + /// Request the shutdown of the queue. + /// + /// \warning This method must be called at some point if this completion queue + /// is accessed with Next or AsyncNext. \a Next will not return false + /// until this method has been called and all pending tags have been drained. + /// (Likewise for \a AsyncNext returning \a NextStatus::SHUTDOWN .) + /// Only once either one of these methods does that (that is, once the queue + /// has been \em drained) can an instance of this class be destroyed. + /// Also note that applications must ensure that no work is enqueued on this + /// completion queue after this method is called. + void Shutdown(); + + /// Returns a \em raw pointer to the underlying \a grpc_completion_queue + /// instance. + /// + /// \warning Remember that the returned instance is owned. No transfer of + /// owership is performed. + grpc_completion_queue* cq() { return cq_; } + + protected: + /// Private constructor of CompletionQueue only visible to friend classes + CompletionQueue(const grpc_completion_queue_attributes& attributes) { + cq_ = ::grpc::g_core_codegen_interface->grpc_completion_queue_create( + ::grpc::g_core_codegen_interface->grpc_completion_queue_factory_lookup( + &attributes), + &attributes, NULL); + InitialAvalanching(); // reserve this for the future shutdown + } + + private: + // Friend synchronous wrappers so that they can access Pluck(), which is + // a semi-private API geared towards the synchronous implementation. + template + friend class ::grpc::ClientReader; + template + friend class ::grpc::ClientWriter; + template + friend class ::grpc::ClientReaderWriter; + template + friend class ::grpc::ServerReader; + template + friend class ::grpc::ServerWriter; + template + friend class ::grpc::internal::ServerReaderWriterBody; + template + friend class ::grpc::internal::RpcMethodHandler; + template + friend class ::grpc::internal::ClientStreamingHandler; + template + friend class ::grpc::internal::ServerStreamingHandler; + template + friend class ::grpc::internal::TemplatedBidiStreamingHandler; + template <::grpc::StatusCode code> + friend class ::grpc::internal::ErrorMethodHandler; + friend class ::grpc_impl::Server; + friend class ::grpc::ServerContext; + friend class ::grpc::ServerInterface; + template + friend class ::grpc::internal::BlockingUnaryCallImpl; + + // Friends that need access to constructor for callback CQ + friend class ::grpc_impl::Channel; + + // For access to Register/CompleteAvalanching + template + friend class ::grpc::internal::CallOpSet; + + /// EXPERIMENTAL + /// Creates a Thread Local cache to store the first event + /// On this completion queue queued from this thread. Once + /// initialized, it must be flushed on the same thread. + class CompletionQueueTLSCache { + public: + CompletionQueueTLSCache(CompletionQueue* cq); + ~CompletionQueueTLSCache(); + bool Flush(void** tag, bool* ok); + + private: + CompletionQueue* cq_; + bool flushed_; + }; + + NextStatus AsyncNextInternal(void** tag, bool* ok, gpr_timespec deadline); + + /// Wraps \a grpc_completion_queue_pluck. + /// \warning Must not be mixed with calls to \a Next. + bool Pluck(::grpc::internal::CompletionQueueTag* tag) { + auto deadline = + ::grpc::g_core_codegen_interface->gpr_inf_future(GPR_CLOCK_REALTIME); + while (true) { + auto ev = ::grpc::g_core_codegen_interface->grpc_completion_queue_pluck( + cq_, tag, deadline, nullptr); + bool ok = ev.success != 0; + void* ignored = tag; + if (tag->FinalizeResult(&ignored, &ok)) { + GPR_CODEGEN_ASSERT(ignored == tag); + return ok; + } + } + } + + /// Performs a single polling pluck on \a tag. + /// \warning Must not be mixed with calls to \a Next. + /// + /// TODO: sreek - This calls tag->FinalizeResult() even if the cq_ is already + /// shutdown. This is most likely a bug and if it is a bug, then change this + /// implementation to simple call the other TryPluck function with a zero + /// timeout. i.e: + /// TryPluck(tag, gpr_time_0(GPR_CLOCK_REALTIME)) + void TryPluck(::grpc::internal::CompletionQueueTag* tag) { + auto deadline = + ::grpc::g_core_codegen_interface->gpr_time_0(GPR_CLOCK_REALTIME); + auto ev = ::grpc::g_core_codegen_interface->grpc_completion_queue_pluck( + cq_, tag, deadline, nullptr); + if (ev.type == GRPC_QUEUE_TIMEOUT) return; + bool ok = ev.success != 0; + void* ignored = tag; + // the tag must be swallowed if using TryPluck + GPR_CODEGEN_ASSERT(!tag->FinalizeResult(&ignored, &ok)); + } + + /// Performs a single polling pluck on \a tag. Calls tag->FinalizeResult if + /// the pluck() was successful and returned the tag. + /// + /// This exects tag->FinalizeResult (if called) to return 'false' i.e expects + /// that the tag is internal not something that is returned to the user. + void TryPluck(::grpc::internal::CompletionQueueTag* tag, + gpr_timespec deadline) { + auto ev = ::grpc::g_core_codegen_interface->grpc_completion_queue_pluck( + cq_, tag, deadline, nullptr); + if (ev.type == GRPC_QUEUE_TIMEOUT || ev.type == GRPC_QUEUE_SHUTDOWN) { + return; + } + + bool ok = ev.success != 0; + void* ignored = tag; + GPR_CODEGEN_ASSERT(!tag->FinalizeResult(&ignored, &ok)); + } + + /// Manage state of avalanching operations : completion queue tags that + /// trigger other completion queue operations. The underlying core completion + /// queue should not really shutdown until all avalanching operations have + /// been finalized. Note that we maintain the requirement that an avalanche + /// registration must take place before CQ shutdown (which must be maintained + /// elsehwere) + void InitialAvalanching() { + gpr_atm_rel_store(&avalanches_in_flight_, static_cast(1)); + } + void RegisterAvalanching() { + gpr_atm_no_barrier_fetch_add(&avalanches_in_flight_, + static_cast(1)); + } + void CompleteAvalanching() { + if (gpr_atm_no_barrier_fetch_add(&avalanches_in_flight_, + static_cast(-1)) == 1) { + ::grpc::g_core_codegen_interface->grpc_completion_queue_shutdown(cq_); + } + } + + grpc_completion_queue* cq_; // owned + + gpr_atm avalanches_in_flight_; +}; + +/// A specific type of completion queue used by the processing of notifications +/// by servers. Instantiated by \a ServerBuilder. +class ServerCompletionQueue : public CompletionQueue { + public: + bool IsFrequentlyPolled() { return polling_type_ != GRPC_CQ_NON_LISTENING; } + + protected: + /// Default constructor + ServerCompletionQueue() : polling_type_(GRPC_CQ_DEFAULT_POLLING) {} + + private: + /// \param completion_type indicates whether this is a NEXT or CALLBACK + /// completion queue. + /// \param polling_type Informs the GRPC library about the type of polling + /// allowed on this completion queue. See grpc_cq_polling_type's description + /// in grpc_types.h for more details. + /// \param shutdown_cb is the shutdown callback used for CALLBACK api queues + ServerCompletionQueue(grpc_cq_completion_type completion_type, + grpc_cq_polling_type polling_type, + grpc_experimental_completion_queue_functor* shutdown_cb) + : CompletionQueue(grpc_completion_queue_attributes{ + GRPC_CQ_CURRENT_VERSION, completion_type, polling_type, + shutdown_cb}), + polling_type_(polling_type) {} + + grpc_cq_polling_type polling_type_; + friend class ::grpc_impl::ServerBuilder; + friend class ::grpc_impl::Server; +}; + +} // namespace grpc_impl + +#endif // GRPCPP_IMPL_CODEGEN_COMPLETION_QUEUE_IMPL_H diff --git a/include/grpcpp/impl/codegen/core_codegen.h b/include/grpcpp/impl/codegen/core_codegen.h index 6ef184d01ab..27729e0d5db 100644 --- a/include/grpcpp/impl/codegen/core_codegen.h +++ b/include/grpcpp/impl/codegen/core_codegen.h @@ -42,6 +42,7 @@ class CoreCodegen final : public CoreCodegenInterface { void* reserved) override; grpc_completion_queue* grpc_completion_queue_create_for_pluck( void* reserved) override; + void grpc_completion_queue_shutdown(grpc_completion_queue* cq) override; void grpc_completion_queue_destroy(grpc_completion_queue* cq) override; grpc_event grpc_completion_queue_pluck(grpc_completion_queue* cq, void* tag, gpr_timespec deadline, @@ -84,6 +85,8 @@ class CoreCodegen final : public CoreCodegenInterface { grpc_byte_buffer_reader* reader) override; int grpc_byte_buffer_reader_next(grpc_byte_buffer_reader* reader, grpc_slice* slice) override; + int grpc_byte_buffer_reader_peek(grpc_byte_buffer_reader* reader, + grpc_slice** slice) override; grpc_byte_buffer* grpc_raw_byte_buffer_create(grpc_slice* slice, size_t nslices) override; diff --git a/include/grpcpp/impl/codegen/core_codegen_interface.h b/include/grpcpp/impl/codegen/core_codegen_interface.h index 20a5b3300c4..3792c3d4693 100644 --- a/include/grpcpp/impl/codegen/core_codegen_interface.h +++ b/include/grpcpp/impl/codegen/core_codegen_interface.h @@ -52,6 +52,7 @@ class CoreCodegenInterface { void* reserved) = 0; virtual grpc_completion_queue* grpc_completion_queue_create_for_pluck( void* reserved) = 0; + virtual void grpc_completion_queue_shutdown(grpc_completion_queue* cq) = 0; virtual void grpc_completion_queue_destroy(grpc_completion_queue* cq) = 0; virtual grpc_event grpc_completion_queue_pluck(grpc_completion_queue* cq, void* tag, @@ -91,6 +92,8 @@ class CoreCodegenInterface { grpc_byte_buffer_reader* reader) = 0; virtual int grpc_byte_buffer_reader_next(grpc_byte_buffer_reader* reader, grpc_slice* slice) = 0; + virtual int grpc_byte_buffer_reader_peek(grpc_byte_buffer_reader* reader, + grpc_slice** slice) = 0; virtual grpc_byte_buffer* grpc_raw_byte_buffer_create(grpc_slice* slice, size_t nslices) = 0; diff --git a/include/grpcpp/impl/codegen/intercepted_channel.h b/include/grpcpp/impl/codegen/intercepted_channel.h index 5255a6d1472..cd0fcc06753 100644 --- a/include/grpcpp/impl/codegen/intercepted_channel.h +++ b/include/grpcpp/impl/codegen/intercepted_channel.h @@ -21,6 +21,10 @@ #include +namespace grpc_impl { +class CompletionQueue; +} + namespace grpc { namespace internal { @@ -46,7 +50,7 @@ class InterceptedChannel : public ChannelInterface { : channel_(channel), interceptor_pos_(pos) {} Call CreateCall(const RpcMethod& method, ClientContext* context, - CompletionQueue* cq) override { + ::grpc_impl::CompletionQueue* cq) override { return channel_->CreateCallInternal(method, context, cq, interceptor_pos_); } @@ -58,7 +62,8 @@ class InterceptedChannel : public ChannelInterface { } void NotifyOnStateChangeImpl(grpc_connectivity_state last_observed, - gpr_timespec deadline, CompletionQueue* cq, + gpr_timespec deadline, + ::grpc_impl::CompletionQueue* cq, void* tag) override { return channel_->NotifyOnStateChangeImpl(last_observed, deadline, cq, tag); } @@ -67,7 +72,9 @@ class InterceptedChannel : public ChannelInterface { return channel_->WaitForStateChangeImpl(last_observed, deadline); } - CompletionQueue* CallbackCQ() override { return channel_->CallbackCQ(); } + ::grpc_impl::CompletionQueue* CallbackCQ() override { + return channel_->CallbackCQ(); + } ChannelInterface* channel_; size_t interceptor_pos_; diff --git a/include/grpcpp/impl/codegen/interceptor.h b/include/grpcpp/impl/codegen/interceptor.h index e449e44a23b..b0f57f71196 100644 --- a/include/grpcpp/impl/codegen/interceptor.h +++ b/include/grpcpp/impl/codegen/interceptor.h @@ -31,99 +31,191 @@ class ChannelInterface; class Status; namespace experimental { -class InterceptedMessage { - public: - template - bool Extract(M* msg); // returns false if definitely invalid extraction - template - M* MutableExtract(); - uint64_t length(); // length on wire -}; +/// An enumeration of different possible points at which the \a Intercept +/// method of the \a Interceptor interface may be called. Any given call +/// to \a Intercept will include one or more of these hook points, and +/// each hook point makes certain types of information available to the +/// interceptor. +/// In these enumeration names, PRE_SEND means that an interception has taken +/// place between the time the application provided a certain type of data +/// (e.g., initial metadata, status) and the time that that data goes to the +/// other side. POST_SEND means that the data has been committed for going to +/// the other side (even if it has not yet been received at the other side). +/// PRE_RECV means an interception between the time that a certain +/// operation has been requested and it is available. POST_RECV means that a +/// result is available but has not yet been passed back to the application. +/// A batch of interception points will only contain either PRE or POST hooks +/// but not both types. For example, a batch with PRE_SEND hook points will not +/// contain POST_RECV or POST_SEND ops. Likewise, a batch with POST_* ops can +/// not contain PRE_* ops. enum class InterceptionHookPoints { - /* The first two in this list are for clients and servers */ + /// The first three in this list are for clients and servers PRE_SEND_INITIAL_METADATA, PRE_SEND_MESSAGE, - PRE_SEND_STATUS /* server only */, - PRE_SEND_CLOSE /* client only */, - /* The following three are for hijacked clients only and can only be - registered by the global interceptor */ + POST_SEND_MESSAGE, + PRE_SEND_STATUS, // server only + PRE_SEND_CLOSE, // client only: WritesDone for stream; after write in unary + /// The following three are for hijacked clients only. A batch with PRE_RECV_* + /// hook points will never contain hook points of other types. PRE_RECV_INITIAL_METADATA, PRE_RECV_MESSAGE, PRE_RECV_STATUS, - /* The following two are for all clients and servers */ + /// The following two are for all clients and servers POST_RECV_INITIAL_METADATA, POST_RECV_MESSAGE, - POST_RECV_STATUS /* client only */, - POST_RECV_CLOSE /* server only */, - /* This is a special hook point available to both clients and servers when - TryCancel() is performed. - - No other hook points will be present along with this. - - It is illegal for an interceptor to block/delay this operation. - - ALL interceptors see this hook point irrespective of whether the RPC was - hijacked or not. */ + POST_RECV_STATUS, // client only + POST_RECV_CLOSE, // server only + /// This is a special hook point available to both clients and servers when + /// TryCancel() is performed. + /// - No other hook points will be present along with this. + /// - It is illegal for an interceptor to block/delay this operation. + /// - ALL interceptors see this hook point irrespective of whether the + /// RPC was hijacked or not. PRE_SEND_CANCEL, NUM_INTERCEPTION_HOOKS }; +/// Class that is passed as an argument to the \a Intercept method +/// of the application's \a Interceptor interface implementation. It has five +/// purposes: +/// 1. Indicate which hook points are present at a specific interception +/// 2. Allow an interceptor to inform the library that an RPC should +/// continue to the next stage of its processing (which may be another +/// interceptor or the main path of the library) +/// 3. Allow an interceptor to hijack the processing of the RPC (only for +/// client-side RPCs with PRE_SEND_INITIAL_METADATA) so that it does not +/// proceed with normal processing beyond that stage +/// 4. Access the relevant fields of an RPC at each interception point +/// 5. Set some fields of an RPC at each interception point, when possible class InterceptorBatchMethods { public: - virtual ~InterceptorBatchMethods(){}; - // Queries to check whether the current batch has an interception hook point - // of type \a type + virtual ~InterceptorBatchMethods() {} + /// Determine whether the current batch has an interception hook point + /// of type \a type virtual bool QueryInterceptionHookPoint(InterceptionHookPoints type) = 0; - // Calling this will signal that the interceptor is done intercepting the - // current batch of the RPC. - // Proceed is a no-op if the batch contains PRE_SEND_CANCEL. Simply returning - // from the Intercept method does the job of continuing the RPC in this case. + /// Signal that the interceptor is done intercepting the current batch of the + /// RPC. Every interceptor must either call Proceed or Hijack on each + /// interception. In most cases, only Proceed will be used. Explicit use of + /// Proceed is what enables interceptors to delay the processing of RPCs + /// while they perform other work. + /// Proceed is a no-op if the batch contains PRE_SEND_CANCEL. Simply returning + /// from the Intercept method does the job of continuing the RPC in this case. + /// This is because PRE_SEND_CANCEL is always in a separate batch and is not + /// allowed to be delayed. virtual void Proceed() = 0; - // Calling this indicates that the interceptor has hijacked the RPC (only - // valid if the batch contains send_initial_metadata on the client side) + /// Indicate that the interceptor has hijacked the RPC (only valid if the + /// batch contains send_initial_metadata on the client side). Later + /// interceptors in the interceptor list will not be called. Later batches + /// on the same RPC will go through interception, but only up to the point + /// of the hijacking interceptor. virtual void Hijack() = 0; - // Returns a modifable ByteBuffer holding serialized form of the message to be - // sent - virtual ByteBuffer* GetSendMessage() = 0; + /// Send Message Methods + /// GetSerializedSendMessage and GetSendMessage/ModifySendMessage are the + /// available methods to view and modify the request payload. An interceptor + /// can access the payload in either serialized form or non-serialized form + /// but not both at the same time. + /// gRPC performs serialization in a lazy manner, which means + /// that a call to GetSerializedSendMessage will result in a serialization + /// operation if the payload stored is not in the serialized form already; the + /// non-serialized form will be lost and GetSendMessage will no longer return + /// a valid pointer, and this will remain true for later interceptors too. + /// This can change however if ModifySendMessage is used to replace the + /// current payload. Note that ModifySendMessage requires a new payload + /// message in the non-serialized form. This will overwrite the existing + /// payload irrespective of whether it had been serialized earlier. Also note + /// that gRPC Async API requires early serialization of the payload which + /// means that the payload would be available in the serialized form only + /// unless an interceptor replaces the payload with ModifySendMessage. - // Returns a modifiable multimap of the initial metadata to be sent + /// Returns a modifable ByteBuffer holding the serialized form of the message + /// that is going to be sent. Valid for PRE_SEND_MESSAGE interceptions. + /// A return value of nullptr indicates that this ByteBuffer is not valid. + virtual ByteBuffer* GetSerializedSendMessage() = 0; + + /// Returns a non-modifiable pointer to the non-serialized form of the message + /// to be sent. Valid for PRE_SEND_MESSAGE interceptions. A return value of + /// nullptr indicates that this field is not valid. + virtual const void* GetSendMessage() = 0; + + /// Overwrites the message to be sent with \a message. \a message should be in + /// the non-serialized form expected by the method. Valid for PRE_SEND_MESSAGE + /// interceptions. Note that the interceptor is responsible for maintaining + /// the life of the message till it is serialized or it receives the + /// POST_SEND_MESSAGE interception point, whichever happens earlier. The + /// modifying interceptor may itself force early serialization by calling + /// GetSerializedSendMessage. + virtual void ModifySendMessage(const void* message) = 0; + + /// Checks whether the SEND MESSAGE op succeeded. Valid for POST_SEND_MESSAGE + /// interceptions. + virtual bool GetSendMessageStatus() = 0; + + /// Returns a modifiable multimap of the initial metadata to be sent. Valid + /// for PRE_SEND_INITIAL_METADATA interceptions. A value of nullptr indicates + /// that this field is not valid. virtual std::multimap* GetSendInitialMetadata() = 0; - // Returns the status to be sent + /// Returns the status to be sent. Valid for PRE_SEND_STATUS interceptions. virtual Status GetSendStatus() = 0; - // Modifies the status with \a status + /// Overwrites the status with \a status. Valid for PRE_SEND_STATUS + /// interceptions. virtual void ModifySendStatus(const Status& status) = 0; - // Returns a modifiable multimap of the trailing metadata to be sent + /// Returns a modifiable multimap of the trailing metadata to be sent. Valid + /// for PRE_SEND_STATUS interceptions. A value of nullptr indicates + /// that this field is not valid. virtual std::multimap* GetSendTrailingMetadata() = 0; - // Returns a pointer to the modifiable received message. Note that the message - // is already deserialized + /// Returns a pointer to the modifiable received message. Note that the + /// message is already deserialized but the type is not set; the interceptor + /// should static_cast to the appropriate type before using it. This is valid + /// for POST_RECV_MESSAGE interceptions; nullptr for not valid virtual void* GetRecvMessage() = 0; - // Returns a modifiable multimap of the received initial metadata + /// Returns a modifiable multimap of the received initial metadata. + /// Valid for POST_RECV_INITIAL_METADATA interceptions; nullptr if not valid virtual std::multimap* GetRecvInitialMetadata() = 0; - // Returns a modifiable view of the received status + /// Returns a modifiable view of the received status on POST_RECV_STATUS + /// interceptions; nullptr if not valid. virtual Status* GetRecvStatus() = 0; - // Returns a modifiable multimap of the received trailing metadata + /// Returns a modifiable multimap of the received trailing metadata on + /// POST_RECV_STATUS interceptions; nullptr if not valid virtual std::multimap* GetRecvTrailingMetadata() = 0; - // Gets an intercepted channel. When a call is started on this interceptor, - // only interceptors after the current interceptor are created from the - // factory objects registered with the channel. + /// Gets an intercepted channel. When a call is started on this interceptor, + /// only interceptors after the current interceptor are created from the + /// factory objects registered with the channel. This allows calls to be + /// started from interceptors without infinite regress through the interceptor + /// list. virtual std::unique_ptr GetInterceptedChannel() = 0; + + /// On a hijacked RPC, an interceptor can decide to fail a PRE_RECV_MESSAGE + /// op. This would be a signal to the reader that there will be no more + /// messages, or the stream has failed or been cancelled. + virtual void FailHijackedRecvMessage() = 0; + + /// On a hijacked RPC/ to-be hijacked RPC, this can be called to fail a SEND + /// MESSAGE op + virtual void FailHijackedSendMessage() = 0; }; +/// Interface for an interceptor. Interceptor authors must create a class +/// that derives from this parent class. class Interceptor { public: virtual ~Interceptor() {} + /// The one public method of an Interceptor interface. Override this to + /// trigger the desired actions at the hook points described above. virtual void Intercept(InterceptorBatchMethods* methods) = 0; }; diff --git a/include/grpcpp/impl/codegen/interceptor_common.h b/include/grpcpp/impl/codegen/interceptor_common.h index d0aa23cb0a0..e7290aca838 100644 --- a/include/grpcpp/impl/codegen/interceptor_common.h +++ b/include/grpcpp/impl/codegen/interceptor_common.h @@ -79,7 +79,26 @@ class InterceptorBatchMethodsImpl hooks_[static_cast(type)] = true; } - ByteBuffer* GetSendMessage() override { return send_message_; } + ByteBuffer* GetSerializedSendMessage() override { + GPR_CODEGEN_ASSERT(orig_send_message_ != nullptr); + if (*orig_send_message_ != nullptr) { + GPR_CODEGEN_ASSERT(serializer_(*orig_send_message_).ok()); + *orig_send_message_ = nullptr; + } + return send_message_; + } + + const void* GetSendMessage() override { + GPR_CODEGEN_ASSERT(orig_send_message_ != nullptr); + return *orig_send_message_; + } + + void ModifySendMessage(const void* message) override { + GPR_CODEGEN_ASSERT(orig_send_message_ != nullptr); + *orig_send_message_ = message; + } + + bool GetSendMessageStatus() override { return !*fail_send_message_; } std::multimap* GetSendInitialMetadata() override { return send_initial_metadata_; @@ -110,12 +129,25 @@ class InterceptorBatchMethodsImpl Status* GetRecvStatus() override { return recv_status_; } + void FailHijackedSendMessage() override { + GPR_CODEGEN_ASSERT(hooks_[static_cast( + experimental::InterceptionHookPoints::PRE_SEND_MESSAGE)]); + *fail_send_message_ = true; + } + std::multimap* GetRecvTrailingMetadata() override { return recv_trailing_metadata_->map(); } - void SetSendMessage(ByteBuffer* buf) { send_message_ = buf; } + void SetSendMessage(ByteBuffer* buf, const void** msg, + bool* fail_send_message, + std::function serializer) { + send_message_ = buf; + orig_send_message_ = msg; + fail_send_message_ = fail_send_message; + serializer_ = serializer; + } void SetSendInitialMetadata( std::multimap* metadata) { @@ -134,7 +166,10 @@ class InterceptorBatchMethodsImpl send_trailing_metadata_ = metadata; } - void SetRecvMessage(void* message) { recv_message_ = message; } + void SetRecvMessage(void* message, bool* got_message) { + recv_message_ = message; + got_message_ = got_message; + } void SetRecvInitialMetadata(MetadataMap* map) { recv_initial_metadata_ = map; @@ -157,6 +192,12 @@ class InterceptorBatchMethodsImpl info->channel(), current_interceptor_index_ + 1)); } + void FailHijackedRecvMessage() override { + GPR_CODEGEN_ASSERT(hooks_[static_cast( + experimental::InterceptionHookPoints::PRE_RECV_MESSAGE)]); + *got_message_ = false; + } + // Clears all state void ClearState() { reverse_ = false; @@ -178,10 +219,29 @@ class InterceptorBatchMethodsImpl // Alternatively, RunInterceptors(std::function f) can be used. void SetCallOpSetInterface(CallOpSetInterface* ops) { ops_ = ops; } - // Returns true if no interceptors are run. This should be used only by - // subclasses of CallOpSetInterface. SetCall and SetCallOpSetInterface should - // have been called before this. After all the interceptors are done running, - // either ContinueFillOpsAfterInterception or + // SetCall should have been called before this. + // Returns true if the interceptors list is empty + bool InterceptorsListEmpty() { + auto* client_rpc_info = call_->client_rpc_info(); + if (client_rpc_info != nullptr) { + if (client_rpc_info->interceptors_.size() == 0) { + return true; + } else { + return false; + } + } + + auto* server_rpc_info = call_->server_rpc_info(); + if (server_rpc_info == nullptr || + server_rpc_info->interceptors_.size() == 0) { + return true; + } + return false; + } + + // This should be used only by subclasses of CallOpSetInterface. SetCall and + // SetCallOpSetInterface should have been called before this. After all the + // interceptors are done running, either ContinueFillOpsAfterInterception or // ContinueFinalizeOpsAfterInterception will be called. Note that neither of // them is invoked if there were no interceptors registered. bool RunInterceptors() { @@ -334,17 +394,20 @@ class InterceptorBatchMethodsImpl std::function callback_; ByteBuffer* send_message_ = nullptr; + bool* fail_send_message_ = nullptr; + const void** orig_send_message_ = nullptr; + std::function serializer_; std::multimap* send_initial_metadata_; grpc_status_code* code_ = nullptr; grpc::string* error_details_ = nullptr; grpc::string* error_message_ = nullptr; - Status send_status_; std::multimap* send_trailing_metadata_ = nullptr; void* recv_message_ = nullptr; + bool* got_message_ = nullptr; MetadataMap* recv_initial_metadata_ = nullptr; @@ -379,13 +442,36 @@ class CancelInterceptorBatchMethods "Cancel notification"); } - ByteBuffer* GetSendMessage() override { + ByteBuffer* GetSerializedSendMessage() override { GPR_CODEGEN_ASSERT(false && "It is illegal to call GetSendMessage on a method which " "has a Cancel notification"); return nullptr; } + bool GetSendMessageStatus() override { + GPR_CODEGEN_ASSERT( + false && + "It is illegal to call GetSendMessageStatus on a method which " + "has a Cancel notification"); + return false; + } + + const void* GetSendMessage() override { + GPR_CODEGEN_ASSERT( + false && + "It is illegal to call GetOriginalSendMessage on a method which " + "has a Cancel notification"); + return nullptr; + } + + void ModifySendMessage(const void* message) override { + GPR_CODEGEN_ASSERT( + false && + "It is illegal to call ModifySendMessage on a method which " + "has a Cancel notification"); + } + std::multimap* GetSendInitialMetadata() override { GPR_CODEGEN_ASSERT(false && "It is illegal to call GetSendInitialMetadata on a " @@ -451,6 +537,18 @@ class CancelInterceptorBatchMethods "method which has a Cancel notification"); return std::unique_ptr(nullptr); } + + void FailHijackedRecvMessage() override { + GPR_CODEGEN_ASSERT(false && + "It is illegal to call FailHijackedRecvMessage on a " + "method which has a Cancel notification"); + } + + void FailHijackedSendMessage() override { + GPR_CODEGEN_ASSERT(false && + "It is illegal to call FailHijackedSendMessage on a " + "method which has a Cancel notification"); + } }; } // namespace internal } // namespace grpc diff --git a/include/grpcpp/impl/codegen/message_allocator.h b/include/grpcpp/impl/codegen/message_allocator.h new file mode 100644 index 00000000000..107bec62f1d --- /dev/null +++ b/include/grpcpp/impl/codegen/message_allocator.h @@ -0,0 +1,55 @@ +/* + * + * Copyright 2019 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_MESSAGE_ALLOCATOR_H +#define GRPCPP_IMPL_CODEGEN_MESSAGE_ALLOCATOR_H + +namespace grpc { +namespace experimental { + +// This is per rpc struct for the allocator. We can potentially put the grpc +// call arena in here in the future. +template +struct RpcAllocatorInfo { + RequestT* request; + ResponseT* response; + // per rpc allocator internal state. MessageAllocator can set it when + // AllocateMessages is called and use it later. + void* allocator_state; +}; + +// Implementations need to be thread-safe +template +class MessageAllocator { + public: + virtual ~MessageAllocator() = default; + // Allocate both request and response + virtual void AllocateMessages( + RpcAllocatorInfo* info) = 0; + // Optional: deallocate request early, called by + // ServerCallbackRpcController::ReleaseRequest + virtual void DeallocateRequest(RpcAllocatorInfo* info) {} + // Deallocate response and request (if applicable) + virtual void DeallocateMessages( + RpcAllocatorInfo* info) = 0; +}; + +} // namespace experimental +} // namespace grpc + +#endif // GRPCPP_IMPL_CODEGEN_MESSAGE_ALLOCATOR_H diff --git a/include/grpcpp/impl/codegen/method_handler_impl.h b/include/grpcpp/impl/codegen/method_handler_impl.h index dd53f975f68..dee1cb56ad1 100644 --- a/include/grpcpp/impl/codegen/method_handler_impl.h +++ b/include/grpcpp/impl/codegen/method_handler_impl.h @@ -79,15 +79,15 @@ class RpcMethodHandler : public MethodHandler { ops.set_compression_level(param.server_context->compression_level()); } if (status.ok()) { - status = ops.SendMessage(rsp); + status = ops.SendMessagePtr(&rsp); } ops.ServerSendStatus(¶m.server_context->trailing_metadata_, status); param.call->PerformOps(&ops); param.call->cq()->Pluck(&ops); } - void* Deserialize(grpc_call* call, grpc_byte_buffer* req, - Status* status) final { + void* Deserialize(grpc_call* call, grpc_byte_buffer* req, Status* status, + void** handler_data) final { ByteBuffer buf; buf.set_buffer(req); auto* request = new (g_core_codegen_interface->grpc_call_arena_alloc( @@ -139,7 +139,7 @@ class ClientStreamingHandler : public MethodHandler { } } if (status.ok()) { - status = ops.SendMessage(rsp); + status = ops.SendMessagePtr(&rsp); } ops.ServerSendStatus(¶m.server_context->trailing_metadata_, status); param.call->PerformOps(&ops); @@ -191,8 +191,8 @@ class ServerStreamingHandler : public MethodHandler { param.call->cq()->Pluck(&ops); } - void* Deserialize(grpc_call* call, grpc_byte_buffer* req, - Status* status) final { + void* Deserialize(grpc_call* call, grpc_byte_buffer* req, Status* status, + void** handler_data) final { ByteBuffer buf; buf.set_buffer(req); auto* request = new (g_core_codegen_interface->grpc_call_arena_alloc( @@ -327,8 +327,8 @@ class ErrorMethodHandler : public MethodHandler { param.call->cq()->Pluck(&ops); } - void* Deserialize(grpc_call* call, grpc_byte_buffer* req, - Status* status) final { + void* Deserialize(grpc_call* call, grpc_byte_buffer* req, Status* status, + void** handler_data) final { // We have to destroy any request payload if (req != nullptr) { g_core_codegen_interface->grpc_byte_buffer_destroy(req); diff --git a/include/grpcpp/impl/codegen/proto_buffer_reader.h b/include/grpcpp/impl/codegen/proto_buffer_reader.h index 9acae476b11..734da366f3a 100644 --- a/include/grpcpp/impl/codegen/proto_buffer_reader.h +++ b/include/grpcpp/impl/codegen/proto_buffer_reader.h @@ -73,7 +73,7 @@ class ProtoBufferReader : public ::grpc::protobuf::io::ZeroCopyInputStream { } /// 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_) - + *data = GRPC_SLICE_START_PTR(*slice_) + GRPC_SLICE_LENGTH(*slice_) - backup_count_; GPR_CODEGEN_ASSERT(backup_count_ <= INT_MAX); *size = (int)backup_count_; @@ -81,15 +81,14 @@ class ProtoBufferReader : public ::grpc::protobuf::io::ZeroCopyInputStream { return true; } /// Otherwise get the next slice from the byte buffer reader - if (!g_core_codegen_interface->grpc_byte_buffer_reader_next(&reader_, + if (!g_core_codegen_interface->grpc_byte_buffer_reader_peek(&reader_, &slice_)) { return false; } - g_core_codegen_interface->grpc_slice_unref(slice_); - *data = GRPC_SLICE_START_PTR(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_); + GPR_CODEGEN_ASSERT(GRPC_SLICE_LENGTH(*slice_) <= INT_MAX); + byte_count_ += * size = (int)GRPC_SLICE_LENGTH(*slice_); return true; } @@ -100,7 +99,7 @@ class ProtoBufferReader : public ::grpc::protobuf::io::ZeroCopyInputStream { /// 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(GRPC_SLICE_LENGTH(slice_))); + GPR_CODEGEN_ASSERT(count <= static_cast(GRPC_SLICE_LENGTH(*slice_))); backup_count_ = count; } @@ -135,14 +134,15 @@ class ProtoBufferReader : public ::grpc::protobuf::io::ZeroCopyInputStream { 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_; } + grpc_slice* slice() { return slice_; } + grpc_slice** mutable_slice_ptr() { 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 + grpc_slice* slice_; ///< current slice passed back to the caller Status status_; ///< status of the entire object }; diff --git a/include/grpcpp/impl/codegen/rpc_service_method.h b/include/grpcpp/impl/codegen/rpc_service_method.h index f465c5fc2f9..21fb2ac2130 100644 --- a/include/grpcpp/impl/codegen/rpc_service_method.h +++ b/include/grpcpp/impl/codegen/rpc_service_method.h @@ -46,21 +46,25 @@ class MethodHandler { /// \param context : the ServerContext structure for this server call /// \param req : the request payload, if appropriate for this RPC /// \param req_status : the request status after any interceptors have run - /// \param rpc_requester : used only by the callback API. It is a function + /// \param handler_data: internal data for the handler. + /// \param requester : used only by the callback API. It is a function /// called by the RPC Controller to request another RPC (and also /// to set up the state required to make that request possible) HandlerParameter(Call* c, ServerContext* context, void* req, - Status req_status, std::function requester) + Status req_status, void* handler_data, + std::function requester) : call(c), server_context(context), request(req), status(req_status), + internal_data(handler_data), call_requester(std::move(requester)) {} ~HandlerParameter() {} Call* call; ServerContext* server_context; void* request; Status status; + void* internal_data; std::function call_requester; }; virtual void RunHandler(const HandlerParameter& param) = 0; @@ -71,7 +75,7 @@ class MethodHandler { pointer after calling RunHandler. Ownership of the deserialized request is retained by the handler. Returns nullptr if deserialization failed. */ virtual void* Deserialize(grpc_call* call, grpc_byte_buffer* req, - Status* status) { + Status* status, void** handler_data) { GPR_CODEGEN_ASSERT(req == nullptr); return nullptr; } diff --git a/include/grpcpp/impl/codegen/server_callback.h b/include/grpcpp/impl/codegen/server_callback.h index b866fc16dcf..3f6d5cd3555 100644 --- a/include/grpcpp/impl/codegen/server_callback.h +++ b/include/grpcpp/impl/codegen/server_callback.h @@ -19,32 +19,81 @@ #ifndef GRPCPP_IMPL_CODEGEN_SERVER_CALLBACK_H #define GRPCPP_IMPL_CODEGEN_SERVER_CALLBACK_H +#include #include +#include #include #include #include #include #include +#include #include #include #include namespace grpc { -// forward declarations +// Declare base class of all reactors as internal namespace internal { -template -class CallbackUnaryHandler; + +// Forward declarations +template +class CallbackClientStreamingHandler; +template +class CallbackServerStreamingHandler; +template +class CallbackBidiHandler; + +class ServerReactor { + public: + virtual ~ServerReactor() = default; + virtual void OnDone() = 0; + virtual void OnCancel() = 0; + + private: + friend class ::grpc::ServerContext; + template + friend class CallbackClientStreamingHandler; + template + friend class CallbackServerStreamingHandler; + template + friend class CallbackBidiHandler; + + // The ServerReactor is responsible for tracking when it is safe to call + // OnCancel. This function should not be called until after OnStarted is done + // and the RPC has completed with a cancellation. This is tracked by counting + // how many of these conditions have been met and calling OnCancel when none + // remain unmet. + + void MaybeCallOnCancel() { + if (on_cancel_conditions_remaining_.fetch_sub( + 1, std::memory_order_acq_rel) == 1) { + OnCancel(); + } + } + + std::atomic_int on_cancel_conditions_remaining_{2}; +}; + } // namespace internal namespace experimental { +// Forward declarations +template +class ServerReadReactor; +template +class ServerWriteReactor; +template +class ServerBidiReactor; + // For unary RPCs, the exposed controller class is only an interface // and the actual implementation is an internal class. class ServerCallbackRpcController { public: - virtual ~ServerCallbackRpcController() {} + virtual ~ServerCallbackRpcController() = default; // The method handler must call this function when it is done so that // the library knows to free its resources @@ -53,45 +102,741 @@ class ServerCallbackRpcController { // Allow the method handler to push out the initial metadata before // the response and status are ready virtual void SendInitialMetadata(std::function) = 0; + + /// SetCancelCallback passes in a callback to be called when the RPC is + /// canceled for whatever reason (streaming calls have OnCancel instead). This + /// is an advanced and uncommon use with several important restrictions. This + /// function may not be called more than once on the same RPC. + /// + /// If code calls SetCancelCallback on an RPC, it must also call + /// ClearCancelCallback before calling Finish on the RPC controller. That + /// method makes sure that no cancellation callback is executed for this RPC + /// beyond the point of its return. ClearCancelCallback may be called even if + /// SetCancelCallback was not called for this RPC, and it may be called + /// multiple times. It _must_ be called if SetCancelCallback was called for + /// this RPC. + /// + /// The callback should generally be lightweight and nonblocking and primarily + /// concerned with clearing application state related to the RPC or causing + /// operations (such as cancellations) to happen on dependent RPCs. + /// + /// If the RPC is already canceled at the time that SetCancelCallback is + /// called, the callback is invoked immediately. + /// + /// The cancellation callback may be executed concurrently with the method + /// handler that invokes it but will certainly not issue or execute after the + /// return of ClearCancelCallback. If ClearCancelCallback is invoked while the + /// callback is already executing, the callback will complete its execution + /// before ClearCancelCallback takes effect. + /// + /// To preserve the orderings described above, the callback may be called + /// under a lock that is also used for ClearCancelCallback and + /// ServerContext::IsCancelled, so the callback CANNOT call either of those + /// operations on this RPC or any other function that causes those operations + /// to be called before the callback completes. + virtual void SetCancelCallback(std::function callback) = 0; + virtual void ClearCancelCallback() = 0; + + // NOTE: This is an API for advanced users who need custom allocators. + // Optionally deallocate request early to reduce the size of working set. + // A custom MessageAllocator needs to be registered to make use of this. + virtual void FreeRequest() = 0; + // NOTE: This is an API for advanced users who need custom allocators. + // Get and maybe mutate the allocator state associated with the current RPC. + virtual void* GetAllocatorState() = 0; +}; + +// NOTE: The actual streaming object classes are provided +// as API only to support mocking. There are no implementations of +// these class interfaces in the API. +template +class ServerCallbackReader { + public: + virtual ~ServerCallbackReader() {} + virtual void Finish(Status s) = 0; + virtual void SendInitialMetadata() = 0; + virtual void Read(Request* msg) = 0; + + protected: + template + void BindReactor(ServerReadReactor* reactor) { + reactor->BindReader(this); + } +}; + +template +class ServerCallbackWriter { + public: + virtual ~ServerCallbackWriter() {} + + virtual void Finish(Status s) = 0; + virtual void SendInitialMetadata() = 0; + virtual void Write(const Response* msg, WriteOptions options) = 0; + virtual void WriteAndFinish(const Response* msg, WriteOptions options, + Status s) { + // Default implementation that can/should be overridden + Write(msg, std::move(options)); + Finish(std::move(s)); + } + + protected: + template + void BindReactor(ServerWriteReactor* reactor) { + reactor->BindWriter(this); + } +}; + +template +class ServerCallbackReaderWriter { + public: + virtual ~ServerCallbackReaderWriter() {} + + virtual void Finish(Status s) = 0; + virtual void SendInitialMetadata() = 0; + virtual void Read(Request* msg) = 0; + virtual void Write(const Response* msg, WriteOptions options) = 0; + virtual void WriteAndFinish(const Response* msg, WriteOptions options, + Status s) { + // Default implementation that can/should be overridden + Write(msg, std::move(options)); + Finish(std::move(s)); + } + + protected: + void BindReactor(ServerBidiReactor* reactor) { + reactor->BindStream(this); + } +}; + +// The following classes are the reactor interfaces that are to be implemented +// by the user, returned as the result of the method handler for a callback +// method, and activated by the call to OnStarted. The library guarantees that +// OnStarted will be called for any reactor that has been created using a +// method handler registered on a service. No operation initiation method may be +// called until after the call to OnStarted. +// Note that none of the classes are pure; all reactions have a default empty +// reaction so that the user class only needs to override those classes that it +// cares about. + +/// \a ServerBidiReactor is the interface for a bidirectional streaming RPC. +template +class ServerBidiReactor : public internal::ServerReactor { + public: + ~ServerBidiReactor() = default; + + /// Do NOT call any operation initiation method (names that start with Start) + /// until after the library has called OnStarted on this object. + + /// Send any initial metadata stored in the RPC context. If not invoked, + /// any initial metadata will be passed along with the first Write or the + /// Finish (if there are no writes). + void StartSendInitialMetadata() { stream_->SendInitialMetadata(); } + + /// Initiate a read operation. + /// + /// \param[out] req Where to eventually store the read message. Valid when + /// the library calls OnReadDone + void StartRead(Request* req) { stream_->Read(req); } + + /// Initiate a write operation. + /// + /// \param[in] resp The message to be written. The library takes temporary + /// ownership until OnWriteDone, at which point the + /// application regains ownership of resp. + void StartWrite(const Response* resp) { StartWrite(resp, WriteOptions()); } + + /// Initiate a write operation with specified options. + /// + /// \param[in] resp The message to be written. The library takes temporary + /// ownership until OnWriteDone, at which point the + /// application regains ownership of resp. + /// \param[in] options The WriteOptions to use for writing this message + void StartWrite(const Response* resp, WriteOptions options) { + stream_->Write(resp, std::move(options)); + } + + /// Initiate a write operation with specified options and final RPC Status, + /// which also causes any trailing metadata for this RPC to be sent out. + /// StartWriteAndFinish is like merging StartWriteLast and Finish into a + /// single step. A key difference, though, is that this operation doesn't have + /// an OnWriteDone reaction - it is considered complete only when OnDone is + /// available. An RPC can either have StartWriteAndFinish or Finish, but not + /// both. + /// + /// \param[in] resp The message to be written. The library takes temporary + /// ownership until Onone, at which point the application + /// regains ownership of resp. + /// \param[in] options The WriteOptions to use for writing this message + /// \param[in] s The status outcome of this RPC + void StartWriteAndFinish(const Response* resp, WriteOptions options, + Status s) { + stream_->WriteAndFinish(resp, std::move(options), std::move(s)); + } + + /// Inform system of a planned write operation with specified options, but + /// allow the library to schedule the actual write coalesced with the writing + /// of trailing metadata (which takes place on a Finish call). + /// + /// \param[in] resp The message to be written. The library takes temporary + /// ownership until OnWriteDone, at which point the + /// application regains ownership of resp. + /// \param[in] options The WriteOptions to use for writing this message + void StartWriteLast(const Response* resp, WriteOptions options) { + StartWrite(resp, std::move(options.set_last_message())); + } + + /// Indicate that the stream is to be finished and the trailing metadata and + /// RPC status are to be sent. Every RPC MUST be finished using either Finish + /// or StartWriteAndFinish (but not both), even if the RPC is already + /// cancelled. + /// + /// \param[in] s The status outcome of this RPC + void Finish(Status s) { stream_->Finish(std::move(s)); } + + /// Notify the application that a streaming RPC has started and that it is now + /// ok to call any operation initiation method. An RPC is considered started + /// after the server has received all initial metadata from the client, which + /// is a result of the client calling StartCall(). + /// + /// \param[in] context The context object now associated with this RPC + virtual void OnStarted(ServerContext* context) {} + + /// Notifies the application that an explicit StartSendInitialMetadata + /// operation completed. Not used when the sending of initial metadata + /// piggybacks onto the first write. + /// + /// \param[in] ok Was it successful? If false, no further write-side operation + /// will succeed. + virtual void OnSendInitialMetadataDone(bool ok) {} + + /// Notifies the application that a StartRead operation completed. + /// + /// \param[in] ok Was it successful? If false, no further read-side operation + /// will succeed. + virtual void OnReadDone(bool ok) {} + + /// Notifies the application that a StartWrite (or StartWriteLast) operation + /// completed. + /// + /// \param[in] ok Was it successful? If false, no further write-side operation + /// will succeed. + virtual void OnWriteDone(bool ok) {} + + /// Notifies the application that all operations associated with this RPC + /// have completed. This is an override (from the internal base class) but not + /// final, so derived classes should override it if they want to take action. + void OnDone() override {} + + /// Notifies the application that this RPC has been cancelled. This is an + /// override (from the internal base class) but not final, so derived classes + /// should override it if they want to take action. + void OnCancel() override {} + + private: + friend class ServerCallbackReaderWriter; + void BindStream(ServerCallbackReaderWriter* stream) { + stream_ = stream; + } + + ServerCallbackReaderWriter* stream_; +}; + +/// \a ServerReadReactor is the interface for a client-streaming RPC. +template +class ServerReadReactor : public internal::ServerReactor { + public: + ~ServerReadReactor() = default; + + /// The following operation initiations are exactly like ServerBidiReactor. + void StartSendInitialMetadata() { reader_->SendInitialMetadata(); } + void StartRead(Request* req) { reader_->Read(req); } + void Finish(Status s) { reader_->Finish(std::move(s)); } + + /// Similar to ServerBidiReactor::OnStarted, except that this also provides + /// the response object that the stream fills in before calling Finish. + /// (It must be filled in if status is OK, but it may be filled in otherwise.) + /// + /// \param[in] context The context object now associated with this RPC + /// \param[in] resp The response object to be used by this RPC + virtual void OnStarted(ServerContext* context, Response* resp) {} + + /// The following notifications are exactly like ServerBidiReactor. + virtual void OnSendInitialMetadataDone(bool ok) {} + virtual void OnReadDone(bool ok) {} + void OnDone() override {} + void OnCancel() override {} + + private: + friend class ServerCallbackReader; + void BindReader(ServerCallbackReader* reader) { reader_ = reader; } + + ServerCallbackReader* reader_; +}; + +/// \a ServerWriteReactor is the interface for a server-streaming RPC. +template +class ServerWriteReactor : public internal::ServerReactor { + public: + ~ServerWriteReactor() = default; + + /// The following operation initiations are exactly like ServerBidiReactor. + void StartSendInitialMetadata() { writer_->SendInitialMetadata(); } + void StartWrite(const Response* resp) { StartWrite(resp, WriteOptions()); } + void StartWrite(const Response* resp, WriteOptions options) { + writer_->Write(resp, std::move(options)); + } + void StartWriteAndFinish(const Response* resp, WriteOptions options, + Status s) { + writer_->WriteAndFinish(resp, std::move(options), std::move(s)); + } + void StartWriteLast(const Response* resp, WriteOptions options) { + StartWrite(resp, std::move(options.set_last_message())); + } + void Finish(Status s) { writer_->Finish(std::move(s)); } + + /// Similar to ServerBidiReactor::OnStarted, except that this also provides + /// the request object sent by the client. + /// + /// \param[in] context The context object now associated with this RPC + /// \param[in] req The request object sent by the client + virtual void OnStarted(ServerContext* context, const Request* req) {} + + /// The following notifications are exactly like ServerBidiReactor. + virtual void OnSendInitialMetadataDone(bool ok) {} + virtual void OnWriteDone(bool ok) {} + void OnDone() override {} + void OnCancel() override {} + + private: + friend class ServerCallbackWriter; + void BindWriter(ServerCallbackWriter* writer) { writer_ = writer; } + + ServerCallbackWriter* writer_; }; } // namespace experimental namespace internal { -template +template +class UnimplementedReadReactor + : public experimental::ServerReadReactor { + public: + void OnDone() override { delete this; } + void OnStarted(ServerContext*, Response*) override { + this->Finish(Status(StatusCode::UNIMPLEMENTED, "")); + } +}; + +template +class UnimplementedWriteReactor + : public experimental::ServerWriteReactor { + public: + void OnDone() override { delete this; } + void OnStarted(ServerContext*, const Request*) override { + this->Finish(Status(StatusCode::UNIMPLEMENTED, "")); + } +}; + +template +class UnimplementedBidiReactor + : public experimental::ServerBidiReactor { + public: + void OnDone() override { delete this; } + void OnStarted(ServerContext*) override { + this->Finish(Status(StatusCode::UNIMPLEMENTED, "")); + } +}; + +template class CallbackUnaryHandler : public MethodHandler { public: CallbackUnaryHandler( std::function - func, - ServiceType* service) + func) : func_(func) {} + + void SetMessageAllocator( + experimental::MessageAllocator* allocator) { + allocator_ = allocator; + } + void RunHandler(const HandlerParameter& param) final { // Arena allocate a controller structure (that includes request/response) g_core_codegen_interface->grpc_call_ref(param.call->call()); + auto* allocator_info = + static_cast*>( + param.internal_data); auto* controller = new (g_core_codegen_interface->grpc_call_arena_alloc( param.call->call(), sizeof(ServerCallbackRpcControllerImpl))) - ServerCallbackRpcControllerImpl( - param.server_context, param.call, - static_cast(param.request), - std::move(param.call_requester)); + ServerCallbackRpcControllerImpl(param.server_context, param.call, + allocator_info, allocator_, + std::move(param.call_requester)); Status status = param.status; - if (status.ok()) { // Call the actual function handler and expect the user to call finish - CatchingCallback(std::move(func_), param.server_context, - controller->request(), controller->response(), - controller); + CatchingCallback(func_, param.server_context, controller->request(), + controller->response(), controller); } else { // if deserialization failed, we need to fail the call controller->Finish(status); } } - void* Deserialize(grpc_call* call, grpc_byte_buffer* req, - Status* status) final { + void* Deserialize(grpc_call* call, grpc_byte_buffer* req, Status* status, + void** handler_data) final { + ByteBuffer buf; + buf.set_buffer(req); + RequestType* request = nullptr; + experimental::RpcAllocatorInfo* allocator_info = + new (g_core_codegen_interface->grpc_call_arena_alloc( + call, sizeof(*allocator_info))) + experimental::RpcAllocatorInfo(); + if (allocator_ != nullptr) { + allocator_->AllocateMessages(allocator_info); + } else { + allocator_info->request = + new (g_core_codegen_interface->grpc_call_arena_alloc( + call, sizeof(RequestType))) RequestType(); + allocator_info->response = + new (g_core_codegen_interface->grpc_call_arena_alloc( + call, sizeof(ResponseType))) ResponseType(); + } + *handler_data = allocator_info; + request = allocator_info->request; + *status = SerializationTraits::Deserialize(&buf, request); + buf.Release(); + if (status->ok()) { + return request; + } + // Clean up on deserialization failure. + if (allocator_ != nullptr) { + allocator_->DeallocateMessages(allocator_info); + } else { + allocator_info->request->~RequestType(); + allocator_info->response->~ResponseType(); + allocator_info->request = nullptr; + allocator_info->response = nullptr; + } + return nullptr; + } + + private: + std::function + func_; + experimental::MessageAllocator* allocator_ = + nullptr; + + // The implementation class of ServerCallbackRpcController is a private member + // of CallbackUnaryHandler since it is never exposed anywhere, and this allows + // it to take advantage of CallbackUnaryHandler's friendships. + class ServerCallbackRpcControllerImpl + : public experimental::ServerCallbackRpcController { + public: + void Finish(Status s) override { + finish_tag_.Set(call_.call(), [this](bool) { MaybeDone(); }, + &finish_ops_); + if (!ctx_->sent_initial_metadata_) { + finish_ops_.SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + finish_ops_.set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + } + // The response is dropped if the status is not OK. + if (s.ok()) { + finish_ops_.ServerSendStatus( + &ctx_->trailing_metadata_, + finish_ops_.SendMessagePtr(allocator_info_->response)); + } else { + finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, s); + } + finish_ops_.set_core_cq_tag(&finish_tag_); + call_.PerformOps(&finish_ops_); + } + + void SendInitialMetadata(std::function f) override { + GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); + callbacks_outstanding_++; + // TODO(vjpai): Consider taking f as a move-capture if we adopt C++14 + // and if performance of this operation matters + meta_tag_.Set(call_.call(), + [this, f](bool ok) { + f(ok); + MaybeDone(); + }, + &meta_ops_); + meta_ops_.SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + meta_ops_.set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + meta_ops_.set_core_cq_tag(&meta_tag_); + call_.PerformOps(&meta_ops_); + } + + // Neither SetCancelCallback nor ClearCancelCallback should affect the + // callbacks_outstanding_ count since they are paired and both must precede + // the invocation of Finish (if they are used at all) + void SetCancelCallback(std::function callback) override { + ctx_->SetCancelCallback(std::move(callback)); + } + + void ClearCancelCallback() override { ctx_->ClearCancelCallback(); } + + void FreeRequest() override { + if (allocator_ != nullptr) { + allocator_->DeallocateRequest(allocator_info_); + } + } + + void* GetAllocatorState() override { + return allocator_info_->allocator_state; + } + + private: + friend class CallbackUnaryHandler; + + ServerCallbackRpcControllerImpl( + ServerContext* ctx, Call* call, + experimental::RpcAllocatorInfo* + allocator_info, + experimental::MessageAllocator* allocator, + std::function call_requester) + : ctx_(ctx), + call_(*call), + allocator_info_(allocator_info), + allocator_(allocator), + call_requester_(std::move(call_requester)) { + ctx_->BeginCompletionOp(call, [this](bool) { MaybeDone(); }, nullptr); + } + + const RequestType* request() { return allocator_info_->request; } + ResponseType* response() { return allocator_info_->response; } + + void MaybeDone() { + if (--callbacks_outstanding_ == 0) { + grpc_call* call = call_.call(); + auto call_requester = std::move(call_requester_); + if (allocator_ != nullptr) { + allocator_->DeallocateMessages(allocator_info_); + } else { + if (allocator_info_->request != nullptr) { + allocator_info_->request->~RequestType(); + } + if (allocator_info_->response != nullptr) { + allocator_info_->response->~ResponseType(); + } + } + this->~ServerCallbackRpcControllerImpl(); // explicitly call destructor + g_core_codegen_interface->grpc_call_unref(call); + call_requester(); + } + } + + CallOpSet meta_ops_; + CallbackWithSuccessTag meta_tag_; + CallOpSet + finish_ops_; + CallbackWithSuccessTag finish_tag_; + + ServerContext* ctx_; + Call call_; + experimental::RpcAllocatorInfo* allocator_info_; + experimental::MessageAllocator* allocator_; + std::function call_requester_; + std::atomic_int callbacks_outstanding_{ + 2}; // reserve for Finish and CompletionOp + }; +}; + +template +class CallbackClientStreamingHandler : public MethodHandler { + public: + CallbackClientStreamingHandler( + std::function< + experimental::ServerReadReactor*()> + func) + : func_(std::move(func)) {} + void RunHandler(const HandlerParameter& param) final { + // Arena allocate a reader structure (that includes response) + g_core_codegen_interface->grpc_call_ref(param.call->call()); + + experimental::ServerReadReactor* reactor = + param.status.ok() + ? CatchingReactorCreator< + experimental::ServerReadReactor>( + func_) + : nullptr; + + if (reactor == nullptr) { + // if deserialization or reactor creator failed, we need to fail the call + reactor = new UnimplementedReadReactor; + } + + auto* reader = new (g_core_codegen_interface->grpc_call_arena_alloc( + param.call->call(), sizeof(ServerCallbackReaderImpl))) + ServerCallbackReaderImpl(param.server_context, param.call, + std::move(param.call_requester), reactor); + + reader->BindReactor(reactor); + reactor->OnStarted(param.server_context, reader->response()); + // The earliest that OnCancel can be called is after OnStarted is done. + reactor->MaybeCallOnCancel(); + reader->MaybeDone(); + } + + private: + std::function*()> + func_; + + class ServerCallbackReaderImpl + : public experimental::ServerCallbackReader { + public: + void Finish(Status s) override { + finish_tag_.Set(call_.call(), [this](bool) { MaybeDone(); }, + &finish_ops_); + if (!ctx_->sent_initial_metadata_) { + finish_ops_.SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + finish_ops_.set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + } + // The response is dropped if the status is not OK. + if (s.ok()) { + finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, + finish_ops_.SendMessagePtr(&resp_)); + } else { + finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, s); + } + finish_ops_.set_core_cq_tag(&finish_tag_); + call_.PerformOps(&finish_ops_); + } + + void SendInitialMetadata() override { + GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); + callbacks_outstanding_++; + meta_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnSendInitialMetadataDone(ok); + MaybeDone(); + }, + &meta_ops_); + meta_ops_.SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + meta_ops_.set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + meta_ops_.set_core_cq_tag(&meta_tag_); + call_.PerformOps(&meta_ops_); + } + + void Read(RequestType* req) override { + callbacks_outstanding_++; + read_ops_.RecvMessage(req); + call_.PerformOps(&read_ops_); + } + + private: + friend class CallbackClientStreamingHandler; + + ServerCallbackReaderImpl( + ServerContext* ctx, Call* call, std::function call_requester, + experimental::ServerReadReactor* reactor) + : ctx_(ctx), + call_(*call), + call_requester_(std::move(call_requester)), + reactor_(reactor) { + ctx_->BeginCompletionOp(call, [this](bool) { MaybeDone(); }, reactor); + read_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnReadDone(ok); + MaybeDone(); + }, + &read_ops_); + read_ops_.set_core_cq_tag(&read_tag_); + } + + ~ServerCallbackReaderImpl() {} + + ResponseType* response() { return &resp_; } + + void MaybeDone() { + if (--callbacks_outstanding_ == 0) { + reactor_->OnDone(); + grpc_call* call = call_.call(); + auto call_requester = std::move(call_requester_); + this->~ServerCallbackReaderImpl(); // explicitly call destructor + g_core_codegen_interface->grpc_call_unref(call); + call_requester(); + } + } + + CallOpSet meta_ops_; + CallbackWithSuccessTag meta_tag_; + CallOpSet + finish_ops_; + CallbackWithSuccessTag finish_tag_; + CallOpSet> read_ops_; + CallbackWithSuccessTag read_tag_; + + ServerContext* ctx_; + Call call_; + ResponseType resp_; + std::function call_requester_; + experimental::ServerReadReactor* reactor_; + std::atomic_int callbacks_outstanding_{ + 3}; // reserve for OnStarted, Finish, and CompletionOp + }; +}; + +template +class CallbackServerStreamingHandler : public MethodHandler { + public: + CallbackServerStreamingHandler( + std::function< + experimental::ServerWriteReactor*()> + func) + : func_(std::move(func)) {} + void RunHandler(const HandlerParameter& param) final { + // Arena allocate a writer structure + g_core_codegen_interface->grpc_call_ref(param.call->call()); + + experimental::ServerWriteReactor* reactor = + param.status.ok() + ? CatchingReactorCreator< + experimental::ServerWriteReactor>( + func_) + : nullptr; + + if (reactor == nullptr) { + // if deserialization or reactor creator failed, we need to fail the call + reactor = new UnimplementedWriteReactor; + } + + auto* writer = new (g_core_codegen_interface->grpc_call_arena_alloc( + param.call->call(), sizeof(ServerCallbackWriterImpl))) + ServerCallbackWriterImpl(param.server_context, param.call, + static_cast(param.request), + std::move(param.call_requester), reactor); + writer->BindReactor(reactor); + reactor->OnStarted(param.server_context, writer->request()); + // The earliest that OnCancel can be called is after OnStarted is done. + reactor->MaybeCallOnCancel(); + writer->MaybeDone(); + } + + void* Deserialize(grpc_call* call, grpc_byte_buffer* req, Status* status, + void** handler_data) final { ByteBuffer buf; buf.set_buffer(req); auto* request = new (g_core_codegen_interface->grpc_call_arena_alloc( @@ -106,90 +851,302 @@ class CallbackUnaryHandler : public MethodHandler { } private: - std::function + std::function*()> func_; - // The implementation class of ServerCallbackRpcController is a private member - // of CallbackUnaryHandler since it is never exposed anywhere, and this allows - // it to take advantage of CallbackUnaryHandler's friendships. - class ServerCallbackRpcControllerImpl - : public experimental::ServerCallbackRpcController { + class ServerCallbackWriterImpl + : public experimental::ServerCallbackWriter { public: void Finish(Status s) override { - finish_tag_.Set( - call_.call(), - [this](bool) { - grpc_call* call = call_.call(); - auto call_requester = std::move(call_requester_); - this->~ServerCallbackRpcControllerImpl(); // explicitly call - // destructor - g_core_codegen_interface->grpc_call_unref(call); - call_requester(); - }, - &finish_buf_); + finish_tag_.Set(call_.call(), [this](bool) { MaybeDone(); }, + &finish_ops_); + finish_ops_.set_core_cq_tag(&finish_tag_); + if (!ctx_->sent_initial_metadata_) { - finish_buf_.SendInitialMetadata(&ctx_->initial_metadata_, + finish_ops_.SendInitialMetadata(&ctx_->initial_metadata_, ctx_->initial_metadata_flags()); if (ctx_->compression_level_set()) { - finish_buf_.set_compression_level(ctx_->compression_level()); + finish_ops_.set_compression_level(ctx_->compression_level()); } ctx_->sent_initial_metadata_ = true; } - // The response is dropped if the status is not OK. - if (s.ok()) { - finish_buf_.ServerSendStatus(&ctx_->trailing_metadata_, - finish_buf_.SendMessage(resp_)); - } else { - finish_buf_.ServerSendStatus(&ctx_->trailing_metadata_, s); - } - finish_buf_.set_core_cq_tag(&finish_tag_); - call_.PerformOps(&finish_buf_); + finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, s); + call_.PerformOps(&finish_ops_); } - void SendInitialMetadata(std::function f) override { + void SendInitialMetadata() override { GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); - - meta_tag_.Set(call_.call(), std::move(f), &meta_buf_); - meta_buf_.SendInitialMetadata(&ctx_->initial_metadata_, + callbacks_outstanding_++; + meta_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnSendInitialMetadataDone(ok); + MaybeDone(); + }, + &meta_ops_); + meta_ops_.SendInitialMetadata(&ctx_->initial_metadata_, ctx_->initial_metadata_flags()); if (ctx_->compression_level_set()) { - meta_buf_.set_compression_level(ctx_->compression_level()); + meta_ops_.set_compression_level(ctx_->compression_level()); } ctx_->sent_initial_metadata_ = true; - meta_buf_.set_core_cq_tag(&meta_tag_); - call_.PerformOps(&meta_buf_); + meta_ops_.set_core_cq_tag(&meta_tag_); + call_.PerformOps(&meta_ops_); + } + + void Write(const ResponseType* resp, WriteOptions options) override { + callbacks_outstanding_++; + if (options.is_last_message()) { + options.set_buffer_hint(); + } + if (!ctx_->sent_initial_metadata_) { + write_ops_.SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + write_ops_.set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + } + // TODO(vjpai): don't assert + GPR_CODEGEN_ASSERT(write_ops_.SendMessagePtr(resp, options).ok()); + call_.PerformOps(&write_ops_); + } + + void WriteAndFinish(const ResponseType* resp, WriteOptions options, + Status s) override { + // This combines the write into the finish callback + // Don't send any message if the status is bad + if (s.ok()) { + // TODO(vjpai): don't assert + GPR_CODEGEN_ASSERT(finish_ops_.SendMessagePtr(resp, options).ok()); + } + Finish(std::move(s)); } private: - template - friend class CallbackUnaryHandler; + friend class CallbackServerStreamingHandler; - ServerCallbackRpcControllerImpl(ServerContext* ctx, Call* call, - RequestType* req, - std::function call_requester) + ServerCallbackWriterImpl( + ServerContext* ctx, Call* call, const RequestType* req, + std::function call_requester, + experimental::ServerWriteReactor* reactor) : ctx_(ctx), call_(*call), req_(req), - call_requester_(std::move(call_requester)) {} + call_requester_(std::move(call_requester)), + reactor_(reactor) { + ctx_->BeginCompletionOp(call, [this](bool) { MaybeDone(); }, reactor); + write_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnWriteDone(ok); + MaybeDone(); + }, + &write_ops_); + write_ops_.set_core_cq_tag(&write_tag_); + } + ~ServerCallbackWriterImpl() { req_->~RequestType(); } - ~ServerCallbackRpcControllerImpl() { req_->~RequestType(); } + const RequestType* request() { return req_; } - RequestType* request() { return req_; } - ResponseType* response() { return &resp_; } + void MaybeDone() { + if (--callbacks_outstanding_ == 0) { + reactor_->OnDone(); + grpc_call* call = call_.call(); + auto call_requester = std::move(call_requester_); + this->~ServerCallbackWriterImpl(); // explicitly call destructor + g_core_codegen_interface->grpc_call_unref(call); + call_requester(); + } + } - CallOpSet meta_buf_; + CallOpSet meta_ops_; CallbackWithSuccessTag meta_tag_; CallOpSet - finish_buf_; + finish_ops_; CallbackWithSuccessTag finish_tag_; + CallOpSet write_ops_; + CallbackWithSuccessTag write_tag_; ServerContext* ctx_; Call call_; - RequestType* req_; - ResponseType resp_; + const RequestType* req_; std::function call_requester_; + experimental::ServerWriteReactor* reactor_; + std::atomic_int callbacks_outstanding_{ + 3}; // reserve for OnStarted, Finish, and CompletionOp + }; +}; + +template +class CallbackBidiHandler : public MethodHandler { + public: + CallbackBidiHandler( + std::function< + experimental::ServerBidiReactor*()> + func) + : func_(std::move(func)) {} + void RunHandler(const HandlerParameter& param) final { + g_core_codegen_interface->grpc_call_ref(param.call->call()); + + experimental::ServerBidiReactor* reactor = + param.status.ok() + ? CatchingReactorCreator< + experimental::ServerBidiReactor>( + func_) + : nullptr; + + if (reactor == nullptr) { + // if deserialization or reactor creator failed, we need to fail the call + reactor = new UnimplementedBidiReactor; + } + + auto* stream = new (g_core_codegen_interface->grpc_call_arena_alloc( + param.call->call(), sizeof(ServerCallbackReaderWriterImpl))) + ServerCallbackReaderWriterImpl(param.server_context, param.call, + std::move(param.call_requester), + reactor); + + stream->BindReactor(reactor); + reactor->OnStarted(param.server_context); + // The earliest that OnCancel can be called is after OnStarted is done. + reactor->MaybeCallOnCancel(); + stream->MaybeDone(); + } + + private: + std::function*()> + func_; + + class ServerCallbackReaderWriterImpl + : public experimental::ServerCallbackReaderWriter { + public: + void Finish(Status s) override { + finish_tag_.Set(call_.call(), [this](bool) { MaybeDone(); }, + &finish_ops_); + finish_ops_.set_core_cq_tag(&finish_tag_); + + if (!ctx_->sent_initial_metadata_) { + finish_ops_.SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + finish_ops_.set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + } + finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, s); + call_.PerformOps(&finish_ops_); + } + + void SendInitialMetadata() override { + GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); + callbacks_outstanding_++; + meta_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnSendInitialMetadataDone(ok); + MaybeDone(); + }, + &meta_ops_); + meta_ops_.SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + meta_ops_.set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + meta_ops_.set_core_cq_tag(&meta_tag_); + call_.PerformOps(&meta_ops_); + } + + void Write(const ResponseType* resp, WriteOptions options) override { + callbacks_outstanding_++; + if (options.is_last_message()) { + options.set_buffer_hint(); + } + if (!ctx_->sent_initial_metadata_) { + write_ops_.SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + write_ops_.set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + } + // TODO(vjpai): don't assert + GPR_CODEGEN_ASSERT(write_ops_.SendMessagePtr(resp, options).ok()); + call_.PerformOps(&write_ops_); + } + + void WriteAndFinish(const ResponseType* resp, WriteOptions options, + Status s) override { + // Don't send any message if the status is bad + if (s.ok()) { + // TODO(vjpai): don't assert + GPR_CODEGEN_ASSERT(finish_ops_.SendMessagePtr(resp, options).ok()); + } + Finish(std::move(s)); + } + + void Read(RequestType* req) override { + callbacks_outstanding_++; + read_ops_.RecvMessage(req); + call_.PerformOps(&read_ops_); + } + + private: + friend class CallbackBidiHandler; + + ServerCallbackReaderWriterImpl( + ServerContext* ctx, Call* call, std::function call_requester, + experimental::ServerBidiReactor* reactor) + : ctx_(ctx), + call_(*call), + call_requester_(std::move(call_requester)), + reactor_(reactor) { + ctx_->BeginCompletionOp(call, [this](bool) { MaybeDone(); }, reactor); + write_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnWriteDone(ok); + MaybeDone(); + }, + &write_ops_); + write_ops_.set_core_cq_tag(&write_tag_); + read_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnReadDone(ok); + MaybeDone(); + }, + &read_ops_); + read_ops_.set_core_cq_tag(&read_tag_); + } + ~ServerCallbackReaderWriterImpl() {} + + void MaybeDone() { + if (--callbacks_outstanding_ == 0) { + reactor_->OnDone(); + grpc_call* call = call_.call(); + auto call_requester = std::move(call_requester_); + this->~ServerCallbackReaderWriterImpl(); // explicitly call destructor + g_core_codegen_interface->grpc_call_unref(call); + call_requester(); + } + } + + CallOpSet meta_ops_; + CallbackWithSuccessTag meta_tag_; + CallOpSet + finish_ops_; + CallbackWithSuccessTag finish_tag_; + CallOpSet write_ops_; + CallbackWithSuccessTag write_tag_; + CallOpSet> read_ops_; + CallbackWithSuccessTag read_tag_; + + ServerContext* ctx_; + Call call_; + std::function call_requester_; + experimental::ServerBidiReactor* reactor_; + std::atomic_int callbacks_outstanding_{ + 3}; // reserve for OnStarted, Finish, and CompletionOp }; }; diff --git a/include/grpcpp/impl/codegen/server_context.h b/include/grpcpp/impl/codegen/server_context.h index 82ee862f61b..c6903743938 100644 --- a/include/grpcpp/impl/codegen/server_context.h +++ b/include/grpcpp/impl/codegen/server_context.h @@ -41,8 +41,15 @@ struct grpc_metadata; struct grpc_call; struct census_context; +namespace grpc_impl { + +class CompletionQueue; +class Server; +} // namespace grpc_impl namespace grpc { class ClientContext; +class GenericServerContext; +class ServerInterface; template class ServerAsyncReader; template @@ -55,6 +62,7 @@ template class ServerReader; template class ServerWriter; + namespace internal { template class ServerReaderWriterBody; @@ -66,19 +74,23 @@ template class ServerStreamingHandler; template class BidiStreamingHandler; -template +template class CallbackUnaryHandler; +template +class CallbackClientStreamingHandler; +template +class CallbackServerStreamingHandler; +template +class CallbackBidiHandler; template class TemplatedBidiStreamingHandler; template class ErrorMethodHandler; class Call; +class ServerReactor; } // namespace internal -class CompletionQueue; -class Server; class ServerInterface; - namespace testing { class InteropServerContextInspector; class ServerContextTestSpouse; @@ -124,6 +136,13 @@ class ServerContext { /// end in "-bin". /// \param value The metadata value. If its value is binary, the key name /// must end in "-bin". + /// + /// Metadata must conform to the following format: + /// Custom-Metadata -> Binary-Header / ASCII-Header + /// Binary-Header -> {Header-Name "-bin" } {binary value} + /// ASCII-Header -> Header-Name ASCII-Value + /// Header-Name -> 1*( %x30-39 / %x61-7A / "_" / "-" / ".") ; 0-9 a-z _ - . + /// ASCII-Value -> 1*( %x20-%x7E ) ; space and printable ASCII void AddInitialMetadata(const grpc::string& key, const grpc::string& value); /// Add the (\a key, \a value) pair to the initial metadata @@ -138,6 +157,13 @@ class ServerContext { /// it must end in "-bin". /// \param value The metadata value. If its value is binary, the key name /// must end in "-bin". + /// + /// Metadata must conform to the following format: + /// Custom-Metadata -> Binary-Header / ASCII-Header + /// Binary-Header -> {Header-Name "-bin" } {binary value} + /// ASCII-Header -> Header-Name ASCII-Value + /// Header-Name -> 1*( %x30-39 / %x61-7A / "_" / "-" / ".") ; 0-9 a-z _ - . + /// ASCII-Value -> 1*( %x20-%x7E ) ; space and printable ASCII void AddTrailingMetadata(const grpc::string& key, const grpc::string& value); /// IsCancelled is always safe to call when using sync or callback API. @@ -247,7 +273,7 @@ class ServerContext { friend class ::grpc::testing::InteropServerContextInspector; friend class ::grpc::testing::ServerContextTestSpouse; friend class ::grpc::ServerInterface; - friend class ::grpc::Server; + friend class ::grpc_impl::Server; template friend class ::grpc::ServerAsyncReader; template @@ -270,11 +296,18 @@ class ServerContext { friend class ::grpc::internal::ServerStreamingHandler; template friend class ::grpc::internal::TemplatedBidiStreamingHandler; - template + template friend class ::grpc::internal::CallbackUnaryHandler; + template + friend class ::grpc::internal::CallbackClientStreamingHandler; + template + friend class ::grpc::internal::CallbackServerStreamingHandler; + template + friend class ::grpc::internal::CallbackBidiHandler; template friend class internal::ErrorMethodHandler; friend class ::grpc::ClientContext; + friend class ::grpc::GenericServerContext; /// Prevent copying. ServerContext(const ServerContext&); @@ -282,7 +315,9 @@ class ServerContext { class CompletionOp; - void BeginCompletionOp(internal::Call* call, bool callback); + void BeginCompletionOp(internal::Call* call, + std::function callback, + internal::ServerReactor* reactor); /// Return the tag queued by BeginCompletionOp() internal::CompletionQueueTag* GetCompletionOpTag(); @@ -298,13 +333,16 @@ class ServerContext { uint32_t initial_metadata_flags() const { return 0; } + void SetCancelCallback(std::function callback); + void ClearCancelCallback(); + experimental::ServerRpcInfo* set_server_rpc_info( - const char* method, + const char* method, internal::RpcMethod::RpcType type, const std::vector< std::unique_ptr>& creators) { if (creators.size() != 0) { - rpc_info_ = new experimental::ServerRpcInfo(this, method); + rpc_info_ = new experimental::ServerRpcInfo(this, method, type); rpc_info_->RegisterInterceptors(creators); } return rpc_info_; @@ -317,7 +355,7 @@ class ServerContext { gpr_timespec deadline_; grpc_call* call_; - CompletionQueue* cq_; + ::grpc_impl::CompletionQueue* cq_; bool sent_initial_metadata_; mutable std::shared_ptr auth_context_; mutable internal::MetadataMap client_metadata_; diff --git a/include/grpcpp/impl/codegen/server_interceptor.h b/include/grpcpp/impl/codegen/server_interceptor.h index 5fb5df28b70..8875a28bf32 100644 --- a/include/grpcpp/impl/codegen/server_interceptor.h +++ b/include/grpcpp/impl/codegen/server_interceptor.h @@ -23,6 +23,7 @@ #include #include +#include #include namespace grpc { @@ -36,27 +37,66 @@ class InterceptorBatchMethodsImpl; namespace experimental { class ServerRpcInfo; +// A factory interface for creation of server interceptors. A vector of +// factories can be provided to ServerBuilder which will be used to create a new +// vector of server interceptors per RPC. Server interceptor authors should +// create a subclass of ServerInterceptorFactorInterface which creates objects +// of their interceptors. class ServerInterceptorFactoryInterface { public: virtual ~ServerInterceptorFactoryInterface() {} + // Returns a pointer to an Interceptor object on successful creation, nullptr + // otherwise. If nullptr is returned, this server interceptor factory is + // ignored for the purposes of that RPC. virtual Interceptor* CreateServerInterceptor(ServerRpcInfo* info) = 0; }; +/// ServerRpcInfo represents the state of a particular RPC as it +/// appears to an interceptor. It is created and owned by the library and +/// passed to the CreateServerInterceptor method of the application's +/// ServerInterceptorFactoryInterface implementation class ServerRpcInfo { public: - ~ServerRpcInfo(){}; + /// Type categorizes RPCs by unary or streaming type + enum class Type { UNARY, CLIENT_STREAMING, SERVER_STREAMING, BIDI_STREAMING }; + ~ServerRpcInfo() {} + + // Delete all copy and move constructors and assignments ServerRpcInfo(const ServerRpcInfo&) = delete; - ServerRpcInfo(ServerRpcInfo&&) = default; - ServerRpcInfo& operator=(ServerRpcInfo&&) = default; + ServerRpcInfo& operator=(const ServerRpcInfo&) = delete; + ServerRpcInfo(ServerRpcInfo&&) = delete; + ServerRpcInfo& operator=(ServerRpcInfo&&) = delete; // Getter methods - const char* method() { return method_; } + + /// Return the fully-specified method name + const char* method() const { return method_; } + + /// Return the type of the RPC (unary or a streaming flavor) + Type type() const { return type_; } + + /// Return a pointer to the underlying ServerContext structure associated + /// with the RPC to support features that apply to it grpc::ServerContext* server_context() { return ctx_; } private: - ServerRpcInfo(grpc::ServerContext* ctx, const char* method) - : ctx_(ctx), method_(method) { + static_assert(Type::UNARY == + static_cast(internal::RpcMethod::NORMAL_RPC), + "violated expectation about Type enum"); + static_assert(Type::CLIENT_STREAMING == + static_cast(internal::RpcMethod::CLIENT_STREAMING), + "violated expectation about Type enum"); + static_assert(Type::SERVER_STREAMING == + static_cast(internal::RpcMethod::SERVER_STREAMING), + "violated expectation about Type enum"); + static_assert(Type::BIDI_STREAMING == + static_cast(internal::RpcMethod::BIDI_STREAMING), + "violated expectation about Type enum"); + + ServerRpcInfo(grpc::ServerContext* ctx, const char* method, + internal::RpcMethod::RpcType type) + : ctx_(ctx), method_(method), type_(static_cast(type)) { ref_.store(1); } @@ -72,8 +112,11 @@ class ServerRpcInfo { std::unique_ptr>& creators) { for (const auto& creator : creators) { - interceptors_.push_back(std::unique_ptr( - creator->CreateServerInterceptor(this))); + auto* interceptor = creator->CreateServerInterceptor(this); + if (interceptor != nullptr) { + interceptors_.push_back( + std::unique_ptr(interceptor)); + } } } @@ -86,6 +129,7 @@ class ServerRpcInfo { grpc::ServerContext* ctx_ = nullptr; const char* method_ = nullptr; + const Type type_; std::atomic_int ref_; std::vector> interceptors_; diff --git a/include/grpcpp/impl/codegen/server_interface.h b/include/grpcpp/impl/codegen/server_interface.h index 55c94f4d2fa..10dc6ab7c13 100644 --- a/include/grpcpp/impl/codegen/server_interface.h +++ b/include/grpcpp/impl/codegen/server_interface.h @@ -28,14 +28,18 @@ #include #include +namespace grpc_impl { + +class CompletionQueue; +class ServerCompletionQueue; +class Channel; +class ServerCredentials; +} // namespace grpc_impl namespace grpc { class AsyncGenericService; -class Channel; class GenericServerContext; -class ServerCompletionQueue; class ServerContext; -class ServerCredentials; class Service; extern CoreCodegenInterface* g_core_codegen_interface; @@ -47,6 +51,10 @@ namespace internal { class ServerAsyncStreamingInterface; } // namespace internal +namespace experimental { +class CallbackGenericService; +} // namespace experimental + class ServerInterface : public internal::CallHook { public: virtual ~ServerInterface() {} @@ -115,6 +123,25 @@ class ServerInterface : public internal::CallHook { /// service. The service must exist for the lifetime of the Server instance. virtual void RegisterAsyncGenericService(AsyncGenericService* service) = 0; + /// NOTE: class experimental_registration_interface is not part of the public + /// API of this class + /// TODO(vjpai): Move these contents to public API when no longer experimental + class experimental_registration_interface { + public: + virtual ~experimental_registration_interface() {} + /// May not be abstract since this is a post-1.0 API addition + virtual void RegisterCallbackGenericService( + experimental::CallbackGenericService* service) {} + }; + + /// NOTE: The function experimental_registration() is not stable public API. + /// It is a view to the experimental components of this class. It may be + /// changed or removed at any time. May not be abstract since this is a + /// post-1.0 API addition + virtual experimental_registration_interface* experimental_registration() { + return nullptr; + } + /// Tries to bind \a server to the given \a addr. /// /// It can be invoked multiple times. @@ -123,11 +150,11 @@ class ServerInterface : public internal::CallHook { /// 192.168.1.1:31416, [::1]:27182, etc.). /// \params creds The credentials associated with the server. /// - /// \return bound port number on sucess, 0 on failure. + /// \return bound port number on success, 0 on failure. /// /// \warning It's an error to call this method on an already started server. virtual int AddListeningPort(const grpc::string& addr, - ServerCredentials* creds) = 0; + grpc_impl::ServerCredentials* creds) = 0; /// Start the server. /// @@ -135,7 +162,8 @@ class ServerInterface : public internal::CallHook { /// caller is required to keep all completion queues live until the server is /// destroyed. /// \param num_cqs How many completion queues does \a cqs hold. - virtual void Start(ServerCompletionQueue** cqs, size_t num_cqs) = 0; + virtual void Start(::grpc_impl::ServerCompletionQueue** cqs, + size_t num_cqs) = 0; virtual void ShutdownInternal(gpr_timespec deadline) = 0; @@ -150,9 +178,9 @@ class ServerInterface : public internal::CallHook { public: BaseAsyncRequest(ServerInterface* server, ServerContext* context, internal::ServerAsyncStreamingInterface* stream, - CompletionQueue* call_cq, - ServerCompletionQueue* notification_cq, void* tag, - bool delete_on_finalize); + ::grpc_impl::CompletionQueue* call_cq, + ::grpc_impl::ServerCompletionQueue* notification_cq, + void* tag, bool delete_on_finalize); virtual ~BaseAsyncRequest(); bool FinalizeResult(void** tag, bool* status) override; @@ -164,8 +192,8 @@ class ServerInterface : public internal::CallHook { ServerInterface* const server_; ServerContext* const context_; internal::ServerAsyncStreamingInterface* const stream_; - CompletionQueue* const call_cq_; - ServerCompletionQueue* const notification_cq_; + ::grpc_impl::CompletionQueue* const call_cq_; + ::grpc_impl::ServerCompletionQueue* const notification_cq_; void* const tag_; const bool delete_on_finalize_; grpc_call* call_; @@ -174,30 +202,33 @@ class ServerInterface : public internal::CallHook { bool done_intercepting_; }; + /// RegisteredAsyncRequest is not part of the C++ API class RegisteredAsyncRequest : public BaseAsyncRequest { public: RegisteredAsyncRequest(ServerInterface* server, ServerContext* context, internal::ServerAsyncStreamingInterface* stream, - CompletionQueue* call_cq, - ServerCompletionQueue* notification_cq, void* tag, - const char* name); + ::grpc_impl::CompletionQueue* call_cq, + ::grpc_impl::ServerCompletionQueue* notification_cq, + void* tag, const char* name, + internal::RpcMethod::RpcType type); virtual bool FinalizeResult(void** tag, bool* status) override { /* If we are done intercepting, then there is nothing more for us to do */ if (done_intercepting_) { return BaseAsyncRequest::FinalizeResult(tag, status); } - call_wrapper_ = internal::Call( + call_wrapper_ = ::grpc::internal::Call( call_, server_, call_cq_, server_->max_receive_message_size(), - context_->set_server_rpc_info(name_, + context_->set_server_rpc_info(name_, type_, *server_->interceptor_creators())); return BaseAsyncRequest::FinalizeResult(tag, status); } protected: void IssueRequest(void* registered_method, grpc_byte_buffer** payload, - ServerCompletionQueue* notification_cq); + ::grpc_impl::ServerCompletionQueue* notification_cq); const char* name_; + const internal::RpcMethod::RpcType type_; }; class NoPayloadAsyncRequest final : public RegisteredAsyncRequest { @@ -205,11 +236,12 @@ class ServerInterface : public internal::CallHook { NoPayloadAsyncRequest(internal::RpcServiceMethod* registered_method, ServerInterface* server, ServerContext* context, internal::ServerAsyncStreamingInterface* stream, - CompletionQueue* call_cq, - ServerCompletionQueue* notification_cq, void* tag) - : RegisteredAsyncRequest(server, context, stream, call_cq, - notification_cq, tag, - registered_method->name()) { + ::grpc_impl::CompletionQueue* call_cq, + ::grpc_impl::ServerCompletionQueue* notification_cq, + void* tag) + : RegisteredAsyncRequest( + server, context, stream, call_cq, notification_cq, tag, + registered_method->name(), registered_method->method_type()) { IssueRequest(registered_method->server_tag(), nullptr, notification_cq); } @@ -222,12 +254,12 @@ class ServerInterface : public internal::CallHook { PayloadAsyncRequest(internal::RpcServiceMethod* registered_method, ServerInterface* server, ServerContext* context, internal::ServerAsyncStreamingInterface* stream, - CompletionQueue* call_cq, - ServerCompletionQueue* notification_cq, void* tag, - Message* request) - : RegisteredAsyncRequest(server, context, stream, call_cq, - notification_cq, tag, - registered_method->name()), + ::grpc_impl::CompletionQueue* call_cq, + ::grpc_impl::ServerCompletionQueue* notification_cq, + void* tag, Message* request) + : RegisteredAsyncRequest( + server, context, stream, call_cq, notification_cq, tag, + registered_method->name(), registered_method->method_type()), registered_method_(registered_method), server_(server), context_(context), @@ -270,7 +302,7 @@ class ServerInterface : public internal::CallHook { /* Set interception point for recv message */ interceptor_methods_.AddInterceptionHookPoint( experimental::InterceptionHookPoints::POST_RECV_MESSAGE); - interceptor_methods_.SetRecvMessage(request_); + interceptor_methods_.SetRecvMessage(request_, nullptr); return RegisteredAsyncRequest::FinalizeResult(tag, status); } @@ -279,9 +311,9 @@ class ServerInterface : public internal::CallHook { ServerInterface* const server_; ServerContext* const context_; internal::ServerAsyncStreamingInterface* const stream_; - CompletionQueue* const call_cq_; + ::grpc_impl::CompletionQueue* const call_cq_; - ServerCompletionQueue* const notification_cq_; + ::grpc_impl::ServerCompletionQueue* const notification_cq_; void* const tag_; Message* const request_; ByteBuffer payload_; @@ -291,9 +323,9 @@ class ServerInterface : public internal::CallHook { public: GenericAsyncRequest(ServerInterface* server, GenericServerContext* context, internal::ServerAsyncStreamingInterface* stream, - CompletionQueue* call_cq, - ServerCompletionQueue* notification_cq, void* tag, - bool delete_on_finalize); + ::grpc_impl::CompletionQueue* call_cq, + ::grpc_impl::ServerCompletionQueue* notification_cq, + void* tag, bool delete_on_finalize); bool FinalizeResult(void** tag, bool* status) override; @@ -305,9 +337,9 @@ class ServerInterface : public internal::CallHook { void RequestAsyncCall(internal::RpcServiceMethod* method, ServerContext* context, internal::ServerAsyncStreamingInterface* stream, - CompletionQueue* call_cq, - ServerCompletionQueue* notification_cq, void* tag, - Message* message) { + ::grpc_impl::CompletionQueue* call_cq, + ::grpc_impl::ServerCompletionQueue* notification_cq, + void* tag, Message* message) { GPR_CODEGEN_ASSERT(method); new PayloadAsyncRequest(method, this, context, stream, call_cq, notification_cq, tag, message); @@ -316,18 +348,19 @@ class ServerInterface : public internal::CallHook { void RequestAsyncCall(internal::RpcServiceMethod* method, ServerContext* context, internal::ServerAsyncStreamingInterface* stream, - CompletionQueue* call_cq, - ServerCompletionQueue* notification_cq, void* tag) { + ::grpc_impl::CompletionQueue* call_cq, + ::grpc_impl::ServerCompletionQueue* notification_cq, + void* tag) { GPR_CODEGEN_ASSERT(method); new NoPayloadAsyncRequest(method, this, context, stream, call_cq, notification_cq, tag); } - void RequestAsyncGenericCall(GenericServerContext* context, - internal::ServerAsyncStreamingInterface* stream, - CompletionQueue* call_cq, - ServerCompletionQueue* notification_cq, - void* tag) { + void RequestAsyncGenericCall( + GenericServerContext* context, + internal::ServerAsyncStreamingInterface* stream, + ::grpc_impl::CompletionQueue* call_cq, + ::grpc_impl::ServerCompletionQueue* notification_cq, void* tag) { new GenericAsyncRequest(this, context, stream, call_cq, notification_cq, tag, true); } @@ -352,7 +385,7 @@ class ServerInterface : public internal::CallHook { // Returns nullptr (rather than being pure) since this is a post-1.0 method // and adding a new pure method to an interface would be a breaking change // (even though this is private and non-API) - virtual CompletionQueue* CallbackCQ() { return nullptr; } + virtual ::grpc_impl::CompletionQueue* CallbackCQ() { return nullptr; } }; } // namespace grpc diff --git a/include/grpcpp/impl/codegen/service_type.h b/include/grpcpp/impl/codegen/service_type.h index 332a04c294f..f1d1272dc20 100644 --- a/include/grpcpp/impl/codegen/service_type.h +++ b/include/grpcpp/impl/codegen/service_type.h @@ -26,12 +26,14 @@ #include #include +namespace grpc_impl { + +class Server; +class CompletionQueue; +} // namespace grpc_impl namespace grpc { -class CompletionQueue; -class Server; class ServerInterface; -class ServerCompletionQueue; class ServerContext; namespace internal { @@ -132,6 +134,11 @@ class Service { internal::RpcServiceMethod::ApiType::RAW_CALL_BACK); } + internal::MethodHandler* GetHandler(int index) { + size_t idx = static_cast(index); + return service_->methods_[idx]->handler(); + } + private: Service* service_; }; @@ -228,7 +235,7 @@ class Service { } private: - friend class Server; + friend class grpc_impl::Server; friend class ServerInterface; ServerInterface* server_; std::vector> methods_; diff --git a/include/grpcpp/impl/codegen/status_code_enum.h b/include/grpcpp/impl/codegen/status_code_enum.h index 09943f10de8..bdd7ead6add 100644 --- a/include/grpcpp/impl/codegen/status_code_enum.h +++ b/include/grpcpp/impl/codegen/status_code_enum.h @@ -119,7 +119,8 @@ enum StatusCode { INTERNAL = 13, /// The service is currently unavailable. This is a most likely a transient - /// condition and may be corrected by retrying with a backoff. + /// condition and may be corrected by retrying with a backoff. Note that it is + /// not always safe to retry non-idempotent operations. /// /// \warning Although data MIGHT not have been transmitted when this /// status occurs, there is NOT A GUARANTEE that the server has not seen diff --git a/include/grpcpp/impl/codegen/sync.h b/include/grpcpp/impl/codegen/sync.h new file mode 100644 index 00000000000..146f182e57b --- /dev/null +++ b/include/grpcpp/impl/codegen/sync.h @@ -0,0 +1,151 @@ +/* + * + * Copyright 2019 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_SYNC_H +#define GRPCPP_IMPL_CODEGEN_SYNC_H + +#include + +#ifdef GPR_HAS_PTHREAD_H +#include +#endif + +#include + +#include +#include + +#include + +// The core library is not accessible in C++ codegen headers, and vice versa. +// Thus, we need to have duplicate headers with similar functionality. +// Make sure any change to this file is also reflected in +// src/core/lib/gprpp/sync.h too. +// +// Whenever possible, prefer "src/core/lib/gprpp/sync.h" over this file, +// since in core we do not rely on g_core_codegen_interface and hence do not +// pay the costs of virtual function calls. + +namespace grpc { +namespace internal { + +class Mutex { + public: + Mutex() { g_core_codegen_interface->gpr_mu_init(&mu_); } + ~Mutex() { g_core_codegen_interface->gpr_mu_destroy(&mu_); } + + Mutex(const Mutex&) = delete; + Mutex& operator=(const Mutex&) = delete; + + gpr_mu* get() { return &mu_; } + const gpr_mu* get() const { return &mu_; } + + private: + union { + gpr_mu mu_; + std::mutex do_not_use_sth_; +#ifdef GPR_HAS_PTHREAD_H + pthread_mutex_t do_not_use_pth_; +#endif + }; +}; + +// MutexLock is a std:: +class MutexLock { + public: + explicit MutexLock(Mutex* mu) : mu_(mu->get()) { + g_core_codegen_interface->gpr_mu_lock(mu_); + } + explicit MutexLock(gpr_mu* mu) : mu_(mu) { + g_core_codegen_interface->gpr_mu_lock(mu_); + } + ~MutexLock() { g_core_codegen_interface->gpr_mu_unlock(mu_); } + + MutexLock(const MutexLock&) = delete; + MutexLock& operator=(const MutexLock&) = delete; + + private: + gpr_mu* const mu_; +}; + +class ReleasableMutexLock { + public: + explicit ReleasableMutexLock(Mutex* mu) : mu_(mu->get()) { + g_core_codegen_interface->gpr_mu_lock(mu_); + } + explicit ReleasableMutexLock(gpr_mu* mu) : mu_(mu) { + g_core_codegen_interface->gpr_mu_lock(mu_); + } + ~ReleasableMutexLock() { + if (!released_) g_core_codegen_interface->gpr_mu_unlock(mu_); + } + + ReleasableMutexLock(const ReleasableMutexLock&) = delete; + ReleasableMutexLock& operator=(const ReleasableMutexLock&) = delete; + + void Lock() { + GPR_DEBUG_ASSERT(released_); + g_core_codegen_interface->gpr_mu_lock(mu_); + released_ = false; + } + + void Unlock() { + GPR_DEBUG_ASSERT(!released_); + released_ = true; + g_core_codegen_interface->gpr_mu_unlock(mu_); + } + + private: + gpr_mu* const mu_; + bool released_ = false; +}; + +class CondVar { + public: + CondVar() { g_core_codegen_interface->gpr_cv_init(&cv_); } + ~CondVar() { g_core_codegen_interface->gpr_cv_destroy(&cv_); } + + CondVar(const CondVar&) = delete; + CondVar& operator=(const CondVar&) = delete; + + void Signal() { g_core_codegen_interface->gpr_cv_signal(&cv_); } + void Broadcast() { g_core_codegen_interface->gpr_cv_broadcast(&cv_); } + + int Wait(Mutex* mu) { + return Wait(mu, + g_core_codegen_interface->gpr_inf_future(GPR_CLOCK_REALTIME)); + } + int Wait(Mutex* mu, const gpr_timespec& deadline) { + return g_core_codegen_interface->gpr_cv_wait(&cv_, mu->get(), deadline); + } + + template + void WaitUntil(Mutex* mu, Predicate pred) { + while (!pred()) { + Wait(mu, g_core_codegen_interface->gpr_inf_future(GPR_CLOCK_REALTIME)); + } + } + + private: + gpr_cv cv_; +}; + +} // namespace internal +} // namespace grpc + +#endif // GRPCPP_IMPL_CODEGEN_SYNC_H diff --git a/include/grpcpp/impl/codegen/sync_stream.h b/include/grpcpp/impl/codegen/sync_stream.h index 6981076f04e..0d3fdfcb8dc 100644 --- a/include/grpcpp/impl/codegen/sync_stream.h +++ b/include/grpcpp/impl/codegen/sync_stream.h @@ -180,7 +180,7 @@ class ClientReader final : public ClientReaderInterface { /// // Side effect: /// Once complete, the initial metadata read from - /// the server will be accessable through the \a ClientContext used to + /// the server will be accessible through the \a ClientContext used to /// construct this object. void WaitForInitialMetadata() override { GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_); @@ -253,7 +253,7 @@ class ClientReader final : public ClientReaderInterface { ops.SendInitialMetadata(&context->send_initial_metadata_, context->initial_metadata_flags()); // TODO(ctiller): don't assert - GPR_CODEGEN_ASSERT(ops.SendMessage(request).ok()); + GPR_CODEGEN_ASSERT(ops.SendMessagePtr(&request).ok()); ops.ClientSendClose(); call_.PerformOps(&ops); cq_.Pluck(&ops); @@ -298,7 +298,7 @@ class ClientWriter : public ClientWriterInterface { /// // Side effect: /// Once complete, the initial metadata read from the server will be - /// accessable through the \a ClientContext used to construct this object. + /// accessible through the \a ClientContext used to construct this object. void WaitForInitialMetadata() { GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_); @@ -331,7 +331,7 @@ class ClientWriter : public ClientWriterInterface { context_->initial_metadata_flags()); context_->set_initial_metadata_corked(false); } - if (!ops.SendMessage(msg, options).ok()) { + if (!ops.SendMessagePtr(&msg, options).ok()) { return false; } @@ -449,7 +449,7 @@ class ClientReaderWriter final : public ClientReaderWriterInterface { /// with or after the \a Finish method. /// /// Once complete, the initial metadata read from the server will be - /// accessable through the \a ClientContext used to construct this object. + /// accessible through the \a ClientContext used to construct this object. void WaitForInitialMetadata() override { GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_); @@ -502,7 +502,7 @@ class ClientReaderWriter final : public ClientReaderWriterInterface { context_->initial_metadata_flags()); context_->set_initial_metadata_corked(false); } - if (!ops.SendMessage(msg, options).ok()) { + if (!ops.SendMessagePtr(&msg, options).ok()) { return false; } @@ -656,7 +656,7 @@ class ServerWriter final : public ServerWriterInterface { options.set_buffer_hint(); } - if (!ctx_->pending_ops_.SendMessage(msg, options).ok()) { + if (!ctx_->pending_ops_.SendMessagePtr(&msg, options).ok()) { return false; } if (!ctx_->sent_initial_metadata_) { @@ -734,7 +734,7 @@ class ServerReaderWriterBody final { if (options.is_last_message()) { options.set_buffer_hint(); } - if (!ctx_->pending_ops_.SendMessage(msg, options).ok()) { + if (!ctx_->pending_ops_.SendMessagePtr(&msg, options).ok()) { return false; } if (!ctx_->sent_initial_metadata_) { diff --git a/include/grpcpp/impl/grpc_library.h b/include/grpcpp/impl/grpc_library.h index d1f3ff1297b..3711c098790 100644 --- a/include/grpcpp/impl/grpc_library.h +++ b/include/grpcpp/impl/grpc_library.h @@ -35,18 +35,17 @@ class GrpcLibrary final : public GrpcLibraryInterface { void shutdown() override { grpc_shutdown(); } }; -static GrpcLibrary g_gli; -static CoreCodegen g_core_codegen; - /// Instantiating this class ensures the proper initialization of gRPC. class GrpcLibraryInitializer final { public: GrpcLibraryInitializer() { if (grpc::g_glip == nullptr) { - grpc::g_glip = &g_gli; + static auto* const g_gli = new GrpcLibrary(); + grpc::g_glip = g_gli; } if (grpc::g_core_codegen_interface == nullptr) { - grpc::g_core_codegen_interface = &g_core_codegen; + static auto* const g_core_codegen = new CoreCodegen(); + grpc::g_core_codegen_interface = g_core_codegen; } } diff --git a/include/grpcpp/impl/server_builder_option.h b/include/grpcpp/impl/server_builder_option.h index c7b7801dab3..4b3d6b54118 100644 --- a/include/grpcpp/impl/server_builder_option.h +++ b/include/grpcpp/impl/server_builder_option.h @@ -1,6 +1,6 @@ /* * - * Copyright 2015 gRPC authors. + * Copyright 2019 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,24 +19,11 @@ #ifndef GRPCPP_IMPL_SERVER_BUILDER_OPTION_H #define GRPCPP_IMPL_SERVER_BUILDER_OPTION_H -#include -#include - -#include -#include +#include namespace grpc { -/// Interface to pass an option to a \a ServerBuilder. -class ServerBuilderOption { - public: - virtual ~ServerBuilderOption() {} - /// Alter the \a ChannelArguments used to create the gRPC server. - virtual void UpdateArguments(ChannelArguments* args) = 0; - /// Alter the ServerBuilderPlugin map that will be added into ServerBuilder. - virtual void UpdatePlugins( - std::vector>* plugins) = 0; -}; +typedef ::grpc_impl::ServerBuilderOption ServerBuilderOption; } // namespace grpc diff --git a/include/grpcpp/impl/server_builder_option_impl.h b/include/grpcpp/impl/server_builder_option_impl.h new file mode 100644 index 00000000000..8271d0f56b2 --- /dev/null +++ b/include/grpcpp/impl/server_builder_option_impl.h @@ -0,0 +1,43 @@ +/* + * + * 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_SERVER_BUILDER_OPTION_IMPL_H +#define GRPCPP_IMPL_SERVER_BUILDER_OPTION_IMPL_H + +#include +#include + +#include +#include + +namespace grpc_impl { + +/// Interface to pass an option to a \a ServerBuilder. +class ServerBuilderOption { + public: + virtual ~ServerBuilderOption() {} + /// Alter the \a ChannelArguments used to create the gRPC server. + virtual void UpdateArguments(grpc::ChannelArguments* args) = 0; + /// Alter the ServerBuilderPlugin map that will be added into ServerBuilder. + virtual void UpdatePlugins( + std::vector>* plugins) = 0; +}; + +} // namespace grpc_impl + +#endif // GRPCPP_IMPL_SERVER_BUILDER_OPTION_IMPL_H diff --git a/include/grpcpp/impl/server_builder_plugin.h b/include/grpcpp/impl/server_builder_plugin.h index 39450b42d56..84a88f2dd7b 100644 --- a/include/grpcpp/impl/server_builder_plugin.h +++ b/include/grpcpp/impl/server_builder_plugin.h @@ -23,11 +23,13 @@ #include -namespace grpc { +namespace grpc_impl { +class ChannelArguments; class ServerBuilder; class ServerInitializer; -class ChannelArguments; +} // namespace grpc_impl +namespace grpc { /// This interface is meant for internal usage only. Implementations of this /// interface should add themselves to a \a ServerBuilder instance through the @@ -40,14 +42,14 @@ class ServerBuilderPlugin { /// UpdateServerBuilder will be called at an early stage in /// ServerBuilder::BuildAndStart(), right after the ServerBuilderOptions have /// done their updates. - virtual void UpdateServerBuilder(ServerBuilder* builder) {} + virtual void UpdateServerBuilder(grpc_impl::ServerBuilder* builder) {} /// InitServer will be called in ServerBuilder::BuildAndStart(), after the /// Server instance is created. - virtual void InitServer(ServerInitializer* si) = 0; + virtual void InitServer(grpc_impl::ServerInitializer* si) = 0; /// Finish will be called at the end of ServerBuilder::BuildAndStart(). - virtual void Finish(ServerInitializer* si) = 0; + virtual void Finish(grpc_impl::ServerInitializer* si) = 0; /// ChangeArguments is an interface that can be used in /// ServerBuilderOption::UpdatePlugins @@ -55,7 +57,7 @@ class ServerBuilderPlugin { /// UpdateChannelArguments will be called in ServerBuilder::BuildAndStart(), /// before the Server instance is created. - virtual void UpdateChannelArguments(ChannelArguments* args) {} + virtual void UpdateChannelArguments(grpc_impl::ChannelArguments* args) {} virtual bool has_sync_methods() const { return false; } virtual bool has_async_methods() const { return false; } diff --git a/include/grpcpp/impl/server_initializer.h b/include/grpcpp/impl/server_initializer.h index f949fabfe6f..d40bb98feb6 100644 --- a/include/grpcpp/impl/server_initializer.h +++ b/include/grpcpp/impl/server_initializer.h @@ -1,6 +1,6 @@ /* * - * Copyright 2016 gRPC authors. + * Copyright 2019 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,36 +19,11 @@ #ifndef GRPCPP_IMPL_SERVER_INITIALIZER_H #define GRPCPP_IMPL_SERVER_INITIALIZER_H -#include -#include - -#include +#include namespace grpc { -class Server; -class Service; - -class ServerInitializer { - public: - ServerInitializer(Server* server) : server_(server) {} - - bool RegisterService(std::shared_ptr service) { - if (!server_->RegisterService(nullptr, service.get())) { - return false; - } - default_services_.push_back(service); - return true; - } - - const std::vector* GetServiceList() { - return &server_->services_; - } - - private: - Server* server_; - std::vector > default_services_; -}; +typedef ::grpc_impl::ServerInitializer ServerInitializer; } // namespace grpc diff --git a/include/grpcpp/impl/server_initializer_impl.h b/include/grpcpp/impl/server_initializer_impl.h new file mode 100644 index 00000000000..0e2c65f4af4 --- /dev/null +++ b/include/grpcpp/impl/server_initializer_impl.h @@ -0,0 +1,57 @@ +/* + * + * 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. + * + */ + +#ifndef GRPCPP_IMPL_SERVER_INITIALIZER_IMPL_H +#define GRPCPP_IMPL_SERVER_INITIALIZER_IMPL_H + +#include +#include + +#include + +namespace grpc { + +class Service; +} // namespace grpc +namespace grpc_impl { +class Server; + +class ServerInitializer { + public: + ServerInitializer(grpc::Server* server) : server_(server) {} + + bool RegisterService(std::shared_ptr service) { + if (!server_->RegisterService(nullptr, service.get())) { + return false; + } + default_services_.push_back(service); + return true; + } + + const std::vector* GetServiceList() { + return &server_->services_; + } + + private: + grpc::Server* server_; + std::vector > default_services_; +}; + +} // namespace grpc_impl + +#endif // GRPCPP_IMPL_SERVER_INITIALIZER_IMPL_H diff --git a/include/grpcpp/opencensus.h b/include/grpcpp/opencensus.h index 29b221f7674..14c6add1d9e 100644 --- a/include/grpcpp/opencensus.h +++ b/include/grpcpp/opencensus.h @@ -19,29 +19,20 @@ #ifndef GRPCPP_OPENCENSUS_H #define GRPCPP_OPENCENSUS_H -#include "opencensus/trace/span.h" +#include "grpcpp/opencensus_impl.h" namespace grpc { -// These symbols in this file will not be included in the binary unless -// grpc_opencensus_plugin build target was added as a dependency. At the moment -// it is only setup to be built with Bazel. -// Registers the OpenCensus plugin with gRPC, so that it will be used for future -// RPCs. This must be called before any views are created. -void RegisterOpenCensusPlugin(); - -// RPC stats definitions, defined by -// https://github.com/census-instrumentation/opencensus-specs/blob/master/stats/gRPC.md - -// Registers the cumulative gRPC views so that they will be exported by any -// registered stats exporter. For on-task stats, construct a View using the -// ViewDescriptors below. -void RegisterOpenCensusViewsForExport(); - -class ServerContext; - -// Returns the tracing Span for the current RPC. -::opencensus::trace::Span GetSpanFromServerContext(ServerContext* context); +static inline void RegisterOpenCensusPlugin() { + ::grpc_impl::RegisterOpenCensusPlugin(); +} +static inline void RegisterOpenCensusViewsForExport() { + ::grpc_impl::RegisterOpenCensusViewsForExport(); +} +static inline ::opencensus::trace::Span GetSpanFromServerContext( + ServerContext* context) { + return ::grpc_impl::GetSpanFromServerContext(context); +} } // namespace grpc diff --git a/include/grpcpp/opencensus_impl.h b/include/grpcpp/opencensus_impl.h new file mode 100644 index 00000000000..631d2b861fd --- /dev/null +++ b/include/grpcpp/opencensus_impl.h @@ -0,0 +1,51 @@ +/* + * + * Copyright 2019 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_OPENCENSUS_IMPL_H +#define GRPCPP_OPENCENSUS_IMPL_H + +#include "opencensus/trace/span.h" + +namespace grpc { + +class ServerContext; +} +namespace grpc_impl { +// These symbols in this file will not be included in the binary unless +// grpc_opencensus_plugin build target was added as a dependency. At the moment +// it is only setup to be built with Bazel. + +// Registers the OpenCensus plugin with gRPC, so that it will be used for future +// RPCs. This must be called before any views are created. +void RegisterOpenCensusPlugin(); + +// RPC stats definitions, defined by +// https://github.com/census-instrumentation/opencensus-specs/blob/master/stats/gRPC.md + +// Registers the cumulative gRPC views so that they will be exported by any +// registered stats exporter. For on-task stats, construct a View using the +// ViewDescriptors below. +void RegisterOpenCensusViewsForExport(); + +// Returns the tracing Span for the current RPC. +::opencensus::trace::Span GetSpanFromServerContext( + grpc::ServerContext* context); + +} // namespace grpc_impl + +#endif // GRPCPP_OPENCENSUS_IMPL_H diff --git a/include/grpcpp/resource_quota.h b/include/grpcpp/resource_quota.h index 50bd1cb849a..333767b95c5 100644 --- a/include/grpcpp/resource_quota.h +++ b/include/grpcpp/resource_quota.h @@ -1,6 +1,6 @@ /* * - * Copyright 2016 gRPC authors. + * Copyright 2019 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,50 +19,11 @@ #ifndef GRPCPP_RESOURCE_QUOTA_H #define GRPCPP_RESOURCE_QUOTA_H -struct grpc_resource_quota; - -#include -#include +#include namespace grpc { -/// ResourceQuota represents a bound on memory and thread usage by the gRPC -/// library. A ResourceQuota can be attached to a server (via \a ServerBuilder), -/// or a client channel (via \a ChannelArguments). -/// gRPC will attempt to keep memory and threads used by all attached entities -/// below the ResourceQuota bound. -class ResourceQuota final : private GrpcLibraryCodegen { - public: - /// \param name - a unique name for this ResourceQuota. - explicit ResourceQuota(const grpc::string& name); - ResourceQuota(); - ~ResourceQuota(); - - /// Resize this \a ResourceQuota to a new size. If \a new_size is smaller - /// than the current size of the pool, memory usage will be monotonically - /// decreased until it falls under \a new_size. - /// No time bound is given for this to occur however. - ResourceQuota& Resize(size_t new_size); - - /// Set the max number of threads that can be allocated from this - /// ResourceQuota object. - /// - /// If the new_max_threads value is smaller than the current value, no new - /// threads are allocated until the number of active threads fall below - /// new_max_threads. There is no time bound on when this may happen i.e none - /// of the current threads are forcefully destroyed and all threads run their - /// normal course. - ResourceQuota& SetMaxThreads(int new_max_threads); - - grpc_resource_quota* c_resource_quota() const { return impl_; } - - private: - ResourceQuota(const ResourceQuota& rhs); - ResourceQuota& operator=(const ResourceQuota& rhs); - - grpc_resource_quota* const impl_; -}; - +typedef ::grpc_impl::ResourceQuota ResourceQuota; } // namespace grpc #endif // GRPCPP_RESOURCE_QUOTA_H diff --git a/include/grpcpp/resource_quota_impl.h b/include/grpcpp/resource_quota_impl.h new file mode 100644 index 00000000000..16c0e35385b --- /dev/null +++ b/include/grpcpp/resource_quota_impl.h @@ -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. + * + */ + +#ifndef GRPCPP_RESOURCE_QUOTA_IMPL_H +#define GRPCPP_RESOURCE_QUOTA_IMPL_H + +struct grpc_resource_quota; + +#include +#include + +namespace grpc_impl { + +/// ResourceQuota represents a bound on memory and thread usage by the gRPC +/// library. A ResourceQuota can be attached to a server (via \a ServerBuilder), +/// or a client channel (via \a ChannelArguments). +/// gRPC will attempt to keep memory and threads used by all attached entities +/// below the ResourceQuota bound. +class ResourceQuota final : private ::grpc::GrpcLibraryCodegen { + public: + /// \param name - a unique name for this ResourceQuota. + explicit ResourceQuota(const grpc::string& name); + ResourceQuota(); + ~ResourceQuota(); + + /// Resize this \a ResourceQuota to a new size. If \a new_size is smaller + /// than the current size of the pool, memory usage will be monotonically + /// decreased until it falls under \a new_size. + /// No time bound is given for this to occur however. + ResourceQuota& Resize(size_t new_size); + + /// Set the max number of threads that can be allocated from this + /// ResourceQuota object. + /// + /// If the new_max_threads value is smaller than the current value, no new + /// threads are allocated until the number of active threads fall below + /// new_max_threads. There is no time bound on when this may happen i.e none + /// of the current threads are forcefully destroyed and all threads run their + /// normal course. + ResourceQuota& SetMaxThreads(int new_max_threads); + + grpc_resource_quota* c_resource_quota() const { return impl_; } + + private: + ResourceQuota(const ResourceQuota& rhs); + ResourceQuota& operator=(const ResourceQuota& rhs); + + grpc_resource_quota* const impl_; +}; + +} // namespace grpc_impl + +#endif // GRPCPP_RESOURCE_QUOTA_IMPL_H diff --git a/include/grpcpp/security/auth_metadata_processor.h b/include/grpcpp/security/auth_metadata_processor.h index 30e24c9f0bc..1b66b72b967 100644 --- a/include/grpcpp/security/auth_metadata_processor.h +++ b/include/grpcpp/security/auth_metadata_processor.h @@ -1,6 +1,6 @@ /* * - * Copyright 2015 gRPC authors. + * Copyright 2019 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,42 +19,11 @@ #ifndef GRPCPP_SECURITY_AUTH_METADATA_PROCESSOR_H #define GRPCPP_SECURITY_AUTH_METADATA_PROCESSOR_H -#include - -#include -#include -#include +#include namespace grpc { -/// Interface allowing custom server-side authorization based on credentials -/// encoded in metadata. Objects of this type can be passed to -/// \a ServerCredentials::SetAuthMetadataProcessor(). -class AuthMetadataProcessor { - public: - typedef std::multimap InputMetadata; - typedef std::multimap OutputMetadata; - - virtual ~AuthMetadataProcessor() {} - - /// If this method returns true, the \a Process function will be scheduled in - /// a different thread from the one processing the call. - virtual bool IsBlocking() const { return true; } - - /// context is read/write: it contains the properties of the channel peer and - /// it is the job of the Process method to augment it with properties derived - /// from the passed-in auth_metadata. - /// consumed_auth_metadata needs to be filled with metadata that has been - /// consumed by the processor and will be removed from the call. - /// response_metadata is the metadata that will be sent as part of the - /// response. - /// If the return value is not Status::OK, the rpc call will be aborted with - /// the error code and error message sent back to the client. - virtual Status Process(const InputMetadata& auth_metadata, - AuthContext* context, - OutputMetadata* consumed_auth_metadata, - OutputMetadata* response_metadata) = 0; -}; +typedef ::grpc_impl::AuthMetadataProcessor AuthMetadataProcessor; } // namespace grpc diff --git a/include/grpcpp/security/auth_metadata_processor_impl.h b/include/grpcpp/security/auth_metadata_processor_impl.h new file mode 100644 index 00000000000..ae454200622 --- /dev/null +++ b/include/grpcpp/security/auth_metadata_processor_impl.h @@ -0,0 +1,61 @@ +/* + * + * 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_SECURITY_AUTH_METADATA_PROCESSOR_IMPL_H +#define GRPCPP_SECURITY_AUTH_METADATA_PROCESSOR_IMPL_H + +#include + +#include +#include +#include + +namespace grpc_impl { + +/// Interface allowing custom server-side authorization based on credentials +/// encoded in metadata. Objects of this type can be passed to +/// \a ServerCredentials::SetAuthMetadataProcessor(). +class AuthMetadataProcessor { + public: + typedef std::multimap InputMetadata; + typedef std::multimap OutputMetadata; + + virtual ~AuthMetadataProcessor() {} + + /// If this method returns true, the \a Process function will be scheduled in + /// a different thread from the one processing the call. + virtual bool IsBlocking() const { return true; } + + /// context is read/write: it contains the properties of the channel peer and + /// it is the job of the Process method to augment it with properties derived + /// from the passed-in auth_metadata. + /// consumed_auth_metadata needs to be filled with metadata that has been + /// consumed by the processor and will be removed from the call. + /// response_metadata is the metadata that will be sent as part of the + /// response. + /// If the return value is not Status::OK, the rpc call will be aborted with + /// the error code and error message sent back to the client. + virtual grpc::Status Process(const InputMetadata& auth_metadata, + grpc::AuthContext* context, + OutputMetadata* consumed_auth_metadata, + OutputMetadata* response_metadata) = 0; +}; + +} // namespace grpc_impl + +#endif // GRPCPP_SECURITY_AUTH_METADATA_PROCESSOR_IMPL_H diff --git a/include/grpcpp/security/credentials.h b/include/grpcpp/security/credentials.h index d8c9e04d778..e924275d592 100644 --- a/include/grpcpp/security/credentials.h +++ b/include/grpcpp/security/credentials.h @@ -19,257 +19,104 @@ #ifndef GRPCPP_SECURITY_CREDENTIALS_H #define GRPCPP_SECURITY_CREDENTIALS_H -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -struct grpc_call; +#include namespace grpc { -class ChannelArguments; -class Channel; -class SecureChannelCredentials; -class CallCredentials; -class SecureCallCredentials; -class ChannelCredentials; +typedef ::grpc_impl::ChannelCredentials ChannelCredentials; +typedef ::grpc_impl::CallCredentials CallCredentials; +typedef ::grpc_impl::SslCredentialsOptions SslCredentialsOptions; +typedef ::grpc_impl::SecureCallCredentials SecureCallCredentials; +typedef ::grpc_impl::SecureChannelCredentials SecureChannelCredentials; -namespace experimental { -std::shared_ptr CreateCustomChannelWithInterceptors( - const grpc::string& target, - const std::shared_ptr& creds, - const ChannelArguments& args, - std::vector< - std::unique_ptr> - interceptor_creators); -} // namespace experimental +static inline std::shared_ptr +GoogleDefaultCredentials() { + return ::grpc_impl::GoogleDefaultCredentials(); +} -/// A channel credentials object encapsulates all the state needed by a client -/// to authenticate with a server for a given channel. -/// It can make various assertions, e.g., about the client’s identity, role -/// for all the calls on that channel. -/// -/// \see https://grpc.io/docs/guides/auth.html -class ChannelCredentials : private GrpcLibraryCodegen { - public: - ChannelCredentials(); - ~ChannelCredentials(); +static inline std::shared_ptr SslCredentials( + const SslCredentialsOptions& options) { + return ::grpc_impl::SslCredentials(options); +} - protected: - friend std::shared_ptr CompositeChannelCredentials( - const std::shared_ptr& channel_creds, - const std::shared_ptr& call_creds); - - virtual SecureChannelCredentials* AsSecureCredentials() = 0; - - private: - friend std::shared_ptr CreateCustomChannel( - const grpc::string& target, - const std::shared_ptr& creds, - const ChannelArguments& args); - - friend std::shared_ptr - experimental::CreateCustomChannelWithInterceptors( - const grpc::string& target, - const std::shared_ptr& creds, - const ChannelArguments& args, - std::vector< - std::unique_ptr> - interceptor_creators); - - virtual std::shared_ptr CreateChannel( - const grpc::string& target, const ChannelArguments& args) = 0; - - // This function should have been a pure virtual function, but it is - // implemented as a virtual function so that it does not break API. - virtual std::shared_ptr CreateChannelWithInterceptors( - const grpc::string& target, const ChannelArguments& args, - std::vector< - std::unique_ptr> - interceptor_creators) { - return nullptr; - }; -}; - -/// A call credentials object encapsulates the state needed by a client to -/// authenticate with a server for a given call on a channel. -/// -/// \see https://grpc.io/docs/guides/auth.html -class CallCredentials : private GrpcLibraryCodegen { - public: - CallCredentials(); - ~CallCredentials(); - - /// Apply this instance's credentials to \a call. - virtual bool ApplyToCall(grpc_call* call) = 0; - - protected: - friend std::shared_ptr CompositeChannelCredentials( - const std::shared_ptr& channel_creds, - const std::shared_ptr& call_creds); - - friend std::shared_ptr CompositeCallCredentials( - const std::shared_ptr& creds1, - const std::shared_ptr& creds2); - - virtual SecureCallCredentials* AsSecureCredentials() = 0; -}; - -/// Options used to build SslCredentials. -struct SslCredentialsOptions { - /// The buffer containing the PEM encoding of the server root certificates. If - /// this parameter is empty, the default roots will be used. The default - /// roots can be overridden using the \a GRPC_DEFAULT_SSL_ROOTS_FILE_PATH - /// environment variable pointing to a file on the file system containing the - /// roots. - grpc::string pem_root_certs; - - /// The buffer containing the PEM encoding of the client's private key. This - /// parameter can be empty if the client does not have a private key. - grpc::string pem_private_key; - - /// The buffer containing the PEM encoding of the client's certificate chain. - /// This parameter can be empty if the client does not have a certificate - /// chain. - grpc::string pem_cert_chain; -}; - -// Factories for building different types of Credentials The functions may -// return empty shared_ptr when credentials cannot be created. If a -// Credentials pointer is returned, it can still be invalid when used to create -// a channel. A lame channel will be created then and all rpcs will fail on it. - -/// Builds credentials with reasonable defaults. -/// -/// \warning Only use these credentials when connecting to a Google endpoint. -/// Using these credentials to connect to any other service may result in this -/// service being able to impersonate your client for requests to Google -/// services. -std::shared_ptr GoogleDefaultCredentials(); - -/// Builds SSL Credentials given SSL specific options -std::shared_ptr SslCredentials( - const SslCredentialsOptions& options); - -/// Builds credentials for use when running in GCE -/// -/// \warning Only use these credentials when connecting to a Google endpoint. -/// Using these credentials to connect to any other service may result in this -/// service being able to impersonate your client for requests to Google -/// services. -std::shared_ptr GoogleComputeEngineCredentials(); +static inline std::shared_ptr +GoogleComputeEngineCredentials() { + return ::grpc_impl::GoogleComputeEngineCredentials(); +} /// Constant for maximum auth token lifetime. -constexpr long kMaxAuthTokenLifetimeSecs = 3600; +constexpr long kMaxAuthTokenLifetimeSecs = + ::grpc_impl::kMaxAuthTokenLifetimeSecs; -/// Builds Service Account JWT Access credentials. -/// json_key is the JSON key string containing the client's private key. -/// token_lifetime_seconds is the lifetime in seconds of each Json Web Token -/// (JWT) created with this credentials. It should not exceed -/// \a kMaxAuthTokenLifetimeSecs or will be cropped to this value. -std::shared_ptr ServiceAccountJWTAccessCredentials( +static inline std::shared_ptr +ServiceAccountJWTAccessCredentials( const grpc::string& json_key, - long token_lifetime_seconds = kMaxAuthTokenLifetimeSecs); + long token_lifetime_seconds = grpc::kMaxAuthTokenLifetimeSecs) { + return ::grpc_impl::ServiceAccountJWTAccessCredentials( + json_key, token_lifetime_seconds); +} -/// Builds refresh token credentials. -/// json_refresh_token is the JSON string containing the refresh token along -/// with a client_id and client_secret. -/// -/// \warning Only use these credentials when connecting to a Google endpoint. -/// Using these credentials to connect to any other service may result in this -/// service being able to impersonate your client for requests to Google -/// services. -std::shared_ptr GoogleRefreshTokenCredentials( - const grpc::string& json_refresh_token); +static inline std::shared_ptr +GoogleRefreshTokenCredentials(const grpc::string& json_refresh_token) { + return ::grpc_impl::GoogleRefreshTokenCredentials(json_refresh_token); +} -/// Builds access token credentials. -/// access_token is an oauth2 access token that was fetched using an out of band -/// mechanism. -/// -/// \warning Only use these credentials when connecting to a Google endpoint. -/// Using these credentials to connect to any other service may result in this -/// service being able to impersonate your client for requests to Google -/// services. -std::shared_ptr AccessTokenCredentials( - const grpc::string& access_token); +static inline std::shared_ptr +AccessTokenCredentials(const grpc::string& access_token) { + return ::grpc_impl::AccessTokenCredentials(access_token); +} -/// Builds IAM credentials. -/// -/// \warning Only use these credentials when connecting to a Google endpoint. -/// Using these credentials to connect to any other service may result in this -/// service being able to impersonate your client for requests to Google -/// services. -std::shared_ptr GoogleIAMCredentials( +static inline std::shared_ptr GoogleIAMCredentials( const grpc::string& authorization_token, - const grpc::string& authority_selector); + const grpc::string& authority_selector) { + return ::grpc_impl::GoogleIAMCredentials(authorization_token, + authority_selector); +} -/// Combines a channel credentials and a call credentials into a composite -/// channel credentials. -std::shared_ptr CompositeChannelCredentials( +static inline std::shared_ptr CompositeChannelCredentials( const std::shared_ptr& channel_creds, - const std::shared_ptr& call_creds); + const std::shared_ptr& call_creds) { + return ::grpc_impl::CompositeChannelCredentials(channel_creds, call_creds); +} -/// Combines two call credentials objects into a composite call credentials. -std::shared_ptr CompositeCallCredentials( - const std::shared_ptr& creds1, - const std::shared_ptr& creds2); +static inline std::shared_ptr +CompositeCallCredentials(const std::shared_ptr& creds1, + const std::shared_ptr& creds2) { + return ::grpc_impl::CompositeCallCredentials(creds1, creds2); +} -/// Credentials for an unencrypted, unauthenticated channel -std::shared_ptr InsecureChannelCredentials(); +static inline std::shared_ptr +InsecureChannelCredentials() { + return ::grpc_impl::InsecureChannelCredentials(); +} -/// Credentials for a channel using Cronet. -std::shared_ptr CronetChannelCredentials(void* engine); +static inline std::shared_ptr +CronetChannelCredentials(void* engine) { + return ::grpc_impl::CronetChannelCredentials(engine); +} -/// User defined metadata credentials. -class MetadataCredentialsPlugin { - public: - virtual ~MetadataCredentialsPlugin() {} +typedef ::grpc_impl::MetadataCredentialsPlugin MetadataCredentialsPlugin; - /// If this method returns true, the Process function will be scheduled in - /// a different thread from the one processing the call. - virtual bool IsBlocking() const { return true; } - - /// Type of credentials this plugin is implementing. - virtual const char* GetType() const { return ""; } - - /// Gets the auth metatada produced by this plugin. - /// The fully qualified method name is: - /// service_url + "/" + method_name. - /// The channel_auth_context contains (among other things), the identity of - /// the server. - virtual Status GetMetadata( - grpc::string_ref service_url, grpc::string_ref method_name, - const AuthContext& channel_auth_context, - std::multimap* metadata) = 0; -}; - -std::shared_ptr MetadataCredentialsFromPlugin( - std::unique_ptr plugin); +static inline std::shared_ptr +MetadataCredentialsFromPlugin( + std::unique_ptr plugin) { + return ::grpc_impl::MetadataCredentialsFromPlugin(std::move(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 target_service_accounts; -}; +typedef ::grpc_impl::experimental::AltsCredentialsOptions + AltsCredentialsOptions; -/// Builds ALTS Credentials given ALTS specific options -std::shared_ptr AltsCredentials( - const AltsCredentialsOptions& options); +static inline std::shared_ptr AltsCredentials( + const AltsCredentialsOptions& options) { + return ::grpc_impl::experimental::AltsCredentials(options); +} -/// Builds Local Credentials. -std::shared_ptr LocalCredentials( - grpc_local_connect_type type); +static inline std::shared_ptr LocalCredentials( + grpc_local_connect_type type) { + return ::grpc_impl::experimental::LocalCredentials(type); +} } // namespace experimental } // namespace grpc diff --git a/include/grpcpp/security/credentials_impl.h b/include/grpcpp/security/credentials_impl.h new file mode 100644 index 00000000000..29ba2075c29 --- /dev/null +++ b/include/grpcpp/security/credentials_impl.h @@ -0,0 +1,281 @@ +/* + * + * 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_SECURITY_CREDENTIALS_IMPL_H +#define GRPCPP_SECURITY_CREDENTIALS_IMPL_H + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +struct grpc_call; + +namespace grpc_impl { + +class ChannelCredentials; +class CallCredentials; +class SecureCallCredentials; +class SecureChannelCredentials; + +std::shared_ptr<::grpc::Channel> CreateCustomChannelImpl( + const grpc::string& target, + const std::shared_ptr& creds, + const grpc::ChannelArguments& args); + +namespace experimental { +std::shared_ptr<::grpc::Channel> CreateCustomChannelWithInterceptors( + const grpc::string& target, + const std::shared_ptr& creds, + const grpc::ChannelArguments& args, + std::vector< + std::unique_ptr> + interceptor_creators); +} + +/// A channel credentials object encapsulates all the state needed by a client +/// to authenticate with a server for a given channel. +/// It can make various assertions, e.g., about the client’s identity, role +/// for all the calls on that channel. +/// +/// \see https://grpc.io/docs/guides/auth.html +class ChannelCredentials : private grpc::GrpcLibraryCodegen { + public: + ChannelCredentials(); + ~ChannelCredentials(); + + protected: + friend std::shared_ptr CompositeChannelCredentials( + const std::shared_ptr& channel_creds, + const std::shared_ptr& call_creds); + + virtual SecureChannelCredentials* AsSecureCredentials() = 0; + + private: + friend std::shared_ptr<::grpc::Channel> CreateCustomChannelImpl( + const grpc::string& target, + const std::shared_ptr& creds, + const grpc::ChannelArguments& args); + + friend std::shared_ptr<::grpc::Channel> + grpc_impl::experimental::CreateCustomChannelWithInterceptors( + const grpc::string& target, + const std::shared_ptr& creds, + const grpc::ChannelArguments& args, + std::vector> + interceptor_creators); + + virtual std::shared_ptr<::grpc::Channel> CreateChannelImpl( + const grpc::string& target, const grpc::ChannelArguments& args) = 0; + + // This function should have been a pure virtual function, but it is + // implemented as a virtual function so that it does not break API. + virtual std::shared_ptr<::grpc::Channel> CreateChannelWithInterceptors( + const grpc::string& target, const grpc::ChannelArguments& args, + std::vector> + interceptor_creators) { + return nullptr; + } +}; + +/// A call credentials object encapsulates the state needed by a client to +/// authenticate with a server for a given call on a channel. +/// +/// \see https://grpc.io/docs/guides/auth.html +class CallCredentials : private grpc::GrpcLibraryCodegen { + public: + CallCredentials(); + ~CallCredentials(); + + /// Apply this instance's credentials to \a call. + virtual bool ApplyToCall(grpc_call* call) = 0; + + protected: + friend std::shared_ptr CompositeChannelCredentials( + const std::shared_ptr& channel_creds, + const std::shared_ptr& call_creds); + + friend std::shared_ptr CompositeCallCredentials( + const std::shared_ptr& creds1, + const std::shared_ptr& creds2); + + virtual SecureCallCredentials* AsSecureCredentials() = 0; +}; + +/// Options used to build SslCredentials. +struct SslCredentialsOptions { + /// The buffer containing the PEM encoding of the server root certificates. If + /// this parameter is empty, the default roots will be used. The default + /// roots can be overridden using the \a GRPC_DEFAULT_SSL_ROOTS_FILE_PATH + /// environment variable pointing to a file on the file system containing the + /// roots. + grpc::string pem_root_certs; + + /// The buffer containing the PEM encoding of the client's private key. This + /// parameter can be empty if the client does not have a private key. + grpc::string pem_private_key; + + /// The buffer containing the PEM encoding of the client's certificate chain. + /// This parameter can be empty if the client does not have a certificate + /// chain. + grpc::string pem_cert_chain; +}; + +// Factories for building different types of Credentials The functions may +// return empty shared_ptr when credentials cannot be created. If a +// Credentials pointer is returned, it can still be invalid when used to create +// a channel. A lame channel will be created then and all rpcs will fail on it. + +/// Builds credentials with reasonable defaults. +/// +/// \warning Only use these credentials when connecting to a Google endpoint. +/// Using these credentials to connect to any other service may result in this +/// service being able to impersonate your client for requests to Google +/// services. +std::shared_ptr GoogleDefaultCredentials(); + +/// Builds SSL Credentials given SSL specific options +std::shared_ptr SslCredentials( + const SslCredentialsOptions& options); + +/// Builds credentials for use when running in GCE +/// +/// \warning Only use these credentials when connecting to a Google endpoint. +/// Using these credentials to connect to any other service may result in this +/// service being able to impersonate your client for requests to Google +/// services. +std::shared_ptr GoogleComputeEngineCredentials(); + +constexpr long kMaxAuthTokenLifetimeSecs = 3600; + +/// Builds Service Account JWT Access credentials. +/// json_key is the JSON key string containing the client's private key. +/// token_lifetime_seconds is the lifetime in seconds of each Json Web Token +/// (JWT) created with this credentials. It should not exceed +/// \a kMaxAuthTokenLifetimeSecs or will be cropped to this value. +std::shared_ptr ServiceAccountJWTAccessCredentials( + const grpc::string& json_key, + long token_lifetime_seconds = grpc_impl::kMaxAuthTokenLifetimeSecs); + +/// Builds refresh token credentials. +/// json_refresh_token is the JSON string containing the refresh token along +/// with a client_id and client_secret. +/// +/// \warning Only use these credentials when connecting to a Google endpoint. +/// Using these credentials to connect to any other service may result in this +/// service being able to impersonate your client for requests to Google +/// services. +std::shared_ptr GoogleRefreshTokenCredentials( + const grpc::string& json_refresh_token); + +/// Builds access token credentials. +/// access_token is an oauth2 access token that was fetched using an out of band +/// mechanism. +/// +/// \warning Only use these credentials when connecting to a Google endpoint. +/// Using these credentials to connect to any other service may result in this +/// service being able to impersonate your client for requests to Google +/// services. +std::shared_ptr AccessTokenCredentials( + const grpc::string& access_token); + +/// Builds IAM credentials. +/// +/// \warning Only use these credentials when connecting to a Google endpoint. +/// Using these credentials to connect to any other service may result in this +/// service being able to impersonate your client for requests to Google +/// services. +std::shared_ptr GoogleIAMCredentials( + const grpc::string& authorization_token, + const grpc::string& authority_selector); + +/// Combines a channel credentials and a call credentials into a composite +/// channel credentials. +std::shared_ptr CompositeChannelCredentials( + const std::shared_ptr& channel_creds, + const std::shared_ptr& call_creds); + +/// Combines two call credentials objects into a composite call credentials. +std::shared_ptr CompositeCallCredentials( + const std::shared_ptr& creds1, + const std::shared_ptr& creds2); + +/// Credentials for an unencrypted, unauthenticated channel +std::shared_ptr InsecureChannelCredentials(); + +/// Credentials for a channel using Cronet. +std::shared_ptr CronetChannelCredentials(void* engine); + +/// User defined metadata credentials. +class MetadataCredentialsPlugin { + public: + virtual ~MetadataCredentialsPlugin() {} + + /// If this method returns true, the Process function will be scheduled in + /// a different thread from the one processing the call. + virtual bool IsBlocking() const { return true; } + + /// Type of credentials this plugin is implementing. + virtual const char* GetType() const { return ""; } + + /// Gets the auth metatada produced by this plugin. + /// The fully qualified method name is: + /// service_url + "/" + method_name. + /// The channel_auth_context contains (among other things), the identity of + /// the server. + virtual grpc::Status GetMetadata( + grpc::string_ref service_url, grpc::string_ref method_name, + const grpc::AuthContext& channel_auth_context, + std::multimap* metadata) = 0; +}; + +std::shared_ptr MetadataCredentialsFromPlugin( + std::unique_ptr 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 target_service_accounts; +}; + +/// Builds ALTS Credentials given ALTS specific options +std::shared_ptr AltsCredentials( + const AltsCredentialsOptions& options); + +/// Builds Local Credentials. +std::shared_ptr LocalCredentials( + grpc_local_connect_type type); + +} // namespace experimental +} // namespace grpc_impl + +#endif // GRPCPP_SECURITY_CREDENTIALS_IMPL_H diff --git a/include/grpcpp/security/server_credentials.h b/include/grpcpp/security/server_credentials.h index bd00a0a1737..57f733886f4 100644 --- a/include/grpcpp/security/server_credentials.h +++ b/include/grpcpp/security/server_credentials.h @@ -1,6 +1,6 @@ /* * - * Copyright 2015 gRPC authors. + * Copyright 2019 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,39 +19,15 @@ #ifndef GRPCPP_SECURITY_SERVER_CREDENTIALS_H #define GRPCPP_SECURITY_SERVER_CREDENTIALS_H -#include -#include +#include -#include -#include -#include +namespace grpc_impl { -struct grpc_server; - -namespace grpc { class Server; +} // namespace grpc_impl +namespace grpc { -/// Wrapper around \a grpc_server_credentials, a way to authenticate a server. -class ServerCredentials { - public: - virtual ~ServerCredentials(); - - /// This method is not thread-safe and has to be called before the server is - /// started. The last call to this function wins. - virtual void SetAuthMetadataProcessor( - const std::shared_ptr& processor) = 0; - - private: - friend class ::grpc::Server; - - /// Tries to bind \a server to the given \a addr (eg, localhost:1234, - /// 192.168.1.1:31416, [::1]:27182, etc.) - /// - /// \return bound port number on sucess, 0 on failure. - // TODO(dgq): the "port" part seems to be a misnomer. - virtual int AddPortToServer(const grpc::string& addr, - grpc_server* server) = 0; -}; +typedef ::grpc_impl::ServerCredentials ServerCredentials; /// Options to create ServerCredentials with SSL struct SslServerCredentialsOptions { @@ -79,27 +55,29 @@ struct SslServerCredentialsOptions { grpc_ssl_client_certificate_request_type client_certificate_request; }; -/// Builds SSL ServerCredentials given SSL specific options -std::shared_ptr SslServerCredentials( - const SslServerCredentialsOptions& options); +static inline std::shared_ptr SslServerCredentials( + const SslServerCredentialsOptions& options) { + return ::grpc_impl::SslServerCredentials(options); +} -/// Builds insecure server credentials. -std::shared_ptr InsecureServerCredentials(); +static inline std::shared_ptr InsecureServerCredentials() { + return ::grpc_impl::InsecureServerCredentials(); +} namespace experimental { -/// Options to create ServerCredentials with ALTS -struct AltsServerCredentialsOptions { - /// Add fields if needed. -}; +typedef ::grpc_impl::experimental::AltsServerCredentialsOptions + AltsServerCredentialsOptions; -/// Builds ALTS ServerCredentials given ALTS specific options -std::shared_ptr AltsServerCredentials( - const AltsServerCredentialsOptions& options); +static inline std::shared_ptr AltsServerCredentials( + const AltsServerCredentialsOptions& options) { + return ::grpc_impl::experimental::AltsServerCredentials(options); +} -/// Builds Local ServerCredentials. -std::shared_ptr LocalServerCredentials( - grpc_local_connect_type type); +static inline std::shared_ptr LocalServerCredentials( + grpc_local_connect_type type) { + return ::grpc_impl::experimental::LocalServerCredentials(type); +} } // namespace experimental } // namespace grpc diff --git a/include/grpcpp/security/server_credentials_impl.h b/include/grpcpp/security/server_credentials_impl.h new file mode 100644 index 00000000000..f08849097ad --- /dev/null +++ b/include/grpcpp/security/server_credentials_impl.h @@ -0,0 +1,85 @@ +/* + * + * 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_SECURITY_SERVER_CREDENTIALS_IMPL_H +#define GRPCPP_SECURITY_SERVER_CREDENTIALS_IMPL_H + +#include +#include + +#include +#include +#include + +struct grpc_server; + +namespace grpc { + +struct SslServerCredentialsOptions; +} // namespace grpc +namespace grpc_impl { +class Server; + +/// Wrapper around \a grpc_server_credentials, a way to authenticate a server. +class ServerCredentials { + public: + virtual ~ServerCredentials(); + + /// This method is not thread-safe and has to be called before the server is + /// started. The last call to this function wins. + virtual void SetAuthMetadataProcessor( + const std::shared_ptr& processor) = 0; + + private: + friend class ::grpc_impl::Server; + + /// Tries to bind \a server to the given \a addr (eg, localhost:1234, + /// 192.168.1.1:31416, [::1]:27182, etc.) + /// + /// \return bound port number on success, 0 on failure. + // TODO(dgq): the "port" part seems to be a misnomer. + virtual int AddPortToServer(const grpc::string& addr, + grpc_server* server) = 0; +}; + +/// Builds SSL ServerCredentials given SSL specific options +std::shared_ptr SslServerCredentials( + const grpc::SslServerCredentialsOptions& options); + +/// Builds insecure server credentials. +std::shared_ptr 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 AltsServerCredentials( + const AltsServerCredentialsOptions& options); + +/// Builds Local ServerCredentials. +std::shared_ptr LocalServerCredentials( + grpc_local_connect_type type); + +} // namespace experimental +} // namespace grpc_impl + +#endif // GRPCPP_SECURITY_SERVER_CREDENTIALS_IMPL_H diff --git a/include/grpcpp/server.h b/include/grpcpp/server.h index cdcac186cb6..3de2aba0b59 100644 --- a/include/grpcpp/server.h +++ b/include/grpcpp/server.h @@ -1,6 +1,6 @@ /* * - * Copyright 2015 gRPC authors. + * Copyright 2019 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,269 +19,11 @@ #ifndef GRPCPP_SERVER_H #define GRPCPP_SERVER_H -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct grpc_server; +#include namespace grpc { -class AsyncGenericService; -class HealthCheckServiceInterface; -class ServerContext; -class ServerInitializer; - -/// Represents a gRPC server. -/// -/// Use a \a grpc::ServerBuilder to create, configure, and start -/// \a Server instances. -class Server : public ServerInterface, private GrpcLibraryCodegen { - public: - ~Server(); - - /// Block until the server shuts down. - /// - /// \warning The server must be either shutting down or some other thread must - /// call \a Shutdown for this function to ever return. - void Wait() override; - - /// Global callbacks are a set of hooks that are called when server - /// events occur. \a SetGlobalCallbacks method is used to register - /// the hooks with gRPC. Note that - /// the \a GlobalCallbacks instance will be shared among all - /// \a Server instances in an application and can be set exactly - /// once per application. - class GlobalCallbacks { - public: - virtual ~GlobalCallbacks() {} - /// Called before server is created. - virtual void UpdateArguments(ChannelArguments* args) {} - /// Called before application callback for each synchronous server request - virtual void PreSynchronousRequest(ServerContext* context) = 0; - /// Called after application callback for each synchronous server request - virtual void PostSynchronousRequest(ServerContext* context) = 0; - /// Called before server is started. - virtual void PreServerStart(Server* server) {} - /// Called after a server port is added. - virtual void AddPort(Server* server, const grpc::string& addr, - ServerCredentials* creds, int port) {} - }; - /// Set the global callback object. Can only be called once per application. - /// Does not take ownership of callbacks, and expects the pointed to object - /// to be alive until all server objects in the process have been destroyed. - /// The same \a GlobalCallbacks object will be used throughout the - /// application and is shared among all \a Server objects. - static void SetGlobalCallbacks(GlobalCallbacks* callbacks); - - /// Returns a \em raw pointer to the underlying \a grpc_server instance. - /// EXPERIMENTAL: for internal/test use only - grpc_server* c_server(); - - /// Returns the health check service. - HealthCheckServiceInterface* GetHealthCheckService() const { - return health_check_service_.get(); - } - - /// Establish a channel for in-process communication - std::shared_ptr InProcessChannel(const ChannelArguments& args); - - /// NOTE: class experimental_type is not part of the public API of this class. - /// TODO(yashykt): Integrate into public API when this is no longer - /// experimental. - class experimental_type { - public: - explicit experimental_type(Server* server) : server_(server) {} - - /// Establish a channel for in-process communication with client - /// interceptors - std::shared_ptr InProcessChannelWithInterceptors( - const ChannelArguments& args, - std::vector< - std::unique_ptr> - interceptor_creators); - - private: - Server* server_; - }; - - /// NOTE: The function experimental() is not stable public API. It is a view - /// to the experimental components of this class. It may be changed or removed - /// at any time. - experimental_type experimental() { return experimental_type(this); } - - protected: - /// Register a service. This call does not take ownership of the service. - /// The service must exist for the lifetime of the Server instance. - bool RegisterService(const grpc::string* host, Service* service) override; - - /// Try binding the server to the given \a addr endpoint - /// (port, and optionally including IP address to bind to). - /// - /// It can be invoked multiple times. Should be used before - /// starting the server. - /// - /// \param addr The address to try to bind to the server (eg, localhost:1234, - /// 192.168.1.1:31416, [::1]:27182, etc.). - /// \param creds The credentials associated with the server. - /// - /// \return bound port number on success, 0 on failure. - /// - /// \warning It is an error to call this method on an already started server. - int AddListeningPort(const grpc::string& addr, - ServerCredentials* creds) override; - - /// NOTE: This is *NOT* a public API. The server constructors are supposed to - /// be used by \a ServerBuilder class only. The constructor will be made - /// 'private' very soon. - /// - /// Server constructors. To be used by \a ServerBuilder only. - /// - /// \param max_message_size Maximum message length that the channel can - /// receive. - /// - /// \param args The channel args - /// - /// \param sync_server_cqs The completion queues to use if the server is a - /// synchronous server (or a hybrid server). The server polls for new RPCs on - /// these queues - /// - /// \param min_pollers The minimum number of polling threads per server - /// completion queue (in param sync_server_cqs) to use for listening to - /// incoming requests (used only in case of sync server) - /// - /// \param max_pollers The maximum number of polling threads per server - /// completion queue (in param sync_server_cqs) to use for listening to - /// incoming requests (used only in case of sync server) - /// - /// \param sync_cq_timeout_msec The timeout to use when calling AsyncNext() on - /// server completion queues passed via sync_server_cqs param. - Server(int max_message_size, ChannelArguments* args, - std::shared_ptr>> - sync_server_cqs, - int min_pollers, int max_pollers, int sync_cq_timeout_msec, - grpc_resource_quota* server_rq = nullptr, - std::vector< - std::unique_ptr> - interceptor_creators = std::vector>()); - - /// Start the server. - /// - /// \param cqs Completion queues for handling asynchronous services. The - /// caller is required to keep all completion queues live until the server is - /// destroyed. - /// \param num_cqs How many completion queues does \a cqs hold. - void Start(ServerCompletionQueue** cqs, size_t num_cqs) override; - - grpc_server* server() override { return server_; }; - - private: - std::vector>* - interceptor_creators() override { - return &interceptor_creators_; - } - - friend class AsyncGenericService; - friend class ServerBuilder; - friend class ServerInitializer; - - class SyncRequest; - class CallbackRequest; - class UnimplementedAsyncRequest; - class UnimplementedAsyncResponse; - - /// SyncRequestThreadManager is an implementation of ThreadManager. This class - /// is responsible for polling for incoming RPCs and calling the RPC handlers. - /// This is only used in case of a Sync server (i.e a server exposing a sync - /// interface) - class SyncRequestThreadManager; - - /// Register a generic service. This call does not take ownership of the - /// service. The service must exist for the lifetime of the Server instance. - void RegisterAsyncGenericService(AsyncGenericService* service) override; - - void PerformOpsOnCall(internal::CallOpSetInterface* ops, - internal::Call* call) override; - - void ShutdownInternal(gpr_timespec deadline) override; - - int max_receive_message_size() const override { - return max_receive_message_size_; - }; - - CompletionQueue* CallbackCQ() override; - - ServerInitializer* initializer(); - - // A vector of interceptor factory objects. - // This should be destroyed after health_check_service_ and this requirement - // is satisfied by declaring interceptor_creators_ before - // health_check_service_. (C++ mandates that member objects be destroyed in - // the reverse order of initialization.) - std::vector> - interceptor_creators_; - - const int max_receive_message_size_; - - /// The following completion queues are ONLY used in case of Sync API - /// i.e. if the server has any services with sync methods. The server uses - /// these completion queues to poll for new RPCs - std::shared_ptr>> - sync_server_cqs_; - - /// List of \a ThreadManager instances (one for each cq in - /// the \a sync_server_cqs) - std::vector> sync_req_mgrs_; - - /// Outstanding callback requests - std::vector> callback_reqs_; - - // Server status - std::mutex mu_; - bool started_; - bool shutdown_; - bool shutdown_notified_; // Was notify called on the shutdown_cv_ - - std::condition_variable shutdown_cv_; - - std::shared_ptr global_callbacks_; - - std::vector services_; - bool has_generic_service_; - - // Pointer to the wrapped grpc_server. - grpc_server* server_; - - std::unique_ptr server_initializer_; - - std::unique_ptr health_check_service_; - bool health_check_service_disabled_; - - // A special handler for resource exhausted in sync case - std::unique_ptr resource_exhausted_handler_; - - // callback_cq_ references the callbackable completion queue associated - // with this server (if any). It is set on the first call to CallbackCQ(). - // It is _not owned_ by the server; ownership belongs with its internal - // shutdown callback tag (invoked when the CQ is fully shutdown). - // It is protected by mu_ - CompletionQueue* callback_cq_ = nullptr; -}; +typedef ::grpc_impl::Server Server; } // namespace grpc diff --git a/include/grpcpp/server_builder.h b/include/grpcpp/server_builder.h index 028b8cffaa7..d9ec7c42f3d 100644 --- a/include/grpcpp/server_builder.h +++ b/include/grpcpp/server_builder.h @@ -1,6 +1,6 @@ /* * - * Copyright 2015-2016 gRPC authors. + * Copyright 2019 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,311 +19,11 @@ #ifndef GRPCPP_SERVER_BUILDER_H #define GRPCPP_SERVER_BUILDER_H -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -struct grpc_resource_quota; +#include namespace grpc { -class AsyncGenericService; -class ResourceQuota; -class CompletionQueue; -class Server; -class ServerCompletionQueue; -class ServerCredentials; -class Service; - -namespace testing { -class ServerBuilderPluginTest; -} // namespace testing - -/// A builder class for the creation and startup of \a grpc::Server instances. -class ServerBuilder { - public: - ServerBuilder(); - virtual ~ServerBuilder(); - - ////////////////////////////////////////////////////////////////////////////// - // Primary API's - - /// Return a running server which is ready for processing calls. - /// Before calling, one typically needs to ensure that: - /// 1. a service is registered - so that the server knows what to serve - /// (via RegisterService, or RegisterAsyncGenericService) - /// 2. a listening port has been added - so the server knows where to receive - /// traffic (via AddListeningPort) - /// 3. [for async api only] completion queues have been added via - /// AddCompletionQueue - virtual std::unique_ptr BuildAndStart(); - - /// Register a service. This call does not take ownership of the service. - /// The service must exist for the lifetime of the \a Server instance returned - /// by \a BuildAndStart(). - /// Matches requests with any :authority - ServerBuilder& RegisterService(Service* service); - - /// Enlists an endpoint \a addr (port with an optional IP address) to - /// bind the \a grpc::Server object to be created to. - /// - /// It can be invoked multiple times. - /// - /// \param addr_uri The address to try to bind to the server in URI form. If - /// the scheme name is omitted, "dns:///" is assumed. To bind to any address, - /// please use IPv6 any, i.e., [::]:, which also accepts IPv4 - /// connections. Valid values include dns:///localhost:1234, / - /// 192.168.1.1:31416, dns:///[::1]:27182, etc.). - /// \param creds The credentials associated with the server. - /// \param selected_port[out] If not `nullptr`, gets populated with the port - /// number bound to the \a grpc::Server for the corresponding endpoint after - /// it is successfully bound by BuildAndStart(), 0 otherwise. AddListeningPort - /// does not modify this pointer. - ServerBuilder& AddListeningPort(const grpc::string& addr_uri, - std::shared_ptr creds, - int* selected_port = nullptr); - - /// Add a completion queue for handling asynchronous services. - /// - /// Best performance is typically obtained by using one thread per polling - /// completion queue. - /// - /// Caller is required to shutdown the server prior to shutting down the - /// returned completion queue. Caller is also required to drain the - /// completion queue after shutting it down. A typical usage scenario: - /// - /// // While building the server: - /// ServerBuilder builder; - /// ... - /// cq_ = builder.AddCompletionQueue(); - /// server_ = builder.BuildAndStart(); - /// - /// // While shutting down the server; - /// server_->Shutdown(); - /// cq_->Shutdown(); // Always *after* the associated server's Shutdown()! - /// // Drain the cq_ that was created - /// void* ignored_tag; - /// bool ignored_ok; - /// while (cq_->Next(&ignored_tag, &ignored_ok)) { } - /// - /// \param is_frequently_polled This is an optional parameter to inform gRPC - /// library about whether this completion queue would be frequently polled - /// (i.e. by calling \a Next() or \a AsyncNext()). The default value is - /// 'true' and is the recommended setting. Setting this to 'false' (i.e. - /// not polling the completion queue frequently) will have a significantly - /// negative performance impact and hence should not be used in production - /// use cases. - std::unique_ptr AddCompletionQueue( - bool is_frequently_polled = true); - - ////////////////////////////////////////////////////////////////////////////// - // Less commonly used RegisterService variants - - /// Register a service. This call does not take ownership of the service. - /// The service must exist for the lifetime of the \a Server instance returned - /// by \a BuildAndStart(). - /// Only matches requests with :authority \a host - ServerBuilder& RegisterService(const grpc::string& host, Service* service); - - /// Register a generic service. - /// Matches requests with any :authority - /// This is mostly useful for writing generic gRPC Proxies where the exact - /// serialization format is unknown - ServerBuilder& RegisterAsyncGenericService(AsyncGenericService* service); - - ////////////////////////////////////////////////////////////////////////////// - // Fine control knobs - - /// Set max receive message size in bytes. - /// The default is GRPC_DEFAULT_MAX_RECV_MESSAGE_LENGTH. - ServerBuilder& SetMaxReceiveMessageSize(int max_receive_message_size) { - max_receive_message_size_ = max_receive_message_size; - return *this; - } - - /// Set max send message size in bytes. - /// The default is GRPC_DEFAULT_MAX_SEND_MESSAGE_LENGTH. - ServerBuilder& SetMaxSendMessageSize(int max_send_message_size) { - max_send_message_size_ = max_send_message_size; - return *this; - } - - /// \deprecated For backward compatibility. - ServerBuilder& SetMaxMessageSize(int max_message_size) { - return SetMaxReceiveMessageSize(max_message_size); - } - - /// Set the support status for compression algorithms. All algorithms are - /// enabled by default. - /// - /// Incoming calls compressed with an unsupported algorithm will fail with - /// \a GRPC_STATUS_UNIMPLEMENTED. - ServerBuilder& SetCompressionAlgorithmSupportStatus( - grpc_compression_algorithm algorithm, bool enabled); - - /// The default compression level to use for all channel calls in the - /// absence of a call-specific level. - ServerBuilder& SetDefaultCompressionLevel(grpc_compression_level level); - - /// The default compression algorithm to use for all channel calls in the - /// absence of a call-specific level. Note that it overrides any compression - /// level set by \a SetDefaultCompressionLevel. - ServerBuilder& SetDefaultCompressionAlgorithm( - grpc_compression_algorithm algorithm); - - /// Set the attached buffer pool for this server - ServerBuilder& SetResourceQuota(const ResourceQuota& resource_quota); - - ServerBuilder& SetOption(std::unique_ptr option); - - /// Options for synchronous servers. - enum SyncServerOption { - NUM_CQS, ///< Number of completion queues. - MIN_POLLERS, ///< Minimum number of polling threads. - MAX_POLLERS, ///< Maximum number of polling threads. - CQ_TIMEOUT_MSEC ///< Completion queue timeout in milliseconds. - }; - - /// Only useful if this is a Synchronous server. - ServerBuilder& SetSyncServerOption(SyncServerOption option, int value); - - /// Add a channel argument (an escape hatch to tuning core library parameters - /// directly) - template - ServerBuilder& AddChannelArgument(const grpc::string& arg, const T& value) { - return SetOption(MakeChannelArgumentOption(arg, value)); - } - - /// For internal use only: Register a ServerBuilderPlugin factory function. - static void InternalAddPluginFactory( - std::unique_ptr (*CreatePlugin)()); - - /// Enable a server workaround. Do not use unless you know what the workaround - /// does. For explanation and detailed descriptions of workarounds, see - /// doc/workarounds.md. - ServerBuilder& EnableWorkaround(grpc_workaround_list id); - - /// NOTE: class experimental_type is not part of the public API of this class. - /// TODO(yashykt): Integrate into public API when this is no longer - /// experimental. - class experimental_type { - public: - explicit experimental_type(ServerBuilder* builder) : builder_(builder) {} - - void SetInterceptorCreators( - std::vector< - std::unique_ptr> - interceptor_creators) { - builder_->interceptor_creators_ = std::move(interceptor_creators); - } - - private: - ServerBuilder* builder_; - }; - - /// NOTE: The function experimental() is not stable public API. It is a view - /// to the experimental components of this class. It may be changed or removed - /// at any time. - experimental_type experimental() { return experimental_type(this); } - - protected: - /// Experimental, to be deprecated - struct Port { - grpc::string addr; - std::shared_ptr creds; - int* selected_port; - }; - - /// Experimental, to be deprecated - typedef std::unique_ptr HostString; - struct NamedService { - explicit NamedService(Service* s) : service(s) {} - NamedService(const grpc::string& h, Service* s) - : host(new grpc::string(h)), service(s) {} - HostString host; - Service* service; - }; - - /// Experimental, to be deprecated - std::vector ports() { return ports_; } - - /// Experimental, to be deprecated - std::vector services() { - std::vector service_refs; - for (auto& ptr : services_) { - service_refs.push_back(ptr.get()); - } - return service_refs; - } - - /// Experimental, to be deprecated - std::vector options() { - std::vector option_refs; - for (auto& ptr : options_) { - option_refs.push_back(ptr.get()); - } - return option_refs; - } - - private: - friend class ::grpc::testing::ServerBuilderPluginTest; - - struct SyncServerSettings { - SyncServerSettings() - : num_cqs(1), min_pollers(1), max_pollers(2), cq_timeout_msec(10000) {} - - /// Number of server completion queues to create to listen to incoming RPCs. - int num_cqs; - - /// Minimum number of threads per completion queue that should be listening - /// to incoming RPCs. - int min_pollers; - - /// Maximum number of threads per completion queue that can be listening to - /// incoming RPCs. - int max_pollers; - - /// The timeout for server completion queue's AsyncNext call. - int cq_timeout_msec; - }; - - int max_receive_message_size_; - int max_send_message_size_; - std::vector> options_; - std::vector> services_; - std::vector ports_; - - SyncServerSettings sync_server_settings_; - - /// List of completion queues added via \a AddCompletionQueue method. - std::vector cqs_; - - std::shared_ptr creds_; - std::vector> plugins_; - grpc_resource_quota* resource_quota_; - AsyncGenericService* generic_service_; - struct { - bool is_set; - grpc_compression_level level; - } maybe_default_compression_level_; - struct { - bool is_set; - grpc_compression_algorithm algorithm; - } maybe_default_compression_algorithm_; - uint32_t enabled_compression_algorithms_bitset_; - std::vector> - interceptor_creators_; -}; +typedef ::grpc_impl::ServerBuilder ServerBuilder; } // namespace grpc diff --git a/include/grpcpp/server_builder_impl.h b/include/grpcpp/server_builder_impl.h new file mode 100644 index 00000000000..57f8dc076a4 --- /dev/null +++ b/include/grpcpp/server_builder_impl.h @@ -0,0 +1,355 @@ +/* + * + * 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. + * + */ + +#ifndef GRPCPP_SERVER_BUILDER_IMPL_H +#define GRPCPP_SERVER_BUILDER_IMPL_H + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct grpc_resource_quota; + +namespace grpc_impl { + +class CompletionQueue; +class ResourceQuota; +class Server; +class ServerCompletionQueue; +class ServerCredentials; +} // namespace grpc_impl +namespace grpc { + +class AsyncGenericService; +class Service; + +namespace testing { +class ServerBuilderPluginTest; +} // namespace testing + +namespace experimental { +class CallbackGenericService; +} +} // namespace grpc +namespace grpc_impl { + +/// A builder class for the creation and startup of \a grpc::Server instances. +class ServerBuilder { + public: + ServerBuilder(); + virtual ~ServerBuilder(); + + ////////////////////////////////////////////////////////////////////////////// + // Primary API's + + /// Return a running server which is ready for processing calls. + /// Before calling, one typically needs to ensure that: + /// 1. a service is registered - so that the server knows what to serve + /// (via RegisterService, or RegisterAsyncGenericService) + /// 2. a listening port has been added - so the server knows where to receive + /// traffic (via AddListeningPort) + /// 3. [for async api only] completion queues have been added via + /// AddCompletionQueue + virtual std::unique_ptr BuildAndStart(); + + /// Register a service. This call does not take ownership of the service. + /// The service must exist for the lifetime of the \a Server instance returned + /// by \a BuildAndStart(). + /// Matches requests with any :authority + ServerBuilder& RegisterService(grpc::Service* service); + + /// Enlists an endpoint \a addr (port with an optional IP address) to + /// bind the \a grpc::Server object to be created to. + /// + /// It can be invoked multiple times. + /// + /// \param addr_uri The address to try to bind to the server in URI form. If + /// the scheme name is omitted, "dns:///" is assumed. To bind to any address, + /// please use IPv6 any, i.e., [::]:, which also accepts IPv4 + /// connections. Valid values include dns:///localhost:1234, / + /// 192.168.1.1:31416, dns:///[::1]:27182, etc.). + /// \param creds The credentials associated with the server. + /// \param selected_port[out] If not `nullptr`, gets populated with the port + /// number bound to the \a grpc::Server for the corresponding endpoint after + /// it is successfully bound by BuildAndStart(), 0 otherwise. AddListeningPort + /// does not modify this pointer. + ServerBuilder& AddListeningPort( + const grpc::string& addr_uri, + std::shared_ptr creds, + int* selected_port = nullptr); + + /// Add a completion queue for handling asynchronous services. + /// + /// Best performance is typically obtained by using one thread per polling + /// completion queue. + /// + /// Caller is required to shutdown the server prior to shutting down the + /// returned completion queue. Caller is also required to drain the + /// completion queue after shutting it down. A typical usage scenario: + /// + /// // While building the server: + /// ServerBuilder builder; + /// ... + /// cq_ = builder.AddCompletionQueue(); + /// server_ = builder.BuildAndStart(); + /// + /// // While shutting down the server; + /// server_->Shutdown(); + /// cq_->Shutdown(); // Always *after* the associated server's Shutdown()! + /// // Drain the cq_ that was created + /// void* ignored_tag; + /// bool ignored_ok; + /// while (cq_->Next(&ignored_tag, &ignored_ok)) { } + /// + /// \param is_frequently_polled This is an optional parameter to inform gRPC + /// library about whether this completion queue would be frequently polled + /// (i.e. by calling \a Next() or \a AsyncNext()). The default value is + /// 'true' and is the recommended setting. Setting this to 'false' (i.e. + /// not polling the completion queue frequently) will have a significantly + /// negative performance impact and hence should not be used in production + /// use cases. + std::unique_ptr AddCompletionQueue( + bool is_frequently_polled = true); + + ////////////////////////////////////////////////////////////////////////////// + // Less commonly used RegisterService variants + + /// Register a service. This call does not take ownership of the service. + /// The service must exist for the lifetime of the \a Server instance + /// returned by \a BuildAndStart(). Only matches requests with :authority \a + /// host + ServerBuilder& RegisterService(const grpc::string& host, + grpc::Service* service); + + /// Register a generic service. + /// Matches requests with any :authority + /// This is mostly useful for writing generic gRPC Proxies where the exact + /// serialization format is unknown + ServerBuilder& RegisterAsyncGenericService( + grpc::AsyncGenericService* service); + + ////////////////////////////////////////////////////////////////////////////// + // Fine control knobs + + /// Set max receive message size in bytes. + /// The default is GRPC_DEFAULT_MAX_RECV_MESSAGE_LENGTH. + ServerBuilder& SetMaxReceiveMessageSize(int max_receive_message_size) { + max_receive_message_size_ = max_receive_message_size; + return *this; + } + + /// Set max send message size in bytes. + /// The default is GRPC_DEFAULT_MAX_SEND_MESSAGE_LENGTH. + ServerBuilder& SetMaxSendMessageSize(int max_send_message_size) { + max_send_message_size_ = max_send_message_size; + return *this; + } + + /// \deprecated For backward compatibility. + ServerBuilder& SetMaxMessageSize(int max_message_size) { + return SetMaxReceiveMessageSize(max_message_size); + } + + /// Set the support status for compression algorithms. All algorithms are + /// enabled by default. + /// + /// Incoming calls compressed with an unsupported algorithm will fail with + /// \a GRPC_STATUS_UNIMPLEMENTED. + ServerBuilder& SetCompressionAlgorithmSupportStatus( + grpc_compression_algorithm algorithm, bool enabled); + + /// The default compression level to use for all channel calls in the + /// absence of a call-specific level. + ServerBuilder& SetDefaultCompressionLevel(grpc_compression_level level); + + /// The default compression algorithm to use for all channel calls in the + /// absence of a call-specific level. Note that it overrides any compression + /// level set by \a SetDefaultCompressionLevel. + ServerBuilder& SetDefaultCompressionAlgorithm( + grpc_compression_algorithm algorithm); + + /// Set the attached buffer pool for this server + ServerBuilder& SetResourceQuota( + const grpc_impl::ResourceQuota& resource_quota); + + ServerBuilder& SetOption(std::unique_ptr option); + + /// Options for synchronous servers. + enum SyncServerOption { + NUM_CQS, ///< Number of completion queues. + MIN_POLLERS, ///< Minimum number of polling threads. + MAX_POLLERS, ///< Maximum number of polling threads. + CQ_TIMEOUT_MSEC ///< Completion queue timeout in milliseconds. + }; + + /// Only useful if this is a Synchronous server. + ServerBuilder& SetSyncServerOption(SyncServerOption option, int value); + + /// Add a channel argument (an escape hatch to tuning core library parameters + /// directly) + template + ServerBuilder& AddChannelArgument(const grpc::string& arg, const T& value) { + return SetOption(grpc::MakeChannelArgumentOption(arg, value)); + } + + /// For internal use only: Register a ServerBuilderPlugin factory function. + static void InternalAddPluginFactory( + std::unique_ptr (*CreatePlugin)()); + + /// Enable a server workaround. Do not use unless you know what the workaround + /// does. For explanation and detailed descriptions of workarounds, see + /// doc/workarounds.md. + ServerBuilder& EnableWorkaround(grpc_workaround_list id); + + /// NOTE: class experimental_type is not part of the public API of this class. + /// TODO(yashykt): Integrate into public API when this is no longer + /// experimental. + class experimental_type { + public: + explicit experimental_type(grpc_impl::ServerBuilder* builder) + : builder_(builder) {} + + void SetInterceptorCreators( + std::vector> + interceptor_creators) { + builder_->interceptor_creators_ = std::move(interceptor_creators); + } + + /// Register a generic service that uses the callback API. + /// Matches requests with any :authority + /// This is mostly useful for writing generic gRPC Proxies where the exact + /// serialization format is unknown + ServerBuilder& RegisterCallbackGenericService( + grpc::experimental::CallbackGenericService* service); + + private: + ServerBuilder* builder_; + }; + + /// NOTE: The function experimental() is not stable public API. It is a view + /// to the experimental components of this class. It may be changed or removed + /// at any time. + experimental_type experimental() { return experimental_type(this); } + + protected: + /// Experimental, to be deprecated + struct Port { + grpc::string addr; + std::shared_ptr creds; + int* selected_port; + }; + + /// Experimental, to be deprecated + typedef std::unique_ptr HostString; + struct NamedService { + explicit NamedService(grpc::Service* s) : service(s) {} + NamedService(const grpc::string& h, grpc::Service* s) + : host(new grpc::string(h)), service(s) {} + HostString host; + grpc::Service* service; + }; + + /// Experimental, to be deprecated + std::vector ports() { return ports_; } + + /// Experimental, to be deprecated + std::vector services() { + std::vector service_refs; + for (auto& ptr : services_) { + service_refs.push_back(ptr.get()); + } + return service_refs; + } + + /// Experimental, to be deprecated + std::vector options() { + std::vector option_refs; + for (auto& ptr : options_) { + option_refs.push_back(ptr.get()); + } + return option_refs; + } + + private: + friend class ::grpc::testing::ServerBuilderPluginTest; + + struct SyncServerSettings { + SyncServerSettings() + : num_cqs(1), min_pollers(1), max_pollers(2), cq_timeout_msec(10000) {} + + /// Number of server completion queues to create to listen to incoming RPCs. + int num_cqs; + + /// Minimum number of threads per completion queue that should be listening + /// to incoming RPCs. + int min_pollers; + + /// Maximum number of threads per completion queue that can be listening to + /// incoming RPCs. + int max_pollers; + + /// The timeout for server completion queue's AsyncNext call. + int cq_timeout_msec; + }; + + int max_receive_message_size_; + int max_send_message_size_; + std::vector> options_; + std::vector> services_; + std::vector ports_; + + SyncServerSettings sync_server_settings_; + + /// List of completion queues added via \a AddCompletionQueue method. + std::vector cqs_; + + std::shared_ptr creds_; + std::vector> plugins_; + grpc_resource_quota* resource_quota_; + grpc::AsyncGenericService* generic_service_{nullptr}; + grpc::experimental::CallbackGenericService* callback_generic_service_{ + nullptr}; + struct { + bool is_set; + grpc_compression_level level; + } maybe_default_compression_level_; + struct { + bool is_set; + grpc_compression_algorithm algorithm; + } maybe_default_compression_algorithm_; + uint32_t enabled_compression_algorithms_bitset_; + std::vector< + std::unique_ptr> + interceptor_creators_; +}; + +} // namespace grpc_impl + +#endif // GRPCPP_SERVER_BUILDER_IMPL_H diff --git a/include/grpcpp/server_impl.h b/include/grpcpp/server_impl.h new file mode 100644 index 00000000000..9d02af8d11f --- /dev/null +++ b/include/grpcpp/server_impl.h @@ -0,0 +1,373 @@ +/* + * + * 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_SERVER_IMPL_H +#define GRPCPP_SERVER_IMPL_H + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct grpc_server; + +namespace grpc { + +class AsyncGenericService; +class ServerContext; + +} // namespace grpc + +namespace grpc_impl { + +class ServerInitializer; + +/// Represents a gRPC server. +/// +/// Use a \a grpc::ServerBuilder to create, configure, and start +/// \a Server instances. +class Server : public grpc::ServerInterface, private grpc::GrpcLibraryCodegen { + public: + ~Server(); + + /// Block until the server shuts down. + /// + /// \warning The server must be either shutting down or some other thread must + /// call \a Shutdown for this function to ever return. + void Wait() override; + + /// Global callbacks are a set of hooks that are called when server + /// events occur. \a SetGlobalCallbacks method is used to register + /// the hooks with gRPC. Note that + /// the \a GlobalCallbacks instance will be shared among all + /// \a Server instances in an application and can be set exactly + /// once per application. + class GlobalCallbacks { + public: + virtual ~GlobalCallbacks() {} + /// Called before server is created. + virtual void UpdateArguments(grpc::ChannelArguments* args) {} + /// Called before application callback for each synchronous server request + virtual void PreSynchronousRequest(grpc::ServerContext* context) = 0; + /// Called after application callback for each synchronous server request + virtual void PostSynchronousRequest(grpc::ServerContext* context) = 0; + /// Called before server is started. + virtual void PreServerStart(Server* server) {} + /// Called after a server port is added. + virtual void AddPort(Server* server, const grpc::string& addr, + grpc::ServerCredentials* creds, int port) {} + }; + /// Set the global callback object. Can only be called once per application. + /// Does not take ownership of callbacks, and expects the pointed to object + /// to be alive until all server objects in the process have been destroyed. + /// The same \a GlobalCallbacks object will be used throughout the + /// application and is shared among all \a Server objects. + static void SetGlobalCallbacks(GlobalCallbacks* callbacks); + + /// Returns a \em raw pointer to the underlying \a grpc_server instance. + /// EXPERIMENTAL: for internal/test use only + grpc_server* c_server(); + + /// Returns the health check service. + grpc::HealthCheckServiceInterface* GetHealthCheckService() const { + return health_check_service_.get(); + } + + /// Establish a channel for in-process communication + std::shared_ptr<::grpc::Channel> InProcessChannel( + const grpc::ChannelArguments& args); + + /// NOTE: class experimental_type is not part of the public API of this class. + /// TODO(yashykt): Integrate into public API when this is no longer + /// experimental. + class experimental_type { + public: + explicit experimental_type(Server* server) : server_(server) {} + + /// Establish a channel for in-process communication with client + /// interceptors + std::shared_ptr<::grpc::Channel> InProcessChannelWithInterceptors( + const grpc::ChannelArguments& args, + std::vector> + interceptor_creators); + + private: + Server* server_; + }; + + /// NOTE: The function experimental() is not stable public API. It is a view + /// to the experimental components of this class. It may be changed or removed + /// at any time. + experimental_type experimental() { return experimental_type(this); } + + protected: + /// Register a service. This call does not take ownership of the service. + /// The service must exist for the lifetime of the Server instance. + bool RegisterService(const grpc::string* host, + grpc::Service* service) override; + + /// Try binding the server to the given \a addr endpoint + /// (port, and optionally including IP address to bind to). + /// + /// It can be invoked multiple times. Should be used before + /// starting the server. + /// + /// \param addr The address to try to bind to the server (eg, localhost:1234, + /// 192.168.1.1:31416, [::1]:27182, etc.). + /// \param creds The credentials associated with the server. + /// + /// \return bound port number on success, 0 on failure. + /// + /// \warning It is an error to call this method on an already started server. + int AddListeningPort(const grpc::string& addr, + grpc::ServerCredentials* creds) override; + + /// NOTE: This is *NOT* a public API. The server constructors are supposed to + /// be used by \a ServerBuilder class only. The constructor will be made + /// 'private' very soon. + /// + /// Server constructors. To be used by \a ServerBuilder only. + /// + /// \param max_message_size Maximum message length that the channel can + /// receive. + /// + /// \param args The channel args + /// + /// \param sync_server_cqs The completion queues to use if the server is a + /// synchronous server (or a hybrid server). The server polls for new RPCs on + /// these queues + /// + /// \param min_pollers The minimum number of polling threads per server + /// completion queue (in param sync_server_cqs) to use for listening to + /// incoming requests (used only in case of sync server) + /// + /// \param max_pollers The maximum number of polling threads per server + /// completion queue (in param sync_server_cqs) to use for listening to + /// incoming requests (used only in case of sync server) + /// + /// \param sync_cq_timeout_msec The timeout to use when calling AsyncNext() on + /// server completion queues passed via sync_server_cqs param. + Server( + int max_message_size, grpc::ChannelArguments* args, + std::shared_ptr>> + sync_server_cqs, + int min_pollers, int max_pollers, int sync_cq_timeout_msec, + grpc_resource_quota* server_rq = nullptr, + std::vector> + interceptor_creators = std::vector>()); + + /// Start the server. + /// + /// \param cqs Completion queues for handling asynchronous services. The + /// caller is required to keep all completion queues live until the server is + /// destroyed. + /// \param num_cqs How many completion queues does \a cqs hold. + void Start(grpc::ServerCompletionQueue** cqs, size_t num_cqs) override; + + grpc_server* server() override { return server_; } + + protected: + /// NOTE: This method is not part of the public API for this class. + void set_health_check_service( + std::unique_ptr service) { + health_check_service_ = std::move(service); + } + + /// NOTE: This method is not part of the public API for this class. + bool health_check_service_disabled() const { + return health_check_service_disabled_; + } + + private: + std::vector< + std::unique_ptr>* + interceptor_creators() override { + return &interceptor_creators_; + } + + friend class grpc::AsyncGenericService; + friend class grpc_impl::ServerBuilder; + friend class grpc_impl::ServerInitializer; + + class SyncRequest; + class CallbackRequestBase; + template + class CallbackRequest; + class UnimplementedAsyncRequest; + class UnimplementedAsyncResponse; + + /// SyncRequestThreadManager is an implementation of ThreadManager. This class + /// is responsible for polling for incoming RPCs and calling the RPC handlers. + /// This is only used in case of a Sync server (i.e a server exposing a sync + /// interface) + class SyncRequestThreadManager; + + /// Register a generic service. This call does not take ownership of the + /// service. The service must exist for the lifetime of the Server instance. + void RegisterAsyncGenericService(grpc::AsyncGenericService* service) override; + + /// NOTE: class experimental_registration_type is not part of the public API + /// of this class + /// TODO(vjpai): Move these contents to the public API of Server when + /// they are no longer experimental + class experimental_registration_type final + : public experimental_registration_interface { + public: + explicit experimental_registration_type(Server* server) : server_(server) {} + void RegisterCallbackGenericService( + grpc::experimental::CallbackGenericService* service) override { + server_->RegisterCallbackGenericService(service); + } + + private: + Server* server_; + }; + + /// TODO(vjpai): Mark this override when experimental type above is deleted + void RegisterCallbackGenericService( + grpc::experimental::CallbackGenericService* service); + + /// NOTE: The function experimental_registration() is not stable public API. + /// It is a view to the experimental components of this class. It may be + /// changed or removed at any time. + experimental_registration_interface* experimental_registration() override { + return &experimental_registration_; + } + + void PerformOpsOnCall(grpc::internal::CallOpSetInterface* ops, + grpc::internal::Call* call) override; + + void ShutdownInternal(gpr_timespec deadline) override; + + int max_receive_message_size() const override { + return max_receive_message_size_; + } + + grpc::CompletionQueue* CallbackCQ() override; + + grpc_impl::ServerInitializer* initializer(); + + // A vector of interceptor factory objects. + // This should be destroyed after health_check_service_ and this requirement + // is satisfied by declaring interceptor_creators_ before + // health_check_service_. (C++ mandates that member objects be destroyed in + // the reverse order of initialization.) + std::vector< + std::unique_ptr> + interceptor_creators_; + + const int max_receive_message_size_; + + /// The following completion queues are ONLY used in case of Sync API + /// i.e. if the server has any services with sync methods. The server uses + /// these completion queues to poll for new RPCs + std::shared_ptr>> + sync_server_cqs_; + + /// List of \a ThreadManager instances (one for each cq in + /// the \a sync_server_cqs) + std::vector> sync_req_mgrs_; + + // Outstanding unmatched callback requests, indexed by method. + // NOTE: Using a gpr_atm rather than atomic_int because atomic_int isn't + // copyable or movable and thus will cause compilation errors. We + // actually only want to extend the vector before the threaded use + // starts, but this is still a limitation. + std::vector callback_unmatched_reqs_count_; + + // List of callback requests to start when server actually starts. + std::list callback_reqs_to_start_; + + // For registering experimental callback generic service; remove when that + // method longer experimental + experimental_registration_type experimental_registration_{this}; + + // Server status + grpc::internal::Mutex mu_; + bool started_; + bool shutdown_; + bool shutdown_notified_; // Was notify called on the shutdown_cv_ + + grpc::internal::CondVar shutdown_cv_; + + // It is ok (but not required) to nest callback_reqs_mu_ under mu_ . + // Incrementing callback_reqs_outstanding_ is ok without a lock but it must be + // decremented under the lock in case it is the last request and enables the + // server shutdown. The increment is performance-critical since it happens + // during periods of increasing load; the decrement happens only when memory + // is maxed out, during server shutdown, or (possibly in a future version) + // during decreasing load, so it is less performance-critical. + grpc::internal::Mutex callback_reqs_mu_; + grpc::internal::CondVar callback_reqs_done_cv_; + std::atomic_int callback_reqs_outstanding_{0}; + + std::shared_ptr global_callbacks_; + + std::vector services_; + bool has_async_generic_service_{false}; + bool has_callback_generic_service_{false}; + + // Pointer to the wrapped grpc_server. + grpc_server* server_; + + std::unique_ptr server_initializer_; + + std::unique_ptr health_check_service_; + bool health_check_service_disabled_; + + // When appropriate, use a default callback generic service to handle + // unimplemented methods + std::unique_ptr + unimplemented_service_; + + // A special handler for resource exhausted in sync case + std::unique_ptr resource_exhausted_handler_; + + // Handler for callback generic service, if any + std::unique_ptr generic_handler_; + + // callback_cq_ references the callbackable completion queue associated + // with this server (if any). It is set on the first call to CallbackCQ(). + // It is _not owned_ by the server; ownership belongs with its internal + // shutdown callback tag (invoked when the CQ is fully shutdown). + // It is protected by mu_ + grpc::CompletionQueue* callback_cq_ = nullptr; +}; + +} // namespace grpc_impl + +#endif // GRPCPP_SERVER_IMPL_H diff --git a/include/grpcpp/server_posix.h b/include/grpcpp/server_posix.h index ef3ee01a5c6..3d209cbc14f 100644 --- a/include/grpcpp/server_posix.h +++ b/include/grpcpp/server_posix.h @@ -19,21 +19,15 @@ #ifndef GRPCPP_SERVER_POSIX_H #define GRPCPP_SERVER_POSIX_H -#include - -#include -#include +#include namespace grpc { #ifdef GPR_SUPPORT_CHANNELS_FROM_FD -/// Add a new client to a \a Server communicating over the given -/// file descriptor. -/// -/// \param server The server to add the client to. -/// \param fd The file descriptor representing a socket. -void AddInsecureChannelFromFd(Server* server, int fd); +static inline void AddInsecureChannelFromFd(Server* server, int fd) { + ::grpc_impl::AddInsecureChannelFromFd(server, fd); +} #endif // GPR_SUPPORT_CHANNELS_FROM_FD diff --git a/include/grpcpp/server_posix_impl.h b/include/grpcpp/server_posix_impl.h new file mode 100644 index 00000000000..c29af271fe9 --- /dev/null +++ b/include/grpcpp/server_posix_impl.h @@ -0,0 +1,42 @@ +/* + * + * 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. + * + */ + +#ifndef GRPCPP_SERVER_POSIX_IMPL_H +#define GRPCPP_SERVER_POSIX_IMPL_H + +#include + +#include +#include + +namespace grpc_impl { + +#ifdef GPR_SUPPORT_CHANNELS_FROM_FD + +/// Add a new client to a \a Server communicating over the given +/// file descriptor. +/// +/// \param server The server to add the client to. +/// \param fd The file descriptor representing a socket. +void AddInsecureChannelFromFd(grpc::Server* server, int fd); + +#endif // GPR_SUPPORT_CHANNELS_FROM_FD + +} // namespace grpc + +#endif // GRPCPP_SERVER_POSIX_IMPL_H diff --git a/include/grpcpp/support/channel_arguments.h b/include/grpcpp/support/channel_arguments.h index 217929d4aca..593aaec76a7 100644 --- a/include/grpcpp/support/channel_arguments.h +++ b/include/grpcpp/support/channel_arguments.h @@ -19,129 +19,17 @@ #ifndef GRPCPP_SUPPORT_CHANNEL_ARGUMENTS_H #define GRPCPP_SUPPORT_CHANNEL_ARGUMENTS_H -#include -#include +#include -#include -#include -#include +namespace grpc_impl { + +class SecureChannelCredentials; +class ResourceQuota; +} // namespace grpc_impl namespace grpc { -namespace testing { -class ChannelArgumentsTest; -} // namespace testing -class ResourceQuota; - -/// Options for channel creation. The user can use generic setters to pass -/// key value pairs down to C channel creation code. For gRPC related options, -/// concrete setters are provided. -class ChannelArguments { - public: - ChannelArguments(); - ~ChannelArguments(); - - ChannelArguments(const ChannelArguments& other); - ChannelArguments& operator=(ChannelArguments other) { - Swap(other); - return *this; - } - - void Swap(ChannelArguments& other); - - /// Dump arguments in this instance to \a channel_args. Does not take - /// ownership of \a channel_args. - /// - /// Note that the underlying arguments are shared. Changes made to either \a - /// channel_args or this instance would be reflected on both. - void SetChannelArgs(grpc_channel_args* channel_args) const; - - // gRPC specific channel argument setters - /// Set target name override for SSL host name checking. This option is for - /// testing only and should never be used in production. - void SetSslTargetNameOverride(const grpc::string& name); - // TODO(yangg) add flow control options - /// Set the compression algorithm for the channel. - void SetCompressionAlgorithm(grpc_compression_algorithm algorithm); - - /// Set the grpclb fallback timeout (in ms) for the channel. If this amount - /// of time has passed but we have not gotten any non-empty \a serverlist from - /// the balancer, we will fall back to use the backend address(es) returned by - /// the resolver. - void SetGrpclbFallbackTimeout(int fallback_timeout); - - /// 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. - void SetUserAgentPrefix(const grpc::string& user_agent_prefix); - - /// Set the buffer pool to be attached to the constructed channel. - void SetResourceQuota(const ResourceQuota& resource_quota); - - /// Set the max receive and send message sizes. - void SetMaxReceiveMessageSize(int size); - void SetMaxSendMessageSize(int size); - - /// Set LB policy name. - /// Note that if the name resolver returns only balancer addresses, the - /// grpclb LB policy will be used, regardless of what is specified here. - void SetLoadBalancingPolicyName(const grpc::string& lb_policy_name); - - /// Set service config in JSON form. - /// Primarily meant for use in unit tests. - void SetServiceConfigJSON(const grpc::string& service_config_json); - - // Generic channel argument setters. Only for advanced use cases. - /// Set an integer argument \a value under \a key. - void SetInt(const grpc::string& key, int value); - - // Generic channel argument setter. Only for advanced use cases. - /// Set a pointer argument \a value under \a key. Owership is not transferred. - void SetPointer(const grpc::string& key, void* value); - - void SetPointerWithVtable(const grpc::string& key, void* value, - const grpc_arg_pointer_vtable* vtable); - - /// Set a textual argument \a value under \a key. - void SetString(const grpc::string& key, const grpc::string& value); - - /// Return (by value) a C \a grpc_channel_args structure which points to - /// arguments owned by this \a ChannelArguments instance - grpc_channel_args c_channel_args() const { - grpc_channel_args out; - out.num_args = args_.size(); - out.args = args_.empty() ? NULL : const_cast(&args_[0]); - return out; - } - - private: - friend class SecureChannelCredentials; - friend class testing::ChannelArgumentsTest; - - /// Default pointer argument operations. - struct PointerVtableMembers { - static void* Copy(void* in) { return in; } - static void Destroy(void* in) {} - static int Compare(void* a, void* b) { - if (a < b) return -1; - if (a > b) return 1; - return 0; - } - }; - - // Returns empty string when it is not set. - grpc::string GetSslTargetNameOverride() const; - - std::vector args_; - std::list strings_; -}; +typedef ::grpc_impl::ChannelArguments ChannelArguments; } // namespace grpc diff --git a/include/grpcpp/support/channel_arguments_impl.h b/include/grpcpp/support/channel_arguments_impl.h new file mode 100644 index 00000000000..0efeadca880 --- /dev/null +++ b/include/grpcpp/support/channel_arguments_impl.h @@ -0,0 +1,152 @@ +/* + * + * 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_SUPPORT_CHANNEL_ARGUMENTS_IMPL_H +#define GRPCPP_SUPPORT_CHANNEL_ARGUMENTS_IMPL_H + +#include +#include + +#include +#include +#include +#include + +namespace grpc { +namespace testing { +class ChannelArgumentsTest; +} // namespace testing +} // namespace grpc + +namespace grpc_impl { + +class SecureChannelCredentials; + +/// Options for channel creation. The user can use generic setters to pass +/// key value pairs down to C channel creation code. For gRPC related options, +/// concrete setters are provided. +class ChannelArguments { + public: + ChannelArguments(); + ~ChannelArguments(); + + ChannelArguments(const ChannelArguments& other); + ChannelArguments& operator=(ChannelArguments other) { + Swap(other); + return *this; + } + + void Swap(ChannelArguments& other); + + /// Dump arguments in this instance to \a channel_args. Does not take + /// ownership of \a channel_args. + /// + /// Note that the underlying arguments are shared. Changes made to either \a + /// channel_args or this instance would be reflected on both. + void SetChannelArgs(grpc_channel_args* channel_args) const; + + // gRPC specific channel argument setters + /// Set target name override for SSL host name checking. This option is for + /// testing only and should never be used in production. + void SetSslTargetNameOverride(const grpc::string& name); + // TODO(yangg) add flow control options + /// Set the compression algorithm for the channel. + void SetCompressionAlgorithm(grpc_compression_algorithm algorithm); + + /// Set the grpclb fallback timeout (in ms) for the channel. If this amount + /// of time has passed but we have not gotten any non-empty \a serverlist from + /// the balancer, we will fall back to use the backend address(es) returned by + /// the resolver. + void SetGrpclbFallbackTimeout(int fallback_timeout); + + /// 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. + void SetUserAgentPrefix(const grpc::string& user_agent_prefix); + + /// Set the buffer pool to be attached to the constructed channel. + void SetResourceQuota(const grpc::ResourceQuota& resource_quota); + + /// Set the max receive and send message sizes. + void SetMaxReceiveMessageSize(int size); + void SetMaxSendMessageSize(int size); + + /// Set LB policy name. + /// Note that if the name resolver returns only balancer addresses, the + /// grpclb LB policy will be used, regardless of what is specified here. + void SetLoadBalancingPolicyName(const grpc::string& lb_policy_name); + + /// Set service config in JSON form. + /// Primarily meant for use in unit tests. + void SetServiceConfigJSON(const grpc::string& service_config_json); + + // Generic channel argument setters. Only for advanced use cases. + /// Set an integer argument \a value under \a key. + void SetInt(const grpc::string& key, int value); + + // Generic channel argument setter. Only for advanced use cases. + /// Set a pointer argument \a value under \a key. Owership is not transferred. + void SetPointer(const grpc::string& key, void* value); + + void SetPointerWithVtable(const grpc::string& key, void* value, + const grpc_arg_pointer_vtable* vtable); + + /// Set a textual argument \a value under \a key. + void SetString(const grpc::string& key, const grpc::string& value); + + /// Return (by value) a C \a grpc_channel_args structure which points to + /// arguments owned by this \a ChannelArguments instance + grpc_channel_args c_channel_args() const { + grpc_channel_args out; + out.num_args = args_.size(); + out.args = args_.empty() ? NULL : const_cast(&args_[0]); + return out; + } + + private: + friend class grpc_impl::SecureChannelCredentials; + friend class grpc::testing::ChannelArgumentsTest; + + /// Default pointer argument operations. + struct PointerVtableMembers { + static void* Copy(void* in) { return in; } + static void Destroy(void* in) {} + static int Compare(void* a, void* b) { + if (a < b) return -1; + if (a > b) return 1; + return 0; + } + }; + + // Returns empty string when it is not set. + grpc::string GetSslTargetNameOverride() const; + + std::vector args_; + std::list strings_; +}; + +} // namespace grpc_impl + +#endif // GRPCPP_SUPPORT_CHANNEL_ARGUMENTS_IMPL_H diff --git a/include/grpcpp/support/client_interceptor.h b/include/grpcpp/support/client_interceptor.h new file mode 100644 index 00000000000..50810e3fe3c --- /dev/null +++ b/include/grpcpp/support/client_interceptor.h @@ -0,0 +1,24 @@ +/* + * + * 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_SUPPORT_CLIENT_INTERCEPTOR_H +#define GRPCPP_SUPPORT_CLIENT_INTERCEPTOR_H + +#include + +#endif // GRPCPP_SUPPORT_CLIENT_INTERCEPTOR_H diff --git a/include/grpcpp/support/error_details.h b/include/grpcpp/support/error_details.h index 84931d98f18..07bc750db5c 100644 --- a/include/grpcpp/support/error_details.h +++ b/include/grpcpp/support/error_details.h @@ -19,7 +19,7 @@ #ifndef GRPCPP_SUPPORT_ERROR_DETAILS_H #define GRPCPP_SUPPORT_ERROR_DETAILS_H -#include +#include namespace google { namespace rpc { @@ -29,17 +29,15 @@ class Status; namespace grpc { -/// Map a \a grpc::Status to a \a google::rpc::Status. -/// The given \a to object will be cleared. -/// On success, returns status with OK. -/// Returns status with \a INVALID_ARGUMENT, if failed to deserialize. -/// Returns status with \a FAILED_PRECONDITION, if \a to is nullptr. -Status ExtractErrorDetails(const Status& from, ::google::rpc::Status* to); +static inline Status ExtractErrorDetails(const Status& from, + ::google::rpc::Status* to) { + return ::grpc_impl::ExtractErrorDetails(from, to); +} -/// Map \a google::rpc::Status to a \a grpc::Status. -/// Returns OK on success. -/// Returns status with \a FAILED_PRECONDITION if \a to is nullptr. -Status SetErrorDetails(const ::google::rpc::Status& from, Status* to); +static inline Status SetErrorDetails(const ::google::rpc::Status& from, + Status* to) { + return ::grpc_impl::SetErrorDetails(from, to); +} } // namespace grpc diff --git a/include/grpcpp/support/error_details_impl.h b/include/grpcpp/support/error_details_impl.h new file mode 100644 index 00000000000..ae5f04ced8f --- /dev/null +++ b/include/grpcpp/support/error_details_impl.h @@ -0,0 +1,48 @@ +/* + * + * 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 GRPCPP_SUPPORT_ERROR_DETAILS_IMPL_H +#define GRPCPP_SUPPORT_ERROR_DETAILS_IMPL_H + +#include + +namespace google { +namespace rpc { +class Status; +} // namespace rpc +} // namespace google + +namespace grpc_impl { + +/// Map a \a grpc::Status to a \a google::rpc::Status. +/// The given \a to object will be cleared. +/// On success, returns status with OK. +/// Returns status with \a INVALID_ARGUMENT, if failed to deserialize. +/// Returns status with \a FAILED_PRECONDITION, if \a to is nullptr. +grpc::Status ExtractErrorDetails(const grpc::Status& from, + ::google::rpc::Status* to); + +/// Map \a google::rpc::Status to a \a grpc::Status. +/// Returns OK on success. +/// Returns status with \a FAILED_PRECONDITION if \a to is nullptr. +grpc::Status SetErrorDetails(const ::google::rpc::Status& from, + grpc::Status* to); + +} // namespace grpc_impl + +#endif // GRPCPP_SUPPORT_ERROR_DETAILS_IMPL_H diff --git a/include/grpcpp/support/interceptor.h b/include/grpcpp/support/interceptor.h new file mode 100644 index 00000000000..7ff79516bae --- /dev/null +++ b/include/grpcpp/support/interceptor.h @@ -0,0 +1,24 @@ +/* + * + * 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_SUPPORT_INTERCEPTOR_H +#define GRPCPP_SUPPORT_INTERCEPTOR_H + +#include + +#endif // GRPCPP_SUPPORT_INTERCEPTOR_H diff --git a/include/grpcpp/support/message_allocator.h b/include/grpcpp/support/message_allocator.h new file mode 100644 index 00000000000..20ce072b901 --- /dev/null +++ b/include/grpcpp/support/message_allocator.h @@ -0,0 +1,24 @@ +/* + * + * Copyright 2019 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_MESSAGE_ALLOCATOR_H +#define GRPCPP_SUPPORT_MESSAGE_ALLOCATOR_H + +#include + +#endif // GRPCPP_SUPPORT_MESSAGE_ALLOCATOR_H diff --git a/include/grpcpp/support/server_interceptor.h b/include/grpcpp/support/server_interceptor.h new file mode 100644 index 00000000000..b0a6229b667 --- /dev/null +++ b/include/grpcpp/support/server_interceptor.h @@ -0,0 +1,24 @@ +/* + * + * 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_SUPPORT_SERVER_INTERCEPTOR_H +#define GRPCPP_SUPPORT_SERVER_INTERCEPTOR_H + +#include + +#endif // GRPCPP_SUPPORT_SERVER_INTERCEPTOR_H diff --git a/package.xml b/package.xml index 3044cbf8625..7d33a000fae 100644 --- a/package.xml +++ b/package.xml @@ -13,8 +13,8 @@ 2018-01-19 - 1.17.0dev - 1.17.0dev + 1.22.0dev + 1.22.0dev beta @@ -104,17 +104,21 @@ + - - + + + + + - + + - @@ -147,7 +151,9 @@ + + @@ -191,6 +197,7 @@ + @@ -228,6 +235,8 @@ + + @@ -236,6 +245,7 @@ + @@ -280,12 +290,14 @@ + + @@ -293,9 +305,12 @@ + + + - + @@ -323,6 +338,7 @@ + @@ -332,6 +348,7 @@ + @@ -341,11 +358,15 @@ + + + + @@ -354,6 +375,7 @@ + @@ -364,7 +386,6 @@ - @@ -401,7 +422,6 @@ - @@ -413,6 +433,7 @@ + @@ -435,7 +456,6 @@ - @@ -458,6 +478,7 @@ + @@ -474,10 +495,10 @@ - + @@ -490,12 +511,15 @@ + + + @@ -508,18 +532,20 @@ + + + - @@ -543,6 +569,7 @@ + @@ -567,7 +594,6 @@ - @@ -607,7 +633,6 @@ - @@ -621,6 +646,7 @@ + @@ -661,6 +687,8 @@ + + @@ -669,6 +697,7 @@ + @@ -723,21 +752,25 @@ + - + + + + - + @@ -770,10 +803,13 @@ + + + diff --git a/requirements.bazel.txt b/requirements.bazel.txt index 61e529a6ec8..e97843794e4 100644 --- a/requirements.bazel.txt +++ b/requirements.bazel.txt @@ -9,7 +9,8 @@ futures>=2.2.0 google-auth>=1.0.0 oauth2client==4.1.0 requests>=2.14.2 -urllib3==1.22 +urllib3>=1.23 chardet==3.0.4 certifi==2017.4.17 idna==2.7 +googleapis-common-protos==1.5.5 diff --git a/setup.cfg b/setup.cfg index 218792e674c..125ec93491d 100644 --- a/setup.cfg +++ b/setup.cfg @@ -15,3 +15,6 @@ exclude=.*protoc_plugin/protoc_plugin_test\.proto$ # Style settings [yapf] based_on_style = google + +[metadata] +license_files = LICENSE diff --git a/setup.py b/setup.py index ae86e6c9fb7..1e205bdf91d 100644 --- a/setup.py +++ b/setup.py @@ -87,6 +87,7 @@ CLASSIFIERS = [ # present, then it will still attempt to use Cython. BUILD_WITH_CYTHON = os.environ.get('GRPC_PYTHON_BUILD_WITH_CYTHON', False) + # Export this variable to use the system installation of openssl. You need to # have the header files installed (in /usr/include/openssl) and during # runtime, the shared library must be installed @@ -105,6 +106,21 @@ BUILD_WITH_SYSTEM_ZLIB = os.environ.get('GRPC_PYTHON_BUILD_SYSTEM_ZLIB', BUILD_WITH_SYSTEM_CARES = os.environ.get('GRPC_PYTHON_BUILD_SYSTEM_CARES', False) +# For local development use only: This skips building gRPC Core and its +# dependencies, including protobuf and boringssl. This allows "incremental" +# compilation by first building gRPC Core using make, then building only the +# Python/Cython layers here. +# +# Note that this requires libboringssl.a in the libs/{dbg,opt}/ directory, which +# may require configuring make to not use the system openssl implementation: +# +# make HAS_SYSTEM_OPENSSL_ALPN=0 +# +# TODO(ericgribkoff) Respect the BUILD_WITH_SYSTEM_* flags alongside this option +USE_PREBUILT_GRPC_CORE = os.environ.get( + 'GRPC_PYTHON_USE_PREBUILT_GRPC_CORE', False) + + # If this environmental variable is set, GRPC will not try to be compatible with # libc versions old than the one it was compiled against. DISABLE_LIBC_COMPATIBILITY = os.environ.get('GRPC_PYTHON_DISABLE_LIBC_COMPATIBILITY', False) @@ -143,8 +159,8 @@ if EXTRA_ENV_COMPILE_ARGS is None: elif "linux" in sys.platform: 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 += ' -stdlib=libc++ -fvisibility=hidden -fno-wrapv -fno-exceptions' +EXTRA_ENV_COMPILE_ARGS += ' -DPB_FIELD_32BIT' if EXTRA_ENV_LINK_ARGS is None: EXTRA_ENV_LINK_ARGS = '' @@ -249,7 +265,7 @@ def cython_extensions_and_necessity(): for name in CYTHON_EXTENSION_MODULE_NAMES] config = os.environ.get('CONFIG', 'opt') prefix = 'libs/' + config + '/' - if "darwin" in sys.platform: + if USE_PREBUILT_GRPC_CORE: extra_objects = [prefix + 'libares.a', prefix + 'libboringssl.a', prefix + 'libgpr.a', @@ -282,12 +298,11 @@ PACKAGE_DIRECTORIES = { } INSTALL_REQUIRES = ( - 'six>=1.5.2', + "six>=1.5.2", + "futures>=2.2.0; python_version<'3.2'", + "enum34>=1.0.4; python_version<'3.4'", ) -if not PY3: - INSTALL_REQUIRES += ('futures>=2.2.0', 'enum34>=1.0.4') - SETUP_REQUIRES = INSTALL_REQUIRES + ( 'Sphinx~=1.8.1', 'six>=1.10', diff --git a/src/android/test/interop/app/build.gradle b/src/android/test/interop/app/build.gradle index 2f58b99c8e2..fb500a71c71 100644 --- a/src/android/test/interop/app/build.gradle +++ b/src/android/test/interop/app/build.gradle @@ -29,7 +29,6 @@ android { arguments '-DgRPC_CPP_PLUGIN_EXECUTABLE=' + grpc_cpp_plugin } } - ndk.abiFilters 'x86' } buildTypes { debug { diff --git a/src/boringssl/gen_build_yaml.py b/src/boringssl/gen_build_yaml.py index 593b66dc4d9..c25a4ed3c94 100755 --- a/src/boringssl/gen_build_yaml.py +++ b/src/boringssl/gen_build_yaml.py @@ -48,6 +48,7 @@ class Grpc(object): yaml = None def WriteFiles(self, files, asm_outputs): + test_binaries = ['ssl_test', 'crypto_test'] self.yaml = { '#': 'generated with tools/buildgen/gen_boring_ssl_build_yaml.py', @@ -86,45 +87,28 @@ class Grpc(object): for f in sorted(files['test_support']) ], } - ] + [ - { - 'name': 'boringssl_%s_lib' % os.path.splitext(os.path.basename(test))[0], - 'build': 'private', - 'secure': 'no', - 'language': 'c' if os.path.splitext(test)[1] == '.c' else 'c++', - 'src': [map_dir(test)], - 'vs_proj_dir': 'test/boringssl', - 'boringssl': True, - 'defaults': 'boringssl', - 'deps': [ - 'boringssl_test_util', - 'boringssl', - ] - } - for test in list(sorted(set(files['ssl_test'] + files['crypto_test']))) ], 'targets': [ { - 'name': 'boringssl_%s' % os.path.splitext(os.path.basename(test))[0], + 'name': 'boringssl_%s' % test, 'build': 'test', 'run': False, 'secure': 'no', 'language': 'c++', - 'src': ["third_party/boringssl/crypto/test/gtest_main.cc"], + 'src': sorted(map_dir(f) for f in files[test]), 'vs_proj_dir': 'test/boringssl', 'boringssl': True, 'defaults': 'boringssl', 'deps': [ - 'boringssl_%s_lib' % os.path.splitext(os.path.basename(test))[0], 'boringssl_test_util', 'boringssl', ] } - for test in list(sorted(set(files['ssl_test'] + files['crypto_test']))) + for test in test_binaries ], 'tests': [ { - 'name': 'boringssl_%s' % os.path.splitext(os.path.basename(test))[0], + 'name': 'boringssl_%s' % test, 'args': [], 'exclude_configs': ['asan', 'ubsan'], 'ci_platforms': ['linux', 'mac', 'posix', 'windows'], @@ -136,9 +120,8 @@ class Grpc(object): 'defaults': 'boringssl', 'cpu_cost': 1.0 } - for test in list(sorted(set(files['ssl_test'] + files['crypto_test']))) + for test in test_binaries ] - } diff --git a/src/c-ares/gen_build_yaml.py b/src/c-ares/gen_build_yaml.py index 4600d8d2241..6e832edcea3 100755 --- a/src/c-ares/gen_build_yaml.py +++ b/src/c-ares/gen_build_yaml.py @@ -97,6 +97,7 @@ try: "third_party/cares/cares/ares_strcasecmp.c", "third_party/cares/cares/ares_strdup.c", "third_party/cares/cares/ares_strerror.c", + "third_party/cares/cares/ares_strsplit.c", "third_party/cares/cares/ares_timeout.c", "third_party/cares/cares/ares_version.c", "third_party/cares/cares/ares_writev.c", @@ -123,6 +124,7 @@ try: "third_party/cares/cares/ares_setup.h", "third_party/cares/cares/ares_strcasecmp.h", "third_party/cares/cares/ares_strdup.h", + "third_party/cares/cares/ares_strsplit.h", "third_party/cares/cares/ares_version.h", "third_party/cares/cares/bitncmp.h", "third_party/cares/cares/config-win32.h", diff --git a/src/compiler/cpp_generator.cc b/src/compiler/cpp_generator.cc index 7986aca6960..77cd7b5ab35 100644 --- a/src/compiler/cpp_generator.cc +++ b/src/compiler/cpp_generator.cc @@ -84,7 +84,7 @@ void PrintIncludes(grpc_generator::Printer* printer, } grpc::string GetHeaderPrologue(grpc_generator::File* file, - const Parameters& /*params*/) { + const Parameters& params) { grpc::string output; { // Scope the output stream so it closes and finalizes output to the string. @@ -94,7 +94,9 @@ grpc::string GetHeaderPrologue(grpc_generator::File* file, vars["filename"] = file->filename(); vars["filename_identifier"] = FilenameIdentifier(file->filename()); vars["filename_base"] = file->filename_without_ext(); - vars["message_header_ext"] = kCppGeneratorMessageHeaderExt; + vars["message_header_ext"] = params.message_header_extension.empty() + ? kCppGeneratorMessageHeaderExt + : params.message_header_extension; printer->Print(vars, "// Generated by the gRPC C++ plugin.\n"); printer->Print(vars, @@ -115,6 +117,13 @@ grpc::string GetHeaderPrologue(grpc_generator::File* file, return output; } +// Convert from "a/b/c.proto" to "#include \"a/b/c$message_header_ext$\"\n" +grpc::string ImportInludeFromProtoName(const grpc::string& proto_name) { + return grpc::string("#include \"") + + proto_name.substr(0, proto_name.size() - 6) + + grpc::string("$message_header_ext$\"\n"); +} + grpc::string GetHeaderIncludes(grpc_generator::File* file, const Parameters& params) { grpc::string output; @@ -132,6 +141,7 @@ grpc::string GetHeaderIncludes(grpc_generator::File* file, "grpcpp/impl/codegen/async_generic_service.h", "grpcpp/impl/codegen/async_stream.h", "grpcpp/impl/codegen/async_unary_call.h", + "grpcpp/impl/codegen/client_callback.h", "grpcpp/impl/codegen/method_handler_impl.h", "grpcpp/impl/codegen/proto_utils.h", "grpcpp/impl/codegen/rpc_method.h", @@ -144,13 +154,35 @@ grpc::string GetHeaderIncludes(grpc_generator::File* file, PrintIncludes(printer.get(), headers, params.use_system_headers, params.grpc_search_path); printer->Print(vars, "\n"); - printer->Print(vars, "namespace grpc {\n"); - printer->Print(vars, "class CompletionQueue;\n"); + printer->Print(vars, "namespace grpc_impl {\n"); printer->Print(vars, "class Channel;\n"); + printer->Print(vars, "class CompletionQueue;\n"); printer->Print(vars, "class ServerCompletionQueue;\n"); + printer->Print(vars, "} // namespace grpc_impl\n\n"); + printer->Print(vars, "namespace grpc {\n"); + printer->Print(vars, "namespace experimental {\n"); + printer->Print(vars, "template \n"); + printer->Print(vars, "class MessageAllocator;\n"); + printer->Print(vars, "} // namespace experimental\n"); + printer->Print(vars, "} // namespace grpc_impl\n\n"); + printer->Print(vars, "namespace grpc {\n"); printer->Print(vars, "class ServerContext;\n"); printer->Print(vars, "} // namespace grpc\n\n"); + vars["message_header_ext"] = params.message_header_extension.empty() + ? kCppGeneratorMessageHeaderExt + : params.message_header_extension; + + if (params.include_import_headers) { + const std::vector import_names = file->GetImportNames(); + for (const auto& import_name : import_names) { + const grpc::string include_name = + ImportInludeFromProtoName(import_name); + printer->Print(vars, include_name.c_str()); + } + printer->PrintRaw("\n"); + } + if (!file->package().empty()) { std::vector parts = file->package_parts(); @@ -579,12 +611,35 @@ void PrintHeaderClientMethodCallbackInterfaces( "virtual void $Method$(::grpc::ClientContext* context, " "const $Request$* request, $Response$* response, " "std::function) = 0;\n"); + printer->Print(*vars, + "virtual void $Method$(::grpc::ClientContext* context, " + "const ::grpc::ByteBuffer* request, $Response$* response, " + "std::function) = 0;\n"); + printer->Print(*vars, + "virtual void $Method$(::grpc::ClientContext* context, " + "const $Request$* request, $Response$* response, " + "::grpc::experimental::ClientUnaryReactor* reactor) = 0;\n"); + printer->Print(*vars, + "virtual void $Method$(::grpc::ClientContext* context, " + "const ::grpc::ByteBuffer* request, $Response$* response, " + "::grpc::experimental::ClientUnaryReactor* reactor) = 0;\n"); } else if (ClientOnlyStreaming(method)) { - // TODO(vjpai): Add support for client-side streaming + printer->Print(*vars, + "virtual void $Method$(::grpc::ClientContext* context, " + "$Response$* response, " + "::grpc::experimental::ClientWriteReactor< $Request$>* " + "reactor) = 0;\n"); } else if (ServerOnlyStreaming(method)) { - // TODO(vjpai): Add support for server-side streaming + printer->Print(*vars, + "virtual void $Method$(::grpc::ClientContext* context, " + "$Request$* request, " + "::grpc::experimental::ClientReadReactor< $Response$>* " + "reactor) = 0;\n"); } else if (method->BidiStreaming()) { - // TODO(vjpai): Add support for bidi streaming + printer->Print(*vars, + "virtual void $Method$(::grpc::ClientContext* context, " + "::grpc::experimental::ClientBidiReactor< " + "$Request$,$Response$>* reactor) = 0;\n"); } } @@ -630,12 +685,38 @@ void PrintHeaderClientMethodCallback(grpc_generator::Printer* printer, "void $Method$(::grpc::ClientContext* context, " "const $Request$* request, $Response$* response, " "std::function) override;\n"); + printer->Print(*vars, + "void $Method$(::grpc::ClientContext* context, " + "const ::grpc::ByteBuffer* request, $Response$* response, " + "std::function) override;\n"); + printer->Print( + *vars, + "void $Method$(::grpc::ClientContext* context, " + "const $Request$* request, $Response$* response, " + "::grpc::experimental::ClientUnaryReactor* reactor) override;\n"); + printer->Print( + *vars, + "void $Method$(::grpc::ClientContext* context, " + "const ::grpc::ByteBuffer* request, $Response$* response, " + "::grpc::experimental::ClientUnaryReactor* reactor) override;\n"); } else if (ClientOnlyStreaming(method)) { - // TODO(vjpai): Add support for client-side streaming + printer->Print(*vars, + "void $Method$(::grpc::ClientContext* context, " + "$Response$* response, " + "::grpc::experimental::ClientWriteReactor< $Request$>* " + "reactor) override;\n"); } else if (ServerOnlyStreaming(method)) { - // TODO(vjpai): Add support for server-side streaming + printer->Print(*vars, + "void $Method$(::grpc::ClientContext* context, " + "$Request$* request, " + "::grpc::experimental::ClientReadReactor< $Response$>* " + "reactor) override;\n"); + } else if (method->BidiStreaming()) { - // TODO(vjpai): Add support for bidi streaming + printer->Print(*vars, + "void $Method$(::grpc::ClientContext* context, " + "::grpc::experimental::ClientBidiReactor< " + "$Request$,$Response$>* reactor) override;\n"); } } @@ -865,6 +946,11 @@ void PrintHeaderServerCallbackMethodsHelper( " abort();\n" " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n" "}\n"); + printer->Print(*vars, + "virtual ::grpc::experimental::ServerReadReactor< " + "$RealRequest$, $RealResponse$>* $Method$() {\n" + " return new ::grpc::internal::UnimplementedReadReactor<\n" + " $RealRequest$, $RealResponse$>;}\n"); } else if (ServerOnlyStreaming(method)) { printer->Print( *vars, @@ -876,6 +962,11 @@ void PrintHeaderServerCallbackMethodsHelper( " abort();\n" " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n" "}\n"); + printer->Print(*vars, + "virtual ::grpc::experimental::ServerWriteReactor< " + "$RealRequest$, $RealResponse$>* $Method$() {\n" + " return new ::grpc::internal::UnimplementedWriteReactor<\n" + " $RealRequest$, $RealResponse$>;}\n"); } else if (method->BidiStreaming()) { printer->Print( *vars, @@ -887,6 +978,11 @@ void PrintHeaderServerCallbackMethodsHelper( " abort();\n" " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n" "}\n"); + printer->Print(*vars, + "virtual ::grpc::experimental::ServerBidiReactor< " + "$RealRequest$, $RealResponse$>* $Method$() {\n" + " return new ::grpc::internal::UnimplementedBidiReactor<\n" + " $RealRequest$, $RealResponse$>;}\n"); } } @@ -915,22 +1011,44 @@ void PrintHeaderServerMethodCallback( *vars, " ::grpc::Service::experimental().MarkMethodCallback($Idx$,\n" " new ::grpc::internal::CallbackUnaryHandler< " - "ExperimentalWithCallbackMethod_$Method$, $RealRequest$, " - "$RealResponse$>(\n" + "$RealRequest$, $RealResponse$>(\n" " [this](::grpc::ServerContext* context,\n" " const $RealRequest$* request,\n" " $RealResponse$* response,\n" " ::grpc::experimental::ServerCallbackRpcController* " "controller) {\n" - " this->$" + " return this->$" "Method$(context, request, response, controller);\n" - " }, this));\n"); + " }));\n}\n"); + printer->Print(*vars, + "void SetMessageAllocatorFor_$Method$(\n" + " ::grpc::experimental::MessageAllocator< " + "$RealRequest$, $RealResponse$>* allocator) {\n" + " static_cast<::grpc::internal::CallbackUnaryHandler< " + "$RealRequest$, $RealResponse$>*>(\n" + " ::grpc::Service::experimental().GetHandler($Idx$))\n" + " ->SetMessageAllocator(allocator);\n"); } else if (ClientOnlyStreaming(method)) { - // TODO(vjpai): Add in code generation for all streaming methods + printer->Print( + *vars, + " ::grpc::Service::experimental().MarkMethodCallback($Idx$,\n" + " new ::grpc::internal::CallbackClientStreamingHandler< " + "$RealRequest$, $RealResponse$>(\n" + " [this] { return this->$Method$(); }));\n"); } else if (ServerOnlyStreaming(method)) { - // TODO(vjpai): Add in code generation for all streaming methods + printer->Print( + *vars, + " ::grpc::Service::experimental().MarkMethodCallback($Idx$,\n" + " new ::grpc::internal::CallbackServerStreamingHandler< " + "$RealRequest$, $RealResponse$>(\n" + " [this] { return this->$Method$(); }));\n"); } else if (method->BidiStreaming()) { - // TODO(vjpai): Add in code generation for all streaming methods + printer->Print( + *vars, + " ::grpc::Service::experimental().MarkMethodCallback($Idx$,\n" + " new ::grpc::internal::CallbackBidiHandler< " + "$RealRequest$, $RealResponse$>(\n" + " [this] { return this->$Method$(); }));\n"); } printer->Print(*vars, "}\n"); printer->Print(*vars, @@ -967,8 +1085,7 @@ void PrintHeaderServerMethodRawCallback( *vars, " ::grpc::Service::experimental().MarkMethodRawCallback($Idx$,\n" " new ::grpc::internal::CallbackUnaryHandler< " - "ExperimentalWithRawCallbackMethod_$Method$, $RealRequest$, " - "$RealResponse$>(\n" + "$RealRequest$, $RealResponse$>(\n" " [this](::grpc::ServerContext* context,\n" " const $RealRequest$* request,\n" " $RealResponse$* response,\n" @@ -976,13 +1093,28 @@ void PrintHeaderServerMethodRawCallback( "controller) {\n" " this->$" "Method$(context, request, response, controller);\n" - " }, this));\n"); + " }));\n"); } else if (ClientOnlyStreaming(method)) { - // TODO(vjpai): Add in code generation for all streaming methods + printer->Print( + *vars, + " ::grpc::Service::experimental().MarkMethodRawCallback($Idx$,\n" + " new ::grpc::internal::CallbackClientStreamingHandler< " + "$RealRequest$, $RealResponse$>(\n" + " [this] { return this->$Method$(); }));\n"); } else if (ServerOnlyStreaming(method)) { - // TODO(vjpai): Add in code generation for all streaming methods + printer->Print( + *vars, + " ::grpc::Service::experimental().MarkMethodRawCallback($Idx$,\n" + " new ::grpc::internal::CallbackServerStreamingHandler< " + "$RealRequest$, $RealResponse$>(\n" + " [this] { return this->$Method$(); }));\n"); } else if (method->BidiStreaming()) { - // TODO(vjpai): Add in code generation for all streaming methods + printer->Print( + *vars, + " ::grpc::Service::experimental().MarkMethodRawCallback($Idx$,\n" + " new ::grpc::internal::CallbackBidiHandler< " + "$RealRequest$, $RealResponse$>(\n" + " [this] { return this->$Method$(); }));\n"); } printer->Print(*vars, "}\n"); printer->Print(*vars, @@ -1481,7 +1613,7 @@ grpc::string GetHeaderEpilogue(grpc_generator::File* file, } grpc::string GetSourcePrologue(grpc_generator::File* file, - const Parameters& /*params*/) { + const Parameters& params) { grpc::string output; { // Scope the output stream so it closes and finalizes output to the string. @@ -1490,7 +1622,9 @@ grpc::string GetSourcePrologue(grpc_generator::File* file, vars["filename"] = file->filename(); vars["filename_base"] = file->filename_without_ext(); - vars["message_header_ext"] = kCppGeneratorMessageHeaderExt; + vars["message_header_ext"] = params.message_header_extension.empty() + ? kCppGeneratorMessageHeaderExt + : params.message_header_extension; vars["service_header_ext"] = kCppGeneratorServiceHeaderExt; printer->Print(vars, "// Generated by the gRPC C++ plugin.\n"); @@ -1512,7 +1646,6 @@ grpc::string GetSourceIncludes(grpc_generator::File* file, // Scope the output stream so it closes and finalizes output to the string. auto printer = file->CreatePrinter(&output); std::map vars; - static const char* headers_strs[] = { "functional", "grpcpp/impl/codegen/async_stream.h", @@ -1572,10 +1705,40 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer, "const $Request$* request, $Response$* response, " "std::function f) {\n"); printer->Print(*vars, - " return ::grpc::internal::CallbackUnaryCall" + " ::grpc::internal::CallbackUnaryCall" "(stub_->channel_.get(), stub_->rpcmethod_$Method$_, " "context, request, response, std::move(f));\n}\n\n"); + printer->Print(*vars, + "void $ns$$Service$::Stub::experimental_async::$Method$(" + "::grpc::ClientContext* context, " + "const ::grpc::ByteBuffer* request, $Response$* response, " + "std::function f) {\n"); + printer->Print(*vars, + " ::grpc::internal::CallbackUnaryCall" + "(stub_->channel_.get(), stub_->rpcmethod_$Method$_, " + "context, request, response, std::move(f));\n}\n\n"); + + printer->Print(*vars, + "void $ns$$Service$::Stub::experimental_async::$Method$(" + "::grpc::ClientContext* context, " + "const $Request$* request, $Response$* response, " + "::grpc::experimental::ClientUnaryReactor* reactor) {\n"); + printer->Print(*vars, + " ::grpc::internal::ClientCallbackUnaryFactory::Create" + "(stub_->channel_.get(), stub_->rpcmethod_$Method$_, " + "context, request, response, reactor);\n}\n\n"); + + printer->Print(*vars, + "void $ns$$Service$::Stub::experimental_async::$Method$(" + "::grpc::ClientContext* context, " + "const ::grpc::ByteBuffer* request, $Response$* response, " + "::grpc::experimental::ClientUnaryReactor* reactor) {\n"); + printer->Print(*vars, + " ::grpc::internal::ClientCallbackUnaryFactory::Create" + "(stub_->channel_.get(), stub_->rpcmethod_$Method$_, " + "context, request, response, reactor);\n}\n\n"); + for (auto async_prefix : async_prefixes) { (*vars)["AsyncPrefix"] = async_prefix.prefix; (*vars)["AsyncStart"] = async_prefix.start; @@ -1607,7 +1770,19 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer, "context, response);\n" "}\n\n"); - // TODO(vjpai): Add callback version + printer->Print( + *vars, + "void $ns$$Service$::" + "Stub::experimental_async::$Method$(::grpc::ClientContext* context, " + "$Response$* response, " + "::grpc::experimental::ClientWriteReactor< $Request$>* reactor) {\n"); + printer->Print(*vars, + " ::grpc::internal::ClientCallbackWriterFactory< " + "$Request$>::Create(" + "stub_->channel_.get(), " + "stub_->rpcmethod_$Method$_, " + "context, response, reactor);\n" + "}\n\n"); for (auto async_prefix : async_prefixes) { (*vars)["AsyncPrefix"] = async_prefix.prefix; @@ -1641,7 +1816,19 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer, "context, request);\n" "}\n\n"); - // TODO(vjpai): Add callback version + printer->Print( + *vars, + "void $ns$$Service$::Stub::experimental_async::$Method$(::grpc::" + "ClientContext* context, " + "$Request$* request, " + "::grpc::experimental::ClientReadReactor< $Response$>* reactor) {\n"); + printer->Print(*vars, + " ::grpc::internal::ClientCallbackReaderFactory< " + "$Response$>::Create(" + "stub_->channel_.get(), " + "stub_->rpcmethod_$Method$_, " + "context, request, reactor);\n" + "}\n\n"); for (auto async_prefix : async_prefixes) { (*vars)["AsyncPrefix"] = async_prefix.prefix; @@ -1675,7 +1862,19 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer, "context);\n" "}\n\n"); - // TODO(vjpai): Add callback version + printer->Print( + *vars, + "void $ns$$Service$::Stub::experimental_async::$Method$(::grpc::" + "ClientContext* context, " + "::grpc::experimental::ClientBidiReactor< $Request$,$Response$>* " + "reactor) {\n"); + printer->Print(*vars, + " ::grpc::internal::ClientCallbackReaderWriterFactory< " + "$Request$,$Response$>::Create(" + "stub_->channel_.get(), " + "stub_->rpcmethod_$Method$_, " + "context, reactor);\n" + "}\n\n"); for (auto async_prefix : async_prefixes) { (*vars)["AsyncPrefix"] = async_prefix.prefix; @@ -1925,7 +2124,7 @@ grpc::string GetSourceEpilogue(grpc_generator::File* file, // TODO(mmukhi): Make sure we need parameters or not. grpc::string GetMockPrologue(grpc_generator::File* file, - const Parameters& /*params*/) { + const Parameters& params) { grpc::string output; { // Scope the output stream so it closes and finalizes output to the string. @@ -1934,7 +2133,9 @@ grpc::string GetMockPrologue(grpc_generator::File* file, vars["filename"] = file->filename(); vars["filename_base"] = file->filename_without_ext(); - vars["message_header_ext"] = kCppGeneratorMessageHeaderExt; + vars["message_header_ext"] = params.message_header_extension.empty() + ? kCppGeneratorMessageHeaderExt + : params.message_header_extension; vars["service_header_ext"] = kCppGeneratorServiceHeaderExt; printer->Print(vars, "// Generated by the gRPC C++ plugin.\n"); @@ -1944,6 +2145,15 @@ grpc::string GetMockPrologue(grpc_generator::File* file, printer->Print(vars, "#include \"$filename_base$$message_header_ext$\"\n"); printer->Print(vars, "#include \"$filename_base$$service_header_ext$\"\n"); + if (params.include_import_headers) { + const std::vector import_names = file->GetImportNames(); + for (const auto& import_name : import_names) { + const grpc::string include_name = + ImportInludeFromProtoName(import_name); + printer->Print(vars, include_name.c_str()); + } + printer->PrintRaw("\n"); + } printer->Print(vars, file->additional_headers().c_str()); printer->Print(vars, "\n"); } diff --git a/src/compiler/cpp_generator.h b/src/compiler/cpp_generator.h index d88ef75c987..c1d64e61d7b 100644 --- a/src/compiler/cpp_generator.h +++ b/src/compiler/cpp_generator.h @@ -56,6 +56,10 @@ struct Parameters { grpc::string gmock_search_path; // *EXPERIMENTAL* Additional include files in grpc.pb.h std::vector additional_header_includes; + // By default, use "pb.h" + grpc::string message_header_extension; + // Whether to include headers corresponding to imports in source file. + bool include_import_headers; }; // Return the prologue of the generated header file. diff --git a/src/compiler/cpp_generator_helpers.h b/src/compiler/cpp_generator_helpers.h index b8efcbdb843..f9a69373bd1 100644 --- a/src/compiler/cpp_generator_helpers.h +++ b/src/compiler/cpp_generator_helpers.h @@ -52,7 +52,7 @@ inline grpc::string ClassName(const grpc::protobuf::Descriptor* descriptor, } // Get leading or trailing comments in a string. Comment lines start with "// ". -// Leading detached comments are put in in front of leading comments. +// Leading detached comments are put in front of leading comments. template inline grpc::string GetCppComments(const DescriptorType* desc, bool leading) { return grpc_generator::GetPrefixedComments(desc, leading, "//"); diff --git a/src/compiler/cpp_plugin.cc b/src/compiler/cpp_plugin.cc index c8ab78863bf..2de2745445f 100644 --- a/src/compiler/cpp_plugin.cc +++ b/src/compiler/cpp_plugin.cc @@ -18,127 +18,7 @@ // Generates cpp gRPC service interface out of Protobuf IDL. // - -#include -#include - -#include "src/compiler/config.h" - -#include "src/compiler/cpp_generator.h" -#include "src/compiler/generator_helpers.h" -#include "src/compiler/protobuf_plugin.h" - -class CppGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator { - public: - CppGrpcGenerator() {} - virtual ~CppGrpcGenerator() {} - - virtual bool Generate(const grpc::protobuf::FileDescriptor* file, - const grpc::string& parameter, - grpc::protobuf::compiler::GeneratorContext* context, - grpc::string* error) const { - if (file->options().cc_generic_services()) { - *error = - "cpp grpc proto compiler plugin does not work with generic " - "services. To generate cpp grpc APIs, please set \"" - "cc_generic_service = false\"."; - return false; - } - - grpc_cpp_generator::Parameters generator_parameters; - generator_parameters.use_system_headers = true; - generator_parameters.generate_mock_code = false; - - ProtoBufFile pbfile(file); - - if (!parameter.empty()) { - std::vector parameters_list = - grpc_generator::tokenize(parameter, ","); - for (auto parameter_string = parameters_list.begin(); - parameter_string != parameters_list.end(); parameter_string++) { - std::vector param = - grpc_generator::tokenize(*parameter_string, "="); - if (param[0] == "services_namespace") { - generator_parameters.services_namespace = param[1]; - } else if (param[0] == "use_system_headers") { - if (param[1] == "true") { - generator_parameters.use_system_headers = true; - } else if (param[1] == "false") { - generator_parameters.use_system_headers = false; - } else { - *error = grpc::string("Invalid parameter: ") + *parameter_string; - return false; - } - } else if (param[0] == "grpc_search_path") { - generator_parameters.grpc_search_path = param[1]; - } else if (param[0] == "generate_mock_code") { - if (param[1] == "true") { - generator_parameters.generate_mock_code = true; - } else if (param[1] != "false") { - *error = grpc::string("Invalid parameter: ") + *parameter_string; - return false; - } - } else if (param[0] == "gmock_search_path") { - generator_parameters.gmock_search_path = param[1]; - } else if (param[0] == "additional_header_includes") { - generator_parameters.additional_header_includes = - grpc_generator::tokenize(param[1], ":"); - } else { - *error = grpc::string("Unknown parameter: ") + *parameter_string; - return false; - } - } - } - - grpc::string file_name = grpc_generator::StripProto(file->name()); - - grpc::string header_code = - grpc_cpp_generator::GetHeaderPrologue(&pbfile, generator_parameters) + - grpc_cpp_generator::GetHeaderIncludes(&pbfile, generator_parameters) + - grpc_cpp_generator::GetHeaderServices(&pbfile, generator_parameters) + - grpc_cpp_generator::GetHeaderEpilogue(&pbfile, generator_parameters); - std::unique_ptr header_output( - context->Open(file_name + ".grpc.pb.h")); - grpc::protobuf::io::CodedOutputStream header_coded_out(header_output.get()); - header_coded_out.WriteRaw(header_code.data(), header_code.size()); - - grpc::string source_code = - grpc_cpp_generator::GetSourcePrologue(&pbfile, generator_parameters) + - grpc_cpp_generator::GetSourceIncludes(&pbfile, generator_parameters) + - grpc_cpp_generator::GetSourceServices(&pbfile, generator_parameters) + - grpc_cpp_generator::GetSourceEpilogue(&pbfile, generator_parameters); - std::unique_ptr source_output( - context->Open(file_name + ".grpc.pb.cc")); - grpc::protobuf::io::CodedOutputStream source_coded_out(source_output.get()); - source_coded_out.WriteRaw(source_code.data(), source_code.size()); - - if (!generator_parameters.generate_mock_code) { - return true; - } - grpc::string mock_code = - grpc_cpp_generator::GetMockPrologue(&pbfile, generator_parameters) + - grpc_cpp_generator::GetMockIncludes(&pbfile, generator_parameters) + - grpc_cpp_generator::GetMockServices(&pbfile, generator_parameters) + - grpc_cpp_generator::GetMockEpilogue(&pbfile, generator_parameters); - std::unique_ptr mock_output( - context->Open(file_name + "_mock.grpc.pb.h")); - grpc::protobuf::io::CodedOutputStream mock_coded_out(mock_output.get()); - mock_coded_out.WriteRaw(mock_code.data(), mock_code.size()); - - return true; - } - - private: - // Insert the given code into the given file at the given insertion point. - void Insert(grpc::protobuf::compiler::GeneratorContext* context, - const grpc::string& filename, const grpc::string& insertion_point, - const grpc::string& code) const { - std::unique_ptr output( - context->OpenForInsert(filename, insertion_point)); - grpc::protobuf::io::CodedOutputStream coded_out(output.get()); - coded_out.WriteRaw(code.data(), code.size()); - } -}; +#include "src/compiler/cpp_plugin.h" int main(int argc, char* argv[]) { CppGrpcGenerator generator; diff --git a/src/compiler/cpp_plugin.h b/src/compiler/cpp_plugin.h new file mode 100644 index 00000000000..1cdf0b3c196 --- /dev/null +++ b/src/compiler/cpp_plugin.h @@ -0,0 +1,154 @@ +/* + * + * Copyright 2019 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_INTERNAL_COMPILER_CPP_PLUGIN_H +#define GRPC_INTERNAL_COMPILER_CPP_PLUGIN_H + +#include +#include + +#include "src/compiler/config.h" + +#include "src/compiler/cpp_generator.h" +#include "src/compiler/generator_helpers.h" +#include "src/compiler/protobuf_plugin.h" + +// Cpp Generator for Protobug IDL +class CppGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator { + public: + CppGrpcGenerator() {} + virtual ~CppGrpcGenerator() {} + + virtual bool Generate(const grpc::protobuf::FileDescriptor* file, + const grpc::string& parameter, + grpc::protobuf::compiler::GeneratorContext* context, + grpc::string* error) const { + if (file->options().cc_generic_services()) { + *error = + "cpp grpc proto compiler plugin does not work with generic " + "services. To generate cpp grpc APIs, please set \"" + "cc_generic_service = false\"."; + return false; + } + + grpc_cpp_generator::Parameters generator_parameters; + generator_parameters.use_system_headers = true; + generator_parameters.generate_mock_code = false; + generator_parameters.include_import_headers = false; + + ProtoBufFile pbfile(file); + + if (!parameter.empty()) { + std::vector parameters_list = + grpc_generator::tokenize(parameter, ","); + for (auto parameter_string = parameters_list.begin(); + parameter_string != parameters_list.end(); parameter_string++) { + std::vector param = + grpc_generator::tokenize(*parameter_string, "="); + if (param[0] == "services_namespace") { + generator_parameters.services_namespace = param[1]; + } else if (param[0] == "use_system_headers") { + if (param[1] == "true") { + generator_parameters.use_system_headers = true; + } else if (param[1] == "false") { + generator_parameters.use_system_headers = false; + } else { + *error = grpc::string("Invalid parameter: ") + *parameter_string; + return false; + } + } else if (param[0] == "grpc_search_path") { + generator_parameters.grpc_search_path = param[1]; + } else if (param[0] == "generate_mock_code") { + if (param[1] == "true") { + generator_parameters.generate_mock_code = true; + } else if (param[1] != "false") { + *error = grpc::string("Invalid parameter: ") + *parameter_string; + return false; + } + } else if (param[0] == "gmock_search_path") { + generator_parameters.gmock_search_path = param[1]; + } else if (param[0] == "additional_header_includes") { + generator_parameters.additional_header_includes = + grpc_generator::tokenize(param[1], ":"); + } else if (param[0] == "message_header_extension") { + generator_parameters.message_header_extension = param[1]; + } else if (param[0] == "include_import_headers") { + if (param[1] == "true") { + generator_parameters.include_import_headers = true; + } else if (param[1] != "false") { + *error = grpc::string("Invalid parameter: ") + *parameter_string; + return false; + } + } else { + *error = grpc::string("Unknown parameter: ") + *parameter_string; + return false; + } + } + } + + grpc::string file_name = grpc_generator::StripProto(file->name()); + + grpc::string header_code = + grpc_cpp_generator::GetHeaderPrologue(&pbfile, generator_parameters) + + grpc_cpp_generator::GetHeaderIncludes(&pbfile, generator_parameters) + + grpc_cpp_generator::GetHeaderServices(&pbfile, generator_parameters) + + grpc_cpp_generator::GetHeaderEpilogue(&pbfile, generator_parameters); + std::unique_ptr header_output( + context->Open(file_name + ".grpc.pb.h")); + grpc::protobuf::io::CodedOutputStream header_coded_out(header_output.get()); + header_coded_out.WriteRaw(header_code.data(), header_code.size()); + + grpc::string source_code = + grpc_cpp_generator::GetSourcePrologue(&pbfile, generator_parameters) + + grpc_cpp_generator::GetSourceIncludes(&pbfile, generator_parameters) + + grpc_cpp_generator::GetSourceServices(&pbfile, generator_parameters) + + grpc_cpp_generator::GetSourceEpilogue(&pbfile, generator_parameters); + std::unique_ptr source_output( + context->Open(file_name + ".grpc.pb.cc")); + grpc::protobuf::io::CodedOutputStream source_coded_out(source_output.get()); + source_coded_out.WriteRaw(source_code.data(), source_code.size()); + + if (!generator_parameters.generate_mock_code) { + return true; + } + grpc::string mock_code = + grpc_cpp_generator::GetMockPrologue(&pbfile, generator_parameters) + + grpc_cpp_generator::GetMockIncludes(&pbfile, generator_parameters) + + grpc_cpp_generator::GetMockServices(&pbfile, generator_parameters) + + grpc_cpp_generator::GetMockEpilogue(&pbfile, generator_parameters); + std::unique_ptr mock_output( + context->Open(file_name + "_mock.grpc.pb.h")); + grpc::protobuf::io::CodedOutputStream mock_coded_out(mock_output.get()); + mock_coded_out.WriteRaw(mock_code.data(), mock_code.size()); + + return true; + } + + private: + // Insert the given code into the given file at the given insertion point. + void Insert(grpc::protobuf::compiler::GeneratorContext* context, + const grpc::string& filename, const grpc::string& insertion_point, + const grpc::string& code) const { + std::unique_ptr output( + context->OpenForInsert(filename, insertion_point)); + grpc::protobuf::io::CodedOutputStream coded_out(output.get()); + coded_out.WriteRaw(code.data(), code.size()); + } +}; + +#endif // GRPC_INTERNAL_COMPILER_CPP_PLUGIN_H diff --git a/src/compiler/csharp_generator.cc b/src/compiler/csharp_generator.cc index 59ddbd82f61..778e5c39284 100644 --- a/src/compiler/csharp_generator.cc +++ b/src/compiler/csharp_generator.cc @@ -199,6 +199,21 @@ std::string GetCSharpMethodType(MethodType method_type) { return ""; } +std::string GetCSharpServerMethodType(MethodType method_type) { + switch (method_type) { + case METHODTYPE_NO_STREAMING: + return "grpc::UnaryServerMethod"; + case METHODTYPE_CLIENT_STREAMING: + return "grpc::ClientStreamingServerMethod"; + case METHODTYPE_SERVER_STREAMING: + return "grpc::ServerStreamingServerMethod"; + case METHODTYPE_BIDI_STREAMING: + return "grpc::DuplexStreamingServerMethod"; + } + GOOGLE_LOG(FATAL) << "Can't get here."; + return ""; +} + std::string GetServiceNameFieldName() { return "__ServiceName"; } std::string GetMarshallerFieldName(const Descriptor* message) { @@ -367,6 +382,10 @@ void GenerateServerClass(Printer* out, const ServiceDescriptor* service) { "/// Base class for server-side implementations of " "$servicename$\n", "servicename", GetServiceClassName(service)); + out->Print( + "[grpc::BindServiceMethod(typeof($classname$), " + "\"BindService\")]\n", + "classname", GetServiceClassName(service)); out->Print("public abstract partial class $name$\n", "name", GetServerClassName(service)); out->Print("{\n"); @@ -612,8 +631,9 @@ void GenerateBindServiceMethod(Printer* out, const ServiceDescriptor* service) { void GenerateBindServiceWithBinderMethod(Printer* out, const ServiceDescriptor* service) { out->Print( - "/// Register service method implementations with a service " - "binder. Useful when customizing the service binding logic.\n" + "/// Register service method with a service " + "binder with or without implementation. Useful when customizing the " + "service binding logic.\n" "/// Note: this method is part of an experimental API that can change or " "be " "removed without any prior notice.\n"); @@ -635,9 +655,13 @@ void GenerateBindServiceWithBinderMethod(Printer* out, for (int i = 0; i < service->method_count(); i++) { const MethodDescriptor* method = service->method(i); out->Print( - "serviceBinder.AddMethod($methodfield$, serviceImpl.$methodname$);\n", - "methodfield", GetMethodFieldName(method), "methodname", - method->name()); + "serviceBinder.AddMethod($methodfield$, serviceImpl == null ? null : " + "new $servermethodtype$<$inputtype$, $outputtype$>(" + "serviceImpl.$methodname$));\n", + "methodfield", GetMethodFieldName(method), "servermethodtype", + GetCSharpServerMethodType(GetMethodType(method)), "inputtype", + GetClassName(method->input_type()), "outputtype", + GetClassName(method->output_type()), "methodname", method->name()); } out->Outdent(); diff --git a/src/compiler/csharp_generator_helpers.h b/src/compiler/csharp_generator_helpers.h index 8c89925551c..0d9ae6360dd 100644 --- a/src/compiler/csharp_generator_helpers.h +++ b/src/compiler/csharp_generator_helpers.h @@ -32,7 +32,7 @@ inline bool ServicesFilename(const grpc::protobuf::FileDescriptor* file, } // Get leading or trailing comments in a string. Comment lines start with "// ". -// Leading detached comments are put in in front of leading comments. +// Leading detached comments are put in front of leading comments. template inline grpc::string GetCsharpComments(const DescriptorType* desc, bool leading) { diff --git a/src/compiler/node_generator_helpers.h b/src/compiler/node_generator_helpers.h index 82d2d845441..110749f77f1 100644 --- a/src/compiler/node_generator_helpers.h +++ b/src/compiler/node_generator_helpers.h @@ -31,7 +31,7 @@ inline grpc::string GetJSServiceFilename(const grpc::string& filename) { } // Get leading or trailing comments in a string. Comment lines start with "// ". -// Leading detached comments are put in in front of leading comments. +// Leading detached comments are put in front of leading comments. template inline grpc::string GetNodeComments(const DescriptorType* desc, bool leading) { return grpc_generator::GetPrefixedComments(desc, leading, "//"); diff --git a/src/compiler/objective_c_generator.cc b/src/compiler/objective_c_generator.cc index 39f68cb9565..24845ecdb06 100644 --- a/src/compiler/objective_c_generator.cc +++ b/src/compiler/objective_c_generator.cc @@ -50,7 +50,8 @@ void PrintProtoRpcDeclarationAsPragma( } template -static void PrintAllComments(const DescriptorType* desc, Printer* printer) { +static void PrintAllComments(const DescriptorType* desc, Printer* printer, + bool deprecated = false) { std::vector comments; grpc_generator::GetComment(desc, grpc_generator::COMMENTTYPE_LEADING_DETACHED, &comments); @@ -70,13 +71,20 @@ static void PrintAllComments(const DescriptorType* desc, Printer* printer) { } printer->Print("\n"); } + if (deprecated) { + printer->Print(" *\n"); + printer->Print( + " * This method belongs to a set of APIs that have been deprecated. " + "Using" + " the v2 API is recommended.\n"); + } printer->Print(" */\n"); } void PrintMethodSignature(Printer* printer, const MethodDescriptor* method, const map< ::grpc::string, ::grpc::string>& vars) { // Print comment - PrintAllComments(method, printer); + PrintAllComments(method, printer, true); printer->Print(vars, "- ($return_type$)$method_name$With"); if (method->client_streaming()) { @@ -113,6 +121,29 @@ void PrintAdvancedSignature(Printer* printer, const MethodDescriptor* method, PrintMethodSignature(printer, method, vars); } +void PrintV2Signature(Printer* printer, const MethodDescriptor* method, + map< ::grpc::string, ::grpc::string> vars) { + if (method->client_streaming()) { + vars["return_type"] = "GRPCStreamingProtoCall *"; + } else { + vars["return_type"] = "GRPCUnaryProtoCall *"; + } + vars["method_name"] = + grpc_generator::LowercaseFirstLetter(vars["method_name"]); + + PrintAllComments(method, printer); + + printer->Print(vars, "- ($return_type$)$method_name$With"); + if (method->client_streaming()) { + printer->Print("ResponseHandler:(id)handler"); + } else { + printer->Print(vars, + "Message:($request_class$ *)message " + "responseHandler:(id)handler"); + } + printer->Print(" callOptions:(GRPCCallOptions *_Nullable)callOptions"); +} + inline map< ::grpc::string, ::grpc::string> GetMethodVars( const MethodDescriptor* method) { map< ::grpc::string, ::grpc::string> res; @@ -135,6 +166,16 @@ void PrintMethodDeclarations(Printer* printer, const MethodDescriptor* method) { printer->Print(";\n\n\n"); } +void PrintV2MethodDeclarations(Printer* printer, + const MethodDescriptor* method) { + map< ::grpc::string, ::grpc::string> vars = GetMethodVars(method); + + PrintProtoRpcDeclarationAsPragma(printer, method, vars); + + PrintV2Signature(printer, method, vars); + printer->Print(";\n\n"); +} + void PrintSimpleImplementation(Printer* printer, const MethodDescriptor* method, map< ::grpc::string, ::grpc::string> vars) { printer->Print("{\n"); @@ -177,6 +218,25 @@ void PrintAdvancedImplementation(Printer* printer, printer->Print("}\n"); } +void PrintV2Implementation(Printer* printer, const MethodDescriptor* method, + map< ::grpc::string, ::grpc::string> vars) { + printer->Print(" {\n"); + if (method->client_streaming()) { + printer->Print(vars, " return [self RPCToMethod:@\"$method_name$\"\n"); + printer->Print(" responseHandler:handler\n"); + printer->Print(" callOptions:callOptions\n"); + printer->Print( + vars, " responseClass:[$response_class$ class]];\n}\n\n"); + } else { + printer->Print(vars, " return [self RPCToMethod:@\"$method_name$\"\n"); + printer->Print(" message:message\n"); + printer->Print(" responseHandler:handler\n"); + printer->Print(" callOptions:callOptions\n"); + printer->Print( + vars, " responseClass:[$response_class$ class]];\n}\n\n"); + } +} + void PrintMethodImplementations(Printer* printer, const MethodDescriptor* method) { map< ::grpc::string, ::grpc::string> vars = GetMethodVars(method); @@ -184,12 +244,16 @@ void PrintMethodImplementations(Printer* printer, PrintProtoRpcDeclarationAsPragma(printer, method, vars); // TODO(jcanizales): Print documentation from the method. + printer->Print("// Deprecated methods.\n"); PrintSimpleSignature(printer, method, vars); PrintSimpleImplementation(printer, method, vars); printer->Print("// Returns a not-yet-started RPC object.\n"); PrintAdvancedSignature(printer, method, vars); PrintAdvancedImplementation(printer, method, vars); + + PrintV2Signature(printer, method, vars); + PrintV2Implementation(printer, method, vars); } } // namespace @@ -222,6 +286,13 @@ void PrintMethodImplementations(Printer* printer, map< ::grpc::string, ::grpc::string> vars = { {"service_class", ServiceClassName(service)}}; + printer.Print(vars, + "/**\n" + " * The methods in this protocol belong to a set of old APIs " + "that have been deprecated. They do not\n" + " * recognize call options provided in the initializer. Using " + "the v2 protocol is recommended.\n" + " */\n"); printer.Print(vars, "@protocol $service_class$ \n\n"); for (int i = 0; i < service->method_count(); i++) { PrintMethodDeclarations(&printer, service->method(i)); @@ -231,6 +302,25 @@ void PrintMethodImplementations(Printer* printer, return output; } +::grpc::string GetV2Protocol(const ServiceDescriptor* service) { + ::grpc::string output; + + // Scope the output stream so it closes and finalizes output to the string. + grpc::protobuf::io::StringOutputStream output_stream(&output); + Printer printer(&output_stream, '$'); + + map< ::grpc::string, ::grpc::string> vars = { + {"service_class", ServiceClassName(service) + "2"}}; + + printer.Print(vars, "@protocol $service_class$ \n\n"); + for (int i = 0; i < service->method_count(); i++) { + PrintV2MethodDeclarations(&printer, service->method(i)); + } + printer.Print("@end\n\n"); + + return output; +} + ::grpc::string GetInterface(const ServiceDescriptor* service) { ::grpc::string output; @@ -248,10 +338,19 @@ void PrintMethodImplementations(Printer* printer, " */\n"); printer.Print(vars, "@interface $service_class$ :" - " GRPCProtoService<$service_class$>\n"); + " GRPCProtoService<$service_class$, $service_class$2>\n"); printer.Print( - "- (instancetype)initWithHost:(NSString *)host" + "- (instancetype)initWithHost:(NSString *)host " + "callOptions:(GRPCCallOptions " + "*_Nullable)callOptions" " NS_DESIGNATED_INITIALIZER;\n"); + printer.Print( + "+ (instancetype)serviceWithHost:(NSString *)host " + "callOptions:(GRPCCallOptions *_Nullable)callOptions;\n"); + printer.Print( + "// The following methods belong to a set of old APIs that have been " + "deprecated.\n"); + printer.Print("- (instancetype)initWithHost:(NSString *)host;\n"); printer.Print("+ (instancetype)serviceWithHost:(NSString *)host;\n"); printer.Print("@end\n"); @@ -272,13 +371,23 @@ void PrintMethodImplementations(Printer* printer, printer.Print(vars, "@implementation $service_class$\n\n" + "#pragma clang diagnostic push\n" + "#pragma clang diagnostic ignored " + "\"-Wobjc-designated-initializers\"\n\n" "// Designated initializer\n" + "- (instancetype)initWithHost:(NSString *)host " + "callOptions:(GRPCCallOptions *_Nullable)callOptions {\n" + " return [super initWithHost:host\n" + " packageName:@\"$package$\"\n" + " serviceName:@\"$service_name$\"\n" + " callOptions:callOptions];\n" + "}\n\n" "- (instancetype)initWithHost:(NSString *)host {\n" - " self = [super initWithHost:host\n" + " return [super initWithHost:host\n" " packageName:@\"$package$\"\n" " serviceName:@\"$service_name$\"];\n" - " return self;\n" - "}\n\n"); + "}\n\n" + "#pragma clang diagnostic pop\n\n"); printer.Print( "// Override superclass initializer to disallow different" @@ -287,12 +396,22 @@ void PrintMethodImplementations(Printer* printer, " packageName:(NSString *)packageName\n" " serviceName:(NSString *)serviceName {\n" " return [self initWithHost:host];\n" + "}\n\n" + "- (instancetype)initWithHost:(NSString *)host\n" + " packageName:(NSString *)packageName\n" + " serviceName:(NSString *)serviceName\n" + " callOptions:(GRPCCallOptions *)callOptions {\n" + " return [self initWithHost:host callOptions:callOptions];\n" "}\n\n"); printer.Print( "#pragma mark - Class Methods\n\n" "+ (instancetype)serviceWithHost:(NSString *)host {\n" " return [[self alloc] initWithHost:host];\n" + "}\n\n" + "+ (instancetype)serviceWithHost:(NSString *)host " + "callOptions:(GRPCCallOptions *_Nullable)callOptions {\n" + " return [[self alloc] initWithHost:host callOptions:callOptions];\n" "}\n\n"); printer.Print("#pragma mark - Method Implementations\n\n"); diff --git a/src/compiler/objective_c_generator.h b/src/compiler/objective_c_generator.h index eb1c7ff005a..c171e5bf772 100644 --- a/src/compiler/objective_c_generator.h +++ b/src/compiler/objective_c_generator.h @@ -32,9 +32,14 @@ using ::grpc::string; string GetAllMessageClasses(const FileDescriptor* file); // Returns the content to be included defining the @protocol segment at the -// insertion point of the generated implementation file. +// insertion point of the generated implementation file. This interface is +// legacy and for backwards compatibility. string GetProtocol(const ServiceDescriptor* service); +// Returns the content to be included defining the @protocol segment at the +// insertion point of the generated implementation file. +string GetV2Protocol(const ServiceDescriptor* service); + // Returns the content to be included defining the @interface segment at the // insertion point of the generated implementation file. string GetInterface(const ServiceDescriptor* service); diff --git a/src/compiler/objective_c_plugin.cc b/src/compiler/objective_c_plugin.cc index f0fe3688cca..87977095d05 100644 --- a/src/compiler/objective_c_plugin.cc +++ b/src/compiler/objective_c_plugin.cc @@ -93,7 +93,13 @@ class ObjectiveCGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator { SystemImport("RxLibrary/GRXWriteable.h") + SystemImport("RxLibrary/GRXWriter.h"); - ::grpc::string forward_declarations = "@class GRPCProtoCall;\n\n"; + ::grpc::string forward_declarations = + "@class GRPCProtoCall;\n" + "@class GRPCUnaryProtoCall;\n" + "@class GRPCStreamingProtoCall;\n" + "@class GRPCCallOptions;\n" + "@protocol GRPCProtoResponseHandler;\n" + "\n"; ::grpc::string class_declarations = grpc_objective_c_generator::GetAllMessageClasses(file); @@ -103,6 +109,12 @@ class ObjectiveCGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator { class_imports += ImportProtoHeaders(file->dependency(i), " "); } + ::grpc::string ng_protocols; + for (int i = 0; i < file->service_count(); i++) { + const grpc::protobuf::ServiceDescriptor* service = file->service(i); + ng_protocols += grpc_objective_c_generator::GetV2Protocol(service); + } + ::grpc::string protocols; for (int i = 0; i < file->service_count(); i++) { const grpc::protobuf::ServiceDescriptor* service = file->service(i); @@ -120,9 +132,10 @@ class ObjectiveCGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator { PreprocIfNot(kProtocolOnly, system_imports) + "\n" + class_declarations + "\n" + PreprocIfNot(kForwardDeclare, class_imports) + "\n" + - forward_declarations + "\n" + kNonNullBegin + "\n" + protocols + - "\n" + PreprocIfNot(kProtocolOnly, interfaces) + "\n" + - kNonNullEnd + "\n"); + forward_declarations + "\n" + kNonNullBegin + "\n" + + ng_protocols + protocols + "\n" + + PreprocIfNot(kProtocolOnly, interfaces) + "\n" + kNonNullEnd + + "\n"); } { diff --git a/src/compiler/php_generator_helpers.h b/src/compiler/php_generator_helpers.h index 3ad19977641..abe273d47bb 100644 --- a/src/compiler/php_generator_helpers.h +++ b/src/compiler/php_generator_helpers.h @@ -63,7 +63,7 @@ inline grpc::string GetPHPServiceFilename( } // Get leading or trailing comments in a string. Comment lines start with "// ". -// Leading detached comments are put in in front of leading comments. +// Leading detached comments are put in front of leading comments. template inline grpc::string GetPHPComments(const DescriptorType* desc, grpc::string prefix) { diff --git a/src/compiler/protobuf_plugin.h b/src/compiler/protobuf_plugin.h index b971af13109..06cda5f85e6 100644 --- a/src/compiler/protobuf_plugin.h +++ b/src/compiler/protobuf_plugin.h @@ -55,22 +55,23 @@ class ProtoBufMethod : public grpc_generator::Method { return method_->output_type()->file()->name(); } - bool get_module_and_message_path_input(grpc::string* str, - grpc::string generator_file_name, - bool generate_in_pb2_grpc, - grpc::string import_prefix) const { + // TODO(https://github.com/grpc/grpc/issues/18800): Clean this up. + bool get_module_and_message_path_input( + grpc::string* str, grpc::string generator_file_name, + bool generate_in_pb2_grpc, grpc::string import_prefix, + const std::vector& prefixes_to_filter) const final { return grpc_python_generator::GetModuleAndMessagePath( method_->input_type(), str, generator_file_name, generate_in_pb2_grpc, - import_prefix); + import_prefix, prefixes_to_filter); } - bool get_module_and_message_path_output(grpc::string* str, - grpc::string generator_file_name, - bool generate_in_pb2_grpc, - grpc::string import_prefix) const { + bool get_module_and_message_path_output( + grpc::string* str, grpc::string generator_file_name, + bool generate_in_pb2_grpc, grpc::string import_prefix, + const std::vector& prefixes_to_filter) const final { return grpc_python_generator::GetModuleAndMessagePath( method_->output_type(), str, generator_file_name, generate_in_pb2_grpc, - import_prefix); + import_prefix, prefixes_to_filter); } bool NoStreaming() const { @@ -108,11 +109,11 @@ class ProtoBufService : public grpc_generator::Service { grpc::string name() const { return service_->name(); } - int method_count() const { return service_->method_count(); }; + int method_count() const { return service_->method_count(); } std::unique_ptr method(int i) const { return std::unique_ptr( new ProtoBufMethod(service_->method(i))); - }; + } grpc::string GetLeadingComments(const grpc::string prefix) const { return GetCommentsHelper(service_, true, prefix); @@ -166,7 +167,7 @@ class ProtoBufFile : public grpc_generator::File { grpc::string additional_headers() const { return ""; } - int service_count() const { return file_->service_count(); }; + int service_count() const { return file_->service_count(); } std::unique_ptr service(int i) const { return std::unique_ptr( new ProtoBufService(file_->service(i))); @@ -189,6 +190,15 @@ class ProtoBufFile : public grpc_generator::File { return grpc_python_generator::get_all_comments(file_); } + vector GetImportNames() const { + vector proto_names; + for (int i = 0; i < file_->dependency_count(); ++i) { + const auto& dep = *file_->dependency(i); + proto_names.push_back(dep.name()); + } + return proto_names; + } + private: const grpc::protobuf::FileDescriptor* file_; }; diff --git a/src/compiler/python_generator.cc b/src/compiler/python_generator.cc index 8a0b8894549..705aef1c884 100644 --- a/src/compiler/python_generator.cc +++ b/src/compiler/python_generator.cc @@ -214,13 +214,15 @@ bool PrivateGenerator::PrintBetaServerFactory( grpc::string input_message_module_and_class; if (!method->get_module_and_message_path_input( &input_message_module_and_class, generator_file_name, - generate_in_pb2_grpc, config.import_prefix)) { + generate_in_pb2_grpc, config.import_prefix, + config.prefixes_to_filter)) { return false; } grpc::string output_message_module_and_class; if (!method->get_module_and_message_path_output( &output_message_module_and_class, generator_file_name, - generate_in_pb2_grpc, config.import_prefix)) { + generate_in_pb2_grpc, config.import_prefix, + config.prefixes_to_filter)) { return false; } method_implementation_constructors.insert( @@ -320,13 +322,15 @@ bool PrivateGenerator::PrintBetaStubFactory( grpc::string input_message_module_and_class; if (!method->get_module_and_message_path_input( &input_message_module_and_class, generator_file_name, - generate_in_pb2_grpc, config.import_prefix)) { + generate_in_pb2_grpc, config.import_prefix, + config.prefixes_to_filter)) { return false; } grpc::string output_message_module_and_class; if (!method->get_module_and_message_path_output( &output_message_module_and_class, generator_file_name, - generate_in_pb2_grpc, config.import_prefix)) { + generate_in_pb2_grpc, config.import_prefix, + config.prefixes_to_filter)) { return false; } method_cardinalities.insert( @@ -425,13 +429,15 @@ bool PrivateGenerator::PrintStub( grpc::string request_module_and_class; if (!method->get_module_and_message_path_input( &request_module_and_class, generator_file_name, - generate_in_pb2_grpc, config.import_prefix)) { + generate_in_pb2_grpc, config.import_prefix, + config.prefixes_to_filter)) { return false; } grpc::string response_module_and_class; if (!method->get_module_and_message_path_output( &response_module_and_class, generator_file_name, - generate_in_pb2_grpc, config.import_prefix)) { + generate_in_pb2_grpc, config.import_prefix, + config.prefixes_to_filter)) { return false; } StringMap method_dict; @@ -516,13 +522,15 @@ bool PrivateGenerator::PrintAddServicerToServer( grpc::string request_module_and_class; if (!method->get_module_and_message_path_input( &request_module_and_class, generator_file_name, - generate_in_pb2_grpc, config.import_prefix)) { + generate_in_pb2_grpc, config.import_prefix, + config.prefixes_to_filter)) { return false; } grpc::string response_module_and_class; if (!method->get_module_and_message_path_output( &response_module_and_class, generator_file_name, - generate_in_pb2_grpc, config.import_prefix)) { + generate_in_pb2_grpc, config.import_prefix, + config.prefixes_to_filter)) { return false; } StringMap method_dict; @@ -589,17 +597,21 @@ bool PrivateGenerator::PrintPreamble(grpc_generator::Printer* out) { grpc::string input_type_file_name = method->get_input_type_name(); grpc::string input_module_name = - ModuleName(input_type_file_name, config.import_prefix); + ModuleName(input_type_file_name, config.import_prefix, + config.prefixes_to_filter); grpc::string input_module_alias = - ModuleAlias(input_type_file_name, config.import_prefix); + ModuleAlias(input_type_file_name, config.import_prefix, + config.prefixes_to_filter); imports_set.insert( std::make_tuple(input_module_name, input_module_alias)); grpc::string output_type_file_name = method->get_output_type_name(); grpc::string output_module_name = - ModuleName(output_type_file_name, config.import_prefix); + ModuleName(output_type_file_name, config.import_prefix, + config.prefixes_to_filter); grpc::string output_module_alias = - ModuleAlias(output_type_file_name, config.import_prefix); + ModuleAlias(output_type_file_name, config.import_prefix, + config.prefixes_to_filter); imports_set.insert( std::make_tuple(output_module_name, output_module_alias)); } diff --git a/src/compiler/python_generator.h b/src/compiler/python_generator.h index 9139307e63c..6077ac4ec68 100644 --- a/src/compiler/python_generator.h +++ b/src/compiler/python_generator.h @@ -20,6 +20,7 @@ #define GRPC_INTERNAL_COMPILER_PYTHON_GENERATOR_H #include +#include #include "src/compiler/config.h" #include "src/compiler/schema_interface.h" @@ -35,6 +36,7 @@ struct GeneratorConfiguration { grpc::string beta_package_root; // TODO(https://github.com/google/protobuf/issues/888): Drop this. grpc::string import_prefix; + std::vector prefixes_to_filter; }; class PythonGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator { diff --git a/src/compiler/python_generator_helpers.h b/src/compiler/python_generator_helpers.h index b1b58befdf4..171dd730a24 100644 --- a/src/compiler/python_generator_helpers.h +++ b/src/compiler/python_generator_helpers.h @@ -49,23 +49,39 @@ namespace { typedef vector DescriptorVector; typedef vector StringVector; +static grpc::string StripModulePrefixes( + const grpc::string& raw_module_name, + const std::vector& prefixes_to_filter) { + for (const auto& prefix : prefixes_to_filter) { + if (raw_module_name.rfind(prefix, 0) == 0) { + return raw_module_name.substr(prefix.size(), + raw_module_name.size() - prefix.size()); + } + } + return raw_module_name; +} + // TODO(https://github.com/google/protobuf/issues/888): // Export `ModuleName` from protobuf's // `src/google/protobuf/compiler/python/python_generator.cc` file. grpc::string ModuleName(const grpc::string& filename, - const grpc::string& import_prefix) { + const grpc::string& import_prefix, + const std::vector& prefixes_to_filter) { grpc::string basename = StripProto(filename); basename = StringReplace(basename, "-", "_"); basename = StringReplace(basename, "/", "."); - return import_prefix + basename + "_pb2"; + return StripModulePrefixes(import_prefix + basename + "_pb2", + prefixes_to_filter); } // TODO(https://github.com/google/protobuf/issues/888): // Export `ModuleAlias` from protobuf's // `src/google/protobuf/compiler/python/python_generator.cc` file. grpc::string ModuleAlias(const grpc::string& filename, - const grpc::string& import_prefix) { - grpc::string module_name = ModuleName(filename, import_prefix); + const grpc::string& import_prefix, + const std::vector& prefixes_to_filter) { + grpc::string module_name = + ModuleName(filename, import_prefix, prefixes_to_filter); // We can't have dots in the module name, so we replace each with _dot_. // But that could lead to a collision between a.b and a_dot_b, so we also // duplicate each underscore. @@ -74,10 +90,10 @@ grpc::string ModuleAlias(const grpc::string& filename, return module_name; } -bool GetModuleAndMessagePath(const Descriptor* type, grpc::string* out, - grpc::string generator_file_name, - bool generate_in_pb2_grpc, - grpc::string& import_prefix) { +bool GetModuleAndMessagePath( + const Descriptor* type, grpc::string* out, grpc::string generator_file_name, + bool generate_in_pb2_grpc, grpc::string& import_prefix, + const std::vector& prefixes_to_filter) { const Descriptor* path_elem_type = type; DescriptorVector message_path; do { @@ -93,7 +109,7 @@ bool GetModuleAndMessagePath(const Descriptor* type, grpc::string* out, grpc::string module; if (generator_file_name != file_name || generate_in_pb2_grpc) { - module = ModuleAlias(file_name, import_prefix) + "."; + module = ModuleAlias(file_name, import_prefix, prefixes_to_filter) + "."; } else { module = ""; } diff --git a/src/compiler/ruby_generator_helpers-inl.h b/src/compiler/ruby_generator_helpers-inl.h index 2323770425a..67a899be93d 100644 --- a/src/compiler/ruby_generator_helpers-inl.h +++ b/src/compiler/ruby_generator_helpers-inl.h @@ -47,7 +47,7 @@ inline grpc::string MessagesRequireName( } // Get leading or trailing comments in a string. Comment lines start with "# ". -// Leading detached comments are put in in front of leading comments. +// Leading detached comments are put in front of leading comments. template inline grpc::string GetRubyComments(const DescriptorType* desc, bool leading) { return grpc_generator::GetPrefixedComments(desc, leading, "#"); diff --git a/src/compiler/schema_interface.h b/src/compiler/schema_interface.h index c000478e681..e7b427d89b1 100644 --- a/src/compiler/schema_interface.h +++ b/src/compiler/schema_interface.h @@ -57,10 +57,12 @@ struct Method : public CommentHolder { virtual bool get_module_and_message_path_input( grpc::string* str, grpc::string generator_file_name, - bool generate_in_pb2_grpc, grpc::string import_prefix) const = 0; + bool generate_in_pb2_grpc, grpc::string import_prefix, + const std::vector& prefixes_to_filter) const = 0; virtual bool get_module_and_message_path_output( grpc::string* str, grpc::string generator_file_name, - bool generate_in_pb2_grpc, grpc::string import_prefix) const = 0; + bool generate_in_pb2_grpc, grpc::string import_prefix, + const std::vector& prefixes_to_filter) const = 0; virtual grpc::string get_input_type_name() const = 0; virtual grpc::string get_output_type_name() const = 0; @@ -101,6 +103,7 @@ struct File : public CommentHolder { virtual grpc::string package() const = 0; virtual std::vector package_parts() const = 0; virtual grpc::string additional_headers() const = 0; + virtual std::vector GetImportNames() const { return {}; } virtual int service_count() const = 0; virtual std::unique_ptr service(int i) const = 0; diff --git a/src/core/README.md b/src/core/README.md index 130d2652b39..5dea45a6925 100644 --- a/src/core/README.md +++ b/src/core/README.md @@ -1,4 +1,4 @@ # Overview -This directory contains source code for C library (a.k.a the *gRPC C core*) that provides all gRPC's core functionality through a low level API. Libraries in other languages in this repository (C++, Ruby, +This directory contains source code for C library (a.k.a the *gRPC C core*) that provides all gRPC's core functionality through a low level API. Libraries in other languages in this repository (C++, C#, Ruby, Python, PHP, NodeJS, Objective-C) are layered on top of this library. diff --git a/src/core/ext/filters/client_channel/README.md b/src/core/ext/filters/client_channel/README.md index 9676a4535b2..ffb09fd34e7 100644 --- a/src/core/ext/filters/client_channel/README.md +++ b/src/core/ext/filters/client_channel/README.md @@ -4,7 +4,7 @@ Client Configuration Support for GRPC This library provides high level configuration machinery to construct client channels and load balance between them. -Each grpc_channel is created with a grpc_resolver. It is the resolver's duty +Each `grpc_channel` is created with a `Resolver`. It is the resolver's duty to resolve a name into a set of arguments for the channel. Such arguments might include: @@ -12,7 +12,7 @@ might include: - a load balancing policy to decide which server to send a request to - a set of filters to mutate outgoing requests (say, by adding metadata) -The resolver provides this data as a stream of grpc_channel_args objects to +The resolver provides this data as a stream of `grpc_channel_args` objects to the channel. We represent arguments as a stream so that they can be changed by the resolver during execution, by reacting to external events (such as new service configuration data being pushed to some store). @@ -21,11 +21,11 @@ new service configuration data being pushed to some store). Load Balancing -------------- -Load balancing configuration is provided by a grpc_lb_policy object. +Load balancing configuration is provided by a `LoadBalancingPolicy` object. The primary job of the load balancing policies is to pick a target server given only the initial metadata for a request. It does this by providing -a grpc_subchannel object to the owning channel. +a `ConnectedSubchannel` object to the owning channel. Sub-Channels @@ -38,9 +38,9 @@ decisions (for example, by avoiding disconnected backends). Configured sub-channels are fully setup to participate in the grpc data plane. Their behavior is specified by a set of grpc channel filters defined at their -construction. To customize this behavior, resolvers build -grpc_client_channel_factory objects, which use the decorator pattern to customize -construction arguments for concrete grpc_subchannel instances. +construction. To customize this behavior, transports build +`ClientChannelFactory` objects, which customize construction arguments for +concrete subchannel instances. Naming for GRPC diff --git a/src/core/ext/filters/client_channel/backup_poller.cc b/src/core/ext/filters/client_channel/backup_poller.cc index 3e2faa57bcf..a2d45c04026 100644 --- a/src/core/ext/filters/client_channel/backup_poller.cc +++ b/src/core/ext/filters/client_channel/backup_poller.cc @@ -25,8 +25,8 @@ #include #include #include "src/core/ext/filters/client_channel/client_channel.h" -#include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/global_config.h" #include "src/core/lib/iomgr/error.h" #include "src/core/lib/iomgr/pollset.h" #include "src/core/lib/iomgr/timer.h" @@ -56,21 +56,22 @@ static backup_poller* g_poller = nullptr; // guarded by g_poller_mu // treated as const. static int g_poll_interval_ms = DEFAULT_POLL_INTERVAL_MS; +GPR_GLOBAL_CONFIG_DEFINE_INT32(grpc_client_channel_backup_poll_interval_ms, + DEFAULT_POLL_INTERVAL_MS, + "Client channel backup poll interval (ms)"); + static void init_globals() { gpr_mu_init(&g_poller_mu); - char* env = gpr_getenv("GRPC_CLIENT_CHANNEL_BACKUP_POLL_INTERVAL_MS"); - if (env != nullptr) { - int poll_interval_ms = gpr_parse_nonnegative_int(env); - if (poll_interval_ms == -1) { - gpr_log(GPR_ERROR, - "Invalid GRPC_CLIENT_CHANNEL_BACKUP_POLL_INTERVAL_MS: %s, " - "default value %d will be used.", - env, g_poll_interval_ms); - } else { - g_poll_interval_ms = poll_interval_ms; - } + int32_t poll_interval_ms = + GPR_GLOBAL_CONFIG_GET(grpc_client_channel_backup_poll_interval_ms); + if (poll_interval_ms < 0) { + gpr_log(GPR_ERROR, + "Invalid GRPC_CLIENT_CHANNEL_BACKUP_POLL_INTERVAL_MS: %d, " + "default value %d will be used.", + poll_interval_ms, g_poll_interval_ms); + } else { + g_poll_interval_ms = poll_interval_ms; } - gpr_free(env); } static void backup_poller_shutdown_unref(backup_poller* p) { diff --git a/src/core/ext/filters/client_channel/backup_poller.h b/src/core/ext/filters/client_channel/backup_poller.h index 8f132f968ce..e1bf4f88b2a 100644 --- a/src/core/ext/filters/client_channel/backup_poller.h +++ b/src/core/ext/filters/client_channel/backup_poller.h @@ -23,6 +23,9 @@ #include #include "src/core/lib/channel/channel_stack.h" +#include "src/core/lib/gprpp/global_config.h" + +GPR_GLOBAL_CONFIG_DECLARE_INT32(grpc_client_channel_backup_poll_interval_ms); /* Start polling \a interested_parties periodically in the timer thread */ void grpc_client_channel_start_backup_polling( diff --git a/src/core/ext/filters/client_channel/channel_connectivity.cc b/src/core/ext/filters/client_channel/channel_connectivity.cc index c71d10274a8..232183d61ff 100644 --- a/src/core/ext/filters/client_channel/channel_connectivity.cc +++ b/src/core/ext/filters/client_channel/channel_connectivity.cc @@ -35,6 +35,7 @@ grpc_connectivity_state grpc_channel_check_connectivity_state( /* forward through to the underlying client channel */ grpc_channel_element* client_channel_elem = grpc_channel_stack_last_element(grpc_channel_get_channel_stack(channel)); + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; grpc_core::ExecCtx exec_ctx; grpc_connectivity_state state; GRPC_API_TRACE( @@ -124,7 +125,7 @@ static void partly_done(state_watcher* w, bool due_to_completion, gpr_mu_lock(&w->mu); if (due_to_completion) { - if (grpc_trace_operation_failures.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_trace_operation_failures)) { GRPC_LOG_IF_ERROR("watch_completion_error", GRPC_ERROR_REF(error)); } GRPC_ERROR_UNREF(error); @@ -202,6 +203,7 @@ void grpc_channel_watch_connectivity_state( gpr_timespec deadline, grpc_completion_queue* cq, void* tag) { grpc_channel_element* client_channel_elem = grpc_channel_stack_last_element(grpc_channel_get_channel_stack(channel)); + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; grpc_core::ExecCtx exec_ctx; state_watcher* w = static_cast(gpr_malloc(sizeof(*w))); diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index be7962261bc..cc4bfdded13 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -32,12 +32,16 @@ #include #include "src/core/ext/filters/client_channel/backup_poller.h" +#include "src/core/ext/filters/client_channel/global_subchannel_pool.h" #include "src/core/ext/filters/client_channel/http_connect_handshaker.h" #include "src/core/ext/filters/client_channel/lb_policy_registry.h" +#include "src/core/ext/filters/client_channel/local_subchannel_pool.h" #include "src/core/ext/filters/client_channel/proxy_mapper_registry.h" #include "src/core/ext/filters/client_channel/resolver_registry.h" #include "src/core/ext/filters/client_channel/resolver_result_parsing.h" +#include "src/core/ext/filters/client_channel/resolving_lb_policy.h" #include "src/core/ext/filters/client_channel/retry_throttle.h" +#include "src/core/ext/filters/client_channel/service_config.h" #include "src/core/ext/filters/client_channel/subchannel.h" #include "src/core/ext/filters/deadline/deadline_filter.h" #include "src/core/lib/backoff/backoff.h" @@ -47,6 +51,7 @@ #include "src/core/lib/gpr/string.h" #include "src/core/lib/gprpp/inlined_vector.h" #include "src/core/lib/gprpp/manual_constructor.h" +#include "src/core/lib/gprpp/sync.h" #include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/iomgr.h" #include "src/core/lib/iomgr/polling_entity.h" @@ -58,16 +63,15 @@ #include "src/core/lib/transport/error_utils.h" #include "src/core/lib/transport/metadata.h" #include "src/core/lib/transport/metadata_batch.h" -#include "src/core/lib/transport/service_config.h" #include "src/core/lib/transport/static_metadata.h" #include "src/core/lib/transport/status_metadata.h" -using grpc_core::internal::ClientChannelMethodParams; -using grpc_core::internal::ClientChannelMethodParamsTable; -using grpc_core::internal::ProcessedResolverResult; +using grpc_core::internal::ClientChannelMethodParsedObject; using grpc_core::internal::ServerRetryThrottleData; -/* Client channel implementation */ +// +// Client channel filter +// // By default, we buffer 256 KiB per RPC for retries. // TODO(roth): Do we have any data to suggest a better value? @@ -77,703 +81,6 @@ using grpc_core::internal::ServerRetryThrottleData; // any even moderately compelling reason to do so. #define RETRY_BACKOFF_JITTER 0.2 -grpc_core::TraceFlag grpc_client_channel_trace(false, "client_channel"); - -/************************************************************************* - * CHANNEL-WIDE FUNCTIONS - */ - -struct external_connectivity_watcher; - -typedef struct client_channel_channel_data { - grpc_core::OrphanablePtr resolver; - bool started_resolving; - bool deadline_checking_enabled; - grpc_client_channel_factory* client_channel_factory; - bool enable_retries; - size_t per_rpc_retry_buffer_size; - - /** combiner protecting all variables below in this data structure */ - grpc_combiner* combiner; - /** currently active load balancer */ - grpc_core::OrphanablePtr lb_policy; - /** retry throttle data */ - grpc_core::RefCountedPtr retry_throttle_data; - /** maps method names to method_parameters structs */ - grpc_core::RefCountedPtr method_params_table; - /** incoming resolver result - set by resolver.next() */ - grpc_channel_args* resolver_result; - /** a list of closures that are all waiting for resolver result to come in */ - grpc_closure_list waiting_for_resolver_result_closures; - /** resolver callback */ - grpc_closure on_resolver_result_changed; - /** connectivity state being tracked */ - grpc_connectivity_state_tracker state_tracker; - /** when an lb_policy arrives, should we try to exit idle */ - bool exit_idle_when_lb_policy_arrives; - /** owning stack */ - grpc_channel_stack* owning_stack; - /** interested parties (owned) */ - grpc_pollset_set* interested_parties; - - /* external_connectivity_watcher_list head is guarded by its own mutex, since - * counts need to be grabbed immediately without polling on a cq */ - gpr_mu external_connectivity_watcher_list_mu; - struct external_connectivity_watcher* external_connectivity_watcher_list_head; - - /* the following properties are guarded by a mutex since APIs require them - to be instantaneously available */ - gpr_mu info_mu; - grpc_core::UniquePtr info_lb_policy_name; - /** service config in JSON form */ - grpc_core::UniquePtr info_service_config_json; - /* backpointer to grpc_channel's channelz node */ - grpc_core::channelz::ClientChannelNode* channelz_channel; - /* caches if the last resolution event contained addresses */ - bool previous_resolution_contained_addresses; -} channel_data; - -typedef struct { - channel_data* chand; - /** used as an identifier, don't dereference it because the LB policy may be - * non-existing when the callback is run */ - grpc_core::LoadBalancingPolicy* lb_policy; - grpc_closure closure; -} reresolution_request_args; - -/** We create one watcher for each new lb_policy that is returned from a - resolver, to watch for state changes from the lb_policy. When a state - change is seen, we update the channel, and create a new watcher. */ -typedef struct { - channel_data* chand; - grpc_closure on_changed; - grpc_connectivity_state state; - grpc_core::LoadBalancingPolicy* lb_policy; -} lb_policy_connectivity_watcher; - -static void watch_lb_policy_locked(channel_data* chand, - grpc_core::LoadBalancingPolicy* lb_policy, - grpc_connectivity_state current_state); - -static const char* channel_connectivity_state_change_string( - grpc_connectivity_state state) { - switch (state) { - case GRPC_CHANNEL_IDLE: - return "Channel state change to IDLE"; - case GRPC_CHANNEL_CONNECTING: - return "Channel state change to CONNECTING"; - case GRPC_CHANNEL_READY: - return "Channel state change to READY"; - case GRPC_CHANNEL_TRANSIENT_FAILURE: - return "Channel state change to TRANSIENT_FAILURE"; - case GRPC_CHANNEL_SHUTDOWN: - return "Channel state change to SHUTDOWN"; - } - GPR_UNREACHABLE_CODE(return "UNKNOWN"); -} - -static void set_channel_connectivity_state_locked(channel_data* chand, - grpc_connectivity_state state, - grpc_error* error, - const char* reason) { - /* TODO: Improve failure handling: - * - Make it possible for policies to return GRPC_CHANNEL_TRANSIENT_FAILURE. - * - Hand over pending picks from old policies during the switch that happens - * when resolver provides an update. */ - if (chand->lb_policy != nullptr) { - if (state == GRPC_CHANNEL_TRANSIENT_FAILURE) { - /* cancel picks with wait_for_ready=false */ - chand->lb_policy->CancelMatchingPicksLocked( - /* mask= */ GRPC_INITIAL_METADATA_WAIT_FOR_READY, - /* check= */ 0, GRPC_ERROR_REF(error)); - } else if (state == GRPC_CHANNEL_SHUTDOWN) { - /* cancel all picks */ - chand->lb_policy->CancelMatchingPicksLocked(/* mask= */ 0, /* check= */ 0, - GRPC_ERROR_REF(error)); - } - } - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p: setting connectivity state to %s", chand, - grpc_connectivity_state_name(state)); - } - if (chand->channelz_channel != nullptr) { - chand->channelz_channel->AddTraceEvent( - grpc_core::channelz::ChannelTrace::Severity::Info, - grpc_slice_from_static_string( - channel_connectivity_state_change_string(state))); - } - grpc_connectivity_state_set(&chand->state_tracker, state, error, reason); -} - -static void on_lb_policy_state_changed_locked(void* arg, grpc_error* error) { - lb_policy_connectivity_watcher* w = - static_cast(arg); - /* 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_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, - GRPC_ERROR_REF(error), "lb_changed"); - if (w->state != GRPC_CHANNEL_SHUTDOWN) { - watch_lb_policy_locked(w->chand, w->lb_policy, w->state); - } - } - GRPC_CHANNEL_STACK_UNREF(w->chand->owning_stack, "watch_lb_policy"); - gpr_free(w); -} - -static void watch_lb_policy_locked(channel_data* chand, - grpc_core::LoadBalancingPolicy* lb_policy, - grpc_connectivity_state current_state) { - lb_policy_connectivity_watcher* w = - static_cast(gpr_malloc(sizeof(*w))); - GRPC_CHANNEL_STACK_REF(chand->owning_stack, "watch_lb_policy"); - w->chand = chand; - GRPC_CLOSURE_INIT(&w->on_changed, on_lb_policy_state_changed_locked, w, - grpc_combiner_scheduler(chand->combiner)); - w->state = current_state; - w->lb_policy = lb_policy; - lb_policy->NotifyOnStateChangeLocked(&w->state, &w->on_changed); -} - -static void start_resolving_locked(channel_data* chand) { - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p: starting name resolution", chand); - } - GPR_ASSERT(!chand->started_resolving); - chand->started_resolving = true; - GRPC_CHANNEL_STACK_REF(chand->owning_stack, "resolver"); - chand->resolver->NextLocked(&chand->resolver_result, - &chand->on_resolver_result_changed); -} - -// Invoked from the resolver NextLocked() callback when the resolver -// is shutting down. -static void on_resolver_shutdown_locked(channel_data* chand, - grpc_error* error) { - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p: shutting down", chand); - } - if (chand->lb_policy != nullptr) { - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p: shutting down lb_policy=%p", chand, - chand->lb_policy.get()); - } - grpc_pollset_set_del_pollset_set(chand->lb_policy->interested_parties(), - chand->interested_parties); - chand->lb_policy.reset(); - } - if (chand->resolver != nullptr) { - // This should never happen; it can only be triggered by a resolver - // implementation spotaneously deciding to report shutdown without - // being orphaned. This code is included just to be defensive. - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p: spontaneous shutdown from resolver %p", - chand, chand->resolver.get()); - } - chand->resolver.reset(); - set_channel_connectivity_state_locked( - chand, GRPC_CHANNEL_SHUTDOWN, - GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Resolver spontaneous shutdown", &error, 1), - "resolver_spontaneous_shutdown"); - } - grpc_closure_list_fail_all(&chand->waiting_for_resolver_result_closures, - GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Channel disconnected", &error, 1)); - GRPC_CLOSURE_LIST_SCHED(&chand->waiting_for_resolver_result_closures); - GRPC_CHANNEL_STACK_UNREF(chand->owning_stack, "resolver"); - grpc_channel_args_destroy(chand->resolver_result); - chand->resolver_result = nullptr; - GRPC_ERROR_UNREF(error); -} - -static void request_reresolution_locked(void* arg, grpc_error* error) { - reresolution_request_args* args = - static_cast(arg); - channel_data* chand = args->chand; - // If this invocation is for a stale LB policy, treat it as an LB shutdown - // signal. - if (args->lb_policy != chand->lb_policy.get() || error != GRPC_ERROR_NONE || - chand->resolver == nullptr) { - GRPC_CHANNEL_STACK_UNREF(chand->owning_stack, "re-resolution"); - gpr_free(args); - return; - } - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p: started name re-resolving", chand); - } - chand->resolver->RequestReresolutionLocked(); - // Give back the closure to the LB policy. - chand->lb_policy->SetReresolutionClosureLocked(&args->closure); -} - -using TraceStringVector = grpc_core::InlinedVector; - -// Creates a new LB policy, replacing any previous one. -// If the new policy is created successfully, sets *connectivity_state and -// *connectivity_error to its initial connectivity state; otherwise, -// leaves them unchanged. -static void create_new_lb_policy_locked( - channel_data* chand, char* lb_policy_name, grpc_json* lb_config, - grpc_connectivity_state* connectivity_state, - grpc_error** connectivity_error, TraceStringVector* trace_strings) { - grpc_core::LoadBalancingPolicy::Args lb_policy_args; - lb_policy_args.combiner = chand->combiner; - lb_policy_args.client_channel_factory = chand->client_channel_factory; - lb_policy_args.args = chand->resolver_result; - lb_policy_args.lb_config = lb_config; - grpc_core::OrphanablePtr new_lb_policy = - grpc_core::LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( - lb_policy_name, lb_policy_args); - if (GPR_UNLIKELY(new_lb_policy == nullptr)) { - gpr_log(GPR_ERROR, "could not create LB policy \"%s\"", lb_policy_name); - if (chand->channelz_channel != nullptr) { - char* str; - gpr_asprintf(&str, "Could not create LB policy \'%s\'", lb_policy_name); - trace_strings->push_back(str); - } - } else { - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p: created new LB policy \"%s\" (%p)", chand, - lb_policy_name, new_lb_policy.get()); - } - if (chand->channelz_channel != nullptr) { - char* str; - gpr_asprintf(&str, "Created new LB policy \'%s\'", lb_policy_name); - trace_strings->push_back(str); - } - // Swap out the LB policy and update the fds in - // chand->interested_parties. - if (chand->lb_policy != nullptr) { - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p: shutting down lb_policy=%p", chand, - chand->lb_policy.get()); - } - grpc_pollset_set_del_pollset_set(chand->lb_policy->interested_parties(), - chand->interested_parties); - chand->lb_policy->HandOffPendingPicksLocked(new_lb_policy.get()); - } - chand->lb_policy = std::move(new_lb_policy); - grpc_pollset_set_add_pollset_set(chand->lb_policy->interested_parties(), - chand->interested_parties); - // Set up re-resolution callback. - reresolution_request_args* args = - static_cast(gpr_zalloc(sizeof(*args))); - args->chand = chand; - args->lb_policy = chand->lb_policy.get(); - GRPC_CLOSURE_INIT(&args->closure, request_reresolution_locked, args, - grpc_combiner_scheduler(chand->combiner)); - GRPC_CHANNEL_STACK_REF(chand->owning_stack, "re-resolution"); - chand->lb_policy->SetReresolutionClosureLocked(&args->closure); - // Get the new LB policy's initial connectivity state and start a - // connectivity watch. - GRPC_ERROR_UNREF(*connectivity_error); - *connectivity_state = - chand->lb_policy->CheckConnectivityLocked(connectivity_error); - if (chand->exit_idle_when_lb_policy_arrives) { - chand->lb_policy->ExitIdleLocked(); - chand->exit_idle_when_lb_policy_arrives = false; - } - watch_lb_policy_locked(chand, chand->lb_policy.get(), *connectivity_state); - } -} - -static void maybe_add_trace_message_for_address_changes_locked( - channel_data* chand, TraceStringVector* trace_strings) { - int resolution_contains_addresses = false; - const grpc_arg* channel_arg = - grpc_channel_args_find(chand->resolver_result, GRPC_ARG_LB_ADDRESSES); - if (channel_arg != nullptr && channel_arg->type == GRPC_ARG_POINTER) { - grpc_lb_addresses* addresses = - static_cast(channel_arg->value.pointer.p); - if (addresses->num_addresses > 0) { - resolution_contains_addresses = true; - } - } - if (!resolution_contains_addresses && - chand->previous_resolution_contained_addresses) { - trace_strings->push_back(gpr_strdup("Address list became empty")); - } else if (resolution_contains_addresses && - !chand->previous_resolution_contained_addresses) { - trace_strings->push_back(gpr_strdup("Address list became non-empty")); - } - chand->previous_resolution_contained_addresses = - resolution_contains_addresses; -} - -static void concatenate_and_add_channel_trace_locked( - channel_data* chand, TraceStringVector* trace_strings) { - if (!trace_strings->empty()) { - gpr_strvec v; - gpr_strvec_init(&v); - gpr_strvec_add(&v, gpr_strdup("Resolution event: ")); - bool is_first = 1; - for (size_t i = 0; i < trace_strings->size(); ++i) { - if (!is_first) gpr_strvec_add(&v, gpr_strdup(", ")); - is_first = false; - gpr_strvec_add(&v, (*trace_strings)[i]); - } - char* flat; - size_t flat_len = 0; - flat = gpr_strvec_flatten(&v, &flat_len); - chand->channelz_channel->AddTraceEvent( - grpc_core::channelz::ChannelTrace::Severity::Info, - grpc_slice_new(flat, flat_len, gpr_free)); - gpr_strvec_destroy(&v); - } -} - -// Callback invoked when a resolver result is available. -static void on_resolver_result_changed_locked(void* arg, grpc_error* error) { - channel_data* chand = static_cast(arg); - if (grpc_client_channel_trace.enabled()) { - const char* disposition = - chand->resolver_result != nullptr - ? "" - : (error == GRPC_ERROR_NONE ? " (transient error)" - : " (resolver shutdown)"); - gpr_log(GPR_INFO, - "chand=%p: got resolver result: resolver_result=%p error=%s%s", - chand, chand->resolver_result, grpc_error_string(error), - disposition); - } - // Handle shutdown. - if (error != GRPC_ERROR_NONE || chand->resolver == nullptr) { - on_resolver_shutdown_locked(chand, GRPC_ERROR_REF(error)); - return; - } - // Data used to set the channel's connectivity state. - bool set_connectivity_state = true; - // We only want to trace the address resolution in the follow cases: - // (a) Address resolution resulted in service config change. - // (b) Address resolution that causes number of backends to go from - // zero to non-zero. - // (c) Address resolution that causes number of backends to go from - // non-zero to zero. - // (d) Address resolution that causes a new LB policy to be created. - // - // we track a list of strings to eventually be concatenated and traced. - TraceStringVector trace_strings; - grpc_connectivity_state connectivity_state = GRPC_CHANNEL_TRANSIENT_FAILURE; - grpc_error* connectivity_error = - GRPC_ERROR_CREATE_FROM_STATIC_STRING("No load balancing policy"); - // chand->resolver_result will be null in the case of a transient - // resolution error. In that case, we don't have any new result to - // process, which means that we keep using the previous result (if any). - if (chand->resolver_result == nullptr) { - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p: resolver transient failure", chand); - } - // Don't override connectivity state if we already have an LB policy. - if (chand->lb_policy != nullptr) set_connectivity_state = false; - } else { - // Parse the resolver result. - ProcessedResolverResult resolver_result(chand->resolver_result, - chand->enable_retries); - chand->retry_throttle_data = resolver_result.retry_throttle_data(); - chand->method_params_table = resolver_result.method_params_table(); - grpc_core::UniquePtr service_config_json = - resolver_result.service_config_json(); - if (service_config_json != nullptr && grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p: resolver returned service config: \"%s\"", - chand, service_config_json.get()); - } - grpc_core::UniquePtr lb_policy_name = - resolver_result.lb_policy_name(); - grpc_json* lb_policy_config = resolver_result.lb_policy_config(); - // Check to see if we're already using the right LB policy. - // Note: It's safe to use chand->info_lb_policy_name here without - // taking a lock on chand->info_mu, because this function is the - // only thing that modifies its value, and it can only be invoked - // once at any given time. - bool lb_policy_name_changed = chand->info_lb_policy_name == nullptr || - gpr_stricmp(chand->info_lb_policy_name.get(), - lb_policy_name.get()) != 0; - if (chand->lb_policy != nullptr && !lb_policy_name_changed) { - // Continue using the same LB policy. Update with new addresses. - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p: updating existing LB policy \"%s\" (%p)", - chand, lb_policy_name.get(), chand->lb_policy.get()); - } - chand->lb_policy->UpdateLocked(*chand->resolver_result, lb_policy_config); - // No need to set the channel's connectivity state; the existing - // watch on the LB policy will take care of that. - set_connectivity_state = false; - } else { - // Instantiate new LB policy. - create_new_lb_policy_locked(chand, lb_policy_name.get(), lb_policy_config, - &connectivity_state, &connectivity_error, - &trace_strings); - } - // Note: It's safe to use chand->info_service_config_json here without - // taking a lock on chand->info_mu, because this function is the - // only thing that modifies its value, and it can only be invoked - // once at any given time. - if (chand->channelz_channel != nullptr) { - if (((service_config_json == nullptr) != - (chand->info_service_config_json == nullptr)) || - (service_config_json != nullptr && - strcmp(service_config_json.get(), - chand->info_service_config_json.get()) != 0)) { - // TODO(ncteisen): might be worth somehow including a snippet of the - // config in the trace, at the risk of bloating the trace logs. - trace_strings.push_back(gpr_strdup("Service config changed")); - } - maybe_add_trace_message_for_address_changes_locked(chand, &trace_strings); - concatenate_and_add_channel_trace_locked(chand, &trace_strings); - } - // Swap out the data used by cc_get_channel_info(). - gpr_mu_lock(&chand->info_mu); - chand->info_lb_policy_name = std::move(lb_policy_name); - chand->info_service_config_json = std::move(service_config_json); - gpr_mu_unlock(&chand->info_mu); - // Clean up. - grpc_channel_args_destroy(chand->resolver_result); - chand->resolver_result = nullptr; - } - // Set the channel's connectivity state if needed. - if (set_connectivity_state) { - set_channel_connectivity_state_locked( - chand, connectivity_state, connectivity_error, "resolver_result"); - } else { - GRPC_ERROR_UNREF(connectivity_error); - } - // Invoke closures that were waiting for results and renew the watch. - GRPC_CLOSURE_LIST_SCHED(&chand->waiting_for_resolver_result_closures); - chand->resolver->NextLocked(&chand->resolver_result, - &chand->on_resolver_result_changed); -} - -static void start_transport_op_locked(void* arg, grpc_error* error_ignored) { - grpc_transport_op* op = static_cast(arg); - grpc_channel_element* elem = - static_cast(op->handler_private.extra_arg); - channel_data* chand = static_cast(elem->channel_data); - - if (op->on_connectivity_state_change != nullptr) { - grpc_connectivity_state_notify_on_state_change( - &chand->state_tracker, op->connectivity_state, - op->on_connectivity_state_change); - op->on_connectivity_state_change = nullptr; - op->connectivity_state = nullptr; - } - - if (op->send_ping.on_initiate != nullptr || op->send_ping.on_ack != nullptr) { - if (chand->lb_policy == nullptr) { - grpc_error* error = - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Ping with no load balancing"); - GRPC_CLOSURE_SCHED(op->send_ping.on_initiate, GRPC_ERROR_REF(error)); - GRPC_CLOSURE_SCHED(op->send_ping.on_ack, error); - } else { - grpc_error* error = GRPC_ERROR_NONE; - grpc_core::LoadBalancingPolicy::PickState pick_state; - pick_state.initial_metadata = nullptr; - pick_state.initial_metadata_flags = 0; - pick_state.on_complete = nullptr; - memset(&pick_state.subchannel_call_context, 0, - sizeof(pick_state.subchannel_call_context)); - pick_state.user_data = nullptr; - // Pick must return synchronously, because pick_state.on_complete is null. - GPR_ASSERT(chand->lb_policy->PickLocked(&pick_state, &error)); - if (pick_state.connected_subchannel != nullptr) { - pick_state.connected_subchannel->Ping(op->send_ping.on_initiate, - op->send_ping.on_ack); - } else { - if (error == GRPC_ERROR_NONE) { - error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "LB policy dropped call on ping"); - } - GRPC_CLOSURE_SCHED(op->send_ping.on_initiate, GRPC_ERROR_REF(error)); - GRPC_CLOSURE_SCHED(op->send_ping.on_ack, error); - } - op->bind_pollset = nullptr; - } - op->send_ping.on_initiate = nullptr; - op->send_ping.on_ack = nullptr; - } - - if (op->disconnect_with_error != GRPC_ERROR_NONE) { - if (chand->resolver != nullptr) { - set_channel_connectivity_state_locked( - chand, GRPC_CHANNEL_SHUTDOWN, - GRPC_ERROR_REF(op->disconnect_with_error), "disconnect"); - chand->resolver.reset(); - if (!chand->started_resolving) { - grpc_closure_list_fail_all(&chand->waiting_for_resolver_result_closures, - GRPC_ERROR_REF(op->disconnect_with_error)); - GRPC_CLOSURE_LIST_SCHED(&chand->waiting_for_resolver_result_closures); - } - if (chand->lb_policy != nullptr) { - grpc_pollset_set_del_pollset_set(chand->lb_policy->interested_parties(), - chand->interested_parties); - chand->lb_policy.reset(); - } - } - GRPC_ERROR_UNREF(op->disconnect_with_error); - } - - if (op->reset_connect_backoff) { - if (chand->resolver != nullptr) { - chand->resolver->ResetBackoffLocked(); - chand->resolver->RequestReresolutionLocked(); - } - if (chand->lb_policy != nullptr) { - chand->lb_policy->ResetBackoffLocked(); - } - } - - GRPC_CHANNEL_STACK_UNREF(chand->owning_stack, "start_transport_op"); - - GRPC_CLOSURE_SCHED(op->on_consumed, GRPC_ERROR_NONE); -} - -static void cc_start_transport_op(grpc_channel_element* elem, - grpc_transport_op* op) { - channel_data* chand = static_cast(elem->channel_data); - - GPR_ASSERT(op->set_accept_stream == false); - if (op->bind_pollset != nullptr) { - grpc_pollset_set_add_pollset(chand->interested_parties, op->bind_pollset); - } - - op->handler_private.extra_arg = elem; - GRPC_CHANNEL_STACK_REF(chand->owning_stack, "start_transport_op"); - GRPC_CLOSURE_SCHED( - GRPC_CLOSURE_INIT(&op->handler_private.closure, start_transport_op_locked, - op, grpc_combiner_scheduler(chand->combiner)), - GRPC_ERROR_NONE); -} - -static void cc_get_channel_info(grpc_channel_element* elem, - const grpc_channel_info* info) { - channel_data* chand = static_cast(elem->channel_data); - gpr_mu_lock(&chand->info_mu); - if (info->lb_policy_name != nullptr) { - *info->lb_policy_name = gpr_strdup(chand->info_lb_policy_name.get()); - } - if (info->service_config_json != nullptr) { - *info->service_config_json = - gpr_strdup(chand->info_service_config_json.get()); - } - gpr_mu_unlock(&chand->info_mu); -} - -/* Constructor for channel_data */ -static grpc_error* cc_init_channel_elem(grpc_channel_element* elem, - grpc_channel_element_args* args) { - channel_data* chand = static_cast(elem->channel_data); - GPR_ASSERT(args->is_last); - GPR_ASSERT(elem->filter == &grpc_client_channel_filter); - // Initialize data members. - chand->combiner = grpc_combiner_create(); - gpr_mu_init(&chand->info_mu); - gpr_mu_init(&chand->external_connectivity_watcher_list_mu); - - gpr_mu_lock(&chand->external_connectivity_watcher_list_mu); - chand->external_connectivity_watcher_list_head = nullptr; - gpr_mu_unlock(&chand->external_connectivity_watcher_list_mu); - - chand->owning_stack = args->channel_stack; - GRPC_CLOSURE_INIT(&chand->on_resolver_result_changed, - on_resolver_result_changed_locked, chand, - grpc_combiner_scheduler(chand->combiner)); - chand->interested_parties = grpc_pollset_set_create(); - grpc_connectivity_state_init(&chand->state_tracker, GRPC_CHANNEL_IDLE, - "client_channel"); - grpc_client_channel_start_backup_polling(chand->interested_parties); - // Record max per-RPC retry buffer size. - const grpc_arg* arg = grpc_channel_args_find( - args->channel_args, GRPC_ARG_PER_RPC_RETRY_BUFFER_SIZE); - chand->per_rpc_retry_buffer_size = (size_t)grpc_channel_arg_get_integer( - arg, {DEFAULT_PER_RPC_RETRY_BUFFER_SIZE, 0, INT_MAX}); - // Record enable_retries. - arg = grpc_channel_args_find(args->channel_args, GRPC_ARG_ENABLE_RETRIES); - chand->enable_retries = grpc_channel_arg_get_bool(arg, true); - chand->channelz_channel = nullptr; - chand->previous_resolution_contained_addresses = false; - // Record client channel factory. - arg = grpc_channel_args_find(args->channel_args, - GRPC_ARG_CLIENT_CHANNEL_FACTORY); - if (arg == nullptr) { - return GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "Missing client channel factory in args for client channel filter"); - } - if (arg->type != GRPC_ARG_POINTER) { - return GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "client channel factory arg must be a pointer"); - } - grpc_client_channel_factory_ref( - static_cast(arg->value.pointer.p)); - chand->client_channel_factory = - static_cast(arg->value.pointer.p); - // Get server name to resolve, using proxy mapper if needed. - arg = grpc_channel_args_find(args->channel_args, GRPC_ARG_SERVER_URI); - if (arg == nullptr) { - return GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "Missing server uri in args for client channel filter"); - } - if (arg->type != GRPC_ARG_STRING) { - return GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "server uri arg must be a string"); - } - char* proxy_name = nullptr; - grpc_channel_args* new_args = nullptr; - grpc_proxy_mappers_map_name(arg->value.string, args->channel_args, - &proxy_name, &new_args); - // Instantiate resolver. - chand->resolver = grpc_core::ResolverRegistry::CreateResolver( - proxy_name != nullptr ? proxy_name : arg->value.string, - new_args != nullptr ? new_args : args->channel_args, - chand->interested_parties, chand->combiner); - if (proxy_name != nullptr) gpr_free(proxy_name); - if (new_args != nullptr) grpc_channel_args_destroy(new_args); - if (chand->resolver == nullptr) { - return GRPC_ERROR_CREATE_FROM_STATIC_STRING("resolver creation failed"); - } - chand->deadline_checking_enabled = - grpc_deadline_checking_enabled(args->channel_args); - return GRPC_ERROR_NONE; -} - -/* Destructor for channel_data */ -static void cc_destroy_channel_elem(grpc_channel_element* elem) { - channel_data* chand = static_cast(elem->channel_data); - if (chand->resolver != nullptr) { - // The only way we can get here is if we never started resolving, - // because we take a ref to the channel stack when we start - // resolving and do not release it until the resolver callback is - // invoked after the resolver shuts down. - chand->resolver.reset(); - } - if (chand->client_channel_factory != nullptr) { - grpc_client_channel_factory_unref(chand->client_channel_factory); - } - if (chand->lb_policy != nullptr) { - grpc_pollset_set_del_pollset_set(chand->lb_policy->interested_parties(), - chand->interested_parties); - chand->lb_policy.reset(); - } - // TODO(roth): Once we convert the filter API to C++, there will no - // longer be any need to explicitly reset these smart pointer data members. - chand->info_lb_policy_name.reset(); - chand->info_service_config_json.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); - GRPC_COMBINER_UNREF(chand->combiner, "client_channel"); - gpr_mu_destroy(&chand->info_mu); - gpr_mu_destroy(&chand->external_connectivity_watcher_list_mu); -} - -/************************************************************************* - * PER-CALL FUNCTIONS - */ - // Max number of batches that can be pending on a call at any given // time. This includes one batch for each of the following ops: // recv_initial_metadata @@ -784,6 +91,1372 @@ static void cc_destroy_channel_elem(grpc_channel_element* elem) { // send_trailing_metadata #define MAX_PENDING_BATCHES 6 +namespace grpc_core { + +TraceFlag grpc_client_channel_call_trace(false, "client_channel_call"); +TraceFlag grpc_client_channel_routing_trace(false, "client_channel_routing"); + +namespace { + +// +// ChannelData definition +// + +class ChannelData { + public: + struct QueuedPick { + LoadBalancingPolicy::PickArgs pick; + grpc_call_element* elem; + QueuedPick* next = nullptr; + }; + + static grpc_error* Init(grpc_channel_element* elem, + grpc_channel_element_args* args); + static void Destroy(grpc_channel_element* elem); + static void StartTransportOp(grpc_channel_element* elem, + grpc_transport_op* op); + static void GetChannelInfo(grpc_channel_element* elem, + const grpc_channel_info* info); + + void set_channelz_node(channelz::ClientChannelNode* node) { + channelz_node_ = node; + resolving_lb_policy_->set_channelz_node(node->Ref()); + } + void FillChildRefsForChannelz(channelz::ChildRefsList* child_subchannels, + channelz::ChildRefsList* child_channels) { + if (resolving_lb_policy_ != nullptr) { + resolving_lb_policy_->FillChildRefsForChannelz(child_subchannels, + child_channels); + } + } + + bool deadline_checking_enabled() const { return deadline_checking_enabled_; } + bool enable_retries() const { return enable_retries_; } + size_t per_rpc_retry_buffer_size() const { + return per_rpc_retry_buffer_size_; + } + + // Note: Does NOT return a new ref. + grpc_error* disconnect_error() const { + return disconnect_error_.Load(MemoryOrder::ACQUIRE); + } + + grpc_combiner* data_plane_combiner() const { return data_plane_combiner_; } + + LoadBalancingPolicy::SubchannelPicker* picker() const { + return picker_.get(); + } + void AddQueuedPick(QueuedPick* pick, grpc_polling_entity* pollent); + void RemoveQueuedPick(QueuedPick* to_remove, grpc_polling_entity* pollent); + + bool received_service_config_data() const { + return received_service_config_data_; + } + RefCountedPtr retry_throttle_data() const { + return retry_throttle_data_; + } + RefCountedPtr service_config() const { + return service_config_; + } + + grpc_connectivity_state CheckConnectivityState(bool try_to_connect); + void AddExternalConnectivityWatcher(grpc_polling_entity pollent, + grpc_connectivity_state* state, + grpc_closure* on_complete, + grpc_closure* watcher_timer_init) { + // Will delete itself. + New(this, pollent, state, on_complete, + watcher_timer_init); + } + int NumExternalConnectivityWatchers() const { + return external_connectivity_watcher_list_.size(); + } + + private: + class ConnectivityStateAndPickerSetter; + class ServiceConfigSetter; + class ClientChannelControlHelper; + + class ExternalConnectivityWatcher { + public: + class WatcherList { + public: + WatcherList() { gpr_mu_init(&mu_); } + ~WatcherList() { gpr_mu_destroy(&mu_); } + + int size() const; + ExternalConnectivityWatcher* Lookup(grpc_closure* on_complete) const; + void Add(ExternalConnectivityWatcher* watcher); + void Remove(const ExternalConnectivityWatcher* watcher); + + private: + // head_ is guarded by a mutex, since the size() method needs to + // iterate over the list, and it's called from the C-core API + // function grpc_channel_num_external_connectivity_watchers(), which + // is synchronous and therefore cannot run in the combiner. + mutable gpr_mu mu_; + ExternalConnectivityWatcher* head_ = nullptr; + }; + + ExternalConnectivityWatcher(ChannelData* chand, grpc_polling_entity pollent, + grpc_connectivity_state* state, + grpc_closure* on_complete, + grpc_closure* watcher_timer_init); + + ~ExternalConnectivityWatcher(); + + private: + static void OnWatchCompleteLocked(void* arg, grpc_error* error); + static void WatchConnectivityStateLocked(void* arg, grpc_error* ignored); + + ChannelData* chand_; + grpc_polling_entity pollent_; + grpc_connectivity_state* state_; + grpc_closure* on_complete_; + grpc_closure* watcher_timer_init_; + grpc_closure my_closure_; + ExternalConnectivityWatcher* next_ = nullptr; + }; + + ChannelData(grpc_channel_element_args* args, grpc_error** error); + ~ChannelData(); + + static bool ProcessResolverResultLocked( + void* arg, Resolver::Result* result, const char** lb_policy_name, + RefCountedPtr* lb_policy_config, + grpc_error** service_config_error); + + grpc_error* DoPingLocked(grpc_transport_op* op); + + static void StartTransportOpLocked(void* arg, grpc_error* ignored); + + static void TryToConnectLocked(void* arg, grpc_error* error_ignored); + + void ProcessLbPolicy( + const Resolver::Result& resolver_result, + const internal::ClientChannelGlobalParsedObject* parsed_service_config, + UniquePtr* lb_policy_name, + RefCountedPtr* lb_policy_config); + + // + // Fields set at construction and never modified. + // + const bool deadline_checking_enabled_; + const bool enable_retries_; + const size_t per_rpc_retry_buffer_size_; + grpc_channel_stack* owning_stack_; + ClientChannelFactory* client_channel_factory_; + UniquePtr server_name_; + RefCountedPtr default_service_config_; + // Initialized shortly after construction. + channelz::ClientChannelNode* channelz_node_ = nullptr; + + // + // Fields used in the data plane. Guarded by data_plane_combiner. + // + grpc_combiner* data_plane_combiner_; + UniquePtr picker_; + QueuedPick* queued_picks_ = nullptr; // Linked list of queued picks. + // Data from service config. + bool received_service_config_data_ = false; + RefCountedPtr retry_throttle_data_; + RefCountedPtr service_config_; + + // + // Fields used in the control plane. Guarded by combiner. + // + grpc_combiner* combiner_; + grpc_pollset_set* interested_parties_; + RefCountedPtr subchannel_pool_; + OrphanablePtr resolving_lb_policy_; + grpc_connectivity_state_tracker state_tracker_; + ExternalConnectivityWatcher::WatcherList external_connectivity_watcher_list_; + RefCountedPtr saved_service_config_; + bool received_first_resolver_result_ = false; + + // + // Fields accessed from both data plane and control plane combiners. + // + Atomic disconnect_error_; + + // + // Fields guarded by a mutex, since they need to be accessed + // synchronously via get_channel_info(). + // + gpr_mu info_mu_; + UniquePtr info_lb_policy_name_; + UniquePtr info_service_config_json_; +}; + +// +// CallData definition +// + +class CallData { + public: + static grpc_error* Init(grpc_call_element* elem, + const grpc_call_element_args* args); + static void Destroy(grpc_call_element* elem, + const grpc_call_final_info* final_info, + grpc_closure* then_schedule_closure); + static void StartTransportStreamOpBatch( + grpc_call_element* elem, grpc_transport_stream_op_batch* batch); + static void SetPollent(grpc_call_element* elem, grpc_polling_entity* pollent); + + RefCountedPtr subchannel_call() { return subchannel_call_; } + + // Invoked by channel for queued picks once resolver results are available. + void MaybeApplyServiceConfigToCallLocked(grpc_call_element* elem); + + // Invoked by channel for queued picks when the picker is updated. + static void StartPickLocked(void* arg, grpc_error* error); + + private: + class QueuedPickCanceller; + + // State used for starting a retryable batch on a subchannel call. + // This provides its own grpc_transport_stream_op_batch and other data + // structures needed to populate the ops in the batch. + // We allocate one struct on the arena for each attempt at starting a + // batch on a given subchannel call. + struct SubchannelCallBatchData { + // Creates a SubchannelCallBatchData object on the call's arena with the + // specified refcount. If set_on_complete is true, the batch's + // on_complete callback will be set to point to on_complete(); + // otherwise, the batch's on_complete callback will be null. + static SubchannelCallBatchData* Create(grpc_call_element* elem, + int refcount, bool set_on_complete); + + void Unref() { + if (gpr_unref(&refs)) Destroy(); + } + + SubchannelCallBatchData(grpc_call_element* elem, CallData* calld, + int refcount, bool set_on_complete); + // All dtor code must be added in `Destroy()`. This is because we may + // call closures in `SubchannelCallBatchData` after they are unrefed by + // `Unref()`, and msan would complain about accessing this class + // after calling dtor. As a result we cannot call the `dtor` in `Unref()`. + // TODO(soheil): We should try to call the dtor in `Unref()`. + ~SubchannelCallBatchData() { Destroy(); } + void Destroy(); + + gpr_refcount refs; + grpc_call_element* elem; + RefCountedPtr subchannel_call; + // The batch to use in the subchannel call. + // Its payload field points to SubchannelCallRetryState::batch_payload. + grpc_transport_stream_op_batch batch; + // For intercepting on_complete. + grpc_closure on_complete; + }; + + // Retry state associated with a subchannel call. + // Stored in the parent_data of the subchannel call object. + struct SubchannelCallRetryState { + explicit SubchannelCallRetryState(grpc_call_context_element* context) + : batch_payload(context), + started_send_initial_metadata(false), + completed_send_initial_metadata(false), + started_send_trailing_metadata(false), + completed_send_trailing_metadata(false), + started_recv_initial_metadata(false), + completed_recv_initial_metadata(false), + started_recv_trailing_metadata(false), + completed_recv_trailing_metadata(false), + retry_dispatched(false) {} + + // SubchannelCallBatchData.batch.payload points to this. + grpc_transport_stream_op_batch_payload batch_payload; + // For send_initial_metadata. + // Note that we need to make a copy of the initial metadata for each + // subchannel call instead of just referring to the copy in call_data, + // because filters in the subchannel stack will probably add entries, + // so we need to start in a pristine state for each attempt of the call. + grpc_linked_mdelem* send_initial_metadata_storage; + grpc_metadata_batch send_initial_metadata; + // For send_message. + // TODO(roth): Restructure this to eliminate use of ManualConstructor. + ManualConstructor send_message; + // For send_trailing_metadata. + grpc_linked_mdelem* send_trailing_metadata_storage; + grpc_metadata_batch send_trailing_metadata; + // For intercepting recv_initial_metadata. + grpc_metadata_batch recv_initial_metadata; + grpc_closure recv_initial_metadata_ready; + bool trailing_metadata_available = false; + // For intercepting recv_message. + grpc_closure recv_message_ready; + OrphanablePtr recv_message; + // For intercepting recv_trailing_metadata. + grpc_metadata_batch recv_trailing_metadata; + grpc_transport_stream_stats collect_stats; + grpc_closure recv_trailing_metadata_ready; + // These fields indicate which ops have been started and completed on + // this subchannel call. + size_t started_send_message_count = 0; + size_t completed_send_message_count = 0; + size_t started_recv_message_count = 0; + size_t completed_recv_message_count = 0; + bool started_send_initial_metadata : 1; + bool completed_send_initial_metadata : 1; + bool started_send_trailing_metadata : 1; + bool completed_send_trailing_metadata : 1; + bool started_recv_initial_metadata : 1; + bool completed_recv_initial_metadata : 1; + bool started_recv_trailing_metadata : 1; + bool completed_recv_trailing_metadata : 1; + // State for callback processing. + SubchannelCallBatchData* recv_initial_metadata_ready_deferred_batch = + nullptr; + grpc_error* recv_initial_metadata_error = GRPC_ERROR_NONE; + SubchannelCallBatchData* recv_message_ready_deferred_batch = nullptr; + grpc_error* recv_message_error = GRPC_ERROR_NONE; + SubchannelCallBatchData* recv_trailing_metadata_internal_batch = nullptr; + // NOTE: Do not move this next to the metadata bitfields above. That would + // save space but will also result in a data race because compiler + // will generate a 2 byte store which overwrites the meta-data + // fields upon setting this field. + bool retry_dispatched : 1; + }; + + // Pending batches stored in call data. + struct PendingBatch { + // The pending batch. If nullptr, this slot is empty. + grpc_transport_stream_op_batch* batch; + // Indicates whether payload for send ops has been cached in CallData. + bool send_ops_cached; + }; + + CallData(grpc_call_element* elem, const ChannelData& chand, + const grpc_call_element_args& args); + ~CallData(); + + // Caches data for send ops so that it can be retried later, if not + // already cached. + void MaybeCacheSendOpsForBatch(PendingBatch* pending); + void FreeCachedSendInitialMetadata(ChannelData* chand); + // Frees cached send_message at index idx. + void FreeCachedSendMessage(ChannelData* chand, size_t idx); + void FreeCachedSendTrailingMetadata(ChannelData* chand); + // Frees cached send ops that have already been completed after + // committing the call. + void FreeCachedSendOpDataAfterCommit(grpc_call_element* elem, + SubchannelCallRetryState* retry_state); + // Frees cached send ops that were completed by the completed batch in + // batch_data. Used when batches are completed after the call is committed. + void FreeCachedSendOpDataForCompletedBatch( + grpc_call_element* elem, SubchannelCallBatchData* batch_data, + SubchannelCallRetryState* retry_state); + + static void MaybeInjectRecvTrailingMetadataReadyForLoadBalancingPolicy( + const LoadBalancingPolicy::PickArgs& pick, + grpc_transport_stream_op_batch* batch); + + // Returns the index into pending_batches_ to be used for batch. + static size_t GetBatchIndex(grpc_transport_stream_op_batch* batch); + void PendingBatchesAdd(grpc_call_element* elem, + grpc_transport_stream_op_batch* batch); + void PendingBatchClear(PendingBatch* pending); + void MaybeClearPendingBatch(grpc_call_element* elem, PendingBatch* pending); + static void FailPendingBatchInCallCombiner(void* arg, grpc_error* error); + // A predicate type and some useful implementations for PendingBatchesFail(). + typedef bool (*YieldCallCombinerPredicate)( + const CallCombinerClosureList& closures); + static bool YieldCallCombiner(const CallCombinerClosureList& closures) { + return true; + } + static bool NoYieldCallCombiner(const CallCombinerClosureList& closures) { + return false; + } + static bool YieldCallCombinerIfPendingBatchesFound( + const CallCombinerClosureList& closures) { + return closures.size() > 0; + } + // Fails all pending batches. + // If yield_call_combiner_predicate returns true, assumes responsibility for + // yielding the call combiner. + void PendingBatchesFail( + grpc_call_element* elem, grpc_error* error, + YieldCallCombinerPredicate yield_call_combiner_predicate); + static void ResumePendingBatchInCallCombiner(void* arg, grpc_error* ignored); + // Resumes all pending batches on subchannel_call_. + void PendingBatchesResume(grpc_call_element* elem); + // Returns a pointer to the first pending batch for which predicate(batch) + // returns true, or null if not found. + template + PendingBatch* PendingBatchFind(grpc_call_element* elem, + const char* log_message, Predicate predicate); + + // Commits the call so that no further retry attempts will be performed. + void RetryCommit(grpc_call_element* elem, + SubchannelCallRetryState* retry_state); + // Starts a retry after appropriate back-off. + void DoRetry(grpc_call_element* elem, SubchannelCallRetryState* retry_state, + grpc_millis server_pushback_ms); + // Returns true if the call is being retried. + bool MaybeRetry(grpc_call_element* elem, SubchannelCallBatchData* batch_data, + grpc_status_code status, grpc_mdelem* server_pushback_md); + + // Invokes recv_initial_metadata_ready for a subchannel batch. + static void InvokeRecvInitialMetadataCallback(void* arg, grpc_error* error); + // Intercepts recv_initial_metadata_ready callback for retries. + // Commits the call and returns the initial metadata up the stack. + static void RecvInitialMetadataReady(void* arg, grpc_error* error); + + // Invokes recv_message_ready for a subchannel batch. + static void InvokeRecvMessageCallback(void* arg, grpc_error* error); + // Intercepts recv_message_ready callback for retries. + // Commits the call and returns the message up the stack. + static void RecvMessageReady(void* arg, grpc_error* error); + + // Sets *status and *server_pushback_md based on md_batch and error. + // Only sets *server_pushback_md if server_pushback_md != nullptr. + void GetCallStatus(grpc_call_element* elem, grpc_metadata_batch* md_batch, + grpc_error* error, grpc_status_code* status, + grpc_mdelem** server_pushback_md); + // Adds recv_trailing_metadata_ready closure to closures. + void AddClosureForRecvTrailingMetadataReady( + grpc_call_element* elem, SubchannelCallBatchData* batch_data, + grpc_error* error, CallCombinerClosureList* closures); + // Adds any necessary closures for deferred recv_initial_metadata and + // recv_message callbacks to closures. + static void AddClosuresForDeferredRecvCallbacks( + SubchannelCallBatchData* batch_data, + SubchannelCallRetryState* retry_state, CallCombinerClosureList* closures); + // Returns true if any op in the batch was not yet started. + // Only looks at send ops, since recv ops are always started immediately. + bool PendingBatchIsUnstarted(PendingBatch* pending, + SubchannelCallRetryState* retry_state); + // For any pending batch containing an op that has not yet been started, + // adds the pending batch's completion closures to closures. + void AddClosuresToFailUnstartedPendingBatches( + grpc_call_element* elem, SubchannelCallRetryState* retry_state, + grpc_error* error, CallCombinerClosureList* closures); + // Runs necessary closures upon completion of a call attempt. + void RunClosuresForCompletedCall(SubchannelCallBatchData* batch_data, + grpc_error* error); + // Intercepts recv_trailing_metadata_ready callback for retries. + // Commits the call and returns the trailing metadata up the stack. + static void RecvTrailingMetadataReady(void* arg, grpc_error* error); + + // Adds the on_complete closure for the pending batch completed in + // batch_data to closures. + void AddClosuresForCompletedPendingBatch( + grpc_call_element* elem, SubchannelCallBatchData* batch_data, + SubchannelCallRetryState* retry_state, grpc_error* error, + CallCombinerClosureList* closures); + + // If there are any cached ops to replay or pending ops to start on the + // subchannel call, adds a closure to closures to invoke + // StartRetriableSubchannelBatches(). + void AddClosuresForReplayOrPendingSendOps( + grpc_call_element* elem, SubchannelCallBatchData* batch_data, + SubchannelCallRetryState* retry_state, CallCombinerClosureList* closures); + + // Callback used to intercept on_complete from subchannel calls. + // Called only when retries are enabled. + static void OnComplete(void* arg, grpc_error* error); + + static void StartBatchInCallCombiner(void* arg, grpc_error* ignored); + // Adds a closure to closures that will execute batch in the call combiner. + void AddClosureForSubchannelBatch(grpc_call_element* elem, + grpc_transport_stream_op_batch* batch, + CallCombinerClosureList* closures); + // Adds retriable send_initial_metadata op to batch_data. + void AddRetriableSendInitialMetadataOp(SubchannelCallRetryState* retry_state, + SubchannelCallBatchData* batch_data); + // Adds retriable send_message op to batch_data. + void AddRetriableSendMessageOp(grpc_call_element* elem, + SubchannelCallRetryState* retry_state, + SubchannelCallBatchData* batch_data); + // Adds retriable send_trailing_metadata op to batch_data. + void AddRetriableSendTrailingMetadataOp(SubchannelCallRetryState* retry_state, + SubchannelCallBatchData* batch_data); + // Adds retriable recv_initial_metadata op to batch_data. + void AddRetriableRecvInitialMetadataOp(SubchannelCallRetryState* retry_state, + SubchannelCallBatchData* batch_data); + // Adds retriable recv_message op to batch_data. + void AddRetriableRecvMessageOp(SubchannelCallRetryState* retry_state, + SubchannelCallBatchData* batch_data); + // Adds retriable recv_trailing_metadata op to batch_data. + void AddRetriableRecvTrailingMetadataOp(SubchannelCallRetryState* retry_state, + SubchannelCallBatchData* batch_data); + // Helper function used to start a recv_trailing_metadata batch. This + // is used in the case where a recv_initial_metadata or recv_message + // op fails in a way that we know the call is over but when the application + // has not yet started its own recv_trailing_metadata op. + void StartInternalRecvTrailingMetadata(grpc_call_element* elem); + // If there are any cached send ops that need to be replayed on the + // current subchannel call, creates and returns a new subchannel batch + // to replay those ops. Otherwise, returns nullptr. + SubchannelCallBatchData* MaybeCreateSubchannelBatchForReplay( + grpc_call_element* elem, SubchannelCallRetryState* retry_state); + // Adds subchannel batches for pending batches to closures. + void AddSubchannelBatchesForPendingBatches( + grpc_call_element* elem, SubchannelCallRetryState* retry_state, + CallCombinerClosureList* closures); + // Constructs and starts whatever subchannel batches are needed on the + // subchannel call. + static void StartRetriableSubchannelBatches(void* arg, grpc_error* ignored); + + void CreateSubchannelCall(grpc_call_element* elem); + // Invoked when a pick is completed, on both success or failure. + static void PickDone(void* arg, grpc_error* error); + // Removes the call from the channel's list of queued picks. + void RemoveCallFromQueuedPicksLocked(grpc_call_element* elem); + // Adds the call to the channel's list of queued picks. + void AddCallToQueuedPicksLocked(grpc_call_element* elem); + // Applies service config to the call. Must be invoked once we know + // that the resolver has returned results to the channel. + void ApplyServiceConfigToCallLocked(grpc_call_element* elem); + + // State for handling deadlines. + // The code in deadline_filter.c requires this to be the first field. + // TODO(roth): This is slightly sub-optimal in that grpc_deadline_state + // and this struct both independently store pointers to the call stack + // and call combiner. If/when we have time, find a way to avoid this + // without breaking the grpc_deadline_state abstraction. + grpc_deadline_state deadline_state_; + + grpc_slice path_; // Request path. + gpr_timespec call_start_time_; + grpc_millis deadline_; + Arena* arena_; + grpc_call_stack* owning_call_; + CallCombiner* call_combiner_; + grpc_call_context_element* call_context_; + + RefCountedPtr retry_throttle_data_; + ServiceConfig::CallData service_config_call_data_; + const ClientChannelMethodParsedObject* method_params_ = nullptr; + + RefCountedPtr subchannel_call_; + + // Set when we get a cancel_stream op. + grpc_error* cancel_error_ = GRPC_ERROR_NONE; + + ChannelData::QueuedPick pick_; + bool pick_queued_ = false; + bool service_config_applied_ = false; + QueuedPickCanceller* pick_canceller_ = nullptr; + grpc_closure pick_closure_; + + grpc_polling_entity* pollent_ = nullptr; + + // Batches are added to this list when received from above. + // They are removed when we are done handling the batch (i.e., when + // either we have invoked all of the batch's callbacks or we have + // passed the batch down to the subchannel call and are not + // intercepting any of its callbacks). + PendingBatch pending_batches_[MAX_PENDING_BATCHES] = {}; + bool pending_send_initial_metadata_ : 1; + bool pending_send_message_ : 1; + bool pending_send_trailing_metadata_ : 1; + + // Retry state. + bool enable_retries_ : 1; + bool retry_committed_ : 1; + bool last_attempt_got_server_pushback_ : 1; + int num_attempts_completed_ = 0; + size_t bytes_buffered_for_retry_ = 0; + // TODO(roth): Restructure this to eliminate use of ManualConstructor. + ManualConstructor retry_backoff_; + grpc_timer retry_timer_; + + // The number of pending retriable subchannel batches containing send ops. + // We hold a ref to the call stack while this is non-zero, since replay + // batches may not complete until after all callbacks have been returned + // to the surface, and we need to make sure that the call is not destroyed + // until all of these batches have completed. + // Note that we actually only need to track replay batches, but it's + // easier to track all batches with send ops. + int num_pending_retriable_subchannel_send_batches_ = 0; + + // Cached data for retrying send ops. + // send_initial_metadata + bool seen_send_initial_metadata_ = false; + grpc_linked_mdelem* send_initial_metadata_storage_ = nullptr; + grpc_metadata_batch send_initial_metadata_; + uint32_t send_initial_metadata_flags_; + gpr_atm* peer_string_; + // send_message + // When we get a send_message op, we replace the original byte stream + // with a CachingByteStream that caches the slices to a local buffer for + // use in retries. + // 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. + InlinedVector send_messages_; + // send_trailing_metadata + bool seen_send_trailing_metadata_ = false; + grpc_linked_mdelem* send_trailing_metadata_storage_ = nullptr; + grpc_metadata_batch send_trailing_metadata_; +}; + +// +// ChannelData::ConnectivityStateAndPickerSetter +// + +// A fire-and-forget class that sets the channel's connectivity state +// and then hops into the data plane combiner to update the picker. +// Must be instantiated while holding the control plane combiner. +// Deletes itself when done. +class ChannelData::ConnectivityStateAndPickerSetter { + public: + ConnectivityStateAndPickerSetter( + ChannelData* chand, grpc_connectivity_state state, const char* reason, + UniquePtr picker) + : chand_(chand), picker_(std::move(picker)) { + // Update connectivity state here, while holding control plane combiner. + grpc_connectivity_state_set(&chand->state_tracker_, state, reason); + if (chand->channelz_node_ != nullptr) { + chand->channelz_node_->AddTraceEvent( + channelz::ChannelTrace::Severity::Info, + grpc_slice_from_static_string( + GetChannelConnectivityStateChangeString(state))); + } + // Bounce into the data plane combiner to reset the picker. + GRPC_CHANNEL_STACK_REF(chand->owning_stack_, + "ConnectivityStateAndPickerSetter"); + GRPC_CLOSURE_INIT(&closure_, SetPicker, this, + grpc_combiner_scheduler(chand->data_plane_combiner_)); + GRPC_CLOSURE_SCHED(&closure_, GRPC_ERROR_NONE); + } + + private: + static const char* GetChannelConnectivityStateChangeString( + grpc_connectivity_state state) { + switch (state) { + case GRPC_CHANNEL_IDLE: + return "Channel state change to IDLE"; + case GRPC_CHANNEL_CONNECTING: + return "Channel state change to CONNECTING"; + case GRPC_CHANNEL_READY: + return "Channel state change to READY"; + case GRPC_CHANNEL_TRANSIENT_FAILURE: + return "Channel state change to TRANSIENT_FAILURE"; + case GRPC_CHANNEL_SHUTDOWN: + return "Channel state change to SHUTDOWN"; + } + GPR_UNREACHABLE_CODE(return "UNKNOWN"); + } + + static void SetPicker(void* arg, grpc_error* ignored) { + auto* self = static_cast(arg); + // Update picker. + self->chand_->picker_ = std::move(self->picker_); + // Re-process queued picks. + for (QueuedPick* pick = self->chand_->queued_picks_; pick != nullptr; + pick = pick->next) { + CallData::StartPickLocked(pick->elem, GRPC_ERROR_NONE); + } + // Clean up. + GRPC_CHANNEL_STACK_UNREF(self->chand_->owning_stack_, + "ConnectivityStateAndPickerSetter"); + Delete(self); + } + + ChannelData* chand_; + UniquePtr picker_; + grpc_closure closure_; +}; + +// +// ChannelData::ServiceConfigSetter +// + +// A fire-and-forget class that sets the channel's service config data +// in the data plane combiner. Deletes itself when done. +class ChannelData::ServiceConfigSetter { + public: + ServiceConfigSetter( + ChannelData* chand, + Optional + retry_throttle_data, + RefCountedPtr service_config) + : chand_(chand), + retry_throttle_data_(retry_throttle_data), + service_config_(std::move(service_config)) { + GRPC_CHANNEL_STACK_REF(chand->owning_stack_, "ServiceConfigSetter"); + GRPC_CLOSURE_INIT(&closure_, SetServiceConfigData, this, + grpc_combiner_scheduler(chand->data_plane_combiner_)); + GRPC_CLOSURE_SCHED(&closure_, GRPC_ERROR_NONE); + } + + private: + static void SetServiceConfigData(void* arg, grpc_error* ignored) { + ServiceConfigSetter* self = static_cast(arg); + ChannelData* chand = self->chand_; + // Update channel state. + chand->received_service_config_data_ = true; + if (self->retry_throttle_data_.has_value()) { + chand->retry_throttle_data_ = + internal::ServerRetryThrottleMap::GetDataForServer( + chand->server_name_.get(), + self->retry_throttle_data_.value().max_milli_tokens, + self->retry_throttle_data_.value().milli_token_ratio); + } + chand->service_config_ = std::move(self->service_config_); + // Apply service config to queued picks. + for (QueuedPick* pick = chand->queued_picks_; pick != nullptr; + pick = pick->next) { + CallData* calld = static_cast(pick->elem->call_data); + calld->MaybeApplyServiceConfigToCallLocked(pick->elem); + } + // Clean up. + GRPC_CHANNEL_STACK_UNREF(self->chand_->owning_stack_, + "ServiceConfigSetter"); + Delete(self); + } + + ChannelData* chand_; + Optional + retry_throttle_data_; + RefCountedPtr service_config_; + grpc_closure closure_; +}; + +// +// ChannelData::ExternalConnectivityWatcher::WatcherList +// + +int ChannelData::ExternalConnectivityWatcher::WatcherList::size() const { + MutexLock lock(&mu_); + int count = 0; + for (ExternalConnectivityWatcher* w = head_; w != nullptr; w = w->next_) { + ++count; + } + return count; +} + +ChannelData::ExternalConnectivityWatcher* +ChannelData::ExternalConnectivityWatcher::WatcherList::Lookup( + grpc_closure* on_complete) const { + MutexLock lock(&mu_); + ExternalConnectivityWatcher* w = head_; + while (w != nullptr && w->on_complete_ != on_complete) { + w = w->next_; + } + return w; +} + +void ChannelData::ExternalConnectivityWatcher::WatcherList::Add( + ExternalConnectivityWatcher* watcher) { + GPR_ASSERT(Lookup(watcher->on_complete_) == nullptr); + MutexLock lock(&mu_); + GPR_ASSERT(watcher->next_ == nullptr); + watcher->next_ = head_; + head_ = watcher; +} + +void ChannelData::ExternalConnectivityWatcher::WatcherList::Remove( + const ExternalConnectivityWatcher* watcher) { + MutexLock lock(&mu_); + if (watcher == head_) { + head_ = watcher->next_; + return; + } + for (ExternalConnectivityWatcher* w = head_; w != nullptr; w = w->next_) { + if (w->next_ == watcher) { + w->next_ = w->next_->next_; + return; + } + } + GPR_UNREACHABLE_CODE(return ); +} + +// +// ChannelData::ExternalConnectivityWatcher +// + +ChannelData::ExternalConnectivityWatcher::ExternalConnectivityWatcher( + ChannelData* chand, grpc_polling_entity pollent, + grpc_connectivity_state* state, grpc_closure* on_complete, + grpc_closure* watcher_timer_init) + : chand_(chand), + pollent_(pollent), + state_(state), + on_complete_(on_complete), + watcher_timer_init_(watcher_timer_init) { + grpc_polling_entity_add_to_pollset_set(&pollent_, + chand_->interested_parties_); + GRPC_CHANNEL_STACK_REF(chand_->owning_stack_, "ExternalConnectivityWatcher"); + GRPC_CLOSURE_SCHED( + GRPC_CLOSURE_INIT(&my_closure_, WatchConnectivityStateLocked, this, + grpc_combiner_scheduler(chand_->combiner_)), + GRPC_ERROR_NONE); +} + +ChannelData::ExternalConnectivityWatcher::~ExternalConnectivityWatcher() { + grpc_polling_entity_del_from_pollset_set(&pollent_, + chand_->interested_parties_); + GRPC_CHANNEL_STACK_UNREF(chand_->owning_stack_, + "ExternalConnectivityWatcher"); +} + +void ChannelData::ExternalConnectivityWatcher::OnWatchCompleteLocked( + void* arg, grpc_error* error) { + ExternalConnectivityWatcher* self = + static_cast(arg); + grpc_closure* on_complete = self->on_complete_; + self->chand_->external_connectivity_watcher_list_.Remove(self); + Delete(self); + GRPC_CLOSURE_SCHED(on_complete, GRPC_ERROR_REF(error)); +} + +void ChannelData::ExternalConnectivityWatcher::WatchConnectivityStateLocked( + void* arg, grpc_error* ignored) { + ExternalConnectivityWatcher* self = + static_cast(arg); + if (self->state_ == nullptr) { + // Handle cancellation. + GPR_ASSERT(self->watcher_timer_init_ == nullptr); + ExternalConnectivityWatcher* found = + self->chand_->external_connectivity_watcher_list_.Lookup( + self->on_complete_); + if (found != nullptr) { + grpc_connectivity_state_notify_on_state_change( + &found->chand_->state_tracker_, nullptr, &found->my_closure_); + } + Delete(self); + return; + } + // New watcher. + self->chand_->external_connectivity_watcher_list_.Add(self); + // This assumes that the closure is scheduled on the ExecCtx scheduler + // and that GRPC_CLOSURE_RUN would run the closure immediately. + GRPC_CLOSURE_RUN(self->watcher_timer_init_, GRPC_ERROR_NONE); + GRPC_CLOSURE_INIT(&self->my_closure_, OnWatchCompleteLocked, self, + grpc_combiner_scheduler(self->chand_->combiner_)); + grpc_connectivity_state_notify_on_state_change( + &self->chand_->state_tracker_, self->state_, &self->my_closure_); +} + +// +// ChannelData::ClientChannelControlHelper +// + +class ChannelData::ClientChannelControlHelper + : public LoadBalancingPolicy::ChannelControlHelper { + public: + explicit ClientChannelControlHelper(ChannelData* chand) : chand_(chand) { + GRPC_CHANNEL_STACK_REF(chand_->owning_stack_, "ClientChannelControlHelper"); + } + + ~ClientChannelControlHelper() override { + GRPC_CHANNEL_STACK_UNREF(chand_->owning_stack_, + "ClientChannelControlHelper"); + } + + Subchannel* CreateSubchannel(const grpc_channel_args& args) override { + grpc_arg arg = SubchannelPoolInterface::CreateChannelArg( + chand_->subchannel_pool_.get()); + grpc_channel_args* new_args = + grpc_channel_args_copy_and_add(&args, &arg, 1); + Subchannel* subchannel = + chand_->client_channel_factory_->CreateSubchannel(new_args); + grpc_channel_args_destroy(new_args); + return subchannel; + } + + grpc_channel* CreateChannel(const char* target, + const grpc_channel_args& args) override { + return chand_->client_channel_factory_->CreateChannel(target, &args); + } + + void UpdateState( + grpc_connectivity_state state, + UniquePtr picker) override { + grpc_error* disconnect_error = + chand_->disconnect_error_.Load(MemoryOrder::ACQUIRE); + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) { + const char* extra = disconnect_error == GRPC_ERROR_NONE + ? "" + : " (ignoring -- channel shutting down)"; + gpr_log(GPR_INFO, "chand=%p: update: state=%s picker=%p%s", chand_, + grpc_connectivity_state_name(state), picker.get(), extra); + } + // Do update only if not shutting down. + if (disconnect_error == GRPC_ERROR_NONE) { + // Will delete itself. + New(chand_, state, "helper", + std::move(picker)); + } + } + + // No-op -- we should never get this from ResolvingLoadBalancingPolicy. + void RequestReresolution() override {} + + private: + ChannelData* chand_; +}; + +// +// ChannelData implementation +// + +grpc_error* ChannelData::Init(grpc_channel_element* elem, + grpc_channel_element_args* args) { + GPR_ASSERT(args->is_last); + GPR_ASSERT(elem->filter == &grpc_client_channel_filter); + grpc_error* error = GRPC_ERROR_NONE; + new (elem->channel_data) ChannelData(args, &error); + return error; +} + +void ChannelData::Destroy(grpc_channel_element* elem) { + ChannelData* chand = static_cast(elem->channel_data); + chand->~ChannelData(); +} + +bool GetEnableRetries(const grpc_channel_args* args) { + return grpc_channel_arg_get_bool( + grpc_channel_args_find(args, GRPC_ARG_ENABLE_RETRIES), true); +} + +size_t GetMaxPerRpcRetryBufferSize(const grpc_channel_args* args) { + return static_cast(grpc_channel_arg_get_integer( + grpc_channel_args_find(args, GRPC_ARG_PER_RPC_RETRY_BUFFER_SIZE), + {DEFAULT_PER_RPC_RETRY_BUFFER_SIZE, 0, INT_MAX})); +} + +RefCountedPtr GetSubchannelPool( + const grpc_channel_args* args) { + const bool use_local_subchannel_pool = grpc_channel_arg_get_bool( + grpc_channel_args_find(args, GRPC_ARG_USE_LOCAL_SUBCHANNEL_POOL), false); + if (use_local_subchannel_pool) { + return MakeRefCounted(); + } + return GlobalSubchannelPool::instance(); +} + +ChannelData::ChannelData(grpc_channel_element_args* args, grpc_error** error) + : deadline_checking_enabled_( + grpc_deadline_checking_enabled(args->channel_args)), + enable_retries_(GetEnableRetries(args->channel_args)), + per_rpc_retry_buffer_size_( + GetMaxPerRpcRetryBufferSize(args->channel_args)), + owning_stack_(args->channel_stack), + client_channel_factory_( + ClientChannelFactory::GetFromChannelArgs(args->channel_args)), + data_plane_combiner_(grpc_combiner_create()), + combiner_(grpc_combiner_create()), + interested_parties_(grpc_pollset_set_create()), + subchannel_pool_(GetSubchannelPool(args->channel_args)), + disconnect_error_(GRPC_ERROR_NONE) { + // Initialize data members. + grpc_connectivity_state_init(&state_tracker_, GRPC_CHANNEL_IDLE, + "client_channel"); + gpr_mu_init(&info_mu_); + // Start backup polling. + grpc_client_channel_start_backup_polling(interested_parties_); + // Check client channel factory. + if (client_channel_factory_ == nullptr) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Missing client channel factory in args for client channel filter"); + return; + } + // Get server name to resolve, using proxy mapper if needed. + const char* server_uri = grpc_channel_arg_get_string( + grpc_channel_args_find(args->channel_args, GRPC_ARG_SERVER_URI)); + if (server_uri == nullptr) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "server URI channel arg missing or wrong type in client channel " + "filter"); + return; + } + // Get default service config + const char* service_config_json = grpc_channel_arg_get_string( + grpc_channel_args_find(args->channel_args, GRPC_ARG_SERVICE_CONFIG)); + if (service_config_json != nullptr) { + *error = GRPC_ERROR_NONE; + default_service_config_ = ServiceConfig::Create(service_config_json, error); + if (*error != GRPC_ERROR_NONE) { + default_service_config_.reset(); + return; + } + } + grpc_uri* uri = grpc_uri_parse(server_uri, true); + if (uri != nullptr && uri->path[0] != '\0') { + server_name_.reset( + gpr_strdup(uri->path[0] == '/' ? uri->path + 1 : uri->path)); + } + grpc_uri_destroy(uri); + char* proxy_name = nullptr; + grpc_channel_args* new_args = nullptr; + grpc_proxy_mappers_map_name(server_uri, args->channel_args, &proxy_name, + &new_args); + UniquePtr target_uri(proxy_name != nullptr ? proxy_name + : gpr_strdup(server_uri)); + // Instantiate resolving LB policy. + LoadBalancingPolicy::Args lb_args; + lb_args.combiner = combiner_; + lb_args.channel_control_helper = + UniquePtr( + New(this)); + lb_args.args = new_args != nullptr ? new_args : args->channel_args; + resolving_lb_policy_.reset(New( + std::move(lb_args), &grpc_client_channel_routing_trace, + std::move(target_uri), ProcessResolverResultLocked, this, error)); + grpc_channel_args_destroy(new_args); + if (*error != GRPC_ERROR_NONE) { + // Orphan the resolving LB policy and flush the exec_ctx to ensure + // that it finishes shutting down. This ensures that if we are + // failing, we destroy the ClientChannelControlHelper (and thus + // unref the channel stack) before we return. + // TODO(roth): This is not a complete solution, because it only + // catches the case where channel stack initialization fails in this + // particular filter. If there is a failure in a different filter, we + // will leave a dangling ref here, which can cause a crash. Fortunately, + // in practice, there are no other filters that can cause failures in + // channel stack initialization, so this works for now. + resolving_lb_policy_.reset(); + ExecCtx::Get()->Flush(); + } else { + grpc_pollset_set_add_pollset_set(resolving_lb_policy_->interested_parties(), + interested_parties_); + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) { + gpr_log(GPR_INFO, "chand=%p: created resolving_lb_policy=%p", this, + resolving_lb_policy_.get()); + } + } +} + +ChannelData::~ChannelData() { + if (resolving_lb_policy_ != nullptr) { + grpc_pollset_set_del_pollset_set(resolving_lb_policy_->interested_parties(), + interested_parties_); + resolving_lb_policy_.reset(); + } + // Stop backup polling. + grpc_client_channel_stop_backup_polling(interested_parties_); + grpc_pollset_set_destroy(interested_parties_); + GRPC_COMBINER_UNREF(data_plane_combiner_, "client_channel"); + GRPC_COMBINER_UNREF(combiner_, "client_channel"); + GRPC_ERROR_UNREF(disconnect_error_.Load(MemoryOrder::RELAXED)); + grpc_connectivity_state_destroy(&state_tracker_); + gpr_mu_destroy(&info_mu_); +} + +void ChannelData::ProcessLbPolicy( + const Resolver::Result& resolver_result, + const internal::ClientChannelGlobalParsedObject* parsed_service_config, + UniquePtr* lb_policy_name, + RefCountedPtr* lb_policy_config) { + // Prefer the LB policy name found in the service config. + if (parsed_service_config != nullptr && + parsed_service_config->parsed_lb_config() != nullptr) { + lb_policy_name->reset( + gpr_strdup(parsed_service_config->parsed_lb_config()->name())); + *lb_policy_config = parsed_service_config->parsed_lb_config(); + return; + } + const char* local_policy_name = nullptr; + if (parsed_service_config != nullptr && + parsed_service_config->parsed_deprecated_lb_policy() != nullptr) { + local_policy_name = parsed_service_config->parsed_deprecated_lb_policy(); + } else { + const grpc_arg* channel_arg = + grpc_channel_args_find(resolver_result.args, GRPC_ARG_LB_POLICY_NAME); + local_policy_name = grpc_channel_arg_get_string(channel_arg); + } + // Special case: If at least one balancer address is present, we use + // the grpclb policy, regardless of what the resolver has returned. + bool found_balancer_address = false; + for (size_t i = 0; i < resolver_result.addresses.size(); ++i) { + const ServerAddress& address = resolver_result.addresses[i]; + if (address.IsBalancer()) { + found_balancer_address = true; + break; + } + } + if (found_balancer_address) { + if (local_policy_name != nullptr && + strcmp(local_policy_name, "grpclb") != 0) { + gpr_log(GPR_INFO, + "resolver requested LB policy %s but provided at least one " + "balancer address -- forcing use of grpclb LB policy", + local_policy_name); + } + local_policy_name = "grpclb"; + } + // Use pick_first if nothing was specified and we didn't select grpclb + // above. + lb_policy_name->reset(gpr_strdup( + local_policy_name == nullptr ? "pick_first" : local_policy_name)); +} + +// Synchronous callback from ResolvingLoadBalancingPolicy to process a +// resolver result update. +bool ChannelData::ProcessResolverResultLocked( + void* arg, Resolver::Result* result, const char** lb_policy_name, + RefCountedPtr* lb_policy_config, + grpc_error** service_config_error) { + ChannelData* chand = static_cast(arg); + RefCountedPtr service_config; + // If resolver did not return a service config or returned an invalid service + // config, we need a fallback service config. + if (result->service_config_error != GRPC_ERROR_NONE) { + // If the service config was invalid, then fallback to the saved service + // config. If there is no saved config either, use the default service + // config. + if (chand->saved_service_config_ != nullptr) { + service_config = chand->saved_service_config_; + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) { + gpr_log(GPR_INFO, + "chand=%p: resolver returned invalid service config. " + "Continuing to use previous service config.", + chand); + } + } else if (chand->default_service_config_ != nullptr) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) { + gpr_log(GPR_INFO, + "chand=%p: resolver returned invalid service config. Using " + "default service config provided by client API.", + chand); + } + service_config = chand->default_service_config_; + } + } else if (result->service_config == nullptr) { + if (chand->default_service_config_ != nullptr) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) { + gpr_log(GPR_INFO, + "chand=%p: resolver returned no service config. Using default " + "service config provided by client API.", + chand); + } + service_config = chand->default_service_config_; + } + } else { + service_config = result->service_config; + } + *service_config_error = GRPC_ERROR_REF(result->service_config_error); + if (service_config == nullptr && + result->service_config_error != GRPC_ERROR_NONE) { + return false; + } + // Process service config. + UniquePtr service_config_json; + const internal::ClientChannelGlobalParsedObject* parsed_service_config = + nullptr; + if (service_config != nullptr) { + parsed_service_config = + static_cast( + service_config->GetParsedGlobalServiceConfigObject( + internal::ClientChannelServiceConfigParser::ParserIndex())); + } + // TODO(roth): Eliminate this hack as part of hiding health check + // service name from LB policy API. As part of this, change the API + // for this function to pass in result as a const reference. + if (parsed_service_config != nullptr && + parsed_service_config->health_check_service_name() != nullptr) { + grpc_arg new_arg = grpc_channel_arg_string_create( + const_cast("grpc.temp.health_check"), + const_cast(parsed_service_config->health_check_service_name())); + grpc_channel_args* new_args = + grpc_channel_args_copy_and_add(result->args, &new_arg, 1); + grpc_channel_args_destroy(result->args); + result->args = new_args; + } + // Check if the config has changed. + const bool service_config_changed = + ((service_config == nullptr) != + (chand->saved_service_config_ == nullptr)) || + (service_config != nullptr && + strcmp(service_config->service_config_json(), + chand->saved_service_config_->service_config_json()) != 0); + if (service_config_changed) { + service_config_json.reset(gpr_strdup( + service_config != nullptr ? service_config->service_config_json() + : "")); + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) { + gpr_log(GPR_INFO, + "chand=%p: resolver returned updated service config: \"%s\"", + chand, service_config_json.get()); + } + chand->saved_service_config_ = std::move(service_config); + } + // We want to set the service config at least once. This should not really be + // needed, but we are doing it as a defensive approach. This can be removed, + // if we feel it is unnecessary. + if (service_config_changed || !chand->received_first_resolver_result_) { + chand->received_first_resolver_result_ = true; + Optional + retry_throttle_data; + if (parsed_service_config != nullptr) { + retry_throttle_data = parsed_service_config->retry_throttling(); + } + // Create service config setter to update channel state in the data + // plane combiner. Destroys itself when done. + New(chand, retry_throttle_data, + chand->saved_service_config_); + } + UniquePtr processed_lb_policy_name; + chand->ProcessLbPolicy(*result, parsed_service_config, + &processed_lb_policy_name, lb_policy_config); + // Swap out the data used by GetChannelInfo(). + { + MutexLock lock(&chand->info_mu_); + chand->info_lb_policy_name_ = std::move(processed_lb_policy_name); + if (service_config_json != nullptr) { + chand->info_service_config_json_ = std::move(service_config_json); + } + } + // Return results. + *lb_policy_name = chand->info_lb_policy_name_.get(); + return service_config_changed; +} + +grpc_error* ChannelData::DoPingLocked(grpc_transport_op* op) { + if (grpc_connectivity_state_check(&state_tracker_) != GRPC_CHANNEL_READY) { + return GRPC_ERROR_CREATE_FROM_STATIC_STRING("channel not connected"); + } + LoadBalancingPolicy::PickArgs pick; + grpc_error* error = GRPC_ERROR_NONE; + picker_->Pick(&pick, &error); + if (pick.connected_subchannel != nullptr) { + pick.connected_subchannel->Ping(op->send_ping.on_initiate, + op->send_ping.on_ack); + } else { + if (error == GRPC_ERROR_NONE) { + error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "LB policy dropped call on ping"); + } + } + return error; +} + +void ChannelData::StartTransportOpLocked(void* arg, grpc_error* ignored) { + grpc_transport_op* op = static_cast(arg); + grpc_channel_element* elem = + static_cast(op->handler_private.extra_arg); + ChannelData* chand = static_cast(elem->channel_data); + // Connectivity watch. + if (op->on_connectivity_state_change != nullptr) { + grpc_connectivity_state_notify_on_state_change( + &chand->state_tracker_, op->connectivity_state, + op->on_connectivity_state_change); + op->on_connectivity_state_change = nullptr; + op->connectivity_state = nullptr; + } + // Ping. + if (op->send_ping.on_initiate != nullptr || op->send_ping.on_ack != nullptr) { + grpc_error* error = chand->DoPingLocked(op); + if (error != GRPC_ERROR_NONE) { + GRPC_CLOSURE_SCHED(op->send_ping.on_initiate, GRPC_ERROR_REF(error)); + GRPC_CLOSURE_SCHED(op->send_ping.on_ack, error); + } + op->bind_pollset = nullptr; + op->send_ping.on_initiate = nullptr; + op->send_ping.on_ack = nullptr; + } + // Reset backoff. + if (op->reset_connect_backoff) { + if (chand->resolving_lb_policy_ != nullptr) { + chand->resolving_lb_policy_->ResetBackoffLocked(); + } + } + // Disconnect. + if (op->disconnect_with_error != GRPC_ERROR_NONE) { + grpc_error* error = GRPC_ERROR_NONE; + GPR_ASSERT(chand->disconnect_error_.CompareExchangeStrong( + &error, op->disconnect_with_error, MemoryOrder::ACQ_REL, + MemoryOrder::ACQUIRE)); + grpc_pollset_set_del_pollset_set( + chand->resolving_lb_policy_->interested_parties(), + chand->interested_parties_); + chand->resolving_lb_policy_.reset(); + // Will delete itself. + New( + chand, GRPC_CHANNEL_SHUTDOWN, "shutdown from API", + UniquePtr( + New( + GRPC_ERROR_REF(op->disconnect_with_error)))); + } + GRPC_CHANNEL_STACK_UNREF(chand->owning_stack_, "start_transport_op"); + GRPC_CLOSURE_SCHED(op->on_consumed, GRPC_ERROR_NONE); +} + +void ChannelData::StartTransportOp(grpc_channel_element* elem, + grpc_transport_op* op) { + ChannelData* chand = static_cast(elem->channel_data); + GPR_ASSERT(op->set_accept_stream == false); + // Handle bind_pollset. + if (op->bind_pollset != nullptr) { + grpc_pollset_set_add_pollset(chand->interested_parties_, op->bind_pollset); + } + // Pop into control plane combiner for remaining ops. + op->handler_private.extra_arg = elem; + GRPC_CHANNEL_STACK_REF(chand->owning_stack_, "start_transport_op"); + GRPC_CLOSURE_SCHED( + GRPC_CLOSURE_INIT(&op->handler_private.closure, + ChannelData::StartTransportOpLocked, op, + grpc_combiner_scheduler(chand->combiner_)), + GRPC_ERROR_NONE); +} + +void ChannelData::GetChannelInfo(grpc_channel_element* elem, + const grpc_channel_info* info) { + ChannelData* chand = static_cast(elem->channel_data); + MutexLock lock(&chand->info_mu_); + if (info->lb_policy_name != nullptr) { + *info->lb_policy_name = gpr_strdup(chand->info_lb_policy_name_.get()); + } + if (info->service_config_json != nullptr) { + *info->service_config_json = + gpr_strdup(chand->info_service_config_json_.get()); + } +} + +void ChannelData::AddQueuedPick(QueuedPick* pick, + grpc_polling_entity* pollent) { + // Add call to queued picks list. + pick->next = queued_picks_; + queued_picks_ = pick; + // Add call's pollent to channel's interested_parties, so that I/O + // can be done under the call's CQ. + grpc_polling_entity_add_to_pollset_set(pollent, interested_parties_); +} + +void ChannelData::RemoveQueuedPick(QueuedPick* to_remove, + grpc_polling_entity* pollent) { + // Remove call's pollent from channel's interested_parties. + grpc_polling_entity_del_from_pollset_set(pollent, interested_parties_); + // Remove from queued picks list. + for (QueuedPick** pick = &queued_picks_; *pick != nullptr; + pick = &(*pick)->next) { + if (*pick == to_remove) { + *pick = to_remove->next; + return; + } + } +} + +void ChannelData::TryToConnectLocked(void* arg, grpc_error* error_ignored) { + auto* chand = static_cast(arg); + if (chand->resolving_lb_policy_ != nullptr) { + chand->resolving_lb_policy_->ExitIdleLocked(); + } + GRPC_CHANNEL_STACK_UNREF(chand->owning_stack_, "TryToConnect"); +} + +grpc_connectivity_state ChannelData::CheckConnectivityState( + bool try_to_connect) { + grpc_connectivity_state out = grpc_connectivity_state_check(&state_tracker_); + if (out == GRPC_CHANNEL_IDLE && try_to_connect) { + GRPC_CHANNEL_STACK_REF(owning_stack_, "TryToConnect"); + GRPC_CLOSURE_SCHED(GRPC_CLOSURE_CREATE(TryToConnectLocked, this, + grpc_combiner_scheduler(combiner_)), + GRPC_ERROR_NONE); + } + return out; +} + +// +// CallData implementation +// + // Retry support: // // In order to support retries, we act as a proxy for stream op batches. @@ -819,361 +1492,263 @@ static void cc_destroy_channel_elem(grpc_channel_element* elem) { // (census filter is on top of this one) // - add census stats for retries -namespace { -struct call_data; +CallData::CallData(grpc_call_element* elem, const ChannelData& chand, + const grpc_call_element_args& args) + : deadline_state_(elem, args.call_stack, args.call_combiner, + GPR_LIKELY(chand.deadline_checking_enabled()) + ? args.deadline + : GRPC_MILLIS_INF_FUTURE), + path_(grpc_slice_ref_internal(args.path)), + call_start_time_(args.start_time), + deadline_(args.deadline), + arena_(args.arena), + owning_call_(args.call_stack), + call_combiner_(args.call_combiner), + call_context_(args.context), + pending_send_initial_metadata_(false), + pending_send_message_(false), + pending_send_trailing_metadata_(false), + enable_retries_(chand.enable_retries()), + retry_committed_(false), + last_attempt_got_server_pushback_(false) {} -// State used for starting a retryable batch on a subchannel call. -// This provides its own grpc_transport_stream_op_batch and other data -// structures needed to populate the ops in the batch. -// We allocate one struct on the arena for each attempt at starting a -// batch on a given subchannel call. -struct subchannel_batch_data { - subchannel_batch_data(grpc_call_element* elem, call_data* calld, int refcount, - bool set_on_complete); - // All dtor code must be added in `destroy`. This is because we may - // call closures in `subchannel_batch_data` after they are unrefed by - // `batch_data_unref`, and msan would complain about accessing this class - // after calling dtor. As a result we cannot call the `dtor` in - // `batch_data_unref`. - // TODO(soheil): We should try to call the dtor in `batch_data_unref`. - ~subchannel_batch_data() { destroy(); } - void destroy(); - - gpr_refcount refs; - grpc_call_element* elem; - grpc_subchannel_call* subchannel_call; // Holds a ref. - // The batch to use in the subchannel call. - // Its payload field points to subchannel_call_retry_state.batch_payload. - grpc_transport_stream_op_batch batch; - // For intercepting on_complete. - grpc_closure on_complete; -}; - -// Retry state associated with a subchannel call. -// Stored in the parent_data of the subchannel call object. -struct subchannel_call_retry_state { - explicit subchannel_call_retry_state(grpc_call_context_element* context) - : batch_payload(context), - started_send_initial_metadata(false), - completed_send_initial_metadata(false), - started_send_trailing_metadata(false), - completed_send_trailing_metadata(false), - started_recv_initial_metadata(false), - completed_recv_initial_metadata(false), - started_recv_trailing_metadata(false), - completed_recv_trailing_metadata(false), - retry_dispatched(false) {} - - // subchannel_batch_data.batch.payload points to this. - grpc_transport_stream_op_batch_payload batch_payload; - // For send_initial_metadata. - // Note that we need to make a copy of the initial metadata for each - // subchannel call instead of just referring to the copy in call_data, - // because filters in the subchannel stack will probably add entries, - // so we need to start in a pristine state for each attempt of the call. - grpc_linked_mdelem* send_initial_metadata_storage; - grpc_metadata_batch send_initial_metadata; - // For send_message. - grpc_core::ManualConstructor - send_message; - // For send_trailing_metadata. - grpc_linked_mdelem* send_trailing_metadata_storage; - grpc_metadata_batch send_trailing_metadata; - // For intercepting recv_initial_metadata. - grpc_metadata_batch recv_initial_metadata; - grpc_closure recv_initial_metadata_ready; - bool trailing_metadata_available = false; - // For intercepting recv_message. - grpc_closure recv_message_ready; - grpc_core::OrphanablePtr recv_message; - // For intercepting recv_trailing_metadata. - grpc_metadata_batch recv_trailing_metadata; - grpc_transport_stream_stats collect_stats; - grpc_closure recv_trailing_metadata_ready; - // These fields indicate which ops have been started and completed on - // this subchannel call. - size_t started_send_message_count = 0; - size_t completed_send_message_count = 0; - size_t started_recv_message_count = 0; - size_t completed_recv_message_count = 0; - bool started_send_initial_metadata : 1; - bool completed_send_initial_metadata : 1; - bool started_send_trailing_metadata : 1; - bool completed_send_trailing_metadata : 1; - bool started_recv_initial_metadata : 1; - bool completed_recv_initial_metadata : 1; - bool started_recv_trailing_metadata : 1; - bool completed_recv_trailing_metadata : 1; - subchannel_batch_data* recv_initial_metadata_ready_deferred_batch = nullptr; - grpc_error* recv_initial_metadata_error = GRPC_ERROR_NONE; - subchannel_batch_data* recv_message_ready_deferred_batch = nullptr; - grpc_error* recv_message_error = GRPC_ERROR_NONE; - subchannel_batch_data* recv_trailing_metadata_internal_batch = nullptr; - // State for callback processing. - // NOTE: Do not move this next to the metadata bitfields above. That would - // save space but will also result in a data race because compiler will - // generate a 2 byte store which overwrites the meta-data fields upon - // setting this field. - bool retry_dispatched : 1; -}; - -// Pending batches stored in call data. -typedef struct { - // The pending batch. If nullptr, this slot is empty. - grpc_transport_stream_op_batch* batch; - // Indicates whether payload for send ops has been cached in call data. - bool send_ops_cached; -} pending_batch; - -/** Call data. Holds a pointer to grpc_subchannel_call and the - associated machinery to create such a pointer. - Handles queueing of stream ops until a call object is ready, waiting - for initial metadata before trying to create a call object, - and handling cancellation gracefully. */ -struct call_data { - call_data(grpc_call_element* elem, const channel_data& chand, - const grpc_call_element_args& args) - : deadline_state(elem, args.call_stack, args.call_combiner, - GPR_LIKELY(chand.deadline_checking_enabled) - ? args.deadline - : GRPC_MILLIS_INF_FUTURE), - path(grpc_slice_ref_internal(args.path)), - call_start_time(args.start_time), - deadline(args.deadline), - arena(args.arena), - owning_call(args.call_stack), - call_combiner(args.call_combiner), - pending_send_initial_metadata(false), - pending_send_message(false), - pending_send_trailing_metadata(false), - enable_retries(chand.enable_retries), - retry_committed(false), - last_attempt_got_server_pushback(false) {} - - ~call_data() { - if (GPR_LIKELY(subchannel_call != nullptr)) { - GRPC_SUBCHANNEL_CALL_UNREF(subchannel_call, - "client_channel_destroy_call"); - } - grpc_slice_unref_internal(path); - GRPC_ERROR_UNREF(cancel_error); - for (size_t i = 0; i < GPR_ARRAY_SIZE(pending_batches); ++i) { - GPR_ASSERT(pending_batches[i].batch == nullptr); - } - for (size_t i = 0; i < GRPC_CONTEXT_COUNT; ++i) { - if (pick.subchannel_call_context[i].value != nullptr) { - pick.subchannel_call_context[i].destroy( - pick.subchannel_call_context[i].value); - } - } +CallData::~CallData() { + grpc_slice_unref_internal(path_); + GRPC_ERROR_UNREF(cancel_error_); + // Make sure there are no remaining pending batches. + for (size_t i = 0; i < GPR_ARRAY_SIZE(pending_batches_); ++i) { + GPR_ASSERT(pending_batches_[i].batch == nullptr); } +} - // State for handling deadlines. - // The code in deadline_filter.c requires this to be the first field. - // TODO(roth): This is slightly sub-optimal in that grpc_deadline_state - // and this struct both independently store pointers to the call stack - // and call combiner. If/when we have time, find a way to avoid this - // without breaking the grpc_deadline_state abstraction. - grpc_deadline_state deadline_state; +grpc_error* CallData::Init(grpc_call_element* elem, + const grpc_call_element_args* args) { + ChannelData* chand = static_cast(elem->channel_data); + new (elem->call_data) CallData(elem, *chand, *args); + return GRPC_ERROR_NONE; +} - grpc_slice path; // Request path. - gpr_timespec call_start_time; - grpc_millis deadline; - gpr_arena* arena; - grpc_call_stack* owning_call; - grpc_call_combiner* call_combiner; +void CallData::Destroy(grpc_call_element* elem, + const grpc_call_final_info* final_info, + grpc_closure* then_schedule_closure) { + CallData* calld = static_cast(elem->call_data); + if (GPR_LIKELY(calld->subchannel_call_ != nullptr)) { + calld->subchannel_call_->SetAfterCallStackDestroy(then_schedule_closure); + then_schedule_closure = nullptr; + } + calld->~CallData(); + GRPC_CLOSURE_SCHED(then_schedule_closure, GRPC_ERROR_NONE); +} - grpc_core::RefCountedPtr retry_throttle_data; - grpc_core::RefCountedPtr method_params; +void CallData::StartTransportStreamOpBatch( + grpc_call_element* elem, grpc_transport_stream_op_batch* batch) { + GPR_TIMER_SCOPE("cc_start_transport_stream_op_batch", 0); + CallData* calld = static_cast(elem->call_data); + ChannelData* chand = static_cast(elem->channel_data); + if (GPR_LIKELY(chand->deadline_checking_enabled())) { + grpc_deadline_state_client_start_transport_stream_op_batch(elem, batch); + } + // If we've previously been cancelled, immediately fail any new batches. + if (GPR_UNLIKELY(calld->cancel_error_ != GRPC_ERROR_NONE)) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) { + 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. + grpc_transport_stream_op_batch_finish_with_failure( + batch, GRPC_ERROR_REF(calld->cancel_error_), calld->call_combiner_); + return; + } + // Handle cancellation. + if (GPR_UNLIKELY(batch->cancel_stream)) { + // Stash a copy of cancel_error in our call data, so that we can use + // it for subsequent operations. This ensures that if the call is + // cancelled before any batches are passed down (e.g., if the deadline + // is in the past when the call starts), we can return the right + // error to the caller when the first batch does get passed down. + GRPC_ERROR_UNREF(calld->cancel_error_); + calld->cancel_error_ = + GRPC_ERROR_REF(batch->payload->cancel_stream.cancel_error); + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) { + 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 + // been started), fail all pending batches. Otherwise, send the + // cancellation down to the subchannel call. + if (calld->subchannel_call_ == nullptr) { + // TODO(roth): If there is a pending retry callback, do we need to + // cancel it here? + calld->PendingBatchesFail(elem, GRPC_ERROR_REF(calld->cancel_error_), + NoYieldCallCombiner); + // Note: This will release the call combiner. + grpc_transport_stream_op_batch_finish_with_failure( + batch, GRPC_ERROR_REF(calld->cancel_error_), calld->call_combiner_); + } else { + // Note: This will release the call combiner. + calld->subchannel_call_->StartTransportStreamOpBatch(batch); + } + return; + } + // Add the batch to the pending list. + calld->PendingBatchesAdd(elem, batch); + // Check if we've already gotten a subchannel call. + // Note that once we have completed the pick, we do not need to enter + // the channel combiner, which is more efficient (especially for + // streaming calls). + if (calld->subchannel_call_ != nullptr) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) { + gpr_log(GPR_INFO, + "chand=%p calld=%p: starting batch on subchannel_call=%p", chand, + calld, calld->subchannel_call_.get()); + } + calld->PendingBatchesResume(elem); + return; + } + // We do not yet have a subchannel call. + // For batches containing a send_initial_metadata op, enter the channel + // combiner to start a pick. + if (GPR_LIKELY(batch->send_initial_metadata)) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) { + gpr_log(GPR_INFO, "chand=%p calld=%p: entering client_channel combiner", + chand, calld); + } + GRPC_CLOSURE_SCHED( + GRPC_CLOSURE_INIT( + &batch->handler_private.closure, StartPickLocked, elem, + grpc_combiner_scheduler(chand->data_plane_combiner())), + GRPC_ERROR_NONE); + } else { + // For all other batches, release the call combiner. + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) { + gpr_log(GPR_INFO, + "chand=%p calld=%p: saved batch, yielding call combiner", chand, + calld); + } + GRPC_CALL_COMBINER_STOP(calld->call_combiner_, + "batch does not include send_initial_metadata"); + } +} - grpc_subchannel_call* subchannel_call = nullptr; - - // Set when we get a cancel_stream op. - grpc_error* cancel_error = GRPC_ERROR_NONE; - - grpc_core::LoadBalancingPolicy::PickState pick; - grpc_closure pick_closure; - grpc_closure pick_cancel_closure; - - grpc_polling_entity* pollent = nullptr; - bool pollent_added_to_interested_parties = false; - - // Batches are added to this list when received from above. - // They are removed when we are done handling the batch (i.e., when - // either we have invoked all of the batch's callbacks or we have - // passed the batch down to the subchannel call and are not - // intercepting any of its callbacks). - pending_batch pending_batches[MAX_PENDING_BATCHES] = {}; - bool pending_send_initial_metadata : 1; - bool pending_send_message : 1; - bool pending_send_trailing_metadata : 1; - - // Retry state. - bool enable_retries : 1; - bool retry_committed : 1; - bool last_attempt_got_server_pushback : 1; - int num_attempts_completed = 0; - size_t bytes_buffered_for_retry = 0; - grpc_core::ManualConstructor retry_backoff; - grpc_timer retry_timer; - - // The number of pending retriable subchannel batches containing send ops. - // We hold a ref to the call stack while this is non-zero, since replay - // batches may not complete until after all callbacks have been returned - // to the surface, and we need to make sure that the call is not destroyed - // until all of these batches have completed. - // Note that we actually only need to track replay batches, but it's - // easier to track all batches with send ops. - int num_pending_retriable_subchannel_send_batches = 0; - - // Cached data for retrying send ops. - // send_initial_metadata - bool seen_send_initial_metadata = false; - grpc_linked_mdelem* send_initial_metadata_storage = nullptr; - grpc_metadata_batch send_initial_metadata; - uint32_t send_initial_metadata_flags; - gpr_atm* peer_string; - // send_message - // When we get a send_message op, we replace the original byte stream - // with a CachingByteStream that caches the slices to a local buffer for - // use in retries. - // 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 send_messages; - // send_trailing_metadata - bool seen_send_trailing_metadata = false; - grpc_linked_mdelem* send_trailing_metadata_storage = nullptr; - grpc_metadata_batch send_trailing_metadata; -}; -} // namespace - -// Forward declarations. -static void retry_commit(grpc_call_element* elem, - subchannel_call_retry_state* retry_state); -static void start_internal_recv_trailing_metadata(grpc_call_element* elem); -static void on_complete(void* arg, grpc_error* error); -static void start_retriable_subchannel_batches(void* arg, grpc_error* ignored); -static void start_pick_locked(void* arg, grpc_error* ignored); +void CallData::SetPollent(grpc_call_element* elem, + grpc_polling_entity* pollent) { + CallData* calld = static_cast(elem->call_data); + calld->pollent_ = pollent; +} // // send op data caching // -// Caches data for send ops so that it can be retried later, if not -// already cached. -static void maybe_cache_send_ops_for_batch(call_data* calld, - pending_batch* pending) { +void CallData::MaybeCacheSendOpsForBatch(PendingBatch* pending) { if (pending->send_ops_cached) return; pending->send_ops_cached = true; grpc_transport_stream_op_batch* batch = pending->batch; // Save a copy of metadata for send_initial_metadata ops. if (batch->send_initial_metadata) { - calld->seen_send_initial_metadata = true; - GPR_ASSERT(calld->send_initial_metadata_storage == nullptr); + seen_send_initial_metadata_ = true; + GPR_ASSERT(send_initial_metadata_storage_ == nullptr); grpc_metadata_batch* send_initial_metadata = batch->payload->send_initial_metadata.send_initial_metadata; - calld->send_initial_metadata_storage = (grpc_linked_mdelem*)gpr_arena_alloc( - calld->arena, + send_initial_metadata_storage_ = (grpc_linked_mdelem*)arena_->Alloc( sizeof(grpc_linked_mdelem) * send_initial_metadata->list.count); - grpc_metadata_batch_copy(send_initial_metadata, - &calld->send_initial_metadata, - calld->send_initial_metadata_storage); - calld->send_initial_metadata_flags = + grpc_metadata_batch_copy(send_initial_metadata, &send_initial_metadata_, + send_initial_metadata_storage_); + send_initial_metadata_flags_ = batch->payload->send_initial_metadata.send_initial_metadata_flags; - calld->peer_string = batch->payload->send_initial_metadata.peer_string; + peer_string_ = batch->payload->send_initial_metadata.peer_string; } // Set up cache for send_message ops. if (batch->send_message) { - grpc_core::ByteStreamCache* cache = - static_cast( - gpr_arena_alloc(calld->arena, sizeof(grpc_core::ByteStreamCache))); - new (cache) grpc_core::ByteStreamCache( + ByteStreamCache* cache = arena_->New( std::move(batch->payload->send_message.send_message)); - calld->send_messages.push_back(cache); + send_messages_.push_back(cache); } // Save metadata batch for send_trailing_metadata ops. if (batch->send_trailing_metadata) { - calld->seen_send_trailing_metadata = true; - GPR_ASSERT(calld->send_trailing_metadata_storage == nullptr); + seen_send_trailing_metadata_ = true; + GPR_ASSERT(send_trailing_metadata_storage_ == nullptr); grpc_metadata_batch* send_trailing_metadata = batch->payload->send_trailing_metadata.send_trailing_metadata; - calld->send_trailing_metadata_storage = - (grpc_linked_mdelem*)gpr_arena_alloc( - calld->arena, - sizeof(grpc_linked_mdelem) * send_trailing_metadata->list.count); - grpc_metadata_batch_copy(send_trailing_metadata, - &calld->send_trailing_metadata, - calld->send_trailing_metadata_storage); + send_trailing_metadata_storage_ = (grpc_linked_mdelem*)arena_->Alloc( + sizeof(grpc_linked_mdelem) * send_trailing_metadata->list.count); + grpc_metadata_batch_copy(send_trailing_metadata, &send_trailing_metadata_, + send_trailing_metadata_storage_); } } -// Frees cached send_initial_metadata. -static void free_cached_send_initial_metadata(channel_data* chand, - call_data* calld) { - if (grpc_client_channel_trace.enabled()) { +void CallData::FreeCachedSendInitialMetadata(ChannelData* chand) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) { gpr_log(GPR_INFO, "chand=%p calld=%p: destroying calld->send_initial_metadata", chand, - calld); + this); } - grpc_metadata_batch_destroy(&calld->send_initial_metadata); + grpc_metadata_batch_destroy(&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()) { +void CallData::FreeCachedSendMessage(ChannelData* chand, size_t idx) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) { gpr_log(GPR_INFO, "chand=%p calld=%p: destroying calld->send_messages[%" PRIuPTR "]", - chand, calld, idx); + chand, this, idx); } - calld->send_messages[idx]->Destroy(); + 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()) { +void CallData::FreeCachedSendTrailingMetadata(ChannelData* chand) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) { gpr_log(GPR_INFO, "chand=%p calld=%p: destroying calld->send_trailing_metadata", - chand, calld); + chand, this); } - grpc_metadata_batch_destroy(&calld->send_trailing_metadata); + grpc_metadata_batch_destroy(&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( - grpc_call_element* elem, subchannel_call_retry_state* retry_state) { - channel_data* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); +void CallData::FreeCachedSendOpDataAfterCommit( + grpc_call_element* elem, SubchannelCallRetryState* retry_state) { + ChannelData* chand = static_cast(elem->channel_data); if (retry_state->completed_send_initial_metadata) { - free_cached_send_initial_metadata(chand, calld); + FreeCachedSendInitialMetadata(chand); } for (size_t i = 0; i < retry_state->completed_send_message_count; ++i) { - free_cached_send_message(chand, calld, i); + FreeCachedSendMessage(chand, i); } if (retry_state->completed_send_trailing_metadata) { - free_cached_send_trailing_metadata(chand, calld); + FreeCachedSendTrailingMetadata(chand); } } -// Frees cached send ops that were completed by the completed batch in -// batch_data. Used when batches are completed after the call is committed. -static void free_cached_send_op_data_for_completed_batch( - grpc_call_element* elem, subchannel_batch_data* batch_data, - subchannel_call_retry_state* retry_state) { - channel_data* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); +void CallData::FreeCachedSendOpDataForCompletedBatch( + grpc_call_element* elem, SubchannelCallBatchData* batch_data, + SubchannelCallRetryState* retry_state) { + ChannelData* chand = static_cast(elem->channel_data); if (batch_data->batch.send_initial_metadata) { - free_cached_send_initial_metadata(chand, calld); + FreeCachedSendInitialMetadata(chand); } if (batch_data->batch.send_message) { - free_cached_send_message(chand, calld, - retry_state->completed_send_message_count - 1); + FreeCachedSendMessage(chand, retry_state->completed_send_message_count - 1); } if (batch_data->batch.send_trailing_metadata) { - free_cached_send_trailing_metadata(chand, calld); + FreeCachedSendTrailingMetadata(chand); + } +} + +// +// LB recv_trailing_metadata_ready handling +// + +void CallData::MaybeInjectRecvTrailingMetadataReadyForLoadBalancingPolicy( + const LoadBalancingPolicy::PickArgs& pick, + grpc_transport_stream_op_batch* batch) { + if (pick.recv_trailing_metadata_ready != nullptr) { + *pick.original_recv_trailing_metadata_ready = + batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready; + batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready = + pick.recv_trailing_metadata_ready; + if (pick.recv_trailing_metadata != nullptr) { + *pick.recv_trailing_metadata = + batch->payload->recv_trailing_metadata.recv_trailing_metadata; + } } } @@ -1181,8 +1756,7 @@ static void free_cached_send_op_data_for_completed_batch( // pending_batches management // -// Returns the index into calld->pending_batches to be used for batch. -static size_t get_batch_index(grpc_transport_stream_op_batch* batch) { +size_t CallData::GetBatchIndex(grpc_transport_stream_op_batch* batch) { // Note: It is important the send_initial_metadata be the first entry // here, since the code in pick_subchannel_locked() assumes it will be. if (batch->send_initial_metadata) return 0; @@ -1195,181 +1769,81 @@ static size_t get_batch_index(grpc_transport_stream_op_batch* batch) { } // This is called via the call combiner, so access to calld is synchronized. -static void pending_batches_add(grpc_call_element* elem, - grpc_transport_stream_op_batch* batch) { - channel_data* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); - const size_t idx = get_batch_index(batch); - if (grpc_client_channel_trace.enabled()) { +void CallData::PendingBatchesAdd(grpc_call_element* elem, + grpc_transport_stream_op_batch* batch) { + ChannelData* chand = static_cast(elem->channel_data); + const size_t idx = GetBatchIndex(batch); + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) { gpr_log(GPR_INFO, "chand=%p calld=%p: adding pending batch at index %" PRIuPTR, chand, - calld, idx); + this, idx); } - pending_batch* pending = &calld->pending_batches[idx]; + PendingBatch* pending = &pending_batches_[idx]; GPR_ASSERT(pending->batch == nullptr); pending->batch = batch; pending->send_ops_cached = false; - if (calld->enable_retries) { + if (enable_retries_) { // Update state in calld about pending batches. // Also check if the batch takes us over the retry buffer limit. // Note: We don't check the size of trailing metadata here, because // gRPC clients do not send trailing metadata. if (batch->send_initial_metadata) { - calld->pending_send_initial_metadata = true; - calld->bytes_buffered_for_retry += grpc_metadata_batch_size( + pending_send_initial_metadata_ = true; + bytes_buffered_for_retry_ += grpc_metadata_batch_size( batch->payload->send_initial_metadata.send_initial_metadata); } if (batch->send_message) { - calld->pending_send_message = true; - calld->bytes_buffered_for_retry += + pending_send_message_ = true; + bytes_buffered_for_retry_ += batch->payload->send_message.send_message->length(); } if (batch->send_trailing_metadata) { - calld->pending_send_trailing_metadata = true; + pending_send_trailing_metadata_ = true; } - if (GPR_UNLIKELY(calld->bytes_buffered_for_retry > - chand->per_rpc_retry_buffer_size)) { - if (grpc_client_channel_trace.enabled()) { + if (GPR_UNLIKELY(bytes_buffered_for_retry_ > + chand->per_rpc_retry_buffer_size())) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) { gpr_log(GPR_INFO, "chand=%p calld=%p: exceeded retry buffer size, committing", - chand, calld); + chand, this); } - subchannel_call_retry_state* retry_state = - calld->subchannel_call == nullptr - ? nullptr - : static_cast( - grpc_connected_subchannel_call_get_parent_data( - calld->subchannel_call)); - retry_commit(elem, retry_state); + SubchannelCallRetryState* retry_state = + subchannel_call_ == nullptr ? nullptr + : static_cast( + subchannel_call_->GetParentData()); + RetryCommit(elem, retry_state); // If we are not going to retry and have not yet started, pretend // retries are disabled so that we don't bother with retry overhead. - if (calld->num_attempts_completed == 0) { - if (grpc_client_channel_trace.enabled()) { + if (num_attempts_completed_ == 0) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) { gpr_log(GPR_INFO, "chand=%p calld=%p: disabling retries before first attempt", - chand, calld); + chand, this); } - calld->enable_retries = false; + enable_retries_ = false; } } } } -static void pending_batch_clear(call_data* calld, pending_batch* pending) { - if (calld->enable_retries) { +void CallData::PendingBatchClear(PendingBatch* pending) { + if (enable_retries_) { if (pending->batch->send_initial_metadata) { - calld->pending_send_initial_metadata = false; + pending_send_initial_metadata_ = false; } if (pending->batch->send_message) { - calld->pending_send_message = false; + pending_send_message_ = false; } if (pending->batch->send_trailing_metadata) { - calld->pending_send_trailing_metadata = false; + pending_send_trailing_metadata_ = false; } } pending->batch = nullptr; } -// This is called via the call combiner, so access to calld is synchronized. -static void fail_pending_batch_in_call_combiner(void* arg, grpc_error* error) { - grpc_transport_stream_op_batch* batch = - static_cast(arg); - call_data* calld = static_cast(batch->handler_private.extra_arg); - // Note: This will release the call combiner. - grpc_transport_stream_op_batch_finish_with_failure( - batch, GRPC_ERROR_REF(error), calld->call_combiner); -} - -// This is called via the call combiner, so access to calld is synchronized. -// If yield_call_combiner is true, assumes responsibility for yielding -// the call combiner. -static void pending_batches_fail(grpc_call_element* elem, grpc_error* error, - bool yield_call_combiner) { - GPR_ASSERT(error != GRPC_ERROR_NONE); - call_data* calld = static_cast(elem->call_data); - if (grpc_client_channel_trace.enabled()) { - size_t num_batches = 0; - 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_INFO, - "chand=%p calld=%p: failing %" PRIuPTR " pending batches: %s", - elem->channel_data, calld, num_batches, grpc_error_string(error)); - } - grpc_core::CallCombinerClosureList closures; - for (size_t i = 0; i < GPR_ARRAY_SIZE(calld->pending_batches); ++i) { - pending_batch* pending = &calld->pending_batches[i]; - grpc_transport_stream_op_batch* batch = pending->batch; - if (batch != nullptr) { - batch->handler_private.extra_arg = calld; - GRPC_CLOSURE_INIT(&batch->handler_private.closure, - fail_pending_batch_in_call_combiner, batch, - grpc_schedule_on_exec_ctx); - closures.Add(&batch->handler_private.closure, GRPC_ERROR_REF(error), - "pending_batches_fail"); - pending_batch_clear(calld, pending); - } - } - if (yield_call_combiner) { - closures.RunClosures(calld->call_combiner); - } else { - closures.RunClosuresWithoutYielding(calld->call_combiner); - } - GRPC_ERROR_UNREF(error); -} - -// This is called via the call combiner, so access to calld is synchronized. -static void resume_pending_batch_in_call_combiner(void* arg, - grpc_error* ignored) { - grpc_transport_stream_op_batch* batch = - static_cast(arg); - grpc_subchannel_call* subchannel_call = - static_cast(batch->handler_private.extra_arg); - // Note: This will release the call combiner. - grpc_subchannel_call_process_op(subchannel_call, batch); -} - -// This is called via the call combiner, so access to calld is synchronized. -static void pending_batches_resume(grpc_call_element* elem) { - channel_data* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); - if (calld->enable_retries) { - start_retriable_subchannel_batches(elem, GRPC_ERROR_NONE); - return; - } - // Retries not enabled; send down batches as-is. - if (grpc_client_channel_trace.enabled()) { - size_t num_batches = 0; - 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_INFO, - "chand=%p calld=%p: starting %" PRIuPTR - " pending batches on subchannel_call=%p", - chand, calld, num_batches, calld->subchannel_call); - } - grpc_core::CallCombinerClosureList closures; - for (size_t i = 0; i < GPR_ARRAY_SIZE(calld->pending_batches); ++i) { - pending_batch* pending = &calld->pending_batches[i]; - grpc_transport_stream_op_batch* batch = pending->batch; - if (batch != nullptr) { - batch->handler_private.extra_arg = calld->subchannel_call; - GRPC_CLOSURE_INIT(&batch->handler_private.closure, - resume_pending_batch_in_call_combiner, batch, - grpc_schedule_on_exec_ctx); - closures.Add(&batch->handler_private.closure, GRPC_ERROR_NONE, - "pending_batches_resume"); - pending_batch_clear(calld, pending); - } - } - // Note: This will release the call combiner. - closures.RunClosures(calld->call_combiner); -} - -static void maybe_clear_pending_batch(grpc_call_element* elem, - pending_batch* pending) { - channel_data* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); +void CallData::MaybeClearPendingBatch(grpc_call_element* elem, + PendingBatch* pending) { + ChannelData* chand = static_cast(elem->channel_data); grpc_transport_stream_op_batch* batch = pending->batch; // We clear the pending batch if all of its callbacks have been // scheduled and reset to nullptr. @@ -1382,30 +1856,128 @@ static void maybe_clear_pending_batch(grpc_call_element* elem, (!batch->recv_trailing_metadata || batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready == nullptr)) { - if (grpc_client_channel_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) { gpr_log(GPR_INFO, "chand=%p calld=%p: clearing pending batch", chand, - calld); + this); } - pending_batch_clear(calld, pending); + PendingBatchClear(pending); } } -// Returns a pointer to the first pending batch for which predicate(batch) -// returns true, or null if not found. +// This is called via the call combiner, so access to calld is synchronized. +void CallData::FailPendingBatchInCallCombiner(void* arg, grpc_error* error) { + grpc_transport_stream_op_batch* batch = + static_cast(arg); + CallData* calld = static_cast(batch->handler_private.extra_arg); + // Note: This will release the call combiner. + grpc_transport_stream_op_batch_finish_with_failure( + batch, GRPC_ERROR_REF(error), calld->call_combiner_); +} + +// This is called via the call combiner, so access to calld is synchronized. +void CallData::PendingBatchesFail( + grpc_call_element* elem, grpc_error* error, + YieldCallCombinerPredicate yield_call_combiner_predicate) { + GPR_ASSERT(error != GRPC_ERROR_NONE); + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) { + size_t num_batches = 0; + for (size_t i = 0; i < GPR_ARRAY_SIZE(pending_batches_); ++i) { + if (pending_batches_[i].batch != nullptr) ++num_batches; + } + gpr_log(GPR_INFO, + "chand=%p calld=%p: failing %" PRIuPTR " pending batches: %s", + elem->channel_data, this, num_batches, grpc_error_string(error)); + } + CallCombinerClosureList closures; + for (size_t i = 0; i < GPR_ARRAY_SIZE(pending_batches_); ++i) { + PendingBatch* pending = &pending_batches_[i]; + grpc_transport_stream_op_batch* batch = pending->batch; + if (batch != nullptr) { + if (batch->recv_trailing_metadata) { + MaybeInjectRecvTrailingMetadataReadyForLoadBalancingPolicy(pick_.pick, + batch); + } + batch->handler_private.extra_arg = this; + GRPC_CLOSURE_INIT(&batch->handler_private.closure, + FailPendingBatchInCallCombiner, batch, + grpc_schedule_on_exec_ctx); + closures.Add(&batch->handler_private.closure, GRPC_ERROR_REF(error), + "PendingBatchesFail"); + PendingBatchClear(pending); + } + } + if (yield_call_combiner_predicate(closures)) { + closures.RunClosures(call_combiner_); + } else { + closures.RunClosuresWithoutYielding(call_combiner_); + } + GRPC_ERROR_UNREF(error); +} + +// This is called via the call combiner, so access to calld is synchronized. +void CallData::ResumePendingBatchInCallCombiner(void* arg, + grpc_error* ignored) { + grpc_transport_stream_op_batch* batch = + static_cast(arg); + SubchannelCall* subchannel_call = + static_cast(batch->handler_private.extra_arg); + // Note: This will release the call combiner. + subchannel_call->StartTransportStreamOpBatch(batch); +} + +// This is called via the call combiner, so access to calld is synchronized. +void CallData::PendingBatchesResume(grpc_call_element* elem) { + ChannelData* chand = static_cast(elem->channel_data); + if (enable_retries_) { + StartRetriableSubchannelBatches(elem, GRPC_ERROR_NONE); + return; + } + // Retries not enabled; send down batches as-is. + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) { + size_t num_batches = 0; + for (size_t i = 0; i < GPR_ARRAY_SIZE(pending_batches_); ++i) { + if (pending_batches_[i].batch != nullptr) ++num_batches; + } + gpr_log(GPR_INFO, + "chand=%p calld=%p: starting %" PRIuPTR + " pending batches on subchannel_call=%p", + chand, this, num_batches, subchannel_call_.get()); + } + CallCombinerClosureList closures; + for (size_t i = 0; i < GPR_ARRAY_SIZE(pending_batches_); ++i) { + PendingBatch* pending = &pending_batches_[i]; + grpc_transport_stream_op_batch* batch = pending->batch; + if (batch != nullptr) { + if (batch->recv_trailing_metadata) { + MaybeInjectRecvTrailingMetadataReadyForLoadBalancingPolicy(pick_.pick, + batch); + } + batch->handler_private.extra_arg = subchannel_call_.get(); + GRPC_CLOSURE_INIT(&batch->handler_private.closure, + ResumePendingBatchInCallCombiner, batch, + grpc_schedule_on_exec_ctx); + closures.Add(&batch->handler_private.closure, GRPC_ERROR_NONE, + "PendingBatchesResume"); + PendingBatchClear(pending); + } + } + // Note: This will release the call combiner. + closures.RunClosures(call_combiner_); +} + template -static pending_batch* pending_batch_find(grpc_call_element* elem, - const char* log_message, - Predicate predicate) { - channel_data* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); - for (size_t i = 0; i < GPR_ARRAY_SIZE(calld->pending_batches); ++i) { - pending_batch* pending = &calld->pending_batches[i]; +CallData::PendingBatch* CallData::PendingBatchFind(grpc_call_element* elem, + const char* log_message, + Predicate predicate) { + ChannelData* chand = static_cast(elem->channel_data); + for (size_t i = 0; i < GPR_ARRAY_SIZE(pending_batches_); ++i) { + PendingBatch* pending = &pending_batches_[i]; grpc_transport_stream_op_batch* batch = pending->batch; if (batch != nullptr && predicate(batch)) { - if (grpc_client_channel_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) { gpr_log(GPR_INFO, "chand=%p calld=%p: %s pending batch at index %" PRIuPTR, chand, - calld, log_message, i); + this, log_message, i); } return pending; } @@ -1417,115 +1989,99 @@ static pending_batch* pending_batch_find(grpc_call_element* elem, // retry code // -// Commits the call so that no further retry attempts will be performed. -static void retry_commit(grpc_call_element* elem, - subchannel_call_retry_state* retry_state) { - channel_data* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); - if (calld->retry_committed) return; - calld->retry_committed = true; - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p calld=%p: committing retries", chand, calld); +void CallData::RetryCommit(grpc_call_element* elem, + SubchannelCallRetryState* retry_state) { + ChannelData* chand = static_cast(elem->channel_data); + if (retry_committed_) return; + retry_committed_ = true; + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) { + gpr_log(GPR_INFO, "chand=%p calld=%p: committing retries", chand, this); } if (retry_state != nullptr) { - free_cached_send_op_data_after_commit(elem, retry_state); + FreeCachedSendOpDataAfterCommit(elem, retry_state); } } -// Starts a retry after appropriate back-off. -static void do_retry(grpc_call_element* elem, - subchannel_call_retry_state* retry_state, - grpc_millis server_pushback_ms) { - channel_data* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); - GPR_ASSERT(calld->method_params != nullptr); - const ClientChannelMethodParams::RetryPolicy* retry_policy = - calld->method_params->retry_policy(); +void CallData::DoRetry(grpc_call_element* elem, + SubchannelCallRetryState* retry_state, + grpc_millis server_pushback_ms) { + ChannelData* chand = static_cast(elem->channel_data); + GPR_ASSERT(method_params_ != nullptr); + const auto* retry_policy = method_params_->retry_policy(); GPR_ASSERT(retry_policy != nullptr); // Reset subchannel call and connected subchannel. - if (calld->subchannel_call != nullptr) { - GRPC_SUBCHANNEL_CALL_UNREF(calld->subchannel_call, - "client_channel_call_retry"); - calld->subchannel_call = nullptr; - } - if (calld->pick.connected_subchannel != nullptr) { - calld->pick.connected_subchannel.reset(); - } + subchannel_call_.reset(); + pick_.pick.connected_subchannel.reset(); // Compute backoff delay. grpc_millis next_attempt_time; if (server_pushback_ms >= 0) { - next_attempt_time = grpc_core::ExecCtx::Get()->Now() + server_pushback_ms; - calld->last_attempt_got_server_pushback = true; + next_attempt_time = ExecCtx::Get()->Now() + server_pushback_ms; + last_attempt_got_server_pushback_ = true; } else { - if (calld->num_attempts_completed == 1 || - calld->last_attempt_got_server_pushback) { - calld->retry_backoff.Init( - grpc_core::BackOff::Options() + if (num_attempts_completed_ == 1 || last_attempt_got_server_pushback_) { + retry_backoff_.Init( + BackOff::Options() .set_initial_backoff(retry_policy->initial_backoff) .set_multiplier(retry_policy->backoff_multiplier) .set_jitter(RETRY_BACKOFF_JITTER) .set_max_backoff(retry_policy->max_backoff)); - calld->last_attempt_got_server_pushback = false; + last_attempt_got_server_pushback_ = false; } - next_attempt_time = calld->retry_backoff->NextAttemptTime(); + next_attempt_time = retry_backoff_->NextAttemptTime(); } - if (grpc_client_channel_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) { gpr_log(GPR_INFO, "chand=%p calld=%p: retrying failed call in %" PRId64 " ms", chand, - calld, next_attempt_time - grpc_core::ExecCtx::Get()->Now()); + this, next_attempt_time - ExecCtx::Get()->Now()); } // Schedule retry after computed delay. - GRPC_CLOSURE_INIT(&calld->pick_closure, start_pick_locked, elem, - grpc_combiner_scheduler(chand->combiner)); - grpc_timer_init(&calld->retry_timer, next_attempt_time, &calld->pick_closure); + GRPC_CLOSURE_INIT(&pick_closure_, StartPickLocked, elem, + grpc_combiner_scheduler(chand->data_plane_combiner())); + grpc_timer_init(&retry_timer_, next_attempt_time, &pick_closure_); // Update bookkeeping. if (retry_state != nullptr) retry_state->retry_dispatched = true; } -// Returns true if the call is being retried. -static bool maybe_retry(grpc_call_element* elem, - subchannel_batch_data* batch_data, - grpc_status_code status, - grpc_mdelem* server_pushback_md) { - channel_data* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); +bool CallData::MaybeRetry(grpc_call_element* elem, + SubchannelCallBatchData* batch_data, + grpc_status_code status, + grpc_mdelem* server_pushback_md) { + ChannelData* chand = static_cast(elem->channel_data); // Get retry policy. - if (calld->method_params == nullptr) return false; - const ClientChannelMethodParams::RetryPolicy* retry_policy = - calld->method_params->retry_policy(); + if (method_params_ == nullptr) return false; + const auto* retry_policy = method_params_->retry_policy(); if (retry_policy == nullptr) return false; // If we've already dispatched a retry from this call, return true. // This catches the case where the batch has multiple callbacks // (i.e., it includes either recv_message or recv_initial_metadata). - subchannel_call_retry_state* retry_state = nullptr; + SubchannelCallRetryState* retry_state = nullptr; if (batch_data != nullptr) { - retry_state = static_cast( - grpc_connected_subchannel_call_get_parent_data( - batch_data->subchannel_call)); + retry_state = static_cast( + batch_data->subchannel_call->GetParentData()); if (retry_state->retry_dispatched) { - if (grpc_client_channel_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) { gpr_log(GPR_INFO, "chand=%p calld=%p: retry already dispatched", chand, - calld); + this); } return true; } } // Check status. if (GPR_LIKELY(status == GRPC_STATUS_OK)) { - if (calld->retry_throttle_data != nullptr) { - calld->retry_throttle_data->RecordSuccess(); + if (retry_throttle_data_ != nullptr) { + retry_throttle_data_->RecordSuccess(); } - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p calld=%p: call succeeded", chand, calld); + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) { + gpr_log(GPR_INFO, "chand=%p calld=%p: call succeeded", chand, this); } 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()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) { gpr_log(GPR_INFO, "chand=%p calld=%p: status %s not configured as retryable", chand, - calld, grpc_status_code_to_string(status)); + this, grpc_status_code_to_string(status)); } return false; } @@ -1536,36 +2092,36 @@ static bool maybe_retry(grpc_call_element* elem, // 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 (calld->retry_throttle_data != nullptr && - !calld->retry_throttle_data->RecordFailure()) { - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p calld=%p: retries throttled", chand, calld); + if (retry_throttle_data_ != nullptr && + !retry_throttle_data_->RecordFailure()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) { + gpr_log(GPR_INFO, "chand=%p calld=%p: retries throttled", chand, this); } return false; } // Check whether the call is committed. - if (calld->retry_committed) { - if (grpc_client_channel_trace.enabled()) { + if (retry_committed_) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) { gpr_log(GPR_INFO, "chand=%p calld=%p: retries already committed", chand, - calld); + this); } return false; } // Check whether we have retries remaining. - ++calld->num_attempts_completed; - if (calld->num_attempts_completed >= retry_policy->max_attempts) { - if (grpc_client_channel_trace.enabled()) { + ++num_attempts_completed_; + if (num_attempts_completed_ >= retry_policy->max_attempts) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) { gpr_log(GPR_INFO, "chand=%p calld=%p: exceeded %d retry attempts", chand, - calld, retry_policy->max_attempts); + this, retry_policy->max_attempts); } return false; } // If the call was cancelled from the surface, don't retry. - if (calld->cancel_error != GRPC_ERROR_NONE) { - if (grpc_client_channel_trace.enabled()) { + if (cancel_error_ != GRPC_ERROR_NONE) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) { gpr_log(GPR_INFO, "chand=%p calld=%p: call cancelled from surface, not retrying", - chand, calld); + chand, this); } return false; } @@ -1575,53 +2131,55 @@ static bool maybe_retry(grpc_call_element* elem, // If the value is "-1" or any other unparseable string, we do not retry. uint32_t ms; if (!grpc_parse_slice_to_uint32(GRPC_MDVALUE(*server_pushback_md), &ms)) { - if (grpc_client_channel_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) { gpr_log(GPR_INFO, "chand=%p calld=%p: not retrying due to server push-back", - chand, calld); + chand, this); } return false; } else { - if (grpc_client_channel_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) { gpr_log(GPR_INFO, "chand=%p calld=%p: server push-back: retry in %u ms", - chand, calld, ms); + chand, this, ms); } server_pushback_ms = (grpc_millis)ms; } } - do_retry(elem, retry_state, server_pushback_ms); + DoRetry(elem, retry_state, server_pushback_ms); return true; } // -// subchannel_batch_data +// CallData::SubchannelCallBatchData // -namespace { -subchannel_batch_data::subchannel_batch_data(grpc_call_element* elem, - call_data* calld, int refcount, - bool set_on_complete) - : elem(elem), - subchannel_call(GRPC_SUBCHANNEL_CALL_REF(calld->subchannel_call, - "batch_data_create")) { - subchannel_call_retry_state* retry_state = - static_cast( - grpc_connected_subchannel_call_get_parent_data( - calld->subchannel_call)); +CallData::SubchannelCallBatchData* CallData::SubchannelCallBatchData::Create( + grpc_call_element* elem, int refcount, bool set_on_complete) { + CallData* calld = static_cast(elem->call_data); + return calld->arena_->New(elem, calld, refcount, + set_on_complete); +} + +CallData::SubchannelCallBatchData::SubchannelCallBatchData( + grpc_call_element* elem, CallData* calld, int refcount, + bool set_on_complete) + : elem(elem), subchannel_call(calld->subchannel_call_) { + SubchannelCallRetryState* retry_state = + static_cast( + calld->subchannel_call_->GetParentData()); batch.payload = &retry_state->batch_payload; gpr_ref_init(&refs, refcount); if (set_on_complete) { - GRPC_CLOSURE_INIT(&on_complete, ::on_complete, this, + GRPC_CLOSURE_INIT(&on_complete, CallData::OnComplete, this, grpc_schedule_on_exec_ctx); batch.on_complete = &on_complete; } - GRPC_CALL_STACK_REF(calld->owning_call, "batch_data"); + GRPC_CALL_STACK_REF(calld->owning_call_, "batch_data"); } -void subchannel_batch_data::destroy() { - subchannel_call_retry_state* retry_state = - static_cast( - grpc_connected_subchannel_call_get_parent_data(subchannel_call)); +void CallData::SubchannelCallBatchData::Destroy() { + SubchannelCallRetryState* retry_state = + static_cast(subchannel_call->GetParentData()); if (batch.send_initial_metadata) { grpc_metadata_batch_destroy(&retry_state->send_initial_metadata); } @@ -1634,42 +2192,21 @@ void subchannel_batch_data::destroy() { if (batch.recv_trailing_metadata) { grpc_metadata_batch_destroy(&retry_state->recv_trailing_metadata); } - GRPC_SUBCHANNEL_CALL_UNREF(subchannel_call, "batch_data_unref"); - call_data* calld = static_cast(elem->call_data); - GRPC_CALL_STACK_UNREF(calld->owning_call, "batch_data"); -} -} // namespace - -// Creates a subchannel_batch_data object on the call's arena with the -// specified refcount. If set_on_complete is true, the batch's -// on_complete callback will be set to point to on_complete(); -// otherwise, the batch's on_complete callback will be null. -static subchannel_batch_data* batch_data_create(grpc_call_element* elem, - int refcount, - bool set_on_complete) { - call_data* calld = static_cast(elem->call_data); - subchannel_batch_data* batch_data = - new (gpr_arena_alloc(calld->arena, sizeof(*batch_data))) - subchannel_batch_data(elem, calld, refcount, set_on_complete); - return batch_data; -} - -static void batch_data_unref(subchannel_batch_data* batch_data) { - if (gpr_unref(&batch_data->refs)) { - batch_data->destroy(); - } + subchannel_call.reset(); + CallData* calld = static_cast(elem->call_data); + GRPC_CALL_STACK_UNREF(calld->owning_call_, "batch_data"); } // // recv_initial_metadata callback handling // -// Invokes recv_initial_metadata_ready for a subchannel batch. -static void invoke_recv_initial_metadata_callback(void* arg, - grpc_error* error) { - subchannel_batch_data* batch_data = static_cast(arg); +void CallData::InvokeRecvInitialMetadataCallback(void* arg, grpc_error* error) { + SubchannelCallBatchData* batch_data = + static_cast(arg); + CallData* calld = static_cast(batch_data->elem->call_data); // Find pending batch. - pending_batch* pending = pending_batch_find( + PendingBatch* pending = calld->PendingBatchFind( batch_data->elem, "invoking recv_initial_metadata_ready for", [](grpc_transport_stream_op_batch* batch) { return batch->recv_initial_metadata && @@ -1678,10 +2215,9 @@ static void invoke_recv_initial_metadata_callback(void* arg, }); GPR_ASSERT(pending != nullptr); // Return metadata. - subchannel_call_retry_state* retry_state = - static_cast( - grpc_connected_subchannel_call_get_parent_data( - batch_data->subchannel_call)); + SubchannelCallRetryState* retry_state = + static_cast( + batch_data->subchannel_call->GetParentData()); grpc_metadata_batch_move( &retry_state->recv_initial_metadata, pending->batch->payload->recv_initial_metadata.recv_initial_metadata); @@ -1693,34 +2229,32 @@ static void invoke_recv_initial_metadata_callback(void* arg, .recv_initial_metadata_ready; pending->batch->payload->recv_initial_metadata.recv_initial_metadata_ready = nullptr; - maybe_clear_pending_batch(batch_data->elem, pending); - batch_data_unref(batch_data); + calld->MaybeClearPendingBatch(batch_data->elem, pending); + batch_data->Unref(); // Invoke callback. GRPC_CLOSURE_RUN(recv_initial_metadata_ready, GRPC_ERROR_REF(error)); } -// Intercepts recv_initial_metadata_ready callback for retries. -// Commits the call and returns the initial metadata up the stack. -static void recv_initial_metadata_ready(void* arg, grpc_error* error) { - subchannel_batch_data* batch_data = static_cast(arg); +void CallData::RecvInitialMetadataReady(void* arg, grpc_error* error) { + SubchannelCallBatchData* batch_data = + static_cast(arg); grpc_call_element* elem = batch_data->elem; - channel_data* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); - if (grpc_client_channel_trace.enabled()) { + ChannelData* chand = static_cast(elem->channel_data); + CallData* calld = static_cast(elem->call_data); + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) { gpr_log(GPR_INFO, "chand=%p calld=%p: got recv_initial_metadata_ready, error=%s", chand, calld, grpc_error_string(error)); } - subchannel_call_retry_state* retry_state = - static_cast( - grpc_connected_subchannel_call_get_parent_data( - batch_data->subchannel_call)); + SubchannelCallRetryState* retry_state = + static_cast( + batch_data->subchannel_call->GetParentData()); retry_state->completed_recv_initial_metadata = true; // If a retry was already dispatched, then we're not going to use the // result of this recv_initial_metadata op, so do nothing. if (retry_state->retry_dispatched) { GRPC_CALL_COMBINER_STOP( - calld->call_combiner, + calld->call_combiner_, "recv_initial_metadata_ready after retry dispatched"); return; } @@ -1731,7 +2265,7 @@ static void recv_initial_metadata_ready(void* arg, grpc_error* error) { if (GPR_UNLIKELY((retry_state->trailing_metadata_available || error != GRPC_ERROR_NONE) && !retry_state->completed_recv_trailing_metadata)) { - if (grpc_client_channel_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) { gpr_log(GPR_INFO, "chand=%p calld=%p: deferring recv_initial_metadata_ready " "(Trailers-Only)", @@ -1742,30 +2276,31 @@ static void recv_initial_metadata_ready(void* arg, grpc_error* error) { if (!retry_state->started_recv_trailing_metadata) { // recv_trailing_metadata not yet started by application; start it // ourselves to get status. - start_internal_recv_trailing_metadata(elem); + calld->StartInternalRecvTrailingMetadata(elem); } else { GRPC_CALL_COMBINER_STOP( - calld->call_combiner, + calld->call_combiner_, "recv_initial_metadata_ready trailers-only or error"); } return; } // Received valid initial metadata, so commit the call. - retry_commit(elem, retry_state); + calld->RetryCommit(elem, retry_state); // Invoke the callback to return the result to the surface. // Manually invoking a callback function; it does not take ownership of error. - invoke_recv_initial_metadata_callback(batch_data, error); + calld->InvokeRecvInitialMetadataCallback(batch_data, error); } // // recv_message callback handling // -// Invokes recv_message_ready for a subchannel batch. -static void invoke_recv_message_callback(void* arg, grpc_error* error) { - subchannel_batch_data* batch_data = static_cast(arg); +void CallData::InvokeRecvMessageCallback(void* arg, grpc_error* error) { + SubchannelCallBatchData* batch_data = + static_cast(arg); + CallData* calld = static_cast(batch_data->elem->call_data); // Find pending op. - pending_batch* pending = pending_batch_find( + PendingBatch* pending = calld->PendingBatchFind( batch_data->elem, "invoking recv_message_ready for", [](grpc_transport_stream_op_batch* batch) { return batch->recv_message && @@ -1773,10 +2308,9 @@ static void invoke_recv_message_callback(void* arg, grpc_error* error) { }); GPR_ASSERT(pending != nullptr); // Return payload. - subchannel_call_retry_state* retry_state = - static_cast( - grpc_connected_subchannel_call_get_parent_data( - batch_data->subchannel_call)); + SubchannelCallRetryState* retry_state = + static_cast( + batch_data->subchannel_call->GetParentData()); *pending->batch->payload->recv_message.recv_message = std::move(retry_state->recv_message); // Update bookkeeping. @@ -1785,32 +2319,30 @@ static void invoke_recv_message_callback(void* arg, grpc_error* error) { grpc_closure* recv_message_ready = pending->batch->payload->recv_message.recv_message_ready; pending->batch->payload->recv_message.recv_message_ready = nullptr; - maybe_clear_pending_batch(batch_data->elem, pending); - batch_data_unref(batch_data); + calld->MaybeClearPendingBatch(batch_data->elem, pending); + batch_data->Unref(); // Invoke callback. GRPC_CLOSURE_RUN(recv_message_ready, GRPC_ERROR_REF(error)); } -// Intercepts recv_message_ready callback for retries. -// Commits the call and returns the message up the stack. -static void recv_message_ready(void* arg, grpc_error* error) { - subchannel_batch_data* batch_data = static_cast(arg); +void CallData::RecvMessageReady(void* arg, grpc_error* error) { + SubchannelCallBatchData* batch_data = + static_cast(arg); grpc_call_element* elem = batch_data->elem; - channel_data* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); - if (grpc_client_channel_trace.enabled()) { + ChannelData* chand = static_cast(elem->channel_data); + CallData* calld = static_cast(elem->call_data); + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) { 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 = - static_cast( - grpc_connected_subchannel_call_get_parent_data( - batch_data->subchannel_call)); + SubchannelCallRetryState* retry_state = + static_cast( + batch_data->subchannel_call->GetParentData()); ++retry_state->completed_recv_message_count; // If a retry was already dispatched, then we're not going to use the // result of this recv_message op, so do nothing. if (retry_state->retry_dispatched) { - GRPC_CALL_COMBINER_STOP(calld->call_combiner, + GRPC_CALL_COMBINER_STOP(calld->call_combiner_, "recv_message_ready after retry dispatched"); return; } @@ -1821,7 +2353,7 @@ static void recv_message_ready(void* arg, grpc_error* error) { if (GPR_UNLIKELY( (retry_state->recv_message == nullptr || error != GRPC_ERROR_NONE) && !retry_state->completed_recv_trailing_metadata)) { - if (grpc_client_channel_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) { gpr_log(GPR_INFO, "chand=%p calld=%p: deferring recv_message_ready (nullptr " "message and recv_trailing_metadata pending)", @@ -1832,33 +2364,29 @@ static void recv_message_ready(void* arg, grpc_error* error) { if (!retry_state->started_recv_trailing_metadata) { // recv_trailing_metadata not yet started by application; start it // ourselves to get status. - start_internal_recv_trailing_metadata(elem); + calld->StartInternalRecvTrailingMetadata(elem); } else { - GRPC_CALL_COMBINER_STOP(calld->call_combiner, "recv_message_ready null"); + GRPC_CALL_COMBINER_STOP(calld->call_combiner_, "recv_message_ready null"); } return; } // Received a valid message, so commit the call. - retry_commit(elem, retry_state); + calld->RetryCommit(elem, retry_state); // Invoke the callback to return the result to the surface. // Manually invoking a callback function; it does not take ownership of error. - invoke_recv_message_callback(batch_data, error); + calld->InvokeRecvMessageCallback(batch_data, error); } // // recv_trailing_metadata handling // -// Sets *status and *server_pushback_md based on md_batch and error. -// Only sets *server_pushback_md if server_pushback_md != nullptr. -static void get_call_status(grpc_call_element* elem, - grpc_metadata_batch* md_batch, grpc_error* error, - grpc_status_code* status, - grpc_mdelem** server_pushback_md) { - call_data* calld = static_cast(elem->call_data); +void CallData::GetCallStatus(grpc_call_element* elem, + grpc_metadata_batch* md_batch, grpc_error* error, + grpc_status_code* status, + grpc_mdelem** server_pushback_md) { if (error != GRPC_ERROR_NONE) { - grpc_error_get_status(error, calld->deadline, status, nullptr, nullptr, - nullptr); + grpc_error_get_status(error, deadline_, status, nullptr, nullptr, nullptr); } else { GPR_ASSERT(md_batch->idx.named.grpc_status != nullptr); *status = @@ -1871,12 +2399,11 @@ static void get_call_status(grpc_call_element* elem, GRPC_ERROR_UNREF(error); } -// Adds recv_trailing_metadata_ready closure to closures. -static void add_closure_for_recv_trailing_metadata_ready( - grpc_call_element* elem, subchannel_batch_data* batch_data, - grpc_error* error, grpc_core::CallCombinerClosureList* closures) { +void CallData::AddClosureForRecvTrailingMetadataReady( + grpc_call_element* elem, SubchannelCallBatchData* batch_data, + grpc_error* error, CallCombinerClosureList* closures) { // Find pending batch. - pending_batch* pending = pending_batch_find( + PendingBatch* pending = PendingBatchFind( elem, "invoking recv_trailing_metadata for", [](grpc_transport_stream_op_batch* batch) { return batch->recv_trailing_metadata && @@ -1884,17 +2411,15 @@ static void add_closure_for_recv_trailing_metadata_ready( .recv_trailing_metadata_ready != nullptr; }); // If we generated the recv_trailing_metadata op internally via - // start_internal_recv_trailing_metadata(), then there will be no - // pending batch. + // StartInternalRecvTrailingMetadata(), then there will be no pending batch. if (pending == nullptr) { GRPC_ERROR_UNREF(error); return; } // Return metadata. - subchannel_call_retry_state* retry_state = - static_cast( - grpc_connected_subchannel_call_get_parent_data( - batch_data->subchannel_call)); + SubchannelCallRetryState* retry_state = + static_cast( + batch_data->subchannel_call->GetParentData()); grpc_metadata_batch_move( &retry_state->recv_trailing_metadata, pending->batch->payload->recv_trailing_metadata.recv_trailing_metadata); @@ -1905,20 +2430,18 @@ static void add_closure_for_recv_trailing_metadata_ready( // Update bookkeeping. pending->batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready = nullptr; - maybe_clear_pending_batch(elem, pending); + MaybeClearPendingBatch(elem, pending); } -// Adds any necessary closures for deferred recv_initial_metadata and -// recv_message callbacks to closures. -static void add_closures_for_deferred_recv_callbacks( - subchannel_batch_data* batch_data, subchannel_call_retry_state* retry_state, - grpc_core::CallCombinerClosureList* closures) { +void CallData::AddClosuresForDeferredRecvCallbacks( + SubchannelCallBatchData* batch_data, SubchannelCallRetryState* retry_state, + CallCombinerClosureList* closures) { if (batch_data->batch.recv_trailing_metadata) { // Add closure for deferred recv_initial_metadata_ready. if (GPR_UNLIKELY(retry_state->recv_initial_metadata_ready_deferred_batch != nullptr)) { GRPC_CLOSURE_INIT(&retry_state->recv_initial_metadata_ready, - invoke_recv_initial_metadata_callback, + InvokeRecvInitialMetadataCallback, retry_state->recv_initial_metadata_ready_deferred_batch, grpc_schedule_on_exec_ctx); closures->Add(&retry_state->recv_initial_metadata_ready, @@ -1930,7 +2453,7 @@ static void add_closures_for_deferred_recv_callbacks( if (GPR_UNLIKELY(retry_state->recv_message_ready_deferred_batch != nullptr)) { GRPC_CLOSURE_INIT(&retry_state->recv_message_ready, - invoke_recv_message_callback, + InvokeRecvMessageCallback, retry_state->recv_message_ready_deferred_batch, grpc_schedule_on_exec_ctx); closures->Add(&retry_state->recv_message_ready, @@ -1941,11 +2464,8 @@ static void add_closures_for_deferred_recv_callbacks( } } -// Returns true if any op in the batch was not yet started. -// Only looks at send ops, since recv ops are always started immediately. -static bool pending_batch_is_unstarted( - pending_batch* pending, call_data* calld, - subchannel_call_retry_state* retry_state) { +bool CallData::PendingBatchIsUnstarted(PendingBatch* pending, + SubchannelCallRetryState* retry_state) { if (pending->batch == nullptr || pending->batch->on_complete == nullptr) { return false; } @@ -1954,7 +2474,7 @@ static bool pending_batch_is_unstarted( return true; } if (pending->batch->send_message && - retry_state->started_send_message_count < calld->send_messages.size()) { + retry_state->started_send_message_count < send_messages_.size()) { return true; } if (pending->batch->send_trailing_metadata && @@ -1964,119 +2484,109 @@ static bool pending_batch_is_unstarted( return false; } -// For any pending batch containing an op that has not yet been started, -// adds the pending batch's completion closures to closures. -static void add_closures_to_fail_unstarted_pending_batches( - grpc_call_element* elem, subchannel_call_retry_state* retry_state, - grpc_error* error, grpc_core::CallCombinerClosureList* closures) { - channel_data* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); - for (size_t i = 0; i < GPR_ARRAY_SIZE(calld->pending_batches); ++i) { - pending_batch* pending = &calld->pending_batches[i]; - if (pending_batch_is_unstarted(pending, calld, retry_state)) { - if (grpc_client_channel_trace.enabled()) { +void CallData::AddClosuresToFailUnstartedPendingBatches( + grpc_call_element* elem, SubchannelCallRetryState* retry_state, + grpc_error* error, CallCombinerClosureList* closures) { + ChannelData* chand = static_cast(elem->channel_data); + for (size_t i = 0; i < GPR_ARRAY_SIZE(pending_batches_); ++i) { + PendingBatch* pending = &pending_batches_[i]; + if (PendingBatchIsUnstarted(pending, retry_state)) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) { gpr_log(GPR_INFO, "chand=%p calld=%p: failing unstarted pending batch at index " "%" PRIuPTR, - chand, calld, i); + chand, this, i); } closures->Add(pending->batch->on_complete, GRPC_ERROR_REF(error), "failing on_complete for pending batch"); pending->batch->on_complete = nullptr; - maybe_clear_pending_batch(elem, pending); + MaybeClearPendingBatch(elem, pending); } } GRPC_ERROR_UNREF(error); } -// Runs necessary closures upon completion of a call attempt. -static void run_closures_for_completed_call(subchannel_batch_data* batch_data, - grpc_error* error) { +void CallData::RunClosuresForCompletedCall(SubchannelCallBatchData* batch_data, + grpc_error* error) { grpc_call_element* elem = batch_data->elem; - call_data* calld = static_cast(elem->call_data); - subchannel_call_retry_state* retry_state = - static_cast( - grpc_connected_subchannel_call_get_parent_data( - batch_data->subchannel_call)); + SubchannelCallRetryState* retry_state = + static_cast( + batch_data->subchannel_call->GetParentData()); // Construct list of closures to execute. - grpc_core::CallCombinerClosureList closures; + CallCombinerClosureList closures; // First, add closure for recv_trailing_metadata_ready. - add_closure_for_recv_trailing_metadata_ready( - elem, batch_data, GRPC_ERROR_REF(error), &closures); + AddClosureForRecvTrailingMetadataReady(elem, batch_data, + GRPC_ERROR_REF(error), &closures); // If there are deferred recv_initial_metadata_ready or recv_message_ready // callbacks, add them to closures. - add_closures_for_deferred_recv_callbacks(batch_data, retry_state, &closures); + AddClosuresForDeferredRecvCallbacks(batch_data, retry_state, &closures); // Add closures to fail any pending batches that have not yet been started. - add_closures_to_fail_unstarted_pending_batches( - elem, retry_state, GRPC_ERROR_REF(error), &closures); + AddClosuresToFailUnstartedPendingBatches(elem, retry_state, + GRPC_ERROR_REF(error), &closures); // Don't need batch_data anymore. - batch_data_unref(batch_data); + batch_data->Unref(); // Schedule all of the closures identified above. // Note: This will release the call combiner. - closures.RunClosures(calld->call_combiner); + closures.RunClosures(call_combiner_); GRPC_ERROR_UNREF(error); } -// Intercepts recv_trailing_metadata_ready callback for retries. -// Commits the call and returns the trailing metadata up the stack. -static void recv_trailing_metadata_ready(void* arg, grpc_error* error) { - subchannel_batch_data* batch_data = static_cast(arg); +void CallData::RecvTrailingMetadataReady(void* arg, grpc_error* error) { + SubchannelCallBatchData* batch_data = + static_cast(arg); grpc_call_element* elem = batch_data->elem; - channel_data* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); - if (grpc_client_channel_trace.enabled()) { + ChannelData* chand = static_cast(elem->channel_data); + CallData* calld = static_cast(elem->call_data); + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) { gpr_log(GPR_INFO, "chand=%p calld=%p: got recv_trailing_metadata_ready, error=%s", chand, calld, grpc_error_string(error)); } - subchannel_call_retry_state* retry_state = - static_cast( - grpc_connected_subchannel_call_get_parent_data( - batch_data->subchannel_call)); + SubchannelCallRetryState* retry_state = + static_cast( + batch_data->subchannel_call->GetParentData()); retry_state->completed_recv_trailing_metadata = true; // Get the call's status and check for server pushback metadata. grpc_status_code status = GRPC_STATUS_OK; grpc_mdelem* server_pushback_md = nullptr; grpc_metadata_batch* md_batch = batch_data->batch.payload->recv_trailing_metadata.recv_trailing_metadata; - get_call_status(elem, md_batch, GRPC_ERROR_REF(error), &status, - &server_pushback_md); - if (grpc_client_channel_trace.enabled()) { + calld->GetCallStatus(elem, md_batch, GRPC_ERROR_REF(error), &status, + &server_pushback_md); + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) { gpr_log(GPR_INFO, "chand=%p calld=%p: call finished, status=%s", chand, calld, grpc_status_code_to_string(status)); } // Check if we should retry. - if (maybe_retry(elem, batch_data, status, server_pushback_md)) { + if (calld->MaybeRetry(elem, batch_data, status, server_pushback_md)) { // Unref batch_data for deferred recv_initial_metadata_ready or // recv_message_ready callbacks, if any. if (retry_state->recv_initial_metadata_ready_deferred_batch != nullptr) { - batch_data_unref(batch_data); + batch_data->Unref(); GRPC_ERROR_UNREF(retry_state->recv_initial_metadata_error); } if (retry_state->recv_message_ready_deferred_batch != nullptr) { - batch_data_unref(batch_data); + batch_data->Unref(); GRPC_ERROR_UNREF(retry_state->recv_message_error); } - batch_data_unref(batch_data); + batch_data->Unref(); return; } // Not retrying, so commit the call. - retry_commit(elem, retry_state); + calld->RetryCommit(elem, retry_state); // Run any necessary closures. - run_closures_for_completed_call(batch_data, GRPC_ERROR_REF(error)); + calld->RunClosuresForCompletedCall(batch_data, GRPC_ERROR_REF(error)); } // // on_complete callback handling // -// Adds the on_complete closure for the pending batch completed in -// batch_data to closures. -static void add_closure_for_completed_pending_batch( - grpc_call_element* elem, subchannel_batch_data* batch_data, - subchannel_call_retry_state* retry_state, grpc_error* error, - grpc_core::CallCombinerClosureList* closures) { - pending_batch* pending = pending_batch_find( +void CallData::AddClosuresForCompletedPendingBatch( + grpc_call_element* elem, SubchannelCallBatchData* batch_data, + SubchannelCallRetryState* retry_state, grpc_error* error, + CallCombinerClosureList* closures) { + PendingBatch* pending = PendingBatchFind( elem, "completed", [batch_data](grpc_transport_stream_op_batch* batch) { // Match the pending batch with the same set of send ops as the // subchannel batch we've just completed. @@ -2097,27 +2607,22 @@ static void add_closure_for_completed_pending_batch( closures->Add(pending->batch->on_complete, error, "on_complete for pending batch"); pending->batch->on_complete = nullptr; - maybe_clear_pending_batch(elem, pending); + MaybeClearPendingBatch(elem, pending); } -// If there are any cached ops to replay or pending ops to start on the -// subchannel call, adds a closure to closures to invoke -// start_retriable_subchannel_batches(). -static void add_closures_for_replay_or_pending_send_ops( - grpc_call_element* elem, subchannel_batch_data* batch_data, - subchannel_call_retry_state* retry_state, - grpc_core::CallCombinerClosureList* closures) { - channel_data* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); +void CallData::AddClosuresForReplayOrPendingSendOps( + grpc_call_element* elem, SubchannelCallBatchData* batch_data, + SubchannelCallRetryState* retry_state, CallCombinerClosureList* closures) { + ChannelData* chand = static_cast(elem->channel_data); bool have_pending_send_message_ops = - retry_state->started_send_message_count < calld->send_messages.size(); + retry_state->started_send_message_count < send_messages_.size(); bool have_pending_send_trailing_metadata_op = - calld->seen_send_trailing_metadata && + seen_send_trailing_metadata_ && !retry_state->started_send_trailing_metadata; if (!have_pending_send_message_ops && !have_pending_send_trailing_metadata_op) { - for (size_t i = 0; i < GPR_ARRAY_SIZE(calld->pending_batches); ++i) { - pending_batch* pending = &calld->pending_batches[i]; + for (size_t i = 0; i < GPR_ARRAY_SIZE(pending_batches_); ++i) { + PendingBatch* pending = &pending_batches_[i]; grpc_transport_stream_op_batch* batch = pending->batch; if (batch == nullptr || pending->send_ops_cached) continue; if (batch->send_message) have_pending_send_message_ops = true; @@ -2127,36 +2632,34 @@ static void add_closures_for_replay_or_pending_send_ops( } } if (have_pending_send_message_ops || have_pending_send_trailing_metadata_op) { - if (grpc_client_channel_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) { gpr_log(GPR_INFO, "chand=%p calld=%p: starting next batch for pending send op(s)", - chand, calld); + chand, this); } GRPC_CLOSURE_INIT(&batch_data->batch.handler_private.closure, - start_retriable_subchannel_batches, elem, + StartRetriableSubchannelBatches, elem, grpc_schedule_on_exec_ctx); closures->Add(&batch_data->batch.handler_private.closure, GRPC_ERROR_NONE, "starting next batch for send_* op(s)"); } } -// Callback used to intercept on_complete from subchannel calls. -// Called only when retries are enabled. -static void on_complete(void* arg, grpc_error* error) { - subchannel_batch_data* batch_data = static_cast(arg); +void CallData::OnComplete(void* arg, grpc_error* error) { + SubchannelCallBatchData* batch_data = + static_cast(arg); grpc_call_element* elem = batch_data->elem; - channel_data* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); - if (grpc_client_channel_trace.enabled()) { + ChannelData* chand = static_cast(elem->channel_data); + CallData* calld = static_cast(elem->call_data); + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) { char* batch_str = grpc_transport_stream_op_batch_string(&batch_data->batch); 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); } - subchannel_call_retry_state* retry_state = - static_cast( - grpc_connected_subchannel_call_get_parent_data( - batch_data->subchannel_call)); + SubchannelCallRetryState* retry_state = + static_cast( + batch_data->subchannel_call->GetParentData()); // Update bookkeeping in retry_state. if (batch_data->batch.send_initial_metadata) { retry_state->completed_send_initial_metadata = true; @@ -2169,38 +2672,38 @@ static void on_complete(void* arg, grpc_error* error) { } // If the call is committed, free cached data for send ops that we've just // completed. - if (calld->retry_committed) { - free_cached_send_op_data_for_completed_batch(elem, batch_data, retry_state); + if (calld->retry_committed_) { + calld->FreeCachedSendOpDataForCompletedBatch(elem, batch_data, retry_state); } // Construct list of closures to execute. - grpc_core::CallCombinerClosureList closures; + CallCombinerClosureList closures; // If a retry was already dispatched, that means we saw // recv_trailing_metadata before this, so we do nothing here. // Otherwise, invoke the callback to return the result to the surface. if (!retry_state->retry_dispatched) { // Add closure for the completed pending batch, if any. - add_closure_for_completed_pending_batch(elem, batch_data, retry_state, - GRPC_ERROR_REF(error), &closures); + calld->AddClosuresForCompletedPendingBatch( + elem, batch_data, retry_state, GRPC_ERROR_REF(error), &closures); // If needed, add a callback to start any replay or pending send ops on // the subchannel call. if (!retry_state->completed_recv_trailing_metadata) { - add_closures_for_replay_or_pending_send_ops(elem, batch_data, retry_state, + calld->AddClosuresForReplayOrPendingSendOps(elem, batch_data, retry_state, &closures); } } // Track number of pending subchannel send batches and determine if this // was the last one. - --calld->num_pending_retriable_subchannel_send_batches; + --calld->num_pending_retriable_subchannel_send_batches_; const bool last_send_batch_complete = - calld->num_pending_retriable_subchannel_send_batches == 0; + calld->num_pending_retriable_subchannel_send_batches_ == 0; // Don't need batch_data anymore. - batch_data_unref(batch_data); + batch_data->Unref(); // Schedule all of the closures identified above. // Note: This yeilds the call combiner. - closures.RunClosures(calld->call_combiner); + closures.RunClosures(calld->call_combiner_); // If this was the last subchannel send batch, unref the call stack. if (last_send_batch_complete) { - GRPC_CALL_STACK_UNREF(calld->owning_call, "subchannel_send_batches"); + GRPC_CALL_STACK_UNREF(calld->owning_call_, "subchannel_send_batches"); } } @@ -2208,40 +2711,35 @@ static void on_complete(void* arg, grpc_error* error) { // subchannel batch construction // -// Helper function used to start a subchannel batch in the call combiner. -static void start_batch_in_call_combiner(void* arg, grpc_error* ignored) { +void CallData::StartBatchInCallCombiner(void* arg, grpc_error* ignored) { grpc_transport_stream_op_batch* batch = static_cast(arg); - grpc_subchannel_call* subchannel_call = - static_cast(batch->handler_private.extra_arg); + SubchannelCall* subchannel_call = + static_cast(batch->handler_private.extra_arg); // Note: This will release the call combiner. - grpc_subchannel_call_process_op(subchannel_call, batch); + subchannel_call->StartTransportStreamOpBatch(batch); } -// Adds a closure to closures that will execute batch in the call combiner. -static void add_closure_for_subchannel_batch( +void CallData::AddClosureForSubchannelBatch( grpc_call_element* elem, grpc_transport_stream_op_batch* batch, - grpc_core::CallCombinerClosureList* closures) { - channel_data* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); - 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); - if (grpc_client_channel_trace.enabled()) { + CallCombinerClosureList* closures) { + ChannelData* chand = static_cast(elem->channel_data); + batch->handler_private.extra_arg = subchannel_call_.get(); + GRPC_CLOSURE_INIT(&batch->handler_private.closure, StartBatchInCallCombiner, + batch, grpc_schedule_on_exec_ctx); + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) { char* batch_str = grpc_transport_stream_op_batch_string(batch); gpr_log(GPR_INFO, "chand=%p calld=%p: starting subchannel batch: %s", chand, - calld, batch_str); + this, batch_str); gpr_free(batch_str); } closures->Add(&batch->handler_private.closure, GRPC_ERROR_NONE, "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, - subchannel_batch_data* batch_data) { +void CallData::AddRetriableSendInitialMetadataOp( + SubchannelCallRetryState* retry_state, + SubchannelCallBatchData* batch_data) { // Maps the number of retries to the corresponding metadata value slice. static const grpc_slice* retry_count_strings[] = { &GRPC_MDSTR_1, &GRPC_MDSTR_2, &GRPC_MDSTR_3, &GRPC_MDSTR_4}; @@ -2252,11 +2750,10 @@ static void add_retriable_send_initial_metadata_op( // If we've already completed one or more attempts, add the // grpc-retry-attempts header. retry_state->send_initial_metadata_storage = - static_cast(gpr_arena_alloc( - calld->arena, sizeof(grpc_linked_mdelem) * - (calld->send_initial_metadata.list.count + - (calld->num_attempts_completed > 0)))); - grpc_metadata_batch_copy(&calld->send_initial_metadata, + static_cast(arena_->Alloc( + sizeof(grpc_linked_mdelem) * + (send_initial_metadata_.list.count + (num_attempts_completed_ > 0)))); + grpc_metadata_batch_copy(&send_initial_metadata_, &retry_state->send_initial_metadata, retry_state->send_initial_metadata_storage); if (GPR_UNLIKELY(retry_state->send_initial_metadata.idx.named @@ -2265,14 +2762,14 @@ static void add_retriable_send_initial_metadata_op( retry_state->send_initial_metadata.idx.named .grpc_previous_rpc_attempts); } - if (GPR_UNLIKELY(calld->num_attempts_completed > 0)) { + if (GPR_UNLIKELY(num_attempts_completed_ > 0)) { grpc_mdelem retry_md = grpc_mdelem_create( GRPC_MDSTR_GRPC_PREVIOUS_RPC_ATTEMPTS, - *retry_count_strings[calld->num_attempts_completed - 1], nullptr); + *retry_count_strings[num_attempts_completed_ - 1], nullptr); grpc_error* error = grpc_metadata_batch_add_tail( &retry_state->send_initial_metadata, - &retry_state->send_initial_metadata_storage[calld->send_initial_metadata - .list.count], + &retry_state + ->send_initial_metadata_storage[send_initial_metadata_.list.count], retry_md); if (GPR_UNLIKELY(error != GRPC_ERROR_NONE)) { gpr_log(GPR_ERROR, "error adding retry metadata: %s", @@ -2285,24 +2782,21 @@ static void add_retriable_send_initial_metadata_op( batch_data->batch.payload->send_initial_metadata.send_initial_metadata = &retry_state->send_initial_metadata; batch_data->batch.payload->send_initial_metadata.send_initial_metadata_flags = - calld->send_initial_metadata_flags; - batch_data->batch.payload->send_initial_metadata.peer_string = - calld->peer_string; + send_initial_metadata_flags_; + batch_data->batch.payload->send_initial_metadata.peer_string = peer_string_; } -// Adds retriable send_message op to batch_data. -static void add_retriable_send_message_op( - grpc_call_element* elem, subchannel_call_retry_state* retry_state, - subchannel_batch_data* batch_data) { - channel_data* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); - if (grpc_client_channel_trace.enabled()) { +void CallData::AddRetriableSendMessageOp(grpc_call_element* elem, + SubchannelCallRetryState* retry_state, + SubchannelCallBatchData* batch_data) { + ChannelData* chand = static_cast(elem->channel_data); + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) { gpr_log(GPR_INFO, "chand=%p calld=%p: starting calld->send_messages[%" PRIuPTR "]", - chand, calld, retry_state->started_send_message_count); + chand, this, retry_state->started_send_message_count); } - grpc_core::ByteStreamCache* cache = - calld->send_messages[retry_state->started_send_message_count]; + ByteStreamCache* cache = + send_messages_[retry_state->started_send_message_count]; ++retry_state->started_send_message_count; retry_state->send_message.Init(cache); batch_data->batch.send_message = true; @@ -2310,18 +2804,16 @@ static void add_retriable_send_message_op( retry_state->send_message.get()); } -// Adds retriable send_trailing_metadata op to batch_data. -static void add_retriable_send_trailing_metadata_op( - call_data* calld, subchannel_call_retry_state* retry_state, - subchannel_batch_data* batch_data) { +void CallData::AddRetriableSendTrailingMetadataOp( + SubchannelCallRetryState* retry_state, + SubchannelCallBatchData* batch_data) { // We need to make a copy of the metadata batch for each attempt, since // the filters in the subchannel stack may modify this batch, and we don't // want those modifications to be passed forward to subsequent attempts. retry_state->send_trailing_metadata_storage = - static_cast(gpr_arena_alloc( - calld->arena, sizeof(grpc_linked_mdelem) * - calld->send_trailing_metadata.list.count)); - grpc_metadata_batch_copy(&calld->send_trailing_metadata, + static_cast(arena_->Alloc( + sizeof(grpc_linked_mdelem) * send_trailing_metadata_.list.count)); + grpc_metadata_batch_copy(&send_trailing_metadata_, &retry_state->send_trailing_metadata, retry_state->send_trailing_metadata_storage); retry_state->started_send_trailing_metadata = true; @@ -2330,10 +2822,9 @@ static void add_retriable_send_trailing_metadata_op( &retry_state->send_trailing_metadata; } -// Adds retriable recv_initial_metadata op to batch_data. -static void add_retriable_recv_initial_metadata_op( - call_data* calld, subchannel_call_retry_state* retry_state, - subchannel_batch_data* batch_data) { +void CallData::AddRetriableRecvInitialMetadataOp( + SubchannelCallRetryState* retry_state, + SubchannelCallBatchData* batch_data) { retry_state->started_recv_initial_metadata = true; batch_data->batch.recv_initial_metadata = true; grpc_metadata_batch_init(&retry_state->recv_initial_metadata); @@ -2342,30 +2833,27 @@ static void add_retriable_recv_initial_metadata_op( batch_data->batch.payload->recv_initial_metadata.trailing_metadata_available = &retry_state->trailing_metadata_available; GRPC_CLOSURE_INIT(&retry_state->recv_initial_metadata_ready, - recv_initial_metadata_ready, batch_data, + RecvInitialMetadataReady, batch_data, grpc_schedule_on_exec_ctx); batch_data->batch.payload->recv_initial_metadata.recv_initial_metadata_ready = &retry_state->recv_initial_metadata_ready; } -// Adds retriable recv_message op to batch_data. -static void add_retriable_recv_message_op( - call_data* calld, subchannel_call_retry_state* retry_state, - subchannel_batch_data* batch_data) { +void CallData::AddRetriableRecvMessageOp(SubchannelCallRetryState* retry_state, + SubchannelCallBatchData* batch_data) { ++retry_state->started_recv_message_count; batch_data->batch.recv_message = true; batch_data->batch.payload->recv_message.recv_message = &retry_state->recv_message; - GRPC_CLOSURE_INIT(&retry_state->recv_message_ready, recv_message_ready, + GRPC_CLOSURE_INIT(&retry_state->recv_message_ready, RecvMessageReady, batch_data, grpc_schedule_on_exec_ctx); batch_data->batch.payload->recv_message.recv_message_ready = &retry_state->recv_message_ready; } -// Adds retriable recv_trailing_metadata op to batch_data. -static void add_retriable_recv_trailing_metadata_op( - call_data* calld, subchannel_call_retry_state* retry_state, - subchannel_batch_data* batch_data) { +void CallData::AddRetriableRecvTrailingMetadataOp( + SubchannelCallRetryState* retry_state, + SubchannelCallBatchData* batch_data) { retry_state->started_recv_trailing_metadata = true; batch_data->batch.recv_trailing_metadata = true; grpc_metadata_batch_init(&retry_state->recv_trailing_metadata); @@ -2374,114 +2862,105 @@ static void add_retriable_recv_trailing_metadata_op( batch_data->batch.payload->recv_trailing_metadata.collect_stats = &retry_state->collect_stats; GRPC_CLOSURE_INIT(&retry_state->recv_trailing_metadata_ready, - recv_trailing_metadata_ready, batch_data, + RecvTrailingMetadataReady, batch_data, grpc_schedule_on_exec_ctx); batch_data->batch.payload->recv_trailing_metadata .recv_trailing_metadata_ready = &retry_state->recv_trailing_metadata_ready; + MaybeInjectRecvTrailingMetadataReadyForLoadBalancingPolicy( + pick_.pick, &batch_data->batch); } -// Helper function used to start a recv_trailing_metadata batch. This -// is used in the case where a recv_initial_metadata or recv_message -// op fails in a way that we know the call is over but when the application -// has not yet started its own recv_trailing_metadata op. -static void start_internal_recv_trailing_metadata(grpc_call_element* elem) { - channel_data* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); - if (grpc_client_channel_trace.enabled()) { +void CallData::StartInternalRecvTrailingMetadata(grpc_call_element* elem) { + ChannelData* chand = static_cast(elem->channel_data); + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) { gpr_log(GPR_INFO, "chand=%p calld=%p: call failed but recv_trailing_metadata not " "started; starting it internally", - chand, calld); + chand, this); } - subchannel_call_retry_state* retry_state = - static_cast( - grpc_connected_subchannel_call_get_parent_data( - calld->subchannel_call)); + SubchannelCallRetryState* retry_state = + static_cast(subchannel_call_->GetParentData()); // Create batch_data with 2 refs, since this batch will be unreffed twice: // once for the recv_trailing_metadata_ready callback 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, false /* set_on_complete */); - add_retriable_recv_trailing_metadata_op(calld, retry_state, batch_data); + SubchannelCallBatchData* batch_data = + SubchannelCallBatchData::Create(elem, 2, false /* set_on_complete */); + AddRetriableRecvTrailingMetadataOp(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); + subchannel_call_->StartTransportStreamOpBatch(&batch_data->batch); } // If there are any cached send ops that need to be replayed on the // current subchannel call, creates and returns a new subchannel batch // to replay those ops. Otherwise, returns nullptr. -static subchannel_batch_data* maybe_create_subchannel_batch_for_replay( - grpc_call_element* elem, subchannel_call_retry_state* retry_state) { - channel_data* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); - subchannel_batch_data* replay_batch_data = nullptr; +CallData::SubchannelCallBatchData* +CallData::MaybeCreateSubchannelBatchForReplay( + grpc_call_element* elem, SubchannelCallRetryState* retry_state) { + ChannelData* chand = static_cast(elem->channel_data); + SubchannelCallBatchData* replay_batch_data = nullptr; // send_initial_metadata. - if (calld->seen_send_initial_metadata && + if (seen_send_initial_metadata_ && !retry_state->started_send_initial_metadata && - !calld->pending_send_initial_metadata) { - if (grpc_client_channel_trace.enabled()) { + !pending_send_initial_metadata_) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) { gpr_log(GPR_INFO, "chand=%p calld=%p: replaying previously completed " "send_initial_metadata op", - chand, calld); + chand, this); } - replay_batch_data = batch_data_create(elem, 1, true /* set_on_complete */); - add_retriable_send_initial_metadata_op(calld, retry_state, - replay_batch_data); + replay_batch_data = + SubchannelCallBatchData::Create(elem, 1, true /* set_on_complete */); + AddRetriableSendInitialMetadataOp(retry_state, replay_batch_data); } // 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 < 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()) { + !pending_send_message_) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) { gpr_log(GPR_INFO, "chand=%p calld=%p: replaying previously completed " "send_message op", - chand, calld); + chand, this); } if (replay_batch_data == nullptr) { replay_batch_data = - batch_data_create(elem, 1, true /* set_on_complete */); + SubchannelCallBatchData::Create(elem, 1, true /* set_on_complete */); } - add_retriable_send_message_op(elem, retry_state, replay_batch_data); + AddRetriableSendMessageOp(elem, retry_state, replay_batch_data); } // send_trailing_metadata. // Note that we only add this op if we have no more send_message ops // 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() && + if (seen_send_trailing_metadata_ && + retry_state->started_send_message_count == send_messages_.size() && !retry_state->started_send_trailing_metadata && - !calld->pending_send_trailing_metadata) { - if (grpc_client_channel_trace.enabled()) { + !pending_send_trailing_metadata_) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) { gpr_log(GPR_INFO, "chand=%p calld=%p: replaying previously completed " "send_trailing_metadata op", - chand, calld); + chand, this); } if (replay_batch_data == nullptr) { replay_batch_data = - batch_data_create(elem, 1, true /* set_on_complete */); + SubchannelCallBatchData::Create(elem, 1, true /* set_on_complete */); } - add_retriable_send_trailing_metadata_op(calld, retry_state, - replay_batch_data); + AddRetriableSendTrailingMetadataOp(retry_state, replay_batch_data); } return replay_batch_data; } -// Adds subchannel batches for pending batches to batches, updating -// *num_batches as needed. -static void add_subchannel_batches_for_pending_batches( - grpc_call_element* elem, subchannel_call_retry_state* retry_state, - grpc_core::CallCombinerClosureList* closures) { - call_data* calld = static_cast(elem->call_data); - for (size_t i = 0; i < GPR_ARRAY_SIZE(calld->pending_batches); ++i) { - pending_batch* pending = &calld->pending_batches[i]; +void CallData::AddSubchannelBatchesForPendingBatches( + grpc_call_element* elem, SubchannelCallRetryState* retry_state, + CallCombinerClosureList* closures) { + for (size_t i = 0; i < GPR_ARRAY_SIZE(pending_batches_); ++i) { + PendingBatch* pending = &pending_batches_[i]; grpc_transport_stream_op_batch* batch = pending->batch; if (batch == nullptr) continue; // Skip any batch that either (a) has already been started on this @@ -2507,7 +2986,7 @@ static void add_subchannel_batches_for_pending_batches( // 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() || + send_messages_.size() || retry_state->started_send_trailing_metadata)) { continue; } @@ -2522,7 +3001,7 @@ static void add_subchannel_batches_for_pending_batches( 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 + // initiated by StartInternalRecvTrailingMetadata(), use the // result of that instead of trying to re-start this op. if (GPR_UNLIKELY((retry_state->recv_trailing_metadata_internal_batch != nullptr))) { @@ -2538,18 +3017,19 @@ static void add_subchannel_batches_for_pending_batches( "re-executing recv_trailing_metadata_ready to propagate " "internally triggered result"); } else { - batch_data_unref(retry_state->recv_trailing_metadata_internal_batch); + retry_state->recv_trailing_metadata_internal_batch->Unref(); } 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) { - add_closure_for_subchannel_batch(elem, batch, closures); - pending_batch_clear(calld, pending); + if (method_params_ == nullptr || + method_params_->retry_policy() == nullptr || retry_committed_) { + // TODO(roth) : We should probably call + // MaybeInjectRecvTrailingMetadataReadyForLoadBalancingPolicy here. + AddClosureForSubchannelBatch(elem, batch, closures); + PendingBatchClear(pending); continue; } // Create batch with the right number of callbacks. @@ -2559,891 +3039,429 @@ static void add_subchannel_batches_for_pending_batches( const int num_callbacks = has_send_ops + batch->recv_initial_metadata + batch->recv_message + batch->recv_trailing_metadata; - subchannel_batch_data* batch_data = batch_data_create( + SubchannelCallBatchData* batch_data = SubchannelCallBatchData::Create( elem, num_callbacks, has_send_ops /* set_on_complete */); // Cache send ops if needed. - maybe_cache_send_ops_for_batch(calld, pending); + MaybeCacheSendOpsForBatch(pending); // send_initial_metadata. if (batch->send_initial_metadata) { - add_retriable_send_initial_metadata_op(calld, retry_state, batch_data); + AddRetriableSendInitialMetadataOp(retry_state, batch_data); } // send_message. if (batch->send_message) { - add_retriable_send_message_op(elem, retry_state, batch_data); + AddRetriableSendMessageOp(elem, retry_state, batch_data); } // send_trailing_metadata. if (batch->send_trailing_metadata) { - add_retriable_send_trailing_metadata_op(calld, retry_state, batch_data); + AddRetriableSendTrailingMetadataOp(retry_state, batch_data); } // recv_initial_metadata. if (batch->recv_initial_metadata) { // recv_flags is only used on the server side. GPR_ASSERT(batch->payload->recv_initial_metadata.recv_flags == nullptr); - add_retriable_recv_initial_metadata_op(calld, retry_state, batch_data); + AddRetriableRecvInitialMetadataOp(retry_state, batch_data); } // recv_message. if (batch->recv_message) { - add_retriable_recv_message_op(calld, retry_state, batch_data); + AddRetriableRecvMessageOp(retry_state, batch_data); } // recv_trailing_metadata. if (batch->recv_trailing_metadata) { - add_retriable_recv_trailing_metadata_op(calld, retry_state, batch_data); + AddRetriableRecvTrailingMetadataOp(retry_state, batch_data); } - add_closure_for_subchannel_batch(elem, &batch_data->batch, closures); + AddClosureForSubchannelBatch(elem, &batch_data->batch, closures); // Track number of pending subchannel send batches. // If this is the first one, take a ref to the call stack. if (batch->send_initial_metadata || batch->send_message || batch->send_trailing_metadata) { - if (calld->num_pending_retriable_subchannel_send_batches == 0) { - GRPC_CALL_STACK_REF(calld->owning_call, "subchannel_send_batches"); + if (num_pending_retriable_subchannel_send_batches_ == 0) { + GRPC_CALL_STACK_REF(owning_call_, "subchannel_send_batches"); } - ++calld->num_pending_retriable_subchannel_send_batches; + ++num_pending_retriable_subchannel_send_batches_; } } } -// Constructs and starts whatever subchannel batches are needed on the -// subchannel call. -static void start_retriable_subchannel_batches(void* arg, grpc_error* ignored) { +void CallData::StartRetriableSubchannelBatches(void* arg, grpc_error* ignored) { grpc_call_element* elem = static_cast(arg); - channel_data* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); - if (grpc_client_channel_trace.enabled()) { + ChannelData* chand = static_cast(elem->channel_data); + CallData* calld = static_cast(elem->call_data); + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) { gpr_log(GPR_INFO, "chand=%p calld=%p: constructing retriable batches", chand, calld); } - subchannel_call_retry_state* retry_state = - static_cast( - grpc_connected_subchannel_call_get_parent_data( - calld->subchannel_call)); + SubchannelCallRetryState* retry_state = + static_cast( + calld->subchannel_call_->GetParentData()); // Construct list of closures to execute, one for each pending batch. - grpc_core::CallCombinerClosureList closures; + CallCombinerClosureList closures; // Replay previously-returned send_* ops if needed. - subchannel_batch_data* replay_batch_data = - maybe_create_subchannel_batch_for_replay(elem, retry_state); + SubchannelCallBatchData* replay_batch_data = + calld->MaybeCreateSubchannelBatchForReplay(elem, retry_state); if (replay_batch_data != nullptr) { - add_closure_for_subchannel_batch(elem, &replay_batch_data->batch, - &closures); + calld->AddClosureForSubchannelBatch(elem, &replay_batch_data->batch, + &closures); // Track number of pending subchannel send batches. // If this is the first one, take a ref to the call stack. - if (calld->num_pending_retriable_subchannel_send_batches == 0) { - GRPC_CALL_STACK_REF(calld->owning_call, "subchannel_send_batches"); + if (calld->num_pending_retriable_subchannel_send_batches_ == 0) { + GRPC_CALL_STACK_REF(calld->owning_call_, "subchannel_send_batches"); } - ++calld->num_pending_retriable_subchannel_send_batches; + ++calld->num_pending_retriable_subchannel_send_batches_; } // Now add pending batches. - add_subchannel_batches_for_pending_batches(elem, retry_state, &closures); + calld->AddSubchannelBatchesForPendingBatches(elem, retry_state, &closures); // Start batches on subchannel call. - if (grpc_client_channel_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) { gpr_log(GPR_INFO, "chand=%p calld=%p: starting %" PRIuPTR " retriable batches on subchannel_call=%p", - chand, calld, closures.size(), calld->subchannel_call); + chand, calld, closures.size(), calld->subchannel_call_.get()); } // Note: This will yield the call combiner. - closures.RunClosures(calld->call_combiner); + closures.RunClosures(calld->call_combiner_); } // // LB pick // -static void create_subchannel_call(grpc_call_element* elem, grpc_error* error) { - channel_data* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); +void CallData::CreateSubchannelCall(grpc_call_element* elem) { + ChannelData* chand = static_cast(elem->channel_data); const size_t parent_data_size = - calld->enable_retries ? sizeof(subchannel_call_retry_state) : 0; - const grpc_core::ConnectedSubchannel::CallArgs call_args = { - calld->pollent, // pollent - calld->path, // path - calld->call_start_time, // start_time - calld->deadline, // deadline - calld->arena, // arena - calld->pick.subchannel_call_context, // context - calld->call_combiner, // call_combiner - parent_data_size // parent_data_size - }; - grpc_error* new_error = calld->pick.connected_subchannel->CreateCall( - call_args, &calld->subchannel_call); - if (grpc_client_channel_trace.enabled()) { + enable_retries_ ? sizeof(SubchannelCallRetryState) : 0; + const ConnectedSubchannel::CallArgs call_args = { + pollent_, path_, call_start_time_, deadline_, arena_, + // TODO(roth): When we implement hedging support, we will probably + // need to use a separate call context for each subchannel call. + call_context_, call_combiner_, parent_data_size}; + grpc_error* error = GRPC_ERROR_NONE; + subchannel_call_ = + pick_.pick.connected_subchannel->CreateCall(call_args, &error); + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) { gpr_log(GPR_INFO, "chand=%p calld=%p: create subchannel_call=%p: error=%s", - chand, calld, calld->subchannel_call, grpc_error_string(new_error)); + chand, this, subchannel_call_.get(), grpc_error_string(error)); } - if (GPR_UNLIKELY(new_error != GRPC_ERROR_NONE)) { - new_error = grpc_error_add_child(new_error, error); - pending_batches_fail(elem, new_error, true /* yield_call_combiner */); + if (GPR_UNLIKELY(error != GRPC_ERROR_NONE)) { + PendingBatchesFail(elem, error, YieldCallCombiner); } else { if (parent_data_size > 0) { - new (grpc_connected_subchannel_call_get_parent_data( - calld->subchannel_call)) - subchannel_call_retry_state(calld->pick.subchannel_call_context); + new (subchannel_call_->GetParentData()) + SubchannelCallRetryState(call_context_); } - pending_batches_resume(elem); + PendingBatchesResume(elem); } - GRPC_ERROR_UNREF(error); } -// Invoked when a pick is completed, on both success or failure. -static void pick_done(void* arg, grpc_error* error) { +void CallData::PickDone(void* arg, grpc_error* error) { grpc_call_element* elem = static_cast(arg); - channel_data* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); - if (GPR_UNLIKELY(calld->pick.connected_subchannel == nullptr)) { - // Failed to create subchannel. - // If there was no error, this is an LB policy drop, in which case - // we return an error; otherwise, we may retry. - grpc_status_code status = GRPC_STATUS_OK; - grpc_error_get_status(error, calld->deadline, &status, nullptr, nullptr, - nullptr); - if (error == GRPC_ERROR_NONE || !calld->enable_retries || - !maybe_retry(elem, nullptr /* batch_data */, status, - nullptr /* server_pushback_md */)) { - grpc_error* new_error = - error == GRPC_ERROR_NONE - ? GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "Call dropped by load balancing policy") - : GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Failed to create subchannel", &error, 1); - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, - "chand=%p calld=%p: failed to create subchannel: error=%s", - chand, calld, grpc_error_string(new_error)); - } - pending_batches_fail(elem, new_error, true /* yield_call_combiner */); + ChannelData* chand = static_cast(elem->channel_data); + CallData* calld = static_cast(elem->call_data); + if (error != GRPC_ERROR_NONE) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) { + gpr_log(GPR_INFO, + "chand=%p calld=%p: failed to pick subchannel: error=%s", chand, + calld, grpc_error_string(error)); } - } else { - /* Create call on subchannel. */ - create_subchannel_call(elem, GRPC_ERROR_REF(error)); + calld->PendingBatchesFail(elem, GRPC_ERROR_REF(error), YieldCallCombiner); + return; } + calld->CreateSubchannelCall(elem); } -static void maybe_add_call_to_channel_interested_parties_locked( - grpc_call_element* elem) { - channel_data* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); - if (!calld->pollent_added_to_interested_parties) { - calld->pollent_added_to_interested_parties = true; - grpc_polling_entity_add_to_pollset_set(calld->pollent, - chand->interested_parties); - } -} - -static void maybe_del_call_from_channel_interested_parties_locked( - grpc_call_element* elem) { - channel_data* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); - if (calld->pollent_added_to_interested_parties) { - calld->pollent_added_to_interested_parties = false; - grpc_polling_entity_del_from_pollset_set(calld->pollent, - chand->interested_parties); - } -} - -// Invoked when a pick is completed to leave the client_channel combiner -// and continue processing in the call combiner. -// If needed, removes the call's polling entity from chand->interested_parties. -static void pick_done_locked(grpc_call_element* elem, grpc_error* error) { - call_data* calld = static_cast(elem->call_data); - maybe_del_call_from_channel_interested_parties_locked(elem); - GRPC_CLOSURE_INIT(&calld->pick_closure, pick_done, elem, - grpc_schedule_on_exec_ctx); - GRPC_CLOSURE_SCHED(&calld->pick_closure, error); -} - -namespace grpc_core { - -// Performs subchannel pick via LB policy. -class LbPicker { +// A class to handle the call combiner cancellation callback for a +// queued pick. +class CallData::QueuedPickCanceller { public: - // Starts a pick on chand->lb_policy. - static void StartLocked(grpc_call_element* elem) { - channel_data* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p calld=%p: starting pick on lb_policy=%p", - chand, calld, chand->lb_policy.get()); - } - // If this is a retry, use the send_initial_metadata payload that - // we've cached; otherwise, use the pending batch. The - // send_initial_metadata batch will be the first pending batch in the - // list, as set by get_batch_index() above. - calld->pick.initial_metadata = - calld->seen_send_initial_metadata - ? &calld->send_initial_metadata - : calld->pending_batches[0] - .batch->payload->send_initial_metadata.send_initial_metadata; - calld->pick.initial_metadata_flags = - calld->seen_send_initial_metadata - ? calld->send_initial_metadata_flags - : calld->pending_batches[0] - .batch->payload->send_initial_metadata - .send_initial_metadata_flags; - GRPC_CLOSURE_INIT(&calld->pick_closure, &LbPicker::DoneLocked, elem, - grpc_combiner_scheduler(chand->combiner)); - calld->pick.on_complete = &calld->pick_closure; - GRPC_CALL_STACK_REF(calld->owning_call, "pick_callback"); - grpc_error* error = GRPC_ERROR_NONE; - const bool pick_done = chand->lb_policy->PickLocked(&calld->pick, &error); - if (GPR_LIKELY(pick_done)) { - // Pick completed synchronously. - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p calld=%p: pick completed synchronously", - chand, calld); - } - pick_done_locked(elem, error); - GRPC_CALL_STACK_UNREF(calld->owning_call, "pick_callback"); - } else { - // Pick will be returned asynchronously. - // Add the polling entity from call_data to the channel_data's - // interested_parties, so that the I/O of the LB policy can be done - // under it. It will be removed in pick_done_locked(). - maybe_add_call_to_channel_interested_parties_locked(elem); - // Request notification on call cancellation. - GRPC_CALL_STACK_REF(calld->owning_call, "pick_callback_cancel"); - grpc_call_combiner_set_notify_on_cancel( - calld->call_combiner, - GRPC_CLOSURE_INIT(&calld->pick_cancel_closure, - &LbPicker::CancelLocked, elem, - grpc_combiner_scheduler(chand->combiner))); - } + explicit QueuedPickCanceller(grpc_call_element* elem) : elem_(elem) { + auto* calld = static_cast(elem->call_data); + auto* chand = static_cast(elem->channel_data); + GRPC_CALL_STACK_REF(calld->owning_call_, "QueuedPickCanceller"); + GRPC_CLOSURE_INIT(&closure_, &CancelLocked, this, + grpc_combiner_scheduler(chand->data_plane_combiner())); + calld->call_combiner_->SetNotifyOnCancel(&closure_); } private: - // Callback invoked by LoadBalancingPolicy::PickLocked() for async picks. - // Unrefs the LB policy and invokes pick_done_locked(). - static void DoneLocked(void* arg, grpc_error* error) { - grpc_call_element* elem = static_cast(arg); - channel_data* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p calld=%p: pick completed asynchronously", - chand, calld); + static void CancelLocked(void* arg, grpc_error* error) { + auto* self = static_cast(arg); + auto* chand = static_cast(self->elem_->channel_data); + auto* calld = static_cast(self->elem_->call_data); + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) { + gpr_log(GPR_INFO, + "chand=%p calld=%p: cancelling queued pick: " + "error=%s self=%p calld->pick_canceller=%p", + chand, calld, grpc_error_string(error), self, + calld->pick_canceller_); } - pick_done_locked(elem, GRPC_ERROR_REF(error)); - GRPC_CALL_STACK_UNREF(calld->owning_call, "pick_callback"); + if (calld->pick_canceller_ == self && error != GRPC_ERROR_NONE) { + // Remove pick from list of queued picks. + calld->RemoveCallFromQueuedPicksLocked(self->elem_); + // Fail pending batches on the call. + calld->PendingBatchesFail(self->elem_, GRPC_ERROR_REF(error), + YieldCallCombinerIfPendingBatchesFound); + } + GRPC_CALL_STACK_UNREF(calld->owning_call_, "QueuedPickCanceller"); + Delete(self); } - // Note: This runs under the client_channel combiner, but will NOT be - // holding the call combiner. - static void CancelLocked(void* arg, grpc_error* error) { - grpc_call_element* elem = static_cast(arg); - channel_data* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); - // Note: chand->lb_policy may have changed since we started our pick, - // in which case we will be cancelling the pick on a policy other than - // the one we started it on. However, this will just be a no-op. - if (GPR_UNLIKELY(error != GRPC_ERROR_NONE && chand->lb_policy != nullptr)) { - if (grpc_client_channel_trace.enabled()) { - 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)); - } - GRPC_CALL_STACK_UNREF(calld->owning_call, "pick_callback_cancel"); - } + grpc_call_element* elem_; + grpc_closure closure_; }; -} // namespace grpc_core +void CallData::RemoveCallFromQueuedPicksLocked(grpc_call_element* elem) { + auto* chand = static_cast(elem->channel_data); + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) { + gpr_log(GPR_INFO, "chand=%p calld=%p: removing from queued picks list", + chand, this); + } + chand->RemoveQueuedPick(&pick_, pollent_); + pick_queued_ = false; + // Lame the call combiner canceller. + pick_canceller_ = nullptr; +} -// Applies service config to the call. Must be invoked once we know -// that the resolver has returned results to the channel. -static void apply_service_config_to_call_locked(grpc_call_element* elem) { - channel_data* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); - if (grpc_client_channel_trace.enabled()) { +void CallData::AddCallToQueuedPicksLocked(grpc_call_element* elem) { + auto* chand = static_cast(elem->channel_data); + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) { + gpr_log(GPR_INFO, "chand=%p calld=%p: adding to queued picks list", chand, + this); + } + pick_queued_ = true; + pick_.elem = elem; + chand->AddQueuedPick(&pick_, pollent_); + // Register call combiner cancellation callback. + pick_canceller_ = New(elem); +} + +void CallData::ApplyServiceConfigToCallLocked(grpc_call_element* elem) { + ChannelData* chand = static_cast(elem->channel_data); + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) { gpr_log(GPR_INFO, "chand=%p calld=%p: applying service config to call", - chand, calld); + chand, this); } - if (chand->retry_throttle_data != nullptr) { - calld->retry_throttle_data = chand->retry_throttle_data->Ref(); + // Store a ref to the service_config in service_config_call_data_. Also, save + // a pointer to this in the call_context so that all future filters can access + // it. + service_config_call_data_ = + ServiceConfig::CallData(chand->service_config(), path_); + if (service_config_call_data_.service_config() != nullptr) { + call_context_[GRPC_SERVICE_CONFIG_CALL_DATA].value = + &service_config_call_data_; + method_params_ = static_cast( + service_config_call_data_.GetMethodParsedObject( + internal::ClientChannelServiceConfigParser::ParserIndex())); } - if (chand->method_params_table != nullptr) { - calld->method_params = grpc_core::ServiceConfig::MethodConfigTableLookup( - *chand->method_params_table, calld->path); - if (calld->method_params != nullptr) { - // If the deadline from the service config is shorter than the one - // from the client API, reset the deadline timer. - if (chand->deadline_checking_enabled && - calld->method_params->timeout() != 0) { - const grpc_millis per_method_deadline = - grpc_timespec_to_millis_round_up(calld->call_start_time) + - calld->method_params->timeout(); - if (per_method_deadline < calld->deadline) { - calld->deadline = per_method_deadline; - grpc_deadline_state_reset(elem, calld->deadline); - } + retry_throttle_data_ = chand->retry_throttle_data(); + if (method_params_ != nullptr) { + // If the deadline from the service config is shorter than the one + // from the client API, reset the deadline timer. + if (chand->deadline_checking_enabled() && method_params_->timeout() != 0) { + const grpc_millis per_method_deadline = + grpc_timespec_to_millis_round_up(call_start_time_) + + method_params_->timeout(); + if (per_method_deadline < deadline_) { + deadline_ = per_method_deadline; + grpc_deadline_state_reset(elem, deadline_); } - // If the service config set wait_for_ready and the application - // did not explicitly set it, use the value from the service config. - uint32_t* send_initial_metadata_flags = - &calld->pending_batches[0] - .batch->payload->send_initial_metadata - .send_initial_metadata_flags; - if (GPR_UNLIKELY( - calld->method_params->wait_for_ready() != - ClientChannelMethodParams::WAIT_FOR_READY_UNSET && - !(*send_initial_metadata_flags & - GRPC_INITIAL_METADATA_WAIT_FOR_READY_EXPLICITLY_SET))) { - if (calld->method_params->wait_for_ready() == - ClientChannelMethodParams::WAIT_FOR_READY_TRUE) { - *send_initial_metadata_flags |= GRPC_INITIAL_METADATA_WAIT_FOR_READY; - } else { - *send_initial_metadata_flags &= ~GRPC_INITIAL_METADATA_WAIT_FOR_READY; - } + } + // If the service config set wait_for_ready and the application + // did not explicitly set it, use the value from the service config. + uint32_t* send_initial_metadata_flags = + &pending_batches_[0] + .batch->payload->send_initial_metadata.send_initial_metadata_flags; + if (method_params_->wait_for_ready().has_value() && + !(*send_initial_metadata_flags & + GRPC_INITIAL_METADATA_WAIT_FOR_READY_EXPLICITLY_SET)) { + if (method_params_->wait_for_ready().value()) { + *send_initial_metadata_flags |= GRPC_INITIAL_METADATA_WAIT_FOR_READY; + } else { + *send_initial_metadata_flags &= ~GRPC_INITIAL_METADATA_WAIT_FOR_READY; } } } // If no retry policy, disable retries. // TODO(roth): Remove this when adding support for transparent retries. - if (calld->method_params == nullptr || - calld->method_params->retry_policy() == nullptr) { - calld->enable_retries = false; + if (method_params_ == nullptr || method_params_->retry_policy() == nullptr) { + enable_retries_ = false; } } -// If the channel is in TRANSIENT_FAILURE and the call is not -// wait_for_ready=true, fails the call and returns true. -static bool fail_call_if_in_transient_failure(grpc_call_element* elem) { - channel_data* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); - grpc_transport_stream_op_batch* batch = calld->pending_batches[0].batch; - if (grpc_connectivity_state_check(&chand->state_tracker) == - GRPC_CHANNEL_TRANSIENT_FAILURE && - (batch->payload->send_initial_metadata.send_initial_metadata_flags & - GRPC_INITIAL_METADATA_WAIT_FOR_READY) == 0) { - pending_batches_fail( - elem, - grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "channel is in state TRANSIENT_FAILURE"), - GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE), - true /* yield_call_combiner */); - return true; +void CallData::MaybeApplyServiceConfigToCallLocked(grpc_call_element* elem) { + ChannelData* chand = static_cast(elem->channel_data); + // Apply service config data to the call only once, and only if the + // channel has the data available. + if (GPR_LIKELY(chand->received_service_config_data() && + !service_config_applied_)) { + service_config_applied_ = true; + ApplyServiceConfigToCallLocked(elem); } - return false; } -// Invoked once resolver results are available. -static void process_service_config_and_start_lb_pick_locked( - grpc_call_element* elem) { - call_data* calld = static_cast(elem->call_data); - // Only get service config data on the first attempt. - if (GPR_LIKELY(calld->num_attempts_completed == 0)) { - apply_service_config_to_call_locked(elem); - // Check this after applying service config, since it may have - // affected the call's wait_for_ready value. - if (fail_call_if_in_transient_failure(elem)) return; +const char* PickResultName(LoadBalancingPolicy::PickResult result) { + switch (result) { + case LoadBalancingPolicy::PICK_COMPLETE: + return "COMPLETE"; + case LoadBalancingPolicy::PICK_QUEUE: + return "QUEUE"; + case LoadBalancingPolicy::PICK_TRANSIENT_FAILURE: + return "TRANSIENT_FAILURE"; } - // Start LB pick. - grpc_core::LbPicker::StartLocked(elem); + GPR_UNREACHABLE_CODE(return "UNKNOWN"); } -namespace grpc_core { - -// Handles waiting for a resolver result. -// Used only for the first call on an idle channel. -class ResolverResultWaiter { - public: - explicit ResolverResultWaiter(grpc_call_element* elem) : elem_(elem) { - channel_data* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, - "chand=%p calld=%p: deferring pick pending resolver result", - chand, calld); - } - // Add closure to be run when a resolver result is available. - GRPC_CLOSURE_INIT(&done_closure_, &ResolverResultWaiter::DoneLocked, this, - grpc_combiner_scheduler(chand->combiner)); - AddToWaitingList(); - // Set cancellation closure, so that we abort if the call is cancelled. - GRPC_CLOSURE_INIT(&cancel_closure_, &ResolverResultWaiter::CancelLocked, - this, grpc_combiner_scheduler(chand->combiner)); - grpc_call_combiner_set_notify_on_cancel(calld->call_combiner, - &cancel_closure_); - } - - private: - // Adds closure_ to chand->waiting_for_resolver_result_closures. - void AddToWaitingList() { - channel_data* chand = static_cast(elem_->channel_data); - grpc_closure_list_append(&chand->waiting_for_resolver_result_closures, - &done_closure_, GRPC_ERROR_NONE); - } - - // Invoked when a resolver result is available. - static void DoneLocked(void* arg, grpc_error* error) { - ResolverResultWaiter* self = static_cast(arg); - // If CancelLocked() has already run, delete ourselves without doing - // anything. Note that the call stack may have already been destroyed, - // so it's not safe to access anything in elem_. - if (GPR_UNLIKELY(self->finished_)) { - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, "call cancelled before resolver result"); - } - Delete(self); - return; - } - // Otherwise, process the resolver result. - grpc_call_element* elem = self->elem_; - channel_data* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); - if (GPR_UNLIKELY(error != GRPC_ERROR_NONE)) { - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p calld=%p: resolver failed to return data", - chand, calld); - } - pick_done_locked(elem, GRPC_ERROR_REF(error)); - } else if (GPR_UNLIKELY(chand->resolver == nullptr)) { - // Shutting down. - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p calld=%p: resolver disconnected", chand, - calld); - } - pick_done_locked(elem, - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Disconnected")); - } else if (GPR_UNLIKELY(chand->lb_policy == nullptr)) { - // Transient resolver failure. - // If call has wait_for_ready=true, try again; otherwise, fail. - uint32_t send_initial_metadata_flags = - calld->seen_send_initial_metadata - ? calld->send_initial_metadata_flags - : calld->pending_batches[0] - .batch->payload->send_initial_metadata - .send_initial_metadata_flags; - if (send_initial_metadata_flags & GRPC_INITIAL_METADATA_WAIT_FOR_READY) { - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, - "chand=%p calld=%p: resolver returned but no LB policy; " - "wait_for_ready=true; trying again", - chand, calld); - } - // Re-add ourselves to the waiting list. - self->AddToWaitingList(); - // Return early so that we don't set finished_ to true below. - return; - } else { - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, - "chand=%p calld=%p: resolver returned but no LB policy; " - "wait_for_ready=false; failing", - chand, calld); - } - pick_done_locked( - elem, - grpc_error_set_int( - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Name resolution failure"), - GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE)); - } - } else { - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p calld=%p: resolver returned, doing LB pick", - chand, calld); - } - process_service_config_and_start_lb_pick_locked(elem); - } - self->finished_ = true; - } - - // Invoked when the call is cancelled. - // Note: This runs under the client_channel combiner, but will NOT be - // holding the call combiner. - static void CancelLocked(void* arg, grpc_error* error) { - ResolverResultWaiter* self = static_cast(arg); - // If DoneLocked() has already run, delete ourselves without doing anything. - if (GPR_LIKELY(self->finished_)) { - Delete(self); - return; - } - // If we are being cancelled, immediately invoke pick_done_locked() - // to propagate the error back to the caller. - if (GPR_UNLIKELY(error != GRPC_ERROR_NONE)) { - grpc_call_element* elem = self->elem_; - channel_data* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, - "chand=%p calld=%p: cancelling call waiting for name " - "resolution", - chand, calld); - } - // Note: Although we are not in the call combiner here, we are - // basically stealing the call combiner from the pending pick, so - // it's safe to call pick_done_locked() here -- we are essentially - // calling it here instead of calling it in DoneLocked(). - pick_done_locked(elem, GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Pick cancelled", &error, 1)); - } - self->finished_ = true; - } - - grpc_call_element* elem_; - grpc_closure done_closure_; - grpc_closure cancel_closure_; - bool finished_ = false; -}; - -} // namespace grpc_core - -static void start_pick_locked(void* arg, grpc_error* ignored) { +void CallData::StartPickLocked(void* arg, grpc_error* error) { grpc_call_element* elem = static_cast(arg); - call_data* calld = static_cast(elem->call_data); - channel_data* chand = static_cast(elem->channel_data); - GPR_ASSERT(calld->pick.connected_subchannel == nullptr); - GPR_ASSERT(calld->subchannel_call == nullptr); - if (GPR_LIKELY(chand->lb_policy != nullptr)) { - // We already have resolver results, so process the service config - // and start an LB pick. - process_service_config_and_start_lb_pick_locked(elem); - } else if (GPR_UNLIKELY(chand->resolver == nullptr)) { - pick_done_locked(elem, - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Disconnected")); - } else { - // We do not yet have an LB policy, so wait for a resolver result. - if (GPR_UNLIKELY(!chand->started_resolving)) { - start_resolving_locked(chand); - } else { - // Normally, we want to do this check in - // process_service_config_and_start_lb_pick_locked(), so that we - // can honor the wait_for_ready setting in the service config. - // However, if the channel is in TRANSIENT_FAILURE at this point, that - // means that the resolver has returned a failure, so we're not going - // to get a service config right away. In that case, we fail the - // call now based on the wait_for_ready value passed in from the - // application. - if (fail_call_if_in_transient_failure(elem)) return; + CallData* calld = static_cast(elem->call_data); + ChannelData* chand = static_cast(elem->channel_data); + GPR_ASSERT(calld->pick_.pick.connected_subchannel == nullptr); + GPR_ASSERT(calld->subchannel_call_ == nullptr); + // If this is a retry, use the send_initial_metadata payload that + // we've cached; otherwise, use the pending batch. The + // send_initial_metadata batch will be the first pending batch in the + // list, as set by GetBatchIndex() above. + // TODO(roth): What if the LB policy needs to add something to the + // call's initial metadata, and then there's a retry? We don't want + // the new metadata to be added twice. We might need to somehow + // allocate the subchannel batch earlier so that we can give the + // subchannel's copy of the metadata batch (which is copied for each + // attempt) to the LB policy instead the one from the parent channel. + calld->pick_.pick.initial_metadata = + calld->seen_send_initial_metadata_ + ? &calld->send_initial_metadata_ + : calld->pending_batches_[0] + .batch->payload->send_initial_metadata.send_initial_metadata; + uint32_t* send_initial_metadata_flags = + calld->seen_send_initial_metadata_ + ? &calld->send_initial_metadata_flags_ + : &calld->pending_batches_[0] + .batch->payload->send_initial_metadata + .send_initial_metadata_flags; + // Apply service config to call if needed. + calld->MaybeApplyServiceConfigToCallLocked(elem); + // When done, we schedule this closure to leave the data plane combiner. + GRPC_CLOSURE_INIT(&calld->pick_closure_, PickDone, elem, + grpc_schedule_on_exec_ctx); + // Attempt pick. + error = GRPC_ERROR_NONE; + auto pick_result = chand->picker()->Pick(&calld->pick_.pick, &error); + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) { + gpr_log(GPR_INFO, + "chand=%p calld=%p: LB pick returned %s (connected_subchannel=%p, " + "error=%s)", + chand, calld, PickResultName(pick_result), + calld->pick_.pick.connected_subchannel.get(), + grpc_error_string(error)); + } + switch (pick_result) { + case LoadBalancingPolicy::PICK_TRANSIENT_FAILURE: { + // If we're shutting down, fail all RPCs. + grpc_error* disconnect_error = chand->disconnect_error(); + if (disconnect_error != GRPC_ERROR_NONE) { + GRPC_ERROR_UNREF(error); + GRPC_CLOSURE_SCHED(&calld->pick_closure_, + GRPC_ERROR_REF(disconnect_error)); + break; + } + // If wait_for_ready is false, then the error indicates the RPC + // attempt's final status. + if ((*send_initial_metadata_flags & + GRPC_INITIAL_METADATA_WAIT_FOR_READY) == 0) { + // Retry if appropriate; otherwise, fail. + grpc_status_code status = GRPC_STATUS_OK; + grpc_error_get_status(error, calld->deadline_, &status, nullptr, + nullptr, nullptr); + if (!calld->enable_retries_ || + !calld->MaybeRetry(elem, nullptr /* batch_data */, status, + nullptr /* server_pushback_md */)) { + grpc_error* new_error = + GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + "Failed to pick subchannel", &error, 1); + GRPC_ERROR_UNREF(error); + GRPC_CLOSURE_SCHED(&calld->pick_closure_, new_error); + } + if (calld->pick_queued_) calld->RemoveCallFromQueuedPicksLocked(elem); + break; + } + // If wait_for_ready is true, then queue to retry when we get a new + // picker. + GRPC_ERROR_UNREF(error); } - // Create a new waiter, which will delete itself when done. - grpc_core::New(elem); - // Add the polling entity from call_data to the channel_data's - // interested_parties, so that the I/O of the resolver can be done - // under it. It will be removed in pick_done_locked(). - maybe_add_call_to_channel_interested_parties_locked(elem); + // Fallthrough + case LoadBalancingPolicy::PICK_QUEUE: + if (!calld->pick_queued_) calld->AddCallToQueuedPicksLocked(elem); + break; + default: // PICK_COMPLETE + // Handle drops. + if (GPR_UNLIKELY(calld->pick_.pick.connected_subchannel == nullptr)) { + error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Call dropped by load balancing policy"); + } + GRPC_CLOSURE_SCHED(&calld->pick_closure_, error); + if (calld->pick_queued_) calld->RemoveCallFromQueuedPicksLocked(elem); } } -// -// filter call vtable functions -// - -static void cc_start_transport_stream_op_batch( - grpc_call_element* elem, grpc_transport_stream_op_batch* batch) { - GPR_TIMER_SCOPE("cc_start_transport_stream_op_batch", 0); - call_data* calld = static_cast(elem->call_data); - channel_data* chand = static_cast(elem->channel_data); - if (GPR_LIKELY(chand->deadline_checking_enabled)) { - grpc_deadline_state_client_start_transport_stream_op_batch(elem, batch); - } - // If we've previously been cancelled, immediately fail any new batches. - if (GPR_UNLIKELY(calld->cancel_error != GRPC_ERROR_NONE)) { - if (grpc_client_channel_trace.enabled()) { - 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. - grpc_transport_stream_op_batch_finish_with_failure( - batch, GRPC_ERROR_REF(calld->cancel_error), calld->call_combiner); - return; - } - // Handle cancellation. - if (GPR_UNLIKELY(batch->cancel_stream)) { - // Stash a copy of cancel_error in our call data, so that we can use - // it for subsequent operations. This ensures that if the call is - // cancelled before any batches are passed down (e.g., if the deadline - // is in the past when the call starts), we can return the right - // error to the caller when the first batch does get passed down. - GRPC_ERROR_UNREF(calld->cancel_error); - calld->cancel_error = - GRPC_ERROR_REF(batch->payload->cancel_stream.cancel_error); - if (grpc_client_channel_trace.enabled()) { - 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 - // been started), fail all pending batches. Otherwise, send the - // cancellation down to the subchannel call. - if (calld->subchannel_call == nullptr) { - pending_batches_fail(elem, GRPC_ERROR_REF(calld->cancel_error), - false /* yield_call_combiner */); - // Note: This will release the call combiner. - grpc_transport_stream_op_batch_finish_with_failure( - batch, GRPC_ERROR_REF(calld->cancel_error), calld->call_combiner); - } else { - // Note: This will release the call combiner. - grpc_subchannel_call_process_op(calld->subchannel_call, batch); - } - return; - } - // Add the batch to the pending list. - pending_batches_add(elem, batch); - // Check if we've already gotten a subchannel call. - // Note that once we have completed the pick, we do not need to enter - // the channel combiner, which is more efficient (especially for - // streaming calls). - if (calld->subchannel_call != nullptr) { - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, - "chand=%p calld=%p: starting batch on subchannel_call=%p", chand, - calld, calld->subchannel_call); - } - pending_batches_resume(elem); - return; - } - // We do not yet have a subchannel call. - // For batches containing a send_initial_metadata op, enter the channel - // combiner to start a pick. - if (GPR_LIKELY(batch->send_initial_metadata)) { - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p calld=%p: entering client_channel combiner", - chand, calld); - } - GRPC_CLOSURE_SCHED( - GRPC_CLOSURE_INIT(&batch->handler_private.closure, start_pick_locked, - elem, grpc_combiner_scheduler(chand->combiner)), - GRPC_ERROR_NONE); - } else { - // For all other batches, release the call combiner. - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, - "chand=%p calld=%p: saved batch, yielding call combiner", chand, - calld); - } - GRPC_CALL_COMBINER_STOP(calld->call_combiner, - "batch does not include send_initial_metadata"); - } -} - -/* Constructor for call_data */ -static grpc_error* cc_init_call_elem(grpc_call_element* elem, - const grpc_call_element_args* args) { - channel_data* chand = static_cast(elem->channel_data); - new (elem->call_data) call_data(elem, *chand, *args); - return GRPC_ERROR_NONE; -} - -/* Destructor for call_data */ -static void cc_destroy_call_elem(grpc_call_element* elem, - const grpc_call_final_info* final_info, - grpc_closure* then_schedule_closure) { - call_data* calld = static_cast(elem->call_data); - if (GPR_LIKELY(calld->subchannel_call != nullptr)) { - grpc_subchannel_call_set_cleanup_closure(calld->subchannel_call, - then_schedule_closure); - then_schedule_closure = nullptr; - } - calld->~call_data(); - GRPC_CLOSURE_SCHED(then_schedule_closure, GRPC_ERROR_NONE); -} - -static void cc_set_pollset_or_pollset_set(grpc_call_element* elem, - grpc_polling_entity* pollent) { - call_data* calld = static_cast(elem->call_data); - calld->pollent = pollent; -} +} // namespace +} // namespace grpc_core /************************************************************************* * EXPORTED SYMBOLS */ +using grpc_core::CallData; +using grpc_core::ChannelData; + const grpc_channel_filter grpc_client_channel_filter = { - cc_start_transport_stream_op_batch, - cc_start_transport_op, - sizeof(call_data), - cc_init_call_elem, - cc_set_pollset_or_pollset_set, - cc_destroy_call_elem, - sizeof(channel_data), - cc_init_channel_elem, - cc_destroy_channel_elem, - cc_get_channel_info, + CallData::StartTransportStreamOpBatch, + ChannelData::StartTransportOp, + sizeof(CallData), + CallData::Init, + CallData::SetPollent, + CallData::Destroy, + sizeof(ChannelData), + ChannelData::Init, + ChannelData::Destroy, + ChannelData::GetChannelInfo, "client-channel", }; -static void try_to_connect_locked(void* arg, grpc_error* error_ignored) { - channel_data* chand = static_cast(arg); - if (chand->lb_policy != nullptr) { - chand->lb_policy->ExitIdleLocked(); - } else { - chand->exit_idle_when_lb_policy_arrives = true; - if (!chand->started_resolving && chand->resolver != nullptr) { - start_resolving_locked(chand); - } - } - GRPC_CHANNEL_STACK_UNREF(chand->owning_stack, "try_to_connect"); -} - void grpc_client_channel_set_channelz_node( grpc_channel_element* elem, grpc_core::channelz::ClientChannelNode* node) { - channel_data* chand = static_cast(elem->channel_data); - chand->channelz_channel = node; + auto* chand = static_cast(elem->channel_data); + chand->set_channelz_node(node); } void grpc_client_channel_populate_child_refs( grpc_channel_element* elem, grpc_core::channelz::ChildRefsList* child_subchannels, grpc_core::channelz::ChildRefsList* child_channels) { - channel_data* chand = static_cast(elem->channel_data); - if (chand->lb_policy != nullptr) { - chand->lb_policy->FillChildRefsForChannelz(child_subchannels, - child_channels); - } + auto* chand = static_cast(elem->channel_data); + chand->FillChildRefsForChannelz(child_subchannels, child_channels); } grpc_connectivity_state grpc_client_channel_check_connectivity_state( grpc_channel_element* elem, int try_to_connect) { - channel_data* chand = static_cast(elem->channel_data); - grpc_connectivity_state out = - grpc_connectivity_state_check(&chand->state_tracker); - if (out == GRPC_CHANNEL_IDLE && try_to_connect) { - GRPC_CHANNEL_STACK_REF(chand->owning_stack, "try_to_connect"); - GRPC_CLOSURE_SCHED( - GRPC_CLOSURE_CREATE(try_to_connect_locked, chand, - grpc_combiner_scheduler(chand->combiner)), - GRPC_ERROR_NONE); - } - return out; -} - -typedef struct external_connectivity_watcher { - channel_data* chand; - grpc_polling_entity pollent; - grpc_closure* on_complete; - grpc_closure* watcher_timer_init; - grpc_connectivity_state* state; - grpc_closure my_closure; - struct external_connectivity_watcher* next; -} external_connectivity_watcher; - -static external_connectivity_watcher* lookup_external_connectivity_watcher( - channel_data* chand, grpc_closure* on_complete) { - gpr_mu_lock(&chand->external_connectivity_watcher_list_mu); - external_connectivity_watcher* w = - chand->external_connectivity_watcher_list_head; - while (w != nullptr && w->on_complete != on_complete) { - w = w->next; - } - gpr_mu_unlock(&chand->external_connectivity_watcher_list_mu); - return w; -} - -static void external_connectivity_watcher_list_append( - channel_data* chand, external_connectivity_watcher* w) { - GPR_ASSERT(!lookup_external_connectivity_watcher(chand, w->on_complete)); - - gpr_mu_lock(&w->chand->external_connectivity_watcher_list_mu); - GPR_ASSERT(!w->next); - w->next = chand->external_connectivity_watcher_list_head; - chand->external_connectivity_watcher_list_head = w; - gpr_mu_unlock(&w->chand->external_connectivity_watcher_list_mu); -} - -static void external_connectivity_watcher_list_remove( - channel_data* chand, external_connectivity_watcher* too_remove) { - GPR_ASSERT( - lookup_external_connectivity_watcher(chand, too_remove->on_complete)); - gpr_mu_lock(&chand->external_connectivity_watcher_list_mu); - if (too_remove == chand->external_connectivity_watcher_list_head) { - chand->external_connectivity_watcher_list_head = too_remove->next; - gpr_mu_unlock(&chand->external_connectivity_watcher_list_mu); - return; - } - external_connectivity_watcher* w = - chand->external_connectivity_watcher_list_head; - while (w != nullptr) { - if (w->next == too_remove) { - w->next = w->next->next; - gpr_mu_unlock(&chand->external_connectivity_watcher_list_mu); - return; - } - w = w->next; - } - GPR_UNREACHABLE_CODE(return ); + auto* chand = static_cast(elem->channel_data); + return chand->CheckConnectivityState(try_to_connect); } int grpc_client_channel_num_external_connectivity_watchers( grpc_channel_element* elem) { - channel_data* chand = static_cast(elem->channel_data); - int count = 0; - - gpr_mu_lock(&chand->external_connectivity_watcher_list_mu); - external_connectivity_watcher* w = - chand->external_connectivity_watcher_list_head; - while (w != nullptr) { - count++; - w = w->next; - } - gpr_mu_unlock(&chand->external_connectivity_watcher_list_mu); - - return count; -} - -static void on_external_watch_complete_locked(void* arg, grpc_error* error) { - external_connectivity_watcher* w = - static_cast(arg); - grpc_closure* follow_up = w->on_complete; - grpc_polling_entity_del_from_pollset_set(&w->pollent, - w->chand->interested_parties); - GRPC_CHANNEL_STACK_UNREF(w->chand->owning_stack, - "external_connectivity_watcher"); - external_connectivity_watcher_list_remove(w->chand, w); - gpr_free(w); - GRPC_CLOSURE_SCHED(follow_up, GRPC_ERROR_REF(error)); -} - -static void watch_connectivity_state_locked(void* arg, - grpc_error* error_ignored) { - external_connectivity_watcher* w = - static_cast(arg); - 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)); - grpc_connectivity_state_notify_on_state_change(&w->chand->state_tracker, - w->state, &w->my_closure); - } else { - GPR_ASSERT(w->watcher_timer_init == nullptr); - found = lookup_external_connectivity_watcher(w->chand, w->on_complete); - if (found) { - GPR_ASSERT(found->on_complete == w->on_complete); - grpc_connectivity_state_notify_on_state_change( - &found->chand->state_tracker, nullptr, &found->my_closure); - } - grpc_polling_entity_del_from_pollset_set(&w->pollent, - w->chand->interested_parties); - GRPC_CHANNEL_STACK_UNREF(w->chand->owning_stack, - "external_connectivity_watcher"); - gpr_free(w); - } + auto* chand = static_cast(elem->channel_data); + return chand->NumExternalConnectivityWatchers(); } void grpc_client_channel_watch_connectivity_state( grpc_channel_element* elem, grpc_polling_entity pollent, grpc_connectivity_state* state, grpc_closure* closure, grpc_closure* watcher_timer_init) { - channel_data* chand = static_cast(elem->channel_data); - external_connectivity_watcher* w = - static_cast(gpr_zalloc(sizeof(*w))); - w->chand = chand; - w->pollent = pollent; - w->on_complete = closure; - w->state = state; - w->watcher_timer_init = watcher_timer_init; - grpc_polling_entity_add_to_pollset_set(&w->pollent, - chand->interested_parties); - GRPC_CHANNEL_STACK_REF(w->chand->owning_stack, - "external_connectivity_watcher"); - GRPC_CLOSURE_SCHED( - GRPC_CLOSURE_INIT(&w->my_closure, watch_connectivity_state_locked, w, - grpc_combiner_scheduler(chand->combiner)), - GRPC_ERROR_NONE); + auto* chand = static_cast(elem->channel_data); + return chand->AddExternalConnectivityWatcher(pollent, state, closure, + watcher_timer_init); } -grpc_subchannel_call* grpc_client_channel_get_subchannel_call( - grpc_call_element* elem) { - call_data* calld = static_cast(elem->call_data); - return calld->subchannel_call; +grpc_core::RefCountedPtr +grpc_client_channel_get_subchannel_call(grpc_call_element* elem) { + auto* calld = static_cast(elem->call_data); + return calld->subchannel_call(); } diff --git a/src/core/ext/filters/client_channel/client_channel.h b/src/core/ext/filters/client_channel/client_channel.h index 4935fd24d87..5bfff4df9cd 100644 --- a/src/core/ext/filters/client_channel/client_channel.h +++ b/src/core/ext/filters/client_channel/client_channel.h @@ -60,7 +60,7 @@ void grpc_client_channel_watch_connectivity_state( grpc_closure* watcher_timer_init); /* Debug helper: pull the subchannel call from a call stack element */ -grpc_subchannel_call* grpc_client_channel_get_subchannel_call( - grpc_call_element* elem); +grpc_core::RefCountedPtr +grpc_client_channel_get_subchannel_call(grpc_call_element* elem); #endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_CLIENT_CHANNEL_H */ diff --git a/src/core/ext/filters/client_channel/client_channel_channelz.cc b/src/core/ext/filters/client_channel/client_channel_channelz.cc index 8e5426081c4..de61819ef54 100644 --- a/src/core/ext/filters/client_channel/client_channel_channelz.cc +++ b/src/core/ext/filters/client_channel/client_channel_channelz.cc @@ -49,8 +49,8 @@ ClientChannelNode::ClientChannelNode(grpc_channel* channel, : ChannelNode(channel, channel_tracer_max_nodes, is_top_level_channel) { client_channel_ = grpc_channel_stack_last_element(grpc_channel_get_channel_stack(channel)); - grpc_client_channel_set_channelz_node(client_channel_, this); GPR_ASSERT(client_channel_->filter == &grpc_client_channel_filter); + grpc_client_channel_set_channelz_node(client_channel_, this); } void ClientChannelNode::PopulateConnectivityState(grpc_json* json) { @@ -113,12 +113,11 @@ RefCountedPtr ClientChannelNode::MakeClientChannelNode( is_top_level_channel); } -SubchannelNode::SubchannelNode(grpc_subchannel* subchannel, +SubchannelNode::SubchannelNode(Subchannel* subchannel, size_t channel_tracer_max_nodes) : BaseNode(EntityType::kSubchannel), subchannel_(subchannel), - target_( - UniquePtr(gpr_strdup(grpc_subchannel_get_target(subchannel_)))), + target_(UniquePtr(gpr_strdup(subchannel_->GetTargetAddress()))), trace_(channel_tracer_max_nodes) {} SubchannelNode::~SubchannelNode() {} @@ -128,8 +127,9 @@ void SubchannelNode::PopulateConnectivityState(grpc_json* json) { if (subchannel_ == nullptr) { state = GRPC_CHANNEL_SHUTDOWN; } else { - state = grpc_subchannel_check_connectivity( - subchannel_, nullptr, true /* inhibit_health_checking */); + state = subchannel_->CheckConnectivityState( + nullptr /* health_check_service_name */, + nullptr /* connected_subchannel */); } json = grpc_json_create_child(nullptr, json, "state", nullptr, GRPC_JSON_OBJECT, false); @@ -170,7 +170,7 @@ grpc_json* SubchannelNode::RenderJson() { call_counter_.PopulateCallCounts(json); json = top_level_json; // populate the child socket. - intptr_t socket_uuid = grpc_subchannel_get_child_socket_uuid(subchannel_); + intptr_t socket_uuid = subchannel_->GetChildSocketUuid(); if (socket_uuid != 0) { grpc_json* array_parent = grpc_json_create_child( nullptr, json, "socketRef", nullptr, GRPC_JSON_ARRAY, false); diff --git a/src/core/ext/filters/client_channel/client_channel_channelz.h b/src/core/ext/filters/client_channel/client_channel_channelz.h index 8a5c3e7e5e5..9272116882e 100644 --- a/src/core/ext/filters/client_channel/client_channel_channelz.h +++ b/src/core/ext/filters/client_channel/client_channel_channelz.h @@ -26,9 +26,10 @@ #include "src/core/lib/channel/channel_trace.h" #include "src/core/lib/channel/channelz.h" -typedef struct grpc_subchannel grpc_subchannel; - namespace grpc_core { + +class Subchannel; + namespace channelz { // Subtype of ChannelNode that overrides and provides client_channel specific @@ -59,7 +60,7 @@ class ClientChannelNode : public ChannelNode { // Handles channelz bookkeeping for sockets class SubchannelNode : public BaseNode { public: - SubchannelNode(grpc_subchannel* subchannel, size_t channel_tracer_max_nodes); + SubchannelNode(Subchannel* subchannel, size_t channel_tracer_max_nodes); ~SubchannelNode() override; void MarkSubchannelDestroyed() { @@ -70,11 +71,11 @@ class SubchannelNode : public BaseNode { grpc_json* RenderJson() override; // proxy methods to composed classes. - void AddTraceEvent(ChannelTrace::Severity severity, grpc_slice data) { + void AddTraceEvent(ChannelTrace::Severity severity, const grpc_slice& data) { trace_.AddTraceEvent(severity, data); } void AddTraceEventWithReference(ChannelTrace::Severity severity, - grpc_slice data, + const grpc_slice& data, RefCountedPtr referenced_channel) { trace_.AddTraceEventWithReference(severity, data, std::move(referenced_channel)); @@ -84,7 +85,7 @@ class SubchannelNode : public BaseNode { void RecordCallSucceeded() { call_counter_.RecordCallSucceeded(); } private: - grpc_subchannel* subchannel_; + Subchannel* subchannel_; UniquePtr target_; CallCountingHelper call_counter_; ChannelTrace trace_; diff --git a/src/core/ext/filters/client_channel/client_channel_factory.cc b/src/core/ext/filters/client_channel/client_channel_factory.cc index 172e9f03c73..671a38430ef 100644 --- a/src/core/ext/filters/client_channel/client_channel_factory.cc +++ b/src/core/ext/filters/client_channel/client_channel_factory.cc @@ -21,47 +21,35 @@ #include "src/core/ext/filters/client_channel/client_channel_factory.h" #include "src/core/lib/channel/channel_args.h" -void grpc_client_channel_factory_ref(grpc_client_channel_factory* factory) { - factory->vtable->ref(factory); -} +// Channel arg key for client channel factory. +#define GRPC_ARG_CLIENT_CHANNEL_FACTORY "grpc.client_channel_factory" -void grpc_client_channel_factory_unref(grpc_client_channel_factory* factory) { - factory->vtable->unref(factory); -} +namespace grpc_core { -grpc_subchannel* grpc_client_channel_factory_create_subchannel( - grpc_client_channel_factory* factory, const grpc_subchannel_args* args) { - return factory->vtable->create_subchannel(factory, args); -} +namespace { -grpc_channel* grpc_client_channel_factory_create_channel( - grpc_client_channel_factory* factory, const char* target, - grpc_client_channel_type type, const grpc_channel_args* args) { - return factory->vtable->create_client_channel(factory, target, type, args); +void* factory_arg_copy(void* f) { return f; } +void factory_arg_destroy(void* f) {} +int factory_arg_cmp(void* factory1, void* factory2) { + return GPR_ICMP(factory1, factory2); } - -static void* factory_arg_copy(void* factory) { - grpc_client_channel_factory_ref( - static_cast(factory)); - return factory; -} - -static void factory_arg_destroy(void* factory) { - grpc_client_channel_factory_unref( - static_cast(factory)); -} - -static int factory_arg_cmp(void* factory1, void* factory2) { - if (factory1 < factory2) return -1; - if (factory1 > factory2) return 1; - return 0; -} - -static const grpc_arg_pointer_vtable factory_arg_vtable = { +const grpc_arg_pointer_vtable factory_arg_vtable = { factory_arg_copy, factory_arg_destroy, factory_arg_cmp}; -grpc_arg grpc_client_channel_factory_create_channel_arg( - grpc_client_channel_factory* factory) { - return grpc_channel_arg_pointer_create((char*)GRPC_ARG_CLIENT_CHANNEL_FACTORY, - factory, &factory_arg_vtable); +} // namespace + +grpc_arg ClientChannelFactory::CreateChannelArg(ClientChannelFactory* factory) { + return grpc_channel_arg_pointer_create( + const_cast(GRPC_ARG_CLIENT_CHANNEL_FACTORY), factory, + &factory_arg_vtable); } + +ClientChannelFactory* ClientChannelFactory::GetFromChannelArgs( + const grpc_channel_args* args) { + const grpc_arg* arg = + grpc_channel_args_find(args, GRPC_ARG_CLIENT_CHANNEL_FACTORY); + if (arg == nullptr || arg->type != GRPC_ARG_POINTER) return nullptr; + return static_cast(arg->value.pointer.p); +} + +} // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/client_channel_factory.h b/src/core/ext/filters/client_channel/client_channel_factory.h index 601ec46b2a5..21f78a833df 100644 --- a/src/core/ext/filters/client_channel/client_channel_factory.h +++ b/src/core/ext/filters/client_channel/client_channel_factory.h @@ -24,51 +24,32 @@ #include #include "src/core/ext/filters/client_channel/subchannel.h" -#include "src/core/lib/channel/channel_stack.h" +#include "src/core/lib/gprpp/abstract.h" -// Channel arg key for client channel factory. -#define GRPC_ARG_CLIENT_CHANNEL_FACTORY "grpc.client_channel_factory" +namespace grpc_core { -typedef struct grpc_client_channel_factory grpc_client_channel_factory; -typedef struct grpc_client_channel_factory_vtable - grpc_client_channel_factory_vtable; +class ClientChannelFactory { + public: + virtual ~ClientChannelFactory() = default; -typedef enum { - GRPC_CLIENT_CHANNEL_TYPE_REGULAR, /** for the user-level regular calls */ - GRPC_CLIENT_CHANNEL_TYPE_LOAD_BALANCING, /** for communication with a load - balancing service */ -} grpc_client_channel_type; + // Creates a subchannel with the specified args. + virtual Subchannel* CreateSubchannel(const grpc_channel_args* args) + GRPC_ABSTRACT; -/** Constructor for new configured channels. - Creating decorators around this type is encouraged to adapt behavior. */ -struct grpc_client_channel_factory { - const grpc_client_channel_factory_vtable* vtable; + // Creates a channel for the specified target with the specified args. + virtual grpc_channel* CreateChannel( + const char* target, const grpc_channel_args* args) GRPC_ABSTRACT; + + // Returns a channel arg containing the specified factory. + static grpc_arg CreateChannelArg(ClientChannelFactory* factory); + + // Returns the factory from args, or null if not found. + static ClientChannelFactory* GetFromChannelArgs( + const grpc_channel_args* args); + + GRPC_ABSTRACT_BASE_CLASS }; -struct grpc_client_channel_factory_vtable { - void (*ref)(grpc_client_channel_factory* factory); - void (*unref)(grpc_client_channel_factory* factory); - grpc_subchannel* (*create_subchannel)(grpc_client_channel_factory* factory, - const grpc_subchannel_args* args); - grpc_channel* (*create_client_channel)(grpc_client_channel_factory* factory, - const char* target, - grpc_client_channel_type type, - const grpc_channel_args* args); -}; - -void grpc_client_channel_factory_ref(grpc_client_channel_factory* factory); -void grpc_client_channel_factory_unref(grpc_client_channel_factory* factory); - -/** Create a new grpc_subchannel */ -grpc_subchannel* grpc_client_channel_factory_create_subchannel( - grpc_client_channel_factory* factory, const grpc_subchannel_args* args); - -/** Create a new grpc_channel */ -grpc_channel* grpc_client_channel_factory_create_channel( - grpc_client_channel_factory* factory, const char* target, - grpc_client_channel_type type, const grpc_channel_args* args); - -grpc_arg grpc_client_channel_factory_create_channel_arg( - grpc_client_channel_factory* factory); +} // namespace grpc_core #endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_CLIENT_CHANNEL_FACTORY_H */ 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 e0784b7e5c1..e564df8be33 100644 --- a/src/core/ext/filters/client_channel/client_channel_plugin.cc +++ b/src/core/ext/filters/client_channel/client_channel_plugin.cc @@ -26,13 +26,14 @@ #include "src/core/ext/filters/client_channel/client_channel.h" #include "src/core/ext/filters/client_channel/client_channel_channelz.h" +#include "src/core/ext/filters/client_channel/global_subchannel_pool.h" #include "src/core/ext/filters/client_channel/http_connect_handshaker.h" #include "src/core/ext/filters/client_channel/http_proxy.h" #include "src/core/ext/filters/client_channel/lb_policy_registry.h" #include "src/core/ext/filters/client_channel/proxy_mapper_registry.h" #include "src/core/ext/filters/client_channel/resolver_registry.h" +#include "src/core/ext/filters/client_channel/resolver_result_parsing.h" #include "src/core/ext/filters/client_channel/retry_throttle.h" -#include "src/core/ext/filters/client_channel/subchannel_index.h" #include "src/core/lib/surface/channel_init.h" static bool append_filter(grpc_channel_stack_builder* builder, void* arg) { @@ -49,12 +50,14 @@ static bool append_filter(grpc_channel_stack_builder* builder, void* arg) { } void grpc_client_channel_init(void) { + grpc_core::ServiceConfig::Init(); + grpc_core::internal::ClientChannelServiceConfigParser::Register(); grpc_core::LoadBalancingPolicyRegistry::Builder::InitRegistry(); grpc_core::ResolverRegistry::Builder::InitRegistry(); grpc_core::internal::ServerRetryThrottleMap::Init(); grpc_proxy_mapper_registry_init(); grpc_register_http_proxy_mapper(); - grpc_subchannel_index_init(); + grpc_core::GlobalSubchannelPool::Init(); grpc_channel_init_register_stage( GRPC_CLIENT_CHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, append_filter, (void*)&grpc_client_channel_filter); @@ -62,10 +65,11 @@ void grpc_client_channel_init(void) { } void grpc_client_channel_shutdown(void) { - grpc_subchannel_index_shutdown(); + grpc_core::GlobalSubchannelPool::Shutdown(); grpc_channel_init_shutdown(); grpc_proxy_mapper_registry_shutdown(); grpc_core::internal::ServerRetryThrottleMap::Shutdown(); grpc_core::ResolverRegistry::Builder::ShutdownRegistry(); grpc_core::LoadBalancingPolicyRegistry::Builder::ShutdownRegistry(); + grpc_core::ServiceConfig::Shutdown(); } diff --git a/src/core/ext/filters/client_channel/global_subchannel_pool.cc b/src/core/ext/filters/client_channel/global_subchannel_pool.cc new file mode 100644 index 00000000000..96a0244eb24 --- /dev/null +++ b/src/core/ext/filters/client_channel/global_subchannel_pool.cc @@ -0,0 +1,179 @@ +// +// +// 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 + +#include "src/core/ext/filters/client_channel/global_subchannel_pool.h" + +#include "src/core/ext/filters/client_channel/subchannel.h" + +namespace grpc_core { + +GlobalSubchannelPool::GlobalSubchannelPool() { + subchannel_map_ = grpc_avl_create(&subchannel_avl_vtable_); + gpr_mu_init(&mu_); +} + +GlobalSubchannelPool::~GlobalSubchannelPool() { + gpr_mu_destroy(&mu_); + grpc_avl_unref(subchannel_map_, nullptr); +} + +void GlobalSubchannelPool::Init() { + instance_ = New>( + MakeRefCounted()); +} + +void GlobalSubchannelPool::Shutdown() { + // To ensure Init() was called before. + GPR_ASSERT(instance_ != nullptr); + // To ensure Shutdown() was not called before. + GPR_ASSERT(*instance_ != nullptr); + instance_->reset(); + Delete(instance_); +} + +RefCountedPtr GlobalSubchannelPool::instance() { + GPR_ASSERT(instance_ != nullptr); + GPR_ASSERT(*instance_ != nullptr); + return *instance_; +} + +Subchannel* GlobalSubchannelPool::RegisterSubchannel(SubchannelKey* key, + Subchannel* constructed) { + Subchannel* c = nullptr; + // Compare and swap (CAS) loop: + while (c == nullptr) { + // Ref the shared map to have a local copy. + gpr_mu_lock(&mu_); + grpc_avl old_map = grpc_avl_ref(subchannel_map_, nullptr); + gpr_mu_unlock(&mu_); + // Check to see if a subchannel already exists. + c = static_cast(grpc_avl_get(old_map, key, nullptr)); + if (c != nullptr) { + // The subchannel already exists. Try to reuse it. + c = GRPC_SUBCHANNEL_REF_FROM_WEAK_REF(c, "subchannel_register+reuse"); + if (c != nullptr) { + GRPC_SUBCHANNEL_UNREF(constructed, + "subchannel_register+found_existing"); + // Exit the CAS loop without modifying the shared map. + } // Else, reuse failed, so retry CAS loop. + } else { + // There hasn't been such subchannel. Add one. + // Note that we should ref the old map first because grpc_avl_add() will + // unref it while we still need to access it later. + grpc_avl new_map = grpc_avl_add( + grpc_avl_ref(old_map, nullptr), New(*key), + GRPC_SUBCHANNEL_WEAK_REF(constructed, "subchannel_register+new"), + nullptr); + // Try to publish the change to the shared map. It may happen (but + // unlikely) that some other thread has changed the shared map, so compare + // to make sure it's unchanged before swapping. Retry if it's changed. + gpr_mu_lock(&mu_); + if (old_map.root == subchannel_map_.root) { + GPR_SWAP(grpc_avl, new_map, subchannel_map_); + c = constructed; + } + gpr_mu_unlock(&mu_); + grpc_avl_unref(new_map, nullptr); + } + grpc_avl_unref(old_map, nullptr); + } + return c; +} + +void GlobalSubchannelPool::UnregisterSubchannel(SubchannelKey* key) { + bool done = false; + // Compare and swap (CAS) loop: + while (!done) { + // Ref the shared map to have a local copy. + gpr_mu_lock(&mu_); + grpc_avl old_map = grpc_avl_ref(subchannel_map_, nullptr); + gpr_mu_unlock(&mu_); + // Remove the subchannel. + // Note that we should ref the old map first because grpc_avl_remove() will + // unref it while we still need to access it later. + grpc_avl new_map = + grpc_avl_remove(grpc_avl_ref(old_map, nullptr), key, nullptr); + // Try to publish the change to the shared map. It may happen (but + // unlikely) that some other thread has changed the shared map, so compare + // to make sure it's unchanged before swapping. Retry if it's changed. + gpr_mu_lock(&mu_); + if (old_map.root == subchannel_map_.root) { + GPR_SWAP(grpc_avl, new_map, subchannel_map_); + done = true; + } + gpr_mu_unlock(&mu_); + grpc_avl_unref(new_map, nullptr); + grpc_avl_unref(old_map, nullptr); + } +} + +Subchannel* GlobalSubchannelPool::FindSubchannel(SubchannelKey* key) { + // Lock, and take a reference to the subchannel map. + // We don't need to do the search under a lock as AVL's are immutable. + gpr_mu_lock(&mu_); + grpc_avl index = grpc_avl_ref(subchannel_map_, nullptr); + gpr_mu_unlock(&mu_); + Subchannel* c = static_cast(grpc_avl_get(index, key, nullptr)); + if (c != nullptr) c = GRPC_SUBCHANNEL_REF_FROM_WEAK_REF(c, "found_from_pool"); + grpc_avl_unref(index, nullptr); + return c; +} + +RefCountedPtr* GlobalSubchannelPool::instance_ = nullptr; + +namespace { + +void sck_avl_destroy(void* p, void* user_data) { + SubchannelKey* key = static_cast(p); + Delete(key); +} + +void* sck_avl_copy(void* p, void* unused) { + const SubchannelKey* key = static_cast(p); + auto* new_key = New(*key); + return static_cast(new_key); +} + +long sck_avl_compare(void* a, void* b, void* unused) { + const SubchannelKey* key_a = static_cast(a); + const SubchannelKey* key_b = static_cast(b); + return key_a->Cmp(*key_b); +} + +void scv_avl_destroy(void* p, void* user_data) { + GRPC_SUBCHANNEL_WEAK_UNREF((Subchannel*)p, "global_subchannel_pool"); +} + +void* scv_avl_copy(void* p, void* unused) { + GRPC_SUBCHANNEL_WEAK_REF((Subchannel*)p, "global_subchannel_pool"); + return p; +} + +} // namespace + +const grpc_avl_vtable GlobalSubchannelPool::subchannel_avl_vtable_ = { + sck_avl_destroy, // destroy_key + sck_avl_copy, // copy_key + sck_avl_compare, // compare_keys + scv_avl_destroy, // destroy_value + scv_avl_copy // copy_value +}; + +} // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/global_subchannel_pool.h b/src/core/ext/filters/client_channel/global_subchannel_pool.h new file mode 100644 index 00000000000..96dc8d7b3a4 --- /dev/null +++ b/src/core/ext/filters/client_channel/global_subchannel_pool.h @@ -0,0 +1,68 @@ +/* + * + * 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_GLOBAL_SUBCHANNEL_POOL_H +#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_GLOBAL_SUBCHANNEL_POOL_H + +#include + +#include "src/core/ext/filters/client_channel/subchannel_pool_interface.h" + +namespace grpc_core { + +// The global subchannel pool. It shares subchannels among channels. There +// should be only one instance of this class. Init() should be called once at +// the filter initialization time; Shutdown() should be called once at the +// filter shutdown time. +// TODO(juanlishen): Enable subchannel retention. +class GlobalSubchannelPool final : public SubchannelPoolInterface { + public: + // The ctor and dtor are not intended to use directly. + GlobalSubchannelPool(); + ~GlobalSubchannelPool() override; + + // Should be called exactly once at filter initialization time. + static void Init(); + // Should be called exactly once at filter shutdown time. + static void Shutdown(); + + // Gets the singleton instance. + static RefCountedPtr instance(); + + // Implements interface methods. + Subchannel* RegisterSubchannel(SubchannelKey* key, + Subchannel* constructed) override; + void UnregisterSubchannel(SubchannelKey* key) override; + Subchannel* FindSubchannel(SubchannelKey* key) override; + + private: + // The singleton instance. (It's a pointer to RefCountedPtr so that this + // non-local static object can be trivially destructible.) + static RefCountedPtr* instance_; + + // The vtable for subchannel operations in an AVL tree. + static const grpc_avl_vtable subchannel_avl_vtable_; + // A map from subchannel key to subchannel. + grpc_avl subchannel_map_; + // To protect subchannel_map_. + gpr_mu mu_; +}; + +} // namespace grpc_core + +#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_GLOBAL_SUBCHANNEL_POOL_H */ diff --git a/src/core/ext/filters/client_channel/health/health_check_client.cc b/src/core/ext/filters/client_channel/health/health_check_client.cc index 587919596ff..faa2ba5b3b1 100644 --- a/src/core/ext/filters/client_channel/health/health_check_client.cc +++ b/src/core/ext/filters/client_channel/health/health_check_client.cc @@ -27,7 +27,7 @@ #include "pb_encode.h" #include "src/core/ext/filters/client_channel/health/health.pb.h" #include "src/core/lib/debug/trace.h" -#include "src/core/lib/gprpp/mutex_lock.h" +#include "src/core/lib/gprpp/sync.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/transport/error_utils.h" #include "src/core/lib/transport/status_metadata.h" @@ -37,11 +37,10 @@ #define HEALTH_CHECK_RECONNECT_MAX_BACKOFF_SECONDS 120 #define HEALTH_CHECK_RECONNECT_JITTER 0.2 -grpc_core::TraceFlag grpc_health_check_client_trace(false, - "health_check_client"); - namespace grpc_core { +TraceFlag grpc_health_check_client_trace(false, "health_check_client"); + // // HealthCheckClient // @@ -50,9 +49,8 @@ HealthCheckClient::HealthCheckClient( const char* service_name, RefCountedPtr connected_subchannel, grpc_pollset_set* interested_parties, - grpc_core::RefCountedPtr channelz_node) - : InternallyRefCountedWithTracing( - &grpc_health_check_client_trace), + RefCountedPtr channelz_node) + : InternallyRefCounted(&grpc_health_check_client_trace), service_name_(service_name), connected_subchannel_(std::move(connected_subchannel)), interested_parties_(interested_parties), @@ -65,21 +63,19 @@ HealthCheckClient::HealthCheckClient( .set_jitter(HEALTH_CHECK_RECONNECT_JITTER) .set_max_backoff(HEALTH_CHECK_RECONNECT_MAX_BACKOFF_SECONDS * 1000)) { - if (grpc_health_check_client_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_health_check_client_trace)) { gpr_log(GPR_INFO, "created HealthCheckClient %p", this); } GRPC_CLOSURE_INIT(&retry_timer_callback_, OnRetryTimer, this, grpc_schedule_on_exec_ctx); - gpr_mu_init(&mu_); StartCall(); } HealthCheckClient::~HealthCheckClient() { - if (grpc_health_check_client_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_health_check_client_trace)) { gpr_log(GPR_INFO, "destroying HealthCheckClient %p", this); } GRPC_ERROR_UNREF(error_); - gpr_mu_destroy(&mu_); } void HealthCheckClient::NotifyOnHealthChange(grpc_connectivity_state* state, @@ -103,7 +99,7 @@ void HealthCheckClient::SetHealthStatus(grpc_connectivity_state state, void HealthCheckClient::SetHealthStatusLocked(grpc_connectivity_state state, grpc_error* error) { - if (grpc_health_check_client_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_health_check_client_trace)) { gpr_log(GPR_INFO, "HealthCheckClient %p: setting state=%d error=%s", this, state, grpc_error_string(error)); } @@ -119,7 +115,7 @@ void HealthCheckClient::SetHealthStatusLocked(grpc_connectivity_state state, } void HealthCheckClient::Orphan() { - if (grpc_health_check_client_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_health_check_client_trace)) { gpr_log(GPR_INFO, "HealthCheckClient %p: shutting down", this); } { @@ -149,7 +145,7 @@ void HealthCheckClient::StartCallLocked() { GPR_ASSERT(call_state_ == nullptr); SetHealthStatusLocked(GRPC_CHANNEL_CONNECTING, GRPC_ERROR_NONE); call_state_ = MakeOrphanable(Ref(), interested_parties_); - if (grpc_health_check_client_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_health_check_client_trace)) { gpr_log(GPR_INFO, "HealthCheckClient %p: created CallState %p", this, call_state_.get()); } @@ -163,7 +159,7 @@ void HealthCheckClient::StartRetryTimer() { GRPC_ERROR_CREATE_FROM_STATIC_STRING( "health check call failed; will retry after backoff")); grpc_millis next_try = retry_backoff_.NextAttemptTime(); - if (grpc_health_check_client_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_health_check_client_trace)) { gpr_log(GPR_INFO, "HealthCheckClient %p: health check call lost...", this); grpc_millis timeout = next_try - ExecCtx::Get()->Now(); if (timeout > 0) { @@ -188,7 +184,7 @@ void HealthCheckClient::OnRetryTimer(void* arg, grpc_error* error) { self->retry_timer_callback_pending_ = false; if (!self->shutting_down_ && error == GRPC_ERROR_NONE && self->call_state_ == nullptr) { - if (grpc_health_check_client_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_health_check_client_trace)) { gpr_log(GPR_INFO, "HealthCheckClient %p: restarting health check call", self); } @@ -281,23 +277,17 @@ bool DecodeResponse(grpc_slice_buffer* slice_buffer, grpc_error** error) { HealthCheckClient::CallState::CallState( RefCountedPtr health_check_client, grpc_pollset_set* interested_parties) - : InternallyRefCountedWithTracing( - &grpc_health_check_client_trace), - health_check_client_(std::move(health_check_client)), + : health_check_client_(std::move(health_check_client)), pollent_(grpc_polling_entity_create_from_pollset_set(interested_parties)), - arena_(gpr_arena_create(health_check_client_->connected_subchannel_ - ->GetInitialCallSizeEstimate(0))), - payload_(context_) { - grpc_call_combiner_init(&call_combiner_); - gpr_atm_rel_store(&seen_response_, static_cast(0)); -} + arena_(Arena::Create(health_check_client_->connected_subchannel_ + ->GetInitialCallSizeEstimate(0))), + payload_(context_) {} HealthCheckClient::CallState::~CallState() { - if (grpc_health_check_client_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_health_check_client_trace)) { gpr_log(GPR_INFO, "HealthCheckClient %p: destroying CallState %p", health_check_client_.get(), this); } - if (call_ != nullptr) GRPC_SUBCHANNEL_CALL_UNREF(call_, "call_ended"); for (size_t i = 0; i < GRPC_CONTEXT_COUNT; i++) { if (context_[i].destroy != nullptr) { context_[i].destroy(context_[i].value); @@ -309,14 +299,13 @@ HealthCheckClient::CallState::~CallState() { // holding to the call stack. Also flush the closures on exec_ctx so that // filters that schedule cancel notification closures on exec_ctx do not // need to take a ref of the call stack to guarantee closure liveness. - grpc_call_combiner_set_notify_on_cancel(&call_combiner_, nullptr); - grpc_core::ExecCtx::Get()->Flush(); - grpc_call_combiner_destroy(&call_combiner_); - gpr_arena_destroy(arena_); + call_combiner_.SetNotifyOnCancel(nullptr); + ExecCtx::Get()->Flush(); + arena_->Destroy(); } void HealthCheckClient::CallState::Orphan() { - grpc_call_combiner_cancel(&call_combiner_, GRPC_ERROR_CANCELLED); + call_combiner_.Cancel(GRPC_ERROR_CANCELLED); Cancel(); } @@ -331,8 +320,14 @@ void HealthCheckClient::CallState::StartCall() { &call_combiner_, 0, // parent_data_size }; - grpc_error* error = - health_check_client_->connected_subchannel_->CreateCall(args, &call_); + grpc_error* error = GRPC_ERROR_NONE; + call_ = health_check_client_->connected_subchannel_->CreateCall(args, &error) + .release(); + // Register after-destruction callback. + GRPC_CLOSURE_INIT(&after_call_stack_destruction_, AfterCallStackDestruction, + this, grpc_schedule_on_exec_ctx); + call_->SetAfterCallStackDestroy(&after_call_stack_destruction_); + // Check if creation failed. if (error != GRPC_ERROR_NONE) { gpr_log(GPR_ERROR, "HealthCheckClient %p CallState %p: error creating health " @@ -341,7 +336,7 @@ void HealthCheckClient::CallState::StartCall() { GRPC_ERROR_UNREF(error); // Schedule instead of running directly, since we must not be // holding health_check_client_->mu_ when CallEnded() is called. - Ref(DEBUG_LOCATION, "call_end_closure").release(); + call_->Ref(DEBUG_LOCATION, "call_end_closure").release(); GRPC_CLOSURE_SCHED( GRPC_CLOSURE_INIT(&batch_.handler_private.closure, CallEndedRetry, this, grpc_schedule_on_exec_ctx), @@ -349,11 +344,10 @@ void HealthCheckClient::CallState::StartCall() { return; } // Initialize payload and batch. - memset(&batch_, 0, sizeof(batch_)); payload_.context = context_; batch_.payload = &payload_; // on_complete callback takes ref, handled manually. - Ref(DEBUG_LOCATION, "on_complete").release(); + call_->Ref(DEBUG_LOCATION, "on_complete").release(); batch_.on_complete = GRPC_CLOSURE_INIT(&on_complete_, OnComplete, this, grpc_schedule_on_exec_ctx); // Add send_initial_metadata op. @@ -386,7 +380,7 @@ void HealthCheckClient::CallState::StartCall() { payload_.recv_initial_metadata.trailing_metadata_available = nullptr; payload_.recv_initial_metadata.peer_string = nullptr; // recv_initial_metadata_ready callback takes ref, handled manually. - Ref(DEBUG_LOCATION, "recv_initial_metadata_ready").release(); + call_->Ref(DEBUG_LOCATION, "recv_initial_metadata_ready").release(); payload_.recv_initial_metadata.recv_initial_metadata_ready = GRPC_CLOSURE_INIT(&recv_initial_metadata_ready_, RecvInitialMetadataReady, this, grpc_schedule_on_exec_ctx); @@ -394,15 +388,13 @@ void HealthCheckClient::CallState::StartCall() { // Add recv_message op. payload_.recv_message.recv_message = &recv_message_; // recv_message callback takes ref, handled manually. - Ref(DEBUG_LOCATION, "recv_message_ready").release(); + call_->Ref(DEBUG_LOCATION, "recv_message_ready").release(); payload_.recv_message.recv_message_ready = GRPC_CLOSURE_INIT( &recv_message_ready_, RecvMessageReady, this, grpc_schedule_on_exec_ctx); batch_.recv_message = true; // Start batch. StartBatch(&batch_); // Initialize recv_trailing_metadata batch. - memset(&recv_trailing_metadata_batch_, 0, - sizeof(recv_trailing_metadata_batch_)); recv_trailing_metadata_batch_.payload = &payload_; // Add recv_trailing_metadata op. grpc_metadata_batch_init(&recv_trailing_metadata_); @@ -425,9 +417,9 @@ void HealthCheckClient::CallState::StartBatchInCallCombiner(void* arg, grpc_error* error) { grpc_transport_stream_op_batch* batch = static_cast(arg); - grpc_subchannel_call* call = - static_cast(batch->handler_private.extra_arg); - grpc_subchannel_call_process_op(call, batch); + SubchannelCall* call = + static_cast(batch->handler_private.extra_arg); + call->StartTransportStreamOpBatch(batch); } void HealthCheckClient::CallState::StartBatch( @@ -439,12 +431,19 @@ void HealthCheckClient::CallState::StartBatch( GRPC_ERROR_NONE, "start_subchannel_batch"); } +void HealthCheckClient::CallState::AfterCallStackDestruction( + void* arg, grpc_error* error) { + HealthCheckClient::CallState* self = + static_cast(arg); + Delete(self); +} + void HealthCheckClient::CallState::OnCancelComplete(void* arg, grpc_error* error) { HealthCheckClient::CallState* self = static_cast(arg); GRPC_CALL_COMBINER_STOP(&self->call_combiner_, "health_cancel"); - self->Unref(DEBUG_LOCATION, "cancel"); + self->call_->Unref(DEBUG_LOCATION, "cancel"); } void HealthCheckClient::CallState::StartCancel(void* arg, grpc_error* error) { @@ -454,12 +453,14 @@ void HealthCheckClient::CallState::StartCancel(void* arg, grpc_error* error) { GRPC_CLOSURE_CREATE(OnCancelComplete, self, grpc_schedule_on_exec_ctx)); batch->cancel_stream = true; batch->payload->cancel_stream.cancel_error = GRPC_ERROR_CANCELLED; - grpc_subchannel_call_process_op(self->call_, batch); + self->call_->StartTransportStreamOpBatch(batch); } void HealthCheckClient::CallState::Cancel() { - if (call_ != nullptr) { - Ref(DEBUG_LOCATION, "cancel").release(); + bool expected = false; + if (cancelled_.CompareExchangeStrong(&expected, true, MemoryOrder::ACQ_REL, + MemoryOrder::ACQUIRE)) { + call_->Ref(DEBUG_LOCATION, "cancel").release(); GRPC_CALL_COMBINER_START( &call_combiner_, GRPC_CLOSURE_CREATE(StartCancel, this, grpc_schedule_on_exec_ctx), @@ -473,7 +474,7 @@ void HealthCheckClient::CallState::OnComplete(void* arg, grpc_error* error) { GRPC_CALL_COMBINER_STOP(&self->call_combiner_, "on_complete"); grpc_metadata_batch_destroy(&self->send_initial_metadata_); grpc_metadata_batch_destroy(&self->send_trailing_metadata_); - self->Unref(DEBUG_LOCATION, "on_complete"); + self->call_->Unref(DEBUG_LOCATION, "on_complete"); } void HealthCheckClient::CallState::RecvInitialMetadataReady(void* arg, @@ -482,7 +483,7 @@ void HealthCheckClient::CallState::RecvInitialMetadataReady(void* arg, static_cast(arg); GRPC_CALL_COMBINER_STOP(&self->call_combiner_, "recv_initial_metadata_ready"); grpc_metadata_batch_destroy(&self->recv_initial_metadata_); - self->Unref(DEBUG_LOCATION, "recv_initial_metadata_ready"); + self->call_->Unref(DEBUG_LOCATION, "recv_initial_metadata_ready"); } void HealthCheckClient::CallState::DoneReadingRecvMessage(grpc_error* error) { @@ -491,7 +492,7 @@ void HealthCheckClient::CallState::DoneReadingRecvMessage(grpc_error* error) { GRPC_ERROR_UNREF(error); Cancel(); grpc_slice_buffer_destroy_internal(&recv_message_buffer_); - Unref(DEBUG_LOCATION, "recv_message_ready"); + call_->Unref(DEBUG_LOCATION, "recv_message_ready"); return; } const bool healthy = DecodeResponse(&recv_message_buffer_, &error); @@ -501,13 +502,12 @@ void HealthCheckClient::CallState::DoneReadingRecvMessage(grpc_error* error) { error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("backend unhealthy"); } health_check_client_->SetHealthStatus(state, error); - gpr_atm_rel_store(&seen_response_, static_cast(1)); + seen_response_.Store(true, MemoryOrder::RELEASE); grpc_slice_buffer_destroy_internal(&recv_message_buffer_); // Start another recv_message batch. // This re-uses the ref we're holding. // Note: Can't just reuse batch_ here, since we don't know that all // callbacks from the original batch have completed yet. - memset(&recv_message_batch_, 0, sizeof(recv_message_batch_)); recv_message_batch_.payload = &payload_; payload_.recv_message.recv_message = &recv_message_; payload_.recv_message.recv_message_ready = GRPC_CLOSURE_INIT( @@ -565,7 +565,7 @@ void HealthCheckClient::CallState::RecvMessageReady(void* arg, static_cast(arg); GRPC_CALL_COMBINER_STOP(&self->call_combiner_, "recv_message_ready"); if (self->recv_message_ == nullptr) { - self->Unref(DEBUG_LOCATION, "recv_message_ready"); + self->call_->Unref(DEBUG_LOCATION, "recv_message_ready"); return; } grpc_slice_buffer_init(&self->recv_message_buffer_); @@ -591,7 +591,7 @@ void HealthCheckClient::CallState::RecvTrailingMetadataReady( status = grpc_get_status_code_from_metadata( self->recv_trailing_metadata_.idx.named.grpc_status->md); } - if (grpc_health_check_client_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_health_check_client_trace)) { gpr_log(GPR_INFO, "HealthCheckClient %p CallState %p: health watch failed with " "status %d", @@ -623,7 +623,7 @@ void HealthCheckClient::CallState::CallEndedRetry(void* arg, HealthCheckClient::CallState* self = static_cast(arg); self->CallEnded(true /* retry */); - self->Unref(DEBUG_LOCATION, "call_end_closure"); + self->call_->Unref(DEBUG_LOCATION, "call_end_closure"); } void HealthCheckClient::CallState::CallEnded(bool retry) { @@ -635,7 +635,7 @@ void HealthCheckClient::CallState::CallEnded(bool retry) { health_check_client_->call_state_.reset(); if (retry) { GPR_ASSERT(!health_check_client_->shutting_down_); - if (static_cast(gpr_atm_acq_load(&seen_response_))) { + if (seen_response_.Load(MemoryOrder::ACQUIRE)) { // If the call fails after we've gotten a successful response, reset // the backoff and restart the call immediately. health_check_client_->retry_backoff_.Reset(); @@ -646,7 +646,9 @@ void HealthCheckClient::CallState::CallEnded(bool retry) { } } } - Unref(DEBUG_LOCATION, "call_ended"); + // When the last ref to the call stack goes away, the CallState object + // will be automatically destroyed. + call_->Unref(DEBUG_LOCATION, "call_ended"); } } // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/health/health_check_client.h b/src/core/ext/filters/client_channel/health/health_check_client.h index f6babef7d62..956c1095550 100644 --- a/src/core/ext/filters/client_channel/health/health_check_client.h +++ b/src/core/ext/filters/client_channel/health/health_check_client.h @@ -22,15 +22,16 @@ #include #include -#include #include #include "src/core/ext/filters/client_channel/client_channel_channelz.h" #include "src/core/ext/filters/client_channel/subchannel.h" #include "src/core/lib/backoff/backoff.h" -#include "src/core/lib/gpr/arena.h" +#include "src/core/lib/gprpp/arena.h" +#include "src/core/lib/gprpp/atomic.h" #include "src/core/lib/gprpp/orphanable.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" +#include "src/core/lib/gprpp/sync.h" #include "src/core/lib/iomgr/call_combiner.h" #include "src/core/lib/iomgr/closure.h" #include "src/core/lib/iomgr/polling_entity.h" @@ -41,8 +42,7 @@ namespace grpc_core { -class HealthCheckClient - : public InternallyRefCountedWithTracing { +class HealthCheckClient : public InternallyRefCounted { public: HealthCheckClient(const char* service_name, RefCountedPtr connected_subchannel, @@ -61,7 +61,7 @@ class HealthCheckClient private: // Contains a call to the backend and all the data related to the call. - class CallState : public InternallyRefCountedWithTracing { + class CallState : public Orphanable { public: CallState(RefCountedPtr health_check_client, grpc_pollset_set* interested_parties_); @@ -92,15 +92,19 @@ class HealthCheckClient grpc_error* PullSliceFromRecvMessage(); void DoneReadingRecvMessage(grpc_error* error); + static void AfterCallStackDestruction(void* arg, grpc_error* error); + RefCountedPtr health_check_client_; grpc_polling_entity pollent_; - gpr_arena* arena_; - grpc_call_combiner call_combiner_; + Arena* arena_; + grpc_core::CallCombiner call_combiner_; grpc_call_context_element context_[GRPC_CONTEXT_COUNT] = {}; - // The streaming call to the backend. Always non-NULL. - grpc_subchannel_call* call_; + // The streaming call to the backend. Always non-null. + // Refs are tracked manually; when the last ref is released, the + // CallState object will be automatically destroyed. + SubchannelCall* call_; grpc_transport_stream_op_batch_payload payload_; grpc_transport_stream_op_batch batch_; @@ -127,12 +131,18 @@ class HealthCheckClient OrphanablePtr recv_message_; grpc_closure recv_message_ready_; grpc_slice_buffer recv_message_buffer_; - gpr_atm seen_response_; + Atomic seen_response_{false}; // recv_trailing_metadata grpc_metadata_batch recv_trailing_metadata_; grpc_transport_stream_stats collect_stats_; grpc_closure recv_trailing_metadata_ready_; + + // True if the cancel_stream batch has been started. + Atomic cancelled_{false}; + + // Closure for call stack destruction. + grpc_closure after_call_stack_destruction_; }; void StartCall(); @@ -150,7 +160,7 @@ class HealthCheckClient grpc_pollset_set* interested_parties_; // Do not own. RefCountedPtr channelz_node_; - gpr_mu mu_; + Mutex mu_; grpc_connectivity_state state_ = GRPC_CHANNEL_CONNECTING; grpc_error* error_ = GRPC_ERROR_NONE; grpc_connectivity_state* notify_state_ = nullptr; 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 0716e468181..90a79843458 100644 --- a/src/core/ext/filters/client_channel/http_connect_handshaker.cc +++ b/src/core/ext/filters/client_channel/http_connect_handshaker.cc @@ -33,151 +33,160 @@ #include "src/core/lib/channel/handshaker_registry.h" #include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/sync.h" #include "src/core/lib/http/format_request.h" #include "src/core/lib/http/parser.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/uri/uri_parser.h" -typedef struct http_connect_handshaker { - // Base class. Must be first. - grpc_handshaker base; +namespace grpc_core { - gpr_refcount refcount; - gpr_mu mu; +namespace { - bool shutdown; +class HttpConnectHandshaker : public Handshaker { + public: + HttpConnectHandshaker(); + void Shutdown(grpc_error* why) override; + void DoHandshake(grpc_tcp_server_acceptor* acceptor, + grpc_closure* on_handshake_done, + HandshakerArgs* args) override; + const char* name() const override { return "http_connect"; } + + private: + virtual ~HttpConnectHandshaker(); + void CleanupArgsForFailureLocked(); + void HandshakeFailedLocked(grpc_error* error); + static void OnWriteDone(void* arg, grpc_error* error); + static void OnReadDone(void* arg, grpc_error* error); + + gpr_mu mu_; + + bool is_shutdown_ = false; // Endpoint and read buffer to destroy after a shutdown. - grpc_endpoint* endpoint_to_destroy; - grpc_slice_buffer* read_buffer_to_destroy; + grpc_endpoint* endpoint_to_destroy_ = nullptr; + grpc_slice_buffer* read_buffer_to_destroy_ = nullptr; // State saved while performing the handshake. - grpc_handshaker_args* args; - grpc_closure* on_handshake_done; + HandshakerArgs* args_ = nullptr; + grpc_closure* on_handshake_done_ = nullptr; // Objects for processing the HTTP CONNECT request and response. - grpc_slice_buffer write_buffer; - grpc_closure request_done_closure; - grpc_closure response_read_closure; - grpc_http_parser http_parser; - grpc_http_response http_response; -} http_connect_handshaker; + grpc_slice_buffer write_buffer_; + grpc_closure request_done_closure_; + grpc_closure response_read_closure_; + grpc_http_parser http_parser_; + grpc_http_response http_response_; +}; -// Unref and clean up handshaker. -static void http_connect_handshaker_unref(http_connect_handshaker* handshaker) { - if (gpr_unref(&handshaker->refcount)) { - gpr_mu_destroy(&handshaker->mu); - if (handshaker->endpoint_to_destroy != nullptr) { - grpc_endpoint_destroy(handshaker->endpoint_to_destroy); - } - if (handshaker->read_buffer_to_destroy != nullptr) { - grpc_slice_buffer_destroy_internal(handshaker->read_buffer_to_destroy); - gpr_free(handshaker->read_buffer_to_destroy); - } - grpc_slice_buffer_destroy_internal(&handshaker->write_buffer); - grpc_http_parser_destroy(&handshaker->http_parser); - grpc_http_response_destroy(&handshaker->http_response); - gpr_free(handshaker); +HttpConnectHandshaker::~HttpConnectHandshaker() { + gpr_mu_destroy(&mu_); + if (endpoint_to_destroy_ != nullptr) { + grpc_endpoint_destroy(endpoint_to_destroy_); } + if (read_buffer_to_destroy_ != nullptr) { + grpc_slice_buffer_destroy_internal(read_buffer_to_destroy_); + gpr_free(read_buffer_to_destroy_); + } + grpc_slice_buffer_destroy_internal(&write_buffer_); + grpc_http_parser_destroy(&http_parser_); + grpc_http_response_destroy(&http_response_); } // Set args fields to nullptr, saving the endpoint and read buffer for // later destruction. -static void cleanup_args_for_failure_locked( - http_connect_handshaker* handshaker) { - handshaker->endpoint_to_destroy = handshaker->args->endpoint; - handshaker->args->endpoint = nullptr; - handshaker->read_buffer_to_destroy = handshaker->args->read_buffer; - handshaker->args->read_buffer = nullptr; - grpc_channel_args_destroy(handshaker->args->args); - handshaker->args->args = nullptr; +void HttpConnectHandshaker::CleanupArgsForFailureLocked() { + endpoint_to_destroy_ = args_->endpoint; + args_->endpoint = nullptr; + read_buffer_to_destroy_ = args_->read_buffer; + args_->read_buffer = nullptr; + grpc_channel_args_destroy(args_->args); + args_->args = nullptr; } // If the handshake failed or we're shutting down, clean up and invoke the // callback with the error. -static void handshake_failed_locked(http_connect_handshaker* handshaker, - grpc_error* error) { +void HttpConnectHandshaker::HandshakeFailedLocked(grpc_error* error) { if (error == GRPC_ERROR_NONE) { // If we were shut down after an endpoint operation succeeded but // before the endpoint callback was invoked, we need to generate our // own error. error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Handshaker shutdown"); } - if (!handshaker->shutdown) { + if (!is_shutdown_) { // TODO(ctiller): It is currently necessary to shutdown endpoints // before destroying them, even if we know that there are no // pending read/write callbacks. This should be fixed, at which // point this can be removed. - grpc_endpoint_shutdown(handshaker->args->endpoint, GRPC_ERROR_REF(error)); + grpc_endpoint_shutdown(args_->endpoint, GRPC_ERROR_REF(error)); // Not shutting down, so the handshake failed. Clean up before // invoking the callback. - cleanup_args_for_failure_locked(handshaker); + CleanupArgsForFailureLocked(); // Set shutdown to true so that subsequent calls to // http_connect_handshaker_shutdown() do nothing. - handshaker->shutdown = true; + is_shutdown_ = true; } // Invoke callback. - GRPC_CLOSURE_SCHED(handshaker->on_handshake_done, error); + GRPC_CLOSURE_SCHED(on_handshake_done_, error); } // Callback invoked when finished writing HTTP CONNECT request. -static void on_write_done(void* arg, grpc_error* error) { - http_connect_handshaker* handshaker = - static_cast(arg); - gpr_mu_lock(&handshaker->mu); - if (error != GRPC_ERROR_NONE || handshaker->shutdown) { +void HttpConnectHandshaker::OnWriteDone(void* arg, grpc_error* error) { + auto* handshaker = static_cast(arg); + gpr_mu_lock(&handshaker->mu_); + if (error != GRPC_ERROR_NONE || handshaker->is_shutdown_) { // If the write failed or we're shutting down, clean up and invoke the // callback with the error. - handshake_failed_locked(handshaker, GRPC_ERROR_REF(error)); - gpr_mu_unlock(&handshaker->mu); - http_connect_handshaker_unref(handshaker); + handshaker->HandshakeFailedLocked(GRPC_ERROR_REF(error)); + gpr_mu_unlock(&handshaker->mu_); + handshaker->Unref(); } else { // Otherwise, read the response. // The read callback inherits our ref to the handshaker. - grpc_endpoint_read(handshaker->args->endpoint, - handshaker->args->read_buffer, - &handshaker->response_read_closure); - gpr_mu_unlock(&handshaker->mu); + grpc_endpoint_read(handshaker->args_->endpoint, + handshaker->args_->read_buffer, + &handshaker->response_read_closure_, /*urgent=*/true); + gpr_mu_unlock(&handshaker->mu_); } } // Callback invoked for reading HTTP CONNECT response. -static void on_read_done(void* arg, grpc_error* error) { - http_connect_handshaker* handshaker = - static_cast(arg); - gpr_mu_lock(&handshaker->mu); - if (error != GRPC_ERROR_NONE || handshaker->shutdown) { +void HttpConnectHandshaker::OnReadDone(void* arg, grpc_error* error) { + auto* handshaker = static_cast(arg); + + gpr_mu_lock(&handshaker->mu_); + if (error != GRPC_ERROR_NONE || handshaker->is_shutdown_) { // If the read failed or we're shutting down, clean up and invoke the // callback with the error. - handshake_failed_locked(handshaker, GRPC_ERROR_REF(error)); + handshaker->HandshakeFailedLocked(GRPC_ERROR_REF(error)); goto done; } // Add buffer to parser. - for (size_t i = 0; i < handshaker->args->read_buffer->count; ++i) { - if (GRPC_SLICE_LENGTH(handshaker->args->read_buffer->slices[i]) > 0) { + for (size_t i = 0; i < handshaker->args_->read_buffer->count; ++i) { + if (GRPC_SLICE_LENGTH(handshaker->args_->read_buffer->slices[i]) > 0) { size_t body_start_offset = 0; - error = grpc_http_parser_parse(&handshaker->http_parser, - handshaker->args->read_buffer->slices[i], + error = grpc_http_parser_parse(&handshaker->http_parser_, + handshaker->args_->read_buffer->slices[i], &body_start_offset); if (error != GRPC_ERROR_NONE) { - handshake_failed_locked(handshaker, error); + handshaker->HandshakeFailedLocked(error); goto done; } - if (handshaker->http_parser.state == GRPC_HTTP_BODY) { + if (handshaker->http_parser_.state == GRPC_HTTP_BODY) { // Remove the data we've already read from the read buffer, // leaving only the leftover bytes (if any). grpc_slice_buffer tmp_buffer; grpc_slice_buffer_init(&tmp_buffer); if (body_start_offset < - GRPC_SLICE_LENGTH(handshaker->args->read_buffer->slices[i])) { + GRPC_SLICE_LENGTH(handshaker->args_->read_buffer->slices[i])) { grpc_slice_buffer_add( &tmp_buffer, - grpc_slice_split_tail(&handshaker->args->read_buffer->slices[i], + grpc_slice_split_tail(&handshaker->args_->read_buffer->slices[i], body_start_offset)); } grpc_slice_buffer_addn(&tmp_buffer, - &handshaker->args->read_buffer->slices[i + 1], - handshaker->args->read_buffer->count - i - 1); - grpc_slice_buffer_swap(handshaker->args->read_buffer, &tmp_buffer); + &handshaker->args_->read_buffer->slices[i + 1], + handshaker->args_->read_buffer->count - i - 1); + grpc_slice_buffer_swap(handshaker->args_->read_buffer, &tmp_buffer); grpc_slice_buffer_destroy_internal(&tmp_buffer); break; } @@ -194,64 +203,53 @@ static void on_read_done(void* arg, grpc_error* error) { // need to fix the HTTP parser to understand when the body is // complete (e.g., handling chunked transfer encoding or looking // at the Content-Length: header). - if (handshaker->http_parser.state != GRPC_HTTP_BODY) { - grpc_slice_buffer_reset_and_unref_internal(handshaker->args->read_buffer); - grpc_endpoint_read(handshaker->args->endpoint, - handshaker->args->read_buffer, - &handshaker->response_read_closure); - gpr_mu_unlock(&handshaker->mu); + if (handshaker->http_parser_.state != GRPC_HTTP_BODY) { + grpc_slice_buffer_reset_and_unref_internal(handshaker->args_->read_buffer); + grpc_endpoint_read(handshaker->args_->endpoint, + handshaker->args_->read_buffer, + &handshaker->response_read_closure_, /*urgent=*/true); + gpr_mu_unlock(&handshaker->mu_); return; } // Make sure we got a 2xx response. - if (handshaker->http_response.status < 200 || - handshaker->http_response.status >= 300) { + if (handshaker->http_response_.status < 200 || + handshaker->http_response_.status >= 300) { char* msg; gpr_asprintf(&msg, "HTTP proxy returned response code %d", - handshaker->http_response.status); + handshaker->http_response_.status); error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); gpr_free(msg); - handshake_failed_locked(handshaker, error); + handshaker->HandshakeFailedLocked(error); goto done; } // Success. Invoke handshake-done callback. - GRPC_CLOSURE_SCHED(handshaker->on_handshake_done, error); + GRPC_CLOSURE_SCHED(handshaker->on_handshake_done_, error); done: // Set shutdown to true so that subsequent calls to // http_connect_handshaker_shutdown() do nothing. - handshaker->shutdown = true; - gpr_mu_unlock(&handshaker->mu); - http_connect_handshaker_unref(handshaker); + handshaker->is_shutdown_ = true; + gpr_mu_unlock(&handshaker->mu_); + handshaker->Unref(); } // // Public handshaker methods // -static void http_connect_handshaker_destroy(grpc_handshaker* handshaker_in) { - http_connect_handshaker* handshaker = - reinterpret_cast(handshaker_in); - http_connect_handshaker_unref(handshaker); -} - -static void http_connect_handshaker_shutdown(grpc_handshaker* handshaker_in, - grpc_error* why) { - http_connect_handshaker* handshaker = - reinterpret_cast(handshaker_in); - gpr_mu_lock(&handshaker->mu); - if (!handshaker->shutdown) { - handshaker->shutdown = true; - grpc_endpoint_shutdown(handshaker->args->endpoint, GRPC_ERROR_REF(why)); - cleanup_args_for_failure_locked(handshaker); +void HttpConnectHandshaker::Shutdown(grpc_error* why) { + gpr_mu_lock(&mu_); + if (!is_shutdown_) { + is_shutdown_ = true; + grpc_endpoint_shutdown(args_->endpoint, GRPC_ERROR_REF(why)); + CleanupArgsForFailureLocked(); } - gpr_mu_unlock(&handshaker->mu); + gpr_mu_unlock(&mu_); GRPC_ERROR_UNREF(why); } -static void http_connect_handshaker_do_handshake( - grpc_handshaker* handshaker_in, grpc_tcp_server_acceptor* acceptor, - grpc_closure* on_handshake_done, grpc_handshaker_args* args) { - http_connect_handshaker* handshaker = - reinterpret_cast(handshaker_in); +void HttpConnectHandshaker::DoHandshake(grpc_tcp_server_acceptor* acceptor, + grpc_closure* on_handshake_done, + HandshakerArgs* args) { // Check for HTTP CONNECT channel arg. // If not found, invoke on_handshake_done without doing anything. const grpc_arg* arg = @@ -260,9 +258,9 @@ static void http_connect_handshaker_do_handshake( if (server_name == nullptr) { // Set shutdown to true so that subsequent calls to // http_connect_handshaker_shutdown() do nothing. - gpr_mu_lock(&handshaker->mu); - handshaker->shutdown = true; - gpr_mu_unlock(&handshaker->mu); + gpr_mu_lock(&mu_); + is_shutdown_ = true; + gpr_mu_unlock(&mu_); GRPC_CLOSURE_SCHED(on_handshake_done, GRPC_ERROR_NONE); return; } @@ -280,6 +278,7 @@ static void http_connect_handshaker_do_handshake( gpr_malloc(sizeof(grpc_http_header) * num_header_strings)); for (size_t i = 0; i < num_header_strings; ++i) { char* sep = strchr(header_strings[i], ':'); + if (sep == nullptr) { gpr_log(GPR_ERROR, "skipping unparseable HTTP CONNECT header: %s", header_strings[i]); @@ -292,9 +291,9 @@ static void http_connect_handshaker_do_handshake( } } // Save state in the handshaker object. - gpr_mu_lock(&handshaker->mu); - handshaker->args = args; - handshaker->on_handshake_done = on_handshake_done; + MutexLock lock(&mu_); + args_ = args; + on_handshake_done_ = on_handshake_done; // Log connection via proxy. char* proxy_name = grpc_endpoint_get_peer(args->endpoint); gpr_log(GPR_INFO, "Connecting to server %s via HTTP proxy %s", server_name, @@ -302,15 +301,18 @@ static void http_connect_handshaker_do_handshake( gpr_free(proxy_name); // Construct HTTP CONNECT request. grpc_httpcli_request request; - memset(&request, 0, sizeof(request)); request.host = server_name; + request.ssl_host_override = nullptr; request.http.method = (char*)"CONNECT"; request.http.path = server_name; + request.http.version = GRPC_HTTP_HTTP10; // Set by OnReadDone request.http.hdrs = headers; request.http.hdr_count = num_headers; + request.http.body_length = 0; + request.http.body = nullptr; request.handshaker = &grpc_httpcli_plaintext; grpc_slice request_slice = grpc_httpcli_format_connect_request(&request); - grpc_slice_buffer_add(&handshaker->write_buffer, request_slice); + grpc_slice_buffer_add(&write_buffer_, request_slice); // Clean up. gpr_free(headers); for (size_t i = 0; i < num_header_strings; ++i) { @@ -318,54 +320,42 @@ static void http_connect_handshaker_do_handshake( } gpr_free(header_strings); // Take a new ref to be held by the write callback. - gpr_ref(&handshaker->refcount); - grpc_endpoint_write(args->endpoint, &handshaker->write_buffer, - &handshaker->request_done_closure, nullptr); - gpr_mu_unlock(&handshaker->mu); + Ref().release(); + grpc_endpoint_write(args->endpoint, &write_buffer_, &request_done_closure_, + nullptr); } -static const grpc_handshaker_vtable http_connect_handshaker_vtable = { - http_connect_handshaker_destroy, http_connect_handshaker_shutdown, - http_connect_handshaker_do_handshake, "http_connect"}; - -static grpc_handshaker* grpc_http_connect_handshaker_create() { - http_connect_handshaker* handshaker = - static_cast(gpr_malloc(sizeof(*handshaker))); - memset(handshaker, 0, sizeof(*handshaker)); - grpc_handshaker_init(&http_connect_handshaker_vtable, &handshaker->base); - gpr_mu_init(&handshaker->mu); - gpr_ref_init(&handshaker->refcount, 1); - grpc_slice_buffer_init(&handshaker->write_buffer); - GRPC_CLOSURE_INIT(&handshaker->request_done_closure, on_write_done, - handshaker, grpc_schedule_on_exec_ctx); - GRPC_CLOSURE_INIT(&handshaker->response_read_closure, on_read_done, - handshaker, grpc_schedule_on_exec_ctx); - grpc_http_parser_init(&handshaker->http_parser, GRPC_HTTP_RESPONSE, - &handshaker->http_response); - return &handshaker->base; +HttpConnectHandshaker::HttpConnectHandshaker() { + gpr_mu_init(&mu_); + grpc_slice_buffer_init(&write_buffer_); + GRPC_CLOSURE_INIT(&request_done_closure_, &HttpConnectHandshaker::OnWriteDone, + this, grpc_schedule_on_exec_ctx); + GRPC_CLOSURE_INIT(&response_read_closure_, &HttpConnectHandshaker::OnReadDone, + this, grpc_schedule_on_exec_ctx); + grpc_http_parser_init(&http_parser_, GRPC_HTTP_RESPONSE, &http_response_); } // // handshaker factory // -static void handshaker_factory_add_handshakers( - grpc_handshaker_factory* factory, const grpc_channel_args* args, - grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr) { - grpc_handshake_manager_add(handshake_mgr, - grpc_http_connect_handshaker_create()); -} +class HttpConnectHandshakerFactory : public HandshakerFactory { + public: + void AddHandshakers(const grpc_channel_args* args, + grpc_pollset_set* interested_parties, + HandshakeManager* handshake_mgr) override { + handshake_mgr->Add(MakeRefCounted()); + } + ~HttpConnectHandshakerFactory() override = default; +}; -static void handshaker_factory_destroy(grpc_handshaker_factory* factory) {} +} // namespace -static const grpc_handshaker_factory_vtable handshaker_factory_vtable = { - handshaker_factory_add_handshakers, handshaker_factory_destroy}; - -static grpc_handshaker_factory handshaker_factory = { - &handshaker_factory_vtable}; +} // namespace grpc_core void grpc_http_connect_register_handshaker_factory() { - grpc_handshaker_factory_register(true /* at_start */, HANDSHAKER_CLIENT, - &handshaker_factory); + using namespace grpc_core; + HandshakerRegistry::RegisterHandshakerFactory( + true /* at_start */, HANDSHAKER_CLIENT, + UniquePtr(New())); } diff --git a/src/core/ext/filters/client_channel/http_connect_handshaker.h b/src/core/ext/filters/client_channel/http_connect_handshaker.h index 928a23dc936..26c31f2a0ab 100644 --- a/src/core/ext/filters/client_channel/http_connect_handshaker.h +++ b/src/core/ext/filters/client_channel/http_connect_handshaker.h @@ -25,7 +25,7 @@ /// Channel arg indicating HTTP CONNECT headers (string). /// Multiple headers are separated by newlines. Key/value pairs are -/// seperated by colons. +/// separated by colons. #define GRPC_ARG_HTTP_CONNECT_HEADERS "grpc.http_connect_headers" /// Registers handshaker factory. diff --git a/src/core/ext/filters/client_channel/lb_policy.cc b/src/core/ext/filters/client_channel/lb_policy.cc index e065f45639b..6fa799343ca 100644 --- a/src/core/ext/filters/client_channel/lb_policy.cc +++ b/src/core/ext/filters/client_channel/lb_policy.cc @@ -19,41 +19,120 @@ #include #include "src/core/ext/filters/client_channel/lb_policy.h" -#include "src/core/lib/iomgr/combiner.h" -grpc_core::DebugOnlyTraceFlag grpc_trace_lb_policy_refcount( - false, "lb_policy_refcount"); +#include "src/core/ext/filters/client_channel/lb_policy_registry.h" +#include "src/core/lib/iomgr/combiner.h" namespace grpc_core { -LoadBalancingPolicy::LoadBalancingPolicy(const Args& args) - : InternallyRefCountedWithTracing(&grpc_trace_lb_policy_refcount), +DebugOnlyTraceFlag grpc_trace_lb_policy_refcount(false, "lb_policy_refcount"); + +// +// LoadBalancingPolicy +// + +LoadBalancingPolicy::LoadBalancingPolicy(Args args, intptr_t initial_refcount) + : InternallyRefCounted(&grpc_trace_lb_policy_refcount, initial_refcount), combiner_(GRPC_COMBINER_REF(args.combiner, "lb_policy")), - client_channel_factory_(args.client_channel_factory), interested_parties_(grpc_pollset_set_create()), - request_reresolution_(nullptr) {} + channel_control_helper_(std::move(args.channel_control_helper)) {} LoadBalancingPolicy::~LoadBalancingPolicy() { grpc_pollset_set_destroy(interested_parties_); GRPC_COMBINER_UNREF(combiner_, "lb_policy"); } -void LoadBalancingPolicy::TryReresolutionLocked( - grpc_core::TraceFlag* grpc_lb_trace, grpc_error* error) { - if (request_reresolution_ != nullptr) { - GRPC_CLOSURE_SCHED(request_reresolution_, error); - request_reresolution_ = nullptr; - if (grpc_lb_trace->enabled()) { - 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_INFO, "%s %p: no available re-resolution closure.", - grpc_lb_trace->name(), this); - } +void LoadBalancingPolicy::Orphan() { + // Invoke ShutdownAndUnrefLocked() inside of the combiner. + // TODO(roth): Is this actually needed? We should already be in the + // combiner here. Note that if we directly call ShutdownLocked(), + // then we can probably remove the hack whereby the helper is + // destroyed at shutdown instead of at destruction. + GRPC_CLOSURE_SCHED( + GRPC_CLOSURE_CREATE(&LoadBalancingPolicy::ShutdownAndUnrefLocked, this, + grpc_combiner_scheduler(combiner_)), + GRPC_ERROR_NONE); +} + +void LoadBalancingPolicy::ShutdownAndUnrefLocked(void* arg, + grpc_error* ignored) { + LoadBalancingPolicy* policy = static_cast(arg); + policy->ShutdownLocked(); + policy->channel_control_helper_.reset(); + policy->Unref(); +} + +// +// LoadBalancingPolicy::UpdateArgs +// + +LoadBalancingPolicy::UpdateArgs::UpdateArgs(const UpdateArgs& other) { + addresses = other.addresses; + config = other.config; + args = grpc_channel_args_copy(other.args); +} + +LoadBalancingPolicy::UpdateArgs::UpdateArgs(UpdateArgs&& other) { + addresses = std::move(other.addresses); + config = std::move(other.config); + // TODO(roth): Use std::move() once channel args is converted to C++. + args = other.args; + other.args = nullptr; +} + +LoadBalancingPolicy::UpdateArgs& LoadBalancingPolicy::UpdateArgs::operator=( + const UpdateArgs& other) { + addresses = other.addresses; + config = other.config; + grpc_channel_args_destroy(args); + args = grpc_channel_args_copy(other.args); + return *this; +} + +LoadBalancingPolicy::UpdateArgs& LoadBalancingPolicy::UpdateArgs::operator=( + UpdateArgs&& other) { + addresses = std::move(other.addresses); + config = std::move(other.config); + // TODO(roth): Use std::move() once channel args is converted to C++. + grpc_channel_args_destroy(args); + args = other.args; + other.args = nullptr; + return *this; +} + +// +// LoadBalancingPolicy::QueuePicker +// + +LoadBalancingPolicy::PickResult LoadBalancingPolicy::QueuePicker::Pick( + PickArgs* pick, grpc_error** error) { + // We invoke the parent's ExitIdleLocked() via a closure instead + // of doing it directly here, for two reasons: + // 1. ExitIdleLocked() may cause the policy's state to change and + // a new picker to be delivered to the channel. If that new + // picker is delivered before ExitIdleLocked() returns, then by + // the time this function returns, the pick will already have + // been processed, and we'll be trying to re-process the same + // pick again, leading to a crash. + // 2. We are currently running in the data plane combiner, but we + // need to bounce into the control plane combiner to call + // ExitIdleLocked(). + if (!exit_idle_called_) { + exit_idle_called_ = true; + parent_->Ref().release(); // ref held by closure. + GRPC_CLOSURE_SCHED( + GRPC_CLOSURE_CREATE(&CallExitIdle, parent_.get(), + grpc_combiner_scheduler(parent_->combiner())), + GRPC_ERROR_NONE); } + return PICK_QUEUE; +} + +void LoadBalancingPolicy::QueuePicker::CallExitIdle(void* arg, + grpc_error* error) { + LoadBalancingPolicy* parent = static_cast(arg); + parent->ExitIdleLocked(); + parent->Unref(); } } // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h index 6733fdca814..2ac7df63b7d 100644 --- a/src/core/ext/filters/client_channel/lb_policy.h +++ b/src/core/ext/filters/client_channel/lb_policy.h @@ -22,7 +22,8 @@ #include #include "src/core/ext/filters/client_channel/client_channel_channelz.h" -#include "src/core/ext/filters/client_channel/client_channel_factory.h" +#include "src/core/ext/filters/client_channel/server_address.h" +#include "src/core/ext/filters/client_channel/service_config.h" #include "src/core/ext/filters/client_channel/subchannel.h" #include "src/core/lib/gprpp/abstract.h" #include "src/core/lib/gprpp/orphanable.h" @@ -35,16 +36,196 @@ extern grpc_core::DebugOnlyTraceFlag grpc_trace_lb_policy_refcount; namespace grpc_core { +/// Interface for parsed forms of load balancing configs found in a service +/// config. +class ParsedLoadBalancingConfig : public RefCounted { + public: + virtual ~ParsedLoadBalancingConfig() = default; + + // Returns the load balancing policy name + virtual const char* name() const GRPC_ABSTRACT; + + GRPC_ABSTRACT_BASE_CLASS; +}; + /// Interface for load balancing policies. /// +/// The following concepts are used here: +/// +/// Channel: An abstraction that manages connections to backend servers +/// on behalf of a client application. The application creates a channel +/// for a given server name and then sends RPCs on it, and the channel +/// figures out which backend server to send each RPC to. A channel +/// contains a resolver, a load balancing policy (or a tree of LB policies), +/// and a set of one or more subchannels. +/// +/// Subchannel: A subchannel represents a connection to one backend server. +/// The LB policy decides which subchannels to create, manages the +/// connectivity state of those subchannels, and decides which subchannel +/// to send any given RPC to. +/// +/// Resolver: A plugin that takes a gRPC server URI and resolves it to a +/// list of one or more addresses and a service config, as described +/// in https://github.com/grpc/grpc/blob/master/doc/naming.md. See +/// resolver.h for the resolver API. +/// +/// Load Balancing (LB) Policy: A plugin that takes a list of addresses +/// from the resolver, maintains and manages a subchannel for each +/// backend address, and decides which subchannel to send each RPC on. +/// An LB policy has two parts: +/// - A LoadBalancingPolicy, which deals with the control plane work of +/// managing subchannels. +/// - A SubchannelPicker, which handles the data plane work of +/// determining which subchannel a given RPC should be sent on. + +/// LoadBalacingPolicy API. +/// /// Note: All methods with a "Locked" suffix must be called from the /// combiner passed to the constructor. /// /// Any I/O done by the LB policy should be done under the pollset_set /// returned by \a interested_parties(). -class LoadBalancingPolicy - : public InternallyRefCountedWithTracing { +// TODO(roth): Once we move to EventManager-based polling, remove the +// interested_parties() hooks from the API. +class LoadBalancingPolicy : public InternallyRefCounted { public: + /// Arguments used when picking a subchannel for an RPC. + struct PickArgs { + /// + /// Input parameters. + /// + /// Initial metadata associated with the picking call. + /// The LB policy may use the existing metadata to influence its routing + /// decision, and it may add new metadata elements to be sent with the + /// call to the chosen backend. + // TODO(roth): Provide a more generic metadata API here. + grpc_metadata_batch* initial_metadata = nullptr; + /// Storage for LB token in \a initial_metadata, or nullptr if not used. + // TODO(roth): Remove this from the API. Maybe have the LB policy + // allocate this on the arena instead? + grpc_linked_mdelem lb_token_mdelem_storage; + /// + /// Output parameters. + /// + /// Will be set to the selected subchannel, or nullptr on failure or when + /// the LB policy decides to drop the call. + RefCountedPtr connected_subchannel; + /// Callback set by lb policy to be notified of trailing metadata. + /// The callback must be scheduled on grpc_schedule_on_exec_ctx. + // TODO(roth): Provide a cleaner callback API. + grpc_closure* recv_trailing_metadata_ready = nullptr; + /// The address that will be set to point to the original + /// recv_trailing_metadata_ready callback, to be invoked by the LB + /// policy's recv_trailing_metadata_ready callback when complete. + /// Must be non-null if recv_trailing_metadata_ready is non-null. + // TODO(roth): Consider making the recv_trailing_metadata closure a + // synchronous callback, in which case it is not responsible for + // chaining to the next callback, so this can be removed from the API. + grpc_closure** original_recv_trailing_metadata_ready = nullptr; + /// If this is not nullptr, then the client channel will point it to the + /// call's trailing metadata before invoking recv_trailing_metadata_ready. + /// If this is nullptr, then the callback will still be called. + /// The lb does not have ownership of the metadata. + // TODO(roth): If we make this a synchronous callback, then this can + // be passed to the callback as a parameter and can be removed from + // the API here. + grpc_metadata_batch** recv_trailing_metadata = nullptr; + }; + + /// The result of picking a subchannel for an RPC. + enum PickResult { + // Pick complete. If connected_subchannel is non-null, client channel + // can immediately proceed with the call on connected_subchannel; + // otherwise, call should be dropped. + PICK_COMPLETE, + // Pick cannot be completed until something changes on the control + // plane. Client channel will queue the pick and try again the + // next time the picker is updated. + PICK_QUEUE, + // LB policy is in transient failure. If the pick is wait_for_ready, + // client channel will wait for the next picker and try again; + // otherwise, the call will be failed immediately (although it may + // be retried if the client channel is configured to do so). + // The Pick() method will set its error parameter if this value is + // returned. + PICK_TRANSIENT_FAILURE, + }; + + /// A subchannel picker is the object used to pick the subchannel to + /// use for a given RPC. + /// + /// Pickers are intended to encapsulate all of the state and logic + /// needed on the data plane (i.e., to actually process picks for + /// individual RPCs sent on the channel) while excluding all of the + /// state and logic needed on the control plane (i.e., resolver + /// updates, connectivity state notifications, etc); the latter should + /// live in the LB policy object itself. + /// + /// Currently, pickers are always accessed from within the + /// client_channel combiner, so they do not have to be thread-safe. + // TODO(roth): In a subsequent PR, split the data plane work (i.e., + // the interaction with the picker) and the control plane work (i.e., + // the interaction with the LB policy) into two different + // synchronization mechanisms, to avoid lock contention between the two. + class SubchannelPicker { + public: + SubchannelPicker() = default; + virtual ~SubchannelPicker() = default; + + virtual PickResult Pick(PickArgs* pick, grpc_error** error) GRPC_ABSTRACT; + + GRPC_ABSTRACT_BASE_CLASS + }; + + /// A proxy object used by the LB policy to communicate with the client + /// channel. + // TODO(juanlishen): Consider adding a mid-layer subclass that helps handle + // things like swapping in pending policy when it's ready. Currently, we are + // duplicating the logic in many subclasses. + class ChannelControlHelper { + public: + ChannelControlHelper() = default; + virtual ~ChannelControlHelper() = default; + + /// Creates a new subchannel with the specified channel args. + virtual Subchannel* CreateSubchannel(const grpc_channel_args& args) + GRPC_ABSTRACT; + + /// Creates a channel with the specified target and channel args. + /// This can be used in cases where the LB policy needs to create a + /// channel for its own use (e.g., to talk to an external load balancer). + virtual grpc_channel* CreateChannel( + const char* target, const grpc_channel_args& args) GRPC_ABSTRACT; + + /// Sets the connectivity state and returns a new picker to be used + /// by the client channel. + virtual void UpdateState(grpc_connectivity_state state, + UniquePtr) GRPC_ABSTRACT; + + /// Requests that the resolver re-resolve. + virtual void RequestReresolution() GRPC_ABSTRACT; + + GRPC_ABSTRACT_BASE_CLASS + }; + + /// Data passed to the UpdateLocked() method when new addresses and + /// config are available. + struct UpdateArgs { + ServerAddressList addresses; + RefCountedPtr config; + const grpc_channel_args* args = nullptr; + + // TODO(roth): Remove everything below once channel args is + // converted to a copyable and movable C++ object. + UpdateArgs() = default; + ~UpdateArgs() { grpc_channel_args_destroy(args); } + UpdateArgs(const UpdateArgs& other); + UpdateArgs(UpdateArgs&& other); + UpdateArgs& operator=(const UpdateArgs& other); + UpdateArgs& operator=(UpdateArgs&& other); + }; + + /// Args used to instantiate an LB policy. struct Args { /// The combiner under which all LB policy calls will be run. /// Policy does NOT take ownership of the reference to the combiner. @@ -52,171 +233,118 @@ class LoadBalancingPolicy // API should change to take a smart pointer that does pass ownership // of a reference. grpc_combiner* combiner = nullptr; - /// Used to create channels and subchannels. - grpc_client_channel_factory* client_channel_factory = nullptr; - /// Channel args from the resolver. - /// Note that the LB policy gets the set of addresses from the - /// GRPC_ARG_LB_ADDRESSES channel arg. - grpc_channel_args* args = nullptr; - /// Load balancing config from the resolver. - grpc_json* lb_config = nullptr; + /// Channel control helper. + /// Note: LB policies MUST NOT call any method on the helper from + /// their constructor. + UniquePtr channel_control_helper; + /// Channel args. + // TODO(roth): Find a better channel args representation for this API. + const grpc_channel_args* args = nullptr; }; - /// State used for an LB pick. - struct PickState { - /// Initial metadata associated with the picking call. - grpc_metadata_batch* initial_metadata = nullptr; - /// Bitmask used for selective cancelling. See - /// \a CancelMatchingPicksLocked() and \a GRPC_INITIAL_METADATA_* in - /// grpc_types.h. - uint32_t initial_metadata_flags = 0; - /// Storage for LB token in \a initial_metadata, or nullptr if not used. - grpc_linked_mdelem lb_token_mdelem_storage; - /// Closure to run when pick is complete, if not completed synchronously. - /// If null, pick will fail if a result is not available synchronously. - grpc_closure* on_complete = nullptr; - /// Will be set to the selected subchannel, or nullptr on failure or when - /// the LB policy decides to drop the call. - RefCountedPtr connected_subchannel; - /// Will be populated with context to pass to the subchannel call, if - /// needed. - grpc_call_context_element subchannel_call_context[GRPC_CONTEXT_COUNT] = {}; - /// Upon success, \a *user_data will be set to whatever opaque information - /// may need to be propagated from the LB policy, or nullptr if not needed. - // TODO(roth): As part of revamping our metadata APIs, try to find a - // way to clean this up and C++-ify it. - void** user_data = nullptr; - /// Next pointer. For internal use by LB policy. - PickState* next = nullptr; - }; + explicit LoadBalancingPolicy(Args args, intptr_t initial_refcount = 1); + virtual ~LoadBalancingPolicy(); // Not copyable nor movable. LoadBalancingPolicy(const LoadBalancingPolicy&) = delete; LoadBalancingPolicy& operator=(const LoadBalancingPolicy&) = delete; - /// Updates the policy with a new set of \a args and a new \a lb_config from - /// the resolver. Note that the LB policy gets the set of addresses from the - /// GRPC_ARG_LB_ADDRESSES channel arg. - virtual void UpdateLocked(const grpc_channel_args& args, - grpc_json* lb_config) GRPC_ABSTRACT; + /// Returns the name of the LB policy. + virtual const char* name() const GRPC_ABSTRACT; - /// Finds an appropriate subchannel for a call, based on data in \a pick. - /// \a pick must remain alive until the pick is complete. - /// - /// If a result is known immediately, returns true, setting \a *error - /// upon failure. Otherwise, \a pick->on_complete will be invoked once - /// the pick is complete with its error argument set to indicate success - /// or failure. - /// - /// If \a pick->on_complete is null and no result is known immediately, - /// a synchronous failure will be returned (i.e., \a *error will be - /// set and true will be returned). - virtual bool PickLocked(PickState* pick, grpc_error** error) GRPC_ABSTRACT; - - /// Cancels \a pick. - /// The \a on_complete callback of the pending pick will be invoked with - /// \a pick->connected_subchannel set to null. - virtual void CancelPickLocked(PickState* pick, - grpc_error* error) GRPC_ABSTRACT; - - /// Cancels all pending picks for which their \a initial_metadata_flags (as - /// given in the call to \a PickLocked()) matches - /// \a initial_metadata_flags_eq when ANDed with - /// \a initial_metadata_flags_mask. - virtual void CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask, - uint32_t initial_metadata_flags_eq, - grpc_error* error) GRPC_ABSTRACT; - - /// Requests a notification when the connectivity state of the policy - /// changes from \a *state. When that happens, sets \a *state to the - /// new state and schedules \a closure. - virtual void NotifyOnStateChangeLocked(grpc_connectivity_state* state, - grpc_closure* closure) GRPC_ABSTRACT; - - /// Returns the policy's current connectivity state. Sets \a error to - /// the associated error, if any. - virtual grpc_connectivity_state CheckConnectivityLocked( - grpc_error** connectivity_error) GRPC_ABSTRACT; - - /// Hands off pending picks to \a new_policy. - virtual void HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) - GRPC_ABSTRACT; + /// Updates the policy with new data from the resolver. Will be invoked + /// immediately after LB policy is constructed, and then again whenever + /// the resolver returns a new result. + virtual void UpdateLocked(UpdateArgs) GRPC_ABSTRACT; // NOLINT /// Tries to enter a READY connectivity state. - /// TODO(roth): As part of restructuring how we handle IDLE state, - /// consider whether this method is still needed. - virtual void ExitIdleLocked() GRPC_ABSTRACT; + /// This is a no-op by default, since most LB policies never go into + /// IDLE state. + virtual void ExitIdleLocked() {} /// Resets connection backoff. virtual void ResetBackoffLocked() GRPC_ABSTRACT; /// Populates child_subchannels and child_channels with the uuids of this - /// LB policy's referenced children. This is not invoked from the - /// client_channel's combiner. The implementation is responsible for - /// providing its own synchronization. + /// LB policy's referenced children. + /// + /// This is not invoked from the client_channel's combiner. The + /// implementation is responsible for providing its own synchronization. virtual void FillChildRefsForChannelz( channelz::ChildRefsList* child_subchannels, channelz::ChildRefsList* child_channels) GRPC_ABSTRACT; - void Orphan() override { - // Invoke ShutdownAndUnrefLocked() inside of the combiner. - GRPC_CLOSURE_SCHED( - GRPC_CLOSURE_CREATE(&LoadBalancingPolicy::ShutdownAndUnrefLocked, this, - grpc_combiner_scheduler(combiner_)), - GRPC_ERROR_NONE); - } - - /// Sets the re-resolution closure to \a request_reresolution. - void SetReresolutionClosureLocked(grpc_closure* request_reresolution) { - GPR_ASSERT(request_reresolution_ == nullptr); - request_reresolution_ = request_reresolution; + void set_channelz_node( + RefCountedPtr channelz_node) { + channelz_node_ = std::move(channelz_node); } grpc_pollset_set* interested_parties() const { return interested_parties_; } + void Orphan() override; + + // A picker that returns PICK_QUEUE for all picks. + // Also calls the parent LB policy's ExitIdleLocked() method when the + // first pick is seen. + class QueuePicker : public SubchannelPicker { + public: + explicit QueuePicker(RefCountedPtr parent) + : parent_(std::move(parent)) {} + + PickResult Pick(PickArgs* pick, grpc_error** error) override; + + private: + static void CallExitIdle(void* arg, grpc_error* error); + + RefCountedPtr parent_; + bool exit_idle_called_ = false; + }; + + // A picker that returns PICK_TRANSIENT_FAILURE for all picks. + class TransientFailurePicker : public SubchannelPicker { + public: + explicit TransientFailurePicker(grpc_error* error) : error_(error) {} + ~TransientFailurePicker() override { GRPC_ERROR_UNREF(error_); } + + PickResult Pick(PickArgs* pick, grpc_error** error) override { + *error = GRPC_ERROR_REF(error_); + return PICK_TRANSIENT_FAILURE; + } + + private: + grpc_error* error_; + }; + GRPC_ABSTRACT_BASE_CLASS protected: - GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE - - explicit LoadBalancingPolicy(const Args& args); - virtual ~LoadBalancingPolicy(); - grpc_combiner* combiner() const { return combiner_; } - grpc_client_channel_factory* client_channel_factory() const { - return client_channel_factory_; + + // Note: LB policies MUST NOT call any method on the helper from their + // constructor. + // Note: This will return null after ShutdownLocked() has been called. + ChannelControlHelper* channel_control_helper() const { + return channel_control_helper_.get(); } - /// Shuts down the policy. Any pending picks that have not been - /// handed off to a new policy via HandOffPendingPicksLocked() will be - /// failed. + channelz::ClientChannelNode* channelz_node() const { + return channelz_node_.get(); + } + + /// Shuts down the policy. virtual void ShutdownLocked() GRPC_ABSTRACT; - /// Tries to request a re-resolution. - void TryReresolutionLocked(grpc_core::TraceFlag* grpc_lb_trace, - grpc_error* error); - private: - static void ShutdownAndUnrefLocked(void* arg, grpc_error* ignored) { - LoadBalancingPolicy* policy = static_cast(arg); - policy->ShutdownLocked(); - policy->Unref(); - } + static void ShutdownAndUnrefLocked(void* arg, grpc_error* ignored); /// Combiner under which LB policy actions take place. grpc_combiner* combiner_; - /// Client channel factory, used to create channels and subchannels. - grpc_client_channel_factory* client_channel_factory_; /// Owned pointer to interested parties in load balancing decisions. grpc_pollset_set* interested_parties_; - /// Callback to force a re-resolution. - grpc_closure* request_reresolution_; - - // Dummy classes needed for alignment issues. - // See https://github.com/grpc/grpc/issues/16032 for context. - // TODO(ncteisen): remove this as soon as the issue is resolved. - channelz::ChildRefsList dummy_list_foo; - channelz::ChildRefsList dummy_list_bar; + /// Channel control helper. + UniquePtr channel_control_helper_; + /// Channelz node. + RefCountedPtr channelz_node_; }; } // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc index 399bb452f45..3bb31fe3b08 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc @@ -37,17 +37,6 @@ static void destroy_channel_elem(grpc_channel_element* elem) {} namespace { struct call_data { - call_data(const grpc_call_element_args& args) { - if (args.context[GRPC_GRPCLB_CLIENT_STATS].value != nullptr) { - // Get stats object from context and take a ref. - client_stats = static_cast( - args.context[GRPC_GRPCLB_CLIENT_STATS].value) - ->Ref(); - // Record call started. - client_stats->AddCallStarted(); - } - } - // Stats object to update. grpc_core::RefCountedPtr client_stats; // State for intercepting send_initial_metadata. @@ -82,7 +71,7 @@ static void recv_initial_metadata_ready(void* arg, grpc_error* error) { static grpc_error* init_call_elem(grpc_call_element* elem, const grpc_call_element_args* args) { GPR_ASSERT(args->context != nullptr); - new (elem->call_data) call_data(*args); + new (elem->call_data) call_data(); return GRPC_ERROR_NONE; } @@ -96,9 +85,6 @@ static void destroy_call_elem(grpc_call_element* elem, calld->client_stats->AddCallFinished( !calld->send_initial_metadata_succeeded /* client_failed_to_send */, calld->recv_initial_metadata_succeeded /* known_received */); - // All done, so unref the stats object. - // TODO(roth): Eliminate this once filter stack is converted to C++. - calld->client_stats.reset(); } calld->~call_data(); } @@ -107,25 +93,36 @@ static void start_transport_stream_op_batch( grpc_call_element* elem, grpc_transport_stream_op_batch* batch) { call_data* calld = static_cast(elem->call_data); GPR_TIMER_SCOPE("clr_start_transport_stream_op_batch", 0); - if (calld->client_stats != nullptr) { - // Intercept send_initial_metadata. - if (batch->send_initial_metadata) { - calld->original_on_complete_for_send = batch->on_complete; - GRPC_CLOSURE_INIT(&calld->on_complete_for_send, on_complete_for_send, - calld, grpc_schedule_on_exec_ctx); - batch->on_complete = &calld->on_complete_for_send; - } - // Intercept recv_initial_metadata. - if (batch->recv_initial_metadata) { - calld->original_recv_initial_metadata_ready = - batch->payload->recv_initial_metadata.recv_initial_metadata_ready; - GRPC_CLOSURE_INIT(&calld->recv_initial_metadata_ready, - recv_initial_metadata_ready, calld, - grpc_schedule_on_exec_ctx); - batch->payload->recv_initial_metadata.recv_initial_metadata_ready = - &calld->recv_initial_metadata_ready; + // Handle send_initial_metadata. + if (batch->send_initial_metadata) { + // Grab client stats object from user_data for LB token metadata. + grpc_linked_mdelem* lb_token = + batch->payload->send_initial_metadata.send_initial_metadata->idx.named + .lb_token; + if (lb_token != nullptr) { + grpc_core::GrpcLbClientStats* client_stats = + static_cast(grpc_mdelem_get_user_data( + lb_token->md, grpc_core::GrpcLbClientStats::Destroy)); + if (client_stats != nullptr) { + calld->client_stats = client_stats->Ref(); + // Intercept completion. + calld->original_on_complete_for_send = batch->on_complete; + GRPC_CLOSURE_INIT(&calld->on_complete_for_send, on_complete_for_send, + calld, grpc_schedule_on_exec_ctx); + batch->on_complete = &calld->on_complete_for_send; + } } } + // Intercept completion of recv_initial_metadata. + if (batch->recv_initial_metadata) { + calld->original_recv_initial_metadata_ready = + batch->payload->recv_initial_metadata.recv_initial_metadata_ready; + GRPC_CLOSURE_INIT(&calld->recv_initial_metadata_ready, + recv_initial_metadata_ready, calld, + grpc_schedule_on_exec_ctx); + batch->payload->recv_initial_metadata.recv_initial_metadata_ready = + &calld->recv_initial_metadata_ready; + } // Chain to next filter. grpc_call_next_op(elem, batch); } 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 dc0e1f89ce6..ed6e8de3f21 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 @@ -26,30 +26,27 @@ /// channel that uses pick_first to select from the list of balancer /// addresses. /// -/// The first time the policy gets a request for a pick, a ping, or to exit -/// the idle state, \a StartPickingLocked() is called. This method is -/// responsible for instantiating the internal *streaming* call to the LB -/// server (whichever address pick_first chose). The call will be complete -/// when either the balancer sends status or when we cancel the call (e.g., -/// because we are shutting down). In needed, we retry the call. If we -/// received at least one valid message from the server, a new call attempt -/// will be made immediately; otherwise, we apply back-off delays between -/// attempts. +/// When we get our initial update, we instantiate the internal *streaming* +/// call to the LB server (whichever address pick_first chose). The call +/// will be complete when either the balancer sends status or when we cancel +/// the call (e.g., because we are shutting down). In needed, we retry the +/// call. If we received at least one valid message from the server, a new +/// call attempt will be made immediately; otherwise, we apply back-off +/// delays between attempts. /// /// We maintain an internal round_robin policy instance for distributing /// requests across backends. Whenever we receive a new serverlist from /// the balancer, we update the round_robin policy with the new list of /// addresses. If we cannot communicate with the balancer on startup, /// however, we may enter fallback mode, in which case we will populate -/// the RR policy's addresses from the backend addresses returned by the +/// the child policy's addresses from the backend addresses returned by the /// resolver. /// -/// Once an RR policy instance is in place (and getting updated as described), +/// Once a child policy instance is in place (and getting updated as described), /// calls for a pick, a ping, or a cancellation will be serviced right -/// away by forwarding them to the RR instance. Any time there's no RR -/// policy available (i.e., right after the creation of the gRPCLB policy), -/// pick and ping requests are added to a list of pending picks and pings -/// to be flushed and serviced when the RR policy instance becomes available. +/// away by forwarding them to the child policy instance. Any time there's no +/// child policy available (i.e., right after the creation of the gRPCLB +/// policy), pick requests are queued. /// /// \see https://github.com/grpc/grpc/blob/master/doc/load-balancing.md for the /// high level design and details. @@ -74,7 +71,6 @@ #include #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" @@ -84,7 +80,7 @@ #include "src/core/ext/filters/client_channel/lb_policy_registry.h" #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h" -#include "src/core/ext/filters/client_channel/subchannel_index.h" +#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/backoff/backoff.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/channel_stack.h" @@ -92,7 +88,6 @@ #include "src/core/lib/gpr/string.h" #include "src/core/lib/gprpp/manual_constructor.h" #include "src/core/lib/gprpp/memory.h" -#include "src/core/lib/gprpp/mutex_lock.h" #include "src/core/lib/gprpp/orphanable.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/combiner.h" @@ -113,66 +108,46 @@ #define GRPC_GRPCLB_RECONNECT_JITTER 0.2 #define GRPC_GRPCLB_DEFAULT_FALLBACK_TIMEOUT_MS 10000 +#define GRPC_ARG_GRPCLB_ADDRESS_LB_TOKEN "grpc.grpclb_address_lb_token" + namespace grpc_core { TraceFlag grpc_lb_glb_trace(false, "glb"); namespace { +constexpr char kGrpclb[] = "grpclb"; + +class ParsedGrpcLbConfig : public ParsedLoadBalancingConfig { + public: + explicit ParsedGrpcLbConfig( + RefCountedPtr child_policy) + : child_policy_(std::move(child_policy)) {} + const char* name() const override { return kGrpclb; } + + RefCountedPtr child_policy() const { + return child_policy_; + } + + private: + RefCountedPtr child_policy_; +}; + class GrpcLb : public LoadBalancingPolicy { public: - GrpcLb(const grpc_lb_addresses* addresses, const Args& args); + explicit GrpcLb(Args args); - void UpdateLocked(const grpc_channel_args& args, - grpc_json* lb_config) override; - bool PickLocked(PickState* pick, grpc_error** error) override; - void CancelPickLocked(PickState* pick, grpc_error* error) override; - void CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask, - uint32_t initial_metadata_flags_eq, - grpc_error* error) override; - void NotifyOnStateChangeLocked(grpc_connectivity_state* state, - grpc_closure* closure) override; - grpc_connectivity_state CheckConnectivityLocked( - grpc_error** connectivity_error) override; - void HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) override; - void ExitIdleLocked() override; + const char* name() const override { return kGrpclb; } + + void UpdateLocked(UpdateArgs args) override; void ResetBackoffLocked() override; void FillChildRefsForChannelz( channelz::ChildRefsList* child_subchannels, channelz::ChildRefsList* child_channels) override; private: - /// Linked list of pending pick requests. It stores all information needed to - /// eventually call (Round Robin's) pick() on them. They mainly stay pending - /// waiting for the RR policy to be created. - /// - /// Note that when a pick is sent to the RR policy, we inject our own - /// on_complete callback, so that we can intercept the result before - /// invoking the original on_complete callback. This allows us to set the - /// LB token metadata and add client_stats to the call context. - /// See \a pending_pick_complete() for details. - struct PendingPick { - // The grpclb instance that created the wrapping. This instance is not - // owned; reference counts are untouched. It's used only for logging - // purposes. - GrpcLb* grpclb_policy; - // The original pick. - PickState* pick; - // Our on_complete closure and the original one. - grpc_closure on_complete; - grpc_closure* original_on_complete; - // The LB token associated with the pick. This is set via user_data in - // the pick. - grpc_mdelem lb_token; - // Stats for client-side load reporting. - RefCountedPtr client_stats; - // Next pending pick. - PendingPick* next = nullptr; - }; - /// Contains a call to the LB server and all the data related to the call. - class BalancerCallState - : public InternallyRefCountedWithTracing { + class BalancerCallState : public InternallyRefCounted { public: explicit BalancerCallState( RefCountedPtr parent_grpclb_policy); @@ -186,6 +161,7 @@ class GrpcLb : public LoadBalancingPolicy { GrpcLbClientStats* client_stats() const { return client_stats_.get(); } bool seen_initial_response() const { return seen_initial_response_; } + bool seen_serverlist() const { return seen_serverlist_; } private: // So Delete() can access our private dtor. @@ -226,6 +202,7 @@ class GrpcLb : public LoadBalancingPolicy { grpc_byte_buffer* recv_message_payload_ = nullptr; grpc_closure lb_on_balancer_message_received_; bool seen_initial_response_ = false; + bool seen_serverlist_ = false; // recv_trailing_metadata grpc_closure lb_on_balancer_status_received_; @@ -246,40 +223,119 @@ class GrpcLb : public LoadBalancingPolicy { grpc_closure client_load_report_closure_; }; + class Serverlist : public RefCounted { + public: + // Takes ownership of serverlist. + explicit Serverlist(grpc_grpclb_serverlist* serverlist) + : serverlist_(serverlist) {} + + ~Serverlist() { grpc_grpclb_destroy_serverlist(serverlist_); } + + bool operator==(const Serverlist& other) const; + + const grpc_grpclb_serverlist* serverlist() const { return serverlist_; } + + // Returns a text representation suitable for logging. + UniquePtr AsText() const; + + // Extracts all non-drop entries into a ServerAddressList. + ServerAddressList GetServerAddressList( + GrpcLbClientStats* client_stats) const; + + // Returns true if the serverlist contains at least one drop entry and + // no backend address entries. + bool ContainsAllDropEntries() const; + + // Returns the LB token to use for a drop, or null if the call + // should not be dropped. + // + // Note: This is called from the picker, so it will be invoked in + // the channel's data plane combiner, NOT the control plane + // combiner. It should not be accessed by any other part of the LB + // policy. + const char* ShouldDrop(); + + private: + grpc_grpclb_serverlist* serverlist_; + + // Guarded by the channel's data plane combiner, NOT the control + // plane combiner. It should not be accessed by anything but the + // picker via the ShouldDrop() method. + size_t drop_index_ = 0; + }; + + class Picker : public SubchannelPicker { + public: + Picker(GrpcLb* parent, RefCountedPtr serverlist, + UniquePtr child_picker, + RefCountedPtr client_stats) + : parent_(parent), + serverlist_(std::move(serverlist)), + child_picker_(std::move(child_picker)), + client_stats_(std::move(client_stats)) {} + + PickResult Pick(PickArgs* pick, grpc_error** error) override; + + private: + // Storing the address for logging, but not holding a ref. + // DO NOT DEFERENCE! + GrpcLb* parent_; + + // Serverlist to be used for determining drops. + RefCountedPtr serverlist_; + + UniquePtr child_picker_; + RefCountedPtr client_stats_; + }; + + class Helper : public ChannelControlHelper { + public: + explicit Helper(RefCountedPtr parent) + : parent_(std::move(parent)) {} + + Subchannel* CreateSubchannel(const grpc_channel_args& args) override; + grpc_channel* CreateChannel(const char* target, + const grpc_channel_args& args) override; + void UpdateState(grpc_connectivity_state state, + UniquePtr picker) override; + void RequestReresolution() override; + + void set_child(LoadBalancingPolicy* child) { child_ = child; } + + private: + bool CalledByPendingChild() const; + bool CalledByCurrentChild() const; + + RefCountedPtr parent_; + LoadBalancingPolicy* child_ = nullptr; + }; + ~GrpcLb(); void ShutdownLocked() override; - // Helper function used in ctor and UpdateLocked(). - void ProcessChannelArgsLocked(const grpc_channel_args& args); - - // Methods for dealing with the balancer channel and call. - void StartPickingLocked(); - void StartBalancerCallLocked(); - static void OnFallbackTimerLocked(void* arg, grpc_error* error); - void StartBalancerCallRetryTimerLocked(); - static void OnBalancerCallRetryTimerLocked(void* arg, grpc_error* error); + // Helper functions used in UpdateLocked(). + void ProcessAddressesAndChannelArgsLocked(const ServerAddressList& addresses, + const grpc_channel_args& args); static void OnBalancerChannelConnectivityChangedLocked(void* arg, grpc_error* error); + void CancelBalancerChannelConnectivityWatchLocked(); - // Pending pick methods. - static void PendingPickSetMetadataAndContext(PendingPick* pp); - PendingPick* PendingPickCreate(PickState* pick); - void AddPendingPick(PendingPick* pp); - static void OnPendingPickComplete(void* arg, grpc_error* error); + // Methods for dealing with fallback state. + void MaybeEnterFallbackModeAfterStartup(); + static void OnFallbackTimerLocked(void* arg, grpc_error* error); - // Methods for dealing with the RR policy. - void CreateOrUpdateRoundRobinPolicyLocked(); - grpc_channel_args* CreateRoundRobinPolicyArgsLocked(); - void CreateRoundRobinPolicyLocked(const Args& args); - bool PickFromRoundRobinPolicyLocked(bool force_async, PendingPick* pp, - grpc_error** error); - void UpdateConnectivityStateFromRoundRobinPolicyLocked( - grpc_error* rr_state_error); - static void OnRoundRobinConnectivityChangedLocked(void* arg, - grpc_error* error); - static void OnRoundRobinRequestReresolutionLocked(void* arg, - grpc_error* error); + // Methods for dealing with the balancer call. + void StartBalancerCallLocked(); + void StartBalancerCallRetryTimerLocked(); + static void OnBalancerCallRetryTimerLocked(void* arg, grpc_error* error); + + // Methods for dealing with the child policy. + grpc_channel_args* CreateChildPolicyArgsLocked( + bool is_backend_from_grpclb_load_balancer); + OrphanablePtr CreateChildPolicyLocked( + const char* name, const grpc_channel_args* args); + void CreateOrUpdateChildPolicyLocked(); // Who the client is trying to communicate with. const char* server_name_ = nullptr; @@ -288,19 +344,12 @@ class GrpcLb : public LoadBalancingPolicy { grpc_channel_args* args_ = nullptr; // Internal state. - bool started_picking_ = false; bool shutting_down_ = false; - grpc_connectivity_state_tracker state_tracker_; // The channel for communicating with the LB server. grpc_channel* lb_channel_ = nullptr; - // Mutex to protect the channel to the LB server. This is used when - // processing a channelz request. - gpr_mu lb_channel_mu_; - grpc_connectivity_state lb_channel_connectivity_; - grpc_closure lb_channel_on_connectivity_changed_; - // Are we already watching the LB channel's connectivity? - bool watching_lb_channel_ = false; + // Uuid of the lb channel. Used for channelz. + gpr_atm lb_channel_uuid_ = 0; // Response generator to inject address updates into lb_channel_. RefCountedPtr response_generator_; @@ -320,101 +369,42 @@ class GrpcLb : public LoadBalancingPolicy { // The deserialized response from the balancer. May be nullptr until one // such response has arrived. - grpc_grpclb_serverlist* serverlist_ = nullptr; - // Index into serverlist for next pick. - // If the server at this index is a drop, we return a drop. - // Otherwise, we delegate to the RR policy. - size_t serverlist_index_ = 0; + RefCountedPtr serverlist_; - // Timeout in milliseconds for before using fallback backend addresses. - // 0 means not using fallback. - int lb_fallback_timeout_ms_ = 0; + // Whether we're in fallback mode. + bool fallback_mode_ = false; // The backend addresses from the resolver. - grpc_lb_addresses* fallback_backend_addresses_ = nullptr; - // Fallback timer. - bool fallback_timer_callback_pending_ = false; + ServerAddressList fallback_backend_addresses_; + // State for fallback-at-startup checks. + // Timeout after startup after which we will go into fallback mode if + // we have not received a serverlist from the balancer. + int fallback_at_startup_timeout_ = 0; + bool fallback_at_startup_checks_pending_ = false; grpc_timer lb_fallback_timer_; grpc_closure lb_on_fallback_; + grpc_connectivity_state lb_channel_connectivity_ = GRPC_CHANNEL_IDLE; + grpc_closure lb_channel_on_connectivity_changed_; - // Pending picks that are waiting on the RR policy's connectivity. - PendingPick* pending_picks_ = nullptr; - - // The RR policy to use for the backends. - OrphanablePtr rr_policy_; - grpc_connectivity_state rr_connectivity_state_; - grpc_closure on_rr_connectivity_changed_; - grpc_closure on_rr_request_reresolution_; + // Lock held when modifying the value of child_policy_ or + // pending_child_policy_. + gpr_mu child_policy_mu_; + // The child policy to use for the backends. + OrphanablePtr child_policy_; + // When switching child policies, the new policy will be stored here + // until it reports READY, at which point it will be moved to child_policy_. + OrphanablePtr pending_child_policy_; + // The child policy config. + RefCountedPtr child_policy_config_; + // Child policy in state READY. + bool child_policy_ready_ = false; }; // -// serverlist parsing code +// GrpcLb::Serverlist // -// vtable for LB tokens in grpc_lb_addresses -void* lb_token_copy(void* token) { - return token == nullptr - ? nullptr - : (void*)GRPC_MDELEM_REF(grpc_mdelem{(uintptr_t)token}).payload; -} -void lb_token_destroy(void* token) { - if (token != nullptr) { - GRPC_MDELEM_UNREF(grpc_mdelem{(uintptr_t)token}); - } -} -int lb_token_cmp(void* token1, void* token2) { - if (token1 > token2) return 1; - if (token1 < token2) return -1; - return 0; -} -const grpc_lb_user_data_vtable lb_token_vtable = { - lb_token_copy, lb_token_destroy, lb_token_cmp}; - -// Returns the backend addresses extracted from the given addresses. -grpc_lb_addresses* ExtractBackendAddresses(const grpc_lb_addresses* addresses) { - // First pass: count the number of backend addresses. - size_t num_backends = 0; - for (size_t i = 0; i < addresses->num_addresses; ++i) { - if (!addresses->addresses[i].is_balancer) { - ++num_backends; - } - } - // Second pass: actually populate the addresses and (empty) LB tokens. - grpc_lb_addresses* backend_addresses = - grpc_lb_addresses_create(num_backends, &lb_token_vtable); - size_t num_copied = 0; - for (size_t i = 0; i < addresses->num_addresses; ++i) { - if (addresses->addresses[i].is_balancer) continue; - const grpc_resolved_address* addr = &addresses->addresses[i].address; - grpc_lb_addresses_set_address(backend_addresses, num_copied, &addr->addr, - addr->len, false /* is_balancer */, - nullptr /* balancer_name */, - (void*)GRPC_MDELEM_LB_TOKEN_EMPTY.payload); - ++num_copied; - } - return backend_addresses; -} - -bool IsServerValid(const grpc_grpclb_server* server, size_t idx, bool log) { - if (server->drop) return false; - const grpc_grpclb_ip_address* ip = &server->ip_address; - if (GPR_UNLIKELY(server->port >> 16 != 0)) { - if (log) { - gpr_log(GPR_ERROR, - "Invalid port '%d' at index %lu of serverlist. Ignoring.", - server->port, (unsigned long)idx); - } - return false; - } - if (GPR_UNLIKELY(ip->size != 4 && ip->size != 16)) { - if (log) { - gpr_log(GPR_ERROR, - "Expected IP to be 4 or 16 bytes, got %d at index %lu of " - "serverlist. Ignoring", - ip->size, (unsigned long)idx); - } - return false; - } - return true; +bool GrpcLb::Serverlist::operator==(const Serverlist& other) const { + return grpc_grpclb_serverlist_equals(serverlist_, other.serverlist_); } void ParseServer(const grpc_grpclb_server* server, @@ -440,31 +430,84 @@ void ParseServer(const grpc_grpclb_server* server, } } -// Returns addresses extracted from \a serverlist. -grpc_lb_addresses* ProcessServerlist(const grpc_grpclb_serverlist* serverlist) { - size_t num_valid = 0; - /* first pass: count how many are valid in order to allocate the necessary - * memory in a single block */ - for (size_t i = 0; i < serverlist->num_servers; ++i) { - if (IsServerValid(serverlist->servers[i], i, true)) ++num_valid; +UniquePtr GrpcLb::Serverlist::AsText() const { + gpr_strvec entries; + gpr_strvec_init(&entries); + for (size_t i = 0; i < serverlist_->num_servers; ++i) { + const auto* server = serverlist_->servers[i]; + char* ipport; + if (server->drop) { + ipport = gpr_strdup("(drop)"); + } else { + grpc_resolved_address addr; + ParseServer(server, &addr); + grpc_sockaddr_to_string(&ipport, &addr, false); + } + char* entry; + gpr_asprintf(&entry, " %" PRIuPTR ": %s token=%s\n", i, ipport, + server->load_balance_token); + gpr_free(ipport); + gpr_strvec_add(&entries, entry); } - grpc_lb_addresses* lb_addresses = - grpc_lb_addresses_create(num_valid, &lb_token_vtable); - /* second pass: actually populate the addresses and LB tokens (aka user data - * to the outside world) to be read by the RR policy during its creation. - * Given that the validity tests are very cheap, they are performed again - * instead of marking the valid ones during the first pass, as this would - * incurr in an allocation due to the arbitrary number of server */ - size_t addr_idx = 0; - for (size_t sl_idx = 0; sl_idx < serverlist->num_servers; ++sl_idx) { - const grpc_grpclb_server* server = serverlist->servers[sl_idx]; - if (!IsServerValid(serverlist->servers[sl_idx], sl_idx, false)) continue; - GPR_ASSERT(addr_idx < num_valid); - /* address processing */ + UniquePtr result(gpr_strvec_flatten(&entries, nullptr)); + gpr_strvec_destroy(&entries); + return result; +} + +// vtable for LB token channel arg. +void* lb_token_copy(void* token) { + return token == nullptr + ? nullptr + : (void*)GRPC_MDELEM_REF(grpc_mdelem{(uintptr_t)token}).payload; +} +void lb_token_destroy(void* token) { + if (token != nullptr) { + GRPC_MDELEM_UNREF(grpc_mdelem{(uintptr_t)token}); + } +} +int lb_token_cmp(void* token1, void* token2) { + // Always indicate a match, since we don't want this channel arg to + // affect the subchannel's key in the index. + return 0; +} +const grpc_arg_pointer_vtable lb_token_arg_vtable = { + lb_token_copy, lb_token_destroy, lb_token_cmp}; + +bool IsServerValid(const grpc_grpclb_server* server, size_t idx, bool log) { + if (server->drop) return false; + const grpc_grpclb_ip_address* ip = &server->ip_address; + if (GPR_UNLIKELY(server->port >> 16 != 0)) { + if (log) { + gpr_log(GPR_ERROR, + "Invalid port '%d' at index %lu of serverlist. Ignoring.", + server->port, (unsigned long)idx); + } + return false; + } + if (GPR_UNLIKELY(ip->size != 4 && ip->size != 16)) { + if (log) { + gpr_log(GPR_ERROR, + "Expected IP to be 4 or 16 bytes, got %d at index %lu of " + "serverlist. Ignoring", + ip->size, (unsigned long)idx); + } + return false; + } + return true; +} + +// Returns addresses extracted from the serverlist. +ServerAddressList GrpcLb::Serverlist::GetServerAddressList( + GrpcLbClientStats* client_stats) const { + ServerAddressList addresses; + for (size_t i = 0; i < serverlist_->num_servers; ++i) { + const grpc_grpclb_server* server = serverlist_->servers[i]; + if (!IsServerValid(serverlist_->servers[i], i, false)) continue; + // Address processing. grpc_resolved_address addr; ParseServer(server, &addr); - /* lb token processing */ - void* user_data; + // LB token processing. + grpc_mdelem lb_token; if (server->has_load_balance_token) { const size_t lb_token_max_length = GPR_ARRAY_SIZE(server->load_balance_token); @@ -472,9 +515,12 @@ grpc_lb_addresses* ProcessServerlist(const grpc_grpclb_serverlist* serverlist) { strnlen(server->load_balance_token, lb_token_max_length); grpc_slice lb_token_mdstr = grpc_slice_from_copied_buffer( server->load_balance_token, lb_token_length); - user_data = - (void*)grpc_mdelem_from_slices(GRPC_MDSTR_LB_TOKEN, lb_token_mdstr) - .payload; + lb_token = grpc_mdelem_from_slices(GRPC_MDSTR_LB_TOKEN, lb_token_mdstr); + if (client_stats != nullptr) { + GPR_ASSERT(grpc_mdelem_set_user_data( + lb_token, GrpcLbClientStats::Destroy, + client_stats->Ref().release()) == client_stats); + } } else { char* uri = grpc_sockaddr_to_uri(&addr); gpr_log(GPR_INFO, @@ -482,15 +528,206 @@ grpc_lb_addresses* ProcessServerlist(const grpc_grpclb_serverlist* serverlist) { "be used instead", uri); gpr_free(uri); - user_data = (void*)GRPC_MDELEM_LB_TOKEN_EMPTY.payload; + lb_token = GRPC_MDELEM_LB_TOKEN_EMPTY; } - grpc_lb_addresses_set_address(lb_addresses, addr_idx, &addr.addr, addr.len, - false /* is_balancer */, - nullptr /* balancer_name */, user_data); - ++addr_idx; + // Add address. + grpc_arg arg = grpc_channel_arg_pointer_create( + const_cast(GRPC_ARG_GRPCLB_ADDRESS_LB_TOKEN), + (void*)lb_token.payload, &lb_token_arg_vtable); + grpc_channel_args* args = grpc_channel_args_copy_and_add(nullptr, &arg, 1); + addresses.emplace_back(addr, args); + // Clean up. + GRPC_MDELEM_UNREF(lb_token); + } + return addresses; +} + +bool GrpcLb::Serverlist::ContainsAllDropEntries() const { + if (serverlist_->num_servers == 0) return false; + for (size_t i = 0; i < serverlist_->num_servers; ++i) { + if (!serverlist_->servers[i]->drop) return false; + } + return true; +} + +const char* GrpcLb::Serverlist::ShouldDrop() { + if (serverlist_->num_servers == 0) return nullptr; + grpc_grpclb_server* server = serverlist_->servers[drop_index_]; + drop_index_ = (drop_index_ + 1) % serverlist_->num_servers; + return server->drop ? server->load_balance_token : nullptr; +} + +// +// GrpcLb::Picker +// + +GrpcLb::PickResult GrpcLb::Picker::Pick(PickArgs* pick, grpc_error** error) { + // Check if we should drop the call. + const char* drop_token = serverlist_->ShouldDrop(); + if (drop_token != nullptr) { + // Update client load reporting stats to indicate the number of + // dropped calls. Note that we have to do this here instead of in + // the client_load_reporting filter, because we do not create a + // subchannel call (and therefore no client_load_reporting filter) + // for dropped calls. + if (client_stats_ != nullptr) { + client_stats_->AddCallDropped(drop_token); + } + return PICK_COMPLETE; + } + // Forward pick to child policy. + PickResult result = child_picker_->Pick(pick, error); + // If pick succeeded, add LB token to initial metadata. + if (result == PickResult::PICK_COMPLETE && + pick->connected_subchannel != nullptr) { + const grpc_arg* arg = grpc_channel_args_find( + pick->connected_subchannel->args(), GRPC_ARG_GRPCLB_ADDRESS_LB_TOKEN); + if (arg == nullptr) { + gpr_log(GPR_ERROR, + "[grpclb %p picker %p] No LB token for connected subchannel " + "pick %p", + parent_, this, pick); + abort(); + } + grpc_mdelem lb_token = {reinterpret_cast(arg->value.pointer.p)}; + GPR_ASSERT(!GRPC_MDISNULL(lb_token)); + GPR_ASSERT(grpc_metadata_batch_add_tail( + pick->initial_metadata, &pick->lb_token_mdelem_storage, + GRPC_MDELEM_REF(lb_token)) == GRPC_ERROR_NONE); + GrpcLbClientStats* client_stats = static_cast( + grpc_mdelem_get_user_data(lb_token, GrpcLbClientStats::Destroy)); + if (client_stats != nullptr) { + client_stats->AddCallStarted(); + } + } + return result; +} + +// +// GrpcLb::Helper +// + +bool GrpcLb::Helper::CalledByPendingChild() const { + GPR_ASSERT(child_ != nullptr); + return child_ == parent_->pending_child_policy_.get(); +} + +bool GrpcLb::Helper::CalledByCurrentChild() const { + GPR_ASSERT(child_ != nullptr); + return child_ == parent_->child_policy_.get(); +} + +Subchannel* GrpcLb::Helper::CreateSubchannel(const grpc_channel_args& args) { + if (parent_->shutting_down_ || + (!CalledByPendingChild() && !CalledByCurrentChild())) { + return nullptr; + } + return parent_->channel_control_helper()->CreateSubchannel(args); +} + +grpc_channel* GrpcLb::Helper::CreateChannel(const char* target, + const grpc_channel_args& args) { + if (parent_->shutting_down_ || + (!CalledByPendingChild() && !CalledByCurrentChild())) { + return nullptr; + } + return parent_->channel_control_helper()->CreateChannel(target, args); +} + +void GrpcLb::Helper::UpdateState(grpc_connectivity_state state, + UniquePtr picker) { + if (parent_->shutting_down_) return; + // If this request is from the pending child policy, ignore it until + // it reports READY, at which point we swap it into place. + if (CalledByPendingChild()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_glb_trace)) { + gpr_log(GPR_INFO, + "[grpclb %p helper %p] pending child policy %p reports state=%s", + parent_.get(), this, parent_->pending_child_policy_.get(), + grpc_connectivity_state_name(state)); + } + if (state != GRPC_CHANNEL_READY) return; + grpc_pollset_set_del_pollset_set( + parent_->child_policy_->interested_parties(), + parent_->interested_parties()); + MutexLock lock(&parent_->child_policy_mu_); + parent_->child_policy_ = std::move(parent_->pending_child_policy_); + } else if (!CalledByCurrentChild()) { + // This request is from an outdated child, so ignore it. + return; + } + // Record whether child policy reports READY. + parent_->child_policy_ready_ = state == GRPC_CHANNEL_READY; + // Enter fallback mode if needed. + parent_->MaybeEnterFallbackModeAfterStartup(); + // There are three cases to consider here: + // 1. We're in fallback mode. In this case, we're always going to use + // the child policy's result, so we pass its picker through as-is. + // 2. The serverlist contains only drop entries. In this case, we + // want to use our own picker so that we can return the drops. + // 3. Not in fallback mode and serverlist is not all drops (i.e., it + // may be empty or contain at least one backend address). There are + // two sub-cases: + // a. The child policy is reporting state READY. In this case, we wrap + // the child's picker in our own, so that we can handle drops and LB + // token metadata for each pick. + // b. The child policy is reporting a state other than READY. In this + // case, we don't want to use our own picker, because we don't want + // to process drops for picks that yield a QUEUE result; this would + // result in dropping too many calls, since we will see the + // queued picks multiple times, and we'd consider each one a + // separate call for the drop calculation. + // + // Cases 1 and 3b: return picker from the child policy as-is. + if (parent_->serverlist_ == nullptr || + (!parent_->serverlist_->ContainsAllDropEntries() && + state != GRPC_CHANNEL_READY)) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_glb_trace)) { + gpr_log(GPR_INFO, + "[grpclb %p helper %p] state=%s passing child picker %p as-is", + parent_.get(), this, grpc_connectivity_state_name(state), + picker.get()); + } + parent_->channel_control_helper()->UpdateState(state, std::move(picker)); + return; + } + // Cases 2 and 3a: wrap picker from the child in our own picker. + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_glb_trace)) { + gpr_log(GPR_INFO, "[grpclb %p helper %p] state=%s wrapping child picker %p", + parent_.get(), this, grpc_connectivity_state_name(state), + picker.get()); + } + RefCountedPtr client_stats; + if (parent_->lb_calld_ != nullptr && + parent_->lb_calld_->client_stats() != nullptr) { + client_stats = parent_->lb_calld_->client_stats()->Ref(); + } + parent_->channel_control_helper()->UpdateState( + state, UniquePtr( + New(parent_.get(), parent_->serverlist_, + std::move(picker), std::move(client_stats)))); +} + +void GrpcLb::Helper::RequestReresolution() { + if (parent_->shutting_down_) return; + const LoadBalancingPolicy* latest_child_policy = + parent_->pending_child_policy_ != nullptr + ? parent_->pending_child_policy_.get() + : parent_->child_policy_.get(); + if (child_ != latest_child_policy) return; + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_glb_trace)) { + gpr_log(GPR_INFO, + "[grpclb %p] Re-resolution requested from %schild policy (%p).", + parent_.get(), CalledByPendingChild() ? "pending " : "", child_); + } + // If we are talking to a balancer, we expect to get updated addresses + // from the balancer, so we can ignore the re-resolution request from + // the child policy. Otherwise, pass the re-resolution request up to the + // channel. + if (parent_->lb_calld_ == nullptr || + !parent_->lb_calld_->seen_initial_response()) { + parent_->channel_control_helper()->RequestReresolution(); } - GPR_ASSERT(addr_idx == num_valid); - return lb_addresses; } // @@ -499,7 +736,7 @@ grpc_lb_addresses* ProcessServerlist(const grpc_grpclb_serverlist* serverlist) { GrpcLb::BalancerCallState::BalancerCallState( RefCountedPtr parent_grpclb_policy) - : InternallyRefCountedWithTracing(&grpc_lb_glb_trace), + : InternallyRefCounted(&grpc_lb_glb_trace), grpclb_policy_(std::move(parent_grpclb_policy)) { GPR_ASSERT(grpclb_policy_ != nullptr); GPR_ASSERT(!grpclb_policy()->shutting_down_); @@ -565,9 +802,8 @@ void GrpcLb::BalancerCallState::Orphan() { void GrpcLb::BalancerCallState::StartQuery() { GPR_ASSERT(lb_call_ != nullptr); - if (grpc_lb_glb_trace.enabled()) { - gpr_log(GPR_INFO, - "[grpclb %p] Starting LB call (lb_calld: %p, lb_call: %p)", + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_glb_trace)) { + gpr_log(GPR_INFO, "[grpclb %p] lb_calld=%p: Starting LB call %p", grpclb_policy_.get(), this, lb_call_); } // Create the ops. @@ -578,7 +814,8 @@ void GrpcLb::BalancerCallState::StartQuery() { grpc_op* op = ops; op->op = GRPC_OP_SEND_INITIAL_METADATA; op->data.send_initial_metadata.count = 0; - op->flags = 0; + op->flags = GRPC_INITIAL_METADATA_WAIT_FOR_READY | + GRPC_INITIAL_METADATA_WAIT_FOR_READY_EXPLICITLY_SET; op->reserved = nullptr; op++; // Op: send request message. @@ -634,7 +871,7 @@ void GrpcLb::BalancerCallState::StartQuery() { call_error = grpc_call_start_batch_and_execute( lb_call_, ops, (size_t)(op - ops), &lb_on_balancer_status_received_); GPR_ASSERT(GRPC_CALL_OK == call_error); -}; +} void GrpcLb::BalancerCallState::ScheduleNextClientLoadReportLocked() { const grpc_millis next_client_load_report_time = @@ -683,7 +920,7 @@ void GrpcLb::BalancerCallState::SendClientLoadReportLocked() { // Construct message payload. GPR_ASSERT(send_message_payload_ == nullptr); grpc_grpclb_request* request = - grpc_grpclb_load_report_request_create_locked(client_stats_.get()); + grpc_grpclb_load_report_request_create(client_stats_.get()); // Skip client load report if the counters were all zero in the last // report and they are still zero in this one. if (LoadReportCountersAreZero(request)) { @@ -711,8 +948,9 @@ void GrpcLb::BalancerCallState::SendClientLoadReportLocked() { grpc_call_error call_error = grpc_call_start_batch_and_execute( lb_call_, &op, 1, &client_load_report_closure_); if (GPR_UNLIKELY(call_error != GRPC_CALL_OK)) { - gpr_log(GPR_ERROR, "[grpclb %p] call_error=%d", grpclb_policy_.get(), - call_error); + gpr_log(GPR_ERROR, + "[grpclb %p] lb_calld=%p call_error=%d sending client load report", + grpclb_policy_.get(), this, call_error); GPR_ASSERT(GRPC_CALL_OK == call_error); } } @@ -749,7 +987,7 @@ void GrpcLb::BalancerCallState::OnBalancerMessageReceivedLocked( void* arg, grpc_error* error) { BalancerCallState* lb_calld = static_cast(arg); GrpcLb* grpclb_policy = lb_calld->grpclb_policy(); - // Empty payload means the LB call was cancelled. + // Null payload means the LB call was cancelled. if (lb_calld != grpclb_policy->lb_calld_.get() || lb_calld->recv_message_payload_ == nullptr) { lb_calld->Unref(DEBUG_LOCATION, "on_message_received"); @@ -771,17 +1009,19 @@ void GrpcLb::BalancerCallState::OnBalancerMessageReceivedLocked( lb_calld->client_stats_report_interval_ = GPR_MAX( GPR_MS_PER_SEC, grpc_grpclb_duration_to_millis( &initial_response->client_stats_report_interval)); - if (grpc_lb_glb_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_glb_trace)) { gpr_log(GPR_INFO, - "[grpclb %p] Received initial LB response message; " - "client load reporting interval = %" PRId64 " milliseconds", - grpclb_policy, lb_calld->client_stats_report_interval_); + "[grpclb %p] lb_calld=%p: Received initial LB response " + "message; client load reporting interval = %" PRId64 + " milliseconds", + grpclb_policy, lb_calld, + lb_calld->client_stats_report_interval_); } - } else if (grpc_lb_glb_trace.enabled()) { + } else if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_glb_trace)) { gpr_log(GPR_INFO, - "[grpclb %p] Received initial LB response message; client load " - "reporting NOT enabled", - grpclb_policy); + "[grpclb %p] lb_calld=%p: Received initial LB response message; " + "client load reporting NOT enabled", + grpclb_policy, lb_calld); } grpc_grpclb_initial_response_destroy(initial_response); lb_calld->seen_initial_response_ = true; @@ -789,76 +1029,80 @@ void GrpcLb::BalancerCallState::OnBalancerMessageReceivedLocked( response_slice)) != nullptr) { // Have seen initial response, look for serverlist. GPR_ASSERT(lb_calld->lb_call_ != nullptr); - if (grpc_lb_glb_trace.enabled()) { + auto serverlist_wrapper = MakeRefCounted(serverlist); + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_glb_trace)) { + UniquePtr serverlist_text = serverlist_wrapper->AsText(); gpr_log(GPR_INFO, - "[grpclb %p] Serverlist with %" PRIuPTR " servers received", - grpclb_policy, serverlist->num_servers); - for (size_t i = 0; i < serverlist->num_servers; ++i) { - grpc_resolved_address addr; - ParseServer(serverlist->servers[i], &addr); - char* ipport; - grpc_sockaddr_to_string(&ipport, &addr, false); - gpr_log(GPR_INFO, "[grpclb %p] Serverlist[%" PRIuPTR "]: %s", - grpclb_policy, i, ipport); - gpr_free(ipport); - } + "[grpclb %p] lb_calld=%p: Serverlist with %" PRIuPTR + " servers received:\n%s", + grpclb_policy, lb_calld, serverlist->num_servers, + serverlist_text.get()); } - /* update serverlist */ - if (serverlist->num_servers > 0) { - // Start sending client load report only after we start using the - // serverlist returned from the current LB call. - if (lb_calld->client_stats_report_interval_ > 0 && - lb_calld->client_stats_ == nullptr) { - lb_calld->client_stats_.reset(New()); - // TODO(roth): We currently track this ref manually. Once the - // ClosureRef API is ready, we should pass the RefCountedPtr<> along - // with the callback. - auto self = lb_calld->Ref(DEBUG_LOCATION, "client_load_report"); - self.release(); - lb_calld->ScheduleNextClientLoadReportLocked(); + lb_calld->seen_serverlist_ = true; + // Start sending client load report only after we start using the + // serverlist returned from the current LB call. + if (lb_calld->client_stats_report_interval_ > 0 && + lb_calld->client_stats_ == nullptr) { + lb_calld->client_stats_ = MakeRefCounted(); + // Ref held by callback. + lb_calld->Ref(DEBUG_LOCATION, "client_load_report").release(); + lb_calld->ScheduleNextClientLoadReportLocked(); + } + // Check if the serverlist differs from the previous one. + if (grpclb_policy->serverlist_ != nullptr && + *grpclb_policy->serverlist_ == *serverlist_wrapper) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_glb_trace)) { + gpr_log(GPR_INFO, + "[grpclb %p] lb_calld=%p: Incoming server list identical to " + "current, ignoring.", + grpclb_policy, lb_calld); } - if (grpc_grpclb_serverlist_equals(grpclb_policy->serverlist_, - serverlist)) { - if (grpc_lb_glb_trace.enabled()) { - gpr_log(GPR_INFO, - "[grpclb %p] Incoming server list identical to current, " - "ignoring.", - grpclb_policy); - } - grpc_grpclb_destroy_serverlist(serverlist); - } else { /* new serverlist */ - if (grpclb_policy->serverlist_ != nullptr) { - /* dispose of the old serverlist */ - grpc_grpclb_destroy_serverlist(grpclb_policy->serverlist_); - } else { - /* or dispose of the fallback */ - grpc_lb_addresses_destroy(grpclb_policy->fallback_backend_addresses_); - grpclb_policy->fallback_backend_addresses_ = nullptr; - if (grpclb_policy->fallback_timer_callback_pending_) { - grpc_timer_cancel(&grpclb_policy->lb_fallback_timer_); - } - } - // and update the copy in the GrpcLb instance. This - // serverlist instance will be destroyed either upon the next - // update or when the GrpcLb instance is destroyed. - grpclb_policy->serverlist_ = serverlist; - grpclb_policy->serverlist_index_ = 0; - grpclb_policy->CreateOrUpdateRoundRobinPolicyLocked(); - } - } else { - if (grpc_lb_glb_trace.enabled()) { - gpr_log(GPR_INFO, "[grpclb %p] Received empty server list, ignoring.", + } else { // New serverlist. + // Dispose of the fallback. + // TODO(roth): Ideally, we should stay in fallback mode until we + // know that we can reach at least one of the backends in the new + // serverlist. Unfortunately, we can't do that, since we need to + // send the new addresses to the child policy in order to determine + // if they are reachable, and if we don't exit fallback mode now, + // CreateOrUpdateChildPolicyLocked() will use the fallback + // addresses instead of the addresses from the new serverlist. + // However, if we can't reach any of the servers in the new + // serverlist, then the child policy will never switch away from + // the fallback addresses, but the grpclb policy will still think + // that we're not in fallback mode, which means that we won't send + // updates to the child policy when the fallback addresses are + // updated by the resolver. This is sub-optimal, but the only way + // to fix it is to maintain a completely separate child policy for + // fallback mode, and that's more work than we want to put into + // the grpclb implementation at this point, since we're deprecating + // it in favor of the xds policy. We will implement this the + // right way in the xds policy instead. + if (grpclb_policy->fallback_mode_) { + gpr_log(GPR_INFO, + "[grpclb %p] Received response from balancer; exiting " + "fallback mode", grpclb_policy); + grpclb_policy->fallback_mode_ = false; } - grpc_grpclb_destroy_serverlist(serverlist); + if (grpclb_policy->fallback_at_startup_checks_pending_) { + grpclb_policy->fallback_at_startup_checks_pending_ = false; + grpc_timer_cancel(&grpclb_policy->lb_fallback_timer_); + grpclb_policy->CancelBalancerChannelConnectivityWatchLocked(); + } + // Update the serverlist in the GrpcLb instance. This serverlist + // instance will be destroyed either upon the next update or when the + // GrpcLb instance is destroyed. + grpclb_policy->serverlist_ = std::move(serverlist_wrapper); + grpclb_policy->CreateOrUpdateChildPolicyLocked(); } } else { // No valid initial response or serverlist found. char* response_slice_str = grpc_dump_slice(response_slice, GPR_DUMP_ASCII | GPR_DUMP_HEX); gpr_log(GPR_ERROR, - "[grpclb %p] Invalid LB response received: '%s'. Ignoring.", - grpclb_policy, response_slice_str); + "[grpclb %p] lb_calld=%p: Invalid LB response received: '%s'. " + "Ignoring.", + grpclb_policy, lb_calld, response_slice_str); gpr_free(response_slice_str); } grpc_slice_unref_internal(response_slice); @@ -885,23 +1129,41 @@ void GrpcLb::BalancerCallState::OnBalancerStatusReceivedLocked( BalancerCallState* lb_calld = static_cast(arg); GrpcLb* grpclb_policy = lb_calld->grpclb_policy(); GPR_ASSERT(lb_calld->lb_call_ != nullptr); - if (grpc_lb_glb_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_glb_trace)) { char* status_details = grpc_slice_to_c_string(lb_calld->lb_call_status_details_); gpr_log(GPR_INFO, - "[grpclb %p] Status from LB server received. Status = %d, details " - "= '%s', (lb_calld: %p, lb_call: %p), error '%s'", - grpclb_policy, lb_calld->lb_call_status_, status_details, lb_calld, + "[grpclb %p] lb_calld=%p: Status from LB server received. " + "Status = %d, details = '%s', (lb_call: %p), error '%s'", + grpclb_policy, lb_calld, lb_calld->lb_call_status_, status_details, lb_calld->lb_call_, grpc_error_string(error)); gpr_free(status_details); } - grpclb_policy->TryReresolutionLocked(&grpc_lb_glb_trace, GRPC_ERROR_NONE); // If this lb_calld is still in use, this call ended because of a failure so // we want to retry connecting. Otherwise, we have deliberately ended this // call and no further action is required. if (lb_calld == grpclb_policy->lb_calld_.get()) { + // If the fallback-at-startup checks are pending, go into fallback mode + // immediately. This short-circuits the timeout for the fallback-at-startup + // case. + if (grpclb_policy->fallback_at_startup_checks_pending_) { + GPR_ASSERT(!lb_calld->seen_serverlist_); + gpr_log(GPR_INFO, + "[grpclb %p] Balancer call finished without receiving " + "serverlist; entering fallback mode", + grpclb_policy); + grpclb_policy->fallback_at_startup_checks_pending_ = false; + grpc_timer_cancel(&grpclb_policy->lb_fallback_timer_); + grpclb_policy->CancelBalancerChannelConnectivityWatchLocked(); + grpclb_policy->fallback_mode_ = true; + grpclb_policy->CreateOrUpdateChildPolicyLocked(); + } else { + // This handles the fallback-after-startup case. + grpclb_policy->MaybeEnterFallbackModeAfterStartup(); + } grpclb_policy->lb_calld_.reset(); GPR_ASSERT(!grpclb_policy->shutting_down_); + grpclb_policy->channel_control_helper()->RequestReresolution(); if (lb_calld->seen_initial_response_) { // If we lose connection to the LB server, reset the backoff and restart // the LB call immediately. @@ -920,31 +1182,25 @@ void GrpcLb::BalancerCallState::OnBalancerStatusReceivedLocked( // helper code for creating balancer channel // -grpc_lb_addresses* ExtractBalancerAddresses( - const grpc_lb_addresses* addresses) { - size_t num_grpclb_addrs = 0; - for (size_t i = 0; i < addresses->num_addresses; ++i) { - if (addresses->addresses[i].is_balancer) ++num_grpclb_addrs; - } - // There must be at least one balancer address, or else the - // client_channel would not have chosen this LB policy. - GPR_ASSERT(num_grpclb_addrs > 0); - grpc_lb_addresses* lb_addresses = - grpc_lb_addresses_create(num_grpclb_addrs, nullptr); - size_t lb_addresses_idx = 0; - for (size_t i = 0; i < addresses->num_addresses; ++i) { - if (!addresses->addresses[i].is_balancer) continue; - if (GPR_UNLIKELY(addresses->addresses[i].user_data != nullptr)) { - gpr_log(GPR_ERROR, - "This LB policy doesn't support user data. It will be ignored"); +ServerAddressList ExtractBalancerAddresses(const ServerAddressList& addresses) { + ServerAddressList balancer_addresses; + for (size_t i = 0; i < addresses.size(); ++i) { + if (addresses[i].IsBalancer()) { + // Strip out the is_balancer channel arg, since we don't want to + // recursively use the grpclb policy in the channel used to talk to + // the balancers. Note that we do NOT strip out the balancer_name + // channel arg, since we need that to set the authority correctly + // to talk to the balancers. + static const char* args_to_remove[] = { + GRPC_ARG_ADDRESS_IS_BALANCER, + }; + balancer_addresses.emplace_back( + addresses[i].address(), + grpc_channel_args_copy_and_remove(addresses[i].args(), args_to_remove, + GPR_ARRAY_SIZE(args_to_remove))); } - grpc_lb_addresses_set_address( - lb_addresses, lb_addresses_idx++, addresses->addresses[i].address.addr, - addresses->addresses[i].address.len, false /* is balancer */, - addresses->addresses[i].balancer_name, nullptr /* user data */); } - GPR_ASSERT(num_grpclb_addrs == lb_addresses_idx); - return lb_addresses; + return balancer_addresses; } /* Returns the channel args for the LB channel, used to create a bidirectional @@ -956,28 +1212,21 @@ grpc_lb_addresses* ExtractBalancerAddresses( * above the grpclb policy. * - \a args: other args inherited from the grpclb policy. */ grpc_channel_args* BuildBalancerChannelArgs( - const grpc_lb_addresses* addresses, + const ServerAddressList& addresses, FakeResolverResponseGenerator* response_generator, const grpc_channel_args* args) { - grpc_lb_addresses* lb_addresses = ExtractBalancerAddresses(addresses); // Channel args to remove. static const char* args_to_remove[] = { // LB policy name, since we want to use the default (pick_first) in // the LB channel. GRPC_ARG_LB_POLICY_NAME, + // Strip out the service config, since we don't want the LB policy + // config specified for the parent channel to affect the LB channel. + GRPC_ARG_SERVICE_CONFIG, // The channel arg for the server URI, since that will be different for // the LB channel than for the parent channel. The client channel // factory will re-add this arg with the right value. GRPC_ARG_SERVER_URI, - // The resolved addresses, which will be generated by the name resolver - // used in the LB channel. Note that the LB channel will use the fake - // resolver, so this won't actually generate a query to DNS (or some - // other name service). However, the addresses returned by the fake - // resolver will have is_balancer=false, whereas our own addresses have - // is_balancer=true. We need the LB channel to return addresses with - // is_balancer=false so that it does not wind up recursively using the - // grpclb LB policy, as per the special case logic in client_channel.c. - GRPC_ARG_LB_ADDRESSES, // The fake resolver response generator, because we are replacing it // with the one from the grpclb policy, used to propagate updates to // the LB channel. @@ -993,10 +1242,6 @@ grpc_channel_args* BuildBalancerChannelArgs( }; // Channel args to add. const grpc_arg args_to_add[] = { - // New LB addresses. - // Note that we pass these in both when creating the LB channel - // and via the fake resolver. The latter is what actually gets used. - grpc_lb_addresses_create_channel_arg(lb_addresses), // The fake resolver response generator, which we use to inject // address updates into the LB channel. grpc_core::FakeResolverResponseGenerator::MakeChannelArg( @@ -1014,19 +1259,15 @@ grpc_channel_args* BuildBalancerChannelArgs( args, args_to_remove, GPR_ARRAY_SIZE(args_to_remove), args_to_add, GPR_ARRAY_SIZE(args_to_add)); // Make any necessary modifications for security. - new_args = grpc_lb_policy_grpclb_modify_lb_channel_args(new_args); - // Clean up. - grpc_lb_addresses_destroy(lb_addresses); - return new_args; + return grpc_lb_policy_grpclb_modify_lb_channel_args(addresses, new_args); } // // ctor and dtor // -GrpcLb::GrpcLb(const grpc_lb_addresses* addresses, - const LoadBalancingPolicy::Args& args) - : LoadBalancingPolicy(args), +GrpcLb::GrpcLb(Args args) + : LoadBalancingPolicy(std::move(args)), response_generator_(MakeRefCounted()), lb_call_backoff_( BackOff::Options() @@ -1037,18 +1278,12 @@ GrpcLb::GrpcLb(const grpc_lb_addresses* addresses, .set_max_backoff(GRPC_GRPCLB_RECONNECT_MAX_BACKOFF_SECONDS * 1000)) { // Initialization. - gpr_mu_init(&lb_channel_mu_); - grpc_subchannel_index_ref(); + GRPC_CLOSURE_INIT(&lb_on_fallback_, &GrpcLb::OnFallbackTimerLocked, this, + grpc_combiner_scheduler(combiner())); GRPC_CLOSURE_INIT(&lb_channel_on_connectivity_changed_, &GrpcLb::OnBalancerChannelConnectivityChangedLocked, this, grpc_combiner_scheduler(args.combiner)); - GRPC_CLOSURE_INIT(&on_rr_connectivity_changed_, - &GrpcLb::OnRoundRobinConnectivityChangedLocked, this, - grpc_combiner_scheduler(args.combiner)); - GRPC_CLOSURE_INIT(&on_rr_request_reresolution_, - &GrpcLb::OnRoundRobinRequestReresolutionLocked, this, - grpc_combiner_scheduler(args.combiner)); - grpc_connectivity_state_init(&state_tracker_, GRPC_CHANNEL_IDLE, "grpclb"); + gpr_mu_init(&child_policy_mu_); // Record server name. const grpc_arg* arg = grpc_channel_args_find(args.args, GRPC_ARG_SERVER_URI); const char* server_uri = grpc_channel_arg_get_string(arg); @@ -1056,7 +1291,7 @@ GrpcLb::GrpcLb(const grpc_lb_addresses* addresses, grpc_uri* uri = grpc_uri_parse(server_uri, true); GPR_ASSERT(uri->path[0] != '\0'); server_name_ = gpr_strdup(uri->path[0] == '/' ? uri->path + 1 : uri->path); - if (grpc_lb_glb_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_glb_trace)) { gpr_log(GPR_INFO, "[grpclb %p] Will use '%s' as the server name for LB request.", this, server_name_); @@ -1065,243 +1300,153 @@ GrpcLb::GrpcLb(const grpc_lb_addresses* addresses, // Record LB call timeout. arg = grpc_channel_args_find(args.args, GRPC_ARG_GRPCLB_CALL_TIMEOUT_MS); lb_call_timeout_ms_ = grpc_channel_arg_get_integer(arg, {0, 0, INT_MAX}); - // Record fallback timeout. + // Record fallback-at-startup timeout. arg = grpc_channel_args_find(args.args, GRPC_ARG_GRPCLB_FALLBACK_TIMEOUT_MS); - lb_fallback_timeout_ms_ = grpc_channel_arg_get_integer( + fallback_at_startup_timeout_ = grpc_channel_arg_get_integer( arg, {GRPC_GRPCLB_DEFAULT_FALLBACK_TIMEOUT_MS, 0, INT_MAX}); - // Process channel args. - ProcessChannelArgsLocked(*args.args); } GrpcLb::~GrpcLb() { - GPR_ASSERT(pending_picks_ == nullptr); - gpr_mu_destroy(&lb_channel_mu_); gpr_free((void*)server_name_); grpc_channel_args_destroy(args_); - grpc_connectivity_state_destroy(&state_tracker_); - if (serverlist_ != nullptr) { - grpc_grpclb_destroy_serverlist(serverlist_); - } - if (fallback_backend_addresses_ != nullptr) { - grpc_lb_addresses_destroy(fallback_backend_addresses_); - } - grpc_subchannel_index_unref(); + gpr_mu_destroy(&child_policy_mu_); } void GrpcLb::ShutdownLocked() { - grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Channel shutdown"); shutting_down_ = true; lb_calld_.reset(); if (retry_timer_callback_pending_) { grpc_timer_cancel(&lb_call_retry_timer_); } - if (fallback_timer_callback_pending_) { + if (fallback_at_startup_checks_pending_) { grpc_timer_cancel(&lb_fallback_timer_); + CancelBalancerChannelConnectivityWatchLocked(); + } + if (child_policy_ != nullptr) { + grpc_pollset_set_del_pollset_set(child_policy_->interested_parties(), + interested_parties()); + } + if (pending_child_policy_ != nullptr) { + grpc_pollset_set_del_pollset_set( + pending_child_policy_->interested_parties(), interested_parties()); + } + { + MutexLock lock(&child_policy_mu_); + child_policy_.reset(); + pending_child_policy_.reset(); } - rr_policy_.reset(); - TryReresolutionLocked(&grpc_lb_glb_trace, GRPC_ERROR_CANCELLED); // We destroy the LB channel here instead of in our destructor because // destroying the channel triggers a last callback to // OnBalancerChannelConnectivityChangedLocked(), and we need to be // alive when that callback is invoked. if (lb_channel_ != nullptr) { - gpr_mu_lock(&lb_channel_mu_); grpc_channel_destroy(lb_channel_); lb_channel_ = nullptr; - gpr_mu_unlock(&lb_channel_mu_); + gpr_atm_no_barrier_store(&lb_channel_uuid_, 0); } - grpc_connectivity_state_set(&state_tracker_, GRPC_CHANNEL_SHUTDOWN, - GRPC_ERROR_REF(error), "grpclb_shutdown"); - // Clear pending picks. - PendingPick* pp; - while ((pp = pending_picks_) != nullptr) { - pending_picks_ = pp->next; - pp->pick->connected_subchannel.reset(); - // Note: pp is deleted in this callback. - GRPC_CLOSURE_SCHED(&pp->on_complete, GRPC_ERROR_REF(error)); - } - GRPC_ERROR_UNREF(error); } // // public methods // -void GrpcLb::HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) { - PendingPick* pp; - while ((pp = pending_picks_) != nullptr) { - pending_picks_ = pp->next; - pp->pick->on_complete = pp->original_on_complete; - pp->pick->user_data = nullptr; - grpc_error* error = GRPC_ERROR_NONE; - if (new_policy->PickLocked(pp->pick, &error)) { - // Synchronous return; schedule closure. - GRPC_CLOSURE_SCHED(pp->pick->on_complete, error); - } - Delete(pp); - } -} - -// Cancel a specific pending pick. -// -// A grpclb pick progresses as follows: -// - If there's a Round Robin policy (rr_policy_) available, it'll be -// handed over to the RR policy (in CreateRoundRobinPolicyLocked()). From -// that point onwards, it'll be RR's responsibility. For cancellations, that -// implies the pick needs also be cancelled by the RR instance. -// - Otherwise, without an RR instance, picks stay pending at this policy's -// level (grpclb), inside the pending_picks_ list. To cancel these, -// we invoke the completion closure and set the pick's connected -// subchannel to nullptr right here. -void GrpcLb::CancelPickLocked(PickState* pick, grpc_error* error) { - PendingPick* pp = pending_picks_; - pending_picks_ = nullptr; - while (pp != nullptr) { - PendingPick* next = pp->next; - if (pp->pick == pick) { - pick->connected_subchannel.reset(); - // Note: pp is deleted in this callback. - GRPC_CLOSURE_SCHED(&pp->on_complete, - GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Pick Cancelled", &error, 1)); - } else { - pp->next = pending_picks_; - pending_picks_ = pp; - } - pp = next; - } - if (rr_policy_ != nullptr) { - rr_policy_->CancelPickLocked(pick, GRPC_ERROR_REF(error)); - } - GRPC_ERROR_UNREF(error); -} - -// Cancel all pending picks. -// -// A grpclb pick progresses as follows: -// - If there's a Round Robin policy (rr_policy_) available, it'll be -// handed over to the RR policy (in CreateRoundRobinPolicyLocked()). From -// that point onwards, it'll be RR's responsibility. For cancellations, that -// implies the pick needs also be cancelled by the RR instance. -// - Otherwise, without an RR instance, picks stay pending at this policy's -// level (grpclb), inside the pending_picks_ list. To cancel these, -// we invoke the completion closure and set the pick's connected -// subchannel to nullptr right here. -void GrpcLb::CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask, - uint32_t initial_metadata_flags_eq, - grpc_error* error) { - PendingPick* pp = pending_picks_; - pending_picks_ = nullptr; - while (pp != nullptr) { - PendingPick* next = pp->next; - if ((pp->pick->initial_metadata_flags & initial_metadata_flags_mask) == - initial_metadata_flags_eq) { - // Note: pp is deleted in this callback. - GRPC_CLOSURE_SCHED(&pp->on_complete, - GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Pick Cancelled", &error, 1)); - } else { - pp->next = pending_picks_; - pending_picks_ = pp; - } - pp = next; - } - if (rr_policy_ != nullptr) { - rr_policy_->CancelMatchingPicksLocked(initial_metadata_flags_mask, - initial_metadata_flags_eq, - GRPC_ERROR_REF(error)); - } - GRPC_ERROR_UNREF(error); -} - -void GrpcLb::ExitIdleLocked() { - if (!started_picking_) { - StartPickingLocked(); - } -} - void GrpcLb::ResetBackoffLocked() { if (lb_channel_ != nullptr) { grpc_channel_reset_connect_backoff(lb_channel_); } - if (rr_policy_ != nullptr) { - rr_policy_->ResetBackoffLocked(); + if (child_policy_ != nullptr) { + child_policy_->ResetBackoffLocked(); } -} - -bool GrpcLb::PickLocked(PickState* pick, grpc_error** error) { - PendingPick* pp = PendingPickCreate(pick); - bool pick_done = false; - if (rr_policy_ != nullptr) { - if (grpc_lb_glb_trace.enabled()) { - gpr_log(GPR_INFO, "[grpclb %p] about to PICK from RR %p", this, - rr_policy_.get()); - } - pick_done = - PickFromRoundRobinPolicyLocked(false /* force_async */, pp, error); - } else { // rr_policy_ == NULL - if (pick->on_complete == nullptr) { - *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "No pick result available but synchronous result required."); - pick_done = true; - } else { - if (grpc_lb_glb_trace.enabled()) { - gpr_log(GPR_INFO, - "[grpclb %p] No RR policy. Adding to grpclb's pending picks", - this); - } - AddPendingPick(pp); - if (!started_picking_) { - StartPickingLocked(); - } - pick_done = false; - } + if (pending_child_policy_ != nullptr) { + pending_child_policy_->ResetBackoffLocked(); } - return pick_done; } void GrpcLb::FillChildRefsForChannelz( channelz::ChildRefsList* child_subchannels, channelz::ChildRefsList* child_channels) { - // delegate to the RoundRobin to fill the children subchannels. - rr_policy_->FillChildRefsForChannelz(child_subchannels, child_channels); - MutexLock lock(&lb_channel_mu_); - if (lb_channel_ != nullptr) { - grpc_core::channelz::ChannelNode* channel_node = - grpc_channel_get_channelz_node(lb_channel_); - if (channel_node != nullptr) { - child_channels->push_back(channel_node->uuid()); + { + // Delegate to the child policy to fill the children subchannels. + // This must be done holding child_policy_mu_, since this method + // does not run in the combiner. + MutexLock lock(&child_policy_mu_); + if (child_policy_ != nullptr) { + child_policy_->FillChildRefsForChannelz(child_subchannels, + child_channels); + } + if (pending_child_policy_ != nullptr) { + pending_child_policy_->FillChildRefsForChannelz(child_subchannels, + child_channels); } } -} - -grpc_connectivity_state GrpcLb::CheckConnectivityLocked( - grpc_error** connectivity_error) { - return grpc_connectivity_state_get(&state_tracker_, connectivity_error); -} - -void GrpcLb::NotifyOnStateChangeLocked(grpc_connectivity_state* current, - grpc_closure* notify) { - grpc_connectivity_state_notify_on_state_change(&state_tracker_, current, - notify); -} - -void GrpcLb::ProcessChannelArgsLocked(const grpc_channel_args& args) { - const grpc_arg* arg = grpc_channel_args_find(&args, GRPC_ARG_LB_ADDRESSES); - if (GPR_UNLIKELY(arg == nullptr || arg->type != GRPC_ARG_POINTER)) { - // Ignore this update. - gpr_log( - GPR_ERROR, - "[grpclb %p] No valid LB addresses channel arg in update, ignoring.", - this); - return; + gpr_atm uuid = gpr_atm_no_barrier_load(&lb_channel_uuid_); + if (uuid != 0) { + child_channels->push_back(uuid); } - const grpc_lb_addresses* addresses = - static_cast(arg->value.pointer.p); +} + +void GrpcLb::UpdateLocked(UpdateArgs args) { + const bool is_initial_update = lb_channel_ == nullptr; + auto* grpclb_config = + static_cast(args.config.get()); + if (grpclb_config != nullptr) { + child_policy_config_ = grpclb_config->child_policy(); + } else { + child_policy_config_ = nullptr; + } + ProcessAddressesAndChannelArgsLocked(args.addresses, *args.args); + // Update the existing child policy. + if (child_policy_ != nullptr) CreateOrUpdateChildPolicyLocked(); + // If this is the initial update, start the fallback-at-startup checks + // and the balancer call. + if (is_initial_update) { + fallback_at_startup_checks_pending_ = true; + // Start timer. + grpc_millis deadline = ExecCtx::Get()->Now() + fallback_at_startup_timeout_; + Ref(DEBUG_LOCATION, "on_fallback_timer").release(); // Ref for callback + grpc_timer_init(&lb_fallback_timer_, deadline, &lb_on_fallback_); + // Start watching the channel's connectivity state. If the channel + // goes into state TRANSIENT_FAILURE before the timer fires, we go into + // fallback mode even if the fallback timeout has not elapsed. + grpc_channel_element* client_channel_elem = grpc_channel_stack_last_element( + grpc_channel_get_channel_stack(lb_channel_)); + GPR_ASSERT(client_channel_elem->filter == &grpc_client_channel_filter); + // Ref held by callback. + Ref(DEBUG_LOCATION, "watch_lb_channel_connectivity").release(); + grpc_client_channel_watch_connectivity_state( + client_channel_elem, + grpc_polling_entity_create_from_pollset_set(interested_parties()), + &lb_channel_connectivity_, &lb_channel_on_connectivity_changed_, + nullptr); + // Start balancer call. + StartBalancerCallLocked(); + } +} + +// +// helpers for UpdateLocked() +// + +// Returns the backend addresses extracted from the given addresses. +ServerAddressList ExtractBackendAddresses(const ServerAddressList& addresses) { + void* lb_token = (void*)GRPC_MDELEM_LB_TOKEN_EMPTY.payload; + grpc_arg arg = grpc_channel_arg_pointer_create( + const_cast(GRPC_ARG_GRPCLB_ADDRESS_LB_TOKEN), lb_token, + &lb_token_arg_vtable); + ServerAddressList backend_addresses; + for (size_t i = 0; i < addresses.size(); ++i) { + if (!addresses[i].IsBalancer()) { + backend_addresses.emplace_back( + addresses[i].address(), + grpc_channel_args_copy_and_add(addresses[i].args(), &arg, 1)); + } + } + return backend_addresses; +} + +void GrpcLb::ProcessAddressesAndChannelArgsLocked( + const ServerAddressList& addresses, const grpc_channel_args& args) { // Update fallback address list. - if (fallback_backend_addresses_ != nullptr) { - grpc_lb_addresses_destroy(fallback_backend_addresses_); - } fallback_backend_addresses_ = ExtractBackendAddresses(addresses); // Make sure that GRPC_ARG_LB_POLICY_NAME is set in channel args, // since we use this to trigger the client_load_reporting filter. @@ -1312,82 +1457,85 @@ void GrpcLb::ProcessChannelArgsLocked(const grpc_channel_args& args) { args_ = grpc_channel_args_copy_and_add_and_remove( &args, args_to_remove, GPR_ARRAY_SIZE(args_to_remove), &new_arg, 1); // Construct args for balancer channel. - grpc_channel_args* lb_channel_args = - BuildBalancerChannelArgs(addresses, response_generator_.get(), &args); + ServerAddressList balancer_addresses = ExtractBalancerAddresses(addresses); + grpc_channel_args* lb_channel_args = BuildBalancerChannelArgs( + balancer_addresses, response_generator_.get(), &args); // Create balancer channel if needed. if (lb_channel_ == nullptr) { char* uri_str; gpr_asprintf(&uri_str, "fake:///%s", server_name_); - gpr_mu_lock(&lb_channel_mu_); - lb_channel_ = grpc_client_channel_factory_create_channel( - client_channel_factory(), uri_str, - GRPC_CLIENT_CHANNEL_TYPE_LOAD_BALANCING, lb_channel_args); - gpr_mu_unlock(&lb_channel_mu_); + lb_channel_ = + channel_control_helper()->CreateChannel(uri_str, *lb_channel_args); GPR_ASSERT(lb_channel_ != nullptr); + grpc_core::channelz::ChannelNode* channel_node = + grpc_channel_get_channelz_node(lb_channel_); + if (channel_node != nullptr) { + gpr_atm_no_barrier_store(&lb_channel_uuid_, channel_node->uuid()); + } gpr_free(uri_str); } // Propagate updates to the LB channel (pick_first) through the fake // resolver. - response_generator_->SetResponse(lb_channel_args); - grpc_channel_args_destroy(lb_channel_args); + Resolver::Result result; + result.addresses = std::move(balancer_addresses); + result.args = lb_channel_args; + response_generator_->SetResponse(std::move(result)); } -void GrpcLb::UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) { - ProcessChannelArgsLocked(args); - // Update the existing RR policy. - if (rr_policy_ != nullptr) CreateOrUpdateRoundRobinPolicyLocked(); - // Start watching the LB channel connectivity for connection, if not - // already doing so. - if (!watching_lb_channel_) { - lb_channel_connectivity_ = grpc_channel_check_connectivity_state( - lb_channel_, true /* try to connect */); - grpc_channel_element* client_channel_elem = grpc_channel_stack_last_element( - grpc_channel_get_channel_stack(lb_channel_)); - GPR_ASSERT(client_channel_elem->filter == &grpc_client_channel_filter); - watching_lb_channel_ = true; - // TODO(roth): We currently track this ref manually. Once the - // ClosureRef API is ready, we should pass the RefCountedPtr<> along - // with the callback. - auto self = Ref(DEBUG_LOCATION, "watch_lb_channel_connectivity"); - self.release(); - grpc_client_channel_watch_connectivity_state( - client_channel_elem, - grpc_polling_entity_create_from_pollset_set(interested_parties()), - &lb_channel_connectivity_, &lb_channel_on_connectivity_changed_, - nullptr); +void GrpcLb::OnBalancerChannelConnectivityChangedLocked(void* arg, + grpc_error* error) { + GrpcLb* self = static_cast(arg); + if (!self->shutting_down_ && self->fallback_at_startup_checks_pending_) { + if (self->lb_channel_connectivity_ != GRPC_CHANNEL_TRANSIENT_FAILURE) { + // Not in TRANSIENT_FAILURE. Renew connectivity watch. + grpc_channel_element* client_channel_elem = + grpc_channel_stack_last_element( + grpc_channel_get_channel_stack(self->lb_channel_)); + GPR_ASSERT(client_channel_elem->filter == &grpc_client_channel_filter); + grpc_client_channel_watch_connectivity_state( + client_channel_elem, + grpc_polling_entity_create_from_pollset_set( + self->interested_parties()), + &self->lb_channel_connectivity_, + &self->lb_channel_on_connectivity_changed_, nullptr); + return; // Early out so we don't drop the ref below. + } + // In TRANSIENT_FAILURE. Cancel the fallback timer and go into + // fallback mode immediately. + gpr_log(GPR_INFO, + "[grpclb %p] balancer channel in state TRANSIENT_FAILURE; " + "entering fallback mode", + self); + self->fallback_at_startup_checks_pending_ = false; + grpc_timer_cancel(&self->lb_fallback_timer_); + self->fallback_mode_ = true; + self->CreateOrUpdateChildPolicyLocked(); } + // Done watching connectivity state, so drop ref. + self->Unref(DEBUG_LOCATION, "watch_lb_channel_connectivity"); +} + +void GrpcLb::CancelBalancerChannelConnectivityWatchLocked() { + grpc_channel_element* client_channel_elem = grpc_channel_stack_last_element( + grpc_channel_get_channel_stack(lb_channel_)); + GPR_ASSERT(client_channel_elem->filter == &grpc_client_channel_filter); + grpc_client_channel_watch_connectivity_state( + client_channel_elem, + grpc_polling_entity_create_from_pollset_set(interested_parties()), + nullptr, &lb_channel_on_connectivity_changed_, nullptr); } // // code for balancer channel and call // -void GrpcLb::StartPickingLocked() { - // Start a timer to fall back. - if (lb_fallback_timeout_ms_ > 0 && serverlist_ == nullptr && - !fallback_timer_callback_pending_) { - grpc_millis deadline = ExecCtx::Get()->Now() + lb_fallback_timeout_ms_; - // TODO(roth): We currently track this ref manually. Once the - // ClosureRef API is ready, we should pass the RefCountedPtr<> along - // with the callback. - auto self = Ref(DEBUG_LOCATION, "on_fallback_timer"); - self.release(); - GRPC_CLOSURE_INIT(&lb_on_fallback_, &GrpcLb::OnFallbackTimerLocked, this, - grpc_combiner_scheduler(combiner())); - fallback_timer_callback_pending_ = true; - grpc_timer_init(&lb_fallback_timer_, deadline, &lb_on_fallback_); - } - started_picking_ = true; - StartBalancerCallLocked(); -} - void GrpcLb::StartBalancerCallLocked() { GPR_ASSERT(lb_channel_ != nullptr); if (shutting_down_) return; // Init the LB call data. GPR_ASSERT(lb_calld_ == nullptr); lb_calld_ = MakeOrphanable(Ref()); - if (grpc_lb_glb_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_glb_trace)) { gpr_log(GPR_INFO, "[grpclb %p] Query for backends (lb_channel: %p, lb_calld: %p)", this, lb_channel_, lb_calld_.get()); @@ -1395,27 +1543,9 @@ void GrpcLb::StartBalancerCallLocked() { lb_calld_->StartQuery(); } -void GrpcLb::OnFallbackTimerLocked(void* arg, grpc_error* error) { - GrpcLb* grpclb_policy = static_cast(arg); - grpclb_policy->fallback_timer_callback_pending_ = false; - // If we receive a serverlist after the timer fires but before this callback - // actually runs, don't fall back. - if (grpclb_policy->serverlist_ == nullptr && !grpclb_policy->shutting_down_ && - error == GRPC_ERROR_NONE) { - if (grpc_lb_glb_trace.enabled()) { - gpr_log(GPR_INFO, - "[grpclb %p] Falling back to use backends from resolver", - grpclb_policy); - } - GPR_ASSERT(grpclb_policy->fallback_backend_addresses_ != nullptr); - grpclb_policy->CreateOrUpdateRoundRobinPolicyLocked(); - } - grpclb_policy->Unref(DEBUG_LOCATION, "on_fallback_timer"); -} - void GrpcLb::StartBalancerCallRetryTimerLocked() { grpc_millis next_try = lb_call_backoff_.NextAttemptTime(); - if (grpc_lb_glb_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_glb_trace)) { gpr_log(GPR_INFO, "[grpclb %p] Connection to LB server lost...", this); grpc_millis timeout = next_try - ExecCtx::Get()->Now(); if (timeout > 0) { @@ -1442,7 +1572,7 @@ void GrpcLb::OnBalancerCallRetryTimerLocked(void* arg, grpc_error* error) { grpclb_policy->retry_timer_callback_pending_ = false; if (!grpclb_policy->shutting_down_ && error == GRPC_ERROR_NONE && grpclb_policy->lb_calld_ == nullptr) { - if (grpc_lb_glb_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_glb_trace)) { gpr_log(GPR_INFO, "[grpclb %p] Restarting call to LB server", grpclb_policy); } @@ -1451,392 +1581,210 @@ void GrpcLb::OnBalancerCallRetryTimerLocked(void* arg, grpc_error* error) { grpclb_policy->Unref(DEBUG_LOCATION, "on_balancer_call_retry_timer"); } -// Invoked as part of the update process. It continues watching the LB channel -// until it shuts down or becomes READY. It's invoked even if the LB channel -// stayed READY throughout the update (for example if the update is identical). -void GrpcLb::OnBalancerChannelConnectivityChangedLocked(void* arg, - grpc_error* error) { - GrpcLb* grpclb_policy = static_cast(arg); - if (grpclb_policy->shutting_down_) goto done; - // Re-initialize the lb_call. This should also take care of updating the - // embedded RR policy. Note that the current RR policy, if any, will stay in - // effect until an update from the new lb_call is received. - switch (grpclb_policy->lb_channel_connectivity_) { - case GRPC_CHANNEL_CONNECTING: - case GRPC_CHANNEL_TRANSIENT_FAILURE: { - // Keep watching the LB channel. - grpc_channel_element* client_channel_elem = - grpc_channel_stack_last_element( - grpc_channel_get_channel_stack(grpclb_policy->lb_channel_)); - GPR_ASSERT(client_channel_elem->filter == &grpc_client_channel_filter); - grpc_client_channel_watch_connectivity_state( - client_channel_elem, - grpc_polling_entity_create_from_pollset_set( - grpclb_policy->interested_parties()), - &grpclb_policy->lb_channel_connectivity_, - &grpclb_policy->lb_channel_on_connectivity_changed_, nullptr); - break; - } - // The LB channel may be IDLE because it's shut down before the update. - // Restart the LB call to kick the LB channel into gear. - case GRPC_CHANNEL_IDLE: - case GRPC_CHANNEL_READY: - grpclb_policy->lb_calld_.reset(); - if (grpclb_policy->started_picking_) { - if (grpclb_policy->retry_timer_callback_pending_) { - grpc_timer_cancel(&grpclb_policy->lb_call_retry_timer_); - } - grpclb_policy->lb_call_backoff_.Reset(); - grpclb_policy->StartBalancerCallLocked(); - } - // fallthrough - case GRPC_CHANNEL_SHUTDOWN: - done: - grpclb_policy->watching_lb_channel_ = false; - grpclb_policy->Unref(DEBUG_LOCATION, - "watch_lb_channel_connectivity_cb_shutdown"); - } -} - // -// PendingPick +// code for handling fallback mode // -// Adds lb_token of selected subchannel (address) to the call's initial -// metadata. -grpc_error* AddLbTokenToInitialMetadata( - grpc_mdelem lb_token, grpc_linked_mdelem* lb_token_mdelem_storage, - grpc_metadata_batch* initial_metadata) { - GPR_ASSERT(lb_token_mdelem_storage != nullptr); - GPR_ASSERT(!GRPC_MDISNULL(lb_token)); - return grpc_metadata_batch_add_tail(initial_metadata, lb_token_mdelem_storage, - lb_token); -} - -// Destroy function used when embedding client stats in call context. -void DestroyClientStats(void* arg) { - static_cast(arg)->Unref(); -} - -void GrpcLb::PendingPickSetMetadataAndContext(PendingPick* pp) { - /* if connected_subchannel is nullptr, no pick has been made by the RR - * policy (e.g., all addresses failed to connect). There won't be any - * user_data/token available */ - if (pp->pick->connected_subchannel != nullptr) { - if (GPR_LIKELY(!GRPC_MDISNULL(pp->lb_token))) { - AddLbTokenToInitialMetadata(GRPC_MDELEM_REF(pp->lb_token), - &pp->pick->lb_token_mdelem_storage, - pp->pick->initial_metadata); - } else { - gpr_log(GPR_ERROR, - "[grpclb %p] No LB token for connected subchannel pick %p", - pp->grpclb_policy, pp->pick); - abort(); - } - // Pass on client stats via context. Passes ownership of the reference. - if (pp->client_stats != nullptr) { - pp->pick->subchannel_call_context[GRPC_GRPCLB_CLIENT_STATS].value = - pp->client_stats.release(); - pp->pick->subchannel_call_context[GRPC_GRPCLB_CLIENT_STATS].destroy = - DestroyClientStats; - } - } else { - pp->client_stats.reset(); - } -} - -/* The \a on_complete closure passed as part of the pick requires keeping a - * reference to its associated round robin instance. We wrap this closure in - * order to unref the round robin instance upon its invocation */ -void GrpcLb::OnPendingPickComplete(void* arg, grpc_error* error) { - PendingPick* pp = static_cast(arg); - PendingPickSetMetadataAndContext(pp); - GRPC_CLOSURE_SCHED(pp->original_on_complete, GRPC_ERROR_REF(error)); - Delete(pp); -} - -GrpcLb::PendingPick* GrpcLb::PendingPickCreate(PickState* pick) { - PendingPick* pp = New(); - pp->grpclb_policy = this; - pp->pick = pick; - GRPC_CLOSURE_INIT(&pp->on_complete, &GrpcLb::OnPendingPickComplete, pp, - grpc_schedule_on_exec_ctx); - pp->original_on_complete = pick->on_complete; - pick->on_complete = &pp->on_complete; - return pp; -} - -void GrpcLb::AddPendingPick(PendingPick* pp) { - pp->next = pending_picks_; - pending_picks_ = pp; -} - -// -// code for interacting with the RR policy -// - -// Performs a pick over \a rr_policy_. Given that a pick can return -// immediately (ignoring its completion callback), we need to perform the -// cleanups this callback would otherwise be responsible for. -// If \a force_async is true, then we will manually schedule the -// completion callback even if the pick is available immediately. -bool GrpcLb::PickFromRoundRobinPolicyLocked(bool force_async, PendingPick* pp, - grpc_error** error) { - // Check for drops if we are not using fallback backend addresses. - if (serverlist_ != nullptr) { - // Look at the index into the serverlist to see if we should drop this call. - grpc_grpclb_server* server = serverlist_->servers[serverlist_index_++]; - if (serverlist_index_ == serverlist_->num_servers) { - serverlist_index_ = 0; // Wrap-around. - } - if (server->drop) { - // Update client load reporting stats to indicate the number of - // dropped calls. Note that we have to do this here instead of in - // the client_load_reporting filter, because we do not create a - // subchannel call (and therefore no client_load_reporting filter) - // for dropped calls. - if (lb_calld_ != nullptr && lb_calld_->client_stats() != nullptr) { - lb_calld_->client_stats()->AddCallDroppedLocked( - server->load_balance_token); - } - if (force_async) { - GRPC_CLOSURE_SCHED(pp->original_on_complete, GRPC_ERROR_NONE); - Delete(pp); - return false; - } - Delete(pp); - return true; - } - } - // Set client_stats and user_data. - if (lb_calld_ != nullptr && lb_calld_->client_stats() != nullptr) { - pp->client_stats = lb_calld_->client_stats()->Ref(); - } - GPR_ASSERT(pp->pick->user_data == nullptr); - pp->pick->user_data = (void**)&pp->lb_token; - // Pick via the RR policy. - bool pick_done = rr_policy_->PickLocked(pp->pick, error); - if (pick_done) { - PendingPickSetMetadataAndContext(pp); - if (force_async) { - GRPC_CLOSURE_SCHED(pp->original_on_complete, *error); - *error = GRPC_ERROR_NONE; - pick_done = false; - } - Delete(pp); - } - // else, the pending pick will be registered and taken care of by the - // pending pick list inside the RR policy. Eventually, - // OnPendingPickComplete() will be called, which will (among other - // things) add the LB token to the call's initial metadata. - return pick_done; -} - -void GrpcLb::CreateRoundRobinPolicyLocked(const Args& args) { - GPR_ASSERT(rr_policy_ == nullptr); - rr_policy_ = LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( - "round_robin", args); - if (GPR_UNLIKELY(rr_policy_ == nullptr)) { - gpr_log(GPR_ERROR, "[grpclb %p] Failure creating a RoundRobin policy", +void GrpcLb::MaybeEnterFallbackModeAfterStartup() { + // Enter fallback mode if all of the following are true: + // - We are not currently in fallback mode. + // - We are not currently waiting for the initial fallback timeout. + // - We are not currently in contact with the balancer. + // - The child policy is not in state READY. + if (!fallback_mode_ && !fallback_at_startup_checks_pending_ && + (lb_calld_ == nullptr || !lb_calld_->seen_serverlist()) && + !child_policy_ready_) { + gpr_log(GPR_INFO, + "[grpclb %p] lost contact with balancer and backends from " + "most recent serverlist; entering fallback mode", this); - return; - } - // TODO(roth): We currently track this ref manually. Once the new - // ClosureRef API is done, pass the RefCountedPtr<> along with the closure. - auto self = Ref(DEBUG_LOCATION, "on_rr_reresolution_requested"); - self.release(); - rr_policy_->SetReresolutionClosureLocked(&on_rr_request_reresolution_); - grpc_error* rr_state_error = nullptr; - rr_connectivity_state_ = rr_policy_->CheckConnectivityLocked(&rr_state_error); - // Connectivity state is a function of the RR policy updated/created. - UpdateConnectivityStateFromRoundRobinPolicyLocked(rr_state_error); - // Add the gRPC LB's interested_parties pollset_set to that of the newly - // created RR policy. This will make the RR policy progress upon activity on - // gRPC LB, which in turn is tied to the application's call. - grpc_pollset_set_add_pollset_set(rr_policy_->interested_parties(), - interested_parties()); - // Subscribe to changes to the connectivity of the new RR. - // TODO(roth): We currently track this ref manually. Once the new - // ClosureRef API is done, pass the RefCountedPtr<> along with the closure. - self = Ref(DEBUG_LOCATION, "on_rr_connectivity_changed"); - self.release(); - rr_policy_->NotifyOnStateChangeLocked(&rr_connectivity_state_, - &on_rr_connectivity_changed_); - rr_policy_->ExitIdleLocked(); - // Send pending picks to RR policy. - PendingPick* pp; - while ((pp = pending_picks_)) { - pending_picks_ = pp->next; - if (grpc_lb_glb_trace.enabled()) { - gpr_log(GPR_INFO, - "[grpclb %p] Pending pick about to (async) PICK from RR %p", this, - rr_policy_.get()); - } - grpc_error* error = GRPC_ERROR_NONE; - PickFromRoundRobinPolicyLocked(true /* force_async */, pp, &error); + fallback_mode_ = true; + CreateOrUpdateChildPolicyLocked(); } } -grpc_channel_args* GrpcLb::CreateRoundRobinPolicyArgsLocked() { - grpc_lb_addresses* addresses; +void GrpcLb::OnFallbackTimerLocked(void* arg, grpc_error* error) { + GrpcLb* grpclb_policy = static_cast(arg); + // If we receive a serverlist after the timer fires but before this callback + // actually runs, don't fall back. + if (grpclb_policy->fallback_at_startup_checks_pending_ && + !grpclb_policy->shutting_down_ && error == GRPC_ERROR_NONE) { + gpr_log(GPR_INFO, + "[grpclb %p] No response from balancer after fallback timeout; " + "entering fallback mode", + grpclb_policy); + grpclb_policy->fallback_at_startup_checks_pending_ = false; + grpclb_policy->CancelBalancerChannelConnectivityWatchLocked(); + grpclb_policy->fallback_mode_ = true; + grpclb_policy->CreateOrUpdateChildPolicyLocked(); + } + grpclb_policy->Unref(DEBUG_LOCATION, "on_fallback_timer"); +} + +// +// code for interacting with the child policy +// + +grpc_channel_args* GrpcLb::CreateChildPolicyArgsLocked( + bool is_backend_from_grpclb_load_balancer) { + InlinedVector args_to_add; + args_to_add.emplace_back(grpc_channel_arg_integer_create( + const_cast(GRPC_ARG_ADDRESS_IS_BACKEND_FROM_GRPCLB_LOAD_BALANCER), + is_backend_from_grpclb_load_balancer)); + if (is_backend_from_grpclb_load_balancer) { + args_to_add.emplace_back(grpc_channel_arg_integer_create( + const_cast(GRPC_ARG_INHIBIT_HEALTH_CHECKING), 1)); + } + return grpc_channel_args_copy_and_add(args_, args_to_add.data(), + args_to_add.size()); +} + +OrphanablePtr GrpcLb::CreateChildPolicyLocked( + const char* name, const grpc_channel_args* args) { + Helper* helper = New(Ref()); + LoadBalancingPolicy::Args lb_policy_args; + lb_policy_args.combiner = combiner(); + lb_policy_args.args = args; + lb_policy_args.channel_control_helper = + UniquePtr(helper); + OrphanablePtr lb_policy = + LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( + name, std::move(lb_policy_args)); + if (GPR_UNLIKELY(lb_policy == nullptr)) { + gpr_log(GPR_ERROR, "[grpclb %p] Failure creating child policy %s", this, + name); + return nullptr; + } + helper->set_child(lb_policy.get()); + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_glb_trace)) { + gpr_log(GPR_INFO, "[grpclb %p] Created new child policy %s (%p)", this, + name, lb_policy.get()); + } + // Add the gRPC LB's interested_parties pollset_set to that of the newly + // created child policy. This will make the child policy progress upon + // activity on gRPC LB, which in turn is tied to the application's call. + grpc_pollset_set_add_pollset_set(lb_policy->interested_parties(), + interested_parties()); + return lb_policy; +} + +void GrpcLb::CreateOrUpdateChildPolicyLocked() { + if (shutting_down_) return; + // Construct update args. + UpdateArgs update_args; 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 + if (fallback_mode_) { + // If CreateOrUpdateChildPolicyLocked() is invoked when we haven't // received any serverlist from the balancer, we use the fallback backends // returned by the resolver. Note that the fallback backend list may be // empty, in which case the new round_robin policy will keep the requested // picks pending. - GPR_ASSERT(fallback_backend_addresses_ != nullptr); - addresses = grpc_lb_addresses_copy(fallback_backend_addresses_); - } - GPR_ASSERT(addresses != nullptr); - // 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}; - grpc_arg args_to_add[3] = { - 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( - GRPC_ARG_ADDRESS_IS_BACKEND_FROM_GRPCLB_LOAD_BALANCER), - is_backend_from_grpclb_load_balancer), - }; - size_t num_args_to_add = 2; - if (is_backend_from_grpclb_load_balancer) { - args_to_add[2] = grpc_channel_arg_integer_create( - const_cast(GRPC_ARG_INHIBIT_HEALTH_CHECKING), 1); - ++num_args_to_add; - } - grpc_channel_args* args = grpc_channel_args_copy_and_add_and_remove( - args_, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), args_to_add, - num_args_to_add); - grpc_lb_addresses_destroy(addresses); - return args; -} - -void GrpcLb::CreateOrUpdateRoundRobinPolicyLocked() { - if (shutting_down_) return; - grpc_channel_args* args = CreateRoundRobinPolicyArgsLocked(); - GPR_ASSERT(args != nullptr); - if (rr_policy_ != nullptr) { - if (grpc_lb_glb_trace.enabled()) { - gpr_log(GPR_INFO, "[grpclb %p] Updating RR policy %p", this, - rr_policy_.get()); - } - rr_policy_->UpdateLocked(*args, nullptr); + update_args.addresses = fallback_backend_addresses_; } else { - LoadBalancingPolicy::Args lb_policy_args; - lb_policy_args.combiner = combiner(); - lb_policy_args.client_channel_factory = client_channel_factory(); - lb_policy_args.args = args; - CreateRoundRobinPolicyLocked(lb_policy_args); - if (grpc_lb_glb_trace.enabled()) { - gpr_log(GPR_INFO, "[grpclb %p] Created new RR policy %p", this, - rr_policy_.get()); + update_args.addresses = serverlist_->GetServerAddressList( + lb_calld_ == nullptr ? nullptr : lb_calld_->client_stats()); + is_backend_from_grpclb_load_balancer = true; + } + update_args.args = + CreateChildPolicyArgsLocked(is_backend_from_grpclb_load_balancer); + GPR_ASSERT(update_args.args != nullptr); + update_args.config = child_policy_config_; + // If the child policy name changes, we need to create a new child + // policy. When this happens, we leave child_policy_ as-is and store + // the new child policy in pending_child_policy_. Once the new child + // policy transitions into state READY, we swap it into child_policy_, + // replacing the original child policy. So pending_child_policy_ is + // non-null only between when we apply an update that changes the child + // policy name and when the new child reports state READY. + // + // Updates can arrive at any point during this transition. We always + // apply updates relative to the most recently created child policy, + // even if the most recent one is still in pending_child_policy_. This + // is true both when applying the updates to an existing child policy + // and when determining whether we need to create a new policy. + // + // As a result of this, there are several cases to consider here: + // + // 1. We have no existing child policy (i.e., we have started up but + // have not yet received a serverlist from the balancer or gone + // into fallback mode; in this case, both child_policy_ and + // pending_child_policy_ are null). In this case, we create a + // new child policy and store it in child_policy_. + // + // 2. We have an existing child policy and have no pending child policy + // from a previous update (i.e., either there has not been a + // previous update that changed the policy name, or we have already + // finished swapping in the new policy; in this case, child_policy_ + // is non-null but pending_child_policy_ is null). In this case: + // a. If child_policy_->name() equals child_policy_name, then we + // update the existing child policy. + // b. If child_policy_->name() does not equal child_policy_name, + // we create a new policy. The policy will be stored in + // pending_child_policy_ and will later be swapped into + // child_policy_ by the helper when the new child transitions + // into state READY. + // + // 3. We have an existing child policy and have a pending child policy + // from a previous update (i.e., a previous update set + // pending_child_policy_ as per case 2b above and that policy has + // not yet transitioned into state READY and been swapped into + // child_policy_; in this case, both child_policy_ and + // pending_child_policy_ are non-null). In this case: + // a. If pending_child_policy_->name() equals child_policy_name, + // then we update the existing pending child policy. + // b. If pending_child_policy->name() does not equal + // child_policy_name, then we create a new policy. The new + // policy is stored in pending_child_policy_ (replacing the one + // that was there before, which will be immediately shut down) + // and will later be swapped into child_policy_ by the helper + // when the new child transitions into state READY. + const char* child_policy_name = child_policy_config_ == nullptr + ? "round_robin" + : child_policy_config_->name(); + const bool create_policy = + // case 1 + child_policy_ == nullptr || + // case 2b + (pending_child_policy_ == nullptr && + strcmp(child_policy_->name(), child_policy_name) != 0) || + // case 3b + (pending_child_policy_ != nullptr && + strcmp(pending_child_policy_->name(), child_policy_name) != 0); + LoadBalancingPolicy* policy_to_update = nullptr; + if (create_policy) { + // Cases 1, 2b, and 3b: create a new child policy. + // If child_policy_ is null, we set it (case 1), else we set + // pending_child_policy_ (cases 2b and 3b). + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_glb_trace)) { + gpr_log(GPR_INFO, "[grpclb %p] Creating new %schild policy %s", this, + child_policy_ == nullptr ? "" : "pending ", child_policy_name); } + auto new_policy = + CreateChildPolicyLocked(child_policy_name, update_args.args); + // Swap the policy into place. + auto& lb_policy = + child_policy_ == nullptr ? child_policy_ : pending_child_policy_; + { + MutexLock lock(&child_policy_mu_); + lb_policy = std::move(new_policy); + } + policy_to_update = lb_policy.get(); + } else { + // Cases 2a and 3a: update an existing policy. + // If we have a pending child policy, send the update to the pending + // policy (case 3a), else send it to the current policy (case 2a). + policy_to_update = pending_child_policy_ != nullptr + ? pending_child_policy_.get() + : child_policy_.get(); } - grpc_channel_args_destroy(args); -} - -void GrpcLb::OnRoundRobinRequestReresolutionLocked(void* arg, - grpc_error* error) { - GrpcLb* grpclb_policy = static_cast(arg); - if (grpclb_policy->shutting_down_ || error != GRPC_ERROR_NONE) { - grpclb_policy->Unref(DEBUG_LOCATION, "on_rr_reresolution_requested"); - return; + GPR_ASSERT(policy_to_update != nullptr); + // Update the policy. + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_glb_trace)) { + gpr_log(GPR_INFO, "[grpclb %p] Updating %schild policy %p", this, + policy_to_update == pending_child_policy_.get() ? "pending " : "", + policy_to_update); } - if (grpc_lb_glb_trace.enabled()) { - gpr_log( - GPR_INFO, - "[grpclb %p] Re-resolution requested from the internal RR policy (%p).", - grpclb_policy, grpclb_policy->rr_policy_.get()); - } - // If we are talking to a balancer, we expect to get updated addresses form - // the balancer, so we can ignore the re-resolution request from the RR - // policy. Otherwise, handle the re-resolution request using the - // grpclb policy's original re-resolution closure. - if (grpclb_policy->lb_calld_ == nullptr || - !grpclb_policy->lb_calld_->seen_initial_response()) { - grpclb_policy->TryReresolutionLocked(&grpc_lb_glb_trace, GRPC_ERROR_NONE); - } - // Give back the wrapper closure to the RR policy. - grpclb_policy->rr_policy_->SetReresolutionClosureLocked( - &grpclb_policy->on_rr_request_reresolution_); -} - -void GrpcLb::UpdateConnectivityStateFromRoundRobinPolicyLocked( - grpc_error* rr_state_error) { - const grpc_connectivity_state curr_glb_state = - grpc_connectivity_state_check(&state_tracker_); - /* The new connectivity status is a function of the previous one and the new - * input coming from the status of the RR policy. - * - * current state (grpclb's) - * | - * v || I | C | R | TF | SD | <- new state (RR's) - * ===++====+=====+=====+======+======+ - * I || I | C | R | [I] | [I] | - * ---++----+-----+-----+------+------+ - * C || I | C | R | [C] | [C] | - * ---++----+-----+-----+------+------+ - * R || I | C | R | [R] | [R] | - * ---++----+-----+-----+------+------+ - * TF || I | C | R | [TF] | [TF] | - * ---++----+-----+-----+------+------+ - * SD || NA | NA | NA | NA | NA | (*) - * ---++----+-----+-----+------+------+ - * - * A [STATE] indicates that the old RR policy is kept. In those cases, STATE - * is the current state of grpclb, which is left untouched. - * - * In summary, if the new state is TRANSIENT_FAILURE or SHUTDOWN, stick to - * the previous RR instance. - * - * Note that the status is never updated to SHUTDOWN as a result of calling - * this function. Only glb_shutdown() has the power to set that state. - * - * (*) This function mustn't be called during shutting down. */ - GPR_ASSERT(curr_glb_state != GRPC_CHANNEL_SHUTDOWN); - switch (rr_connectivity_state_) { - case GRPC_CHANNEL_TRANSIENT_FAILURE: - case GRPC_CHANNEL_SHUTDOWN: - GPR_ASSERT(rr_state_error != GRPC_ERROR_NONE); - break; - case GRPC_CHANNEL_IDLE: - case GRPC_CHANNEL_CONNECTING: - case GRPC_CHANNEL_READY: - GPR_ASSERT(rr_state_error == GRPC_ERROR_NONE); - } - if (grpc_lb_glb_trace.enabled()) { - gpr_log( - GPR_INFO, - "[grpclb %p] Setting grpclb's state to %s from new RR policy %p state.", - this, grpc_connectivity_state_name(rr_connectivity_state_), - rr_policy_.get()); - } - grpc_connectivity_state_set(&state_tracker_, rr_connectivity_state_, - rr_state_error, - "update_lb_connectivity_status_locked"); -} - -void GrpcLb::OnRoundRobinConnectivityChangedLocked(void* arg, - grpc_error* error) { - GrpcLb* grpclb_policy = static_cast(arg); - if (grpclb_policy->shutting_down_) { - grpclb_policy->Unref(DEBUG_LOCATION, "on_rr_connectivity_changed"); - return; - } - grpclb_policy->UpdateConnectivityStateFromRoundRobinPolicyLocked( - GRPC_ERROR_REF(error)); - // Resubscribe. Reuse the "on_rr_connectivity_changed" ref. - grpclb_policy->rr_policy_->NotifyOnStateChangeLocked( - &grpclb_policy->rr_connectivity_state_, - &grpclb_policy->on_rr_connectivity_changed_); + policy_to_update->UpdateLocked(std::move(update_args)); } // @@ -1846,24 +1794,45 @@ void GrpcLb::OnRoundRobinConnectivityChangedLocked(void* arg, class GrpcLbFactory : public LoadBalancingPolicyFactory { public: OrphanablePtr CreateLoadBalancingPolicy( - const LoadBalancingPolicy::Args& args) const override { - /* Count the number of gRPC-LB addresses. There must be at least one. */ - const grpc_arg* arg = - grpc_channel_args_find(args.args, GRPC_ARG_LB_ADDRESSES); - if (arg == nullptr || arg->type != GRPC_ARG_POINTER) { - return nullptr; - } - grpc_lb_addresses* addresses = - static_cast(arg->value.pointer.p); - size_t num_grpclb_addrs = 0; - for (size_t i = 0; i < addresses->num_addresses; ++i) { - if (addresses->addresses[i].is_balancer) ++num_grpclb_addrs; - } - if (num_grpclb_addrs == 0) return nullptr; - return OrphanablePtr(New(addresses, args)); + LoadBalancingPolicy::Args args) const override { + return OrphanablePtr(New(std::move(args))); } - const char* name() const override { return "grpclb"; } + const char* name() const override { return kGrpclb; } + + RefCountedPtr ParseLoadBalancingConfig( + const grpc_json* json, grpc_error** error) const override { + GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); + if (json == nullptr) { + return RefCountedPtr( + New(nullptr)); + } + InlinedVector error_list; + RefCountedPtr child_policy; + for (const grpc_json* field = json->child; field != nullptr; + field = field->next) { + if (field->key == nullptr) continue; + if (strcmp(field->key, "childPolicy") == 0) { + if (child_policy != nullptr) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:childPolicy error:Duplicate entry")); + } + grpc_error* parse_error = GRPC_ERROR_NONE; + child_policy = LoadBalancingPolicyRegistry::ParseLoadBalancingConfig( + field, &parse_error); + if (parse_error != GRPC_ERROR_NONE) { + error_list.push_back(parse_error); + } + } + } + if (error_list.empty()) { + return RefCountedPtr( + New(std::move(child_policy))); + } else { + *error = GRPC_ERROR_CREATE_FROM_VECTOR("GrpcLb Parser", &error_list); + return nullptr; + } + } }; } // namespace diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.cc index fd873f096d8..b713e26713f 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.cc @@ -21,6 +21,6 @@ #include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h" grpc_channel_args* grpc_lb_policy_grpclb_modify_lb_channel_args( - grpc_channel_args* args) { + const grpc_core::ServerAddressList& addresses, grpc_channel_args* args) { return args; } diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h index 825065a9c32..c78ba36cf1d 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h @@ -21,7 +21,9 @@ #include -#include "src/core/ext/filters/client_channel/lb_policy_factory.h" +#include + +#include "src/core/ext/filters/client_channel/server_address.h" /// Makes any necessary modifications to \a args for use in the grpclb /// balancer channel. @@ -30,7 +32,7 @@ /// /// Caller takes ownership of the returned args. grpc_channel_args* grpc_lb_policy_grpclb_modify_lb_channel_args( - grpc_channel_args* args); + const grpc_core::ServerAddressList& addresses, grpc_channel_args* args); #endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_GRPCLB_GRPCLB_CHANNEL_H \ */ diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc index 441efd5e23b..892cdeb27b7 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc @@ -26,6 +26,7 @@ #include #include "src/core/ext/filters/client_channel/client_channel.h" +#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/iomgr/sockaddr_utils.h" @@ -42,22 +43,23 @@ int BalancerNameCmp(const grpc_core::UniquePtr& a, } RefCountedPtr CreateTargetAuthorityTable( - grpc_lb_addresses* addresses) { + const ServerAddressList& addresses) { TargetAuthorityTable::Entry* target_authority_entries = - static_cast(gpr_zalloc( - sizeof(*target_authority_entries) * addresses->num_addresses)); - for (size_t i = 0; i < addresses->num_addresses; ++i) { + static_cast( + gpr_zalloc(sizeof(*target_authority_entries) * addresses.size())); + for (size_t i = 0; i < addresses.size(); ++i) { char* addr_str; - GPR_ASSERT(grpc_sockaddr_to_string( - &addr_str, &addresses->addresses[i].address, true) > 0); + GPR_ASSERT( + grpc_sockaddr_to_string(&addr_str, &addresses[i].address(), true) > 0); target_authority_entries[i].key = grpc_slice_from_copied_string(addr_str); - target_authority_entries[i].value.reset( - gpr_strdup(addresses->addresses[i].balancer_name)); gpr_free(addr_str); + char* balancer_name = grpc_channel_arg_get_string(grpc_channel_args_find( + addresses[i].args(), GRPC_ARG_ADDRESS_BALANCER_NAME)); + target_authority_entries[i].value.reset(gpr_strdup(balancer_name)); } RefCountedPtr target_authority_table = - TargetAuthorityTable::Create(addresses->num_addresses, - target_authority_entries, BalancerNameCmp); + TargetAuthorityTable::Create(addresses.size(), target_authority_entries, + BalancerNameCmp); gpr_free(target_authority_entries); return target_authority_table; } @@ -66,17 +68,12 @@ RefCountedPtr CreateTargetAuthorityTable( } // namespace grpc_core grpc_channel_args* grpc_lb_policy_grpclb_modify_lb_channel_args( - grpc_channel_args* args) { + const grpc_core::ServerAddressList& addresses, grpc_channel_args* args) { const char* args_to_remove[1]; size_t num_args_to_remove = 0; grpc_arg args_to_add[2]; size_t num_args_to_add = 0; // Add arg for targets info table. - const grpc_arg* arg = grpc_channel_args_find(args, GRPC_ARG_LB_ADDRESSES); - GPR_ASSERT(arg != nullptr); - GPR_ASSERT(arg->type == GRPC_ARG_POINTER); - grpc_lb_addresses* addresses = - static_cast(arg->value.pointer.p); grpc_core::RefCountedPtr target_authority_table = grpc_core::CreateTargetAuthorityTable(addresses); args_to_add[num_args_to_add++] = @@ -87,22 +84,18 @@ grpc_channel_args* grpc_lb_policy_grpclb_modify_lb_channel_args( // bearer token credentials. grpc_channel_credentials* channel_credentials = grpc_channel_credentials_find_in_args(args); - grpc_channel_credentials* creds_sans_call_creds = nullptr; + grpc_core::RefCountedPtr creds_sans_call_creds; if (channel_credentials != nullptr) { creds_sans_call_creds = - grpc_channel_credentials_duplicate_without_call_credentials( - channel_credentials); + channel_credentials->duplicate_without_call_credentials(); GPR_ASSERT(creds_sans_call_creds != nullptr); args_to_remove[num_args_to_remove++] = GRPC_ARG_CHANNEL_CREDENTIALS; args_to_add[num_args_to_add++] = - grpc_channel_credentials_to_arg(creds_sans_call_creds); + grpc_channel_credentials_to_arg(creds_sans_call_creds.get()); } grpc_channel_args* result = grpc_channel_args_copy_and_add_and_remove( args, args_to_remove, num_args_to_remove, args_to_add, num_args_to_add); // Clean up. grpc_channel_args_destroy(args); - if (creds_sans_call_creds != nullptr) { - grpc_channel_credentials_unref(creds_sans_call_creds); - } return result; } diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc index 087cd8f276e..35123633feb 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc @@ -25,6 +25,8 @@ #include #include +#include "src/core/lib/gprpp/sync.h" + namespace grpc_core { void GrpcLbClientStats::AddCallStarted() { @@ -43,11 +45,12 @@ void GrpcLbClientStats::AddCallFinished( } } -void GrpcLbClientStats::AddCallDroppedLocked(char* token) { +void GrpcLbClientStats::AddCallDropped(const char* token) { // Increment num_calls_started and num_calls_finished. gpr_atm_full_fetch_add(&num_calls_started_, (gpr_atm)1); gpr_atm_full_fetch_add(&num_calls_finished_, (gpr_atm)1); // Record the drop. + MutexLock lock(&drop_count_mu_); if (drop_token_counts_ == nullptr) { drop_token_counts_.reset(New()); } @@ -69,7 +72,7 @@ void AtomicGetAndResetCounter(int64_t* value, gpr_atm* counter) { } // namespace -void GrpcLbClientStats::GetLocked( +void GrpcLbClientStats::Get( int64_t* num_calls_started, int64_t* num_calls_finished, int64_t* num_calls_finished_with_client_failed_to_send, int64_t* num_calls_finished_known_received, @@ -80,6 +83,7 @@ void GrpcLbClientStats::GetLocked( &num_calls_finished_with_client_failed_to_send_); AtomicGetAndResetCounter(num_calls_finished_known_received, &num_calls_finished_known_received_); + MutexLock lock(&drop_count_mu_); *drop_token_counts = std::move(drop_token_counts_); } diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h index 18ab2c94529..bcc6598c105 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h @@ -26,6 +26,7 @@ #include "src/core/lib/gprpp/inlined_vector.h" #include "src/core/lib/gprpp/memory.h" #include "src/core/lib/gprpp/ref_counted.h" +#include "src/core/lib/gprpp/sync.h" namespace grpc_core { @@ -41,29 +42,30 @@ class GrpcLbClientStats : public RefCounted { typedef InlinedVector DroppedCallCounts; - GrpcLbClientStats() {} - void AddCallStarted(); void AddCallFinished(bool finished_with_client_failed_to_send, bool finished_known_received); - // This method is not thread-safe; caller must synchronize. - void AddCallDroppedLocked(char* token); + void AddCallDropped(const char* token); - // This method is not thread-safe; caller must synchronize. - void GetLocked(int64_t* num_calls_started, int64_t* num_calls_finished, - int64_t* num_calls_finished_with_client_failed_to_send, - int64_t* num_calls_finished_known_received, - UniquePtr* drop_token_counts); + void Get(int64_t* num_calls_started, int64_t* num_calls_finished, + int64_t* num_calls_finished_with_client_failed_to_send, + int64_t* num_calls_finished_known_received, + UniquePtr* drop_token_counts); + + // A destruction function to use as the user_data key when attaching + // client stats to a grpc_mdelem. + static void Destroy(void* arg) { + static_cast(arg)->Unref(); + } private: - // This field must only be accessed via *_locked() methods. - UniquePtr drop_token_counts_; - // These fields may be accessed from multiple threads at a time. gpr_atm num_calls_started_ = 0; gpr_atm num_calls_finished_ = 0; gpr_atm num_calls_finished_with_client_failed_to_send_ = 0; gpr_atm num_calls_finished_known_received_ = 0; + Mutex drop_count_mu_; // Guards drop_token_counts_. + UniquePtr drop_token_counts_; }; } // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc index f24281a5bfb..b51db110395 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc @@ -107,7 +107,7 @@ static bool encode_drops(pb_ostream_t* stream, const pb_field_t* field, return true; } -grpc_grpclb_request* grpc_grpclb_load_report_request_create_locked( +grpc_grpclb_request* grpc_grpclb_load_report_request_create( grpc_core::GrpcLbClientStats* client_stats) { grpc_grpclb_request* req = static_cast( gpr_zalloc(sizeof(grpc_grpclb_request))); @@ -122,7 +122,7 @@ grpc_grpclb_request* grpc_grpclb_load_report_request_create_locked( req->client_stats.calls_finished_with_drop.funcs.encode = encode_drops; grpc_core::UniquePtr drop_counts; - client_stats->GetLocked( + client_stats->Get( &req->client_stats.num_calls_started, &req->client_stats.num_calls_finished, &req->client_stats.num_calls_finished_with_client_failed_to_send, @@ -161,10 +161,10 @@ void grpc_grpclb_request_destroy(grpc_grpclb_request* request) { typedef grpc_lb_v1_LoadBalanceResponse grpc_grpclb_response; grpc_grpclb_initial_response* grpc_grpclb_initial_response_parse( - grpc_slice encoded_grpc_grpclb_response) { - pb_istream_t stream = - pb_istream_from_buffer(GRPC_SLICE_START_PTR(encoded_grpc_grpclb_response), - GRPC_SLICE_LENGTH(encoded_grpc_grpclb_response)); + const grpc_slice& encoded_grpc_grpclb_response) { + pb_istream_t stream = pb_istream_from_buffer( + const_cast(GRPC_SLICE_START_PTR(encoded_grpc_grpclb_response)), + GRPC_SLICE_LENGTH(encoded_grpc_grpclb_response)); grpc_grpclb_response res; memset(&res, 0, sizeof(grpc_grpclb_response)); if (GPR_UNLIKELY( @@ -185,10 +185,10 @@ grpc_grpclb_initial_response* grpc_grpclb_initial_response_parse( } grpc_grpclb_serverlist* grpc_grpclb_response_parse_serverlist( - grpc_slice encoded_grpc_grpclb_response) { - pb_istream_t stream = - pb_istream_from_buffer(GRPC_SLICE_START_PTR(encoded_grpc_grpclb_response), - GRPC_SLICE_LENGTH(encoded_grpc_grpclb_response)); + const grpc_slice& encoded_grpc_grpclb_response) { + pb_istream_t stream = pb_istream_from_buffer( + const_cast(GRPC_SLICE_START_PTR(encoded_grpc_grpclb_response)), + GRPC_SLICE_LENGTH(encoded_grpc_grpclb_response)); pb_istream_t stream_at_start = stream; grpc_grpclb_serverlist* sl = static_cast( gpr_zalloc(sizeof(grpc_grpclb_serverlist))); diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h b/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h index 9ca7b28d8e6..8005f6fe301 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h @@ -25,7 +25,7 @@ #include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h" #include "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h" -#include "src/core/ext/filters/client_channel/lb_policy_factory.h" +#include "src/core/lib/iomgr/exec_ctx.h" #define GRPC_GRPCLB_SERVICE_NAME_MAX_LENGTH 128 @@ -43,7 +43,7 @@ typedef struct { /** Create a request for a gRPC LB service under \a lb_service_name */ grpc_grpclb_request* grpc_grpclb_request_create(const char* lb_service_name); -grpc_grpclb_request* grpc_grpclb_load_report_request_create_locked( +grpc_grpclb_request* grpc_grpclb_load_report_request_create( grpc_core::GrpcLbClientStats* client_stats); /** Protocol Buffers v3-encode \a request */ @@ -55,11 +55,11 @@ void grpc_grpclb_request_destroy(grpc_grpclb_request* request); /** Parse (ie, decode) the bytes in \a encoded_grpc_grpclb_response as a \a * grpc_grpclb_initial_response */ grpc_grpclb_initial_response* grpc_grpclb_initial_response_parse( - grpc_slice encoded_grpc_grpclb_response); + const grpc_slice& encoded_grpc_grpclb_response); /** Parse the list of servers from an encoded \a grpc_grpclb_response */ grpc_grpclb_serverlist* grpc_grpclb_response_parse_serverlist( - grpc_slice encoded_grpc_grpclb_response); + const grpc_slice& encoded_grpc_grpclb_response); /** Return a copy of \a sl. The caller is responsible for calling \a * grpc_grpclb_destroy_serverlist on the returned copy. */ 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 d454401a669..199e973e72c 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 @@ -24,10 +24,10 @@ #include "src/core/ext/filters/client_channel/lb_policy/subchannel_list.h" #include "src/core/ext/filters/client_channel/lb_policy_registry.h" +#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/ext/filters/client_channel/subchannel.h" -#include "src/core/ext/filters/client_channel/subchannel_index.h" #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gprpp/mutex_lock.h" +#include "src/core/lib/gprpp/sync.h" #include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/sockaddr_utils.h" #include "src/core/lib/transport/connectivity_state.h" @@ -42,22 +42,15 @@ namespace { // pick_first LB policy // +constexpr char kPickFirst[] = "pick_first"; + class PickFirst : public LoadBalancingPolicy { public: - explicit PickFirst(const Args& args); + explicit PickFirst(Args args); - void UpdateLocked(const grpc_channel_args& args, - grpc_json* lb_config) override; - bool PickLocked(PickState* pick, grpc_error** error) override; - void CancelPickLocked(PickState* pick, grpc_error* error) override; - void CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask, - uint32_t initial_metadata_flags_eq, - grpc_error* error) override; - void NotifyOnStateChangeLocked(grpc_connectivity_state* state, - grpc_closure* closure) override; - grpc_connectivity_state CheckConnectivityLocked( - grpc_error** connectivity_error) override; - void HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) override; + const char* name() const override { return kPickFirst; } + + void UpdateLocked(UpdateArgs args) override; void ExitIdleLocked() override; void ResetBackoffLocked() override; void FillChildRefsForChannelz(channelz::ChildRefsList* child_subchannels, @@ -75,14 +68,11 @@ class PickFirst : public LoadBalancingPolicy { PickFirstSubchannelData( SubchannelList* 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) {} + const ServerAddress& address, Subchannel* subchannel) + : SubchannelData(subchannel_list, address, subchannel) {} void ProcessConnectivityChangeLocked( - grpc_connectivity_state connectivity_state, grpc_error* error) override; + grpc_connectivity_state connectivity_state) override; // Processes the connectivity change to READY for an unselected subchannel. void ProcessUnselectedReadyLocked(); @@ -95,12 +85,11 @@ class PickFirst : public LoadBalancingPolicy { PickFirstSubchannelData> { public: PickFirstSubchannelList(PickFirst* policy, TraceFlag* tracer, - const grpc_lb_addresses* addresses, + const ServerAddressList& 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) { + policy->channel_control_helper(), 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. @@ -111,6 +100,28 @@ class PickFirst : public LoadBalancingPolicy { PickFirst* p = static_cast(policy()); p->Unref(DEBUG_LOCATION, "subchannel_list"); } + + bool in_transient_failure() const { return in_transient_failure_; } + void set_in_transient_failure(bool in_transient_failure) { + in_transient_failure_ = in_transient_failure; + } + + private: + bool in_transient_failure_ = false; + }; + + class Picker : public SubchannelPicker { + public: + explicit Picker(RefCountedPtr connected_subchannel) + : connected_subchannel_(std::move(connected_subchannel)) {} + + PickResult Pick(PickArgs* pick, grpc_error** error) override { + pick->connected_subchannel = connected_subchannel_; + return PICK_COMPLETE; + } + + private: + RefCountedPtr connected_subchannel_; }; // Helper class to ensure that any function that modifies the child refs @@ -127,7 +138,6 @@ class PickFirst : public LoadBalancingPolicy { void ShutdownLocked() override; - void StartPickingLocked(); void UpdateChildRefsLocked(); // All our subchannels. @@ -136,130 +146,58 @@ class PickFirst : public LoadBalancingPolicy { OrphanablePtr latest_pending_subchannel_list_; // Selected subchannel in \a subchannel_list_. PickFirstSubchannelData* selected_ = nullptr; - // Have we started picking? - bool started_picking_ = false; + // Are we in IDLE state? + bool idle_ = false; // Are we shut down? bool shutdown_ = false; - // List of picks that are waiting on connectivity. - PickState* pending_picks_ = nullptr; - // Our connectivity state tracker. - grpc_connectivity_state_tracker state_tracker_; /// Lock and data used to capture snapshots of this channels child /// channels and subchannels. This data is consumed by channelz. - gpr_mu child_refs_mu_; + Mutex child_refs_mu_; channelz::ChildRefsList child_subchannels_; channelz::ChildRefsList child_channels_; }; -PickFirst::PickFirst(const Args& args) : LoadBalancingPolicy(args) { - GPR_ASSERT(args.client_channel_factory != nullptr); - gpr_mu_init(&child_refs_mu_); - grpc_connectivity_state_init(&state_tracker_, GRPC_CHANNEL_IDLE, - "pick_first"); - if (grpc_lb_pick_first_trace.enabled()) { +PickFirst::PickFirst(Args args) : LoadBalancingPolicy(std::move(args)) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_pick_first_trace)) { gpr_log(GPR_INFO, "Pick First %p created.", this); } - UpdateLocked(*args.args, args.lb_config); - grpc_subchannel_index_ref(); } PickFirst::~PickFirst() { - if (grpc_lb_pick_first_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_pick_first_trace)) { gpr_log(GPR_INFO, "Destroying Pick First %p", this); } - gpr_mu_destroy(&child_refs_mu_); GPR_ASSERT(subchannel_list_ == nullptr); GPR_ASSERT(latest_pending_subchannel_list_ == nullptr); - GPR_ASSERT(pending_picks_ == nullptr); - grpc_connectivity_state_destroy(&state_tracker_); - grpc_subchannel_index_unref(); -} - -void PickFirst::HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) { - PickState* pick; - while ((pick = pending_picks_) != nullptr) { - pending_picks_ = pick->next; - grpc_error* error = GRPC_ERROR_NONE; - if (new_policy->PickLocked(pick, &error)) { - // Synchronous return, schedule closure. - GRPC_CLOSURE_SCHED(pick->on_complete, error); - } - } } void PickFirst::ShutdownLocked() { AutoChildRefsUpdater guard(this); - grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Channel shutdown"); - if (grpc_lb_pick_first_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_pick_first_trace)) { gpr_log(GPR_INFO, "Pick First %p Shutting down", this); } shutdown_ = true; - PickState* pick; - while ((pick = pending_picks_) != nullptr) { - pending_picks_ = pick->next; - pick->connected_subchannel.reset(); - GRPC_CLOSURE_SCHED(pick->on_complete, GRPC_ERROR_REF(error)); - } - grpc_connectivity_state_set(&state_tracker_, GRPC_CHANNEL_SHUTDOWN, - GRPC_ERROR_REF(error), "shutdown"); subchannel_list_.reset(); latest_pending_subchannel_list_.reset(); - TryReresolutionLocked(&grpc_lb_pick_first_trace, GRPC_ERROR_CANCELLED); - GRPC_ERROR_UNREF(error); -} - -void PickFirst::CancelPickLocked(PickState* pick, grpc_error* error) { - PickState* pp = pending_picks_; - pending_picks_ = nullptr; - while (pp != nullptr) { - PickState* next = pp->next; - if (pp == pick) { - pick->connected_subchannel.reset(); - GRPC_CLOSURE_SCHED(pick->on_complete, - GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Pick Cancelled", &error, 1)); - } else { - pp->next = pending_picks_; - pending_picks_ = pp; - } - pp = next; - } - GRPC_ERROR_UNREF(error); -} - -void PickFirst::CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask, - uint32_t initial_metadata_flags_eq, - grpc_error* error) { - PickState* pick = pending_picks_; - pending_picks_ = nullptr; - while (pick != nullptr) { - PickState* next = pick->next; - if ((pick->initial_metadata_flags & initial_metadata_flags_mask) == - initial_metadata_flags_eq) { - GRPC_CLOSURE_SCHED(pick->on_complete, - GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Pick Cancelled", &error, 1)); - } else { - pick->next = pending_picks_; - pending_picks_ = pick; - } - pick = next; - } - GRPC_ERROR_UNREF(error); -} - -void PickFirst::StartPickingLocked() { - started_picking_ = true; - if (subchannel_list_ != nullptr && subchannel_list_->num_subchannels() > 0) { - subchannel_list_->subchannel(0) - ->CheckConnectivityStateAndStartWatchingLocked(); - } } void PickFirst::ExitIdleLocked() { - if (!started_picking_) { - StartPickingLocked(); + if (shutdown_) return; + if (idle_) { + idle_ = false; + if (subchannel_list_ == nullptr || + subchannel_list_->num_subchannels() == 0) { + grpc_error* error = grpc_error_set_int( + GRPC_ERROR_CREATE_FROM_STATIC_STRING("No addresses to connect to"), + GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE); + channel_control_helper()->UpdateState( + GRPC_CHANNEL_TRANSIENT_FAILURE, + UniquePtr(New(error))); + } else { + subchannel_list_->subchannel(0) + ->CheckConnectivityStateAndStartWatchingLocked(); + } } } @@ -270,36 +208,6 @@ void PickFirst::ResetBackoffLocked() { } } -bool PickFirst::PickLocked(PickState* pick, grpc_error** error) { - // If we have a selected subchannel already, return synchronously. - if (selected_ != nullptr) { - pick->connected_subchannel = selected_->connected_subchannel()->Ref(); - return true; - } - // No subchannel selected yet, so handle asynchronously. - if (pick->on_complete == nullptr) { - *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "No pick result available but synchronous result required."); - return true; - } - pick->next = pending_picks_; - pending_picks_ = pick; - if (!started_picking_) { - StartPickingLocked(); - } - return false; -} - -grpc_connectivity_state PickFirst::CheckConnectivityLocked(grpc_error** error) { - return grpc_connectivity_state_get(&state_tracker_, error); -} - -void PickFirst::NotifyOnStateChangeLocked(grpc_connectivity_state* current, - grpc_closure* notify) { - grpc_connectivity_state_notify_on_state_change(&state_tracker_, current, - notify); -} - void PickFirst::FillChildRefsForChannelz( channelz::ChildRefsList* child_subchannels_to_fill, channelz::ChildRefsList* ignored) { @@ -334,101 +242,82 @@ void PickFirst::UpdateChildRefsLocked() { child_subchannels_ = std::move(cs); } -void PickFirst::UpdateLocked(const grpc_channel_args& args, - grpc_json* lb_config) { +void PickFirst::UpdateLocked(UpdateArgs args) { AutoChildRefsUpdater guard(this); - const grpc_arg* arg = grpc_channel_args_find(&args, GRPC_ARG_LB_ADDRESSES); - if (arg == nullptr || arg->type != GRPC_ARG_POINTER) { - if (subchannel_list_ == nullptr) { - // If we don't have a current subchannel list, go into TRANSIENT FAILURE. - grpc_connectivity_state_set( - &state_tracker_, GRPC_CHANNEL_TRANSIENT_FAILURE, - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Missing update in args"), - "pf_update_missing"); - } else { - // otherwise, keep using the current subchannel list (ignore this update). - gpr_log(GPR_ERROR, - "No valid LB addresses channel arg for Pick First %p update, " - "ignoring.", - this); - } - return; - } - const grpc_lb_addresses* addresses = - static_cast(arg->value.pointer.p); - if (grpc_lb_pick_first_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_pick_first_trace)) { gpr_log(GPR_INFO, "Pick First %p received update with %" PRIuPTR " addresses", this, - addresses->num_addresses); + args.addresses.size()); } grpc_arg new_arg = grpc_channel_arg_integer_create( const_cast(GRPC_ARG_INHIBIT_HEALTH_CHECKING), 1); grpc_channel_args* new_args = - grpc_channel_args_copy_and_add(&args, &new_arg, 1); + grpc_channel_args_copy_and_add(args.args, &new_arg, 1); auto subchannel_list = MakeOrphanable( - this, &grpc_lb_pick_first_trace, addresses, combiner(), - client_channel_factory(), *new_args); + this, &grpc_lb_pick_first_trace, args.addresses, combiner(), *new_args); grpc_channel_args_destroy(new_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"); + // subchannels. subchannel_list_ = std::move(subchannel_list); // Empty list. selected_ = nullptr; + // If not idle, put the channel in TRANSIENT_FAILURE. + // (If we are idle, then this will happen in ExitIdleLocked() if we + // haven't gotten a non-empty update by the time the application tries + // to start a new call.) + if (!idle_) { + grpc_error* error = grpc_error_set_int( + GRPC_ERROR_CREATE_FROM_STATIC_STRING("Empty update"), + GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE); + channel_control_helper()->UpdateState( + GRPC_CHANNEL_TRANSIENT_FAILURE, + UniquePtr(New(error))); + } return; } + // If one of the subchannels in the new list is already in state + // READY, then select it immediately. This can happen when the + // currently selected subchannel is also present in the update. It + // can also happen if one of the subchannels in the update is already + // in the global subchannel pool because it's in use by another channel. + // TODO(roth): If we're in IDLE state, we should probably defer this + // check and instead do it in ExitIdleLocked(). + for (size_t i = 0; i < subchannel_list->num_subchannels(); ++i) { + PickFirstSubchannelData* sd = subchannel_list->subchannel(i); + grpc_connectivity_state state = sd->CheckConnectivityStateLocked(); + if (state == GRPC_CHANNEL_READY) { + subchannel_list_ = std::move(subchannel_list); + sd->StartConnectivityWatchLocked(); + sd->ProcessUnselectedReadyLocked(); + // 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(); + // Make sure that subsequent calls to ExitIdleLocked() don't cause + // us to start watching a subchannel other than the one we've + // selected. + idle_ = false; + return; + } + } if (selected_ == nullptr) { // We don't yet have a selected subchannel, so replace the current // subchannel list immediately. subchannel_list_ = std::move(subchannel_list); - // If we've started picking, start trying to connect to the first + // If we're not in IDLE state, start trying to connect to the first // subchannel in the new list. - if (started_picking_) { - subchannel_list_->subchannel(0) - ->CheckConnectivityStateAndStartWatchingLocked(); + if (!idle_) { + // Note: No need to use CheckConnectivityStateAndStartWatchingLocked() + // here, since we've already checked the initial connectivity + // state of all subchannels above. + subchannel_list_->subchannel(0)->StartConnectivityWatchLocked(); + subchannel_list_->subchannel(0)->subchannel()->AttemptToConnect(); } } 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) { - 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()); - } - // 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); - 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; - } - GRPC_ERROR_UNREF(error); - } - } - // Not keeping the previous selected subchannel, so set the latest - // pending subchannel list to the new subchannel list. We will wait - // for it to report READY before swapping it into the current - // subchannel list. + // We do have a selected subchannel (which means it's READY), so keep + // using it until one of the subchannels in the new list reports READY. if (latest_pending_subchannel_list_ != nullptr) { - if (grpc_lb_pick_first_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_pick_first_trace)) { gpr_log(GPR_INFO, "Pick First %p Shutting down latest pending subchannel list " "%p, about to be replaced by newer latest %p", @@ -437,17 +326,23 @@ void PickFirst::UpdateLocked(const grpc_channel_args& args, } } latest_pending_subchannel_list_ = std::move(subchannel_list); - // If we've started picking, start trying to connect to the first + // If we're not in IDLE state, start trying to connect to the first // subchannel in the new list. - if (started_picking_) { + if (!idle_) { + // Note: No need to use CheckConnectivityStateAndStartWatchingLocked() + // here, since we've already checked the initial connectivity + // state of all subchannels above. latest_pending_subchannel_list_->subchannel(0) - ->CheckConnectivityStateAndStartWatchingLocked(); + ->StartConnectivityWatchLocked(); + latest_pending_subchannel_list_->subchannel(0) + ->subchannel() + ->AttemptToConnect(); } } } void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( - grpc_connectivity_state connectivity_state, grpc_error* error) { + grpc_connectivity_state connectivity_state) { PickFirst* p = static_cast(subchannel_list()->policy()); AutoChildRefsUpdater guard(p); // The notification must be for a subchannel in either the current or @@ -457,15 +352,16 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( GPR_ASSERT(connectivity_state != GRPC_CHANNEL_SHUTDOWN); // Handle updates for the currently selected subchannel. if (p->selected_ == this) { - if (grpc_lb_pick_first_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_pick_first_trace)) { gpr_log(GPR_INFO, - "Pick First %p connectivity changed for selected subchannel", p); + "Pick First %p selected subchannel connectivity changed to %s", p, + grpc_connectivity_state_name(connectivity_state)); } // If the new state is anything other than READY and there is a // pending update, switch to the pending update. if (connectivity_state != GRPC_CHANNEL_READY && p->latest_pending_subchannel_list_ != nullptr) { - if (grpc_lb_pick_first_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_pick_first_trace)) { gpr_log(GPR_INFO, "Pick First %p promoting pending subchannel list %p to " "replace %p", @@ -473,39 +369,51 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( p->subchannel_list_.get()); } p->selected_ = nullptr; - StopConnectivityWatchLocked(); + CancelConnectivityWatchLocked( + "selected subchannel failed; switching to pending update"); p->subchannel_list_ = std::move(p->latest_pending_subchannel_list_); - grpc_connectivity_state_set( - &p->state_tracker_, GRPC_CHANNEL_TRANSIENT_FAILURE, - 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"); + // Set our state to that of the pending subchannel list. + if (p->subchannel_list_->in_transient_failure()) { + grpc_error* error = grpc_error_set_int( + GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "selected subchannel failed; switching to pending update"), + GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE); + p->channel_control_helper()->UpdateState( + GRPC_CHANNEL_TRANSIENT_FAILURE, + UniquePtr(New(error))); + } else { + p->channel_control_helper()->UpdateState( + GRPC_CHANNEL_CONNECTING, + UniquePtr(New(p->Ref()))); + } } else { if (connectivity_state == GRPC_CHANNEL_TRANSIENT_FAILURE) { - // If the selected subchannel goes bad, request a re-resolution. We also - // set the channel state to IDLE and reset started_picking_. The reason - // is that if the new state is TRANSIENT_FAILURE due to a GOAWAY - // reception we don't want to connect to the re-resolved backends until - // we leave the IDLE state. - grpc_connectivity_state_set(&p->state_tracker_, GRPC_CHANNEL_IDLE, - GRPC_ERROR_NONE, - "selected_changed+reresolve"); - p->started_picking_ = false; - p->TryReresolutionLocked(&grpc_lb_pick_first_trace, GRPC_ERROR_NONE); - // In transient failure. Rely on re-resolution to recover. + // If the selected subchannel goes bad, request a re-resolution. We + // also set the channel state to IDLE. The reason is that if the new + // state is TRANSIENT_FAILURE due to a GOAWAY reception we don't want + // to connect to the re-resolved backends until we leave IDLE state. + p->idle_ = true; + p->channel_control_helper()->RequestReresolution(); p->selected_ = nullptr; - StopConnectivityWatchLocked(); + CancelConnectivityWatchLocked("selected subchannel failed; going IDLE"); + p->channel_control_helper()->UpdateState( + GRPC_CHANNEL_IDLE, + UniquePtr(New(p->Ref()))); } else { - grpc_connectivity_state_set(&p->state_tracker_, connectivity_state, - GRPC_ERROR_REF(error), "selected_changed"); - // Renew notification. - RenewConnectivityWatchLocked(); + // This is unlikely but can happen when a subchannel has been asked + // to reconnect by a different channel and this channel has dropped + // some connectivity state notifications. + if (connectivity_state == GRPC_CHANNEL_READY) { + p->channel_control_helper()->UpdateState( + GRPC_CHANNEL_READY, UniquePtr(New( + connected_subchannel()->Ref()))); + } else { // CONNECTING + p->channel_control_helper()->UpdateState( + connectivity_state, + UniquePtr(New(p->Ref()))); + } } } - GRPC_ERROR_UNREF(error); return; } // If we get here, there are two possible cases: @@ -517,26 +425,37 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( // 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. + subchannel_list()->set_in_transient_failure(false); switch (connectivity_state) { case GRPC_CHANNEL_READY: { ProcessUnselectedReadyLocked(); - // Renew notification. - RenewConnectivityWatchLocked(); break; } case GRPC_CHANNEL_TRANSIENT_FAILURE: { - StopConnectivityWatchLocked(); + CancelConnectivityWatchLocked("connection attempt failed"); PickFirstSubchannelData* sd = this; size_t next_index = (sd->Index() + 1) % subchannel_list()->num_subchannels(); sd = subchannel_list()->subchannel(next_index); - // Case 1: Only set state to TRANSIENT_FAILURE if we've tried - // all subchannels. - if (sd->Index() == 0 && subchannel_list() == p->subchannel_list_.get()) { - p->TryReresolutionLocked(&grpc_lb_pick_first_trace, GRPC_ERROR_NONE); - grpc_connectivity_state_set( - &p->state_tracker_, GRPC_CHANNEL_TRANSIENT_FAILURE, - GRPC_ERROR_REF(error), "exhausted_subchannels"); + // If we're tried all subchannels, set state to TRANSIENT_FAILURE. + if (sd->Index() == 0) { + // Re-resolve if this is the most recent subchannel list. + if (subchannel_list() == (p->latest_pending_subchannel_list_ != nullptr + ? p->latest_pending_subchannel_list_.get() + : p->subchannel_list_.get())) { + p->channel_control_helper()->RequestReresolution(); + } + subchannel_list()->set_in_transient_failure(true); + // Only report new state in case 1. + if (subchannel_list() == p->subchannel_list_.get()) { + grpc_error* error = grpc_error_set_int( + GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "failed to connect to all addresses"), + GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE); + p->channel_control_helper()->UpdateState( + GRPC_CHANNEL_TRANSIENT_FAILURE, + UniquePtr(New(error))); + } } sd->CheckConnectivityStateAndStartWatchingLocked(); break; @@ -545,18 +464,15 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( case GRPC_CHANNEL_IDLE: { // Only update connectivity state in case 1. if (subchannel_list() == p->subchannel_list_.get()) { - grpc_connectivity_state_set(&p->state_tracker_, GRPC_CHANNEL_CONNECTING, - GRPC_ERROR_REF(error), - "connecting_changed"); + p->channel_control_helper()->UpdateState( + GRPC_CHANNEL_CONNECTING, + UniquePtr(New(p->Ref()))); } - // Renew notification. - RenewConnectivityWatchLocked(); break; } case GRPC_CHANNEL_SHUTDOWN: GPR_UNREACHABLE_CODE(break); } - GRPC_ERROR_UNREF(error); } void PickFirst::PickFirstSubchannelData::ProcessUnselectedReadyLocked() { @@ -574,7 +490,7 @@ void PickFirst::PickFirstSubchannelData::ProcessUnselectedReadyLocked() { subchannel_list() == p->latest_pending_subchannel_list_.get()); // Case 2. Promote p->latest_pending_subchannel_list_ to p->subchannel_list_. if (subchannel_list() == p->latest_pending_subchannel_list_.get()) { - if (grpc_lb_pick_first_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_pick_first_trace)) { gpr_log(GPR_INFO, "Pick First %p promoting pending subchannel list %p to " "replace %p", @@ -584,40 +500,38 @@ void PickFirst::PickFirstSubchannelData::ProcessUnselectedReadyLocked() { 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, "subchannel_ready"); p->selected_ = this; - if (grpc_lb_pick_first_trace.enabled()) { + p->channel_control_helper()->UpdateState( + GRPC_CHANNEL_READY, + UniquePtr(New(connected_subchannel()->Ref()))); + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_pick_first_trace)) { gpr_log(GPR_INFO, "Pick First %p selected subchannel %p", p, subchannel()); } - // Update any calls that were waiting for a pick. - PickState* pick; - while ((pick = p->pending_picks_)) { - p->pending_picks_ = pick->next; - 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", - p->selected_->subchannel()); - } - GRPC_CLOSURE_SCHED(pick->on_complete, GRPC_ERROR_NONE); - } } void PickFirst::PickFirstSubchannelData:: CheckConnectivityStateAndStartWatchingLocked() { PickFirst* p = static_cast(subchannel_list()->policy()); - grpc_error* error = GRPC_ERROR_NONE; - if (p->selected_ != this && - CheckConnectivityStateLocked(&error) == GRPC_CHANNEL_READY) { - // We must process the READY subchannel before we start watching it. - // Otherwise, we won't know it's READY because we will be waiting for its - // connectivity state to change from READY. - ProcessUnselectedReadyLocked(); - } - GRPC_ERROR_UNREF(error); + // Check current state. + grpc_connectivity_state current_state = CheckConnectivityStateLocked(); + // Start watch. StartConnectivityWatchLocked(); + // If current state is READY, select the subchannel now, since we started + // watching from this state and will not get a notification of it + // transitioning into this state. + // If the current state is not READY, attempt to connect. + if (current_state == GRPC_CHANNEL_READY) { + if (p->selected_ != this) ProcessUnselectedReadyLocked(); + } else { + subchannel()->AttemptToConnect(); + } } +class ParsedPickFirstConfig : public ParsedLoadBalancingConfig { + public: + const char* name() const override { return kPickFirst; } +}; + // // factory // @@ -625,11 +539,20 @@ void PickFirst::PickFirstSubchannelData:: class PickFirstFactory : public LoadBalancingPolicyFactory { public: OrphanablePtr CreateLoadBalancingPolicy( - const LoadBalancingPolicy::Args& args) const override { - return OrphanablePtr(New(args)); + LoadBalancingPolicy::Args args) const override { + return OrphanablePtr(New(std::move(args))); } - const char* name() const override { return "pick_first"; } + const char* name() const override { return kPickFirst; } + + RefCountedPtr ParseLoadBalancingConfig( + const grpc_json* json, grpc_error** error) const override { + if (json != nullptr) { + GPR_DEBUG_ASSERT(strcmp(json->key, name()) == 0); + } + return RefCountedPtr( + New()); + } }; } // namespace 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 2a169751317..1693032ea24 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 @@ -26,6 +26,7 @@ #include +#include #include #include @@ -33,11 +34,10 @@ #include "src/core/ext/filters/client_channel/lb_policy/subchannel_list.h" #include "src/core/ext/filters/client_channel/lb_policy_registry.h" #include "src/core/ext/filters/client_channel/subchannel.h" -#include "src/core/ext/filters/client_channel/subchannel_index.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/debug/trace.h" -#include "src/core/lib/gprpp/mutex_lock.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" +#include "src/core/lib/gprpp/sync.h" #include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/sockaddr_utils.h" #include "src/core/lib/transport/connectivity_state.h" @@ -53,23 +53,15 @@ namespace { // round_robin LB policy // +constexpr char kRoundRobin[] = "round_robin"; + class RoundRobin : public LoadBalancingPolicy { public: - explicit RoundRobin(const Args& args); + explicit RoundRobin(Args args); - void UpdateLocked(const grpc_channel_args& args, - grpc_json* lb_config) override; - bool PickLocked(PickState* pick, grpc_error** error) override; - void CancelPickLocked(PickState* pick, grpc_error* error) override; - void CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask, - uint32_t initial_metadata_flags_eq, - grpc_error* error) override; - void NotifyOnStateChangeLocked(grpc_connectivity_state* state, - grpc_closure* closure) override; - grpc_connectivity_state CheckConnectivityLocked( - grpc_error** connectivity_error) override; - void HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) override; - void ExitIdleLocked() override; + const char* name() const override { return kRoundRobin; } + + void UpdateLocked(UpdateArgs args) override; void ResetBackoffLocked() override; void FillChildRefsForChannelz(channelz::ChildRefsList* child_subchannels, channelz::ChildRefsList* ignored) override; @@ -82,8 +74,6 @@ class RoundRobin : public LoadBalancingPolicy { // 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 @@ -93,40 +83,20 @@ class RoundRobin : public LoadBalancingPolicy { RoundRobinSubchannelData( SubchannelList* 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_; } + const ServerAddress& address, Subchannel* subchannel) + : SubchannelData(subchannel_list, address, subchannel) {} grpc_connectivity_state connectivity_state() const { return last_connectivity_state_; } void UpdateConnectivityStateLocked( - grpc_connectivity_state connectivity_state, grpc_error* error); + grpc_connectivity_state connectivity_state); private: void ProcessConnectivityChangeLocked( - grpc_connectivity_state connectivity_state, grpc_error* error) override; + grpc_connectivity_state connectivity_state) override; - const grpc_lb_user_data_vtable* user_data_vtable_; - void* user_data_ = nullptr; grpc_connectivity_state last_connectivity_state_ = GRPC_CHANNEL_IDLE; }; @@ -135,14 +105,12 @@ class RoundRobin : public LoadBalancingPolicy { : public SubchannelList { 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) + RoundRobinSubchannelList(RoundRobin* policy, TraceFlag* tracer, + const ServerAddressList& addresses, + grpc_combiner* combiner, + const grpc_channel_args& args) : SubchannelList(policy, tracer, addresses, combiner, - client_channel_factory, args), - last_ready_index_(num_subchannels() - 1) { + policy->channel_control_helper(), 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. @@ -150,7 +118,6 @@ class RoundRobin : public LoadBalancingPolicy { } ~RoundRobinSubchannelList() { - GRPC_ERROR_UNREF(last_transient_failure_error_); RoundRobin* p = static_cast(policy()); p->Unref(DEBUG_LOCATION, "subchannel_list"); } @@ -160,11 +127,8 @@ class RoundRobin : public LoadBalancingPolicy { // 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); + grpc_connectivity_state new_state); // If this subchannel list is the RR policy's current subchannel // list, updates the RR policy's connectivity state based on the @@ -175,15 +139,24 @@ class RoundRobin : public LoadBalancingPolicy { // 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_; // Index into list of last pick. + }; + + class Picker : public SubchannelPicker { + public: + Picker(RoundRobin* parent, RoundRobinSubchannelList* subchannel_list); + + PickResult Pick(PickArgs* pick, grpc_error** error) override; + + private: + // Using pointer value only, no ref held -- do not dereference! + RoundRobin* parent_; + + size_t last_picked_index_; + InlinedVector, 10> subchannels_; }; // Helper class to ensure that any function that modifies the child refs @@ -200,9 +173,6 @@ class RoundRobin : public LoadBalancingPolicy { void ShutdownLocked() override; - void StartPickingLocked(); - bool DoPickLocked(PickState* pick); - void DrainPendingPicksLocked(); void UpdateChildRefsLocked(); /** list of subchannels */ @@ -213,129 +183,83 @@ class RoundRobin : public LoadBalancingPolicy { * racing callbacks that reference outdated subchannel lists won't perform any * update. */ OrphanablePtr latest_pending_subchannel_list_; - /** have we started picking? */ - bool started_picking_ = false; /** are we shutting down? */ bool shutdown_ = false; - /** List of picks that are waiting on connectivity */ - PickState* pending_picks_ = nullptr; - /** our connectivity state tracker */ - grpc_connectivity_state_tracker state_tracker_; /// Lock and data used to capture snapshots of this channel's child /// channels and subchannels. This data is consumed by channelz. - gpr_mu child_refs_mu_; + Mutex child_refs_mu_; channelz::ChildRefsList child_subchannels_; channelz::ChildRefsList child_channels_; }; -RoundRobin::RoundRobin(const Args& args) : LoadBalancingPolicy(args) { - GPR_ASSERT(args.client_channel_factory != nullptr); - gpr_mu_init(&child_refs_mu_); - grpc_connectivity_state_init(&state_tracker_, GRPC_CHANNEL_IDLE, - "round_robin"); - UpdateLocked(*args.args, args.lb_config); - if (grpc_lb_round_robin_trace.enabled()) { - gpr_log(GPR_INFO, "[RR %p] Created with %" PRIuPTR " subchannels", this, - subchannel_list_->num_subchannels()); +// +// RoundRobin::Picker +// + +RoundRobin::Picker::Picker(RoundRobin* parent, + RoundRobinSubchannelList* subchannel_list) + : parent_(parent) { + for (size_t i = 0; i < subchannel_list->num_subchannels(); ++i) { + auto* connected_subchannel = + subchannel_list->subchannel(i)->connected_subchannel(); + if (connected_subchannel != nullptr) { + subchannels_.push_back(connected_subchannel->Ref()); + } + } + // For discussion on why we generate a random starting index for + // the picker, see https://github.com/grpc/grpc-go/issues/2580. + // TODO(roth): rand(3) is not thread-safe. This should be replaced with + // something better as part of https://github.com/grpc/grpc/issues/17891. + last_picked_index_ = rand() % subchannels_.size(); + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_round_robin_trace)) { + gpr_log(GPR_INFO, + "[RR %p picker %p] created picker from subchannel_list=%p " + "with %" PRIuPTR " READY subchannels; last_picked_index_=%" PRIuPTR, + parent_, this, subchannel_list, subchannels_.size(), + last_picked_index_); + } +} + +RoundRobin::PickResult RoundRobin::Picker::Pick(PickArgs* pick, + grpc_error** error) { + last_picked_index_ = (last_picked_index_ + 1) % subchannels_.size(); + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_round_robin_trace)) { + gpr_log(GPR_INFO, + "[RR %p picker %p] returning index %" PRIuPTR + ", connected_subchannel=%p", + parent_, this, last_picked_index_, + subchannels_[last_picked_index_].get()); + } + pick->connected_subchannel = subchannels_[last_picked_index_]; + return PICK_COMPLETE; +} + +// +// RoundRobin +// + +RoundRobin::RoundRobin(Args args) : LoadBalancingPolicy(std::move(args)) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_round_robin_trace)) { + gpr_log(GPR_INFO, "[RR %p] Created", this); } - grpc_subchannel_index_ref(); } RoundRobin::~RoundRobin() { - if (grpc_lb_round_robin_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_round_robin_trace)) { gpr_log(GPR_INFO, "[RR %p] Destroying Round Robin policy", this); } - gpr_mu_destroy(&child_refs_mu_); GPR_ASSERT(subchannel_list_ == nullptr); GPR_ASSERT(latest_pending_subchannel_list_ == nullptr); - GPR_ASSERT(pending_picks_ == nullptr); - grpc_connectivity_state_destroy(&state_tracker_); - grpc_subchannel_index_unref(); -} - -void RoundRobin::HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) { - PickState* pick; - while ((pick = pending_picks_) != nullptr) { - pending_picks_ = pick->next; - grpc_error* error = GRPC_ERROR_NONE; - if (new_policy->PickLocked(pick, &error)) { - // Synchronous return, schedule closure. - GRPC_CLOSURE_SCHED(pick->on_complete, error); - } - } } void RoundRobin::ShutdownLocked() { AutoChildRefsUpdater guard(this); - grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Channel shutdown"); - if (grpc_lb_round_robin_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_round_robin_trace)) { gpr_log(GPR_INFO, "[RR %p] Shutting down", this); } shutdown_ = true; - PickState* pick; - while ((pick = pending_picks_) != nullptr) { - pending_picks_ = pick->next; - pick->connected_subchannel.reset(); - GRPC_CLOSURE_SCHED(pick->on_complete, GRPC_ERROR_REF(error)); - } - grpc_connectivity_state_set(&state_tracker_, GRPC_CHANNEL_SHUTDOWN, - GRPC_ERROR_REF(error), "rr_shutdown"); subchannel_list_.reset(); latest_pending_subchannel_list_.reset(); - TryReresolutionLocked(&grpc_lb_round_robin_trace, GRPC_ERROR_CANCELLED); - GRPC_ERROR_UNREF(error); -} - -void RoundRobin::CancelPickLocked(PickState* pick, grpc_error* error) { - PickState* pp = pending_picks_; - pending_picks_ = nullptr; - while (pp != nullptr) { - PickState* next = pp->next; - if (pp == pick) { - pick->connected_subchannel.reset(); - GRPC_CLOSURE_SCHED(pick->on_complete, - GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Pick Cancelled", &error, 1)); - } else { - pp->next = pending_picks_; - pending_picks_ = pp; - } - pp = next; - } - GRPC_ERROR_UNREF(error); -} - -void RoundRobin::CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask, - uint32_t initial_metadata_flags_eq, - grpc_error* error) { - PickState* pick = pending_picks_; - pending_picks_ = nullptr; - while (pick != nullptr) { - PickState* next = pick->next; - if ((pick->initial_metadata_flags & initial_metadata_flags_mask) == - initial_metadata_flags_eq) { - pick->connected_subchannel.reset(); - GRPC_CLOSURE_SCHED(pick->on_complete, - GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Pick Cancelled", &error, 1)); - } else { - pick->next = pending_picks_; - pending_picks_ = pick; - } - pick = next; - } - GRPC_ERROR_UNREF(error); -} - -void RoundRobin::StartPickingLocked() { - started_picking_ = true; - subchannel_list_->StartWatchingLocked(); -} - -void RoundRobin::ExitIdleLocked() { - if (!started_picking_) { - StartPickingLocked(); - } } void RoundRobin::ResetBackoffLocked() { @@ -345,63 +269,6 @@ void RoundRobin::ResetBackoffLocked() { } } -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, grpc_error** error) { - if (grpc_lb_round_robin_trace.enabled()) { - gpr_log(GPR_INFO, "[RR %p] Trying to pick (shutdown: %d)", this, shutdown_); - } - GPR_ASSERT(!shutdown_); - if (subchannel_list_ != nullptr) { - if (DoPickLocked(pick)) return true; - } - if (pick->on_complete == nullptr) { - *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "No pick result available but synchronous result required."); - return true; - } - /* no pick currently available. Save for later in list of pending picks */ - pick->next = pending_picks_; - pending_picks_ = pick; - if (!started_picking_) { - StartPickingLocked(); - } - return false; -} - void RoundRobin::FillChildRefsForChannelz( channelz::ChildRefsList* child_subchannels_to_fill, channelz::ChildRefsList* ignored) { @@ -442,26 +309,25 @@ void RoundRobin::RoundRobinSubchannelList::StartWatchingLocked() { // 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); + subchannel(i)->CheckConnectivityStateLocked(); if (state != GRPC_CHANNEL_IDLE) { - subchannel(i)->UpdateConnectivityStateLocked(state, error); + subchannel(i)->UpdateConnectivityStateLocked(state); } } - // 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(); + subchannel(i)->subchannel()->AttemptToConnect(); } } + // Now set the LB policy's state based on the subchannels' states. + UpdateRoundRobinStateFromSubchannelStateCountsLocked(); } void RoundRobin::RoundRobinSubchannelList::UpdateStateCountersLocked( - grpc_connectivity_state old_state, grpc_connectivity_state new_state, - grpc_error* transient_failure_error) { + grpc_connectivity_state old_state, grpc_connectivity_state new_state) { GPR_ASSERT(old_state != GRPC_CHANNEL_SHUTDOWN); GPR_ASSERT(new_state != GRPC_CHANNEL_SHUTDOWN); if (old_state == GRPC_CHANNEL_READY) { @@ -481,12 +347,10 @@ void RoundRobin::RoundRobinSubchannelList::UpdateStateCountersLocked( } 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. +// Sets the RR policy's connectivity state and generates a new picker based +// on the current subchannel list. void RoundRobin::RoundRobinSubchannelList:: MaybeUpdateRoundRobinConnectivityStateLocked() { RoundRobin* p = static_cast(policy()); @@ -508,18 +372,22 @@ void RoundRobin::RoundRobinSubchannelList:: */ if (num_ready_ > 0) { /* 1) READY */ - grpc_connectivity_state_set(&p->state_tracker_, GRPC_CHANNEL_READY, - GRPC_ERROR_NONE, "rr_ready"); + p->channel_control_helper()->UpdateState( + GRPC_CHANNEL_READY, UniquePtr(New(p, this))); } else if (num_connecting_ > 0) { /* 2) CONNECTING */ - grpc_connectivity_state_set(&p->state_tracker_, GRPC_CHANNEL_CONNECTING, - GRPC_ERROR_NONE, "rr_connecting"); + p->channel_control_helper()->UpdateState( + GRPC_CHANNEL_CONNECTING, + UniquePtr(New(p->Ref()))); } else if (num_transient_failure_ == num_subchannels()) { /* 3) TRANSIENT_FAILURE */ - grpc_connectivity_state_set(&p->state_tracker_, - GRPC_CHANNEL_TRANSIENT_FAILURE, - GRPC_ERROR_REF(last_transient_failure_error_), - "rr_exhausted_subchannels"); + grpc_error* error = + grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "connections to all backends failing"), + GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE); + p->channel_control_helper()->UpdateState( + GRPC_CHANNEL_TRANSIENT_FAILURE, + UniquePtr(New(error))); } } @@ -535,7 +403,7 @@ void RoundRobin::RoundRobinSubchannelList:: // 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()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_round_robin_trace)) { const size_t old_num_subchannels = p->subchannel_list_ != nullptr ? p->subchannel_list_->num_subchannels() @@ -548,17 +416,15 @@ void RoundRobin::RoundRobinSubchannelList:: } 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) { + grpc_connectivity_state connectivity_state) { RoundRobin* p = static_cast(subchannel_list()->policy()); - if (grpc_lb_round_robin_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_round_robin_trace)) { gpr_log( GPR_INFO, "[RR %p] connectivity changed for subchannel %p, subchannel_list %p " @@ -569,12 +435,12 @@ void RoundRobin::RoundRobinSubchannelData::UpdateConnectivityStateLocked( grpc_connectivity_state_name(connectivity_state)); } subchannel_list()->UpdateStateCountersLocked(last_connectivity_state_, - connectivity_state, error); + connectivity_state); last_connectivity_state_ = connectivity_state; } void RoundRobin::RoundRobinSubchannelData::ProcessConnectivityChangeLocked( - grpc_connectivity_state connectivity_state, grpc_error* error) { + grpc_connectivity_state connectivity_state) { RoundRobin* p = static_cast(subchannel_list()->policy()); GPR_ASSERT(subchannel() != nullptr); // If the new state is TRANSIENT_FAILURE, re-resolve. @@ -582,139 +448,66 @@ void RoundRobin::RoundRobinSubchannelData::ProcessConnectivityChangeLocked( // 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. + // Also attempt to reconnect. if (connectivity_state == GRPC_CHANNEL_TRANSIENT_FAILURE) { - if (grpc_lb_round_robin_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_round_robin_trace)) { gpr_log(GPR_INFO, "[RR %p] Subchannel %p has gone into TRANSIENT_FAILURE. " "Requesting re-resolution", p, subchannel()); } - p->TryReresolutionLocked(&grpc_lb_round_robin_trace, GRPC_ERROR_NONE); + p->channel_control_helper()->RequestReresolution(); + subchannel()->AttemptToConnect(); } // Update state counters. - UpdateConnectivityStateLocked(connectivity_state, error); + UpdateConnectivityStateLocked(connectivity_state); // 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_); - } - 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( - grpc_error** error) { - return grpc_connectivity_state_get(&state_tracker_, error); -} - -void RoundRobin::NotifyOnStateChangeLocked(grpc_connectivity_state* current, - grpc_closure* notify) { - grpc_connectivity_state_notify_on_state_change(&state_tracker_, current, - notify); -} - -void RoundRobin::UpdateLocked(const grpc_channel_args& args, - grpc_json* lb_config) { - const grpc_arg* arg = grpc_channel_args_find(&args, GRPC_ARG_LB_ADDRESSES); +void RoundRobin::UpdateLocked(UpdateArgs args) { AutoChildRefsUpdater guard(this); - if (GPR_UNLIKELY(arg == nullptr || arg->type != GRPC_ARG_POINTER)) { - gpr_log(GPR_ERROR, "[RR %p] update provided no addresses; ignoring", this); - // If we don't have a current subchannel list, go into TRANSIENT_FAILURE. - // Otherwise, keep using the current subchannel list (ignore this update). - if (subchannel_list_ == nullptr) { - grpc_connectivity_state_set( - &state_tracker_, GRPC_CHANNEL_TRANSIENT_FAILURE, - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Missing update in args"), - "rr_update_missing"); - } - return; - } - grpc_lb_addresses* addresses = - static_cast(arg->value.pointer.p); - if (grpc_lb_round_robin_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_round_robin_trace)) { gpr_log(GPR_INFO, "[RR %p] received update with %" PRIuPTR " addresses", - this, addresses->num_addresses); + this, args.addresses.size()); } // Replace latest_pending_subchannel_list_. if (latest_pending_subchannel_list_ != nullptr) { - if (grpc_lb_round_robin_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_round_robin_trace)) { gpr_log(GPR_INFO, "[RR %p] Shutting down previous pending subchannel list %p", this, latest_pending_subchannel_list_.get()); } } latest_pending_subchannel_list_ = MakeOrphanable( - 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"); - } + this, &grpc_lb_round_robin_trace, args.addresses, combiner(), *args.args); + if (latest_pending_subchannel_list_->num_subchannels() == 0) { + // If the new list is empty, immediately promote the new list to the + // current list and transition to TRANSIENT_FAILURE. + grpc_error* error = + grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING("Empty update"), + GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE); + channel_control_helper()->UpdateState( + GRPC_CHANNEL_TRANSIENT_FAILURE, + UniquePtr(New(error))); subchannel_list_ = std::move(latest_pending_subchannel_list_); + } else if (subchannel_list_ == nullptr) { + // If there is no current list, immediately promote the new list to + // the current list and start watching it. + subchannel_list_ = std::move(latest_pending_subchannel_list_); + subchannel_list_->StartWatchingLocked(); } else { - // If we've started picking, start watching the new list. + // Start watching the pending list. It will get swapped into the + // current list when it reports READY. latest_pending_subchannel_list_->StartWatchingLocked(); } } +class ParsedRoundRobinConfig : public ParsedLoadBalancingConfig { + public: + const char* name() const override { return kRoundRobin; } +}; + // // factory // @@ -722,11 +515,20 @@ void RoundRobin::UpdateLocked(const grpc_channel_args& args, class RoundRobinFactory : public LoadBalancingPolicyFactory { public: OrphanablePtr CreateLoadBalancingPolicy( - const LoadBalancingPolicy::Args& args) const override { - return OrphanablePtr(New(args)); + LoadBalancingPolicy::Args args) const override { + return OrphanablePtr(New(std::move(args))); } - const char* name() const override { return "round_robin"; } + const char* name() const override { return kRoundRobin; } + + RefCountedPtr ParseLoadBalancingConfig( + const grpc_json* json, grpc_error** error) const override { + if (json != nullptr) { + GPR_DEBUG_ASSERT(strcmp(json->key, name()) == 0); + } + return RefCountedPtr( + New()); + } }; } // namespace 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 4ec9e935ed1..93b4bbd369a 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 @@ -26,6 +26,7 @@ #include #include "src/core/ext/filters/client_channel/lb_policy_registry.h" +#include "src/core/ext/filters/client_channel/server_address.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" @@ -50,7 +51,7 @@ class MySubchannelData : public SubchannelData { public: void ProcessConnectivityChangeLocked( - grpc_connectivity_state connectivity_state, grpc_error* error) override { + grpc_connectivity_state connectivity_state) override { // ...code to handle connectivity changes... } }; @@ -87,7 +88,7 @@ class SubchannelData { } // Returns a pointer to the subchannel. - grpc_subchannel* subchannel() const { return subchannel_; } + Subchannel* subchannel() const { return subchannel_; } // Returns the connected subchannel. Will be null if the subchannel // is not connected. @@ -97,15 +98,13 @@ class SubchannelData { // 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, subchannel_list_->inhibit_health_checking()); - UpdateConnectedSubchannelLocked(); - return pending_connectivity_state_unsafe_; + // pending (i.e., between calling StartConnectivityWatchLocked() and + // calling CancelConnectivityWatchLocked()). + grpc_connectivity_state CheckConnectivityStateLocked() { + GPR_ASSERT(pending_watcher_ == nullptr); + connectivity_state_ = subchannel()->CheckConnectivityState( + subchannel_list_->health_check_service_name(), &connected_subchannel_); + return connectivity_state_; } // Resets the connection backoff. @@ -114,23 +113,11 @@ class SubchannelData { void ResetBackoffLocked(); // Starts watching the connectivity state of the subchannel. - // ProcessConnectivityChangeLocked() will be called when the + // ProcessConnectivityChangeLocked() will be called whenever 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. @@ -141,53 +128,85 @@ class SubchannelData { protected: SubchannelData( SubchannelList* subchannel_list, - const grpc_lb_user_data_vtable* user_data_vtable, - const grpc_lb_address& address, grpc_subchannel* subchannel, - grpc_combiner* combiner); + const ServerAddress& address, Subchannel* subchannel); 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. + // After StartConnectivityWatchLocked() is called, this method will be + // invoked whenever the subchannel's connectivity state changes. + // To stop watching, use CancelConnectivityWatchLocked(). virtual void ProcessConnectivityChangeLocked( - grpc_connectivity_state connectivity_state, - grpc_error* error) GRPC_ABSTRACT; - - // Unrefs the subchannel. May be overridden by subclasses that need - // to perform extra cleanup when unreffing the subchannel. - virtual void UnrefSubchannelLocked(const char* reason); + grpc_connectivity_state connectivity_state) GRPC_ABSTRACT; private: - // Updates connected_subchannel_ based on pending_connectivity_state_unsafe_. - // Returns true if the connectivity state should be reported. - bool UpdateConnectedSubchannelLocked(); + // Watcher for subchannel connectivity state. + class Watcher : public Subchannel::ConnectivityStateWatcher { + public: + Watcher( + SubchannelData* subchannel_data, + RefCountedPtr subchannel_list) + : subchannel_data_(subchannel_data), + subchannel_list_(std::move(subchannel_list)) {} - static void OnConnectivityChangedLocked(void* arg, grpc_error* error); + ~Watcher() { subchannel_list_.reset(DEBUG_LOCATION, "Watcher dtor"); } + + void OnConnectivityStateChange( + grpc_connectivity_state new_state, + RefCountedPtr connected_subchannel) override; + + grpc_pollset_set* interested_parties() override { + return subchannel_list_->policy()->interested_parties(); + } + + private: + // A fire-and-forget class that bounces into the combiner to process + // a connectivity state update. + class Updater { + public: + Updater( + SubchannelData* + subchannel_data, + RefCountedPtr> + subchannel_list, + grpc_connectivity_state state, + RefCountedPtr connected_subchannel); + + ~Updater() { + subchannel_list_.reset(DEBUG_LOCATION, "Watcher::Updater dtor"); + } + + private: + static void OnUpdateLocked(void* arg, grpc_error* error); + + SubchannelData* subchannel_data_; + RefCountedPtr> + subchannel_list_; + const grpc_connectivity_state state_; + RefCountedPtr connected_subchannel_; + grpc_closure closure_; + }; + + SubchannelData* subchannel_data_; + RefCountedPtr subchannel_list_; + }; + + // Unrefs the subchannel. + void UnrefSubchannelLocked(const char* reason); // Backpointer to owning subchannel list. Not owned. SubchannelList* subchannel_list_; - - // The subchannel and connected subchannel. - grpc_subchannel* subchannel_; + // The subchannel. + Subchannel* subchannel_; + // Will be non-null when the subchannel's state is being watched. + Subchannel::ConnectivityStateWatcher* pending_watcher_ = nullptr; + // Data updated by the watcher. + grpc_connectivity_state connectivity_state_; RefCountedPtr 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 -class SubchannelList - : public InternallyRefCountedWithTracing { +class SubchannelList : public InternallyRefCounted { public: typedef InlinedVector SubchannelVector; @@ -205,7 +224,7 @@ class SubchannelList for (size_t i = 0; i < subchannels_.size(); ++i) { if (subchannels_[i].subchannel() != nullptr) { grpc_core::channelz::SubchannelNode* subchannel_node = - grpc_subchannel_get_channelz_node(subchannels_[i].subchannel()); + subchannels_[i].subchannel()->channelz_node(); if (subchannel_node != nullptr) { refs_list->push_back(subchannel_node->uuid()); } @@ -216,7 +235,9 @@ class SubchannelList // Accessors. LoadBalancingPolicy* policy() const { return policy_; } TraceFlag* tracer() const { return tracer_; } - bool inhibit_health_checking() const { return inhibit_health_checking_; } + const char* health_check_service_name() const { + return health_check_service_name_.get(); + } // Resets connection backoff of all subchannels. // TODO(roth): We will probably need to rethink this as part of moving @@ -226,16 +247,15 @@ class SubchannelList // Note: Caller must ensure that this is invoked inside of the combiner. void Orphan() override { ShutdownLocked(); - InternallyRefCountedWithTracing::Unref(DEBUG_LOCATION, - "shutdown"); + InternallyRefCounted::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 ServerAddressList& addresses, grpc_combiner* combiner, + LoadBalancingPolicy::ChannelControlHelper* helper, const grpc_channel_args& args); virtual ~SubchannelList(); @@ -255,7 +275,7 @@ class SubchannelList TraceFlag* tracer_; - bool inhibit_health_checking_; + UniquePtr health_check_service_name_; grpc_combiner* combiner_; @@ -272,6 +292,67 @@ class SubchannelList // implementation -- no user-servicable parts below // +// +// SubchannelData::Watcher +// + +template +void SubchannelData::Watcher:: + OnConnectivityStateChange( + grpc_connectivity_state new_state, + RefCountedPtr connected_subchannel) { + // Will delete itself. + New(subchannel_data_, + subchannel_list_->Ref(DEBUG_LOCATION, "Watcher::Updater"), + new_state, std::move(connected_subchannel)); +} + +template +SubchannelData::Watcher::Updater:: + Updater( + SubchannelData* subchannel_data, + RefCountedPtr> + subchannel_list, + grpc_connectivity_state state, + RefCountedPtr connected_subchannel) + : subchannel_data_(subchannel_data), + subchannel_list_(std::move(subchannel_list)), + state_(state), + connected_subchannel_(std::move(connected_subchannel)) { + GRPC_CLOSURE_INIT(&closure_, &OnUpdateLocked, this, + grpc_combiner_scheduler(subchannel_list_->combiner_)); + GRPC_CLOSURE_SCHED(&closure_, GRPC_ERROR_NONE); +} + +template +void SubchannelData::Watcher::Updater:: + OnUpdateLocked(void* arg, grpc_error* error) { + Updater* self = static_cast(arg); + SubchannelData* sd = self->subchannel_data_; + if (GRPC_TRACE_FLAG_ENABLED(*sd->subchannel_list_->tracer())) { + gpr_log(GPR_INFO, + "[%s %p] subchannel list %p index %" PRIuPTR " of %" PRIuPTR + " (subchannel %p): connectivity changed: state=%s, " + "connected_subchannel=%p, shutting_down=%d, pending_watcher=%p", + 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(self->state_), + self->connected_subchannel_.get(), + sd->subchannel_list_->shutting_down(), sd->pending_watcher_); + } + if (!sd->subchannel_list_->shutting_down() && + sd->pending_watcher_ != nullptr) { + sd->connectivity_state_ = self->state_; + // Get or release ref to connected subchannel. + sd->connected_subchannel_ = std::move(self->connected_subchannel_); + // Call the subclass's ProcessConnectivityChangeLocked() method. + sd->ProcessConnectivityChangeLocked(sd->connectivity_state_); + } + // Clean up. + Delete(self); +} + // // SubchannelData // @@ -279,31 +360,23 @@ class SubchannelList template SubchannelData::SubchannelData( SubchannelList* subchannel_list, - const grpc_lb_user_data_vtable* user_data_vtable, - const grpc_lb_address& address, grpc_subchannel* subchannel, - grpc_combiner* combiner) + const ServerAddress& address, Subchannel* subchannel) : 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::OnConnectivityChangedLocked), - this, grpc_combiner_scheduler(combiner)); -} + connectivity_state_(GRPC_CHANNEL_IDLE) {} template SubchannelData::~SubchannelData() { - UnrefSubchannelLocked("subchannel_data_destroy"); + GPR_ASSERT(subchannel_ == nullptr); } template void SubchannelData:: UnrefSubchannelLocked(const char* reason) { if (subchannel_ != nullptr) { - if (subchannel_list_->tracer()->enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(*subchannel_list_->tracer())) { gpr_log(GPR_INFO, "[%s %p] subchannel list %p index %" PRIuPTR " of %" PRIuPTR " (subchannel %p): unreffing subchannel", @@ -321,72 +394,35 @@ template void SubchannelData::ResetBackoffLocked() { if (subchannel_ != nullptr) { - grpc_subchannel_reset_backoff(subchannel_); + subchannel_->ResetBackoff(); } } template void SubchannelData::StartConnectivityWatchLocked() { - if (subchannel_list_->tracer()->enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(*subchannel_list_->tracer())) { gpr_log(GPR_INFO, "[%s %p] subchannel list %p index %" PRIuPTR " of %" PRIuPTR - " (subchannel %p): starting watch: requesting connectivity change " - "notification (from %s)", + " (subchannel %p): starting watch (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_)); + subchannel_, grpc_connectivity_state_name(connectivity_state_)); } - 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_, - subchannel_list_->inhibit_health_checking()); -} - -template -void SubchannelData::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_, - subchannel_list_->inhibit_health_checking()); -} - -template -void SubchannelData::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"); + GPR_ASSERT(pending_watcher_ == nullptr); + pending_watcher_ = + New(this, subchannel_list()->Ref(DEBUG_LOCATION, "Watcher")); + subchannel_->WatchConnectivityState( + connectivity_state_, + UniquePtr( + gpr_strdup(subchannel_list_->health_check_service_name())), + UniquePtr(pending_watcher_)); } template void SubchannelData:: CancelConnectivityWatchLocked(const char* reason) { - if (subchannel_list_->tracer()->enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(*subchannel_list_->tracer())) { gpr_log(GPR_INFO, "[%s %p] subchannel list %p index %" PRIuPTR " of %" PRIuPTR " (subchannel %p): canceling connectivity watch (%s)", @@ -394,93 +430,17 @@ void SubchannelData:: 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_, - subchannel_list_->inhibit_health_checking()); -} - -template -bool SubchannelData::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(); + if (pending_watcher_ != nullptr) { + subchannel_->CancelConnectivityStateWatch( + subchannel_list_->health_check_service_name(), pending_watcher_); + pending_watcher_ = nullptr; } - return true; -} - -template -void SubchannelData:: - OnConnectivityChangedLocked(void* arg, grpc_error* error) { - SubchannelData* sd = static_cast(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 void SubchannelData::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"); - } + if (pending_watcher_ != nullptr) CancelConnectivityWatchLocked("shutdown"); + UnrefSubchannelLocked("shutdown"); } // @@ -490,48 +450,66 @@ void SubchannelData::ShutdownLocked() { template SubchannelList::SubchannelList( LoadBalancingPolicy* policy, TraceFlag* tracer, - const grpc_lb_addresses* addresses, grpc_combiner* combiner, - grpc_client_channel_factory* client_channel_factory, + const ServerAddressList& addresses, grpc_combiner* combiner, + LoadBalancingPolicy::ChannelControlHelper* helper, const grpc_channel_args& args) - : InternallyRefCountedWithTracing(tracer), + : InternallyRefCounted(tracer), policy_(policy), tracer_(tracer), combiner_(GRPC_COMBINER_REF(combiner, "subchannel_list")) { - if (tracer_->enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(*tracer_)) { gpr_log(GPR_INFO, "[%s %p] Creating subchannel list %p for %" PRIuPTR " subchannels", - tracer_->name(), policy, this, addresses->num_addresses); + tracer_->name(), policy, this, addresses.size()); + } + subchannels_.reserve(addresses.size()); + // Find health check service name. + const bool inhibit_health_checking = grpc_channel_arg_get_bool( + grpc_channel_args_find(&args, GRPC_ARG_INHIBIT_HEALTH_CHECKING), false); + if (!inhibit_health_checking) { + const char* health_check_service_name = grpc_channel_arg_get_string( + grpc_channel_args_find(&args, "grpc.temp.health_check")); + if (health_check_service_name != nullptr) { + health_check_service_name_.reset(gpr_strdup(health_check_service_name)); + } } - 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. - // We also remove the inhibit-health-checking arg, since we are + // We also remove the health-checking-related args, since we are // handling that here. - inhibit_health_checking_ = grpc_channel_arg_get_bool( - grpc_channel_args_find(&args, GRPC_ARG_INHIBIT_HEALTH_CHECKING), false); - static const char* keys_to_remove[] = {GRPC_ARG_SUBCHANNEL_ADDRESS, - GRPC_ARG_LB_ADDRESSES, - GRPC_ARG_INHIBIT_HEALTH_CHECKING}; + // We remove the service config, since it will be passed into the + // subchannel via call context. + static const char* keys_to_remove[] = { + GRPC_ARG_SUBCHANNEL_ADDRESS, "grpc.temp.health_check", + GRPC_ARG_INHIBIT_HEALTH_CHECKING, GRPC_ARG_SERVICE_CONFIG}; // 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); + for (size_t i = 0; i < addresses.size(); i++) { + // TODO(roth): we should ideally hide this from the LB policy code. In + // principle, if we're dealing with this special case in the client_channel + // code for selecting grpclb, then we should also strip out these addresses + // there if we're not using grpclb. + if (addresses[i].IsBalancer()) { + continue; + } + InlinedVector args_to_add; + const size_t subchannel_address_arg_index = args_to_add.size(); + args_to_add.emplace_back( + Subchannel::CreateSubchannelAddressArg(&addresses[i].address())); + if (addresses[i].args() != nullptr) { + for (size_t j = 0; j < addresses[i].args()->num_args; ++j) { + args_to_add.emplace_back(addresses[i].args()->args[j]); + } + } 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); + &args, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), + args_to_add.data(), args_to_add.size()); + gpr_free(args_to_add[subchannel_address_arg_index].value.string); + Subchannel* subchannel = helper->CreateSubchannel(*new_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); + if (GRPC_TRACE_FLAG_ENABLED(*tracer_)) { + char* address_uri = grpc_sockaddr_to_uri(&addresses[i].address()); gpr_log(GPR_INFO, "[%s %p] could not create subchannel for address uri %s, " "ignoring", @@ -540,9 +518,8 @@ SubchannelList::SubchannelList( } continue; } - if (tracer_->enabled()) { - char* address_uri = - grpc_sockaddr_to_uri(&addresses->addresses[i].address); + if (GRPC_TRACE_FLAG_ENABLED(*tracer_)) { + char* address_uri = grpc_sockaddr_to_uri(&addresses[i].address()); gpr_log(GPR_INFO, "[%s %p] subchannel list %p index %" PRIuPTR ": Created subchannel %p for address uri %s", @@ -550,14 +527,13 @@ SubchannelList::SubchannelList( address_uri); gpr_free(address_uri); } - subchannels_.emplace_back(this, addresses->user_data_vtable, - addresses->addresses[i], subchannel, combiner); + subchannels_.emplace_back(this, addresses[i], subchannel); } } template SubchannelList::~SubchannelList() { - if (tracer_->enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(*tracer_)) { gpr_log(GPR_INFO, "[%s %p] Destroying subchannel_list %p", tracer_->name(), policy_, this); } @@ -566,7 +542,7 @@ SubchannelList::~SubchannelList() { template void SubchannelList::ShutdownLocked() { - if (tracer_->enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(*tracer_)) { gpr_log(GPR_INFO, "[%s %p] Shutting down subchannel_list %p", tracer_->name(), policy_, this); } diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc index 29cd9043755..3eb94371c71 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc @@ -26,14 +26,13 @@ /// channel that uses pick_first to select from the list of balancer /// addresses. /// -/// The first time the xDS policy gets a request for a pick or to exit the idle -/// state, \a StartPickingLocked() is called. This method is responsible for -/// instantiating the internal *streaming* call to the LB server (whichever -/// address pick_first chose). The call will be complete when either the -/// balancer sends status or when we cancel the call (e.g., because we are -/// shutting down). In needed, we retry the call. If we received at least one -/// valid message from the server, a new call attempt will be made immediately; -/// otherwise, we apply back-off delays between attempts. +/// When we get our initial update, we instantiate the internal *streaming* +/// call to the LB server (whichever address pick_first chose). The call +/// will be complete when either the balancer sends status or when we cancel +/// the call (e.g., because we are shutting down). In needed, we retry the +/// call. If we received at least one valid message from the server, a new +/// call attempt will be made immediately; otherwise, we apply back-off +/// delays between attempts. /// /// We maintain an internal child policy (round_robin) instance for distributing /// requests across backends. Whenever we receive a new serverlist from @@ -69,8 +68,9 @@ #include #include +#include "include/grpc/support/alloc.h" #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.h" #include "src/core/ext/filters/client_channel/lb_policy/xds/xds.h" #include "src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h" #include "src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.h" @@ -79,17 +79,19 @@ #include "src/core/ext/filters/client_channel/lb_policy_registry.h" #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h" -#include "src/core/ext/filters/client_channel/subchannel_index.h" +#include "src/core/ext/filters/client_channel/server_address.h" +#include "src/core/ext/filters/client_channel/service_config.h" #include "src/core/lib/backoff/backoff.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/channel_stack.h" #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gprpp/manual_constructor.h" +#include "src/core/lib/gprpp/map.h" #include "src/core/lib/gprpp/memory.h" -#include "src/core/lib/gprpp/mutex_lock.h" #include "src/core/lib/gprpp/orphanable.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" +#include "src/core/lib/gprpp/sync.h" #include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/sockaddr.h" #include "src/core/lib/iomgr/sockaddr_utils.h" @@ -114,274 +116,546 @@ TraceFlag grpc_lb_xds_trace(false, "xds"); namespace { +constexpr char kXds[] = "xds_experimental"; +constexpr char kDefaultLocalityName[] = "xds_default_locality"; +constexpr uint32_t kDefaultLocalityWeight = 3; + +class ParsedXdsConfig : public ParsedLoadBalancingConfig { + public: + ParsedXdsConfig(const char* balancer_name, + RefCountedPtr child_policy, + RefCountedPtr fallback_policy) + : balancer_name_(balancer_name), + child_policy_(std::move(child_policy)), + fallback_policy_(std::move(fallback_policy)) {} + + const char* name() const override { return kXds; } + + const char* balancer_name() const { return balancer_name_; }; + + RefCountedPtr child_policy() const { + return child_policy_; + } + + RefCountedPtr fallback_policy() const { + return fallback_policy_; + } + + private: + const char* balancer_name_ = nullptr; + RefCountedPtr child_policy_; + RefCountedPtr fallback_policy_; +}; + class XdsLb : public LoadBalancingPolicy { public: - XdsLb(const grpc_lb_addresses* addresses, const Args& args); + explicit XdsLb(Args args); - void UpdateLocked(const grpc_channel_args& args, - grpc_json* lb_config) override; - bool PickLocked(PickState* pick, grpc_error** error) override; - void CancelPickLocked(PickState* pick, grpc_error* error) override; - void CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask, - uint32_t initial_metadata_flags_eq, - grpc_error* error) override; - void NotifyOnStateChangeLocked(grpc_connectivity_state* state, - grpc_closure* closure) override; - grpc_connectivity_state CheckConnectivityLocked( - grpc_error** connectivity_error) override; - void HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) override; - void ExitIdleLocked() override; + const char* name() const override { return kXds; } + + void UpdateLocked(UpdateArgs args) override; void ResetBackoffLocked() override; void FillChildRefsForChannelz( channelz::ChildRefsList* child_subchannels, channelz::ChildRefsList* child_channels) override; private: - /// Linked list of pending pick requests. It stores all information needed to - /// eventually call pick() on them. They mainly stay pending waiting for the - /// child policy to be created. - /// - /// Note that when a pick is sent to the child policy, we inject our own - /// on_complete callback, so that we can intercept the result before - /// invoking the original on_complete callback. This allows us to set the - /// LB token metadata and add client_stats to the call context. - /// See \a pending_pick_complete() for details. - struct PendingPick { - // The xds lb instance that created the wrapping. This instance is not - // owned; reference counts are untouched. It's used only for logging - // purposes. - XdsLb* xdslb_policy; - // The original pick. - PickState* pick; - // Our on_complete closure and the original one. - grpc_closure on_complete; - grpc_closure* original_on_complete; - // The LB token associated with the pick. This is set via user_data in - // the pick. - grpc_mdelem lb_token; - // Stats for client-side load reporting. - RefCountedPtr client_stats; - // Next pending pick. - PendingPick* next = nullptr; - }; + struct LocalityServerlistEntry; + using LocalityList = InlinedVector, 1>; - /// Contains a call to the LB server and all the data related to the call. - class BalancerCallState - : public InternallyRefCountedWithTracing { + /// Contains a channel to the LB server and all the data related to the + /// channel. + class BalancerChannelState + : public InternallyRefCounted { public: - explicit BalancerCallState( - RefCountedPtr parent_xdslb_policy); + /// Contains a call to the LB server and all the data related to the call. + class BalancerCallState : public InternallyRefCounted { + public: + explicit BalancerCallState(RefCountedPtr lb_chand); + + // It's the caller's responsibility to ensure that Orphan() is called from + // inside the combiner. + void Orphan() override; + + void StartQuery(); + + RefCountedPtr client_stats() const { + return client_stats_; + } + + bool seen_initial_response() const { return seen_initial_response_; } + + private: + // So Delete() can access our private dtor. + template + friend void grpc_core::Delete(T*); + + ~BalancerCallState(); + + XdsLb* xdslb_policy() const { return lb_chand_->xdslb_policy_.get(); } + + bool IsCurrentCallOnChannel() const { + return this == lb_chand_->lb_calld_.get(); + } + + void ScheduleNextClientLoadReportLocked(); + void SendClientLoadReportLocked(); + + static bool LoadReportCountersAreZero(xds_grpclb_request* request); + + static void MaybeSendClientLoadReportLocked(void* arg, grpc_error* error); + static void OnInitialRequestSentLocked(void* arg, grpc_error* error); + static void OnBalancerMessageReceivedLocked(void* arg, grpc_error* error); + static void OnBalancerStatusReceivedLocked(void* arg, grpc_error* error); + + // The owning LB channel. + RefCountedPtr lb_chand_; + + // The streaming call to the LB server. Always non-NULL. + grpc_call* lb_call_ = nullptr; + + // recv_initial_metadata + grpc_metadata_array lb_initial_metadata_recv_; + + // send_message + grpc_byte_buffer* send_message_payload_ = nullptr; + grpc_closure lb_on_initial_request_sent_; + + // recv_message + grpc_byte_buffer* recv_message_payload_ = nullptr; + grpc_closure lb_on_balancer_message_received_; + bool seen_initial_response_ = false; + + // recv_trailing_metadata + grpc_closure lb_on_balancer_status_received_; + grpc_metadata_array lb_trailing_metadata_recv_; + grpc_status_code lb_call_status_; + grpc_slice lb_call_status_details_; + + // The stats for client-side load reporting associated with this LB call. + // Created after the first serverlist is received. + RefCountedPtr client_stats_; + grpc_millis client_stats_report_interval_ = 0; + grpc_timer client_load_report_timer_; + bool client_load_report_timer_callback_pending_ = false; + bool last_client_load_report_counters_were_zero_ = false; + bool client_load_report_is_due_ = false; + // The closure used for either the load report timer or the callback for + // completion of sending the load report. + grpc_closure client_load_report_closure_; + }; + + BalancerChannelState(const char* balancer_name, + const grpc_channel_args& args, + RefCountedPtr parent_xdslb_policy); + ~BalancerChannelState(); - // It's the caller's responsibility to ensure that Orphan() is called from - // inside the combiner. void Orphan() override; - void StartQuery(); + grpc_channel* channel() const { return channel_; } + BalancerCallState* lb_calld() const { return lb_calld_.get(); } - XdsLbClientStats* client_stats() const { return client_stats_.get(); } + bool IsCurrentChannel() const { + return this == xdslb_policy_->lb_chand_.get(); + } + bool IsPendingChannel() const { + return this == xdslb_policy_->pending_lb_chand_.get(); + } + bool HasActiveCall() const { return lb_calld_ != nullptr; } - bool seen_initial_response() const { return seen_initial_response_; } + void StartCallRetryTimerLocked(); + static void OnCallRetryTimerLocked(void* arg, grpc_error* error); + void StartCallLocked(); + + void StartConnectivityWatchLocked(); + void CancelConnectivityWatchLocked(); + static void OnConnectivityChangedLocked(void* arg, grpc_error* error); private: - // So Delete() can access our private dtor. - template - friend void grpc_core::Delete(T*); + // The owning LB policy. + RefCountedPtr xdslb_policy_; - ~BalancerCallState(); + // The channel and its status. + grpc_channel* channel_; + bool shutting_down_ = false; + grpc_connectivity_state connectivity_ = GRPC_CHANNEL_IDLE; + grpc_closure on_connectivity_changed_; - XdsLb* xdslb_policy() const { - return static_cast(xdslb_policy_.get()); + // The data associated with the current LB call. It holds a ref to this LB + // channel. It's instantiated every time we query for backends. It's reset + // whenever the current LB call is no longer needed (e.g., the LB policy is + // shutting down, or the LB call has ended). A non-NULL lb_calld_ always + // contains a non-NULL lb_call_. + OrphanablePtr lb_calld_; + BackOff lb_call_backoff_; + grpc_timer lb_call_retry_timer_; + grpc_closure lb_on_call_retry_; + bool retry_timer_callback_pending_ = false; + }; + + // Since pickers are UniquePtrs we use this RefCounted wrapper + // to control references to it by the xds picker and the locality + // entry + class PickerRef : public RefCounted { + public: + explicit PickerRef(UniquePtr picker) + : picker_(std::move(picker)) {} + PickResult Pick(PickArgs* pick, grpc_error** error) { + return picker_->Pick(pick, error); } - void ScheduleNextClientLoadReportLocked(); - void SendClientLoadReportLocked(); + private: + UniquePtr picker_; + }; - static bool LoadReportCountersAreZero(xds_grpclb_request* request); + // The picker will use a stateless weighting algorithm to pick the locality to + // use for each request. + class Picker : public SubchannelPicker { + public: + // Maintains a weighted list of pickers from each locality that is in ready + // state. The first element in the pair represents the end of a range + // proportional to the locality's weight. The start of the range is the + // previous value in the vector and is 0 for the first element. + using PickerList = + InlinedVector>, 1>; + Picker(RefCountedPtr client_stats, PickerList pickers) + : client_stats_(std::move(client_stats)), + pickers_(std::move(pickers)) {} - static void MaybeSendClientLoadReportLocked(void* arg, grpc_error* error); - static void ClientLoadReportDoneLocked(void* arg, grpc_error* error); - static void OnInitialRequestSentLocked(void* arg, grpc_error* error); - static void OnBalancerMessageReceivedLocked(void* arg, grpc_error* error); - static void OnBalancerStatusReceivedLocked(void* arg, grpc_error* error); + PickResult Pick(PickArgs* pick, grpc_error** error) override; - // The owning LB policy. - RefCountedPtr xdslb_policy_; - - // The streaming call to the LB server. Always non-NULL. - grpc_call* lb_call_ = nullptr; - - // recv_initial_metadata - grpc_metadata_array lb_initial_metadata_recv_; - - // send_message - grpc_byte_buffer* send_message_payload_ = nullptr; - grpc_closure lb_on_initial_request_sent_; - - // recv_message - grpc_byte_buffer* recv_message_payload_ = nullptr; - grpc_closure lb_on_balancer_message_received_; - bool seen_initial_response_ = false; - - // recv_trailing_metadata - grpc_closure lb_on_balancer_status_received_; - grpc_metadata_array lb_trailing_metadata_recv_; - grpc_status_code lb_call_status_; - grpc_slice lb_call_status_details_; - - // The stats for client-side load reporting associated with this LB call. - // Created after the first serverlist is received. + private: + // Calls the picker of the locality that the key falls within + PickResult PickFromLocality(const uint32_t key, PickArgs* pick, + grpc_error** error); RefCountedPtr client_stats_; - grpc_millis client_stats_report_interval_ = 0; - grpc_timer client_load_report_timer_; - bool client_load_report_timer_callback_pending_ = false; - bool last_client_load_report_counters_were_zero_ = false; - bool client_load_report_is_due_ = false; - // The closure used for either the load report timer or the callback for - // completion of sending the load report. - grpc_closure client_load_report_closure_; + PickerList pickers_; + }; + + class FallbackHelper : public ChannelControlHelper { + public: + explicit FallbackHelper(RefCountedPtr parent) + : parent_(std::move(parent)) {} + + Subchannel* CreateSubchannel(const grpc_channel_args& args) override; + grpc_channel* CreateChannel(const char* target, + const grpc_channel_args& args) override; + void UpdateState(grpc_connectivity_state state, + UniquePtr picker) override; + void RequestReresolution() override; + + void set_child(LoadBalancingPolicy* child) { child_ = child; } + + private: + bool CalledByPendingFallback() const; + bool CalledByCurrentFallback() const; + + RefCountedPtr parent_; + LoadBalancingPolicy* child_ = nullptr; + }; + + class LocalityMap { + public: + class LocalityEntry : public InternallyRefCounted { + public: + LocalityEntry(RefCountedPtr parent, uint32_t locality_weight) + : parent_(std::move(parent)), locality_weight_(locality_weight) {} + ~LocalityEntry() = default; + + void UpdateLocked(xds_grpclb_serverlist* serverlist, + ParsedLoadBalancingConfig* child_policy_config, + const grpc_channel_args* args); + void ShutdownLocked(); + void ResetBackoffLocked(); + void FillChildRefsForChannelz(channelz::ChildRefsList* child_subchannels, + channelz::ChildRefsList* child_channels); + void Orphan() override; + + private: + class Helper : public ChannelControlHelper { + public: + explicit Helper(RefCountedPtr entry) + : entry_(std::move(entry)) {} + + Subchannel* CreateSubchannel(const grpc_channel_args& args) override; + grpc_channel* CreateChannel(const char* target, + const grpc_channel_args& args) override; + void UpdateState(grpc_connectivity_state state, + UniquePtr picker) override; + void RequestReresolution() override; + void set_child(LoadBalancingPolicy* child) { child_ = child; } + + private: + bool CalledByPendingChild() const; + bool CalledByCurrentChild() const; + + RefCountedPtr entry_; + LoadBalancingPolicy* child_ = nullptr; + }; + // Methods for dealing with the child policy. + OrphanablePtr CreateChildPolicyLocked( + const char* name, const grpc_channel_args* args); + grpc_channel_args* CreateChildPolicyArgsLocked( + const grpc_channel_args* args); + + OrphanablePtr child_policy_; + OrphanablePtr pending_child_policy_; + // Lock held when modifying the value of child_policy_ or + // pending_child_policy_. + Mutex child_policy_mu_; + RefCountedPtr parent_; + RefCountedPtr picker_ref_; + grpc_connectivity_state connectivity_state_; + uint32_t locality_weight_; + }; + + void UpdateLocked(const LocalityList& locality_list, + ParsedLoadBalancingConfig* child_policy_config, + const grpc_channel_args* args, XdsLb* parent); + void ShutdownLocked(); + void ResetBackoffLocked(); + void FillChildRefsForChannelz(channelz::ChildRefsList* child_subchannels, + channelz::ChildRefsList* child_channels); + + private: + void PruneLocalities(const LocalityList& locality_list); + Map, OrphanablePtr, StringLess> map_; + // Lock held while filling child refs for all localities + // inside the map + Mutex child_refs_mu_; + }; + + struct LocalityServerlistEntry { + ~LocalityServerlistEntry() { + gpr_free(locality_name); + xds_grpclb_destroy_serverlist(serverlist); + } + + char* locality_name; + uint32_t locality_weight; + // The deserialized response from the balancer. May be nullptr until one + // such response has arrived. + xds_grpclb_serverlist* serverlist; }; ~XdsLb(); void ShutdownLocked() override; - // Helper function used in ctor and UpdateLocked(). - void ProcessChannelArgsLocked(const grpc_channel_args& args); + // Helper function used in UpdateLocked(). + void ProcessAddressesAndChannelArgsLocked(const ServerAddressList& addresses, + const grpc_channel_args& args); - // Methods for dealing with the balancer channel and call. - void StartPickingLocked(); - void StartBalancerCallLocked(); + // Parses the xds config given the JSON node of the first child of XdsConfig. + // If parsing succeeds, updates \a balancer_name, and updates \a + // child_policy_config_ and \a fallback_policy_config_ if they are also + // found. Does nothing upon failure. + void ParseLbConfig(const ParsedXdsConfig* xds_config); + + BalancerChannelState* LatestLbChannel() const { + return pending_lb_chand_ != nullptr ? pending_lb_chand_.get() + : lb_chand_.get(); + } + + // Methods for dealing with fallback state. + void MaybeCancelFallbackAtStartupChecks(); static void OnFallbackTimerLocked(void* arg, grpc_error* error); - void StartBalancerCallRetryTimerLocked(); - static void OnBalancerCallRetryTimerLocked(void* arg, grpc_error* error); - static void OnBalancerChannelConnectivityChangedLocked(void* arg, - grpc_error* error); - - // Pending pick methods. - static void PendingPickSetMetadataAndContext(PendingPick* pp); - PendingPick* PendingPickCreate(PickState* pick); - void AddPendingPick(PendingPick* pp); - static void OnPendingPickComplete(void* arg, grpc_error* error); - - // Methods for dealing with the child policy. - void CreateOrUpdateChildPolicyLocked(); - grpc_channel_args* CreateChildPolicyArgsLocked(); - void CreateChildPolicyLocked(const Args& args); - bool PickFromChildPolicyLocked(bool force_async, PendingPick* pp, - grpc_error** error); - void UpdateConnectivityStateFromChildPolicyLocked( - grpc_error* child_state_error); - static void OnChildPolicyConnectivityChangedLocked(void* arg, - grpc_error* error); - static void OnChildPolicyRequestReresolutionLocked(void* arg, - grpc_error* error); + void UpdateFallbackPolicyLocked(); + OrphanablePtr CreateFallbackPolicyLocked( + const char* name, const grpc_channel_args* args); + void MaybeExitFallbackMode(); // Who the client is trying to communicate with. const char* server_name_ = nullptr; + // Name of the balancer to connect to. + UniquePtr balancer_name_; + // Current channel args from the resolver. grpc_channel_args* args_ = nullptr; // Internal state. - bool started_picking_ = false; bool shutting_down_ = false; - grpc_connectivity_state_tracker state_tracker_; // The channel for communicating with the LB server. - grpc_channel* lb_channel_ = nullptr; + OrphanablePtr lb_chand_; + OrphanablePtr pending_lb_chand_; // Mutex to protect the channel to the LB server. This is used when // processing a channelz request. - gpr_mu lb_channel_mu_; - grpc_connectivity_state lb_channel_connectivity_; - grpc_closure lb_channel_on_connectivity_changed_; - // Are we already watching the LB channel's connectivity? - bool watching_lb_channel_ = false; - // Response generator to inject address updates into lb_channel_. - RefCountedPtr response_generator_; + // TODO(juanlishen): Replace this with atomic. + Mutex lb_chand_mu_; - // The data associated with the current LB call. It holds a ref to this LB - // policy. It's initialized every time we query for backends. It's reset to - // NULL whenever the current LB call is no longer needed (e.g., the LB policy - // is shutting down, or the LB call has ended). A non-NULL lb_calld_ always - // contains a non-NULL lb_call_. - OrphanablePtr lb_calld_; // Timeout in milliseconds for the LB call. 0 means no deadline. int lb_call_timeout_ms_ = 0; - // Balancer call retry state. - BackOff lb_call_backoff_; - bool retry_timer_callback_pending_ = false; - grpc_timer lb_call_retry_timer_; - grpc_closure lb_on_call_retry_; - - // The deserialized response from the balancer. May be nullptr until one - // such response has arrived. - xds_grpclb_serverlist* serverlist_ = nullptr; + // Whether the checks for fallback at startup are ALL pending. There are + // several cases where this can be reset: + // 1. The fallback timer fires, we enter fallback mode. + // 2. Before the fallback timer fires, the LB channel becomes + // TRANSIENT_FAILURE or the LB call fails, we enter fallback mode. + // 3. Before the fallback timer fires, we receive a response from the + // balancer, we cancel the fallback timer and use the response to update the + // locality map. + bool fallback_at_startup_checks_pending_ = false; // Timeout in milliseconds for before using fallback backend addresses. // 0 means not using fallback. int lb_fallback_timeout_ms_ = 0; // The backend addresses from the resolver. - grpc_lb_addresses* fallback_backend_addresses_ = nullptr; + ServerAddressList fallback_backend_addresses_; // Fallback timer. - bool fallback_timer_callback_pending_ = false; grpc_timer lb_fallback_timer_; grpc_closure lb_on_fallback_; - // Pending picks that are waiting on the xDS policy's connectivity. - PendingPick* pending_picks_ = nullptr; + // The policy to use for the fallback backends. + RefCountedPtr fallback_policy_config_; + // Lock held when modifying the value of fallback_policy_ or + // pending_fallback_policy_. + Mutex fallback_policy_mu_; + // Non-null iff we are in fallback mode. + OrphanablePtr fallback_policy_; + OrphanablePtr pending_fallback_policy_; // The policy to use for the backends. - OrphanablePtr child_policy_; - grpc_connectivity_state child_connectivity_state_; - grpc_closure on_child_connectivity_changed_; - grpc_closure on_child_request_reresolution_; + RefCountedPtr child_policy_config_; + // Map of policies to use in the backend + LocalityMap locality_map_; + // TODO(mhaidry) : Add support for multiple maps of localities + // with different priorities + LocalityList locality_serverlist_; + // TODO(mhaidry) : Add a pending locality map that may be swapped with the + // the current one when new localities in the pending map are ready + // to accept connections }; +// +// XdsLb::Picker +// + +XdsLb::PickResult XdsLb::Picker::Pick(PickArgs* pick, grpc_error** error) { + // TODO(roth): Add support for drop handling. + // Generate a random number between 0 and the total weight + const uint32_t key = + (rand() * pickers_[pickers_.size() - 1].first) / RAND_MAX; + // Forward pick to whichever locality maps to the range in which the + // random number falls in. + PickResult result = PickFromLocality(key, pick, error); + // If pick succeeded, add client stats. + if (result == PickResult::PICK_COMPLETE && + pick->connected_subchannel != nullptr && client_stats_ != nullptr) { + // TODO(roth): Add support for client stats. + } + return result; +} + +XdsLb::PickResult XdsLb::Picker::PickFromLocality(const uint32_t key, + PickArgs* pick, + grpc_error** error) { + size_t mid = 0; + size_t start_index = 0; + size_t end_index = pickers_.size() - 1; + size_t index = 0; + while (end_index > start_index) { + mid = (start_index + end_index) / 2; + if (pickers_[mid].first > key) { + end_index = mid; + } else if (pickers_[mid].first < key) { + start_index = mid + 1; + } else { + index = mid + 1; + break; + } + } + if (index == 0) index = start_index; + GPR_ASSERT(pickers_[index].first > key); + return pickers_[index].second->Pick(pick, error); +} + +// +// XdsLb::FallbackHelper +// + +bool XdsLb::FallbackHelper::CalledByPendingFallback() const { + GPR_ASSERT(child_ != nullptr); + return child_ == parent_->pending_fallback_policy_.get(); +} + +bool XdsLb::FallbackHelper::CalledByCurrentFallback() const { + GPR_ASSERT(child_ != nullptr); + return child_ == parent_->fallback_policy_.get(); +} + +Subchannel* XdsLb::FallbackHelper::CreateSubchannel( + const grpc_channel_args& args) { + if (parent_->shutting_down_ || + (!CalledByPendingFallback() && !CalledByCurrentFallback())) { + return nullptr; + } + return parent_->channel_control_helper()->CreateSubchannel(args); +} + +grpc_channel* XdsLb::FallbackHelper::CreateChannel( + const char* target, const grpc_channel_args& args) { + if (parent_->shutting_down_ || + (!CalledByPendingFallback() && !CalledByCurrentFallback())) { + return nullptr; + } + return parent_->channel_control_helper()->CreateChannel(target, args); +} + +void XdsLb::FallbackHelper::UpdateState(grpc_connectivity_state state, + UniquePtr picker) { + if (parent_->shutting_down_) return; + // If this request is from the pending fallback policy, ignore it until + // it reports READY, at which point we swap it into place. + if (CalledByPendingFallback()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) { + gpr_log( + GPR_INFO, + "[xdslb %p helper %p] pending fallback policy %p reports state=%s", + parent_.get(), this, parent_->pending_fallback_policy_.get(), + grpc_connectivity_state_name(state)); + } + if (state != GRPC_CHANNEL_READY) return; + grpc_pollset_set_del_pollset_set( + parent_->fallback_policy_->interested_parties(), + parent_->interested_parties()); + MutexLock lock(&parent_->fallback_policy_mu_); + parent_->fallback_policy_ = std::move(parent_->pending_fallback_policy_); + } else if (!CalledByCurrentFallback()) { + // This request is from an outdated fallback policy, so ignore it. + return; + } + parent_->channel_control_helper()->UpdateState(state, std::move(picker)); +} + +void XdsLb::FallbackHelper::RequestReresolution() { + if (parent_->shutting_down_) return; + const LoadBalancingPolicy* latest_fallback_policy = + parent_->pending_fallback_policy_ != nullptr + ? parent_->pending_fallback_policy_.get() + : parent_->fallback_policy_.get(); + if (child_ != latest_fallback_policy) return; + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) { + gpr_log(GPR_INFO, + "[xdslb %p] Re-resolution requested from the fallback policy (%p).", + parent_.get(), child_); + } + GPR_ASSERT(parent_->lb_chand_ != nullptr); + parent_->channel_control_helper()->RequestReresolution(); +} + // // serverlist parsing code // -// vtable for LB tokens in grpc_lb_addresses -void* lb_token_copy(void* token) { - return token == nullptr - ? nullptr - : (void*)GRPC_MDELEM_REF(grpc_mdelem{(uintptr_t)token}).payload; -} -void lb_token_destroy(void* token) { - if (token != nullptr) { - GRPC_MDELEM_UNREF(grpc_mdelem{(uintptr_t)token}); - } -} -int lb_token_cmp(void* token1, void* token2) { - if (token1 > token2) return 1; - if (token1 < token2) return -1; - return 0; -} -const grpc_lb_user_data_vtable lb_token_vtable = { - lb_token_copy, lb_token_destroy, lb_token_cmp}; - // Returns the backend addresses extracted from the given addresses. -grpc_lb_addresses* ExtractBackendAddresses(const grpc_lb_addresses* addresses) { - // First pass: count the number of backend addresses. - size_t num_backends = 0; - for (size_t i = 0; i < addresses->num_addresses; ++i) { - if (!addresses->addresses[i].is_balancer) { - ++num_backends; +ServerAddressList ExtractBackendAddresses(const ServerAddressList& addresses) { + ServerAddressList backend_addresses; + for (size_t i = 0; i < addresses.size(); ++i) { + if (!addresses[i].IsBalancer()) { + backend_addresses.emplace_back(addresses[i]); } } - // Second pass: actually populate the addresses and (empty) LB tokens. - grpc_lb_addresses* backend_addresses = - grpc_lb_addresses_create(num_backends, &lb_token_vtable); - size_t num_copied = 0; - for (size_t i = 0; i < addresses->num_addresses; ++i) { - if (addresses->addresses[i].is_balancer) continue; - const grpc_resolved_address* addr = &addresses->addresses[i].address; - grpc_lb_addresses_set_address(backend_addresses, num_copied, &addr->addr, - addr->len, false /* is_balancer */, - nullptr /* balancer_name */, - (void*)GRPC_MDELEM_LB_TOKEN_EMPTY.payload); - ++num_copied; - } return backend_addresses; } @@ -431,67 +705,170 @@ void ParseServer(const xds_grpclb_server* server, grpc_resolved_address* addr) { } // Returns addresses extracted from \a serverlist. -grpc_lb_addresses* ProcessServerlist(const xds_grpclb_serverlist* serverlist) { - size_t num_valid = 0; - /* first pass: count how many are valid in order to allocate the necessary - * memory in a single block */ +ServerAddressList ProcessServerlist(const xds_grpclb_serverlist* serverlist) { + ServerAddressList addresses; for (size_t i = 0; i < serverlist->num_servers; ++i) { - if (IsServerValid(serverlist->servers[i], i, true)) ++num_valid; - } - grpc_lb_addresses* lb_addresses = - grpc_lb_addresses_create(num_valid, &lb_token_vtable); - /* second pass: actually populate the addresses and LB tokens (aka user data - * to the outside world) to be read by the child policy during its creation. - * Given that the validity tests are very cheap, they are performed again - * instead of marking the valid ones during the first pass, as this would - * incurr in an allocation due to the arbitrary number of server */ - size_t addr_idx = 0; - for (size_t sl_idx = 0; sl_idx < serverlist->num_servers; ++sl_idx) { - const xds_grpclb_server* server = serverlist->servers[sl_idx]; - if (!IsServerValid(serverlist->servers[sl_idx], sl_idx, false)) continue; - GPR_ASSERT(addr_idx < num_valid); - /* address processing */ + const xds_grpclb_server* server = serverlist->servers[i]; + if (!IsServerValid(serverlist->servers[i], i, false)) continue; grpc_resolved_address addr; ParseServer(server, &addr); - /* lb token processing */ - void* user_data; - if (server->has_load_balance_token) { - const size_t lb_token_max_length = - GPR_ARRAY_SIZE(server->load_balance_token); - const size_t lb_token_length = - strnlen(server->load_balance_token, lb_token_max_length); - grpc_slice lb_token_mdstr = grpc_slice_from_copied_buffer( - server->load_balance_token, lb_token_length); - user_data = - (void*)grpc_mdelem_from_slices(GRPC_MDSTR_LB_TOKEN, lb_token_mdstr) - .payload; - } else { - char* uri = grpc_sockaddr_to_uri(&addr); - gpr_log(GPR_INFO, - "Missing LB token for backend address '%s'. The empty token will " - "be used instead", - uri); - gpr_free(uri); - user_data = (void*)GRPC_MDELEM_LB_TOKEN_EMPTY.payload; - } - grpc_lb_addresses_set_address(lb_addresses, addr_idx, &addr.addr, addr.len, - false /* is_balancer */, - nullptr /* balancer_name */, user_data); - ++addr_idx; + addresses.emplace_back(addr, nullptr); } - GPR_ASSERT(addr_idx == num_valid); - return lb_addresses; + return addresses; } // -// XdsLb::BalancerCallState +// XdsLb::BalancerChannelState // -XdsLb::BalancerCallState::BalancerCallState( - RefCountedPtr parent_xdslb_policy) - : InternallyRefCountedWithTracing(&grpc_lb_xds_trace), - xdslb_policy_(std::move(parent_xdslb_policy)) { - GPR_ASSERT(xdslb_policy_ != nullptr); +XdsLb::BalancerChannelState::BalancerChannelState( + const char* balancer_name, const grpc_channel_args& args, + grpc_core::RefCountedPtr parent_xdslb_policy) + : InternallyRefCounted(&grpc_lb_xds_trace), + xdslb_policy_(std::move(parent_xdslb_policy)), + lb_call_backoff_( + BackOff::Options() + .set_initial_backoff(GRPC_XDS_INITIAL_CONNECT_BACKOFF_SECONDS * + 1000) + .set_multiplier(GRPC_XDS_RECONNECT_BACKOFF_MULTIPLIER) + .set_jitter(GRPC_XDS_RECONNECT_JITTER) + .set_max_backoff(GRPC_XDS_RECONNECT_MAX_BACKOFF_SECONDS * 1000)) { + GRPC_CLOSURE_INIT(&on_connectivity_changed_, + &XdsLb::BalancerChannelState::OnConnectivityChangedLocked, + this, grpc_combiner_scheduler(xdslb_policy_->combiner())); + channel_ = xdslb_policy_->channel_control_helper()->CreateChannel( + balancer_name, args); + GPR_ASSERT(channel_ != nullptr); + StartCallLocked(); +} + +XdsLb::BalancerChannelState::~BalancerChannelState() { + grpc_channel_destroy(channel_); +} + +void XdsLb::BalancerChannelState::Orphan() { + shutting_down_ = true; + lb_calld_.reset(); + if (retry_timer_callback_pending_) grpc_timer_cancel(&lb_call_retry_timer_); + Unref(DEBUG_LOCATION, "lb_channel_orphaned"); +} + +void XdsLb::BalancerChannelState::StartCallRetryTimerLocked() { + grpc_millis next_try = lb_call_backoff_.NextAttemptTime(); + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) { + gpr_log(GPR_INFO, + "[xdslb %p] Failed to connect to LB server (lb_chand: %p)...", + xdslb_policy_.get(), this); + grpc_millis timeout = next_try - ExecCtx::Get()->Now(); + if (timeout > 0) { + gpr_log(GPR_INFO, "[xdslb %p] ... retry_timer_active in %" PRId64 "ms.", + xdslb_policy_.get(), timeout); + } else { + gpr_log(GPR_INFO, "[xdslb %p] ... retry_timer_active immediately.", + xdslb_policy_.get()); + } + } + Ref(DEBUG_LOCATION, "on_balancer_call_retry_timer").release(); + GRPC_CLOSURE_INIT(&lb_on_call_retry_, &OnCallRetryTimerLocked, this, + grpc_combiner_scheduler(xdslb_policy_->combiner())); + grpc_timer_init(&lb_call_retry_timer_, next_try, &lb_on_call_retry_); + retry_timer_callback_pending_ = true; +} + +void XdsLb::BalancerChannelState::OnCallRetryTimerLocked(void* arg, + grpc_error* error) { + BalancerChannelState* lb_chand = static_cast(arg); + lb_chand->retry_timer_callback_pending_ = false; + if (!lb_chand->shutting_down_ && error == GRPC_ERROR_NONE && + lb_chand->lb_calld_ == nullptr) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) { + gpr_log(GPR_INFO, + "[xdslb %p] Restarting call to LB server (lb_chand: %p)", + lb_chand->xdslb_policy_.get(), lb_chand); + } + lb_chand->StartCallLocked(); + } + lb_chand->Unref(DEBUG_LOCATION, "on_balancer_call_retry_timer"); +} + +void XdsLb::BalancerChannelState::StartCallLocked() { + if (shutting_down_) return; + GPR_ASSERT(channel_ != nullptr); + GPR_ASSERT(lb_calld_ == nullptr); + lb_calld_ = MakeOrphanable(Ref()); + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) { + gpr_log(GPR_INFO, + "[xdslb %p] Query for backends (lb_chand: %p, lb_calld: %p)", + xdslb_policy_.get(), this, lb_calld_.get()); + } + lb_calld_->StartQuery(); +} + +void XdsLb::BalancerChannelState::StartConnectivityWatchLocked() { + grpc_channel_element* client_channel_elem = + grpc_channel_stack_last_element(grpc_channel_get_channel_stack(channel_)); + GPR_ASSERT(client_channel_elem->filter == &grpc_client_channel_filter); + // Ref held by callback. + Ref(DEBUG_LOCATION, "watch_lb_channel_connectivity").release(); + grpc_client_channel_watch_connectivity_state( + client_channel_elem, + grpc_polling_entity_create_from_pollset_set( + xdslb_policy_->interested_parties()), + &connectivity_, &on_connectivity_changed_, nullptr); +} + +void XdsLb::BalancerChannelState::CancelConnectivityWatchLocked() { + grpc_channel_element* client_channel_elem = + grpc_channel_stack_last_element(grpc_channel_get_channel_stack(channel_)); + GPR_ASSERT(client_channel_elem->filter == &grpc_client_channel_filter); + grpc_client_channel_watch_connectivity_state( + client_channel_elem, + grpc_polling_entity_create_from_pollset_set( + xdslb_policy_->interested_parties()), + nullptr, &on_connectivity_changed_, nullptr); +} + +void XdsLb::BalancerChannelState::OnConnectivityChangedLocked( + void* arg, grpc_error* error) { + BalancerChannelState* self = static_cast(arg); + if (!self->shutting_down_ && + self->xdslb_policy_->fallback_at_startup_checks_pending_) { + if (self->connectivity_ != GRPC_CHANNEL_TRANSIENT_FAILURE) { + // Not in TRANSIENT_FAILURE. Renew connectivity watch. + grpc_channel_element* client_channel_elem = + grpc_channel_stack_last_element( + grpc_channel_get_channel_stack(self->channel_)); + GPR_ASSERT(client_channel_elem->filter == &grpc_client_channel_filter); + grpc_client_channel_watch_connectivity_state( + client_channel_elem, + grpc_polling_entity_create_from_pollset_set( + self->xdslb_policy_->interested_parties()), + &self->connectivity_, &self->on_connectivity_changed_, nullptr); + return; // Early out so we don't drop the ref below. + } + // In TRANSIENT_FAILURE. Cancel the fallback timer and go into + // fallback mode immediately. + gpr_log(GPR_INFO, + "[xdslb %p] Balancer channel in state TRANSIENT_FAILURE; " + "entering fallback mode", + self); + self->xdslb_policy_->fallback_at_startup_checks_pending_ = false; + grpc_timer_cancel(&self->xdslb_policy_->lb_fallback_timer_); + self->xdslb_policy_->UpdateFallbackPolicyLocked(); + } + // Done watching connectivity state, so drop ref. + self->Unref(DEBUG_LOCATION, "watch_lb_channel_connectivity"); +} + +// +// XdsLb::BalancerChannelState::BalancerCallState +// + +XdsLb::BalancerChannelState::BalancerCallState::BalancerCallState( + RefCountedPtr lb_chand) + : InternallyRefCounted(&grpc_lb_xds_trace), + lb_chand_(std::move(lb_chand)) { + GPR_ASSERT(xdslb_policy() != nullptr); GPR_ASSERT(!xdslb_policy()->shutting_down_); // Init the LB call. Note that the LB call will progress every time there's // activity in xdslb_policy_->interested_parties(), which is comprised of @@ -503,8 +880,8 @@ XdsLb::BalancerCallState::BalancerCallState( ? GRPC_MILLIS_INF_FUTURE : ExecCtx::Get()->Now() + xdslb_policy()->lb_call_timeout_ms_; lb_call_ = grpc_channel_create_pollset_set_call( - xdslb_policy()->lb_channel_, nullptr, GRPC_PROPAGATE_DEFAULTS, - xdslb_policy_->interested_parties(), + lb_chand_->channel_, nullptr, GRPC_PROPAGATE_DEFAULTS, + xdslb_policy()->interested_parties(), GRPC_MDSTR_SLASH_GRPC_DOT_LB_DOT_V1_DOT_LOADBALANCER_SLASH_BALANCELOAD, nullptr, deadline, nullptr); // Init the LB call request payload. @@ -528,7 +905,7 @@ XdsLb::BalancerCallState::BalancerCallState( grpc_combiner_scheduler(xdslb_policy()->combiner())); } -XdsLb::BalancerCallState::~BalancerCallState() { +XdsLb::BalancerChannelState::BalancerCallState::~BalancerCallState() { GPR_ASSERT(lb_call_ != nullptr); grpc_call_unref(lb_call_); grpc_metadata_array_destroy(&lb_initial_metadata_recv_); @@ -538,7 +915,7 @@ XdsLb::BalancerCallState::~BalancerCallState() { grpc_slice_unref_internal(lb_call_status_details_); } -void XdsLb::BalancerCallState::Orphan() { +void XdsLb::BalancerChannelState::BalancerCallState::Orphan() { GPR_ASSERT(lb_call_ != nullptr); // If we are here because xdslb_policy wants to cancel the call, // lb_on_balancer_status_received_ will complete the cancellation and clean @@ -553,11 +930,11 @@ void XdsLb::BalancerCallState::Orphan() { // in lb_on_balancer_status_received_ instead of here. } -void XdsLb::BalancerCallState::StartQuery() { +void XdsLb::BalancerChannelState::BalancerCallState::StartQuery() { GPR_ASSERT(lb_call_ != nullptr); - if (grpc_lb_xds_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) { gpr_log(GPR_INFO, "[xdslb %p] Starting LB call (lb_calld: %p, lb_call: %p)", - xdslb_policy_.get(), this, lb_call_); + xdslb_policy(), this, lb_call_); } // Create the ops. grpc_call_error call_error; @@ -625,7 +1002,8 @@ void XdsLb::BalancerCallState::StartQuery() { GPR_ASSERT(GRPC_CALL_OK == call_error); } -void XdsLb::BalancerCallState::ScheduleNextClientLoadReportLocked() { +void XdsLb::BalancerChannelState::BalancerCallState:: + ScheduleNextClientLoadReportLocked() { const grpc_millis next_client_load_report_time = ExecCtx::Get()->Now() + client_stats_report_interval_; GRPC_CLOSURE_INIT(&client_load_report_closure_, @@ -636,12 +1014,11 @@ void XdsLb::BalancerCallState::ScheduleNextClientLoadReportLocked() { client_load_report_timer_callback_pending_ = true; } -void XdsLb::BalancerCallState::MaybeSendClientLoadReportLocked( - void* arg, grpc_error* error) { +void XdsLb::BalancerChannelState::BalancerCallState:: + MaybeSendClientLoadReportLocked(void* arg, grpc_error* error) { BalancerCallState* lb_calld = static_cast(arg); - XdsLb* xdslb_policy = lb_calld->xdslb_policy(); lb_calld->client_load_report_timer_callback_pending_ = false; - if (error != GRPC_ERROR_NONE || lb_calld != xdslb_policy->lb_calld_.get()) { + if (error != GRPC_ERROR_NONE || !lb_calld->IsCurrentCallOnChannel()) { lb_calld->Unref(DEBUG_LOCATION, "client_load_report"); return; } @@ -655,7 +1032,7 @@ void XdsLb::BalancerCallState::MaybeSendClientLoadReportLocked( } } -bool XdsLb::BalancerCallState::LoadReportCountersAreZero( +bool XdsLb::BalancerChannelState::BalancerCallState::LoadReportCountersAreZero( xds_grpclb_request* request) { XdsLbClientStats::DroppedCallCounts* drop_entries = static_cast( @@ -668,7 +1045,9 @@ bool XdsLb::BalancerCallState::LoadReportCountersAreZero( (drop_entries == nullptr || drop_entries->empty()); } -void XdsLb::BalancerCallState::SendClientLoadReportLocked() { +// TODO(vpowar): Use LRS to send the client Load Report. +void XdsLb::BalancerChannelState::BalancerCallState:: + SendClientLoadReportLocked() { // Construct message payload. GPR_ASSERT(send_message_payload_ == nullptr); xds_grpclb_request* request = @@ -685,61 +1064,31 @@ void XdsLb::BalancerCallState::SendClientLoadReportLocked() { } else { last_client_load_report_counters_were_zero_ = false; } - grpc_slice request_payload_slice = xds_grpclb_request_encode(request); - send_message_payload_ = - grpc_raw_byte_buffer_create(&request_payload_slice, 1); - grpc_slice_unref_internal(request_payload_slice); + // TODO(vpowar): Send the report on LRS stream. xds_grpclb_request_destroy(request); - // Send the report. - grpc_op op; - memset(&op, 0, sizeof(op)); - op.op = GRPC_OP_SEND_MESSAGE; - op.data.send_message.send_message = send_message_payload_; - GRPC_CLOSURE_INIT(&client_load_report_closure_, ClientLoadReportDoneLocked, - this, grpc_combiner_scheduler(xdslb_policy()->combiner())); - grpc_call_error call_error = grpc_call_start_batch_and_execute( - lb_call_, &op, 1, &client_load_report_closure_); - if (GPR_UNLIKELY(call_error != GRPC_CALL_OK)) { - gpr_log(GPR_ERROR, "[xdslb %p] call_error=%d", xdslb_policy_.get(), - call_error); - GPR_ASSERT(GRPC_CALL_OK == call_error); - } } -void XdsLb::BalancerCallState::ClientLoadReportDoneLocked(void* arg, - grpc_error* error) { - BalancerCallState* lb_calld = static_cast(arg); - XdsLb* xdslb_policy = lb_calld->xdslb_policy(); - grpc_byte_buffer_destroy(lb_calld->send_message_payload_); - lb_calld->send_message_payload_ = nullptr; - if (error != GRPC_ERROR_NONE || lb_calld != xdslb_policy->lb_calld_.get()) { - lb_calld->Unref(DEBUG_LOCATION, "client_load_report"); - return; - } - lb_calld->ScheduleNextClientLoadReportLocked(); -} - -void XdsLb::BalancerCallState::OnInitialRequestSentLocked(void* arg, - grpc_error* error) { +void XdsLb::BalancerChannelState::BalancerCallState::OnInitialRequestSentLocked( + void* arg, grpc_error* error) { BalancerCallState* lb_calld = static_cast(arg); grpc_byte_buffer_destroy(lb_calld->send_message_payload_); lb_calld->send_message_payload_ = nullptr; // If we attempted to send a client load report before the initial request was // sent (and this lb_calld is still in use), send the load report now. if (lb_calld->client_load_report_is_due_ && - lb_calld == lb_calld->xdslb_policy()->lb_calld_.get()) { + lb_calld->IsCurrentCallOnChannel()) { lb_calld->SendClientLoadReportLocked(); lb_calld->client_load_report_is_due_ = false; } lb_calld->Unref(DEBUG_LOCATION, "on_initial_request_sent"); } -void XdsLb::BalancerCallState::OnBalancerMessageReceivedLocked( - void* arg, grpc_error* error) { +void XdsLb::BalancerChannelState::BalancerCallState:: + OnBalancerMessageReceivedLocked(void* arg, grpc_error* error) { BalancerCallState* lb_calld = static_cast(arg); XdsLb* xdslb_policy = lb_calld->xdslb_policy(); // Empty payload means the LB call was cancelled. - if (lb_calld != xdslb_policy->lb_calld_.get() || + if (!lb_calld->IsCurrentCallOnChannel() || lb_calld->recv_message_payload_ == nullptr) { lb_calld->Unref(DEBUG_LOCATION, "on_message_received"); return; @@ -756,21 +1105,34 @@ void XdsLb::BalancerCallState::OnBalancerMessageReceivedLocked( (initial_response = xds_grpclb_initial_response_parse(response_slice)) != nullptr) { // Have NOT seen initial response, look for initial response. + // TODO(juanlishen): When we convert this to use the xds protocol, the + // balancer will send us a fallback timeout such that we should go into + // fallback mode if we have lost contact with the balancer after a certain + // period of time. We will need to save the timeout value here, and then + // when the balancer call ends, we will need to start a timer for the + // specified period of time, and if the timer fires, we go into fallback + // mode. We will also need to cancel the timer when we receive a serverlist + // from the balancer. if (initial_response->has_client_stats_report_interval) { - lb_calld->client_stats_report_interval_ = GPR_MAX( - GPR_MS_PER_SEC, xds_grpclb_duration_to_millis( - &initial_response->client_stats_report_interval)); - if (grpc_lb_xds_trace.enabled()) { + const grpc_millis interval = xds_grpclb_duration_to_millis( + &initial_response->client_stats_report_interval); + if (interval > 0) { + lb_calld->client_stats_report_interval_ = + GPR_MAX(GPR_MS_PER_SEC, interval); + } + } + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) { + if (lb_calld->client_stats_report_interval_ != 0) { gpr_log(GPR_INFO, "[xdslb %p] Received initial LB response message; " "client load reporting interval = %" PRId64 " milliseconds", xdslb_policy, lb_calld->client_stats_report_interval_); + } else { + gpr_log(GPR_INFO, + "[xdslb %p] Received initial LB response message; client load " + "reporting NOT enabled", + xdslb_policy); } - } else if (grpc_lb_xds_trace.enabled()) { - gpr_log(GPR_INFO, - "[xdslb %p] Received initial LB response message; client load " - "reporting NOT enabled", - xdslb_policy); } xds_grpclb_initial_response_destroy(initial_response); lb_calld->seen_initial_response_ = true; @@ -778,7 +1140,7 @@ void XdsLb::BalancerCallState::OnBalancerMessageReceivedLocked( response_slice)) != nullptr) { // Have seen initial response, look for serverlist. GPR_ASSERT(lb_calld->lb_call_ != nullptr); - if (grpc_lb_xds_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) { gpr_log(GPR_INFO, "[xdslb %p] Serverlist with %" PRIuPTR " servers received", xdslb_policy, serverlist->num_servers); @@ -792,52 +1154,69 @@ void XdsLb::BalancerCallState::OnBalancerMessageReceivedLocked( gpr_free(ipport); } } - /* update serverlist */ - if (serverlist->num_servers > 0) { - // Start sending client load report only after we start using the - // serverlist returned from the current LB call. - if (lb_calld->client_stats_report_interval_ > 0 && - lb_calld->client_stats_ == nullptr) { - lb_calld->client_stats_.reset(New()); - // TODO(roth): We currently track this ref manually. Once the - // ClosureRef API is ready, we should pass the RefCountedPtr<> along - // with the callback. - auto self = lb_calld->Ref(DEBUG_LOCATION, "client_load_report"); - self.release(); - lb_calld->ScheduleNextClientLoadReportLocked(); + // Pending LB channel receives a serverlist; promote it. + // Note that this call can't be on a discarded pending channel, because + // such channels don't have any current call but we have checked this call + // is a current call. + if (!lb_calld->lb_chand_->IsCurrentChannel()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) { + gpr_log(GPR_INFO, + "[xdslb %p] Promoting pending LB channel %p to replace " + "current LB channel %p", + xdslb_policy, lb_calld->lb_chand_.get(), + lb_calld->xdslb_policy()->lb_chand_.get()); } - if (xds_grpclb_serverlist_equals(xdslb_policy->serverlist_, serverlist)) { - if (grpc_lb_xds_trace.enabled()) { - gpr_log(GPR_INFO, - "[xdslb %p] Incoming server list identical to current, " - "ignoring.", - xdslb_policy); - } - xds_grpclb_destroy_serverlist(serverlist); - } else { /* new serverlist */ - if (xdslb_policy->serverlist_ != nullptr) { - /* dispose of the old serverlist */ - xds_grpclb_destroy_serverlist(xdslb_policy->serverlist_); - } else { - /* or dispose of the fallback */ - grpc_lb_addresses_destroy(xdslb_policy->fallback_backend_addresses_); - xdslb_policy->fallback_backend_addresses_ = nullptr; - if (xdslb_policy->fallback_timer_callback_pending_) { - grpc_timer_cancel(&xdslb_policy->lb_fallback_timer_); - } - } - // and update the copy in the XdsLb instance. This - // serverlist instance will be destroyed either upon the next - // update or when the XdsLb instance is destroyed. - xdslb_policy->serverlist_ = serverlist; - xdslb_policy->CreateOrUpdateChildPolicyLocked(); - } - } else { - if (grpc_lb_xds_trace.enabled()) { - gpr_log(GPR_INFO, "[xdslb %p] Received empty server list, ignoring.", + lb_calld->xdslb_policy()->lb_chand_ = + std::move(lb_calld->xdslb_policy()->pending_lb_chand_); + } + // Start sending client load report only after we start using the + // serverlist returned from the current LB call. + if (lb_calld->client_stats_report_interval_ > 0 && + lb_calld->client_stats_ == nullptr) { + lb_calld->client_stats_ = MakeRefCounted(); + lb_calld->Ref(DEBUG_LOCATION, "client_load_report").release(); + lb_calld->ScheduleNextClientLoadReportLocked(); + } + if (!xdslb_policy->locality_serverlist_.empty() && + xds_grpclb_serverlist_equals( + xdslb_policy->locality_serverlist_[0]->serverlist, serverlist)) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) { + gpr_log(GPR_INFO, + "[xdslb %p] Incoming server list identical to current, " + "ignoring.", xdslb_policy); } xds_grpclb_destroy_serverlist(serverlist); + } else { // New serverlist. + // If the balancer tells us to drop all the calls, we should exit fallback + // mode immediately. + // TODO(juanlishen): When we add EDS drop, we should change to check + // drop_percentage. + if (serverlist->num_servers == 0) xdslb_policy->MaybeExitFallbackMode(); + if (!xdslb_policy->locality_serverlist_.empty()) { + xds_grpclb_destroy_serverlist( + xdslb_policy->locality_serverlist_[0]->serverlist); + } else { + // This is the first serverlist we've received, don't enter fallback + // mode. + xdslb_policy->MaybeCancelFallbackAtStartupChecks(); + // Initialize locality serverlist, currently the list only handles + // one child. + xdslb_policy->locality_serverlist_.emplace_back( + MakeUnique()); + xdslb_policy->locality_serverlist_[0]->locality_name = + static_cast(gpr_strdup(kDefaultLocalityName)); + xdslb_policy->locality_serverlist_[0]->locality_weight = + kDefaultLocalityWeight; + } + // Update the serverlist in the XdsLb instance. This serverlist + // instance will be destroyed either upon the next update or when the + // XdsLb instance is destroyed. + xdslb_policy->locality_serverlist_[0]->serverlist = serverlist; + xdslb_policy->locality_map_.UpdateLocked( + xdslb_policy->locality_serverlist_, + xdslb_policy->child_policy_config_.get(), xdslb_policy->args_, + xdslb_policy); } } else { // No valid initial response or serverlist found. @@ -867,37 +1246,65 @@ void XdsLb::BalancerCallState::OnBalancerMessageReceivedLocked( } } -void XdsLb::BalancerCallState::OnBalancerStatusReceivedLocked( - void* arg, grpc_error* error) { +void XdsLb::BalancerChannelState::BalancerCallState:: + OnBalancerStatusReceivedLocked(void* arg, grpc_error* error) { BalancerCallState* lb_calld = static_cast(arg); XdsLb* xdslb_policy = lb_calld->xdslb_policy(); + BalancerChannelState* lb_chand = lb_calld->lb_chand_.get(); GPR_ASSERT(lb_calld->lb_call_ != nullptr); - if (grpc_lb_xds_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) { char* status_details = grpc_slice_to_c_string(lb_calld->lb_call_status_details_); gpr_log(GPR_INFO, "[xdslb %p] Status from LB server received. Status = %d, details " - "= '%s', (lb_calld: %p, lb_call: %p), error '%s'", - xdslb_policy, lb_calld->lb_call_status_, status_details, lb_calld, - lb_calld->lb_call_, grpc_error_string(error)); + "= '%s', (lb_chand: %p, lb_calld: %p, lb_call: %p), error '%s'", + xdslb_policy, lb_calld->lb_call_status_, status_details, lb_chand, + lb_calld, lb_calld->lb_call_, grpc_error_string(error)); gpr_free(status_details); } - xdslb_policy->TryReresolutionLocked(&grpc_lb_xds_trace, GRPC_ERROR_NONE); - // If this lb_calld is still in use, this call ended because of a failure so - // we want to retry connecting. Otherwise, we have deliberately ended this - // call and no further action is required. - if (lb_calld == xdslb_policy->lb_calld_.get()) { - xdslb_policy->lb_calld_.reset(); + // Ignore status from a stale call. + if (lb_calld->IsCurrentCallOnChannel()) { + // Because this call is the current one on the channel, the channel can't + // have been swapped out; otherwise, the call should have been reset. + GPR_ASSERT(lb_chand->IsCurrentChannel() || lb_chand->IsPendingChannel()); GPR_ASSERT(!xdslb_policy->shutting_down_); - if (lb_calld->seen_initial_response_) { - // If we lose connection to the LB server, reset the backoff and restart - // the LB call immediately. - xdslb_policy->lb_call_backoff_.Reset(); - xdslb_policy->StartBalancerCallLocked(); + if (lb_chand != xdslb_policy->LatestLbChannel()) { + // This channel must be the current one and there is a pending one. Swap + // in the pending one and we are done. + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) { + gpr_log(GPR_INFO, + "[xdslb %p] Promoting pending LB channel %p to replace " + "current LB channel %p", + xdslb_policy, lb_calld->lb_chand_.get(), + lb_calld->xdslb_policy()->lb_chand_.get()); + } + xdslb_policy->lb_chand_ = std::move(xdslb_policy->pending_lb_chand_); } else { - // If this LB call fails establishing any connection to the LB server, - // retry later. - xdslb_policy->StartBalancerCallRetryTimerLocked(); + // This channel is the most recently created one. Try to restart the call + // and reresolve. + lb_chand->lb_calld_.reset(); + if (lb_calld->seen_initial_response_) { + // If we lost connection to the LB server, reset the backoff and restart + // the LB call immediately. + lb_chand->lb_call_backoff_.Reset(); + lb_chand->StartCallLocked(); + } else { + // If we failed to connect to the LB server, retry later. + lb_chand->StartCallRetryTimerLocked(); + } + xdslb_policy->channel_control_helper()->RequestReresolution(); + // If the fallback-at-startup checks are pending, go into fallback mode + // immediately. This short-circuits the timeout for the + // fallback-at-startup case. + if (xdslb_policy->fallback_at_startup_checks_pending_) { + gpr_log(GPR_INFO, + "[xdslb %p] Balancer call finished; entering fallback mode", + xdslb_policy); + xdslb_policy->fallback_at_startup_checks_pending_ = false; + grpc_timer_cancel(&xdslb_policy->lb_fallback_timer_); + lb_chand->CancelConnectivityWatchLocked(); + xdslb_policy->UpdateFallbackPolicyLocked(); + } } } lb_calld->Unref(DEBUG_LOCATION, "lb_call_ended"); @@ -907,68 +1314,20 @@ void XdsLb::BalancerCallState::OnBalancerStatusReceivedLocked( // helper code for creating balancer channel // -grpc_lb_addresses* ExtractBalancerAddresses( - const grpc_lb_addresses* addresses) { - size_t num_grpclb_addrs = 0; - for (size_t i = 0; i < addresses->num_addresses; ++i) { - if (addresses->addresses[i].is_balancer) ++num_grpclb_addrs; - } - // There must be at least one balancer address, or else the - // client_channel would not have chosen this LB policy. - GPR_ASSERT(num_grpclb_addrs > 0); - grpc_lb_addresses* lb_addresses = - grpc_lb_addresses_create(num_grpclb_addrs, nullptr); - size_t lb_addresses_idx = 0; - for (size_t i = 0; i < addresses->num_addresses; ++i) { - if (!addresses->addresses[i].is_balancer) continue; - if (GPR_UNLIKELY(addresses->addresses[i].user_data != nullptr)) { - gpr_log(GPR_ERROR, - "This LB policy doesn't support user data. It will be ignored"); - } - grpc_lb_addresses_set_address( - lb_addresses, lb_addresses_idx++, addresses->addresses[i].address.addr, - addresses->addresses[i].address.len, false /* is balancer */, - addresses->addresses[i].balancer_name, nullptr /* user data */); - } - GPR_ASSERT(num_grpclb_addrs == lb_addresses_idx); - return lb_addresses; -} - -/* Returns the channel args for the LB channel, used to create a bidirectional - * stream for the reception of load balancing updates. - * - * Inputs: - * - \a addresses: corresponding to the balancers. - * - \a response_generator: in order to propagate updates from the resolver - * above the grpclb policy. - * - \a args: other args inherited from the xds policy. */ -grpc_channel_args* BuildBalancerChannelArgs( - const grpc_lb_addresses* addresses, - FakeResolverResponseGenerator* response_generator, - const grpc_channel_args* args) { - grpc_lb_addresses* lb_addresses = ExtractBalancerAddresses(addresses); - // Channel args to remove. +// Returns the channel args for the LB channel, used to create a bidirectional +// stream for the reception of load balancing updates. +grpc_channel_args* BuildBalancerChannelArgs(const grpc_channel_args* args) { static const char* args_to_remove[] = { // LB policy name, since we want to use the default (pick_first) in // the LB channel. GRPC_ARG_LB_POLICY_NAME, + // The service config that contains the LB config. We don't want to + // recursively use xds in the LB channel. + GRPC_ARG_SERVICE_CONFIG, // The channel arg for the server URI, since that will be different for // the LB channel than for the parent channel. The client channel // factory will re-add this arg with the right value. GRPC_ARG_SERVER_URI, - // The resolved addresses, which will be generated by the name resolver - // used in the LB channel. Note that the LB channel will use the fake - // resolver, so this won't actually generate a query to DNS (or some - // other name service). However, the addresses returned by the fake - // resolver will have is_balancer=false, whereas our own addresses have - // is_balancer=true. We need the LB channel to return addresses with - // is_balancer=false so that it does not wind up recursively using the - // xds LB policy, as per the special case logic in client_channel.c. - GRPC_ARG_LB_ADDRESSES, - // The fake resolver response generator, because we are replacing it - // with the one from the xds 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_xds_modify_lb_channel_args), // as opposed to the authority from the parent channel. @@ -980,14 +1339,6 @@ grpc_channel_args* BuildBalancerChannelArgs( }; // Channel args to add. const grpc_arg args_to_add[] = { - // New LB addresses. - // Note that we pass these in both when creating the LB channel - // and via the fake resolver. The latter is what actually gets used. - grpc_lb_addresses_create_channel_arg(lb_addresses), - // The fake resolver response generator, which we use to inject - // address updates into the LB channel. - grpc_core::FakeResolverResponseGenerator::MakeChannelArg( - response_generator), // A channel arg indicating the target is a xds load balancer. grpc_channel_arg_integer_create( const_cast(GRPC_ARG_ADDRESS_IS_XDS_LOAD_BALANCER), 1), @@ -1001,41 +1352,17 @@ grpc_channel_args* BuildBalancerChannelArgs( args, args_to_remove, GPR_ARRAY_SIZE(args_to_remove), args_to_add, GPR_ARRAY_SIZE(args_to_add)); // Make any necessary modifications for security. - new_args = grpc_lb_policy_xds_modify_lb_channel_args(new_args); - // Clean up. - grpc_lb_addresses_destroy(lb_addresses); - return new_args; + return grpc_lb_policy_xds_modify_lb_channel_args(new_args); } // // ctor and dtor // -// TODO(vishalpowar): Use lb_config in args to configure LB policy. -XdsLb::XdsLb(const grpc_lb_addresses* addresses, - const LoadBalancingPolicy::Args& args) - : LoadBalancingPolicy(args), - response_generator_(MakeRefCounted()), - lb_call_backoff_( - BackOff::Options() - .set_initial_backoff(GRPC_XDS_INITIAL_CONNECT_BACKOFF_SECONDS * - 1000) - .set_multiplier(GRPC_XDS_RECONNECT_BACKOFF_MULTIPLIER) - .set_jitter(GRPC_XDS_RECONNECT_JITTER) - .set_max_backoff(GRPC_XDS_RECONNECT_MAX_BACKOFF_SECONDS * 1000)) { - // Initialization. - gpr_mu_init(&lb_channel_mu_); - grpc_subchannel_index_ref(); - GRPC_CLOSURE_INIT(&lb_channel_on_connectivity_changed_, - &XdsLb::OnBalancerChannelConnectivityChangedLocked, this, - grpc_combiner_scheduler(args.combiner)); - GRPC_CLOSURE_INIT(&on_child_connectivity_changed_, - &XdsLb::OnChildPolicyConnectivityChangedLocked, this, - grpc_combiner_scheduler(args.combiner)); - GRPC_CLOSURE_INIT(&on_child_request_reresolution_, - &XdsLb::OnChildPolicyRequestReresolutionLocked, this, - grpc_combiner_scheduler(args.combiner)); - grpc_connectivity_state_init(&state_tracker_, GRPC_CHANNEL_IDLE, "xds"); +XdsLb::XdsLb(Args args) + : LoadBalancingPolicy(std::move(args)), + locality_map_(), + locality_serverlist_() { // Record server name. const grpc_arg* arg = grpc_channel_args_find(args.args, GRPC_ARG_SERVER_URI); const char* server_uri = grpc_channel_arg_get_string(arg); @@ -1043,7 +1370,7 @@ XdsLb::XdsLb(const grpc_lb_addresses* addresses, grpc_uri* uri = grpc_uri_parse(server_uri, true); GPR_ASSERT(uri->path[0] != '\0'); server_name_ = gpr_strdup(uri->path[0] == '/' ? uri->path + 1 : uri->path); - if (grpc_lb_xds_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) { gpr_log(GPR_INFO, "[xdslb %p] Will use '%s' as the server name for LB request.", this, server_name_); @@ -1053,239 +1380,102 @@ XdsLb::XdsLb(const grpc_lb_addresses* addresses, arg = grpc_channel_args_find(args.args, GRPC_ARG_GRPCLB_CALL_TIMEOUT_MS); lb_call_timeout_ms_ = grpc_channel_arg_get_integer(arg, {0, 0, INT_MAX}); // Record fallback timeout. - arg = grpc_channel_args_find(args.args, GRPC_ARG_GRPCLB_FALLBACK_TIMEOUT_MS); + arg = grpc_channel_args_find(args.args, GRPC_ARG_XDS_FALLBACK_TIMEOUT_MS); lb_fallback_timeout_ms_ = grpc_channel_arg_get_integer( arg, {GRPC_XDS_DEFAULT_FALLBACK_TIMEOUT_MS, 0, INT_MAX}); - // Process channel args. - ProcessChannelArgsLocked(*args.args); } XdsLb::~XdsLb() { - GPR_ASSERT(pending_picks_ == nullptr); - gpr_mu_destroy(&lb_channel_mu_); gpr_free((void*)server_name_); grpc_channel_args_destroy(args_); - grpc_connectivity_state_destroy(&state_tracker_); - if (serverlist_ != nullptr) { - xds_grpclb_destroy_serverlist(serverlist_); - } - if (fallback_backend_addresses_ != nullptr) { - grpc_lb_addresses_destroy(fallback_backend_addresses_); - } - grpc_subchannel_index_unref(); + locality_serverlist_.clear(); } void XdsLb::ShutdownLocked() { - grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Channel shutdown"); shutting_down_ = true; - lb_calld_.reset(); - if (retry_timer_callback_pending_) { - grpc_timer_cancel(&lb_call_retry_timer_); - } - if (fallback_timer_callback_pending_) { + if (fallback_at_startup_checks_pending_) { grpc_timer_cancel(&lb_fallback_timer_); } - child_policy_.reset(); - TryReresolutionLocked(&grpc_lb_xds_trace, GRPC_ERROR_CANCELLED); - // We destroy the LB channel here instead of in our destructor because - // destroying the channel triggers a last callback to - // OnBalancerChannelConnectivityChangedLocked(), and we need to be - // alive when that callback is invoked. - if (lb_channel_ != nullptr) { - gpr_mu_lock(&lb_channel_mu_); - grpc_channel_destroy(lb_channel_); - lb_channel_ = nullptr; - gpr_mu_unlock(&lb_channel_mu_); + locality_map_.ShutdownLocked(); + if (fallback_policy_ != nullptr) { + grpc_pollset_set_del_pollset_set(fallback_policy_->interested_parties(), + interested_parties()); } - grpc_connectivity_state_set(&state_tracker_, GRPC_CHANNEL_SHUTDOWN, - GRPC_ERROR_REF(error), "xds_shutdown"); - // Clear pending picks. - PendingPick* pp; - while ((pp = pending_picks_) != nullptr) { - pending_picks_ = pp->next; - pp->pick->connected_subchannel.reset(); - // Note: pp is deleted in this callback. - GRPC_CLOSURE_SCHED(&pp->on_complete, GRPC_ERROR_REF(error)); + if (pending_fallback_policy_ != nullptr) { + grpc_pollset_set_del_pollset_set( + pending_fallback_policy_->interested_parties(), interested_parties()); + } + { + MutexLock lock(&fallback_policy_mu_); + fallback_policy_.reset(); + pending_fallback_policy_.reset(); + } + // We reset the LB channels here instead of in our destructor because they + // hold refs to XdsLb. + { + MutexLock lock(&lb_chand_mu_); + lb_chand_.reset(); + pending_lb_chand_.reset(); } - GRPC_ERROR_UNREF(error); } // // public methods // -void XdsLb::HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) { - PendingPick* pp; - while ((pp = pending_picks_) != nullptr) { - pending_picks_ = pp->next; - pp->pick->on_complete = pp->original_on_complete; - pp->pick->user_data = nullptr; - grpc_error* error = GRPC_ERROR_NONE; - if (new_policy->PickLocked(pp->pick, &error)) { - // Synchronous return; schedule closure. - GRPC_CLOSURE_SCHED(pp->pick->on_complete, error); - } - Delete(pp); - } -} - -// Cancel a specific pending pick. -// -// A pick progresses as follows: -// - If there's a child policy available, it'll be handed over to child policy -// (in CreateChildPolicyLocked()). From that point onwards, it'll be the -// child policy's responsibility. For cancellations, that implies the pick -// needs to be also cancelled by the child policy instance. -// - Otherwise, without a child policy instance, picks stay pending at this -// policy's level (xds), inside the pending_picks_ list. To cancel these, -// we invoke the completion closure and set the pick's connected -// subchannel to nullptr right here. -void XdsLb::CancelPickLocked(PickState* pick, grpc_error* error) { - PendingPick* pp = pending_picks_; - pending_picks_ = nullptr; - while (pp != nullptr) { - PendingPick* next = pp->next; - if (pp->pick == pick) { - pick->connected_subchannel.reset(); - // Note: pp is deleted in this callback. - GRPC_CLOSURE_SCHED(&pp->on_complete, - GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Pick Cancelled", &error, 1)); - } else { - pp->next = pending_picks_; - pending_picks_ = pp; - } - pp = next; - } - if (child_policy_ != nullptr) { - child_policy_->CancelPickLocked(pick, GRPC_ERROR_REF(error)); - } - GRPC_ERROR_UNREF(error); -} - -// Cancel all pending picks. -// -// A pick progresses as follows: -// - If there's a child policy available, it'll be handed over to child policy -// (in CreateChildPolicyLocked()). From that point onwards, it'll be the -// child policy's responsibility. For cancellations, that implies the pick -// needs to be also cancelled by the child policy instance. -// - Otherwise, without a child policy instance, picks stay pending at this -// policy's level (xds), inside the pending_picks_ list. To cancel these, -// we invoke the completion closure and set the pick's connected -// subchannel to nullptr right here. -void XdsLb::CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask, - uint32_t initial_metadata_flags_eq, - grpc_error* error) { - PendingPick* pp = pending_picks_; - pending_picks_ = nullptr; - while (pp != nullptr) { - PendingPick* next = pp->next; - if ((pp->pick->initial_metadata_flags & initial_metadata_flags_mask) == - initial_metadata_flags_eq) { - // Note: pp is deleted in this callback. - GRPC_CLOSURE_SCHED(&pp->on_complete, - GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Pick Cancelled", &error, 1)); - } else { - pp->next = pending_picks_; - pending_picks_ = pp; - } - pp = next; - } - if (child_policy_ != nullptr) { - child_policy_->CancelMatchingPicksLocked(initial_metadata_flags_mask, - initial_metadata_flags_eq, - GRPC_ERROR_REF(error)); - } - GRPC_ERROR_UNREF(error); -} - -void XdsLb::ExitIdleLocked() { - if (!started_picking_) { - StartPickingLocked(); - } -} - void XdsLb::ResetBackoffLocked() { - if (lb_channel_ != nullptr) { - grpc_channel_reset_connect_backoff(lb_channel_); + if (lb_chand_ != nullptr) { + grpc_channel_reset_connect_backoff(lb_chand_->channel()); } - if (child_policy_ != nullptr) { - child_policy_->ResetBackoffLocked(); + if (pending_lb_chand_ != nullptr) { + grpc_channel_reset_connect_backoff(pending_lb_chand_->channel()); } -} - -bool XdsLb::PickLocked(PickState* pick, grpc_error** error) { - PendingPick* pp = PendingPickCreate(pick); - bool pick_done = false; - if (child_policy_ != nullptr) { - if (grpc_lb_xds_trace.enabled()) { - gpr_log(GPR_INFO, "[xdslb %p] about to PICK from policy %p", this, - child_policy_.get()); - } - pick_done = PickFromChildPolicyLocked(false /* force_async */, pp, error); - } else { // child_policy_ == NULL - if (pick->on_complete == nullptr) { - *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "No pick result available but synchronous result required."); - pick_done = true; - } else { - if (grpc_lb_xds_trace.enabled()) { - gpr_log(GPR_INFO, - "[xdslb %p] No child policy. Adding to xds's pending picks", - this); - } - AddPendingPick(pp); - if (!started_picking_) { - StartPickingLocked(); - } - pick_done = false; - } + locality_map_.ResetBackoffLocked(); + if (fallback_policy_ != nullptr) { + fallback_policy_->ResetBackoffLocked(); + } + if (pending_fallback_policy_ != nullptr) { + pending_fallback_policy_->ResetBackoffLocked(); } - return pick_done; } void XdsLb::FillChildRefsForChannelz(channelz::ChildRefsList* child_subchannels, channelz::ChildRefsList* child_channels) { - // delegate to the child_policy_ to fill the children subchannels. - child_policy_->FillChildRefsForChannelz(child_subchannels, child_channels); - MutexLock lock(&lb_channel_mu_); - if (lb_channel_ != nullptr) { + // Delegate to the locality_map_ to fill the children subchannels. + locality_map_.FillChildRefsForChannelz(child_subchannels, child_channels); + { + // This must be done holding fallback_policy_mu_, since this method does not + // run in the combiner. + MutexLock lock(&fallback_policy_mu_); + if (fallback_policy_ != nullptr) { + fallback_policy_->FillChildRefsForChannelz(child_subchannels, + child_channels); + } + if (pending_fallback_policy_ != nullptr) { + pending_fallback_policy_->FillChildRefsForChannelz(child_subchannels, + child_channels); + } + } + MutexLock lock(&lb_chand_mu_); + if (lb_chand_ != nullptr) { grpc_core::channelz::ChannelNode* channel_node = - grpc_channel_get_channelz_node(lb_channel_); + grpc_channel_get_channelz_node(lb_chand_->channel()); + if (channel_node != nullptr) { + child_channels->push_back(channel_node->uuid()); + } + } + if (pending_lb_chand_ != nullptr) { + grpc_core::channelz::ChannelNode* channel_node = + grpc_channel_get_channelz_node(pending_lb_chand_->channel()); if (channel_node != nullptr) { child_channels->push_back(channel_node->uuid()); } } } -grpc_connectivity_state XdsLb::CheckConnectivityLocked( - grpc_error** connectivity_error) { - return grpc_connectivity_state_get(&state_tracker_, connectivity_error); -} - -void XdsLb::NotifyOnStateChangeLocked(grpc_connectivity_state* current, - grpc_closure* closure) { - grpc_connectivity_state_notify_on_state_change(&state_tracker_, current, - closure); -} - -void XdsLb::ProcessChannelArgsLocked(const grpc_channel_args& args) { - const grpc_arg* arg = grpc_channel_args_find(&args, GRPC_ARG_LB_ADDRESSES); - if (GPR_UNLIKELY(arg == nullptr || arg->type != GRPC_ARG_POINTER)) { - // Ignore this update. - gpr_log(GPR_ERROR, - "[xdslb %p] No valid LB addresses channel arg in update, ignoring.", - this); - return; - } - const grpc_lb_addresses* addresses = - static_cast(arg->value.pointer.p); +void XdsLb::ProcessAddressesAndChannelArgsLocked( + const ServerAddressList& addresses, const grpc_channel_args& args) { // Update fallback address list. - if (fallback_backend_addresses_ != nullptr) { - grpc_lb_addresses_destroy(fallback_backend_addresses_); - } fallback_backend_addresses_ = ExtractBackendAddresses(addresses); // Make sure that GRPC_ARG_LB_POLICY_NAME is set in channel args, // since we use this to trigger the client_load_reporting filter. @@ -1296,495 +1486,664 @@ void XdsLb::ProcessChannelArgsLocked(const grpc_channel_args& args) { args_ = grpc_channel_args_copy_and_add_and_remove( &args, args_to_remove, GPR_ARRAY_SIZE(args_to_remove), &new_arg, 1); // Construct args for balancer channel. - grpc_channel_args* lb_channel_args = - BuildBalancerChannelArgs(addresses, response_generator_.get(), &args); - // Create balancer channel if needed. - if (lb_channel_ == nullptr) { - char* uri_str; - gpr_asprintf(&uri_str, "fake:///%s", server_name_); - gpr_mu_lock(&lb_channel_mu_); - lb_channel_ = grpc_client_channel_factory_create_channel( - client_channel_factory(), uri_str, - GRPC_CLIENT_CHANNEL_TYPE_LOAD_BALANCING, lb_channel_args); - gpr_mu_unlock(&lb_channel_mu_); - GPR_ASSERT(lb_channel_ != nullptr); - gpr_free(uri_str); + grpc_channel_args* lb_channel_args = BuildBalancerChannelArgs(&args); + // Create an LB channel if we don't have one yet or the balancer name has + // changed from the last received one. + bool create_lb_channel = lb_chand_ == nullptr; + if (lb_chand_ != nullptr) { + UniquePtr last_balancer_name( + grpc_channel_get_target(LatestLbChannel()->channel())); + create_lb_channel = + strcmp(last_balancer_name.get(), balancer_name_.get()) != 0; + } + if (create_lb_channel) { + OrphanablePtr lb_chand = + MakeOrphanable(balancer_name_.get(), + *lb_channel_args, Ref()); + if (lb_chand_ == nullptr || !lb_chand_->HasActiveCall()) { + GPR_ASSERT(pending_lb_chand_ == nullptr); + // If we do not have a working LB channel yet, use the newly created one. + lb_chand_ = std::move(lb_chand); + } else { + // Otherwise, wait until the new LB channel to be ready to swap it in. + pending_lb_chand_ = std::move(lb_chand); + } } - // Propagate updates to the LB channel (pick_first) through the fake - // resolver. - response_generator_->SetResponse(lb_channel_args); grpc_channel_args_destroy(lb_channel_args); } -// TODO(vishalpowar): Use lb_config to configure LB policy. -void XdsLb::UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) { - ProcessChannelArgsLocked(args); - // Update the existing child policy. - // Note: We have disabled fallback mode in the code, so this child policy must - // have been created from a serverlist. - // TODO(vpowar): Handle the fallback_address changes when we add support for - // fallback in xDS. - if (child_policy_ != nullptr) CreateOrUpdateChildPolicyLocked(); - // Start watching the LB channel connectivity for connection, if not - // already doing so. - if (!watching_lb_channel_) { - lb_channel_connectivity_ = grpc_channel_check_connectivity_state( - lb_channel_, true /* try to connect */); - grpc_channel_element* client_channel_elem = grpc_channel_stack_last_element( - grpc_channel_get_channel_stack(lb_channel_)); - GPR_ASSERT(client_channel_elem->filter == &grpc_client_channel_filter); - watching_lb_channel_ = true; - // TODO(roth): We currently track this ref manually. Once the - // ClosureRef API is ready, we should pass the RefCountedPtr<> along - // with the callback. - auto self = Ref(DEBUG_LOCATION, "watch_lb_channel_connectivity"); - self.release(); - grpc_client_channel_watch_connectivity_state( - client_channel_elem, - grpc_polling_entity_create_from_pollset_set(interested_parties()), - &lb_channel_connectivity_, &lb_channel_on_connectivity_changed_, - nullptr); - } +void XdsLb::ParseLbConfig(const ParsedXdsConfig* xds_config) { + if (xds_config == nullptr || xds_config->balancer_name() == nullptr) return; + // TODO(yashykt) : does this need to be a gpr_strdup + balancer_name_ = UniquePtr(gpr_strdup(xds_config->balancer_name())); + child_policy_config_ = xds_config->child_policy(); + fallback_policy_config_ = xds_config->fallback_policy(); } -// -// code for balancer channel and call -// - -void XdsLb::StartPickingLocked() { - // Start a timer to fall back. - if (lb_fallback_timeout_ms_ > 0 && serverlist_ == nullptr && - !fallback_timer_callback_pending_) { +void XdsLb::UpdateLocked(UpdateArgs args) { + const bool is_initial_update = lb_chand_ == nullptr; + ParseLbConfig(static_cast(args.config.get())); + if (balancer_name_ == nullptr) { + gpr_log(GPR_ERROR, "[xdslb %p] LB config parsing fails.", this); + return; + } + ProcessAddressesAndChannelArgsLocked(args.addresses, *args.args); + locality_map_.UpdateLocked(locality_serverlist_, child_policy_config_.get(), + args_, this); + // Update the existing fallback policy. The fallback policy config and/or the + // fallback addresses may be new. + if (fallback_policy_ != nullptr) UpdateFallbackPolicyLocked(); + // If this is the initial update, start the fallback-at-startup checks. + if (is_initial_update) { grpc_millis deadline = ExecCtx::Get()->Now() + lb_fallback_timeout_ms_; - // TODO(roth): We currently track this ref manually. Once the - // ClosureRef API is ready, we should pass the RefCountedPtr<> along - // with the callback. - auto self = Ref(DEBUG_LOCATION, "on_fallback_timer"); - self.release(); + Ref(DEBUG_LOCATION, "on_fallback_timer").release(); // Held by closure GRPC_CLOSURE_INIT(&lb_on_fallback_, &XdsLb::OnFallbackTimerLocked, this, grpc_combiner_scheduler(combiner())); - fallback_timer_callback_pending_ = true; + fallback_at_startup_checks_pending_ = true; grpc_timer_init(&lb_fallback_timer_, deadline, &lb_on_fallback_); + // Start watching the channel's connectivity state. If the channel + // goes into state TRANSIENT_FAILURE, we go into fallback mode even if + // the fallback timeout has not elapsed. + lb_chand_->StartConnectivityWatchLocked(); } - started_picking_ = true; - StartBalancerCallLocked(); } -void XdsLb::StartBalancerCallLocked() { - GPR_ASSERT(lb_channel_ != nullptr); - if (shutting_down_) return; - // Init the LB call data. - GPR_ASSERT(lb_calld_ == nullptr); - lb_calld_ = MakeOrphanable(Ref()); - if (grpc_lb_xds_trace.enabled()) { - gpr_log(GPR_INFO, - "[xdslb %p] Query for backends (lb_channel: %p, lb_calld: %p)", - this, lb_channel_, lb_calld_.get()); - } - lb_calld_->StartQuery(); +// +// fallback-related methods +// + +void XdsLb::MaybeCancelFallbackAtStartupChecks() { + if (!fallback_at_startup_checks_pending_) return; + gpr_log(GPR_INFO, + "[xdslb %p] Cancelling fallback timer and LB channel connectivity " + "watch", + this); + grpc_timer_cancel(&lb_fallback_timer_); + lb_chand_->CancelConnectivityWatchLocked(); + fallback_at_startup_checks_pending_ = false; } void XdsLb::OnFallbackTimerLocked(void* arg, grpc_error* error) { XdsLb* xdslb_policy = static_cast(arg); - xdslb_policy->fallback_timer_callback_pending_ = false; - // If we receive a serverlist after the timer fires but before this callback - // actually runs, don't fall back. - if (xdslb_policy->serverlist_ == nullptr && !xdslb_policy->shutting_down_ && - error == GRPC_ERROR_NONE) { - if (grpc_lb_xds_trace.enabled()) { + // If some fallback-at-startup check is done after the timer fires but before + // this callback actually runs, don't fall back. + if (xdslb_policy->fallback_at_startup_checks_pending_ && + !xdslb_policy->shutting_down_ && error == GRPC_ERROR_NONE) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) { gpr_log(GPR_INFO, - "[xdslb %p] Fallback timer fired. Not using fallback backends", + "[xdslb %p] Child policy not ready after fallback timeout; " + "entering fallback mode", xdslb_policy); } + xdslb_policy->fallback_at_startup_checks_pending_ = false; + xdslb_policy->UpdateFallbackPolicyLocked(); + xdslb_policy->lb_chand_->CancelConnectivityWatchLocked(); } xdslb_policy->Unref(DEBUG_LOCATION, "on_fallback_timer"); } -void XdsLb::StartBalancerCallRetryTimerLocked() { - grpc_millis next_try = lb_call_backoff_.NextAttemptTime(); - if (grpc_lb_xds_trace.enabled()) { - gpr_log(GPR_INFO, "[xdslb %p] Connection to LB server lost...", this); - grpc_millis timeout = next_try - ExecCtx::Get()->Now(); - if (timeout > 0) { - gpr_log(GPR_INFO, "[xdslb %p] ... retry_timer_active in %" PRId64 "ms.", - this, timeout); - } else { - gpr_log(GPR_INFO, "[xdslb %p] ... retry_timer_active immediately.", this); +void XdsLb::UpdateFallbackPolicyLocked() { + if (shutting_down_) return; + // Construct update args. + UpdateArgs update_args; + update_args.addresses = fallback_backend_addresses_; + update_args.config = fallback_policy_config_ == nullptr + ? nullptr + : fallback_policy_config_->Ref(); + update_args.args = grpc_channel_args_copy(args_); + // If the child policy name changes, we need to create a new child + // policy. When this happens, we leave child_policy_ as-is and store + // the new child policy in pending_child_policy_. Once the new child + // policy transitions into state READY, we swap it into child_policy_, + // replacing the original child policy. So pending_child_policy_ is + // non-null only between when we apply an update that changes the child + // policy name and when the new child reports state READY. + // + // Updates can arrive at any point during this transition. We always + // apply updates relative to the most recently created child policy, + // even if the most recent one is still in pending_child_policy_. This + // is true both when applying the updates to an existing child policy + // and when determining whether we need to create a new policy. + // + // As a result of this, there are several cases to consider here: + // + // 1. We have no existing child policy (i.e., we have started up but + // have not yet received a serverlist from the balancer or gone + // into fallback mode; in this case, both child_policy_ and + // pending_child_policy_ are null). In this case, we create a + // new child policy and store it in child_policy_. + // + // 2. We have an existing child policy and have no pending child policy + // from a previous update (i.e., either there has not been a + // previous update that changed the policy name, or we have already + // finished swapping in the new policy; in this case, child_policy_ + // is non-null but pending_child_policy_ is null). In this case: + // a. If child_policy_->name() equals child_policy_name, then we + // update the existing child policy. + // b. If child_policy_->name() does not equal child_policy_name, + // we create a new policy. The policy will be stored in + // pending_child_policy_ and will later be swapped into + // child_policy_ by the helper when the new child transitions + // into state READY. + // + // 3. We have an existing child policy and have a pending child policy + // from a previous update (i.e., a previous update set + // pending_child_policy_ as per case 2b above and that policy has + // not yet transitioned into state READY and been swapped into + // child_policy_; in this case, both child_policy_ and + // pending_child_policy_ are non-null). In this case: + // a. If pending_child_policy_->name() equals child_policy_name, + // then we update the existing pending child policy. + // b. If pending_child_policy->name() does not equal + // child_policy_name, then we create a new policy. The new + // policy is stored in pending_child_policy_ (replacing the one + // that was there before, which will be immediately shut down) + // and will later be swapped into child_policy_ by the helper + // when the new child transitions into state READY. + const char* fallback_policy_name = fallback_policy_config_ == nullptr + ? "round_robin" + : fallback_policy_config_->name(); + const bool create_policy = + // case 1 + fallback_policy_ == nullptr || + // case 2b + (pending_fallback_policy_ == nullptr && + strcmp(fallback_policy_->name(), fallback_policy_name) != 0) || + // case 3b + (pending_fallback_policy_ != nullptr && + strcmp(pending_fallback_policy_->name(), fallback_policy_name) != 0); + LoadBalancingPolicy* policy_to_update = nullptr; + if (create_policy) { + // Cases 1, 2b, and 3b: create a new child policy. + // If child_policy_ is null, we set it (case 1), else we set + // pending_child_policy_ (cases 2b and 3b). + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) { + gpr_log(GPR_INFO, "[xdslb %p] Creating new %sfallback policy %s", this, + fallback_policy_ == nullptr ? "" : "pending ", + fallback_policy_name); } - } - // TODO(roth): We currently track this ref manually. Once the - // ClosureRef API is ready, we should pass the RefCountedPtr<> along - // with the callback. - auto self = Ref(DEBUG_LOCATION, "on_balancer_call_retry_timer"); - self.release(); - GRPC_CLOSURE_INIT(&lb_on_call_retry_, &XdsLb::OnBalancerCallRetryTimerLocked, - this, grpc_combiner_scheduler(combiner())); - retry_timer_callback_pending_ = true; - grpc_timer_init(&lb_call_retry_timer_, next_try, &lb_on_call_retry_); -} - -void XdsLb::OnBalancerCallRetryTimerLocked(void* arg, grpc_error* error) { - XdsLb* xdslb_policy = static_cast(arg); - xdslb_policy->retry_timer_callback_pending_ = false; - if (!xdslb_policy->shutting_down_ && error == GRPC_ERROR_NONE && - xdslb_policy->lb_calld_ == nullptr) { - if (grpc_lb_xds_trace.enabled()) { - gpr_log(GPR_INFO, "[xdslb %p] Restarting call to LB server", - xdslb_policy); - } - xdslb_policy->StartBalancerCallLocked(); - } - xdslb_policy->Unref(DEBUG_LOCATION, "on_balancer_call_retry_timer"); -} - -// Invoked as part of the update process. It continues watching the LB channel -// until it shuts down or becomes READY. It's invoked even if the LB channel -// stayed READY throughout the update (for example if the update is identical). -void XdsLb::OnBalancerChannelConnectivityChangedLocked(void* arg, - grpc_error* error) { - XdsLb* xdslb_policy = static_cast(arg); - if (xdslb_policy->shutting_down_) goto done; - // Re-initialize the lb_call. This should also take care of updating the - // child policy. Note that the current child policy, if any, will - // stay in effect until an update from the new lb_call is received. - switch (xdslb_policy->lb_channel_connectivity_) { - case GRPC_CHANNEL_CONNECTING: - case GRPC_CHANNEL_TRANSIENT_FAILURE: { - // Keep watching the LB channel. - grpc_channel_element* client_channel_elem = - grpc_channel_stack_last_element( - grpc_channel_get_channel_stack(xdslb_policy->lb_channel_)); - GPR_ASSERT(client_channel_elem->filter == &grpc_client_channel_filter); - grpc_client_channel_watch_connectivity_state( - client_channel_elem, - grpc_polling_entity_create_from_pollset_set( - xdslb_policy->interested_parties()), - &xdslb_policy->lb_channel_connectivity_, - &xdslb_policy->lb_channel_on_connectivity_changed_, nullptr); - break; - } - // The LB channel may be IDLE because it's shut down before the update. - // Restart the LB call to kick the LB channel into gear. - case GRPC_CHANNEL_IDLE: - case GRPC_CHANNEL_READY: - xdslb_policy->lb_calld_.reset(); - if (xdslb_policy->started_picking_) { - if (xdslb_policy->retry_timer_callback_pending_) { - grpc_timer_cancel(&xdslb_policy->lb_call_retry_timer_); - } - xdslb_policy->lb_call_backoff_.Reset(); - xdslb_policy->StartBalancerCallLocked(); - } - // Fall through. - case GRPC_CHANNEL_SHUTDOWN: - done: - xdslb_policy->watching_lb_channel_ = false; - xdslb_policy->Unref(DEBUG_LOCATION, - "watch_lb_channel_connectivity_cb_shutdown"); - } -} - -// -// PendingPick -// - -// Adds lb_token of selected subchannel (address) to the call's initial -// metadata. -grpc_error* AddLbTokenToInitialMetadata( - grpc_mdelem lb_token, grpc_linked_mdelem* lb_token_mdelem_storage, - grpc_metadata_batch* initial_metadata) { - GPR_ASSERT(lb_token_mdelem_storage != nullptr); - GPR_ASSERT(!GRPC_MDISNULL(lb_token)); - return grpc_metadata_batch_add_tail(initial_metadata, lb_token_mdelem_storage, - lb_token); -} - -// Destroy function used when embedding client stats in call context. -void DestroyClientStats(void* arg) { - static_cast(arg)->Unref(); -} - -void XdsLb::PendingPickSetMetadataAndContext(PendingPick* pp) { - /* if connected_subchannel is nullptr, no pick has been made by the - * child policy (e.g., all addresses failed to connect). There won't be any - * user_data/token available */ - if (pp->pick->connected_subchannel != nullptr) { - if (GPR_LIKELY(!GRPC_MDISNULL(pp->lb_token))) { - AddLbTokenToInitialMetadata(GRPC_MDELEM_REF(pp->lb_token), - &pp->pick->lb_token_mdelem_storage, - pp->pick->initial_metadata); - } else { - gpr_log(GPR_ERROR, - "[xdslb %p] No LB token for connected subchannel pick %p", - pp->xdslb_policy, pp->pick); - abort(); - } - // Pass on client stats via context. Passes ownership of the reference. - if (pp->client_stats != nullptr) { - pp->pick->subchannel_call_context[GRPC_GRPCLB_CLIENT_STATS].value = - pp->client_stats.release(); - pp->pick->subchannel_call_context[GRPC_GRPCLB_CLIENT_STATS].destroy = - DestroyClientStats; + auto new_policy = + CreateFallbackPolicyLocked(fallback_policy_name, update_args.args); + auto& lb_policy = fallback_policy_ == nullptr ? fallback_policy_ + : pending_fallback_policy_; + { + MutexLock lock(&fallback_policy_mu_); + lb_policy = std::move(new_policy); } + policy_to_update = lb_policy.get(); } else { - pp->client_stats.reset(); + // Cases 2a and 3a: update an existing policy. + // If we have a pending child policy, send the update to the pending + // policy (case 3a), else send it to the current policy (case 2a). + policy_to_update = pending_fallback_policy_ != nullptr + ? pending_fallback_policy_.get() + : fallback_policy_.get(); } -} - -/* The \a on_complete closure passed as part of the pick requires keeping a - * reference to its associated child policy instance. We wrap this closure in - * order to unref the child policy instance upon its invocation */ -void XdsLb::OnPendingPickComplete(void* arg, grpc_error* error) { - PendingPick* pp = static_cast(arg); - PendingPickSetMetadataAndContext(pp); - GRPC_CLOSURE_SCHED(pp->original_on_complete, GRPC_ERROR_REF(error)); - Delete(pp); -} - -XdsLb::PendingPick* XdsLb::PendingPickCreate(PickState* pick) { - PendingPick* pp = New(); - pp->xdslb_policy = this; - pp->pick = pick; - GRPC_CLOSURE_INIT(&pp->on_complete, &XdsLb::OnPendingPickComplete, pp, - grpc_schedule_on_exec_ctx); - pp->original_on_complete = pick->on_complete; - pick->on_complete = &pp->on_complete; - return pp; -} - -void XdsLb::AddPendingPick(PendingPick* pp) { - pp->next = pending_picks_; - pending_picks_ = pp; -} - -// -// code for interacting with the child policy -// - -// Performs a pick over \a child_policy_. Given that a pick can return -// immediately (ignoring its completion callback), we need to perform the -// cleanups this callback would otherwise be responsible for. -// If \a force_async is true, then we will manually schedule the -// completion callback even if the pick is available immediately. -bool XdsLb::PickFromChildPolicyLocked(bool force_async, PendingPick* pp, - grpc_error** error) { - // Set client_stats and user_data. - if (lb_calld_ != nullptr && lb_calld_->client_stats() != nullptr) { - pp->client_stats = lb_calld_->client_stats()->Ref(); + GPR_ASSERT(policy_to_update != nullptr); + // Update the policy. + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) { + gpr_log( + GPR_INFO, "[xdslb %p] Updating %sfallback policy %p", this, + policy_to_update == pending_fallback_policy_.get() ? "pending " : "", + policy_to_update); } - GPR_ASSERT(pp->pick->user_data == nullptr); - pp->pick->user_data = (void**)&pp->lb_token; - // Pick via the child policy. - bool pick_done = child_policy_->PickLocked(pp->pick, error); - if (pick_done) { - PendingPickSetMetadataAndContext(pp); - if (force_async) { - GRPC_CLOSURE_SCHED(pp->original_on_complete, *error); - *error = GRPC_ERROR_NONE; - pick_done = false; - } - Delete(pp); - } - // else, the pending pick will be registered and taken care of by the - // pending pick list inside the child policy. Eventually, - // OnPendingPickComplete() will be called, which will (among other - // things) add the LB token to the call's initial metadata. - return pick_done; + policy_to_update->UpdateLocked(std::move(update_args)); } -void XdsLb::CreateChildPolicyLocked(const Args& args) { - GPR_ASSERT(child_policy_ == nullptr); - child_policy_ = LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( - "round_robin", args); - if (GPR_UNLIKELY(child_policy_ == nullptr)) { - gpr_log(GPR_ERROR, "[xdslb %p] Failure creating a child policy", this); - return; +OrphanablePtr XdsLb::CreateFallbackPolicyLocked( + const char* name, const grpc_channel_args* args) { + FallbackHelper* helper = New(Ref()); + LoadBalancingPolicy::Args lb_policy_args; + lb_policy_args.combiner = combiner(); + lb_policy_args.args = args; + lb_policy_args.channel_control_helper = + UniquePtr(helper); + OrphanablePtr lb_policy = + LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( + name, std::move(lb_policy_args)); + if (GPR_UNLIKELY(lb_policy == nullptr)) { + gpr_log(GPR_ERROR, "[xdslb %p] Failure creating fallback policy %s", this, + name); + return nullptr; + } + helper->set_child(lb_policy.get()); + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) { + gpr_log(GPR_INFO, "[xdslb %p] Created new fallback policy %s (%p)", this, + name, lb_policy.get()); } - // TODO(roth): We currently track this ref manually. Once the new - // ClosureRef API is done, pass the RefCountedPtr<> along with the closure. - auto self = Ref(DEBUG_LOCATION, "on_child_reresolution_requested"); - self.release(); - child_policy_->SetReresolutionClosureLocked(&on_child_request_reresolution_); - grpc_error* child_state_error = nullptr; - child_connectivity_state_ = - child_policy_->CheckConnectivityLocked(&child_state_error); - // Connectivity state is a function of the child policy updated/created. - UpdateConnectivityStateFromChildPolicyLocked(child_state_error); // Add the xDS's interested_parties pollset_set to that of the newly created - // child policy. This will make the child policy progress upon activity on - // xDS LB, which in turn is tied to the application's call. - grpc_pollset_set_add_pollset_set(child_policy_->interested_parties(), + // child policy. This will make the child policy progress upon activity on xDS + // LB, which in turn is tied to the application's call. + grpc_pollset_set_add_pollset_set(lb_policy->interested_parties(), interested_parties()); - // Subscribe to changes to the connectivity of the new child policy. - // TODO(roth): We currently track this ref manually. Once the new - // ClosureRef API is done, pass the RefCountedPtr<> along with the closure. - self = Ref(DEBUG_LOCATION, "on_child_connectivity_changed"); - self.release(); - child_policy_->NotifyOnStateChangeLocked(&child_connectivity_state_, - &on_child_connectivity_changed_); - child_policy_->ExitIdleLocked(); - // Send pending picks to child policy. - PendingPick* pp; - while ((pp = pending_picks_)) { - pending_picks_ = pp->next; - if (grpc_lb_xds_trace.enabled()) { - gpr_log( - GPR_INFO, - "[xdslb %p] Pending pick about to (async) PICK from child policy %p", - this, child_policy_.get()); + return lb_policy; +} + +void XdsLb::MaybeExitFallbackMode() { + if (fallback_policy_ == nullptr) return; + gpr_log(GPR_INFO, "[xdslb %p] Exiting fallback mode", this); + fallback_policy_.reset(); + pending_fallback_policy_.reset(); +} + +// +// XdsLb::LocalityMap +// + +void XdsLb::LocalityMap::PruneLocalities(const LocalityList& locality_list) { + for (auto iter = map_.begin(); iter != map_.end();) { + bool found = false; + for (size_t i = 0; i < locality_list.size(); i++) { + if (!gpr_stricmp(locality_list[i]->locality_name, iter->first.get())) { + found = true; + } } - grpc_error* error = GRPC_ERROR_NONE; - PickFromChildPolicyLocked(true /* force_async */, pp, &error); + if (!found) { // Remove entries not present in the locality list + MutexLock lock(&child_refs_mu_); + iter = map_.erase(iter); + } else + iter++; } } -grpc_channel_args* XdsLb::CreateChildPolicyArgsLocked() { - grpc_lb_addresses* addresses; - bool is_backend_from_grpclb_load_balancer = false; - // This should never be invoked if we do not have serverlist_, as fallback - // mode is disabled for xDS plugin. - GPR_ASSERT(serverlist_ != nullptr); - GPR_ASSERT(serverlist_->num_servers > 0); - addresses = ProcessServerlist(serverlist_); - is_backend_from_grpclb_load_balancer = true; - GPR_ASSERT(addresses != nullptr); - // 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}; +void XdsLb::LocalityMap::UpdateLocked( + const LocalityList& locality_serverlist, + ParsedLoadBalancingConfig* child_policy_config, + const grpc_channel_args* args, XdsLb* parent) { + if (parent->shutting_down_) return; + for (size_t i = 0; i < locality_serverlist.size(); i++) { + UniquePtr locality_name( + gpr_strdup(locality_serverlist[i]->locality_name)); + auto iter = map_.find(locality_name); + if (iter == map_.end()) { + OrphanablePtr new_entry = MakeOrphanable( + parent->Ref(), locality_serverlist[i]->locality_weight); + MutexLock lock(&child_refs_mu_); + iter = map_.emplace(std::move(locality_name), std::move(new_entry)).first; + } + // Don't create new child policies if not directed to + xds_grpclb_serverlist* serverlist = + parent->locality_serverlist_[i]->serverlist; + iter->second->UpdateLocked(serverlist, child_policy_config, args); + } + PruneLocalities(locality_serverlist); +} + +void XdsLb::LocalityMap::ShutdownLocked() { + MutexLock lock(&child_refs_mu_); + map_.clear(); +} + +void XdsLb::LocalityMap::ResetBackoffLocked() { + for (auto& p : map_) { + p.second->ResetBackoffLocked(); + } +} + +void XdsLb::LocalityMap::FillChildRefsForChannelz( + channelz::ChildRefsList* child_subchannels, + channelz::ChildRefsList* child_channels) { + MutexLock lock(&child_refs_mu_); + for (auto& p : map_) { + p.second->FillChildRefsForChannelz(child_subchannels, child_channels); + } +} + +// +// XdsLb::LocalityMap::LocalityEntry +// + +grpc_channel_args* +XdsLb::LocalityMap::LocalityEntry::CreateChildPolicyArgsLocked( + const grpc_channel_args* args_in) { 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(GRPC_ARG_ADDRESS_IS_BACKEND_FROM_XDS_LOAD_BALANCER), - is_backend_from_grpclb_load_balancer), + 1), + // Inhibit client-side health checking, since the balancer does + // this for us. + grpc_channel_arg_integer_create( + const_cast(GRPC_ARG_INHIBIT_HEALTH_CHECKING), 1), }; - grpc_channel_args* args = grpc_channel_args_copy_and_add_and_remove( - 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; + return grpc_channel_args_copy_and_add(args_in, args_to_add, + GPR_ARRAY_SIZE(args_to_add)); } -void XdsLb::CreateOrUpdateChildPolicyLocked() { - if (shutting_down_) return; - grpc_channel_args* args = CreateChildPolicyArgsLocked(); - GPR_ASSERT(args != nullptr); - if (child_policy_ != nullptr) { - if (grpc_lb_xds_trace.enabled()) { - gpr_log(GPR_INFO, "[xdslb %p] Updating the child policy %p", this, - child_policy_.get()); +OrphanablePtr +XdsLb::LocalityMap::LocalityEntry::CreateChildPolicyLocked( + const char* name, const grpc_channel_args* args) { + Helper* helper = New(this->Ref()); + LoadBalancingPolicy::Args lb_policy_args; + lb_policy_args.combiner = parent_->combiner(); + lb_policy_args.args = args; + lb_policy_args.channel_control_helper = + UniquePtr(helper); + OrphanablePtr lb_policy = + LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( + name, std::move(lb_policy_args)); + if (GPR_UNLIKELY(lb_policy == nullptr)) { + gpr_log(GPR_ERROR, "[xdslb %p] Failure creating child policy %s", this, + name); + return nullptr; + } + helper->set_child(lb_policy.get()); + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) { + gpr_log(GPR_INFO, "[xdslb %p] Created new child policy %s (%p)", this, name, + lb_policy.get()); + } + // Add the xDS's interested_parties pollset_set to that of the newly created + // child policy. This will make the child policy progress upon activity on xDS + // LB, which in turn is tied to the application's call. + grpc_pollset_set_add_pollset_set(lb_policy->interested_parties(), + parent_->interested_parties()); + return lb_policy; +} + +void XdsLb::LocalityMap::LocalityEntry::UpdateLocked( + xds_grpclb_serverlist* serverlist, + ParsedLoadBalancingConfig* child_policy_config, + const grpc_channel_args* args_in) { + if (parent_->shutting_down_) return; + // Construct update args. + UpdateArgs update_args; + update_args.addresses = ProcessServerlist(serverlist); + update_args.config = + child_policy_config == nullptr ? nullptr : child_policy_config->Ref(); + update_args.args = CreateChildPolicyArgsLocked(args_in); + // If the child policy name changes, we need to create a new child + // policy. When this happens, we leave child_policy_ as-is and store + // the new child policy in pending_child_policy_. Once the new child + // policy transitions into state READY, we swap it into child_policy_, + // replacing the original child policy. So pending_child_policy_ is + // non-null only between when we apply an update that changes the child + // policy name and when the new child reports state READY. + // + // Updates can arrive at any point during this transition. We always + // apply updates relative to the most recently created child policy, + // even if the most recent one is still in pending_child_policy_. This + // is true both when applying the updates to an existing child policy + // and when determining whether we need to create a new policy. + // + // As a result of this, there are several cases to consider here: + // + // 1. We have no existing child policy (i.e., we have started up but + // have not yet received a serverlist from the balancer or gone + // into fallback mode; in this case, both child_policy_ and + // pending_child_policy_ are null). In this case, we create a + // new child policy and store it in child_policy_. + // + // 2. We have an existing child policy and have no pending child policy + // from a previous update (i.e., either there has not been a + // previous update that changed the policy name, or we have already + // finished swapping in the new policy; in this case, child_policy_ + // is non-null but pending_child_policy_ is null). In this case: + // a. If child_policy_->name() equals child_policy_name, then we + // update the existing child policy. + // b. If child_policy_->name() does not equal child_policy_name, + // we create a new policy. The policy will be stored in + // pending_child_policy_ and will later be swapped into + // child_policy_ by the helper when the new child transitions + // into state READY. + // + // 3. We have an existing child policy and have a pending child policy + // from a previous update (i.e., a previous update set + // pending_child_policy_ as per case 2b above and that policy has + // not yet transitioned into state READY and been swapped into + // child_policy_; in this case, both child_policy_ and + // pending_child_policy_ are non-null). In this case: + // a. If pending_child_policy_->name() equals child_policy_name, + // then we update the existing pending child policy. + // b. If pending_child_policy->name() does not equal + // child_policy_name, then we create a new policy. The new + // policy is stored in pending_child_policy_ (replacing the one + // that was there before, which will be immediately shut down) + // and will later be swapped into child_policy_ by the helper + // when the new child transitions into state READY. + // TODO(juanlishen): If the child policy is not configured via service config, + // use whatever algorithm is specified by the balancer. + const char* child_policy_name = child_policy_config == nullptr + ? "round_robin" + : child_policy_config->name(); + const bool create_policy = + // case 1 + child_policy_ == nullptr || + // case 2b + (pending_child_policy_ == nullptr && + strcmp(child_policy_->name(), child_policy_name) != 0) || + // case 3b + (pending_child_policy_ != nullptr && + strcmp(pending_child_policy_->name(), child_policy_name) != 0); + LoadBalancingPolicy* policy_to_update = nullptr; + if (create_policy) { + // Cases 1, 2b, and 3b: create a new child policy. + // If child_policy_ is null, we set it (case 1), else we set + // pending_child_policy_ (cases 2b and 3b). + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) { + gpr_log(GPR_INFO, "[xdslb %p] Creating new %schild policy %s", this, + child_policy_ == nullptr ? "" : "pending ", child_policy_name); } - // TODO(vishalpowar): Pass the correct LB config. - child_policy_->UpdateLocked(*args, nullptr); + auto new_policy = + CreateChildPolicyLocked(child_policy_name, update_args.args); + auto& lb_policy = + child_policy_ == nullptr ? child_policy_ : pending_child_policy_; + { + MutexLock lock(&child_policy_mu_); + lb_policy = std::move(new_policy); + } + policy_to_update = lb_policy.get(); } else { - LoadBalancingPolicy::Args lb_policy_args; - lb_policy_args.combiner = combiner(); - lb_policy_args.client_channel_factory = client_channel_factory(); - lb_policy_args.args = args; - CreateChildPolicyLocked(lb_policy_args); - if (grpc_lb_xds_trace.enabled()) { - gpr_log(GPR_INFO, "[xdslb %p] Created a new child policy %p", this, - child_policy_.get()); + // Cases 2a and 3a: update an existing policy. + // If we have a pending child policy, send the update to the pending + // policy (case 3a), else send it to the current policy (case 2a). + policy_to_update = pending_child_policy_ != nullptr + ? pending_child_policy_.get() + : child_policy_.get(); + } + GPR_ASSERT(policy_to_update != nullptr); + // Update the policy. + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) { + gpr_log(GPR_INFO, "[xdslb %p] Updating %schild policy %p", this, + policy_to_update == pending_child_policy_.get() ? "pending " : "", + policy_to_update); + } + policy_to_update->UpdateLocked(std::move(update_args)); +} + +void XdsLb::LocalityMap::LocalityEntry::ShutdownLocked() { + // Remove the child policy's interested_parties pollset_set from the + // xDS policy. + grpc_pollset_set_del_pollset_set(child_policy_->interested_parties(), + parent_->interested_parties()); + if (pending_child_policy_ != nullptr) { + grpc_pollset_set_del_pollset_set( + pending_child_policy_->interested_parties(), + parent_->interested_parties()); + } + { + MutexLock lock(&child_policy_mu_); + child_policy_.reset(); + pending_child_policy_.reset(); + } +} + +void XdsLb::LocalityMap::LocalityEntry::ResetBackoffLocked() { + child_policy_->ResetBackoffLocked(); + if (pending_child_policy_ != nullptr) { + pending_child_policy_->ResetBackoffLocked(); + } +} + +void XdsLb::LocalityMap::LocalityEntry::FillChildRefsForChannelz( + channelz::ChildRefsList* child_subchannels, + channelz::ChildRefsList* child_channels) { + MutexLock lock(&child_policy_mu_); + child_policy_->FillChildRefsForChannelz(child_subchannels, child_channels); + if (pending_child_policy_ != nullptr) { + pending_child_policy_->FillChildRefsForChannelz(child_subchannels, + child_channels); + } +} + +void XdsLb::LocalityMap::LocalityEntry::Orphan() { + ShutdownLocked(); + Unref(); +} + +// +// XdsLb::LocalityEntry::Helper +// + +bool XdsLb::LocalityMap::LocalityEntry::Helper::CalledByPendingChild() const { + GPR_ASSERT(child_ != nullptr); + return child_ == entry_->pending_child_policy_.get(); +} + +bool XdsLb::LocalityMap::LocalityEntry::Helper::CalledByCurrentChild() const { + GPR_ASSERT(child_ != nullptr); + return child_ == entry_->child_policy_.get(); +} + +Subchannel* XdsLb::LocalityMap::LocalityEntry::Helper::CreateSubchannel( + const grpc_channel_args& args) { + if (entry_->parent_->shutting_down_ || + (!CalledByPendingChild() && !CalledByCurrentChild())) { + return nullptr; + } + return entry_->parent_->channel_control_helper()->CreateSubchannel(args); +} + +grpc_channel* XdsLb::LocalityMap::LocalityEntry::Helper::CreateChannel( + const char* target, const grpc_channel_args& args) { + if (entry_->parent_->shutting_down_ || + (!CalledByPendingChild() && !CalledByCurrentChild())) { + return nullptr; + } + return entry_->parent_->channel_control_helper()->CreateChannel(target, args); +} + +void XdsLb::LocalityMap::LocalityEntry::Helper::UpdateState( + grpc_connectivity_state state, UniquePtr picker) { + if (entry_->parent_->shutting_down_) return; + // If this request is from the pending child policy, ignore it until + // it reports READY, at which point we swap it into place. + if (CalledByPendingChild()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) { + gpr_log(GPR_INFO, + "[xdslb %p helper %p] pending child policy %p reports state=%s", + entry_->parent_.get(), this, entry_->pending_child_policy_.get(), + grpc_connectivity_state_name(state)); + } + if (state != GRPC_CHANNEL_READY) return; + grpc_pollset_set_del_pollset_set( + entry_->child_policy_->interested_parties(), + entry_->parent_->interested_parties()); + MutexLock lock(&entry_->child_policy_mu_); + entry_->child_policy_ = std::move(entry_->pending_child_policy_); + } else if (!CalledByCurrentChild()) { + // This request is from an outdated child, so ignore it. + return; + } + // At this point, child_ must be the current child policy. + if (state == GRPC_CHANNEL_READY) entry_->parent_->MaybeExitFallbackMode(); + // If we are in fallback mode, ignore update request from the child policy. + if (entry_->parent_->fallback_policy_ != nullptr) return; + GPR_ASSERT(entry_->parent_->lb_chand_ != nullptr); + RefCountedPtr client_stats = + entry_->parent_->lb_chand_->lb_calld() == nullptr + ? nullptr + : entry_->parent_->lb_chand_->lb_calld()->client_stats(); + // Cache the picker and its state in the entry + entry_->picker_ref_ = MakeRefCounted(std::move(picker)); + entry_->connectivity_state_ = state; + // Construct a new xds picker which maintains a map of all locality pickers + // that are ready. Each locality is represented by a portion of the range + // proportional to its weight, such that the total range is the sum of the + // weights of all localities + uint32_t end = 0; + size_t num_connecting = 0; + size_t num_idle = 0; + size_t num_transient_failures = 0; + auto& locality_map = this->entry_->parent_->locality_map_.map_; + Picker::PickerList pickers; + for (auto& p : locality_map) { + const LocalityEntry* entry = p.second.get(); + grpc_connectivity_state connectivity_state = entry->connectivity_state_; + switch (connectivity_state) { + case GRPC_CHANNEL_READY: { + end += entry->locality_weight_; + pickers.push_back(MakePair(end, entry->picker_ref_)); + break; + } + case GRPC_CHANNEL_CONNECTING: { + num_connecting++; + break; + } + case GRPC_CHANNEL_IDLE: { + num_idle++; + break; + } + case GRPC_CHANNEL_TRANSIENT_FAILURE: { + num_transient_failures++; + break; + } + default: { + gpr_log(GPR_ERROR, "Invalid locality connectivity state - %d", + connectivity_state); + } } } - grpc_channel_args_destroy(args); + // Pass on the constructed xds picker if it has any ready pickers in their map + // otherwise pass a QueuePicker if any of the locality pickers are in a + // connecting or idle state, finally return a transient failure picker if all + // locality pickers are in transient failure + if (pickers.size() > 0) { + entry_->parent_->channel_control_helper()->UpdateState( + GRPC_CHANNEL_READY, + UniquePtr( + New(std::move(client_stats), std::move(pickers)))); + } else if (num_connecting > 0) { + entry_->parent_->channel_control_helper()->UpdateState( + GRPC_CHANNEL_CONNECTING, + UniquePtr(New(this->entry_->parent_))); + } else if (num_idle > 0) { + entry_->parent_->channel_control_helper()->UpdateState( + GRPC_CHANNEL_IDLE, + UniquePtr(New(this->entry_->parent_))); + } else { + GPR_ASSERT(num_transient_failures == locality_map.size()); + grpc_error* error = + grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "connections to all localities failing"), + GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE); + entry_->parent_->channel_control_helper()->UpdateState( + state, UniquePtr(New(error))); + } } -void XdsLb::OnChildPolicyRequestReresolutionLocked(void* arg, - grpc_error* error) { - XdsLb* xdslb_policy = static_cast(arg); - if (xdslb_policy->shutting_down_ || error != GRPC_ERROR_NONE) { - xdslb_policy->Unref(DEBUG_LOCATION, "on_child_reresolution_requested"); +void XdsLb::LocalityMap::LocalityEntry::Helper::RequestReresolution() { + if (entry_->parent_->shutting_down_) return; + // If there is a pending child policy, ignore re-resolution requests + // from the current child policy (or any outdated child). + if (entry_->pending_child_policy_ != nullptr && !CalledByPendingChild()) { return; } - if (grpc_lb_xds_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) { gpr_log(GPR_INFO, - "[xdslb %p] Re-resolution requested from child policy " + "[xdslb %p] Re-resolution requested from the internal RR policy " "(%p).", - xdslb_policy, xdslb_policy->child_policy_.get()); + entry_->parent_.get(), entry_->child_policy_.get()); } - // If we are talking to a balancer, we expect to get updated addresses form - // the balancer, so we can ignore the re-resolution request from the child - // policy. - // Otherwise, handle the re-resolution request using the xds policy's - // original re-resolution closure. - if (xdslb_policy->lb_calld_ == nullptr || - !xdslb_policy->lb_calld_->seen_initial_response()) { - xdslb_policy->TryReresolutionLocked(&grpc_lb_xds_trace, GRPC_ERROR_NONE); + GPR_ASSERT(entry_->parent_->lb_chand_ != nullptr); + // If we are talking to a balancer, we expect to get updated addresses + // from the balancer, so we can ignore the re-resolution request from + // the child policy. Otherwise, pass the re-resolution request up to the + // channel. + if (entry_->parent_->lb_chand_->lb_calld() == nullptr || + !entry_->parent_->lb_chand_->lb_calld()->seen_initial_response()) { + entry_->parent_->channel_control_helper()->RequestReresolution(); } - // Give back the wrapper closure to the child policy. - xdslb_policy->child_policy_->SetReresolutionClosureLocked( - &xdslb_policy->on_child_request_reresolution_); -} - -void XdsLb::UpdateConnectivityStateFromChildPolicyLocked( - grpc_error* child_state_error) { - const grpc_connectivity_state curr_glb_state = - grpc_connectivity_state_check(&state_tracker_); - /* The new connectivity status is a function of the previous one and the new - * input coming from the status of the child policy. - * - * current state (xds's) - * | - * v || I | C | R | TF | SD | <- new state (child policy's) - * ===++====+=====+=====+======+======+ - * I || I | C | R | [I] | [I] | - * ---++----+-----+-----+------+------+ - * C || I | C | R | [C] | [C] | - * ---++----+-----+-----+------+------+ - * R || I | C | R | [R] | [R] | - * ---++----+-----+-----+------+------+ - * TF || I | C | R | [TF] | [TF] | - * ---++----+-----+-----+------+------+ - * SD || NA | NA | NA | NA | NA | (*) - * ---++----+-----+-----+------+------+ - * - * A [STATE] indicates that the old child policy is kept. In those cases, - * STATE is the current state of xds, which is left untouched. - * - * In summary, if the new state is TRANSIENT_FAILURE or SHUTDOWN, stick to - * the previous child policy instance. - * - * Note that the status is never updated to SHUTDOWN as a result of calling - * this function. Only glb_shutdown() has the power to set that state. - * - * (*) This function mustn't be called during shutting down. */ - GPR_ASSERT(curr_glb_state != GRPC_CHANNEL_SHUTDOWN); - switch (child_connectivity_state_) { - case GRPC_CHANNEL_TRANSIENT_FAILURE: - case GRPC_CHANNEL_SHUTDOWN: - GPR_ASSERT(child_state_error != GRPC_ERROR_NONE); - break; - case GRPC_CHANNEL_IDLE: - case GRPC_CHANNEL_CONNECTING: - case GRPC_CHANNEL_READY: - GPR_ASSERT(child_state_error == GRPC_ERROR_NONE); - } - if (grpc_lb_xds_trace.enabled()) { - gpr_log(GPR_INFO, - "[xdslb %p] Setting xds's state to %s from child policy %p state.", - this, grpc_connectivity_state_name(child_connectivity_state_), - child_policy_.get()); - } - grpc_connectivity_state_set(&state_tracker_, child_connectivity_state_, - child_state_error, - "update_lb_connectivity_status_locked"); -} - -void XdsLb::OnChildPolicyConnectivityChangedLocked(void* arg, - grpc_error* error) { - XdsLb* xdslb_policy = static_cast(arg); - if (xdslb_policy->shutting_down_) { - xdslb_policy->Unref(DEBUG_LOCATION, "on_child_connectivity_changed"); - return; - } - xdslb_policy->UpdateConnectivityStateFromChildPolicyLocked( - GRPC_ERROR_REF(error)); - // Resubscribe. Reuse the "on_child_connectivity_changed" ref. - xdslb_policy->child_policy_->NotifyOnStateChangeLocked( - &xdslb_policy->child_connectivity_state_, - &xdslb_policy->on_child_connectivity_changed_); } // @@ -1794,24 +2153,82 @@ void XdsLb::OnChildPolicyConnectivityChangedLocked(void* arg, class XdsFactory : public LoadBalancingPolicyFactory { public: OrphanablePtr CreateLoadBalancingPolicy( - const LoadBalancingPolicy::Args& args) const override { - /* Count the number of gRPC-LB addresses. There must be at least one. */ - const grpc_arg* arg = - grpc_channel_args_find(args.args, GRPC_ARG_LB_ADDRESSES); - if (arg == nullptr || arg->type != GRPC_ARG_POINTER) { - return nullptr; - } - grpc_lb_addresses* addresses = - static_cast(arg->value.pointer.p); - size_t num_grpclb_addrs = 0; - for (size_t i = 0; i < addresses->num_addresses; ++i) { - if (addresses->addresses[i].is_balancer) ++num_grpclb_addrs; - } - if (num_grpclb_addrs == 0) return nullptr; - return OrphanablePtr(New(addresses, args)); + LoadBalancingPolicy::Args args) const override { + return OrphanablePtr(New(std::move(args))); } - const char* name() const override { return "xds"; } + const char* name() const override { return kXds; } + + RefCountedPtr ParseLoadBalancingConfig( + const grpc_json* json, grpc_error** error) const override { + GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); + if (json == nullptr) { + // xds was mentioned as a policy in the deprecated loadBalancingPolicy + // field or in the client API. + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:loadBalancingPolicy error:Xds Parser has required field - " + "balancerName. Please use loadBalancingConfig field of service " + "config instead."); + return nullptr; + } + GPR_DEBUG_ASSERT(strcmp(json->key, name()) == 0); + + InlinedVector error_list; + const char* balancer_name = nullptr; + RefCountedPtr child_policy; + RefCountedPtr fallback_policy; + for (const grpc_json* field = json->child; field != nullptr; + field = field->next) { + if (field->key == nullptr) continue; + if (strcmp(field->key, "balancerName") == 0) { + if (balancer_name != nullptr) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:balancerName error:Duplicate entry")); + } + if (field->type != GRPC_JSON_STRING) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:balancerName error:type should be string")); + continue; + } + balancer_name = field->value; + } else if (strcmp(field->key, "childPolicy") == 0) { + if (child_policy != nullptr) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:childPolicy error:Duplicate entry")); + } + grpc_error* parse_error = GRPC_ERROR_NONE; + child_policy = LoadBalancingPolicyRegistry::ParseLoadBalancingConfig( + field, &parse_error); + if (child_policy == nullptr) { + GPR_DEBUG_ASSERT(parse_error != GRPC_ERROR_NONE); + error_list.push_back(parse_error); + } + } else if (strcmp(field->key, "fallbackPolicy") == 0) { + if (fallback_policy != nullptr) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:fallbackPolicy error:Duplicate entry")); + } + grpc_error* parse_error = GRPC_ERROR_NONE; + fallback_policy = LoadBalancingPolicyRegistry::ParseLoadBalancingConfig( + field, &parse_error); + if (fallback_policy == nullptr) { + GPR_DEBUG_ASSERT(parse_error != GRPC_ERROR_NONE); + error_list.push_back(parse_error); + } + } + } + if (balancer_name == nullptr) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:balancerName error:not found")); + } + if (error_list.empty()) { + return RefCountedPtr(New( + balancer_name, std::move(child_policy), std::move(fallback_policy))); + } else { + *error = GRPC_ERROR_CREATE_FROM_VECTOR("Xds Parser", &error_list); + return nullptr; + } + } }; } // namespace diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h b/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h index 32c4acc8a3e..f713b7f563d 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h @@ -21,7 +21,7 @@ #include -#include "src/core/ext/filters/client_channel/lb_policy_factory.h" +#include /// Makes any necessary modifications to \a args for use in the xds /// balancer channel. diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_secure.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_secure.cc index 5ab72efce46..7f8c232d6d0 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_secure.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_secure.cc @@ -25,6 +25,7 @@ #include #include "src/core/ext/filters/client_channel/client_channel.h" +#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/iomgr/sockaddr_utils.h" @@ -32,76 +33,29 @@ #include "src/core/lib/security/transport/target_authority_table.h" #include "src/core/lib/slice/slice_internal.h" -namespace grpc_core { -namespace { - -int BalancerNameCmp(const grpc_core::UniquePtr& a, - const grpc_core::UniquePtr& b) { - return strcmp(a.get(), b.get()); -} - -RefCountedPtr CreateTargetAuthorityTable( - grpc_lb_addresses* addresses) { - TargetAuthorityTable::Entry* target_authority_entries = - static_cast(gpr_zalloc( - sizeof(*target_authority_entries) * addresses->num_addresses)); - for (size_t i = 0; i < addresses->num_addresses; ++i) { - char* addr_str; - GPR_ASSERT(grpc_sockaddr_to_string( - &addr_str, &addresses->addresses[i].address, true) > 0); - target_authority_entries[i].key = grpc_slice_from_copied_string(addr_str); - target_authority_entries[i].value.reset( - gpr_strdup(addresses->addresses[i].balancer_name)); - gpr_free(addr_str); - } - RefCountedPtr target_authority_table = - TargetAuthorityTable::Create(addresses->num_addresses, - target_authority_entries, BalancerNameCmp); - gpr_free(target_authority_entries); - return target_authority_table; -} - -} // namespace -} // namespace grpc_core - grpc_channel_args* grpc_lb_policy_xds_modify_lb_channel_args( grpc_channel_args* args) { const char* args_to_remove[1]; size_t num_args_to_remove = 0; grpc_arg args_to_add[2]; size_t num_args_to_add = 0; - // Add arg for targets info table. - const grpc_arg* arg = grpc_channel_args_find(args, GRPC_ARG_LB_ADDRESSES); - GPR_ASSERT(arg != nullptr); - GPR_ASSERT(arg->type == GRPC_ARG_POINTER); - grpc_lb_addresses* addresses = - static_cast(arg->value.pointer.p); - grpc_core::RefCountedPtr - target_authority_table = grpc_core::CreateTargetAuthorityTable(addresses); - args_to_add[num_args_to_add++] = - grpc_core::CreateTargetAuthorityTableChannelArg( - target_authority_table.get()); // Substitute the channel credentials with a version without call // credentials: the load balancer is not necessarily trusted to handle // bearer token credentials. grpc_channel_credentials* channel_credentials = grpc_channel_credentials_find_in_args(args); - grpc_channel_credentials* creds_sans_call_creds = nullptr; + grpc_core::RefCountedPtr creds_sans_call_creds; if (channel_credentials != nullptr) { creds_sans_call_creds = - grpc_channel_credentials_duplicate_without_call_credentials( - channel_credentials); + channel_credentials->duplicate_without_call_credentials(); GPR_ASSERT(creds_sans_call_creds != nullptr); args_to_remove[num_args_to_remove++] = GRPC_ARG_CHANNEL_CREDENTIALS; args_to_add[num_args_to_add++] = - grpc_channel_credentials_to_arg(creds_sans_call_creds); + grpc_channel_credentials_to_arg(creds_sans_call_creds.get()); } grpc_channel_args* result = grpc_channel_args_copy_and_add_and_remove( args, args_to_remove, num_args_to_remove, args_to_add, num_args_to_add); // Clean up. grpc_channel_args_destroy(args); - if (creds_sans_call_creds != nullptr) { - grpc_channel_credentials_unref(creds_sans_call_creds); - } return result; } diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.cc index 79b7bdbe338..90094974a14 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.cc @@ -161,10 +161,10 @@ void xds_grpclb_request_destroy(xds_grpclb_request* request) { typedef grpc_lb_v1_LoadBalanceResponse xds_grpclb_response; xds_grpclb_initial_response* xds_grpclb_initial_response_parse( - grpc_slice encoded_xds_grpclb_response) { - pb_istream_t stream = - pb_istream_from_buffer(GRPC_SLICE_START_PTR(encoded_xds_grpclb_response), - GRPC_SLICE_LENGTH(encoded_xds_grpclb_response)); + const grpc_slice& encoded_xds_grpclb_response) { + pb_istream_t stream = pb_istream_from_buffer( + const_cast(GRPC_SLICE_START_PTR(encoded_xds_grpclb_response)), + GRPC_SLICE_LENGTH(encoded_xds_grpclb_response)); xds_grpclb_response res; memset(&res, 0, sizeof(xds_grpclb_response)); if (GPR_UNLIKELY( @@ -185,10 +185,10 @@ xds_grpclb_initial_response* xds_grpclb_initial_response_parse( } xds_grpclb_serverlist* xds_grpclb_response_parse_serverlist( - grpc_slice encoded_xds_grpclb_response) { - pb_istream_t stream = - pb_istream_from_buffer(GRPC_SLICE_START_PTR(encoded_xds_grpclb_response), - GRPC_SLICE_LENGTH(encoded_xds_grpclb_response)); + const grpc_slice& encoded_xds_grpclb_response) { + pb_istream_t stream = pb_istream_from_buffer( + const_cast(GRPC_SLICE_START_PTR(encoded_xds_grpclb_response)), + GRPC_SLICE_LENGTH(encoded_xds_grpclb_response)); pb_istream_t stream_at_start = stream; xds_grpclb_serverlist* sl = static_cast( gpr_zalloc(sizeof(xds_grpclb_serverlist))); diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h b/src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h index 9d08defa7ef..e52d20f8658 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h @@ -25,7 +25,7 @@ #include "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h" #include "src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.h" -#include "src/core/ext/filters/client_channel/lb_policy_factory.h" +#include "src/core/lib/iomgr/exec_ctx.h" #define XDS_SERVICE_NAME_MAX_LENGTH 128 @@ -55,11 +55,11 @@ void xds_grpclb_request_destroy(xds_grpclb_request* request); /** Parse (ie, decode) the bytes in \a encoded_xds_grpclb_response as a \a * xds_grpclb_initial_response */ xds_grpclb_initial_response* xds_grpclb_initial_response_parse( - grpc_slice encoded_xds_grpclb_response); + const grpc_slice& encoded_xds_grpclb_response); /** Parse the list of servers from an encoded \a xds_grpclb_response */ xds_grpclb_serverlist* xds_grpclb_response_parse_serverlist( - grpc_slice encoded_xds_grpclb_response); + const grpc_slice& encoded_xds_grpclb_response); /** Return a copy of \a sl. The caller is responsible for calling \a * xds_grpclb_destroy_serverlist on the returned copy. */ diff --git a/src/core/ext/filters/client_channel/lb_policy_factory.cc b/src/core/ext/filters/client_channel/lb_policy_factory.cc deleted file mode 100644 index 5c6363d2952..00000000000 --- a/src/core/ext/filters/client_channel/lb_policy_factory.cc +++ /dev/null @@ -1,163 +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 - -#include - -#include -#include - -#include "src/core/lib/channel/channel_args.h" - -#include "src/core/ext/filters/client_channel/lb_policy_factory.h" -#include "src/core/ext/filters/client_channel/parse_address.h" - -grpc_lb_addresses* grpc_lb_addresses_create( - size_t num_addresses, const grpc_lb_user_data_vtable* user_data_vtable) { - grpc_lb_addresses* addresses = - static_cast(gpr_zalloc(sizeof(grpc_lb_addresses))); - addresses->num_addresses = num_addresses; - addresses->user_data_vtable = user_data_vtable; - const size_t addresses_size = sizeof(grpc_lb_address) * num_addresses; - addresses->addresses = - static_cast(gpr_zalloc(addresses_size)); - return addresses; -} - -grpc_lb_addresses* grpc_lb_addresses_copy(const grpc_lb_addresses* addresses) { - grpc_lb_addresses* new_addresses = grpc_lb_addresses_create( - addresses->num_addresses, addresses->user_data_vtable); - memcpy(new_addresses->addresses, addresses->addresses, - sizeof(grpc_lb_address) * addresses->num_addresses); - for (size_t i = 0; i < addresses->num_addresses; ++i) { - if (new_addresses->addresses[i].balancer_name != nullptr) { - new_addresses->addresses[i].balancer_name = - gpr_strdup(new_addresses->addresses[i].balancer_name); - } - if (new_addresses->addresses[i].user_data != nullptr) { - new_addresses->addresses[i].user_data = addresses->user_data_vtable->copy( - new_addresses->addresses[i].user_data); - } - } - return new_addresses; -} - -void grpc_lb_addresses_set_address(grpc_lb_addresses* addresses, size_t index, - const void* address, size_t address_len, - bool is_balancer, const char* balancer_name, - void* user_data) { - GPR_ASSERT(index < addresses->num_addresses); - if (user_data != nullptr) GPR_ASSERT(addresses->user_data_vtable != nullptr); - grpc_lb_address* target = &addresses->addresses[index]; - memcpy(target->address.addr, address, address_len); - target->address.len = static_cast(address_len); - target->is_balancer = is_balancer; - target->balancer_name = gpr_strdup(balancer_name); - target->user_data = user_data; -} - -bool grpc_lb_addresses_set_address_from_uri(grpc_lb_addresses* addresses, - size_t index, const grpc_uri* uri, - bool is_balancer, - const char* balancer_name, - void* user_data) { - grpc_resolved_address address; - if (!grpc_parse_uri(uri, &address)) return false; - grpc_lb_addresses_set_address(addresses, index, address.addr, address.len, - is_balancer, balancer_name, user_data); - return true; -} - -int grpc_lb_addresses_cmp(const grpc_lb_addresses* addresses1, - const grpc_lb_addresses* addresses2) { - if (addresses1->num_addresses > addresses2->num_addresses) return 1; - if (addresses1->num_addresses < addresses2->num_addresses) return -1; - if (addresses1->user_data_vtable > addresses2->user_data_vtable) return 1; - if (addresses1->user_data_vtable < addresses2->user_data_vtable) return -1; - for (size_t i = 0; i < addresses1->num_addresses; ++i) { - const grpc_lb_address* target1 = &addresses1->addresses[i]; - const grpc_lb_address* target2 = &addresses2->addresses[i]; - if (target1->address.len > target2->address.len) return 1; - if (target1->address.len < target2->address.len) return -1; - int retval = memcmp(target1->address.addr, target2->address.addr, - target1->address.len); - if (retval != 0) return retval; - if (target1->is_balancer > target2->is_balancer) return 1; - if (target1->is_balancer < target2->is_balancer) return -1; - const char* balancer_name1 = - target1->balancer_name != nullptr ? target1->balancer_name : ""; - const char* balancer_name2 = - target2->balancer_name != nullptr ? target2->balancer_name : ""; - retval = strcmp(balancer_name1, balancer_name2); - if (retval != 0) return retval; - if (addresses1->user_data_vtable != nullptr) { - retval = addresses1->user_data_vtable->cmp(target1->user_data, - target2->user_data); - if (retval != 0) return retval; - } - } - return 0; -} - -void grpc_lb_addresses_destroy(grpc_lb_addresses* addresses) { - for (size_t i = 0; i < addresses->num_addresses; ++i) { - gpr_free(addresses->addresses[i].balancer_name); - if (addresses->addresses[i].user_data != nullptr) { - addresses->user_data_vtable->destroy(addresses->addresses[i].user_data); - } - } - gpr_free(addresses->addresses); - gpr_free(addresses); -} - -static void* lb_addresses_copy(void* addresses) { - return grpc_lb_addresses_copy(static_cast(addresses)); -} -static void lb_addresses_destroy(void* addresses) { - grpc_lb_addresses_destroy(static_cast(addresses)); -} -static int lb_addresses_cmp(void* addresses1, void* addresses2) { - return grpc_lb_addresses_cmp(static_cast(addresses1), - static_cast(addresses2)); -} -static const grpc_arg_pointer_vtable lb_addresses_arg_vtable = { - lb_addresses_copy, lb_addresses_destroy, lb_addresses_cmp}; - -grpc_arg grpc_lb_addresses_create_channel_arg( - const grpc_lb_addresses* addresses) { - return grpc_channel_arg_pointer_create( - (char*)GRPC_ARG_LB_ADDRESSES, (void*)addresses, &lb_addresses_arg_vtable); -} - -grpc_lb_addresses* grpc_lb_addresses_find_channel_arg( - const grpc_channel_args* channel_args) { - const grpc_arg* lb_addresses_arg = - grpc_channel_args_find(channel_args, GRPC_ARG_LB_ADDRESSES); - if (lb_addresses_arg == nullptr || lb_addresses_arg->type != GRPC_ARG_POINTER) - return nullptr; - return static_cast(lb_addresses_arg->value.pointer.p); -} - -bool grpc_lb_addresses_contains_balancer_address( - const grpc_lb_addresses& addresses) { - for (size_t i = 0; i < addresses.num_addresses; ++i) { - if (addresses.addresses[i].is_balancer) return true; - } - return false; -} diff --git a/src/core/ext/filters/client_channel/lb_policy_factory.h b/src/core/ext/filters/client_channel/lb_policy_factory.h index a59deadb265..aaf3e959542 100644 --- a/src/core/ext/filters/client_channel/lb_policy_factory.h +++ b/src/core/ext/filters/client_channel/lb_policy_factory.h @@ -21,91 +21,9 @@ #include -#include "src/core/lib/iomgr/resolve_address.h" - -#include "src/core/ext/filters/client_channel/client_channel_factory.h" #include "src/core/ext/filters/client_channel/lb_policy.h" -#include "src/core/lib/uri/uri_parser.h" - -// -// representation of an LB address -// - -// Channel arg key for grpc_lb_addresses. -#define GRPC_ARG_LB_ADDRESSES "grpc.lb_addresses" - -/** A resolved address alongside any LB related information associated with it. - * \a user_data, if not NULL, contains opaque data meant to be consumed by the - * gRPC LB policy. Note that no all LB policies support \a user_data as input. - * Those who don't will simply ignore it and will correspondingly return NULL in - * their namesake pick() output argument. */ -// TODO(roth): Once we figure out a better way of handling user_data in -// LB policies, convert these structs to C++ classes. -typedef struct grpc_lb_address { - grpc_resolved_address address; - bool is_balancer; - char* balancer_name; /* For secure naming. */ - void* user_data; -} grpc_lb_address; - -typedef struct grpc_lb_user_data_vtable { - void* (*copy)(void*); - void (*destroy)(void*); - int (*cmp)(void*, void*); -} grpc_lb_user_data_vtable; - -typedef struct grpc_lb_addresses { - size_t num_addresses; - grpc_lb_address* addresses; - const grpc_lb_user_data_vtable* user_data_vtable; -} grpc_lb_addresses; - -/** Returns a grpc_addresses struct with enough space for - \a num_addresses addresses. The \a user_data_vtable argument may be - NULL if no user data will be added. */ -grpc_lb_addresses* grpc_lb_addresses_create( - size_t num_addresses, const grpc_lb_user_data_vtable* user_data_vtable); - -/** Creates a copy of \a addresses. */ -grpc_lb_addresses* grpc_lb_addresses_copy(const grpc_lb_addresses* addresses); - -/** Sets the value of the address at index \a index of \a addresses. - * \a address is a socket address of length \a address_len. */ -void grpc_lb_addresses_set_address(grpc_lb_addresses* addresses, size_t index, - const void* address, size_t address_len, - bool is_balancer, const char* balancer_name, - void* user_data); - -/** Sets the value of the address at index \a index of \a addresses from \a uri. - * Returns true upon success, false otherwise. */ -bool grpc_lb_addresses_set_address_from_uri(grpc_lb_addresses* addresses, - size_t index, const grpc_uri* uri, - bool is_balancer, - const char* balancer_name, - void* user_data); - -/** Compares \a addresses1 and \a addresses2. */ -int grpc_lb_addresses_cmp(const grpc_lb_addresses* addresses1, - const grpc_lb_addresses* addresses2); - -/** Destroys \a addresses. */ -void grpc_lb_addresses_destroy(grpc_lb_addresses* addresses); - -/** Returns a channel arg containing \a addresses. */ -grpc_arg grpc_lb_addresses_create_channel_arg( - const grpc_lb_addresses* addresses); - -/** Returns the \a grpc_lb_addresses instance in \a channel_args or NULL */ -grpc_lb_addresses* grpc_lb_addresses_find_channel_arg( - const grpc_channel_args* channel_args); - -// Returns true if addresses contains at least one balancer address. -bool grpc_lb_addresses_contains_balancer_address( - const grpc_lb_addresses& addresses); - -// -// LB policy factory -// +#include "src/core/lib/gprpp/abstract.h" +#include "src/core/lib/gprpp/orphanable.h" namespace grpc_core { @@ -113,15 +31,18 @@ class LoadBalancingPolicyFactory { public: /// Returns a new LB policy instance. virtual OrphanablePtr CreateLoadBalancingPolicy( - const LoadBalancingPolicy::Args& args) const GRPC_ABSTRACT; + LoadBalancingPolicy::Args) const GRPC_ABSTRACT; /// Returns the LB policy name that this factory provides. /// Caller does NOT take ownership of result. virtual const char* name() const GRPC_ABSTRACT; + virtual RefCountedPtr ParseLoadBalancingConfig( + const grpc_json* json, grpc_error** error) const GRPC_ABSTRACT; + virtual ~LoadBalancingPolicyFactory() {} - GRPC_ABSTRACT_BASE_CLASS + GRPC_ABSTRACT_BASE_CLASS; }; } // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/lb_policy_registry.cc b/src/core/ext/filters/client_channel/lb_policy_registry.cc index ad459c9c8cf..973aa26d0f6 100644 --- a/src/core/ext/filters/client_channel/lb_policy_registry.cc +++ b/src/core/ext/filters/client_channel/lb_policy_registry.cc @@ -84,19 +84,122 @@ void LoadBalancingPolicyRegistry::Builder::RegisterLoadBalancingPolicyFactory( OrphanablePtr LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( - const char* name, const LoadBalancingPolicy::Args& args) { + const char* name, LoadBalancingPolicy::Args args) { GPR_ASSERT(g_state != nullptr); // Find factory. LoadBalancingPolicyFactory* factory = g_state->GetLoadBalancingPolicyFactory(name); if (factory == nullptr) return nullptr; // Specified name not found. // Create policy via factory. - return factory->CreateLoadBalancingPolicy(args); + return factory->CreateLoadBalancingPolicy(std::move(args)); } -bool LoadBalancingPolicyRegistry::LoadBalancingPolicyExists(const char* name) { +bool LoadBalancingPolicyRegistry::LoadBalancingPolicyExists( + const char* name, bool* requires_config) { GPR_ASSERT(g_state != nullptr); - return g_state->GetLoadBalancingPolicyFactory(name) != nullptr; + auto* factory = g_state->GetLoadBalancingPolicyFactory(name); + if (factory == nullptr) { + return false; + } + if (requires_config != nullptr) { + grpc_error* error = GRPC_ERROR_NONE; + // Check if the load balancing policy allows an empty config + *requires_config = + factory->ParseLoadBalancingConfig(nullptr, &error) == nullptr; + GRPC_ERROR_UNREF(error); + } + return true; +} + +namespace { +// Returns the JSON node of policy (with both policy name and config content) +// given the JSON node of a LoadBalancingConfig array. +grpc_json* ParseLoadBalancingConfigHelper(const grpc_json* lb_config_array, + grpc_error** error) { + GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); + char* error_msg; + if (lb_config_array == nullptr || lb_config_array->type != GRPC_JSON_ARRAY) { + gpr_asprintf(&error_msg, "field:%s error:type should be array", + lb_config_array->key); + *error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg); + gpr_free(error_msg); + return nullptr; + } + const char* field_name = lb_config_array->key; + // Find the first LB policy that this client supports. + for (const grpc_json* lb_config = lb_config_array->child; + lb_config != nullptr; lb_config = lb_config->next) { + if (lb_config->type != GRPC_JSON_OBJECT) { + gpr_asprintf(&error_msg, + "field:%s error:child entry should be of type object", + field_name); + *error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg); + gpr_free(error_msg); + return nullptr; + } + grpc_json* policy = nullptr; + for (grpc_json* field = lb_config->child; field != nullptr; + field = field->next) { + if (field->key == nullptr || field->type != GRPC_JSON_OBJECT) { + gpr_asprintf(&error_msg, + "field:%s error:child entry should be of type object", + field_name); + *error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg); + gpr_free(error_msg); + return nullptr; + } + if (policy != nullptr) { + gpr_asprintf(&error_msg, "field:%s error:oneOf violation", field_name); + *error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg); + gpr_free(error_msg); + return nullptr; + } // Violate "oneof" type. + policy = field; + } + if (policy == nullptr) { + gpr_asprintf(&error_msg, "field:%s error:no policy found in child entry", + field_name); + *error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg); + gpr_free(error_msg); + return nullptr; + } + // If we support this policy, then select it. + if (LoadBalancingPolicyRegistry::LoadBalancingPolicyExists(policy->key, + nullptr)) { + return policy; + } + } + gpr_asprintf(&error_msg, "field:%s error:No known policy", field_name); + *error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg); + gpr_free(error_msg); + return nullptr; +} +} // namespace + +RefCountedPtr +LoadBalancingPolicyRegistry::ParseLoadBalancingConfig(const grpc_json* json, + grpc_error** error) { + GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); + GPR_ASSERT(g_state != nullptr); + const grpc_json* policy = ParseLoadBalancingConfigHelper(json, error); + if (policy == nullptr) { + return nullptr; + } else { + GPR_DEBUG_ASSERT(*error == GRPC_ERROR_NONE && json != nullptr); + // Find factory. + LoadBalancingPolicyFactory* factory = + g_state->GetLoadBalancingPolicyFactory(policy->key); + if (factory == nullptr) { + char* msg; + gpr_asprintf(&msg, "field:%s error:Factory not found to create policy", + json->key); + *error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); + gpr_free(msg); + return nullptr; + } + // Parse load balancing config via factory. + return factory->ParseLoadBalancingConfig(policy, error); + } } } // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/lb_policy_registry.h b/src/core/ext/filters/client_channel/lb_policy_registry.h index 338f7c9f696..6820cfc9334 100644 --- a/src/core/ext/filters/client_channel/lb_policy_registry.h +++ b/src/core/ext/filters/client_channel/lb_policy_registry.h @@ -46,11 +46,18 @@ class LoadBalancingPolicyRegistry { /// Creates an LB policy of the type specified by \a name. static OrphanablePtr CreateLoadBalancingPolicy( - const char* name, const LoadBalancingPolicy::Args& args); + const char* name, LoadBalancingPolicy::Args args); /// Returns true if the LB policy factory specified by \a name exists in this - /// registry. - static bool LoadBalancingPolicyExists(const char* name); + /// registry. If the load balancing policy requires a config to be specified + /// then sets \a requires_config to true. + static bool LoadBalancingPolicyExists(const char* name, + bool* requires_config); + + /// Returns a parsed object of the load balancing policy to be used from a + /// LoadBalancingConfig array \a json. + static RefCountedPtr ParseLoadBalancingConfig( + const grpc_json* json, grpc_error** error); }; } // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/local_subchannel_pool.cc b/src/core/ext/filters/client_channel/local_subchannel_pool.cc new file mode 100644 index 00000000000..d1c1cacb441 --- /dev/null +++ b/src/core/ext/filters/client_channel/local_subchannel_pool.cc @@ -0,0 +1,96 @@ +// +// +// 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 + +#include "src/core/ext/filters/client_channel/local_subchannel_pool.h" + +#include "src/core/ext/filters/client_channel/subchannel.h" + +namespace grpc_core { + +LocalSubchannelPool::LocalSubchannelPool() { + subchannel_map_ = grpc_avl_create(&subchannel_avl_vtable_); +} + +LocalSubchannelPool::~LocalSubchannelPool() { + grpc_avl_unref(subchannel_map_, nullptr); +} + +Subchannel* LocalSubchannelPool::RegisterSubchannel(SubchannelKey* key, + Subchannel* constructed) { + // Check to see if a subchannel already exists. + Subchannel* c = + static_cast(grpc_avl_get(subchannel_map_, key, nullptr)); + if (c != nullptr) { + // The subchannel already exists. Reuse it. + c = GRPC_SUBCHANNEL_REF(c, "subchannel_register+reuse"); + GRPC_SUBCHANNEL_UNREF(constructed, "subchannel_register+found_existing"); + } else { + // There hasn't been such subchannel. Add one. + subchannel_map_ = grpc_avl_add(subchannel_map_, New(*key), + constructed, nullptr); + c = constructed; + } + return c; +} + +void LocalSubchannelPool::UnregisterSubchannel(SubchannelKey* key) { + subchannel_map_ = grpc_avl_remove(subchannel_map_, key, nullptr); +} + +Subchannel* LocalSubchannelPool::FindSubchannel(SubchannelKey* key) { + Subchannel* c = + static_cast(grpc_avl_get(subchannel_map_, key, nullptr)); + return c == nullptr ? c : GRPC_SUBCHANNEL_REF(c, "found_from_pool"); +} + +namespace { + +void sck_avl_destroy(void* p, void* user_data) { + SubchannelKey* key = static_cast(p); + Delete(key); +} + +void* sck_avl_copy(void* p, void* unused) { + const SubchannelKey* key = static_cast(p); + auto new_key = New(*key); + return static_cast(new_key); +} + +long sck_avl_compare(void* a, void* b, void* unused) { + const SubchannelKey* key_a = static_cast(a); + const SubchannelKey* key_b = static_cast(b); + return key_a->Cmp(*key_b); +} + +void scv_avl_destroy(void* p, void* user_data) {} + +void* scv_avl_copy(void* p, void* unused) { return p; } + +} // namespace + +const grpc_avl_vtable LocalSubchannelPool::subchannel_avl_vtable_ = { + sck_avl_destroy, // destroy_key + sck_avl_copy, // copy_key + sck_avl_compare, // compare_keys + scv_avl_destroy, // destroy_value + scv_avl_copy // copy_value +}; + +} // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/local_subchannel_pool.h b/src/core/ext/filters/client_channel/local_subchannel_pool.h new file mode 100644 index 00000000000..a6b7e259fbb --- /dev/null +++ b/src/core/ext/filters/client_channel/local_subchannel_pool.h @@ -0,0 +1,56 @@ +/* + * + * 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_LOCAL_SUBCHANNEL_POOL_H +#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LOCAL_SUBCHANNEL_POOL_H + +#include + +#include "src/core/ext/filters/client_channel/subchannel_pool_interface.h" + +namespace grpc_core { + +// The local subchannel pool that is owned by a single channel. It doesn't +// support subchannel sharing with other channels by nature. Nor does it support +// subchannel retention when a subchannel is not used. The only real purpose of +// using this subchannel pool is to allow subchannel reuse within the channel +// when an incoming resolver update contains some addresses for which the +// channel has already created subchannels. +// Thread-unsafe. +class LocalSubchannelPool final : public SubchannelPoolInterface { + public: + LocalSubchannelPool(); + ~LocalSubchannelPool() override; + + // Implements interface methods. + // Thread-unsafe. Intended to be invoked within the client_channel combiner. + Subchannel* RegisterSubchannel(SubchannelKey* key, + Subchannel* constructed) override; + void UnregisterSubchannel(SubchannelKey* key) override; + Subchannel* FindSubchannel(SubchannelKey* key) override; + + private: + // The vtable for subchannel operations in an AVL tree. + static const grpc_avl_vtable subchannel_avl_vtable_; + // A map from subchannel key to subchannel. + grpc_avl subchannel_map_; +}; + +} // namespace grpc_core + +#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LOCAL_SUBCHANNEL_POOL_H */ diff --git a/src/core/ext/filters/client_channel/parse_address.cc b/src/core/ext/filters/client_channel/parse_address.cc index 707beb88769..c5e1ed811bc 100644 --- a/src/core/ext/filters/client_channel/parse_address.cc +++ b/src/core/ext/filters/client_channel/parse_address.cc @@ -19,6 +19,7 @@ #include #include "src/core/ext/filters/client_channel/parse_address.h" +#include "src/core/lib/iomgr/grpc_if_nametoindex.h" #include "src/core/lib/iomgr/sockaddr.h" #include "src/core/lib/iomgr/socket_utils.h" @@ -35,6 +36,11 @@ #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" +#ifdef GRPC_POSIX_SOCKET +#include +#include +#endif + #ifdef GRPC_HAVE_UNIX_SOCKET bool grpc_parse_unix(const grpc_uri* uri, @@ -69,7 +75,12 @@ bool grpc_parse_ipv4_hostport(const char* hostport, grpc_resolved_address* addr, // Split host and port. char* host; char* port; - if (!gpr_split_host_port(hostport, &host, &port)) return false; + if (!gpr_split_host_port(hostport, &host, &port)) { + if (log_errors) { + gpr_log(GPR_ERROR, "Failed gpr_split_host_port(%s, ...)", hostport); + } + return false; + } // Parse IP address. memset(addr, 0, sizeof(*addr)); addr->len = static_cast(sizeof(grpc_sockaddr_in)); @@ -115,7 +126,12 @@ bool grpc_parse_ipv6_hostport(const char* hostport, grpc_resolved_address* addr, // Split host and port. char* host; char* port; - if (!gpr_split_host_port(hostport, &host, &port)) return false; + if (!gpr_split_host_port(hostport, &host, &port)) { + if (log_errors) { + gpr_log(GPR_ERROR, "Failed gpr_split_host_port(%s, ...)", hostport); + } + return false; + } // Parse IP address. memset(addr, 0, sizeof(*addr)); addr->len = static_cast(sizeof(grpc_sockaddr_in6)); @@ -150,10 +166,13 @@ bool grpc_parse_ipv6_hostport(const char* hostport, grpc_resolved_address* addr, if (gpr_parse_bytes_to_uint32(host_end + 1, strlen(host) - host_without_scope_len - 1, &sin6_scope_id) == 0) { - if (log_errors) { - gpr_log(GPR_ERROR, "invalid ipv6 scope id: '%s'", host_end + 1); + if ((sin6_scope_id = grpc_if_nametoindex(host_end + 1)) == 0) { + gpr_log(GPR_ERROR, + "Invalid interface name: '%s'. " + "Non-numeric and failed if_nametoindex.", + host_end + 1); + goto done; } - goto done; } // Handle "sin6_scope_id" being type "u_long". See grpc issue #10027. in6->sin6_scope_id = sin6_scope_id; diff --git a/src/core/ext/filters/client_channel/resolver.cc b/src/core/ext/filters/client_channel/resolver.cc index cd11eeb9e4d..b50c42f6a1c 100644 --- a/src/core/ext/filters/client_channel/resolver.cc +++ b/src/core/ext/filters/client_channel/resolver.cc @@ -26,10 +26,63 @@ grpc_core::DebugOnlyTraceFlag grpc_trace_resolver_refcount(false, namespace grpc_core { -Resolver::Resolver(grpc_combiner* combiner) - : InternallyRefCountedWithTracing(&grpc_trace_resolver_refcount), +// +// Resolver +// + +Resolver::Resolver(grpc_combiner* combiner, + UniquePtr result_handler) + : InternallyRefCounted(&grpc_trace_resolver_refcount), + result_handler_(std::move(result_handler)), combiner_(GRPC_COMBINER_REF(combiner, "resolver")) {} Resolver::~Resolver() { GRPC_COMBINER_UNREF(combiner_, "resolver"); } +// +// Resolver::Result +// + +Resolver::Result::~Result() { + GRPC_ERROR_UNREF(service_config_error); + grpc_channel_args_destroy(args); +} + +Resolver::Result::Result(const Result& other) { + addresses = other.addresses; + service_config = other.service_config; + service_config_error = GRPC_ERROR_REF(other.service_config_error); + args = grpc_channel_args_copy(other.args); +} + +Resolver::Result::Result(Result&& other) { + addresses = std::move(other.addresses); + service_config = std::move(other.service_config); + service_config_error = other.service_config_error; + other.service_config_error = GRPC_ERROR_NONE; + args = other.args; + other.args = nullptr; +} + +Resolver::Result& Resolver::Result::operator=(const Result& other) { + addresses = other.addresses; + service_config = other.service_config; + GRPC_ERROR_UNREF(service_config_error); + service_config_error = GRPC_ERROR_REF(other.service_config_error); + grpc_channel_args_destroy(args); + args = grpc_channel_args_copy(other.args); + return *this; +} + +Resolver::Result& Resolver::Result::operator=(Result&& other) { + addresses = std::move(other.addresses); + service_config = std::move(other.service_config); + GRPC_ERROR_UNREF(service_config_error); + service_config_error = other.service_config_error; + other.service_config_error = GRPC_ERROR_NONE; + grpc_channel_args_destroy(args); + args = other.args; + other.args = nullptr; + return *this; +} + } // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/resolver.h b/src/core/ext/filters/client_channel/resolver.h index e9acbb7c41c..9aa504225ad 100644 --- a/src/core/ext/filters/client_channel/resolver.h +++ b/src/core/ext/filters/client_channel/resolver.h @@ -23,8 +23,11 @@ #include +#include "src/core/ext/filters/client_channel/server_address.h" +#include "src/core/ext/filters/client_channel/service_config.h" #include "src/core/lib/gprpp/abstract.h" #include "src/core/lib/gprpp/orphanable.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/iomgr.h" @@ -44,29 +47,52 @@ namespace grpc_core { /// /// Note: All methods with a "Locked" suffix must be called from the /// combiner passed to the constructor. -class Resolver : public InternallyRefCountedWithTracing { +class Resolver : public InternallyRefCounted { public: + /// Results returned by the resolver. + struct Result { + ServerAddressList addresses; + RefCountedPtr service_config; + grpc_error* service_config_error = GRPC_ERROR_NONE; + const grpc_channel_args* args = nullptr; + + // TODO(roth): Remove everything below once grpc_error and + // grpc_channel_args are convert to copyable and movable C++ objects. + Result() = default; + ~Result(); + Result(const Result& other); + Result(Result&& other); + Result& operator=(const Result& other); + Result& operator=(Result&& other); + }; + + /// A proxy object used by the resolver to return results to the + /// client channel. + class ResultHandler { + public: + virtual ~ResultHandler() {} + + /// Returns a result to the channel. + /// Takes ownership of \a result.args. + virtual void ReturnResult(Result result) GRPC_ABSTRACT; // NOLINT + + /// Returns a transient error to the channel. + /// If the resolver does not set the GRPC_ERROR_INT_GRPC_STATUS + /// attribute on the error, calls will be failed with status UNKNOWN. + virtual void ReturnError(grpc_error* error) GRPC_ABSTRACT; + + // TODO(yashkt): As part of the service config error handling + // changes, add a method to parse the service config JSON string. + + GRPC_ABSTRACT_BASE_CLASS + }; + // Not copyable nor movable. Resolver(const Resolver&) = delete; Resolver& operator=(const Resolver&) = delete; - /// Requests a callback when a new result becomes available. - /// When the new result is available, sets \a *result to the new result - /// and schedules \a on_complete for execution. - /// Upon transient failure, sets \a *result to nullptr and schedules - /// \a on_complete with no error. - /// If resolution is fatally broken, sets \a *result to nullptr and - /// schedules \a on_complete with an error. - /// TODO(roth): When we have time, improve the way this API represents - /// transient failure vs. shutdown. - /// - /// Note that the client channel will almost always have a request - /// to \a NextLocked() pending. When it gets the callback, it will - /// process the new result and then immediately make another call to - /// \a NextLocked(). This allows push-based resolvers to provide new - /// data as soon as it becomes available. - virtual void NextLocked(grpc_channel_args** result, - grpc_closure* on_complete) GRPC_ABSTRACT; + /// Starts resolving. + virtual void StartLocked() GRPC_ABSTRACT; /// Asks the resolver to obtain an updated resolver result, if /// applicable. @@ -79,8 +105,8 @@ class Resolver : public InternallyRefCountedWithTracing { /// /// For push-based implementations, this may be a no-op. /// - /// If this causes new data to become available, then the currently - /// pending call to \a NextLocked() will return the new result. + /// Note: Implementations must not invoke any method on the + /// ResultHandler from within this call. virtual void RequestReresolutionLocked() {} /// Resets the re-resolution backoff, if any. @@ -108,16 +134,18 @@ class Resolver : public InternallyRefCountedWithTracing { // TODO(roth): Once we have a C++-like interface for combiners, this // API should change to take a RefCountedPtr<>, so that we always take // ownership of a new ref. - explicit Resolver(grpc_combiner* combiner); + explicit Resolver(grpc_combiner* combiner, + UniquePtr result_handler); virtual ~Resolver(); - /// Shuts down the resolver. If there is a pending call to - /// NextLocked(), the callback will be scheduled with an error. + /// Shuts down the resolver. virtual void ShutdownLocked() GRPC_ABSTRACT; grpc_combiner* combiner() const { return combiner_; } + ResultHandler* result_handler() const { return result_handler_.get(); } + private: static void ShutdownAndUnrefLocked(void* arg, grpc_error* ignored) { Resolver* resolver = static_cast(arg); @@ -125,6 +153,7 @@ class Resolver : public InternallyRefCountedWithTracing { resolver->Unref(); } + UniquePtr result_handler_; grpc_combiner* combiner_; }; 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 90bc88961d9..27d543363a3 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 @@ -18,7 +18,7 @@ #include -#if GRPC_ARES == 1 && !defined(GRPC_UV) +#if GRPC_ARES == 1 #include #include @@ -33,6 +33,8 @@ #include "src/core/ext/filters/client_channel/lb_policy_registry.h" #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" #include "src/core/ext/filters/client_channel/resolver_registry.h" +#include "src/core/ext/filters/client_channel/server_address.h" +#include "src/core/ext/filters/client_channel/service_config.h" #include "src/core/lib/backoff/backoff.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gpr/env.h" @@ -41,10 +43,10 @@ #include "src/core/lib/gprpp/manual_constructor.h" #include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/gethostname.h" +#include "src/core/lib/iomgr/iomgr_custom.h" #include "src/core/lib/iomgr/resolve_address.h" #include "src/core/lib/iomgr/timer.h" #include "src/core/lib/json/json.h" -#include "src/core/lib/transport/service_config.h" #define GRPC_DNS_INITIAL_CONNECT_BACKOFF_SECONDS 1 #define GRPC_DNS_RECONNECT_BACKOFF_MULTIPLIER 1.6 @@ -59,10 +61,9 @@ const char kDefaultPort[] = "https"; class AresDnsResolver : public Resolver { public: - explicit AresDnsResolver(const ResolverArgs& args); + explicit AresDnsResolver(ResolverArgs args); - void NextLocked(grpc_channel_args** result, - grpc_closure* on_complete) override; + void StartLocked() override; void RequestReresolutionLocked() override; @@ -75,7 +76,6 @@ class AresDnsResolver : public Resolver { void MaybeStartResolvingLocked(); void StartResolvingLocked(); - void MaybeFinishNextLocked(); static void OnNextResolutionLocked(void* arg, grpc_error* error); static void OnResolvedLocked(void* arg, grpc_error* error); @@ -97,16 +97,6 @@ class AresDnsResolver : public Resolver { bool resolving_ = false; /// the pending resolving request grpc_ares_request* pending_request_ = nullptr; - /// which version of the result have we published? - int published_version_ = 0; - /// which version of the result is current? - int resolved_version_ = 0; - /// pending next completion, or NULL - grpc_closure* next_completion_ = nullptr; - /// target result address for next completion - grpc_channel_args** target_result_ = nullptr; - /// current (fully resolved) result - grpc_channel_args* resolved_result_ = nullptr; /// next resolution timer bool have_next_resolution_timer_ = false; grpc_timer next_resolution_timer_; @@ -117,15 +107,19 @@ class AresDnsResolver : public Resolver { /// retry backoff state BackOff backoff_; /// currently resolving addresses - grpc_lb_addresses* lb_addresses_ = nullptr; + UniquePtr addresses_; /// currently resolving service config char* service_config_json_ = nullptr; // has shutdown been initiated bool shutdown_initiated_ = false; + // timeout in milliseconds for active DNS queries + int query_timeout_ms_; + // whether or not to enable SRV DNS queries + bool enable_srv_queries_; }; -AresDnsResolver::AresDnsResolver(const ResolverArgs& args) - : Resolver(args.combiner), +AresDnsResolver::AresDnsResolver(ResolverArgs args) + : Resolver(args.combiner, std::move(args.result_handler)), backoff_( BackOff::Options() .set_initial_backoff(GRPC_DNS_INITIAL_CONNECT_BACKOFF_SECONDS * @@ -143,14 +137,18 @@ AresDnsResolver::AresDnsResolver(const ResolverArgs& args) dns_server_ = gpr_strdup(args.uri->authority); } channel_args_ = grpc_channel_args_copy(args.args); + // Disable service config option const grpc_arg* arg = grpc_channel_args_find( channel_args_, GRPC_ARG_SERVICE_CONFIG_DISABLE_RESOLUTION); - grpc_integer_options integer_options = {false, false, true}; - request_service_config_ = !grpc_channel_arg_get_integer(arg, integer_options); + request_service_config_ = !grpc_channel_arg_get_bool(arg, true); + // Min time b/t resolutions option arg = grpc_channel_args_find(channel_args_, GRPC_ARG_DNS_MIN_TIME_BETWEEN_RESOLUTIONS_MS); min_time_between_resolutions_ = grpc_channel_arg_get_integer(arg, {1000, 0, INT_MAX}); + // Enable SRV queries option + arg = grpc_channel_args_find(channel_args_, GRPC_ARG_DNS_ENABLE_SRV_QUERIES); + enable_srv_queries_ = grpc_channel_arg_get_bool(arg, false); interested_parties_ = grpc_pollset_set_create(); if (args.pollset_set != nullptr) { grpc_pollset_set_add_pollset_set(interested_parties_, args.pollset_set); @@ -159,30 +157,25 @@ AresDnsResolver::AresDnsResolver(const ResolverArgs& args) grpc_combiner_scheduler(combiner())); GRPC_CLOSURE_INIT(&on_resolved_, OnResolvedLocked, this, grpc_combiner_scheduler(combiner())); + const grpc_arg* query_timeout_ms_arg = + grpc_channel_args_find(channel_args_, GRPC_ARG_DNS_ARES_QUERY_TIMEOUT_MS); + query_timeout_ms_ = grpc_channel_arg_get_integer( + query_timeout_ms_arg, + {GRPC_DNS_ARES_DEFAULT_QUERY_TIMEOUT_MS, 0, INT_MAX}); } AresDnsResolver::~AresDnsResolver() { - gpr_log(GPR_DEBUG, "destroying AresDnsResolver"); - if (resolved_result_ != nullptr) { - grpc_channel_args_destroy(resolved_result_); - } + GRPC_CARES_TRACE_LOG("resolver:%p destroying AresDnsResolver", this); grpc_pollset_set_destroy(interested_parties_); gpr_free(dns_server_); gpr_free(name_to_resolve_); grpc_channel_args_destroy(channel_args_); } -void AresDnsResolver::NextLocked(grpc_channel_args** target_result, - grpc_closure* on_complete) { - gpr_log(GPR_DEBUG, "AresDnsResolver::NextLocked() is called."); - GPR_ASSERT(next_completion_ == nullptr); - next_completion_ = on_complete; - target_result_ = target_result; - if (resolved_version_ == 0 && !resolving_) { - MaybeStartResolvingLocked(); - } else { - MaybeFinishNextLocked(); - } +void AresDnsResolver::StartLocked() { + GRPC_CARES_TRACE_LOG("resolver:%p AresDnsResolver::StartLocked() is called.", + this); + MaybeStartResolvingLocked(); } void AresDnsResolver::RequestReresolutionLocked() { @@ -206,23 +199,19 @@ void AresDnsResolver::ShutdownLocked() { if (pending_request_ != nullptr) { grpc_cancel_ares_request_locked(pending_request_); } - if (next_completion_ != nullptr) { - *target_result_ = nullptr; - GRPC_CLOSURE_SCHED(next_completion_, GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "Resolver Shutdown")); - next_completion_ = nullptr; - } } void AresDnsResolver::OnNextResolutionLocked(void* arg, grpc_error* error) { AresDnsResolver* r = static_cast(arg); GRPC_CARES_TRACE_LOG( - "%p re-resolution timer fired. error: %s. shutdown_initiated_: %d", r, - grpc_error_string(error), r->shutdown_initiated_); + "resolver:%p re-resolution timer fired. error: %s. shutdown_initiated_: " + "%d", + r, grpc_error_string(error), r->shutdown_initiated_); r->have_next_resolution_timer_ = false; if (error == GRPC_ERROR_NONE && !r->shutdown_initiated_) { if (!r->resolving_) { - GRPC_CARES_TRACE_LOG("%p start resolving due to re-resolution timer", r); + GRPC_CARES_TRACE_LOG( + "resolver:%p start resolving due to re-resolution timer", r); r->StartResolvingLocked(); } } @@ -238,130 +227,156 @@ bool ValueInJsonArray(grpc_json* array, const char* value) { return false; } -char* ChooseServiceConfig(char* service_config_choice_json) { +char* ChooseServiceConfig(char* service_config_choice_json, + grpc_error** error) { grpc_json* choices_json = grpc_json_parse_string(service_config_choice_json); - if (choices_json == nullptr || choices_json->type != GRPC_JSON_ARRAY) { - gpr_log(GPR_ERROR, "cannot parse service config JSON string"); + if (choices_json == nullptr) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Service Config JSON Parsing, error: could not parse"); + return nullptr; + } + if (choices_json->type != GRPC_JSON_ARRAY) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Service Config Choices, error: should be of type array"); return nullptr; } char* service_config = nullptr; + InlinedVector error_list; + bool found_choice = false; // have we found a choice? for (grpc_json* choice = choices_json->child; choice != nullptr; choice = choice->next) { if (choice->type != GRPC_JSON_OBJECT) { - gpr_log(GPR_ERROR, "cannot parse service config JSON string"); - break; + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Service Config Choice, error: should be of type object")); + continue; } grpc_json* service_config_json = nullptr; + bool selected = true; // has this choice been rejected? for (grpc_json* field = choice->child; field != nullptr; field = field->next) { // Check client language, if specified. if (strcmp(field->key, "clientLanguage") == 0) { - if (field->type != GRPC_JSON_ARRAY || !ValueInJsonArray(field, "c++")) { - service_config_json = nullptr; - break; + if (field->type != GRPC_JSON_ARRAY) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:clientLanguage error:should be of type array")); + } else if (!ValueInJsonArray(field, "c++")) { + selected = false; } } // Check client hostname, if specified. if (strcmp(field->key, "clientHostname") == 0) { + if (field->type != GRPC_JSON_ARRAY) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:clientHostname error:should be of type array")); + continue; + } char* hostname = grpc_gethostname(); - if (hostname == nullptr || field->type != GRPC_JSON_ARRAY || - !ValueInJsonArray(field, hostname)) { - service_config_json = nullptr; - break; + if (hostname == nullptr || !ValueInJsonArray(field, hostname)) { + selected = false; } } // Check percentage, if specified. if (strcmp(field->key, "percentage") == 0) { if (field->type != GRPC_JSON_NUMBER) { - service_config_json = nullptr; - break; + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:percentage error:should be of type number")); + continue; } int random_pct = rand() % 100; int percentage; - if (sscanf(field->value, "%d", &percentage) != 1 || - random_pct > percentage || percentage == 0) { - service_config_json = nullptr; - break; + if (sscanf(field->value, "%d", &percentage) != 1) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:percentage error:should be of type integer")); + continue; + } + if (random_pct > percentage || percentage == 0) { + selected = false; } } // Save service config. if (strcmp(field->key, "serviceConfig") == 0) { if (field->type == GRPC_JSON_OBJECT) { service_config_json = field; + } else { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:serviceConfig error:should be of type object")); } } } - if (service_config_json != nullptr) { + if (!found_choice && selected && service_config_json != nullptr) { service_config = grpc_json_dump_to_string(service_config_json, 0); - break; + found_choice = true; } } grpc_json_destroy(choices_json); + if (!error_list.empty()) { + gpr_free(service_config); + service_config = nullptr; + *error = GRPC_ERROR_CREATE_FROM_VECTOR("Service Config Choices Parser", + &error_list); + } return service_config; } void AresDnsResolver::OnResolvedLocked(void* arg, grpc_error* error) { AresDnsResolver* r = static_cast(arg); - grpc_channel_args* result = nullptr; GPR_ASSERT(r->resolving_); r->resolving_ = false; gpr_free(r->pending_request_); r->pending_request_ = nullptr; - if (r->lb_addresses_ != nullptr) { - static const char* args_to_remove[1]; - size_t num_args_to_remove = 0; - grpc_arg args_to_add[2]; - size_t num_args_to_add = 0; - args_to_add[num_args_to_add++] = - grpc_lb_addresses_create_channel_arg(r->lb_addresses_); - char* service_config_string = nullptr; + if (r->shutdown_initiated_) { + r->Unref(DEBUG_LOCATION, "OnResolvedLocked() shutdown"); + return; + } + if (r->addresses_ != nullptr) { + Result result; + result.addresses = std::move(*r->addresses_); if (r->service_config_json_ != nullptr) { - service_config_string = ChooseServiceConfig(r->service_config_json_); + char* service_config_string = ChooseServiceConfig( + r->service_config_json_, &result.service_config_error); gpr_free(r->service_config_json_); - if (service_config_string != nullptr) { - gpr_log(GPR_INFO, "selected service config choice: %s", - service_config_string); - args_to_remove[num_args_to_remove++] = GRPC_ARG_SERVICE_CONFIG; - args_to_add[num_args_to_add++] = grpc_channel_arg_string_create( - (char*)GRPC_ARG_SERVICE_CONFIG, service_config_string); + if (result.service_config_error == GRPC_ERROR_NONE && + service_config_string != nullptr) { + GRPC_CARES_TRACE_LOG("resolver:%p selected service config choice: %s", + r, service_config_string); + result.service_config = ServiceConfig::Create( + service_config_string, &result.service_config_error); } + gpr_free(service_config_string); } - result = grpc_channel_args_copy_and_add_and_remove( - r->channel_args_, args_to_remove, num_args_to_remove, args_to_add, - num_args_to_add); - gpr_free(service_config_string); - grpc_lb_addresses_destroy(r->lb_addresses_); + result.args = grpc_channel_args_copy(r->channel_args_); + r->result_handler()->ReturnResult(std::move(result)); + r->addresses_.reset(); // Reset backoff state so that we start from the beginning when the // next request gets triggered. r->backoff_.Reset(); - } else if (!r->shutdown_initiated_) { - const char* msg = grpc_error_string(error); - gpr_log(GPR_DEBUG, "dns resolution failed: %s", msg); + } else { + GRPC_CARES_TRACE_LOG("resolver:%p dns resolution failed: %s", r, + grpc_error_string(error)); + r->result_handler()->ReturnError(grpc_error_set_int( + GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + "DNS resolution failed", &error, 1), + GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE)); + // Set retry timer. grpc_millis next_try = r->backoff_.NextAttemptTime(); grpc_millis timeout = next_try - ExecCtx::Get()->Now(); - gpr_log(GPR_INFO, "dns resolution failed (will retry): %s", - grpc_error_string(error)); + GRPC_CARES_TRACE_LOG("resolver:%p dns resolution failed (will retry): %s", + r, grpc_error_string(error)); GPR_ASSERT(!r->have_next_resolution_timer_); r->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 self = r->Ref(DEBUG_LOCATION, "retry-timer"); - self.release(); + r->Ref(DEBUG_LOCATION, "retry-timer").release(); if (timeout > 0) { - gpr_log(GPR_DEBUG, "retrying in %" PRId64 " milliseconds", timeout); + GRPC_CARES_TRACE_LOG("resolver:%p retrying in %" PRId64 " milliseconds", + r, timeout); } else { - gpr_log(GPR_DEBUG, "retrying immediately"); + GRPC_CARES_TRACE_LOG("resolver:%p retrying immediately", r); } grpc_timer_init(&r->next_resolution_timer_, next_try, &r->on_next_resolution_); } - if (r->resolved_result_ != nullptr) { - grpc_channel_args_destroy(r->resolved_result_); - } - r->resolved_result_ = result; - ++r->resolved_version_; - r->MaybeFinishNextLocked(); r->Unref(DEBUG_LOCATION, "dns-resolving"); } @@ -377,17 +392,15 @@ void AresDnsResolver::MaybeStartResolvingLocked() { if (ms_until_next_resolution > 0) { const grpc_millis last_resolution_ago = grpc_core::ExecCtx::Get()->Now() - last_resolution_timestamp_; - gpr_log(GPR_DEBUG, - "In cooldown from last resolution (from %" PRId64 - " ms ago). Will resolve again in %" PRId64 " ms", - last_resolution_ago, ms_until_next_resolution); + GRPC_CARES_TRACE_LOG( + "resolver:%p In cooldown from last resolution (from %" PRId64 + " ms ago). Will resolve again in %" PRId64 " ms", + this, last_resolution_ago, ms_until_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 self = - Ref(DEBUG_LOCATION, "next_resolution_timer_cooldown"); - self.release(); + Ref(DEBUG_LOCATION, "next_resolution_timer_cooldown").release(); grpc_timer_init(&next_resolution_timer_, ms_until_next_resolution, &on_next_resolution_); return; @@ -397,33 +410,21 @@ void AresDnsResolver::MaybeStartResolvingLocked() { } 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. - RefCountedPtr self = Ref(DEBUG_LOCATION, "dns-resolving"); - self.release(); + Ref(DEBUG_LOCATION, "dns-resolving").release(); GPR_ASSERT(!resolving_); resolving_ = true; - lb_addresses_ = nullptr; service_config_json_ = nullptr; pending_request_ = grpc_dns_lookup_ares_locked( dns_server_, name_to_resolve_, kDefaultPort, interested_parties_, - &on_resolved_, &lb_addresses_, true /* check_grpclb */, - request_service_config_ ? &service_config_json_ : nullptr, combiner()); + &on_resolved_, &addresses_, enable_srv_queries_ /* check_grpclb */, + request_service_config_ ? &service_config_json_ : nullptr, + query_timeout_ms_, combiner()); last_resolution_timestamp_ = grpc_core::ExecCtx::Get()->Now(); -} - -void AresDnsResolver::MaybeFinishNextLocked() { - if (next_completion_ != nullptr && resolved_version_ != published_version_) { - *target_result_ = resolved_result_ == nullptr - ? nullptr - : grpc_channel_args_copy(resolved_result_); - gpr_log(GPR_DEBUG, "AresDnsResolver::MaybeFinishNextLocked()"); - GRPC_CLOSURE_SCHED(next_completion_, GRPC_ERROR_NONE); - next_completion_ = nullptr; - published_version_ = resolved_version_; - } + GRPC_CARES_TRACE_LOG("resolver:%p Started resolving. pending_request_:%p", + this, pending_request_); } // @@ -432,9 +433,8 @@ void AresDnsResolver::MaybeFinishNextLocked() { class AresDnsResolverFactory : public ResolverFactory { public: - OrphanablePtr CreateResolver( - const ResolverArgs& args) const override { - return OrphanablePtr(New(args)); + OrphanablePtr CreateResolver(ResolverArgs args) const override { + return OrphanablePtr(New(std::move(args))); } const char* scheme() const override { return "dns"; } @@ -457,15 +457,30 @@ static grpc_error* blocking_resolve_address_ares( static grpc_address_resolver_vtable ares_resolver = { grpc_resolve_address_ares, blocking_resolve_address_ares}; +#ifdef GRPC_UV +/* TODO(murgatroid99): Remove this when we want the cares resolver to be the + * default when using libuv */ +static bool should_use_ares(const char* resolver_env) { + return resolver_env != nullptr && gpr_stricmp(resolver_env, "ares") == 0; +} +#else /* GRPC_UV */ +static bool should_use_ares(const char* resolver_env) { + // TODO(lidiz): Remove the "g_custom_iomgr_enabled" flag once c-ares support + // custom IO managers (e.g. gevent). + return !g_custom_iomgr_enabled && + (resolver_env == nullptr || strlen(resolver_env) == 0 || + gpr_stricmp(resolver_env, "ares") == 0); +} +#endif /* GRPC_UV */ + void grpc_resolver_dns_ares_init() { char* resolver_env = gpr_getenv("GRPC_DNS_RESOLVER"); - /* TODO(zyc): Turn on c-ares based resolver by default after the address - sorter and the CNAME support are added. */ - if (resolver_env != nullptr && gpr_stricmp(resolver_env, "ares") == 0) { + if (should_use_ares(resolver_env)) { + gpr_log(GPR_DEBUG, "Using ares dns resolver"); address_sorting_init(); grpc_error* error = grpc_ares_init(); if (error != GRPC_ERROR_NONE) { - GRPC_LOG_IF_ERROR("ares_library_init() failed", error); + GRPC_LOG_IF_ERROR("grpc_ares_init() failed", error); return; } if (default_resolver == nullptr) { @@ -481,17 +496,17 @@ void grpc_resolver_dns_ares_init() { void grpc_resolver_dns_ares_shutdown() { char* resolver_env = gpr_getenv("GRPC_DNS_RESOLVER"); - if (resolver_env != nullptr && gpr_stricmp(resolver_env, "ares") == 0) { + if (should_use_ares(resolver_env)) { address_sorting_shutdown(); grpc_ares_cleanup(); } gpr_free(resolver_env); } -#else /* GRPC_ARES == 1 && !defined(GRPC_UV) */ +#else /* GRPC_ARES == 1 */ void grpc_resolver_dns_ares_init(void) {} void grpc_resolver_dns_ares_shutdown(void) {} -#endif /* GRPC_ARES == 1 && !defined(GRPC_UV) */ +#endif /* GRPC_ARES == 1 */ diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc index fdbd07ebf51..4ad80786519 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc @@ -18,7 +18,7 @@ #include #include "src/core/lib/iomgr/port.h" -#if GRPC_ARES == 1 && !defined(GRPC_UV) +#if GRPC_ARES == 1 #include #include @@ -31,8 +31,10 @@ #include #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/iomgr_internal.h" #include "src/core/lib/iomgr/sockaddr_utils.h" +#include "src/core/lib/iomgr/timer.h" typedef struct fd_node { /** the owner of this fd node */ @@ -76,21 +78,34 @@ struct grpc_ares_ev_driver { grpc_ares_request* request; /** Owned by the ev_driver. Creates new GrpcPolledFd's */ grpc_core::UniquePtr polled_fd_factory; + /** query timeout in milliseconds */ + int query_timeout_ms; + /** alarm to cancel active queries */ + grpc_timer query_timeout; + /** cancels queries on a timeout */ + grpc_closure on_timeout_locked; + /** alarm to poll ares_process on in case fd events don't happen */ + grpc_timer ares_backup_poll_alarm; + /** polls ares_process on a periodic timer */ + grpc_closure on_ares_backup_poll_alarm_locked; }; static void grpc_ares_notify_on_event_locked(grpc_ares_ev_driver* ev_driver); static grpc_ares_ev_driver* grpc_ares_ev_driver_ref( grpc_ares_ev_driver* ev_driver) { - gpr_log(GPR_DEBUG, "Ref ev_driver %" PRIuPTR, (uintptr_t)ev_driver); + GRPC_CARES_TRACE_LOG("request:%p Ref ev_driver %p", ev_driver->request, + ev_driver); gpr_ref(&ev_driver->refs); return ev_driver; } static void grpc_ares_ev_driver_unref(grpc_ares_ev_driver* ev_driver) { - gpr_log(GPR_DEBUG, "Unref ev_driver %" PRIuPTR, (uintptr_t)ev_driver); + GRPC_CARES_TRACE_LOG("request:%p Unref ev_driver %p", ev_driver->request, + ev_driver); if (gpr_unref(&ev_driver->refs)) { - gpr_log(GPR_DEBUG, "destroy ev_driver %" PRIuPTR, (uintptr_t)ev_driver); + GRPC_CARES_TRACE_LOG("request:%p destroy ev_driver %p", ev_driver->request, + ev_driver); GPR_ASSERT(ev_driver->fds == nullptr); GRPC_COMBINER_UNREF(ev_driver->combiner, "free ares event driver"); ares_destroy(ev_driver->channel); @@ -100,7 +115,8 @@ static void grpc_ares_ev_driver_unref(grpc_ares_ev_driver* ev_driver) { } static void fd_node_destroy_locked(fd_node* fdn) { - gpr_log(GPR_DEBUG, "delete fd: %s", fdn->grpc_polled_fd->GetName()); + GRPC_CARES_TRACE_LOG("request:%p delete fd: %s", fdn->ev_driver->request, + fdn->grpc_polled_fd->GetName()); GPR_ASSERT(!fdn->readable_registered); GPR_ASSERT(!fdn->writable_registered); GPR_ASSERT(fdn->already_shutdown); @@ -116,8 +132,18 @@ static void fd_node_shutdown_locked(fd_node* fdn, const char* reason) { } } +static void on_timeout_locked(void* arg, grpc_error* error); + +static void on_ares_backup_poll_alarm_locked(void* arg, grpc_error* error); + +static void noop_inject_channel_config(ares_channel channel) {} + +void (*grpc_ares_test_only_inject_config)(ares_channel channel) = + noop_inject_channel_config; + grpc_error* grpc_ares_ev_driver_create_locked(grpc_ares_ev_driver** ev_driver, grpc_pollset_set* pollset_set, + int query_timeout_ms, grpc_combiner* combiner, grpc_ares_request* request) { *ev_driver = grpc_core::New(); @@ -125,7 +151,8 @@ grpc_error* grpc_ares_ev_driver_create_locked(grpc_ares_ev_driver** ev_driver, memset(&opts, 0, sizeof(opts)); opts.flags |= ARES_FLAG_STAYOPEN; int status = ares_init_options(&(*ev_driver)->channel, &opts, ARES_OPT_FLAGS); - gpr_log(GPR_DEBUG, "grpc_ares_ev_driver_create_locked"); + grpc_ares_test_only_inject_config((*ev_driver)->channel); + GRPC_CARES_TRACE_LOG("request:%p grpc_ares_ev_driver_create_locked", request); if (status != ARES_SUCCESS) { char* err_msg; gpr_asprintf(&err_msg, "Failed to init ares channel. C-ares error: %s", @@ -146,6 +173,12 @@ grpc_error* grpc_ares_ev_driver_create_locked(grpc_ares_ev_driver** ev_driver, grpc_core::NewGrpcPolledFdFactory((*ev_driver)->combiner); (*ev_driver) ->polled_fd_factory->ConfigureAresChannelLocked((*ev_driver)->channel); + GRPC_CLOSURE_INIT(&(*ev_driver)->on_timeout_locked, on_timeout_locked, + *ev_driver, grpc_combiner_scheduler(combiner)); + GRPC_CLOSURE_INIT(&(*ev_driver)->on_ares_backup_poll_alarm_locked, + on_ares_backup_poll_alarm_locked, *ev_driver, + grpc_combiner_scheduler(combiner)); + (*ev_driver)->query_timeout_ms = query_timeout_ms; return GRPC_ERROR_NONE; } @@ -155,6 +188,8 @@ void grpc_ares_ev_driver_on_queries_complete_locked( // is working, grpc_ares_notify_on_event_locked will shut down the // fds; if it's not working, there are no fds to shut down. ev_driver->shutting_down = true; + grpc_timer_cancel(&ev_driver->query_timeout); + grpc_timer_cancel(&ev_driver->ares_backup_poll_alarm); grpc_ares_ev_driver_unref(ev_driver); } @@ -185,12 +220,82 @@ static fd_node* pop_fd_node_locked(fd_node** head, ares_socket_t as) { return nullptr; } +static grpc_millis calculate_next_ares_backup_poll_alarm_ms( + grpc_ares_ev_driver* driver) { + // An alternative here could be to use ares_timeout to try to be more + // accurate, but that would require using "struct timeval"'s, which just makes + // things a bit more complicated. So just poll every second, as suggested + // by the c-ares code comments. + grpc_millis ms_until_next_ares_backup_poll_alarm = 1000; + GRPC_CARES_TRACE_LOG( + "request:%p ev_driver=%p. next ares process poll time in " + "%" PRId64 " ms", + driver->request, driver, ms_until_next_ares_backup_poll_alarm); + return ms_until_next_ares_backup_poll_alarm + + grpc_core::ExecCtx::Get()->Now(); +} + +static void on_timeout_locked(void* arg, grpc_error* error) { + grpc_ares_ev_driver* driver = static_cast(arg); + GRPC_CARES_TRACE_LOG( + "request:%p ev_driver=%p on_timeout_locked. driver->shutting_down=%d. " + "err=%s", + driver->request, driver, driver->shutting_down, grpc_error_string(error)); + if (!driver->shutting_down && error == GRPC_ERROR_NONE) { + grpc_ares_ev_driver_shutdown_locked(driver); + } + grpc_ares_ev_driver_unref(driver); +} + +/* In case of non-responsive DNS servers, dropped packets, etc., c-ares has + * intelligent timeout and retry logic, which we can take advantage of by + * polling ares_process_fd on time intervals. Overall, the c-ares library is + * meant to be called into and given a chance to proceed name resolution: + * a) when fd events happen + * b) when some time has passed without fd events having happened + * For the latter, we use this backup poller. Also see + * https://github.com/grpc/grpc/pull/17688 description for more details. */ +static void on_ares_backup_poll_alarm_locked(void* arg, grpc_error* error) { + grpc_ares_ev_driver* driver = static_cast(arg); + GRPC_CARES_TRACE_LOG( + "request:%p ev_driver=%p on_ares_backup_poll_alarm_locked. " + "driver->shutting_down=%d. " + "err=%s", + driver->request, driver, driver->shutting_down, grpc_error_string(error)); + if (!driver->shutting_down && error == GRPC_ERROR_NONE) { + fd_node* fdn = driver->fds; + while (fdn != nullptr) { + if (!fdn->already_shutdown) { + GRPC_CARES_TRACE_LOG( + "request:%p ev_driver=%p on_ares_backup_poll_alarm_locked; " + "ares_process_fd. fd=%s", + driver->request, driver, fdn->grpc_polled_fd->GetName()); + ares_socket_t as = fdn->grpc_polled_fd->GetWrappedAresSocketLocked(); + ares_process_fd(driver->channel, as, as); + } + fdn = fdn->next; + } + if (!driver->shutting_down) { + grpc_millis next_ares_backup_poll_alarm = + calculate_next_ares_backup_poll_alarm_ms(driver); + grpc_ares_ev_driver_ref(driver); + grpc_timer_init(&driver->ares_backup_poll_alarm, + next_ares_backup_poll_alarm, + &driver->on_ares_backup_poll_alarm_locked); + } + grpc_ares_notify_on_event_locked(driver); + } + grpc_ares_ev_driver_unref(driver); +} + static void on_readable_locked(void* arg, grpc_error* error) { fd_node* fdn = static_cast(arg); + GPR_ASSERT(fdn->readable_registered); grpc_ares_ev_driver* ev_driver = fdn->ev_driver; const ares_socket_t as = fdn->grpc_polled_fd->GetWrappedAresSocketLocked(); fdn->readable_registered = false; - gpr_log(GPR_DEBUG, "readable on %s", fdn->grpc_polled_fd->GetName()); + GRPC_CARES_TRACE_LOG("request:%p readable on %s", fdn->ev_driver->request, + fdn->grpc_polled_fd->GetName()); if (error == GRPC_ERROR_NONE) { do { ares_process_fd(ev_driver->channel, as, ARES_SOCKET_BAD); @@ -210,10 +315,12 @@ static void on_readable_locked(void* arg, grpc_error* error) { static void on_writable_locked(void* arg, grpc_error* error) { fd_node* fdn = static_cast(arg); + GPR_ASSERT(fdn->writable_registered); grpc_ares_ev_driver* ev_driver = fdn->ev_driver; const ares_socket_t as = fdn->grpc_polled_fd->GetWrappedAresSocketLocked(); fdn->writable_registered = false; - gpr_log(GPR_DEBUG, "writable on %s", fdn->grpc_polled_fd->GetName()); + GRPC_CARES_TRACE_LOG("request:%p writable on %s", ev_driver->request, + fdn->grpc_polled_fd->GetName()); if (error == GRPC_ERROR_NONE) { ares_process_fd(ev_driver->channel, ARES_SOCKET_BAD, as); } else { @@ -252,7 +359,8 @@ static void grpc_ares_notify_on_event_locked(grpc_ares_ev_driver* ev_driver) { fdn->grpc_polled_fd = ev_driver->polled_fd_factory->NewGrpcPolledFdLocked( socks[i], ev_driver->pollset_set, ev_driver->combiner); - gpr_log(GPR_DEBUG, "new fd: %s", fdn->grpc_polled_fd->GetName()); + GRPC_CARES_TRACE_LOG("request:%p new fd: %s", ev_driver->request, + fdn->grpc_polled_fd->GetName()); fdn->ev_driver = ev_driver; fdn->readable_registered = false; fdn->writable_registered = false; @@ -269,8 +377,9 @@ static void grpc_ares_notify_on_event_locked(grpc_ares_ev_driver* ev_driver) { if (ARES_GETSOCK_READABLE(socks_bitmask, i) && !fdn->readable_registered) { grpc_ares_ev_driver_ref(ev_driver); - gpr_log(GPR_DEBUG, "notify read on: %s", - fdn->grpc_polled_fd->GetName()); + GRPC_CARES_TRACE_LOG("request:%p notify read on: %s", + ev_driver->request, + fdn->grpc_polled_fd->GetName()); fdn->grpc_polled_fd->RegisterForOnReadableLocked(&fdn->read_closure); fdn->readable_registered = true; } @@ -278,8 +387,9 @@ static void grpc_ares_notify_on_event_locked(grpc_ares_ev_driver* ev_driver) { // has not been registered with this socket. if (ARES_GETSOCK_WRITABLE(socks_bitmask, i) && !fdn->writable_registered) { - gpr_log(GPR_DEBUG, "notify write on: %s", - fdn->grpc_polled_fd->GetName()); + GRPC_CARES_TRACE_LOG("request:%p notify write on: %s", + ev_driver->request, + fdn->grpc_polled_fd->GetName()); grpc_ares_ev_driver_ref(ev_driver); fdn->grpc_polled_fd->RegisterForOnWriteableLocked( &fdn->write_closure); @@ -306,7 +416,8 @@ static void grpc_ares_notify_on_event_locked(grpc_ares_ev_driver* ev_driver) { // If the ev driver has no working fd, all the tasks are done. if (new_list == nullptr) { ev_driver->working = false; - gpr_log(GPR_DEBUG, "ev driver stop working"); + GRPC_CARES_TRACE_LOG("request:%p ev driver stop working", + ev_driver->request); } } @@ -314,7 +425,26 @@ void grpc_ares_ev_driver_start_locked(grpc_ares_ev_driver* ev_driver) { if (!ev_driver->working) { ev_driver->working = true; grpc_ares_notify_on_event_locked(ev_driver); + // Initialize overall DNS resolution timeout alarm + grpc_millis timeout = + ev_driver->query_timeout_ms == 0 + ? GRPC_MILLIS_INF_FUTURE + : ev_driver->query_timeout_ms + grpc_core::ExecCtx::Get()->Now(); + GRPC_CARES_TRACE_LOG( + "request:%p ev_driver=%p grpc_ares_ev_driver_start_locked. timeout in " + "%" PRId64 " ms", + ev_driver->request, ev_driver, timeout); + grpc_ares_ev_driver_ref(ev_driver); + grpc_timer_init(&ev_driver->query_timeout, timeout, + &ev_driver->on_timeout_locked); + // Initialize the backup poll alarm + grpc_millis next_ares_backup_poll_alarm = + calculate_next_ares_backup_poll_alarm_ms(ev_driver); + grpc_ares_ev_driver_ref(ev_driver); + grpc_timer_init(&ev_driver->ares_backup_poll_alarm, + next_ares_backup_poll_alarm, + &ev_driver->on_ares_backup_poll_alarm_locked); } } -#endif /* GRPC_ARES == 1 && !defined(GRPC_UV) */ +#endif /* GRPC_ARES == 1 */ diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h index 671c537fe72..2d172eb3d1e 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h @@ -43,6 +43,7 @@ ares_channel* grpc_ares_ev_driver_get_channel_locked( created successfully. */ grpc_error* grpc_ares_ev_driver_create_locked(grpc_ares_ev_driver** ev_driver, grpc_pollset_set* pollset_set, + int query_timeout_ms, grpc_combiner* combiner, grpc_ares_request* request); @@ -53,6 +54,9 @@ void grpc_ares_ev_driver_on_queries_complete_locked( /* Shutdown all the grpc_fds used by \a ev_driver */ void grpc_ares_ev_driver_shutdown_locked(grpc_ares_ev_driver* ev_driver); +/* Exposed in this header for C-core tests only */ +extern void (*grpc_ares_test_only_inject_config)(ares_channel channel); + namespace grpc_core { /* A wrapped fd that integrates with the grpc iomgr of the current platform. diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc new file mode 100644 index 00000000000..04e36fbcee7 --- /dev/null +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc @@ -0,0 +1,179 @@ +/* + * + * Copyright 2019 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 + +#include "src/core/lib/iomgr/port.h" +#if GRPC_ARES == 1 && defined(GRPC_UV) + +#include +#include + +#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h" + +#include +#include +#include +#include +#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/iomgr/combiner.h" + +namespace grpc_core { + +void ares_uv_poll_cb(uv_poll_t* handle, int status, int events); + +void ares_uv_poll_close_cb(uv_handle_t* handle) { Delete(handle); } + +class GrpcPolledFdLibuv : public GrpcPolledFd { + public: + GrpcPolledFdLibuv(ares_socket_t as, grpc_combiner* combiner) + : as_(as), combiner_(combiner) { + gpr_asprintf(&name_, "c-ares socket: %" PRIdPTR, (intptr_t)as); + handle_ = New(); + uv_poll_init_socket(uv_default_loop(), handle_, as); + handle_->data = this; + GRPC_COMBINER_REF(combiner_, "libuv ares event driver"); + } + + ~GrpcPolledFdLibuv() { + gpr_free(name_); + GRPC_COMBINER_UNREF(combiner_, "libuv ares event driver"); + } + + void RegisterForOnReadableLocked(grpc_closure* read_closure) override { + GPR_ASSERT(read_closure_ == nullptr); + GPR_ASSERT((poll_events_ & UV_READABLE) == 0); + read_closure_ = read_closure; + poll_events_ |= UV_READABLE; + uv_poll_start(handle_, poll_events_, ares_uv_poll_cb); + } + + void RegisterForOnWriteableLocked(grpc_closure* write_closure) override { + GPR_ASSERT(write_closure_ == nullptr); + GPR_ASSERT((poll_events_ & UV_WRITABLE) == 0); + write_closure_ = write_closure; + poll_events_ |= UV_WRITABLE; + uv_poll_start(handle_, poll_events_, ares_uv_poll_cb); + } + + bool IsFdStillReadableLocked() override { + /* uv_poll_t is based on poll, which is level triggered. So, if cares + * leaves some data unread, the event will trigger again. */ + return false; + } + + void ShutdownInternalLocked(grpc_error* error) { + uv_poll_stop(handle_); + uv_close(reinterpret_cast(handle_), ares_uv_poll_close_cb); + if (read_closure_ != nullptr) { + GRPC_CLOSURE_SCHED(read_closure_, GRPC_ERROR_CANCELLED); + } + if (write_closure_ != nullptr) { + GRPC_CLOSURE_SCHED(write_closure_, GRPC_ERROR_CANCELLED); + } + } + + void ShutdownLocked(grpc_error* error) override { + if (grpc_core::ExecCtx::Get() == nullptr) { + grpc_core::ExecCtx exec_ctx; + ShutdownInternalLocked(error); + } else { + ShutdownInternalLocked(error); + } + } + + ares_socket_t GetWrappedAresSocketLocked() override { return as_; } + + const char* GetName() override { return name_; } + + char* name_; + ares_socket_t as_; + uv_poll_t* handle_; + grpc_closure* read_closure_ = nullptr; + grpc_closure* write_closure_ = nullptr; + int poll_events_ = 0; + grpc_combiner* combiner_; +}; + +struct AresUvPollCbArg { + AresUvPollCbArg(uv_poll_t* handle, int status, int events) + : handle(handle), status(status), events(events) {} + + uv_poll_t* handle; + int status; + int events; +}; + +static void ares_uv_poll_cb_locked(void* arg, grpc_error* error) { + grpc_core::UniquePtr arg_struct( + reinterpret_cast(arg)); + uv_poll_t* handle = arg_struct->handle; + int status = arg_struct->status; + int events = arg_struct->events; + GrpcPolledFdLibuv* polled_fd = + reinterpret_cast(handle->data); + if (status < 0) { + error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("cares polling error"); + error = + grpc_error_set_str(error, GRPC_ERROR_STR_OS_ERROR, + grpc_slice_from_static_string(uv_strerror(status))); + } + if (events & UV_READABLE) { + GPR_ASSERT(polled_fd->read_closure_ != nullptr); + GRPC_CLOSURE_SCHED(polled_fd->read_closure_, error); + polled_fd->read_closure_ = nullptr; + polled_fd->poll_events_ &= ~UV_READABLE; + } + if (events & UV_WRITABLE) { + GPR_ASSERT(polled_fd->write_closure_ != nullptr); + GRPC_CLOSURE_SCHED(polled_fd->write_closure_, error); + polled_fd->write_closure_ = nullptr; + polled_fd->poll_events_ &= ~UV_WRITABLE; + } + uv_poll_start(handle, polled_fd->poll_events_, ares_uv_poll_cb); +} + +void ares_uv_poll_cb(uv_poll_t* handle, int status, int events) { + grpc_core::ExecCtx exec_ctx; + GrpcPolledFdLibuv* polled_fd = + reinterpret_cast(handle->data); + AresUvPollCbArg* arg = New(handle, status, events); + GRPC_CLOSURE_SCHED( + GRPC_CLOSURE_CREATE(ares_uv_poll_cb_locked, arg, + grpc_combiner_scheduler(polled_fd->combiner_)), + GRPC_ERROR_NONE); +} + +class GrpcPolledFdFactoryLibuv : public GrpcPolledFdFactory { + public: + GrpcPolledFd* NewGrpcPolledFdLocked(ares_socket_t as, + grpc_pollset_set* driver_pollset_set, + grpc_combiner* combiner) override { + return New(as, combiner); + } + + void ConfigureAresChannelLocked(ares_channel channel) override {} +}; + +UniquePtr NewGrpcPolledFdFactory(grpc_combiner* combiner) { + return UniquePtr(New()); +} + +} // namespace grpc_core + +#endif /* GRPC_ARES == 1 && defined(GRPC_UV) */ diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc index 02121aa0ab4..ce39007f905 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc @@ -109,6 +109,7 @@ class GrpcPolledFdWindows : public GrpcPolledFd { read_closure_ = read_closure; GPR_ASSERT(GRPC_SLICE_LENGTH(read_buf_) == 0); grpc_slice_unref_internal(read_buf_); + GPR_ASSERT(!read_buf_has_data_); read_buf_ = GRPC_SLICE_MALLOC(4192); WSABUF buffer; buffer.buf = (char*)GRPC_SLICE_START_PTR(read_buf_); @@ -120,13 +121,14 @@ class GrpcPolledFdWindows : public GrpcPolledFd { nullptr, &flags, (sockaddr*)recv_from_source_addr_, &recv_from_source_addr_len_, &winsocket_->read_info.overlapped, nullptr)) { - char* msg = gpr_format_message(WSAGetLastError()); + int wsa_last_error = WSAGetLastError(); + char* msg = gpr_format_message(wsa_last_error); grpc_error* error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); GRPC_CARES_TRACE_LOG( "RegisterForOnReadableLocked: WSARecvFrom error:|%s|. fd:|%s|", msg, GetName()); gpr_free(msg); - if (WSAGetLastError() != WSA_IO_PENDING) { + if (wsa_last_error != WSA_IO_PENDING) { ScheduleAndNullReadClosure(error); return; } @@ -174,7 +176,7 @@ class GrpcPolledFdWindows : public GrpcPolledFd { GRPC_CARES_TRACE_LOG( "RecvFrom called on fd:|%s|. Current read buf length:|%d|", GetName(), GRPC_SLICE_LENGTH(read_buf_)); - if (GRPC_SLICE_LENGTH(read_buf_) == 0) { + if (!read_buf_has_data_) { WSASetLastError(WSAEWOULDBLOCK); return -1; } @@ -185,6 +187,9 @@ class GrpcPolledFdWindows : public GrpcPolledFd { } read_buf_ = grpc_slice_sub_no_ref(read_buf_, bytes_read, GRPC_SLICE_LENGTH(read_buf_)); + if (GRPC_SLICE_LENGTH(read_buf_) == 0) { + read_buf_has_data_ = false; + } /* c-ares overloads this recv_from virtual socket function to receive * data on both UDP and TCP sockets, and from is nullptr for TCP. */ if (from != nullptr) { @@ -229,12 +234,13 @@ class GrpcPolledFdWindows : public GrpcPolledFd { ares_ssize_t total_sent; DWORD bytes_sent = 0; if (SendWriteBuf(&bytes_sent, nullptr) != 0) { - char* msg = gpr_format_message(WSAGetLastError()); + int wsa_last_error = WSAGetLastError(); + char* msg = gpr_format_message(wsa_last_error); GRPC_CARES_TRACE_LOG( "TrySendWriteBufSyncNonBlocking: SendWriteBuf error:|%s|. fd:|%s|", msg, GetName()); gpr_free(msg); - if (WSAGetLastError() == WSA_IO_PENDING) { + if (wsa_last_error == WSA_IO_PENDING) { WSASetLastError(WSAEWOULDBLOCK); write_state_ = WRITE_REQUESTED; } @@ -284,9 +290,10 @@ class GrpcPolledFdWindows : public GrpcPolledFd { int out = WSAConnect(s, target, target_len, nullptr, nullptr, nullptr, nullptr); if (out != 0) { - char* msg = gpr_format_message(WSAGetLastError()); + int wsa_last_error = WSAGetLastError(); + char* msg = gpr_format_message(wsa_last_error); GRPC_CARES_TRACE_LOG("Connect error code:|%d|, msg:|%s|. fd:|%s|", - WSAGetLastError(), msg, GetName()); + wsa_last_error, msg, GetName()); gpr_free(msg); // c-ares expects a posix-style connect API out = -1; @@ -299,6 +306,11 @@ class GrpcPolledFdWindows : public GrpcPolledFd { polled_fd->OnIocpReadableInner(error); } + // TODO(apolcyn): improve this error handling to be less conversative. + // An e.g. ECONNRESET error here should result in errors when + // c-ares reads from this socket later, but it shouldn't necessarily cancel + // the entire resolution attempt. Doing so will allow the "inject broken + // nameserver list" test to pass on Windows. void OnIocpReadableInner(grpc_error* error) { if (error == GRPC_ERROR_NONE) { if (winsocket_->read_info.wsa_error != 0) { @@ -320,6 +332,7 @@ class GrpcPolledFdWindows : public GrpcPolledFd { if (error == GRPC_ERROR_NONE) { read_buf_ = grpc_slice_sub_no_ref(read_buf_, 0, winsocket_->read_info.bytes_transfered); + read_buf_has_data_ = true; } else { grpc_slice_unref_internal(read_buf_); read_buf_ = grpc_empty_slice(); @@ -367,6 +380,7 @@ class GrpcPolledFdWindows : public GrpcPolledFd { char recv_from_source_addr_[200]; ares_socklen_t recv_from_source_addr_len_; grpc_slice read_buf_; + bool read_buf_has_data_ = false; grpc_slice write_buf_; grpc_closure* read_closure_ = nullptr; grpc_closure* write_closure_ = nullptr; @@ -442,7 +456,8 @@ class SockToPolledFdMap { */ static ares_socket_t Socket(int af, int type, int protocol, void* user_data) { SockToPolledFdMap* map = static_cast(user_data); - SOCKET s = WSASocket(af, type, protocol, nullptr, 0, WSA_FLAG_OVERLAPPED); + SOCKET s = WSASocket(af, type, protocol, nullptr, 0, + grpc_get_default_wsa_socket_flags()); if (s == INVALID_SOCKET) { return s; } 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 582e2203fc7..0f04f14fd8a 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 @@ -18,7 +18,7 @@ #include -#if GRPC_ARES == 1 && !defined(GRPC_UV) +#if GRPC_ARES == 1 #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" #include "src/core/lib/iomgr/sockaddr.h" @@ -37,14 +37,15 @@ #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h" #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/error.h" #include "src/core/lib/iomgr/executor.h" #include "src/core/lib/iomgr/iomgr_internal.h" #include "src/core/lib/iomgr/nameser.h" #include "src/core/lib/iomgr/sockaddr_utils.h" -static gpr_once g_basic_init = GPR_ONCE_INIT; -static gpr_mu g_init_mu; +using grpc_core::ServerAddress; +using grpc_core::ServerAddressList; grpc_core::TraceFlag grpc_trace_cares_address_sorting(false, "cares_address_sorting"); @@ -58,7 +59,7 @@ struct grpc_ares_request { /** closure to call when the request completes */ grpc_closure* on_done; /** the pointer to receive the resolved addresses */ - grpc_lb_addresses** lb_addrs_out; + grpc_core::UniquePtr* addresses_out; /** the pointer to receive the service config in JSON */ char** service_config_json_out; /** the evernt driver used by this request */ @@ -66,9 +67,7 @@ struct grpc_ares_request { /** number of ongoing queries */ size_t pending_queries; - /** is there at least one successful query, set in on_done_cb */ - bool success; - /** the errors explaining the request failure, set in on_done_cb */ + /** the errors explaining query failures, appended to in query callbacks */ grpc_error* error; }; @@ -85,48 +84,44 @@ typedef struct grpc_ares_hostbyname_request { bool is_balancer; } grpc_ares_hostbyname_request; -static void do_basic_init(void) { gpr_mu_init(&g_init_mu); } - -static void log_address_sorting_list(grpc_lb_addresses* lb_addrs, +static void log_address_sorting_list(const ServerAddressList& addresses, const char* input_output_str) { - for (size_t i = 0; i < lb_addrs->num_addresses; i++) { + for (size_t i = 0; i < addresses.size(); i++) { char* addr_str; - if (grpc_sockaddr_to_string(&addr_str, &lb_addrs->addresses[i].address, - true)) { - gpr_log(GPR_DEBUG, "c-ares address sorting: %s[%" PRIuPTR "]=%s", + if (grpc_sockaddr_to_string(&addr_str, &addresses[i].address(), true)) { + gpr_log(GPR_INFO, "c-ares address sorting: %s[%" PRIuPTR "]=%s", input_output_str, i, addr_str); gpr_free(addr_str); } else { - gpr_log(GPR_DEBUG, + gpr_log(GPR_INFO, "c-ares address sorting: %s[%" PRIuPTR "]=", input_output_str, i); } } } -void grpc_cares_wrapper_address_sorting_sort(grpc_lb_addresses* lb_addrs) { - if (grpc_trace_cares_address_sorting.enabled()) { - log_address_sorting_list(lb_addrs, "input"); +void grpc_cares_wrapper_address_sorting_sort(ServerAddressList* addresses) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_trace_cares_address_sorting)) { + log_address_sorting_list(*addresses, "input"); } address_sorting_sortable* sortables = (address_sorting_sortable*)gpr_zalloc( - sizeof(address_sorting_sortable) * lb_addrs->num_addresses); - for (size_t i = 0; i < lb_addrs->num_addresses; i++) { - sortables[i].user_data = &lb_addrs->addresses[i]; - memcpy(&sortables[i].dest_addr.addr, &lb_addrs->addresses[i].address.addr, - lb_addrs->addresses[i].address.len); - sortables[i].dest_addr.len = lb_addrs->addresses[i].address.len; + sizeof(address_sorting_sortable) * addresses->size()); + for (size_t i = 0; i < addresses->size(); ++i) { + sortables[i].user_data = &(*addresses)[i]; + memcpy(&sortables[i].dest_addr.addr, &(*addresses)[i].address().addr, + (*addresses)[i].address().len); + sortables[i].dest_addr.len = (*addresses)[i].address().len; } - address_sorting_rfc_6724_sort(sortables, lb_addrs->num_addresses); - grpc_lb_address* sorted_lb_addrs = (grpc_lb_address*)gpr_zalloc( - sizeof(grpc_lb_address) * lb_addrs->num_addresses); - for (size_t i = 0; i < lb_addrs->num_addresses; i++) { - sorted_lb_addrs[i] = *(grpc_lb_address*)sortables[i].user_data; + address_sorting_rfc_6724_sort(sortables, addresses->size()); + ServerAddressList sorted; + sorted.reserve(addresses->size()); + for (size_t i = 0; i < addresses->size(); ++i) { + sorted.emplace_back(*static_cast(sortables[i].user_data)); } gpr_free(sortables); - gpr_free(lb_addrs->addresses); - lb_addrs->addresses = sorted_lb_addrs; - if (grpc_trace_cares_address_sorting.enabled()) { - log_address_sorting_list(lb_addrs, "output"); + *addresses = std::move(sorted); + if (GRPC_TRACE_FLAG_ENABLED(grpc_trace_cares_address_sorting)) { + log_address_sorting_list(*addresses, "output"); } } @@ -145,9 +140,13 @@ void grpc_ares_complete_request_locked(grpc_ares_request* r) { /* Invoke on_done callback and destroy the request */ r->ev_driver = nullptr; - grpc_lb_addresses* lb_addrs = *(r->lb_addrs_out); - if (lb_addrs != nullptr) { - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + ServerAddressList* addresses = r->addresses_out->get(); + if (addresses != nullptr) { + grpc_cares_wrapper_address_sorting_sort(addresses); + GRPC_ERROR_UNREF(r->error); + r->error = GRPC_ERROR_NONE; + // TODO(apolcyn): allow c-ares to return a service config + // with no addresses along side it } GRPC_CLOSURE_SCHED(r->on_done, r->error); } @@ -155,6 +154,10 @@ void grpc_ares_complete_request_locked(grpc_ares_request* r) { static grpc_ares_hostbyname_request* create_hostbyname_request_locked( grpc_ares_request* parent_request, char* host, uint16_t port, bool is_balancer) { + GRPC_CARES_TRACE_LOG( + "request:%p create_hostbyname_request_locked host:%s port:%d " + "is_balancer:%d", + parent_request, host, port, is_balancer); grpc_ares_hostbyname_request* hr = static_cast( gpr_zalloc(sizeof(grpc_ares_hostbyname_request))); hr->parent_request = parent_request; @@ -178,78 +181,69 @@ static void on_hostbyname_done_locked(void* arg, int status, int timeouts, static_cast(arg); grpc_ares_request* r = hr->parent_request; if (status == ARES_SUCCESS) { - GRPC_ERROR_UNREF(r->error); - r->error = GRPC_ERROR_NONE; - r->success = true; - grpc_lb_addresses** lb_addresses = r->lb_addrs_out; - if (*lb_addresses == nullptr) { - *lb_addresses = grpc_lb_addresses_create(0, nullptr); + GRPC_CARES_TRACE_LOG( + "request:%p on_hostbyname_done_locked host=%s ARES_SUCCESS", r, + hr->host); + if (*r->addresses_out == nullptr) { + *r->addresses_out = grpc_core::MakeUnique(); } - size_t prev_naddr = (*lb_addresses)->num_addresses; - size_t i; - for (i = 0; hostent->h_addr_list[i] != nullptr; i++) { - } - (*lb_addresses)->num_addresses += i; - (*lb_addresses)->addresses = static_cast( - gpr_realloc((*lb_addresses)->addresses, - sizeof(grpc_lb_address) * (*lb_addresses)->num_addresses)); - for (i = prev_naddr; i < (*lb_addresses)->num_addresses; i++) { + ServerAddressList& addresses = **r->addresses_out; + for (size_t i = 0; hostent->h_addr_list[i] != nullptr; ++i) { + grpc_core::InlinedVector args_to_add; + if (hr->is_balancer) { + args_to_add.emplace_back(grpc_channel_arg_integer_create( + const_cast(GRPC_ARG_ADDRESS_IS_BALANCER), 1)); + args_to_add.emplace_back(grpc_channel_arg_string_create( + const_cast(GRPC_ARG_ADDRESS_BALANCER_NAME), hr->host)); + } + grpc_channel_args* args = grpc_channel_args_copy_and_add( + nullptr, args_to_add.data(), args_to_add.size()); switch (hostent->h_addrtype) { case AF_INET6: { size_t addr_len = sizeof(struct sockaddr_in6); struct sockaddr_in6 addr; memset(&addr, 0, addr_len); - memcpy(&addr.sin6_addr, hostent->h_addr_list[i - prev_naddr], + memcpy(&addr.sin6_addr, hostent->h_addr_list[i], sizeof(struct in6_addr)); addr.sin6_family = static_cast(hostent->h_addrtype); addr.sin6_port = hr->port; - grpc_lb_addresses_set_address( - *lb_addresses, i, &addr, addr_len, - hr->is_balancer /* is_balancer */, - hr->is_balancer ? hr->host : nullptr /* balancer_name */, - nullptr /* user_data */); + addresses.emplace_back(&addr, addr_len, args); char output[INET6_ADDRSTRLEN]; ares_inet_ntop(AF_INET6, &addr.sin6_addr, output, INET6_ADDRSTRLEN); - gpr_log(GPR_DEBUG, - "c-ares resolver gets a AF_INET6 result: \n" - " addr: %s\n port: %d\n sin6_scope_id: %d\n", - output, ntohs(hr->port), addr.sin6_scope_id); + GRPC_CARES_TRACE_LOG( + "request:%p c-ares resolver gets a AF_INET6 result: \n" + " addr: %s\n port: %d\n sin6_scope_id: %d\n", + r, output, ntohs(hr->port), addr.sin6_scope_id); break; } case AF_INET: { size_t addr_len = sizeof(struct sockaddr_in); struct sockaddr_in addr; memset(&addr, 0, addr_len); - memcpy(&addr.sin_addr, hostent->h_addr_list[i - prev_naddr], + memcpy(&addr.sin_addr, hostent->h_addr_list[i], sizeof(struct in_addr)); addr.sin_family = static_cast(hostent->h_addrtype); addr.sin_port = hr->port; - grpc_lb_addresses_set_address( - *lb_addresses, i, &addr, addr_len, - hr->is_balancer /* is_balancer */, - hr->is_balancer ? hr->host : nullptr /* balancer_name */, - nullptr /* user_data */); + addresses.emplace_back(&addr, addr_len, args); char output[INET_ADDRSTRLEN]; ares_inet_ntop(AF_INET, &addr.sin_addr, output, INET_ADDRSTRLEN); - gpr_log(GPR_DEBUG, - "c-ares resolver gets a AF_INET result: \n" - " addr: %s\n port: %d\n", - output, ntohs(hr->port)); + GRPC_CARES_TRACE_LOG( + "request:%p c-ares resolver gets a AF_INET result: \n" + " addr: %s\n port: %d\n", + r, output, ntohs(hr->port)); break; } } } - } else if (!r->success) { + } else { char* error_msg; gpr_asprintf(&error_msg, "C-ares status is not ARES_SUCCESS: %s", ares_strerror(status)); + GRPC_CARES_TRACE_LOG("request:%p on_hostbyname_done_locked host=%s %s", r, + hr->host, error_msg); grpc_error* error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg); gpr_free(error_msg); - if (r->error == GRPC_ERROR_NONE) { - r->error = error; - } else { - r->error = grpc_error_add_child(error, r->error); - } + r->error = grpc_error_add_child(error, r->error); } destroy_hostbyname_request_locked(hr); } @@ -257,11 +251,12 @@ static void on_hostbyname_done_locked(void* arg, int status, int timeouts, static void on_srv_query_done_locked(void* arg, int status, int timeouts, unsigned char* abuf, int alen) { grpc_ares_request* r = static_cast(arg); - gpr_log(GPR_DEBUG, "on_query_srv_done_locked"); if (status == ARES_SUCCESS) { - gpr_log(GPR_DEBUG, "on_query_srv_done_locked ARES_SUCCESS"); + GRPC_CARES_TRACE_LOG("request:%p on_srv_query_done_locked ARES_SUCCESS", r); struct ares_srv_reply* reply; const int parse_status = ares_parse_srv_reply(abuf, alen, &reply); + GRPC_CARES_TRACE_LOG("request:%p ares_parse_srv_reply: %d", r, + parse_status); if (parse_status == ARES_SUCCESS) { ares_channel* channel = grpc_ares_ev_driver_get_channel_locked(r->ev_driver); @@ -283,17 +278,15 @@ static void on_srv_query_done_locked(void* arg, int status, int timeouts, if (reply != nullptr) { ares_free_data(reply); } - } else if (!r->success) { + } else { char* error_msg; gpr_asprintf(&error_msg, "C-ares status is not ARES_SUCCESS: %s", ares_strerror(status)); + GRPC_CARES_TRACE_LOG("request:%p on_srv_query_done_locked %s", r, + error_msg); grpc_error* error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg); gpr_free(error_msg); - if (r->error == GRPC_ERROR_NONE) { - r->error = error; - } else { - r->error = grpc_error_add_child(error, r->error); - } + r->error = grpc_error_add_child(error, r->error); } grpc_ares_request_unref_locked(r); } @@ -302,7 +295,6 @@ static const char g_service_config_attribute_prefix[] = "grpc_config="; static void on_txt_done_locked(void* arg, int status, int timeouts, unsigned char* buf, int len) { - gpr_log(GPR_DEBUG, "on_txt_done_locked"); char* error_msg; grpc_ares_request* r = static_cast(arg); const size_t prefix_len = sizeof(g_service_config_attribute_prefix) - 1; @@ -310,6 +302,7 @@ static void on_txt_done_locked(void* arg, int status, int timeouts, struct ares_txt_ext* reply = nullptr; grpc_error* error = GRPC_ERROR_NONE; if (status != ARES_SUCCESS) goto fail; + GRPC_CARES_TRACE_LOG("request:%p on_txt_done_locked ARES_SUCCESS", r); status = ares_parse_txt_reply_ext(buf, len, &reply); if (status != ARES_SUCCESS) goto fail; // Find service config in TXT record. @@ -337,7 +330,8 @@ static void on_txt_done_locked(void* arg, int status, int timeouts, service_config_len += result->length; } (*r->service_config_json_out)[service_config_len] = '\0'; - gpr_log(GPR_INFO, "found service config: %s", *r->service_config_json_out); + GRPC_CARES_TRACE_LOG("request:%p found service config: %s", r, + *r->service_config_json_out); } // Clean up. ares_free_data(reply); @@ -346,12 +340,9 @@ fail: gpr_asprintf(&error_msg, "C-ares TXT lookup status is not ARES_SUCCESS: %s", ares_strerror(status)); error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg); + GRPC_CARES_TRACE_LOG("request:%p on_txt_done_locked %s", r, error_msg); gpr_free(error_msg); - if (r->error == GRPC_ERROR_NONE) { - r->error = error; - } else { - r->error = grpc_error_add_child(error, r->error); - } + r->error = grpc_error_add_child(error, r->error); done: grpc_ares_request_unref_locked(r); } @@ -359,16 +350,10 @@ done: void grpc_dns_lookup_ares_continue_after_check_localhost_and_ip_literals_locked( grpc_ares_request* r, const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, - bool check_grpclb, grpc_combiner* combiner) { + bool check_grpclb, int query_timeout_ms, grpc_combiner* combiner) { grpc_error* error = GRPC_ERROR_NONE; grpc_ares_hostbyname_request* hr = nullptr; ares_channel* channel = nullptr; - /* TODO(zyc): Enable tracing after #9603 is checked in */ - /* if (grpc_dns_trace) { - gpr_log(GPR_DEBUG, "resolve_address (blocking): name=%s, default_port=%s", - name, default_port); - } */ - /* parse name, splitting it into host and port parts */ char* host; char* port; @@ -388,12 +373,12 @@ void grpc_dns_lookup_ares_continue_after_check_localhost_and_ip_literals_locked( port = gpr_strdup(default_port); } error = grpc_ares_ev_driver_create_locked(&r->ev_driver, interested_parties, - combiner, r); + query_timeout_ms, combiner, r); if (error != GRPC_ERROR_NONE) goto error_cleanup; channel = grpc_ares_ev_driver_get_channel_locked(r->ev_driver); // If dns_server is specified, use it. if (dns_server != nullptr) { - gpr_log(GPR_INFO, "Using DNS server %s", dns_server); + GRPC_CARES_TRACE_LOG("request:%p Using DNS server %s", r, dns_server); grpc_resolved_address addr; if (grpc_parse_ipv4_hostport(dns_server, &addr, false /* log_errors */)) { r->dns_server_addr.family = AF_INET; @@ -467,11 +452,10 @@ error_cleanup: gpr_free(port); } -static bool inner_resolve_as_ip_literal_locked(const char* name, - const char* default_port, - grpc_lb_addresses** addrs, - char** host, char** port, - char** hostport) { +static bool inner_resolve_as_ip_literal_locked( + const char* name, const char* default_port, + grpc_core::UniquePtr* addrs, char** host, + char** port, char** hostport) { gpr_split_host_port(name, host, port); if (*host == nullptr) { gpr_log(GPR_ERROR, @@ -495,18 +479,16 @@ static bool inner_resolve_as_ip_literal_locked(const char* name, if (grpc_parse_ipv4_hostport(*hostport, &addr, false /* log errors */) || grpc_parse_ipv6_hostport(*hostport, &addr, false /* log errors */)) { GPR_ASSERT(*addrs == nullptr); - *addrs = grpc_lb_addresses_create(1, nullptr); - grpc_lb_addresses_set_address( - *addrs, 0, addr.addr, addr.len, false /* is_balancer */, - nullptr /* balancer_name */, nullptr /* user_data */); + *addrs = grpc_core::MakeUnique(); + (*addrs)->emplace_back(addr.addr, addr.len, nullptr /* args */); return true; } return false; } -static bool resolve_as_ip_literal_locked(const char* name, - const char* default_port, - grpc_lb_addresses** addrs) { +static bool resolve_as_ip_literal_locked( + const char* name, const char* default_port, + grpc_core::UniquePtr* addrs) { char* host = nullptr; char* port = nullptr; char* hostport = nullptr; @@ -518,42 +500,76 @@ static bool resolve_as_ip_literal_locked(const char* name, return out; } +static bool target_matches_localhost_inner(const char* name, char** host, + char** port) { + if (!gpr_split_host_port(name, host, port)) { + gpr_log(GPR_ERROR, "Unable to split host and port for name: %s", name); + return false; + } + if (gpr_stricmp(*host, "localhost") == 0) { + return true; + } else { + return false; + } +} + +static bool target_matches_localhost(const char* name) { + char* host = nullptr; + char* port = nullptr; + bool out = target_matches_localhost_inner(name, &host, &port); + gpr_free(host); + gpr_free(port); + return out; +} + static grpc_ares_request* grpc_dns_lookup_ares_locked_impl( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json, + grpc_core::UniquePtr* addrs, + bool check_grpclb, char** service_config_json, int query_timeout_ms, grpc_combiner* combiner) { grpc_ares_request* r = static_cast(gpr_zalloc(sizeof(grpc_ares_request))); r->ev_driver = nullptr; r->on_done = on_done; - r->lb_addrs_out = addrs; + r->addresses_out = addrs; r->service_config_json_out = service_config_json; - r->success = false; r->error = GRPC_ERROR_NONE; r->pending_queries = 0; + GRPC_CARES_TRACE_LOG( + "request:%p c-ares grpc_dns_lookup_ares_locked_impl name=%s, " + "default_port=%s", + r, name, default_port); // Early out if the target is an ipv4 or ipv6 literal. if (resolve_as_ip_literal_locked(name, default_port, addrs)) { - GRPC_CLOSURE_SCHED(on_done, GRPC_ERROR_NONE); + grpc_ares_complete_request_locked(r); return r; } // Early out if the target is localhost and we're on Windows. if (grpc_ares_maybe_resolve_localhost_manually_locked(name, default_port, addrs)) { - GRPC_CLOSURE_SCHED(on_done, GRPC_ERROR_NONE); + grpc_ares_complete_request_locked(r); return r; } + // Don't query for SRV and TXT records if the target is "localhost", so + // as to cut down on lookups over the network, especially in tests: + // https://github.com/grpc/proposal/pull/79 + if (target_matches_localhost(name)) { + check_grpclb = false; + r->service_config_json_out = nullptr; + } // Look up name using c-ares lib. grpc_dns_lookup_ares_continue_after_check_localhost_and_ip_literals_locked( r, dns_server, name, default_port, interested_parties, check_grpclb, - combiner); + query_timeout_ms, combiner); return r; } grpc_ares_request* (*grpc_dns_lookup_ares_locked)( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json, + grpc_core::UniquePtr* addrs, + bool check_grpclb, char** service_config_json, int query_timeout_ms, grpc_combiner* combiner) = grpc_dns_lookup_ares_locked_impl; static void grpc_cancel_ares_request_locked_impl(grpc_ares_request* r) { @@ -566,12 +582,12 @@ static void grpc_cancel_ares_request_locked_impl(grpc_ares_request* r) { void (*grpc_cancel_ares_request_locked)(grpc_ares_request* r) = grpc_cancel_ares_request_locked_impl; +// ares_library_init and ares_library_cleanup are currently no-op except under +// Windows. Calling them may cause race conditions when other parts of the +// binary calls these functions concurrently. +#ifdef GPR_WINDOWS grpc_error* grpc_ares_init(void) { - gpr_once_init(&g_basic_init, do_basic_init); - gpr_mu_lock(&g_init_mu); int status = ares_library_init(ARES_LIB_INIT_ALL); - gpr_mu_unlock(&g_init_mu); - if (status != ARES_SUCCESS) { char* error_msg; gpr_asprintf(&error_msg, "ares_library_init failed: %s", @@ -583,11 +599,11 @@ grpc_error* grpc_ares_init(void) { return GRPC_ERROR_NONE; } -void grpc_ares_cleanup(void) { - gpr_mu_lock(&g_init_mu); - ares_library_cleanup(); - gpr_mu_unlock(&g_init_mu); -} +void grpc_ares_cleanup(void) { ares_library_cleanup(); } +#else +grpc_error* grpc_ares_init(void) { return GRPC_ERROR_NONE; } +void grpc_ares_cleanup(void) {} +#endif // GPR_WINDOWS /* * grpc_resolve_address_ares related structs and functions @@ -598,8 +614,8 @@ typedef struct grpc_resolve_address_ares_request { grpc_combiner* combiner; /** the pointer to receive the resolved addresses */ grpc_resolved_addresses** addrs_out; - /** currently resolving lb addresses */ - grpc_lb_addresses* lb_addrs; + /** currently resolving addresses */ + grpc_core::UniquePtr addresses; /** closure to call when the resolve_address_ares request completes */ grpc_closure* on_resolve_address_done; /** a closure wrapping on_resolve_address_done, which should be invoked when @@ -612,7 +628,7 @@ typedef struct grpc_resolve_address_ares_request { /* pollset_set to be driven by */ grpc_pollset_set* interested_parties; /* underlying ares_request that the query is performed on */ - grpc_ares_request* ares_request; + grpc_ares_request* ares_request = nullptr; } grpc_resolve_address_ares_request; static void on_dns_lookup_done_locked(void* arg, grpc_error* error) { @@ -620,25 +636,24 @@ static void on_dns_lookup_done_locked(void* arg, grpc_error* error) { static_cast(arg); gpr_free(r->ares_request); grpc_resolved_addresses** resolved_addresses = r->addrs_out; - if (r->lb_addrs == nullptr || r->lb_addrs->num_addresses == 0) { + if (r->addresses == nullptr || r->addresses->empty()) { *resolved_addresses = nullptr; } else { *resolved_addresses = static_cast( gpr_zalloc(sizeof(grpc_resolved_addresses))); - (*resolved_addresses)->naddrs = r->lb_addrs->num_addresses; + (*resolved_addresses)->naddrs = r->addresses->size(); (*resolved_addresses)->addrs = static_cast(gpr_zalloc( sizeof(grpc_resolved_address) * (*resolved_addresses)->naddrs)); - for (size_t i = 0; i < (*resolved_addresses)->naddrs; i++) { - GPR_ASSERT(!r->lb_addrs->addresses[i].is_balancer); - memcpy(&(*resolved_addresses)->addrs[i], - &r->lb_addrs->addresses[i].address, sizeof(grpc_resolved_address)); + for (size_t i = 0; i < (*resolved_addresses)->naddrs; ++i) { + GPR_ASSERT(!(*r->addresses)[i].IsBalancer()); + memcpy(&(*resolved_addresses)->addrs[i], &(*r->addresses)[i].address(), + sizeof(grpc_resolved_address)); } } GRPC_CLOSURE_SCHED(r->on_resolve_address_done, GRPC_ERROR_REF(error)); - if (r->lb_addrs != nullptr) grpc_lb_addresses_destroy(r->lb_addrs); GRPC_COMBINER_UNREF(r->combiner, "on_dns_lookup_done_cb"); - gpr_free(r); + grpc_core::Delete(r); } static void grpc_resolve_address_invoke_dns_lookup_ares_locked( @@ -647,8 +662,9 @@ static void grpc_resolve_address_invoke_dns_lookup_ares_locked( static_cast(arg); r->ares_request = grpc_dns_lookup_ares_locked( nullptr /* dns_server */, r->name, r->default_port, r->interested_parties, - &r->on_dns_lookup_done_locked, &r->lb_addrs, false /* check_grpclb */, - nullptr /* service_config_json */, r->combiner); + &r->on_dns_lookup_done_locked, &r->addresses, false /* check_grpclb */, + nullptr /* service_config_json */, GRPC_DNS_ARES_DEFAULT_QUERY_TIMEOUT_MS, + r->combiner); } static void grpc_resolve_address_ares_impl(const char* name, @@ -657,8 +673,7 @@ static void grpc_resolve_address_ares_impl(const char* name, grpc_closure* on_done, grpc_resolved_addresses** addrs) { grpc_resolve_address_ares_request* r = - static_cast( - gpr_zalloc(sizeof(grpc_resolve_address_ares_request))); + grpc_core::New(); r->combiner = grpc_combiner_create(); r->addrs_out = addrs; r->on_resolve_address_done = on_done; @@ -678,4 +693,4 @@ void (*grpc_resolve_address_ares)( grpc_pollset_set* interested_parties, grpc_closure* on_done, grpc_resolved_addresses** addrs) = grpc_resolve_address_ares_impl; -#endif /* GRPC_ARES == 1 && !defined(GRPC_UV) */ +#endif /* GRPC_ARES == 1 */ diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h index a1231cc4e0d..2cb7c9e53a5 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h @@ -21,19 +21,23 @@ #include -#include "src/core/ext/filters/client_channel/lb_policy_factory.h" +#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/iomgr/iomgr.h" #include "src/core/lib/iomgr/polling_entity.h" #include "src/core/lib/iomgr/resolve_address.h" +#define GRPC_DNS_ARES_DEFAULT_QUERY_TIMEOUT_MS 120000 + extern grpc_core::TraceFlag grpc_trace_cares_address_sorting; extern grpc_core::TraceFlag grpc_trace_cares_resolver; -#define GRPC_CARES_TRACE_LOG(format, ...) \ - if (grpc_trace_cares_resolver.enabled()) { \ - gpr_log(GPR_DEBUG, "(c-ares resolver) " format, __VA_ARGS__); \ - } +#define GRPC_CARES_TRACE_LOG(format, ...) \ + do { \ + if (GRPC_TRACE_FLAG_ENABLED(grpc_trace_cares_resolver)) { \ + gpr_log(GPR_DEBUG, "(c-ares resolver) " format, __VA_ARGS__); \ + } \ + } while (0) typedef struct grpc_ares_request grpc_ares_request; @@ -59,8 +63,9 @@ extern void (*grpc_resolve_address_ares)(const char* name, extern grpc_ares_request* (*grpc_dns_lookup_ares_locked)( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - grpc_lb_addresses** addresses, bool check_grpclb, - char** service_config_json, grpc_combiner* combiner); + grpc_core::UniquePtr* addresses, + bool check_grpclb, char** service_config_json, int query_timeout_ms, + grpc_combiner* combiner); /* Cancel the pending grpc_ares_request \a request */ extern void (*grpc_cancel_ares_request_locked)(grpc_ares_request* request); @@ -87,10 +92,12 @@ bool grpc_ares_query_ipv6(); * Returns a bool indicating whether or not such an action was performed. * See https://github.com/grpc/grpc/issues/15158. */ bool grpc_ares_maybe_resolve_localhost_manually_locked( - const char* name, const char* default_port, grpc_lb_addresses** addrs); + const char* name, const char* default_port, + grpc_core::UniquePtr* addrs); /* Sorts destinations in lb_addrs according to RFC 6724. */ -void grpc_cares_wrapper_address_sorting_sort(grpc_lb_addresses* lb_addrs); +void grpc_cares_wrapper_address_sorting_sort( + grpc_core::ServerAddressList* addresses); #endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_C_ARES_GRPC_ARES_WRAPPER_H \ */ diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc index 9f293c1ac07..d2de88eaa1e 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc @@ -18,7 +18,7 @@ #include -#if GRPC_ARES != 1 || defined(GRPC_UV) +#if GRPC_ARES != 1 #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" @@ -29,7 +29,8 @@ struct grpc_ares_request { static grpc_ares_request* grpc_dns_lookup_ares_locked_impl( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json, + grpc_core::UniquePtr* addrs, + bool check_grpclb, char** service_config_json, int query_timeout_ms, grpc_combiner* combiner) { return NULL; } @@ -37,7 +38,8 @@ static grpc_ares_request* grpc_dns_lookup_ares_locked_impl( grpc_ares_request* (*grpc_dns_lookup_ares_locked)( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json, + grpc_core::UniquePtr* addrs, + bool check_grpclb, char** service_config_json, int query_timeout_ms, grpc_combiner* combiner) = grpc_dns_lookup_ares_locked_impl; static void grpc_cancel_ares_request_locked_impl(grpc_ares_request* r) {} @@ -60,4 +62,4 @@ void (*grpc_resolve_address_ares)( grpc_pollset_set* interested_parties, grpc_closure* on_done, grpc_resolved_addresses** addrs) = grpc_resolve_address_ares_impl; -#endif /* GRPC_ARES != 1 || defined(GRPC_UV) */ +#endif /* GRPC_ARES != 1 */ diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc new file mode 100644 index 00000000000..fdbb8969a1f --- /dev/null +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc @@ -0,0 +1,52 @@ +/* + * + * 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. + * + */ + +#include + +#include "src/core/lib/iomgr/port.h" +#if GRPC_ARES == 1 && defined(GRPC_UV) + +#include + +#include "src/core/ext/filters/client_channel/parse_address.h" +#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" +#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h" +#include "src/core/ext/filters/client_channel/server_address.h" +#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gpr/string.h" + +bool grpc_ares_query_ipv6() { + /* The libuv grpc code currently does not have the code to probe for this, + * so we assume for now that IPv6 is always available in contexts where this + * code will be used. */ + return true; +} + +bool grpc_ares_maybe_resolve_localhost_manually_locked( + const char* name, const char* default_port, + grpc_core::UniquePtr* addrs) { + char* host = nullptr; + char* port = nullptr; + bool out = inner_maybe_resolve_localhost_manually_locked(name, default_port, + addrs, &host, &port); + gpr_free(host); + gpr_free(port); + return out; +} + +#endif /* GRPC_ARES == 1 && defined(GRPC_UV) */ diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc new file mode 100644 index 00000000000..1232fc9d57c --- /dev/null +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc @@ -0,0 +1,83 @@ +/* + * + * Copyright 2019 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 + +#include "src/core/lib/iomgr/port.h" +#if GRPC_ARES == 1 && (defined(GRPC_UV) || defined(GPR_WINDOWS)) + +#include + +#include "src/core/ext/filters/client_channel/parse_address.h" +#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" +#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h" +#include "src/core/ext/filters/client_channel/server_address.h" +#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gpr/string.h" + +bool inner_maybe_resolve_localhost_manually_locked( + const char* name, const char* default_port, + grpc_core::UniquePtr* addrs, char** host, + char** port) { + gpr_split_host_port(name, host, port); + if (*host == nullptr) { + gpr_log(GPR_ERROR, + "Failed to parse %s into host:port during manual localhost " + "resolution check.", + name); + return false; + } + if (*port == nullptr) { + if (default_port == nullptr) { + gpr_log(GPR_ERROR, + "No port or default port for %s during manual localhost " + "resolution check.", + name); + return false; + } + *port = gpr_strdup(default_port); + } + if (gpr_stricmp(*host, "localhost") == 0) { + GPR_ASSERT(*addrs == nullptr); + *addrs = grpc_core::MakeUnique(); + uint16_t numeric_port = grpc_strhtons(*port); + // Append the ipv6 loopback address. + struct sockaddr_in6 ipv6_loopback_addr; + memset(&ipv6_loopback_addr, 0, sizeof(ipv6_loopback_addr)); + ((char*)&ipv6_loopback_addr.sin6_addr)[15] = 1; + ipv6_loopback_addr.sin6_family = AF_INET6; + ipv6_loopback_addr.sin6_port = numeric_port; + (*addrs)->emplace_back(&ipv6_loopback_addr, sizeof(ipv6_loopback_addr), + nullptr /* args */); + // Append the ipv4 loopback address. + struct sockaddr_in ipv4_loopback_addr; + memset(&ipv4_loopback_addr, 0, sizeof(ipv4_loopback_addr)); + ((char*)&ipv4_loopback_addr.sin_addr)[0] = 0x7f; + ((char*)&ipv4_loopback_addr.sin_addr)[3] = 0x01; + ipv4_loopback_addr.sin_family = AF_INET; + ipv4_loopback_addr.sin_port = numeric_port; + (*addrs)->emplace_back(&ipv4_loopback_addr, sizeof(ipv4_loopback_addr), + nullptr /* args */); + // Let the address sorter figure out which one should be tried first. + grpc_cares_wrapper_address_sorting_sort(addrs->get()); + return true; + } + return false; +} + +#endif /* GRPC_ARES == 1 && (defined(GRPC_UV) || defined(GPR_WINDOWS)) */ diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h new file mode 100644 index 00000000000..ed40e58f7cc --- /dev/null +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h @@ -0,0 +1,34 @@ +/* + * + * Copyright 2019 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_RESOLVER_DNS_C_ARES_GRPC_ARES_WRAPPER_LIBUV_WINDOWS_H +#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_C_ARES_GRPC_ARES_WRAPPER_LIBUV_WINDOWS_H + +#include + +#include + +#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" + +bool inner_maybe_resolve_localhost_manually_locked( + const char* name, const char* default_port, + grpc_core::UniquePtr* addrs, char** host, + char** port); + +#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_C_ARES_GRPC_ARES_WRAPPER_LIBUV_WINDOWS_H \ + */ diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc index 639eec2323f..028d8442169 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc @@ -27,7 +27,8 @@ bool grpc_ares_query_ipv6() { return grpc_ipv6_loopback_available(); } bool grpc_ares_maybe_resolve_localhost_manually_locked( - const char* name, const char* default_port, grpc_lb_addresses** addrs) { + const char* name, const char* default_port, + grpc_core::UniquePtr* addrs) { return false; } diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc index 7e34784691f..60398c6aedd 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc @@ -23,70 +23,19 @@ #include -#include "src/core/ext/filters/client_channel/lb_policy_factory.h" #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" +#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h" +#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/iomgr/socket_windows.h" bool grpc_ares_query_ipv6() { return grpc_ipv6_loopback_available(); } -static bool inner_maybe_resolve_localhost_manually_locked( - const char* name, const char* default_port, grpc_lb_addresses** addrs, - char** host, char** port) { - gpr_split_host_port(name, host, port); - if (*host == nullptr) { - gpr_log(GPR_ERROR, - "Failed to parse %s into host:port during Windows localhost " - "resolution check.", - name); - return false; - } - if (*port == nullptr) { - if (default_port == nullptr) { - gpr_log(GPR_ERROR, - "No port or default port for %s during Windows localhost " - "resolution check.", - name); - return false; - } - *port = gpr_strdup(default_port); - } - if (gpr_stricmp(*host, "localhost") == 0) { - GPR_ASSERT(*addrs == nullptr); - *addrs = grpc_lb_addresses_create(2, nullptr); - uint16_t numeric_port = grpc_strhtons(*port); - // Append the ipv6 loopback address. - struct sockaddr_in6 ipv6_loopback_addr; - memset(&ipv6_loopback_addr, 0, sizeof(ipv6_loopback_addr)); - ((char*)&ipv6_loopback_addr.sin6_addr)[15] = 1; - ipv6_loopback_addr.sin6_family = AF_INET6; - ipv6_loopback_addr.sin6_port = numeric_port; - grpc_lb_addresses_set_address( - *addrs, 0, &ipv6_loopback_addr, sizeof(ipv6_loopback_addr), - false /* is_balancer */, nullptr /* balancer_name */, - nullptr /* user_data */); - // Append the ipv4 loopback address. - struct sockaddr_in ipv4_loopback_addr; - memset(&ipv4_loopback_addr, 0, sizeof(ipv4_loopback_addr)); - ((char*)&ipv4_loopback_addr.sin_addr)[0] = 0x7f; - ((char*)&ipv4_loopback_addr.sin_addr)[3] = 0x01; - ipv4_loopback_addr.sin_family = AF_INET; - ipv4_loopback_addr.sin_port = numeric_port; - grpc_lb_addresses_set_address( - *addrs, 1, &ipv4_loopback_addr, sizeof(ipv4_loopback_addr), - false /* is_balancer */, nullptr /* balancer_name */, - nullptr /* user_data */); - // Let the address sorter figure out which one should be tried first. - grpc_cares_wrapper_address_sorting_sort(*addrs); - return true; - } - return false; -} - bool grpc_ares_maybe_resolve_localhost_manually_locked( - const char* name, const char* default_port, grpc_lb_addresses** addrs) { + const char* name, const char* default_port, + grpc_core::UniquePtr* addrs) { char* host = nullptr; char* port = nullptr; bool out = inner_maybe_resolve_localhost_manually_locked(name, default_port, 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 65ff1ec1a5b..164d308c0dd 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 @@ -26,8 +26,8 @@ #include #include -#include "src/core/ext/filters/client_channel/lb_policy_registry.h" #include "src/core/ext/filters/client_channel/resolver_registry.h" +#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/backoff/backoff.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gpr/env.h" @@ -51,10 +51,9 @@ const char kDefaultPort[] = "https"; class NativeDnsResolver : public Resolver { public: - explicit NativeDnsResolver(const ResolverArgs& args); + explicit NativeDnsResolver(ResolverArgs args); - void NextLocked(grpc_channel_args** result, - grpc_closure* on_complete) override; + void StartLocked() override; void RequestReresolutionLocked() override; @@ -67,7 +66,6 @@ class NativeDnsResolver : public Resolver { void MaybeStartResolvingLocked(); void StartResolvingLocked(); - void MaybeFinishNextLocked(); static void OnNextResolutionLocked(void* arg, grpc_error* error); static void OnResolvedLocked(void* arg, grpc_error* error); @@ -78,19 +76,11 @@ class NativeDnsResolver : public Resolver { grpc_channel_args* channel_args_ = nullptr; /// pollset_set to drive the name resolution process grpc_pollset_set* interested_parties_ = nullptr; + /// are we shutting down? + bool shutdown_ = false; /// are we currently resolving? bool resolving_ = false; grpc_closure on_resolved_; - /// which version of the result have we published? - int published_version_ = 0; - /// which version of the result is current? - int resolved_version_ = 0; - /// pending next completion, or nullptr - grpc_closure* next_completion_ = nullptr; - /// target result address for next completion - grpc_channel_args** target_result_ = nullptr; - /// current (fully resolved) result - grpc_channel_args* resolved_result_ = nullptr; /// next resolution timer bool have_next_resolution_timer_ = false; grpc_timer next_resolution_timer_; @@ -105,8 +95,8 @@ class NativeDnsResolver : public Resolver { grpc_resolved_addresses* addresses_ = nullptr; }; -NativeDnsResolver::NativeDnsResolver(const ResolverArgs& args) - : Resolver(args.combiner), +NativeDnsResolver::NativeDnsResolver(ResolverArgs args) + : Resolver(args.combiner, std::move(args.result_handler)), backoff_( BackOff::Options() .set_initial_backoff(GRPC_DNS_INITIAL_CONNECT_BACKOFF_SECONDS * @@ -134,25 +124,12 @@ NativeDnsResolver::NativeDnsResolver(const ResolverArgs& args) } NativeDnsResolver::~NativeDnsResolver() { - if (resolved_result_ != nullptr) { - grpc_channel_args_destroy(resolved_result_); - } + grpc_channel_args_destroy(channel_args_); grpc_pollset_set_destroy(interested_parties_); gpr_free(name_to_resolve_); - grpc_channel_args_destroy(channel_args_); } -void NativeDnsResolver::NextLocked(grpc_channel_args** result, - grpc_closure* on_complete) { - GPR_ASSERT(next_completion_ == nullptr); - next_completion_ = on_complete; - target_result_ = result; - if (resolved_version_ == 0 && !resolving_) { - MaybeStartResolvingLocked(); - } else { - MaybeFinishNextLocked(); - } -} +void NativeDnsResolver::StartLocked() { MaybeStartResolvingLocked(); } void NativeDnsResolver::RequestReresolutionLocked() { if (!resolving_) { @@ -168,15 +145,10 @@ void NativeDnsResolver::ResetBackoffLocked() { } void NativeDnsResolver::ShutdownLocked() { + shutdown_ = true; if (have_next_resolution_timer_) { grpc_timer_cancel(&next_resolution_timer_); } - if (next_completion_ != nullptr) { - *target_result_ = nullptr; - GRPC_CLOSURE_SCHED(next_completion_, GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "Resolver Shutdown")); - next_completion_ = nullptr; - } } void NativeDnsResolver::OnNextResolutionLocked(void* arg, grpc_error* error) { @@ -190,42 +162,42 @@ void NativeDnsResolver::OnNextResolutionLocked(void* arg, grpc_error* error) { void NativeDnsResolver::OnResolvedLocked(void* arg, grpc_error* error) { NativeDnsResolver* r = static_cast(arg); - grpc_channel_args* result = nullptr; GPR_ASSERT(r->resolving_); r->resolving_ = false; - GRPC_ERROR_REF(error); - error = - grpc_error_set_str(error, GRPC_ERROR_STR_TARGET_ADDRESS, - grpc_slice_from_copied_string(r->name_to_resolve_)); + if (r->shutdown_) { + r->Unref(DEBUG_LOCATION, "dns-resolving"); + return; + } if (r->addresses_ != nullptr) { - grpc_lb_addresses* addresses = grpc_lb_addresses_create( - r->addresses_->naddrs, nullptr /* user_data_vtable */); + Result result; for (size_t i = 0; i < r->addresses_->naddrs; ++i) { - grpc_lb_addresses_set_address( - addresses, i, &r->addresses_->addrs[i].addr, - r->addresses_->addrs[i].len, false /* is_balancer */, - nullptr /* balancer_name */, nullptr /* user_data */); + result.addresses.emplace_back(&r->addresses_->addrs[i].addr, + r->addresses_->addrs[i].len, + nullptr /* args */); } - grpc_arg new_arg = grpc_lb_addresses_create_channel_arg(addresses); - result = grpc_channel_args_copy_and_add(r->channel_args_, &new_arg, 1); grpc_resolved_addresses_destroy(r->addresses_); - grpc_lb_addresses_destroy(addresses); + result.args = grpc_channel_args_copy(r->channel_args_); + r->result_handler()->ReturnResult(std::move(result)); // Reset backoff state so that we start from the beginning when the // next request gets triggered. r->backoff_.Reset(); } else { - grpc_millis next_try = r->backoff_.NextAttemptTime(); - grpc_millis timeout = next_try - ExecCtx::Get()->Now(); gpr_log(GPR_INFO, "dns resolution failed (will retry): %s", grpc_error_string(error)); + // Return transient error. + r->result_handler()->ReturnError(grpc_error_set_int( + GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + "DNS resolution failed", &error, 1), + GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE)); + // Set up for retry. + grpc_millis next_try = r->backoff_.NextAttemptTime(); + grpc_millis timeout = next_try - ExecCtx::Get()->Now(); GPR_ASSERT(!r->have_next_resolution_timer_); r->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 self = - r->Ref(DEBUG_LOCATION, "next_resolution_timer"); - self.release(); + r->Ref(DEBUG_LOCATION, "next_resolution_timer").release(); if (timeout > 0) { gpr_log(GPR_DEBUG, "retrying in %" PRId64 " milliseconds", timeout); } else { @@ -234,13 +206,6 @@ void NativeDnsResolver::OnResolvedLocked(void* arg, grpc_error* error) { grpc_timer_init(&r->next_resolution_timer_, next_try, &r->on_next_resolution_); } - if (r->resolved_result_ != nullptr) { - grpc_channel_args_destroy(r->resolved_result_); - } - r->resolved_result_ = result; - ++r->resolved_version_; - r->MaybeFinishNextLocked(); - GRPC_ERROR_UNREF(error); r->Unref(DEBUG_LOCATION, "dns-resolving"); } @@ -264,9 +229,7 @@ void NativeDnsResolver::MaybeStartResolvingLocked() { // 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 self = - Ref(DEBUG_LOCATION, "next_resolution_timer_cooldown"); - self.release(); + Ref(DEBUG_LOCATION, "next_resolution_timer_cooldown").release(); grpc_timer_init(&next_resolution_timer_, ms_until_next_resolution, &on_next_resolution_); return; @@ -280,8 +243,7 @@ void NativeDnsResolver::StartResolvingLocked() { // 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 self = Ref(DEBUG_LOCATION, "dns-resolving"); - self.release(); + Ref(DEBUG_LOCATION, "dns-resolving").release(); GPR_ASSERT(!resolving_); resolving_ = true; addresses_ = nullptr; @@ -290,30 +252,18 @@ void NativeDnsResolver::StartResolvingLocked() { last_resolution_timestamp_ = grpc_core::ExecCtx::Get()->Now(); } -void NativeDnsResolver::MaybeFinishNextLocked() { - if (next_completion_ != nullptr && resolved_version_ != published_version_) { - *target_result_ = resolved_result_ == nullptr - ? nullptr - : grpc_channel_args_copy(resolved_result_); - GRPC_CLOSURE_SCHED(next_completion_, GRPC_ERROR_NONE); - next_completion_ = nullptr; - published_version_ = resolved_version_; - } -} - // // Factory // class NativeDnsResolverFactory : public ResolverFactory { public: - OrphanablePtr CreateResolver( - const ResolverArgs& args) const override { + OrphanablePtr CreateResolver(ResolverArgs args) const override { if (GPR_UNLIKELY(0 != strcmp(args.uri->authority, ""))) { gpr_log(GPR_ERROR, "authority based dns uri's not supported"); return OrphanablePtr(nullptr); } - return OrphanablePtr(New(args)); + return OrphanablePtr(New(std::move(args))); } const char* scheme() const override { return "dns"; } diff --git a/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc b/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc index 3aa690bea41..85b9bea6f70 100644 --- a/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc +++ b/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc @@ -28,12 +28,13 @@ #include #include -#include "src/core/ext/filters/client_channel/lb_policy_factory.h" #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver_registry.h" +#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gpr/useful.h" #include "src/core/lib/iomgr/closure.h" #include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/resolve_address.h" @@ -49,10 +50,9 @@ namespace grpc_core { // FakeResolverResponseGenerator. class FakeResolver : public Resolver { public: - explicit FakeResolver(const ResolverArgs& args); + explicit FakeResolver(ResolverArgs args); - void NextLocked(grpc_channel_args** result, - grpc_closure* on_complete) override; + void StartLocked() override; void RequestReresolutionLocked() override; @@ -61,76 +61,99 @@ class FakeResolver : public Resolver { virtual ~FakeResolver(); - void MaybeFinishNextLocked(); + void ShutdownLocked() override { active_ = false; } - void ShutdownLocked() override; + void MaybeSendResultLocked(); + + static void ReturnReresolutionResult(void* arg, grpc_error* error); // passed-in parameters grpc_channel_args* channel_args_ = nullptr; - // If not NULL, the next set of resolution results to be returned to - // NextLocked()'s closure. - grpc_channel_args* next_results_ = nullptr; - // Results to use for the pretended re-resolution in + // If has_next_result_ is true, next_result_ is the next resolution result + // to be returned. + bool has_next_result_ = false; + Result next_result_; + // Result to use for the pretended re-resolution in // RequestReresolutionLocked(). - grpc_channel_args* reresolution_results_ = nullptr; - // pending next completion, or NULL - grpc_closure* next_completion_ = nullptr; - // target result address for next completion - grpc_channel_args** target_result_ = nullptr; + bool has_reresolution_result_ = false; + Result reresolution_result_; + // True between the calls to StartLocked() ShutdownLocked(). + bool active_ = false; // if true, return failure bool return_failure_ = false; + // pending re-resolution + grpc_closure reresolution_closure_; + bool reresolution_closure_pending_ = false; }; -FakeResolver::FakeResolver(const ResolverArgs& args) : Resolver(args.combiner) { +FakeResolver::FakeResolver(ResolverArgs args) + : Resolver(args.combiner, std::move(args.result_handler)) { + GRPC_CLOSURE_INIT(&reresolution_closure_, ReturnReresolutionResult, this, + grpc_combiner_scheduler(combiner())); channel_args_ = grpc_channel_args_copy(args.args); FakeResolverResponseGenerator* response_generator = FakeResolverResponseGenerator::GetFromArgs(args.args); - if (response_generator != nullptr) response_generator->resolver_ = this; + if (response_generator != nullptr) { + response_generator->resolver_ = this; + if (response_generator->has_result_) { + response_generator->SetResponse(std::move(response_generator->result_)); + response_generator->has_result_ = false; + } + } } -FakeResolver::~FakeResolver() { - grpc_channel_args_destroy(next_results_); - grpc_channel_args_destroy(reresolution_results_); - grpc_channel_args_destroy(channel_args_); -} +FakeResolver::~FakeResolver() { grpc_channel_args_destroy(channel_args_); } -void FakeResolver::NextLocked(grpc_channel_args** target_result, - grpc_closure* on_complete) { - GPR_ASSERT(next_completion_ == nullptr); - next_completion_ = on_complete; - target_result_ = target_result; - MaybeFinishNextLocked(); +void FakeResolver::StartLocked() { + active_ = true; + MaybeSendResultLocked(); } void FakeResolver::RequestReresolutionLocked() { - if (reresolution_results_ != nullptr || return_failure_) { - grpc_channel_args_destroy(next_results_); - next_results_ = grpc_channel_args_copy(reresolution_results_); - MaybeFinishNextLocked(); + if (has_reresolution_result_ || return_failure_) { + next_result_ = reresolution_result_; + has_next_result_ = true; + // Return the result in a different closure, so that we don't call + // back into the LB policy while it's still processing the previous + // update. + if (!reresolution_closure_pending_) { + reresolution_closure_pending_ = true; + Ref().release(); // ref held by closure + GRPC_CLOSURE_SCHED(&reresolution_closure_, GRPC_ERROR_NONE); + } } } -void FakeResolver::MaybeFinishNextLocked() { - if (next_completion_ != nullptr && - (next_results_ != nullptr || return_failure_)) { - *target_result_ = - return_failure_ ? nullptr - : grpc_channel_args_union(next_results_, channel_args_); - grpc_channel_args_destroy(next_results_); - next_results_ = nullptr; - GRPC_CLOSURE_SCHED(next_completion_, GRPC_ERROR_NONE); - next_completion_ = nullptr; +void FakeResolver::MaybeSendResultLocked() { + if (!active_) return; + if (return_failure_) { + // TODO(roth): Change resolver result generator to be able to inject + // the error to be returned. + result_handler()->ReturnError(grpc_error_set_int( + GRPC_ERROR_CREATE_FROM_STATIC_STRING("Resolver transient failure"), + GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE)); return_failure_ = false; + } else if (has_next_result_) { + Result result; + result.addresses = std::move(next_result_.addresses); + result.service_config = std::move(next_result_.service_config); + // TODO(roth): Use std::move() once grpc_error is converted to C++. + result.service_config_error = next_result_.service_config_error; + next_result_.service_config_error = GRPC_ERROR_NONE; + // When both next_results_ and channel_args_ contain an arg with the same + // name, only the one in next_results_ will be kept since next_results_ is + // before channel_args_. + result.args = grpc_channel_args_union(next_result_.args, channel_args_); + result_handler()->ReturnResult(std::move(result)); + has_next_result_ = false; } } -void FakeResolver::ShutdownLocked() { - if (next_completion_ != nullptr) { - *target_result_ = nullptr; - GRPC_CLOSURE_SCHED(next_completion_, GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "Resolver Shutdown")); - next_completion_ = nullptr; - } +void FakeResolver::ReturnReresolutionResult(void* arg, grpc_error* error) { + FakeResolver* self = static_cast(arg); + self->reresolution_closure_pending_ = false; + self->MaybeSendResultLocked(); + self->Unref(); } // @@ -140,7 +163,8 @@ void FakeResolver::ShutdownLocked() { struct SetResponseClosureArg { grpc_closure set_response_closure; FakeResolverResponseGenerator* generator; - grpc_channel_args* response; + Resolver::Result result; + bool has_result = false; bool immediate = true; }; @@ -148,41 +172,56 @@ void FakeResolverResponseGenerator::SetResponseLocked(void* arg, grpc_error* error) { SetResponseClosureArg* closure_arg = static_cast(arg); FakeResolver* resolver = closure_arg->generator->resolver_; - grpc_channel_args_destroy(resolver->next_results_); - resolver->next_results_ = closure_arg->response; - resolver->MaybeFinishNextLocked(); + resolver->next_result_ = std::move(closure_arg->result); + resolver->has_next_result_ = true; + resolver->MaybeSendResultLocked(); Delete(closure_arg); } -void FakeResolverResponseGenerator::SetResponse(grpc_channel_args* response) { - GPR_ASSERT(response != nullptr); - GPR_ASSERT(resolver_ != nullptr); - SetResponseClosureArg* closure_arg = New(); - closure_arg->generator = this; - closure_arg->response = grpc_channel_args_copy(response); - GRPC_CLOSURE_SCHED( - GRPC_CLOSURE_INIT(&closure_arg->set_response_closure, SetResponseLocked, - closure_arg, - grpc_combiner_scheduler(resolver_->combiner())), - GRPC_ERROR_NONE); +void FakeResolverResponseGenerator::SetResponse(Resolver::Result result) { + if (resolver_ != nullptr) { + SetResponseClosureArg* closure_arg = New(); + closure_arg->generator = this; + closure_arg->result = std::move(result); + GRPC_CLOSURE_SCHED( + GRPC_CLOSURE_INIT(&closure_arg->set_response_closure, SetResponseLocked, + closure_arg, + grpc_combiner_scheduler(resolver_->combiner())), + GRPC_ERROR_NONE); + } else { + GPR_ASSERT(!has_result_); + has_result_ = true; + result_ = std::move(result); + } } void FakeResolverResponseGenerator::SetReresolutionResponseLocked( void* arg, grpc_error* error) { SetResponseClosureArg* closure_arg = static_cast(arg); FakeResolver* resolver = closure_arg->generator->resolver_; - grpc_channel_args_destroy(resolver->reresolution_results_); - resolver->reresolution_results_ = closure_arg->response; + resolver->reresolution_result_ = std::move(closure_arg->result); + resolver->has_reresolution_result_ = closure_arg->has_result; Delete(closure_arg); } void FakeResolverResponseGenerator::SetReresolutionResponse( - grpc_channel_args* response) { + Resolver::Result result) { + GPR_ASSERT(resolver_ != nullptr); + SetResponseClosureArg* closure_arg = New(); + closure_arg->generator = this; + closure_arg->result = std::move(result); + closure_arg->has_result = true; + GRPC_CLOSURE_SCHED( + GRPC_CLOSURE_INIT(&closure_arg->set_response_closure, + SetReresolutionResponseLocked, closure_arg, + grpc_combiner_scheduler(resolver_->combiner())), + GRPC_ERROR_NONE); +} + +void FakeResolverResponseGenerator::UnsetReresolutionResponse() { GPR_ASSERT(resolver_ != nullptr); SetResponseClosureArg* closure_arg = New(); closure_arg->generator = this; - closure_arg->response = - response != nullptr ? grpc_channel_args_copy(response) : nullptr; GRPC_CLOSURE_SCHED( GRPC_CLOSURE_INIT(&closure_arg->set_response_closure, SetReresolutionResponseLocked, closure_arg, @@ -195,7 +234,7 @@ void FakeResolverResponseGenerator::SetFailureLocked(void* arg, SetResponseClosureArg* closure_arg = static_cast(arg); FakeResolver* resolver = closure_arg->generator->resolver_; resolver->return_failure_ = true; - if (closure_arg->immediate) resolver->MaybeFinishNextLocked(); + if (closure_arg->immediate) resolver->MaybeSendResultLocked(); Delete(closure_arg); } @@ -275,9 +314,8 @@ namespace { class FakeResolverFactory : public ResolverFactory { public: - OrphanablePtr CreateResolver( - const ResolverArgs& args) const override { - return OrphanablePtr(New(args)); + OrphanablePtr CreateResolver(ResolverArgs args) const override { + return OrphanablePtr(New(std::move(args))); } const char* scheme() const override { return "fake"; } diff --git a/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h b/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h index 7f690593510..3b1ea8e8909 100644 --- a/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h +++ b/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h @@ -19,10 +19,10 @@ #include -#include "src/core/ext/filters/client_channel/lb_policy_factory.h" +#include "src/core/ext/filters/client_channel/resolver.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gprpp/ref_counted.h" -#include "src/core/lib/uri/uri_parser.h" +#include "src/core/lib/iomgr/error.h" #define GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR \ "grpc.fake_resolver.response_generator" @@ -45,20 +45,22 @@ class FakeResolverResponseGenerator FakeResolverResponseGenerator() {} // Instructs the fake resolver associated with the response generator - // instance to trigger a new resolution with the specified response. - void SetResponse(grpc_channel_args* next_response); + // instance to trigger a new resolution with the specified result. If the + // resolver is not available yet, delays response setting until it is. This + // can be called at most once before the resolver is available. + void SetResponse(Resolver::Result result); // Sets the re-resolution response, which is returned by the fake resolver // when re-resolution is requested (via \a RequestReresolutionLocked()). // The new re-resolution response replaces any previous re-resolution // response that may have been set by a previous call. - // If the re-resolution response is set to NULL, then the fake - // resolver will not return anything when \a RequestReresolutionLocked() - // is called. - void SetReresolutionResponse(grpc_channel_args* response); + void SetReresolutionResponse(Resolver::Result result); - // Tells the resolver to return a transient failure (signalled by - // returning a null result with no error). + // Unsets the re-resolution response. After this, the fake resolver will + // not return anything when \a RequestReresolutionLocked() is called. + void UnsetReresolutionResponse(); + + // Tells the resolver to return a transient failure. void SetFailure(); // Same as SetFailure(), but instead of returning the error @@ -80,6 +82,8 @@ class FakeResolverResponseGenerator static void SetFailureLocked(void* arg, grpc_error* error); FakeResolver* resolver_ = nullptr; // Do not own. + Resolver::Result result_; + bool has_result_ = false; }; } // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc b/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc index 801734764b4..1465b0c644e 100644 --- a/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc +++ b/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc @@ -26,9 +26,9 @@ #include #include -#include "src/core/ext/filters/client_channel/lb_policy_factory.h" #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver_registry.h" +#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" @@ -44,67 +44,35 @@ namespace { class SockaddrResolver : public Resolver { public: - /// Takes ownership of \a addresses. - SockaddrResolver(const ResolverArgs& args, grpc_lb_addresses* addresses); + SockaddrResolver(ServerAddressList addresses, ResolverArgs args); + ~SockaddrResolver() override; - void NextLocked(grpc_channel_args** result, - grpc_closure* on_complete) override; + void StartLocked() override; - void ShutdownLocked() override; + void ShutdownLocked() override {} private: - virtual ~SockaddrResolver(); - - void MaybeFinishNextLocked(); - - /// the addresses that we've "resolved" - grpc_lb_addresses* addresses_ = nullptr; - /// channel args - grpc_channel_args* channel_args_ = nullptr; - /// have we published? - bool published_ = false; - /// pending next completion, or NULL - grpc_closure* next_completion_ = nullptr; - /// target result address for next completion - grpc_channel_args** target_result_ = nullptr; + ServerAddressList addresses_; + const grpc_channel_args* channel_args_ = nullptr; }; -SockaddrResolver::SockaddrResolver(const ResolverArgs& args, - grpc_lb_addresses* addresses) - : Resolver(args.combiner), - addresses_(addresses), +SockaddrResolver::SockaddrResolver(ServerAddressList addresses, + ResolverArgs args) + : Resolver(args.combiner, std::move(args.result_handler)), + addresses_(std::move(addresses)), channel_args_(grpc_channel_args_copy(args.args)) {} SockaddrResolver::~SockaddrResolver() { - grpc_lb_addresses_destroy(addresses_); grpc_channel_args_destroy(channel_args_); } -void SockaddrResolver::NextLocked(grpc_channel_args** target_result, - grpc_closure* on_complete) { - GPR_ASSERT(!next_completion_); - next_completion_ = on_complete; - target_result_ = target_result; - MaybeFinishNextLocked(); -} - -void SockaddrResolver::ShutdownLocked() { - if (next_completion_ != nullptr) { - *target_result_ = nullptr; - GRPC_CLOSURE_SCHED(next_completion_, GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "Resolver Shutdown")); - next_completion_ = nullptr; - } -} - -void SockaddrResolver::MaybeFinishNextLocked() { - if (next_completion_ != nullptr && !published_) { - published_ = true; - grpc_arg arg = grpc_lb_addresses_create_channel_arg(addresses_); - *target_result_ = grpc_channel_args_copy_and_add(channel_args_, &arg, 1); - GRPC_CLOSURE_SCHED(next_completion_, GRPC_ERROR_NONE); - next_completion_ = nullptr; - } +void SockaddrResolver::StartLocked() { + Result result; + result.addresses = std::move(addresses_); + // TODO(roth): Use std::move() once channel args is converted to C++. + result.args = channel_args_; + channel_args_ = nullptr; + result_handler()->ReturnResult(std::move(result)); } // @@ -114,12 +82,12 @@ void SockaddrResolver::MaybeFinishNextLocked() { void DoNothing(void* ignored) {} OrphanablePtr CreateSockaddrResolver( - const ResolverArgs& args, + ResolverArgs args, bool parse(const grpc_uri* uri, grpc_resolved_address* dst)) { if (0 != strcmp(args.uri->authority, "")) { gpr_log(GPR_ERROR, "authority-based URIs not supported by the %s scheme", args.uri->scheme); - return OrphanablePtr(nullptr); + return nullptr; } // Construct addresses. grpc_slice path_slice = @@ -127,34 +95,33 @@ OrphanablePtr CreateSockaddrResolver( grpc_slice_buffer path_parts; grpc_slice_buffer_init(&path_parts); grpc_slice_split(path_slice, ",", &path_parts); - grpc_lb_addresses* addresses = grpc_lb_addresses_create( - path_parts.count, nullptr /* user_data_vtable */); + ServerAddressList addresses; bool errors_found = false; - for (size_t i = 0; i < addresses->num_addresses; i++) { + for (size_t i = 0; i < path_parts.count; i++) { grpc_uri ith_uri = *args.uri; - char* part_str = grpc_slice_to_c_string(path_parts.slices[i]); - ith_uri.path = part_str; - if (!parse(&ith_uri, &addresses->addresses[i].address)) { - errors_found = true; /* GPR_TRUE */ + UniquePtr part_str(grpc_slice_to_c_string(path_parts.slices[i])); + ith_uri.path = part_str.get(); + grpc_resolved_address addr; + if (!parse(&ith_uri, &addr)) { + errors_found = true; + break; } - gpr_free(part_str); - if (errors_found) break; + addresses.emplace_back(addr, nullptr /* args */); } grpc_slice_buffer_destroy_internal(&path_parts); grpc_slice_unref_internal(path_slice); if (errors_found) { - grpc_lb_addresses_destroy(addresses); return OrphanablePtr(nullptr); } // Instantiate resolver. - return OrphanablePtr(New(args, addresses)); + return OrphanablePtr( + New(std::move(addresses), std::move(args))); } class IPv4ResolverFactory : public ResolverFactory { public: - OrphanablePtr CreateResolver( - const ResolverArgs& args) const override { - return CreateSockaddrResolver(args, grpc_parse_ipv4); + OrphanablePtr CreateResolver(ResolverArgs args) const override { + return CreateSockaddrResolver(std::move(args), grpc_parse_ipv4); } const char* scheme() const override { return "ipv4"; } @@ -162,9 +129,8 @@ class IPv4ResolverFactory : public ResolverFactory { class IPv6ResolverFactory : public ResolverFactory { public: - OrphanablePtr CreateResolver( - const ResolverArgs& args) const override { - return CreateSockaddrResolver(args, grpc_parse_ipv6); + OrphanablePtr CreateResolver(ResolverArgs args) const override { + return CreateSockaddrResolver(std::move(args), grpc_parse_ipv6); } const char* scheme() const override { return "ipv6"; } @@ -173,9 +139,8 @@ class IPv6ResolverFactory : public ResolverFactory { #ifdef GRPC_HAVE_UNIX_SOCKET class UnixResolverFactory : public ResolverFactory { public: - OrphanablePtr CreateResolver( - const ResolverArgs& args) const override { - return CreateSockaddrResolver(args, grpc_parse_unix); + OrphanablePtr CreateResolver(ResolverArgs args) const override { + return CreateSockaddrResolver(std::move(args), grpc_parse_unix); } UniquePtr GetDefaultAuthority(grpc_uri* uri) const override { diff --git a/src/core/ext/filters/client_channel/resolver_factory.h b/src/core/ext/filters/client_channel/resolver_factory.h index d891ef62e1d..273fd8d24f0 100644 --- a/src/core/ext/filters/client_channel/resolver_factory.h +++ b/src/core/ext/filters/client_channel/resolver_factory.h @@ -41,12 +41,14 @@ struct ResolverArgs { grpc_pollset_set* pollset_set = nullptr; /// The combiner under which all resolver calls will be run. grpc_combiner* combiner = nullptr; + /// The result handler to be used by the resolver. + UniquePtr result_handler; }; class ResolverFactory { public: /// Returns a new resolver instance. - virtual OrphanablePtr CreateResolver(const ResolverArgs& args) const + virtual OrphanablePtr CreateResolver(ResolverArgs args) const GRPC_ABSTRACT; /// Returns a string representing the default authority to use for this diff --git a/src/core/ext/filters/client_channel/resolver_registry.cc b/src/core/ext/filters/client_channel/resolver_registry.cc index 91c0267f95e..5b00eab341e 100644 --- a/src/core/ext/filters/client_channel/resolver_registry.cc +++ b/src/core/ext/filters/client_channel/resolver_registry.cc @@ -134,7 +134,8 @@ ResolverFactory* ResolverRegistry::LookupResolverFactory(const char* scheme) { OrphanablePtr ResolverRegistry::CreateResolver( const char* target, const grpc_channel_args* args, - grpc_pollset_set* pollset_set, grpc_combiner* combiner) { + grpc_pollset_set* pollset_set, grpc_combiner* combiner, + UniquePtr result_handler) { GPR_ASSERT(g_state != nullptr); grpc_uri* uri = nullptr; char* canonical_target = nullptr; @@ -145,8 +146,10 @@ OrphanablePtr ResolverRegistry::CreateResolver( resolver_args.args = args; resolver_args.pollset_set = pollset_set; resolver_args.combiner = combiner; + resolver_args.result_handler = std::move(result_handler); OrphanablePtr resolver = - factory == nullptr ? nullptr : factory->CreateResolver(resolver_args); + factory == nullptr ? nullptr + : factory->CreateResolver(std::move(resolver_args)); grpc_uri_destroy(uri); gpr_free(canonical_target); return resolver; diff --git a/src/core/ext/filters/client_channel/resolver_registry.h b/src/core/ext/filters/client_channel/resolver_registry.h index d6ec6811bd7..0eec6782609 100644 --- a/src/core/ext/filters/client_channel/resolver_registry.h +++ b/src/core/ext/filters/client_channel/resolver_registry.h @@ -62,10 +62,11 @@ class ResolverRegistry { /// \a args are the channel args to be included in resolver results. /// \a pollset_set is used to drive I/O in the name resolution process. /// \a combiner is the combiner under which all resolver calls will be run. - static OrphanablePtr CreateResolver(const char* target, - const grpc_channel_args* args, - grpc_pollset_set* pollset_set, - grpc_combiner* combiner); + /// \a result_handler is used to return results from the resolver. + static OrphanablePtr CreateResolver( + const char* target, const grpc_channel_args* args, + grpc_pollset_set* pollset_set, grpc_combiner* combiner, + UniquePtr result_handler); /// Returns the default authority to pass from a client for \a target. static UniquePtr GetDefaultAuthority(const char* target); diff --git a/src/core/ext/filters/client_channel/resolver_result_parsing.cc b/src/core/ext/filters/client_channel/resolver_result_parsing.cc index 82a26ace634..ac6bc7ed16a 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.cc +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.cc @@ -30,9 +30,13 @@ #include "src/core/ext/filters/client_channel/client_channel.h" #include "src/core/ext/filters/client_channel/lb_policy_registry.h" +#include "src/core/ext/filters/client_channel/server_address.h" +#include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/status_util.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gprpp/memory.h" +#include "src/core/lib/gprpp/optional.h" +#include "src/core/lib/uri/uri_parser.h" // As per the retry design, we do not allow more than 5 retry attempts. #define MAX_MAX_RETRY_ATTEMPTS 5 @@ -41,220 +45,21 @@ namespace grpc_core { namespace internal { namespace { - -// Converts string format from JSON to proto. -grpc_core::UniquePtr ConvertCamelToSnake(const char* camel) { - const size_t size = strlen(camel); - char* snake = static_cast(gpr_malloc(size * 2)); - size_t j = 0; - for (size_t i = 0; i < size; ++i) { - if (isupper(camel[i])) { - snake[j++] = '_'; - snake[j++] = tolower(camel[i]); - } else { - snake[j++] = camel[i]; - } - } - snake[j] = '\0'; - return grpc_core::UniquePtr(snake); +size_t g_client_channel_service_config_parser_index; } -} // namespace - -ProcessedResolverResult::ProcessedResolverResult( - const grpc_channel_args* resolver_result, bool parse_retry) { - ProcessServiceConfig(resolver_result, parse_retry); - // If no LB config was found above, just find the LB policy name then. - if (lb_policy_config_ == nullptr) ProcessLbPolicyName(resolver_result); +size_t ClientChannelServiceConfigParser::ParserIndex() { + return g_client_channel_service_config_parser_index; } -void ProcessedResolverResult::ProcessServiceConfig( - const grpc_channel_args* resolver_result, bool parse_retry) { - const grpc_arg* channel_arg = - grpc_channel_args_find(resolver_result, GRPC_ARG_SERVICE_CONFIG); - const char* service_config_json = grpc_channel_arg_get_string(channel_arg); - if (service_config_json != nullptr) { - service_config_json_.reset(gpr_strdup(service_config_json)); - service_config_ = grpc_core::ServiceConfig::Create(service_config_json); - if (service_config_ != nullptr) { - if (parse_retry) { - channel_arg = - grpc_channel_args_find(resolver_result, GRPC_ARG_SERVER_URI); - const char* server_uri = grpc_channel_arg_get_string(channel_arg); - GPR_ASSERT(server_uri != nullptr); - grpc_uri* uri = grpc_uri_parse(server_uri, true); - GPR_ASSERT(uri->path[0] != '\0'); - server_name_ = uri->path[0] == '/' ? uri->path + 1 : uri->path; - service_config_->ParseGlobalParams(ParseServiceConfig, this); - grpc_uri_destroy(uri); - } else { - service_config_->ParseGlobalParams(ParseServiceConfig, this); - } - method_params_table_ = service_config_->CreateMethodConfigTable( - ClientChannelMethodParams::CreateFromJson); - } - } -} - -void ProcessedResolverResult::ProcessLbPolicyName( - const grpc_channel_args* resolver_result) { - const char* lb_policy_name = nullptr; - // Prefer the LB policy name found in the service config. Note that this is - // checking the deprecated loadBalancingPolicy field, rather than the new - // loadBalancingConfig field. - if (service_config_ != nullptr) { - lb_policy_name = service_config_->GetLoadBalancingPolicyName(); - } - // Otherwise, find the LB policy name set by the client API. - if (lb_policy_name == nullptr) { - const grpc_arg* channel_arg = - grpc_channel_args_find(resolver_result, GRPC_ARG_LB_POLICY_NAME); - lb_policy_name = grpc_channel_arg_get_string(channel_arg); - } - // Special case: If at least one balancer address is present, we use - // the grpclb policy, regardless of what the resolver has returned. - const grpc_arg* channel_arg = - grpc_channel_args_find(resolver_result, GRPC_ARG_LB_ADDRESSES); - if (channel_arg != nullptr && channel_arg->type == GRPC_ARG_POINTER) { - grpc_lb_addresses* addresses = - static_cast(channel_arg->value.pointer.p); - if (grpc_lb_addresses_contains_balancer_address(*addresses)) { - if (lb_policy_name != nullptr && - gpr_stricmp(lb_policy_name, "grpclb") != 0) { - gpr_log(GPR_INFO, - "resolver requested LB policy %s but provided at least one " - "balancer address -- forcing use of grpclb LB policy", - lb_policy_name); - } - lb_policy_name = "grpclb"; - } - } - // Use pick_first if nothing was specified and we didn't select grpclb - // above. - if (lb_policy_name == nullptr) lb_policy_name = "pick_first"; - lb_policy_name_.reset(gpr_strdup(lb_policy_name)); -} - -void ProcessedResolverResult::ParseServiceConfig( - const grpc_json* field, ProcessedResolverResult* parsing_state) { - parsing_state->ParseLbConfigFromServiceConfig(field); - if (parsing_state->server_name_ != nullptr) { - parsing_state->ParseRetryThrottleParamsFromServiceConfig(field); - } -} - -void ProcessedResolverResult::ParseLbConfigFromServiceConfig( - const grpc_json* field) { - if (lb_policy_config_ != nullptr) return; // Already found. - // Find the LB config global parameter. - if (field->key == nullptr || strcmp(field->key, "loadBalancingConfig") != 0 || - field->type != GRPC_JSON_ARRAY) { - return; // Not valid lb config array. - } - // Find the first LB policy that this client supports. - for (grpc_json* lb_config = field->child; lb_config != nullptr; - lb_config = lb_config->next) { - if (lb_config->type != GRPC_JSON_OBJECT) return; - // Find the policy object. - grpc_json* policy = nullptr; - for (grpc_json* field = lb_config->child; field != nullptr; - field = field->next) { - if (field->key == nullptr || strcmp(field->key, "policy") != 0 || - field->type != GRPC_JSON_OBJECT) { - return; - } - if (policy != nullptr) return; // Duplicate. - policy = field; - } - // Find the specific policy content since the policy object is of type - // "oneof". - grpc_json* policy_content = nullptr; - for (grpc_json* field = policy->child; field != nullptr; - field = field->next) { - if (field->key == nullptr || field->type != GRPC_JSON_OBJECT) return; - if (policy_content != nullptr) return; // Violate "oneof" type. - policy_content = field; - } - grpc_core::UniquePtr lb_policy_name = - ConvertCamelToSnake(policy_content->key); - if (!grpc_core::LoadBalancingPolicyRegistry::LoadBalancingPolicyExists( - lb_policy_name.get())) { - continue; - } - lb_policy_name_ = std::move(lb_policy_name); - lb_policy_config_ = policy_content->child; - return; - } -} - -void ProcessedResolverResult::ParseRetryThrottleParamsFromServiceConfig( - const grpc_json* field) { - if (strcmp(field->key, "retryThrottling") == 0) { - if (retry_throttle_data_ != nullptr) return; // Duplicate. - if (field->type != GRPC_JSON_OBJECT) return; - int max_milli_tokens = 0; - int milli_token_ratio = 0; - for (grpc_json* sub_field = field->child; sub_field != nullptr; - sub_field = sub_field->next) { - if (sub_field->key == nullptr) return; - if (strcmp(sub_field->key, "maxTokens") == 0) { - if (max_milli_tokens != 0) return; // Duplicate. - if (sub_field->type != GRPC_JSON_NUMBER) return; - max_milli_tokens = gpr_parse_nonnegative_int(sub_field->value); - if (max_milli_tokens == -1) return; - max_milli_tokens *= 1000; - } else if (strcmp(sub_field->key, "tokenRatio") == 0) { - if (milli_token_ratio != 0) return; // Duplicate. - if (sub_field->type != GRPC_JSON_NUMBER) return; - // We support up to 3 decimal digits. - size_t whole_len = strlen(sub_field->value); - uint32_t multiplier = 1; - uint32_t decimal_value = 0; - const char* decimal_point = strchr(sub_field->value, '.'); - if (decimal_point != nullptr) { - whole_len = static_cast(decimal_point - sub_field->value); - multiplier = 1000; - size_t decimal_len = strlen(decimal_point + 1); - if (decimal_len > 3) decimal_len = 3; - if (!gpr_parse_bytes_to_uint32(decimal_point + 1, decimal_len, - &decimal_value)) { - return; - } - uint32_t decimal_multiplier = 1; - for (size_t i = 0; i < (3 - decimal_len); ++i) { - decimal_multiplier *= 10; - } - decimal_value *= decimal_multiplier; - } - uint32_t whole_value; - if (!gpr_parse_bytes_to_uint32(sub_field->value, whole_len, - &whole_value)) { - return; - } - milli_token_ratio = - static_cast((whole_value * multiplier) + decimal_value); - if (milli_token_ratio <= 0) return; - } - } - retry_throttle_data_ = - grpc_core::internal::ServerRetryThrottleMap::GetDataForServer( - server_name_, max_milli_tokens, milli_token_ratio); - } +void ClientChannelServiceConfigParser::Register() { + g_client_channel_service_config_parser_index = + ServiceConfig::RegisterParser(UniquePtr( + New())); } namespace { -bool ParseWaitForReady( - grpc_json* field, ClientChannelMethodParams::WaitForReady* wait_for_ready) { - if (field->type != GRPC_JSON_TRUE && field->type != GRPC_JSON_FALSE) { - return false; - } - *wait_for_ready = field->type == GRPC_JSON_TRUE - ? ClientChannelMethodParams::WAIT_FOR_READY_TRUE - : ClientChannelMethodParams::WAIT_FOR_READY_FALSE; - return true; -} - // Parses a JSON field of the form generated for a google.proto.Duration // proto message, as per: // https://developers.google.com/protocol-buffers/docs/proto3#json @@ -287,18 +92,36 @@ bool ParseDuration(grpc_json* field, grpc_millis* duration) { return true; } -UniquePtr ParseRetryPolicy( - grpc_json* field) { - auto retry_policy = MakeUnique(); - if (field->type != GRPC_JSON_OBJECT) return nullptr; +UniquePtr ParseRetryPolicy( + grpc_json* field, grpc_error** error) { + GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); + auto retry_policy = + MakeUnique(); + if (field->type != GRPC_JSON_OBJECT) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryPolicy error:should be of type object"); + return nullptr; + } + InlinedVector error_list; for (grpc_json* sub_field = field->child; sub_field != nullptr; sub_field = sub_field->next) { - if (sub_field->key == nullptr) return nullptr; + if (sub_field->key == nullptr) continue; if (strcmp(sub_field->key, "maxAttempts") == 0) { - if (retry_policy->max_attempts != 0) return nullptr; // Duplicate. - if (sub_field->type != GRPC_JSON_NUMBER) return nullptr; + if (retry_policy->max_attempts != 0) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxAttempts error:Duplicate entry")); + } // Duplicate. Continue Parsing + if (sub_field->type != GRPC_JSON_NUMBER) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxAttempts error:should be of type number")); + continue; + } retry_policy->max_attempts = gpr_parse_nonnegative_int(sub_field->value); - if (retry_policy->max_attempts <= 1) return nullptr; + if (retry_policy->max_attempts <= 1) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxAttempts error:should be at least 2")); + continue; + } if (retry_policy->max_attempts > MAX_MAX_RETRY_ATTEMPTS) { gpr_log(GPR_ERROR, "service config: clamped retryPolicy.maxAttempts at %d", @@ -306,78 +129,375 @@ UniquePtr ParseRetryPolicy( retry_policy->max_attempts = MAX_MAX_RETRY_ATTEMPTS; } } else if (strcmp(sub_field->key, "initialBackoff") == 0) { - if (retry_policy->initial_backoff > 0) return nullptr; // Duplicate. + if (retry_policy->initial_backoff > 0) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:initialBackoff error:Duplicate entry")); + } // Duplicate, continue parsing. if (!ParseDuration(sub_field, &retry_policy->initial_backoff)) { - return nullptr; + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:initialBackoff error:Failed to parse")); + continue; + } + if (retry_policy->initial_backoff == 0) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:initialBackoff error:must be greater than 0")); } - if (retry_policy->initial_backoff == 0) return nullptr; } else if (strcmp(sub_field->key, "maxBackoff") == 0) { - if (retry_policy->max_backoff > 0) return nullptr; // Duplicate. + if (retry_policy->max_backoff > 0) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxBackoff error:Duplicate entry")); + } // Duplicate, continue parsing. if (!ParseDuration(sub_field, &retry_policy->max_backoff)) { - return nullptr; + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxBackoff error:failed to parse")); + continue; + } + if (retry_policy->max_backoff == 0) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxBackoff error:should be greater than 0")); } - if (retry_policy->max_backoff == 0) return nullptr; } else if (strcmp(sub_field->key, "backoffMultiplier") == 0) { - if (retry_policy->backoff_multiplier != 0) return nullptr; // Duplicate. - if (sub_field->type != GRPC_JSON_NUMBER) return nullptr; + if (retry_policy->backoff_multiplier != 0) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:backoffMultiplier error:Duplicate entry")); + } // Duplicate, continue parsing. + if (sub_field->type != GRPC_JSON_NUMBER) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:backoffMultiplier error:should be of type number")); + continue; + } if (sscanf(sub_field->value, "%f", &retry_policy->backoff_multiplier) != 1) { - return nullptr; + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:backoffMultiplier error:failed to parse")); + continue; + } + if (retry_policy->backoff_multiplier <= 0) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:backoffMultiplier error:should be greater than 0")); } - if (retry_policy->backoff_multiplier <= 0) return nullptr; } else if (strcmp(sub_field->key, "retryableStatusCodes") == 0) { if (!retry_policy->retryable_status_codes.Empty()) { - return nullptr; // Duplicate. + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryableStatusCodes error:Duplicate entry")); + } // Duplicate, continue parsing. + if (sub_field->type != GRPC_JSON_ARRAY) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryableStatusCodes error:should be of type array")); + continue; } - if (sub_field->type != GRPC_JSON_ARRAY) return nullptr; for (grpc_json* element = sub_field->child; element != nullptr; element = element->next) { - if (element->type != GRPC_JSON_STRING) return nullptr; + if (element->type != GRPC_JSON_STRING) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryableStatusCodes error:status codes should be of type " + "string")); + continue; + } grpc_status_code status; if (!grpc_status_code_from_string(element->value, &status)) { - return nullptr; + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryableStatusCodes error:failed to parse status code")); + continue; } retry_policy->retryable_status_codes.Add(status); } - if (retry_policy->retryable_status_codes.Empty()) return nullptr; + if (retry_policy->retryable_status_codes.Empty()) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryableStatusCodes error:should be non-empty")); + }; } } // Make sure required fields are set. - if (retry_policy->max_attempts == 0 || retry_policy->initial_backoff == 0 || - retry_policy->max_backoff == 0 || retry_policy->backoff_multiplier == 0 || - retry_policy->retryable_status_codes.Empty()) { + if (error_list.empty()) { + if (retry_policy->max_attempts == 0 || retry_policy->initial_backoff == 0 || + retry_policy->max_backoff == 0 || + retry_policy->backoff_multiplier == 0 || + retry_policy->retryable_status_codes.Empty()) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryPolicy error:Missing required field(s)"); + return nullptr; + } + } + *error = GRPC_ERROR_CREATE_FROM_VECTOR("retryPolicy", &error_list); + return *error == GRPC_ERROR_NONE ? std::move(retry_policy) : nullptr; +} + +const char* ParseHealthCheckConfig(const grpc_json* field, grpc_error** error) { + GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); + const char* service_name = nullptr; + GPR_DEBUG_ASSERT(strcmp(field->key, "healthCheckConfig") == 0); + if (field->type != GRPC_JSON_OBJECT) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:healthCheckConfig error:should be of type object"); return nullptr; } - return retry_policy; + InlinedVector error_list; + for (grpc_json* sub_field = field->child; sub_field != nullptr; + sub_field = sub_field->next) { + if (sub_field->key == nullptr) { + GPR_DEBUG_ASSERT(false); + continue; + } + if (strcmp(sub_field->key, "serviceName") == 0) { + if (service_name != nullptr) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:serviceName error:Duplicate " + "entry")); + } // Duplicate. Continue parsing + if (sub_field->type != GRPC_JSON_STRING) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:serviceName error:should be of type string")); + continue; + } + service_name = sub_field->value; + } + } + if (!error_list.empty()) { + return nullptr; + } + *error = + GRPC_ERROR_CREATE_FROM_VECTOR("field:healthCheckConfig", &error_list); + return service_name; } } // namespace -RefCountedPtr -ClientChannelMethodParams::CreateFromJson(const grpc_json* json) { - RefCountedPtr method_params = - MakeRefCounted(); +UniquePtr +ClientChannelServiceConfigParser::ParseGlobalParams(const grpc_json* json, + grpc_error** error) { + GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); + InlinedVector error_list; + RefCountedPtr parsed_lb_config; + UniquePtr lb_policy_name; + Optional retry_throttling; + const char* health_check_service_name = nullptr; + for (grpc_json* field = json->child; field != nullptr; field = field->next) { + if (field->key == nullptr) { + continue; // Not the LB config global parameter + } + // Parsed Load balancing config + if (strcmp(field->key, "loadBalancingConfig") == 0) { + if (parsed_lb_config != nullptr) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:loadBalancingConfig error:Duplicate entry")); + } // Duplicate, continue parsing. + grpc_error* parse_error = GRPC_ERROR_NONE; + parsed_lb_config = LoadBalancingPolicyRegistry::ParseLoadBalancingConfig( + field, &parse_error); + if (parsed_lb_config == nullptr) { + error_list.push_back(parse_error); + } + } + // Parse deprecated loadBalancingPolicy + if (strcmp(field->key, "loadBalancingPolicy") == 0) { + if (lb_policy_name != nullptr) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:loadBalancingPolicy error:Duplicate entry")); + } // Duplicate, continue parsing. + if (field->type != GRPC_JSON_STRING) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:loadBalancingPolicy error:type should be string")); + continue; + } + lb_policy_name.reset(gpr_strdup(field->value)); + char* lb_policy = lb_policy_name.get(); + if (lb_policy != nullptr) { + for (size_t i = 0; i < strlen(lb_policy); ++i) { + lb_policy[i] = tolower(lb_policy[i]); + } + } + bool requires_config = false; + if (!LoadBalancingPolicyRegistry::LoadBalancingPolicyExists( + lb_policy, &requires_config)) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:loadBalancingPolicy error:Unknown lb policy")); + } else if (requires_config) { + char* error_msg; + gpr_asprintf(&error_msg, + "field:loadBalancingPolicy error:%s requires a config. " + "Please use loadBalancingConfig instead.", + lb_policy); + error_list.push_back(GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg)); + gpr_free(error_msg); + } + } + // Parse retry throttling + if (strcmp(field->key, "retryThrottling") == 0) { + if (retry_throttling.has_value()) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryThrottling error:Duplicate entry")); + } // Duplicate, continue parsing. + if (field->type != GRPC_JSON_OBJECT) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryThrottling error:Type should be object")); + continue; + } + Optional max_milli_tokens; + Optional milli_token_ratio; + for (grpc_json* sub_field = field->child; sub_field != nullptr; + sub_field = sub_field->next) { + if (sub_field->key == nullptr) continue; + if (strcmp(sub_field->key, "maxTokens") == 0) { + if (max_milli_tokens.has_value()) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryThrottling field:maxTokens error:Duplicate " + "entry")); + } // Duplicate, continue parsing. + if (sub_field->type != GRPC_JSON_NUMBER) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryThrottling field:maxTokens error:Type should be " + "number")); + } else { + max_milli_tokens.set(gpr_parse_nonnegative_int(sub_field->value) * + 1000); + if (max_milli_tokens.value() <= 0) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryThrottling field:maxTokens error:should be " + "greater than zero")); + } + } + } else if (strcmp(sub_field->key, "tokenRatio") == 0) { + if (milli_token_ratio.has_value()) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryThrottling field:tokenRatio error:Duplicate " + "entry")); + } // Duplicate, continue parsing. + if (sub_field->type != GRPC_JSON_NUMBER) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryThrottling field:tokenRatio error:type should be " + "number")); + } else { + // We support up to 3 decimal digits. + size_t whole_len = strlen(sub_field->value); + uint32_t multiplier = 1; + uint32_t decimal_value = 0; + const char* decimal_point = strchr(sub_field->value, '.'); + if (decimal_point != nullptr) { + whole_len = static_cast(decimal_point - sub_field->value); + multiplier = 1000; + size_t decimal_len = strlen(decimal_point + 1); + if (decimal_len > 3) decimal_len = 3; + if (!gpr_parse_bytes_to_uint32(decimal_point + 1, decimal_len, + &decimal_value)) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryThrottling field:tokenRatio error:Failed " + "parsing")); + continue; + } + uint32_t decimal_multiplier = 1; + for (size_t i = 0; i < (3 - decimal_len); ++i) { + decimal_multiplier *= 10; + } + decimal_value *= decimal_multiplier; + } + uint32_t whole_value; + if (!gpr_parse_bytes_to_uint32(sub_field->value, whole_len, + &whole_value)) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryThrottling field:tokenRatio error:Failed " + "parsing")); + continue; + } + milli_token_ratio.set( + static_cast((whole_value * multiplier) + decimal_value)); + if (milli_token_ratio.value() <= 0) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryThrottling field:tokenRatio error:value should " + "be greater than 0")); + } + } + } + } + ClientChannelGlobalParsedObject::RetryThrottling data; + if (!max_milli_tokens.has_value()) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryThrottling field:maxTokens error:Not found")); + } else { + data.max_milli_tokens = max_milli_tokens.value(); + } + if (!milli_token_ratio.has_value()) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryThrottling field:tokenRatio error:Not found")); + } else { + data.milli_token_ratio = milli_token_ratio.value(); + } + retry_throttling.set(data); + } + if (strcmp(field->key, "healthCheckConfig") == 0) { + if (health_check_service_name != nullptr) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:healthCheckConfig error:Duplicate entry")); + } // Duplicate continue parsing + grpc_error* parsing_error = GRPC_ERROR_NONE; + health_check_service_name = ParseHealthCheckConfig(field, &parsing_error); + if (parsing_error != GRPC_ERROR_NONE) { + error_list.push_back(parsing_error); + } + } + } + *error = GRPC_ERROR_CREATE_FROM_VECTOR("Client channel global parser", + &error_list); + if (*error == GRPC_ERROR_NONE) { + return UniquePtr( + New( + std::move(parsed_lb_config), std::move(lb_policy_name), + retry_throttling, health_check_service_name)); + } + return nullptr; +} + +UniquePtr +ClientChannelServiceConfigParser::ParsePerMethodParams(const grpc_json* json, + grpc_error** error) { + GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); + InlinedVector error_list; + Optional wait_for_ready; + grpc_millis timeout = 0; + UniquePtr retry_policy; for (grpc_json* field = json->child; field != nullptr; field = field->next) { if (field->key == nullptr) continue; if (strcmp(field->key, "waitForReady") == 0) { - if (method_params->wait_for_ready_ != WAIT_FOR_READY_UNSET) { - return nullptr; // Duplicate. - } - if (!ParseWaitForReady(field, &method_params->wait_for_ready_)) { - return nullptr; + if (wait_for_ready.has_value()) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:waitForReady error:Duplicate entry")); + } // Duplicate, continue parsing. + if (field->type == GRPC_JSON_TRUE) { + wait_for_ready.set(true); + } else if (field->type == GRPC_JSON_FALSE) { + wait_for_ready.set(false); + } else { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:waitForReady error:Type should be true/false")); } } else if (strcmp(field->key, "timeout") == 0) { - if (method_params->timeout_ > 0) return nullptr; // Duplicate. - if (!ParseDuration(field, &method_params->timeout_)) return nullptr; + if (timeout > 0) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:timeout error:Duplicate entry")); + } // Duplicate, continue parsing. + if (!ParseDuration(field, &timeout)) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:timeout error:Failed parsing")); + }; } else if (strcmp(field->key, "retryPolicy") == 0) { - if (method_params->retry_policy_ != nullptr) { - return nullptr; // Duplicate. + if (retry_policy != nullptr) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryPolicy error:Duplicate entry")); + } // Duplicate, continue parsing. + grpc_error* error = GRPC_ERROR_NONE; + retry_policy = ParseRetryPolicy(field, &error); + if (retry_policy == nullptr) { + error_list.push_back(error); } - method_params->retry_policy_ = ParseRetryPolicy(field); - if (method_params->retry_policy_ == nullptr) return nullptr; } } - return method_params; + *error = GRPC_ERROR_CREATE_FROM_VECTOR("Client channel parser", &error_list); + if (*error == GRPC_ERROR_NONE) { + return UniquePtr( + New(timeout, wait_for_ready, + std::move(retry_policy))); + } + return nullptr; } } // namespace internal diff --git a/src/core/ext/filters/client_channel/resolver_result_parsing.h b/src/core/ext/filters/client_channel/resolver_result_parsing.h index f1fb7406bcb..9af8b16876a 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.h +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.h @@ -21,91 +21,64 @@ #include +#include "src/core/ext/filters/client_channel/lb_policy.h" +#include "src/core/ext/filters/client_channel/lb_policy_factory.h" +#include "src/core/ext/filters/client_channel/resolver.h" #include "src/core/ext/filters/client_channel/retry_throttle.h" +#include "src/core/ext/filters/client_channel/service_config.h" #include "src/core/lib/channel/status_util.h" +#include "src/core/lib/gprpp/optional.h" #include "src/core/lib/gprpp/ref_counted.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/exec_ctx.h" // for grpc_millis #include "src/core/lib/json/json.h" #include "src/core/lib/slice/slice_hash_table.h" -#include "src/core/lib/transport/service_config.h" namespace grpc_core { namespace internal { -class ClientChannelMethodParams; - -// A table mapping from a method name to its method parameters. -typedef grpc_core::SliceHashTable< - grpc_core::RefCountedPtr> - ClientChannelMethodParamsTable; - -// A container of processed fields from the resolver result. Simplifies the -// usage of resolver result. -class ProcessedResolverResult { +class ClientChannelGlobalParsedObject : public ServiceConfig::ParsedConfig { public: - // Processes the resolver result and populates the relative members - // for later consumption. Tries to parse retry parameters only if parse_retry - // is true. - ProcessedResolverResult(const grpc_channel_args* resolver_result, - bool parse_retry); - - // Getters. Any managed object's ownership is transferred. - grpc_core::UniquePtr service_config_json() { - return std::move(service_config_json_); - } - grpc_core::RefCountedPtr retry_throttle_data() { - return std::move(retry_throttle_data_); - } - grpc_core::RefCountedPtr - method_params_table() { - return std::move(method_params_table_); - } - grpc_core::UniquePtr lb_policy_name() { - return std::move(lb_policy_name_); - } - grpc_json* lb_policy_config() { return lb_policy_config_; } - - private: - // Finds the service config; extracts LB config and (maybe) retry throttle - // params from it. - void ProcessServiceConfig(const grpc_channel_args* resolver_result, - bool parse_retry); - - // Finds the LB policy name (when no LB config was found). - void ProcessLbPolicyName(const grpc_channel_args* resolver_result); - - // Parses the service config. Intended to be used by - // ServiceConfig::ParseGlobalParams. - static void ParseServiceConfig(const grpc_json* field, - ProcessedResolverResult* parsing_state); - // Parses the LB config from service config. - void ParseLbConfigFromServiceConfig(const grpc_json* field); - // Parses the retry throttle parameters from service config. - void ParseRetryThrottleParamsFromServiceConfig(const grpc_json* field); - - // Service config. - grpc_core::UniquePtr service_config_json_; - grpc_core::UniquePtr service_config_; - // LB policy. - grpc_json* lb_policy_config_ = nullptr; - grpc_core::UniquePtr lb_policy_name_; - // Retry throttle data. - char* server_name_ = nullptr; - grpc_core::RefCountedPtr retry_throttle_data_; - // Method params table. - grpc_core::RefCountedPtr method_params_table_; -}; - -// The parameters of a method. -class ClientChannelMethodParams : public RefCounted { - public: - enum WaitForReady { - WAIT_FOR_READY_UNSET = 0, - WAIT_FOR_READY_FALSE, - WAIT_FOR_READY_TRUE + struct RetryThrottling { + intptr_t max_milli_tokens = 0; + intptr_t milli_token_ratio = 0; }; + ClientChannelGlobalParsedObject( + RefCountedPtr parsed_lb_config, + UniquePtr parsed_deprecated_lb_policy, + const Optional& retry_throttling, + const char* health_check_service_name) + : parsed_lb_config_(std::move(parsed_lb_config)), + parsed_deprecated_lb_policy_(std::move(parsed_deprecated_lb_policy)), + retry_throttling_(retry_throttling), + health_check_service_name_(health_check_service_name) {} + + Optional retry_throttling() const { + return retry_throttling_; + } + + RefCountedPtr parsed_lb_config() const { + return parsed_lb_config_; + } + + const char* parsed_deprecated_lb_policy() const { + return parsed_deprecated_lb_policy_.get(); + } + + const char* health_check_service_name() const { + return health_check_service_name_; + } + + private: + RefCountedPtr parsed_lb_config_; + UniquePtr parsed_deprecated_lb_policy_; + Optional retry_throttling_; + const char* health_check_service_name_; +}; + +class ClientChannelMethodParsedObject : public ServiceConfig::ParsedConfig { + public: struct RetryPolicy { int max_attempts = 0; grpc_millis initial_backoff = 0; @@ -114,32 +87,37 @@ class ClientChannelMethodParams : public RefCounted { StatusCodeSet retryable_status_codes; }; - /// Creates a method_parameters object from \a json. - /// Intended for use with ServiceConfig::CreateMethodConfigTable(). - static RefCountedPtr CreateFromJson( - const grpc_json* json); + ClientChannelMethodParsedObject(grpc_millis timeout, + const Optional& wait_for_ready, + UniquePtr retry_policy) + : timeout_(timeout), + wait_for_ready_(wait_for_ready), + retry_policy_(std::move(retry_policy)) {} grpc_millis timeout() const { return timeout_; } - WaitForReady wait_for_ready() const { return wait_for_ready_; } + + Optional wait_for_ready() const { return wait_for_ready_; } + const RetryPolicy* retry_policy() const { return retry_policy_.get(); } private: - // So New() can call our private ctor. - template - friend T* grpc_core::New(Args&&... args); - - // So Delete() can call our private dtor. - template - friend void grpc_core::Delete(T*); - - ClientChannelMethodParams() {} - virtual ~ClientChannelMethodParams() {} - grpc_millis timeout_ = 0; - WaitForReady wait_for_ready_ = WAIT_FOR_READY_UNSET; + Optional wait_for_ready_; UniquePtr retry_policy_; }; +class ClientChannelServiceConfigParser : public ServiceConfig::Parser { + public: + UniquePtr ParseGlobalParams( + const grpc_json* json, grpc_error** error) override; + + UniquePtr ParsePerMethodParams( + const grpc_json* json, grpc_error** error) override; + + static size_t ParserIndex(); + static void Register(); +}; + } // namespace internal } // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/resolving_lb_policy.cc b/src/core/ext/filters/client_channel/resolving_lb_policy.cc new file mode 100644 index 00000000000..4e383f65dd1 --- /dev/null +++ b/src/core/ext/filters/client_channel/resolving_lb_policy.cc @@ -0,0 +1,579 @@ +/* + * + * 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 + +#include "src/core/ext/filters/client_channel/resolving_lb_policy.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "src/core/ext/filters/client_channel/backup_poller.h" +#include "src/core/ext/filters/client_channel/http_connect_handshaker.h" +#include "src/core/ext/filters/client_channel/lb_policy_registry.h" +#include "src/core/ext/filters/client_channel/proxy_mapper_registry.h" +#include "src/core/ext/filters/client_channel/resolver_registry.h" +#include "src/core/ext/filters/client_channel/retry_throttle.h" +#include "src/core/ext/filters/client_channel/server_address.h" +#include "src/core/ext/filters/client_channel/service_config.h" +#include "src/core/ext/filters/client_channel/subchannel.h" +#include "src/core/ext/filters/deadline/deadline_filter.h" +#include "src/core/lib/backoff/backoff.h" +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/channel/connected_channel.h" +#include "src/core/lib/channel/status_util.h" +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/inlined_vector.h" +#include "src/core/lib/gprpp/manual_constructor.h" +#include "src/core/lib/gprpp/sync.h" +#include "src/core/lib/iomgr/combiner.h" +#include "src/core/lib/iomgr/iomgr.h" +#include "src/core/lib/iomgr/polling_entity.h" +#include "src/core/lib/profiling/timers.h" +#include "src/core/lib/slice/slice_internal.h" +#include "src/core/lib/slice/slice_string_helpers.h" +#include "src/core/lib/surface/channel.h" +#include "src/core/lib/transport/connectivity_state.h" +#include "src/core/lib/transport/error_utils.h" +#include "src/core/lib/transport/metadata.h" +#include "src/core/lib/transport/metadata_batch.h" +#include "src/core/lib/transport/static_metadata.h" +#include "src/core/lib/transport/status_metadata.h" + +namespace grpc_core { + +// +// ResolvingLoadBalancingPolicy::ResolverResultHandler +// + +class ResolvingLoadBalancingPolicy::ResolverResultHandler + : public Resolver::ResultHandler { + public: + explicit ResolverResultHandler( + RefCountedPtr parent) + : parent_(std::move(parent)) {} + + ~ResolverResultHandler() { + if (GRPC_TRACE_FLAG_ENABLED(*(parent_->tracer_))) { + gpr_log(GPR_INFO, "resolving_lb=%p: resolver shutdown complete", + parent_.get()); + } + } + + void ReturnResult(Resolver::Result result) override { + parent_->OnResolverResultChangedLocked(std::move(result)); + } + + void ReturnError(grpc_error* error) override { + parent_->OnResolverError(error); + } + + private: + RefCountedPtr parent_; +}; + +// +// ResolvingLoadBalancingPolicy::ResolvingControlHelper +// + +class ResolvingLoadBalancingPolicy::ResolvingControlHelper + : public LoadBalancingPolicy::ChannelControlHelper { + public: + explicit ResolvingControlHelper( + RefCountedPtr parent) + : parent_(std::move(parent)) {} + + Subchannel* CreateSubchannel(const grpc_channel_args& args) override { + if (parent_->resolver_ == nullptr) return nullptr; // Shutting down. + if (!CalledByCurrentChild() && !CalledByPendingChild()) return nullptr; + return parent_->channel_control_helper()->CreateSubchannel(args); + } + + grpc_channel* CreateChannel(const char* target, + const grpc_channel_args& args) override { + if (parent_->resolver_ == nullptr) return nullptr; // Shutting down. + if (!CalledByCurrentChild() && !CalledByPendingChild()) return nullptr; + return parent_->channel_control_helper()->CreateChannel(target, args); + } + + void UpdateState(grpc_connectivity_state state, + UniquePtr picker) override { + if (parent_->resolver_ == nullptr) return; // Shutting down. + // If this request is from the pending child policy, ignore it until + // it reports READY, at which point we swap it into place. + if (CalledByPendingChild()) { + if (GRPC_TRACE_FLAG_ENABLED(*(parent_->tracer_))) { + gpr_log(GPR_INFO, + "resolving_lb=%p helper=%p: pending child policy %p reports " + "state=%s", + parent_.get(), this, child_, + grpc_connectivity_state_name(state)); + } + if (state != GRPC_CHANNEL_READY) return; + grpc_pollset_set_del_pollset_set( + parent_->lb_policy_->interested_parties(), + parent_->interested_parties()); + MutexLock lock(&parent_->lb_policy_mu_); + parent_->lb_policy_ = std::move(parent_->pending_lb_policy_); + } else if (!CalledByCurrentChild()) { + // This request is from an outdated child, so ignore it. + return; + } + parent_->channel_control_helper()->UpdateState(state, std::move(picker)); + } + + void RequestReresolution() override { + // If there is a pending child policy, ignore re-resolution requests + // from the current child policy (or any outdated child). + if (parent_->pending_lb_policy_ != nullptr && !CalledByPendingChild()) { + return; + } + if (GRPC_TRACE_FLAG_ENABLED(*(parent_->tracer_))) { + gpr_log(GPR_INFO, "resolving_lb=%p: started name re-resolving", + parent_.get()); + } + if (parent_->resolver_ != nullptr) { + parent_->resolver_->RequestReresolutionLocked(); + } + } + + void set_child(LoadBalancingPolicy* child) { child_ = child; } + + private: + bool CalledByPendingChild() const { + GPR_ASSERT(child_ != nullptr); + return child_ == parent_->pending_lb_policy_.get(); + } + + bool CalledByCurrentChild() const { + GPR_ASSERT(child_ != nullptr); + return child_ == parent_->lb_policy_.get(); + }; + + RefCountedPtr parent_; + LoadBalancingPolicy* child_ = nullptr; +}; + +// +// ResolvingLoadBalancingPolicy +// + +ResolvingLoadBalancingPolicy::ResolvingLoadBalancingPolicy( + Args args, TraceFlag* tracer, UniquePtr target_uri, + UniquePtr child_policy_name, + RefCountedPtr child_lb_config, + grpc_error** error) + : LoadBalancingPolicy(std::move(args)), + tracer_(tracer), + target_uri_(std::move(target_uri)), + child_policy_name_(std::move(child_policy_name)), + child_lb_config_(std::move(child_lb_config)) { + GPR_ASSERT(child_policy_name_ != nullptr); + // Don't fetch service config, since this ctor is for use in nested LB + // policies, not at the top level, and we only fetch the service + // config at the top level. + grpc_arg arg = grpc_channel_arg_integer_create( + const_cast(GRPC_ARG_SERVICE_CONFIG_DISABLE_RESOLUTION), 0); + grpc_channel_args* new_args = + grpc_channel_args_copy_and_add(args.args, &arg, 1); + *error = Init(*new_args); + grpc_channel_args_destroy(new_args); +} + +ResolvingLoadBalancingPolicy::ResolvingLoadBalancingPolicy( + Args args, TraceFlag* tracer, UniquePtr target_uri, + ProcessResolverResultCallback process_resolver_result, + void* process_resolver_result_user_data, grpc_error** error) + : LoadBalancingPolicy(std::move(args)), + tracer_(tracer), + target_uri_(std::move(target_uri)), + process_resolver_result_(process_resolver_result), + process_resolver_result_user_data_(process_resolver_result_user_data) { + GPR_ASSERT(process_resolver_result != nullptr); + gpr_mu_init(&lb_policy_mu_); + *error = Init(*args.args); +} + +grpc_error* ResolvingLoadBalancingPolicy::Init(const grpc_channel_args& args) { + resolver_ = ResolverRegistry::CreateResolver( + target_uri_.get(), &args, interested_parties(), combiner(), + UniquePtr(New(Ref()))); + if (resolver_ == nullptr) { + return GRPC_ERROR_CREATE_FROM_STATIC_STRING("resolver creation failed"); + } + // Return our picker to the channel. + channel_control_helper()->UpdateState( + GRPC_CHANNEL_IDLE, UniquePtr(New(Ref()))); + return GRPC_ERROR_NONE; +} + +ResolvingLoadBalancingPolicy::~ResolvingLoadBalancingPolicy() { + GPR_ASSERT(resolver_ == nullptr); + GPR_ASSERT(lb_policy_ == nullptr); + gpr_mu_destroy(&lb_policy_mu_); +} + +void ResolvingLoadBalancingPolicy::ShutdownLocked() { + if (resolver_ != nullptr) { + resolver_.reset(); + MutexLock lock(&lb_policy_mu_); + if (lb_policy_ != nullptr) { + if (GRPC_TRACE_FLAG_ENABLED(*tracer_)) { + gpr_log(GPR_INFO, "resolving_lb=%p: shutting down lb_policy=%p", this, + lb_policy_.get()); + } + grpc_pollset_set_del_pollset_set(lb_policy_->interested_parties(), + interested_parties()); + lb_policy_.reset(); + } + if (pending_lb_policy_ != nullptr) { + if (GRPC_TRACE_FLAG_ENABLED(*tracer_)) { + gpr_log(GPR_INFO, "resolving_lb=%p: shutting down pending lb_policy=%p", + this, pending_lb_policy_.get()); + } + grpc_pollset_set_del_pollset_set(pending_lb_policy_->interested_parties(), + interested_parties()); + pending_lb_policy_.reset(); + } + } +} + +void ResolvingLoadBalancingPolicy::ExitIdleLocked() { + if (lb_policy_ != nullptr) { + lb_policy_->ExitIdleLocked(); + if (pending_lb_policy_ != nullptr) pending_lb_policy_->ExitIdleLocked(); + } else { + if (!started_resolving_ && resolver_ != nullptr) { + StartResolvingLocked(); + } + } +} + +void ResolvingLoadBalancingPolicy::ResetBackoffLocked() { + if (resolver_ != nullptr) { + resolver_->ResetBackoffLocked(); + resolver_->RequestReresolutionLocked(); + } + if (lb_policy_ != nullptr) lb_policy_->ResetBackoffLocked(); + if (pending_lb_policy_ != nullptr) pending_lb_policy_->ResetBackoffLocked(); +} + +void ResolvingLoadBalancingPolicy::FillChildRefsForChannelz( + channelz::ChildRefsList* child_subchannels, + channelz::ChildRefsList* child_channels) { + // Delegate to the lb_policy_ to fill the children subchannels. + // This must be done holding lb_policy_mu_, since this method does not + // run in the combiner. + MutexLock lock(&lb_policy_mu_); + if (lb_policy_ != nullptr) { + lb_policy_->FillChildRefsForChannelz(child_subchannels, child_channels); + } + if (pending_lb_policy_ != nullptr) { + pending_lb_policy_->FillChildRefsForChannelz(child_subchannels, + child_channels); + } +} + +void ResolvingLoadBalancingPolicy::StartResolvingLocked() { + if (GRPC_TRACE_FLAG_ENABLED(*tracer_)) { + gpr_log(GPR_INFO, "resolving_lb=%p: starting name resolution", this); + } + GPR_ASSERT(!started_resolving_); + started_resolving_ = true; + channel_control_helper()->UpdateState( + GRPC_CHANNEL_CONNECTING, + UniquePtr(New(Ref()))); + resolver_->StartLocked(); +} + +void ResolvingLoadBalancingPolicy::OnResolverError(grpc_error* error) { + if (resolver_ == nullptr) { + GRPC_ERROR_UNREF(error); + return; + } + if (GRPC_TRACE_FLAG_ENABLED(*tracer_)) { + gpr_log(GPR_INFO, "resolving_lb=%p: resolver transient failure: %s", this, + grpc_error_string(error)); + } + // If we already have an LB policy from a previous resolution + // result, then we continue to let it set the connectivity state. + // Otherwise, we go into TRANSIENT_FAILURE. + if (lb_policy_ == nullptr) { + grpc_error* state_error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + "Resolver transient failure", &error, 1); + channel_control_helper()->UpdateState( + GRPC_CHANNEL_TRANSIENT_FAILURE, + UniquePtr(New(state_error))); + } + GRPC_ERROR_UNREF(error); +} + +void ResolvingLoadBalancingPolicy::CreateOrUpdateLbPolicyLocked( + const char* lb_policy_name, + RefCountedPtr lb_policy_config, + Resolver::Result result, TraceStringVector* trace_strings) { + // If the child policy name changes, we need to create a new child + // policy. When this happens, we leave child_policy_ as-is and store + // the new child policy in pending_child_policy_. Once the new child + // policy transitions into state READY, we swap it into child_policy_, + // replacing the original child policy. So pending_child_policy_ is + // non-null only between when we apply an update that changes the child + // policy name and when the new child reports state READY. + // + // Updates can arrive at any point during this transition. We always + // apply updates relative to the most recently created child policy, + // even if the most recent one is still in pending_child_policy_. This + // is true both when applying the updates to an existing child policy + // and when determining whether we need to create a new policy. + // + // As a result of this, there are several cases to consider here: + // + // 1. We have no existing child policy (i.e., we have started up but + // have not yet received a serverlist from the balancer or gone + // into fallback mode; in this case, both child_policy_ and + // pending_child_policy_ are null). In this case, we create a + // new child policy and store it in child_policy_. + // + // 2. We have an existing child policy and have no pending child policy + // from a previous update (i.e., either there has not been a + // previous update that changed the policy name, or we have already + // finished swapping in the new policy; in this case, child_policy_ + // is non-null but pending_child_policy_ is null). In this case: + // a. If child_policy_->name() equals child_policy_name, then we + // update the existing child policy. + // b. If child_policy_->name() does not equal child_policy_name, + // we create a new policy. The policy will be stored in + // pending_child_policy_ and will later be swapped into + // child_policy_ by the helper when the new child transitions + // into state READY. + // + // 3. We have an existing child policy and have a pending child policy + // from a previous update (i.e., a previous update set + // pending_child_policy_ as per case 2b above and that policy has + // not yet transitioned into state READY and been swapped into + // child_policy_; in this case, both child_policy_ and + // pending_child_policy_ are non-null). In this case: + // a. If pending_child_policy_->name() equals child_policy_name, + // then we update the existing pending child policy. + // b. If pending_child_policy->name() does not equal + // child_policy_name, then we create a new policy. The new + // policy is stored in pending_child_policy_ (replacing the one + // that was there before, which will be immediately shut down) + // and will later be swapped into child_policy_ by the helper + // when the new child transitions into state READY. + const bool create_policy = + // case 1 + lb_policy_ == nullptr || + // case 2b + (pending_lb_policy_ == nullptr && + strcmp(lb_policy_->name(), lb_policy_name) != 0) || + // case 3b + (pending_lb_policy_ != nullptr && + strcmp(pending_lb_policy_->name(), lb_policy_name) != 0); + LoadBalancingPolicy* policy_to_update = nullptr; + if (create_policy) { + // Cases 1, 2b, and 3b: create a new child policy. + // If lb_policy_ is null, we set it (case 1), else we set + // pending_lb_policy_ (cases 2b and 3b). + if (GRPC_TRACE_FLAG_ENABLED(*tracer_)) { + gpr_log(GPR_INFO, "resolving_lb=%p: Creating new %schild policy %s", this, + lb_policy_ == nullptr ? "" : "pending ", lb_policy_name); + } + auto new_policy = + CreateLbPolicyLocked(lb_policy_name, *result.args, trace_strings); + auto& lb_policy = lb_policy_ == nullptr ? lb_policy_ : pending_lb_policy_; + { + MutexLock lock(&lb_policy_mu_); + lb_policy = std::move(new_policy); + } + policy_to_update = lb_policy.get(); + } else { + // Cases 2a and 3a: update an existing policy. + // If we have a pending child policy, send the update to the pending + // policy (case 3a), else send it to the current policy (case 2a). + policy_to_update = pending_lb_policy_ != nullptr ? pending_lb_policy_.get() + : lb_policy_.get(); + } + GPR_ASSERT(policy_to_update != nullptr); + // Update the policy. + if (GRPC_TRACE_FLAG_ENABLED(*tracer_)) { + gpr_log(GPR_INFO, "resolving_lb=%p: Updating %schild policy %p", this, + policy_to_update == pending_lb_policy_.get() ? "pending " : "", + policy_to_update); + } + UpdateArgs update_args; + update_args.addresses = std::move(result.addresses); + update_args.config = std::move(lb_policy_config); + // TODO(roth): Once channel args is converted to C++, use std::move() here. + update_args.args = result.args; + result.args = nullptr; + policy_to_update->UpdateLocked(std::move(update_args)); +} + +// Creates a new LB policy. +// Updates trace_strings to indicate what was done. +OrphanablePtr +ResolvingLoadBalancingPolicy::CreateLbPolicyLocked( + const char* lb_policy_name, const grpc_channel_args& args, + TraceStringVector* trace_strings) { + ResolvingControlHelper* helper = New(Ref()); + LoadBalancingPolicy::Args lb_policy_args; + lb_policy_args.combiner = combiner(); + lb_policy_args.channel_control_helper = + UniquePtr(helper); + lb_policy_args.args = &args; + OrphanablePtr lb_policy = + LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( + lb_policy_name, std::move(lb_policy_args)); + if (GPR_UNLIKELY(lb_policy == nullptr)) { + gpr_log(GPR_ERROR, "could not create LB policy \"%s\"", lb_policy_name); + if (channelz_node() != nullptr) { + char* str; + gpr_asprintf(&str, "Could not create LB policy \"%s\"", lb_policy_name); + trace_strings->push_back(str); + } + return nullptr; + } + helper->set_child(lb_policy.get()); + if (GRPC_TRACE_FLAG_ENABLED(*tracer_)) { + gpr_log(GPR_INFO, "resolving_lb=%p: created new LB policy \"%s\" (%p)", + this, lb_policy_name, lb_policy.get()); + } + if (channelz_node() != nullptr) { + char* str; + gpr_asprintf(&str, "Created new LB policy \"%s\"", lb_policy_name); + trace_strings->push_back(str); + } + // Propagate channelz node. + auto* channelz = channelz_node(); + if (channelz != nullptr) { + lb_policy->set_channelz_node(channelz->Ref()); + } + grpc_pollset_set_add_pollset_set(lb_policy->interested_parties(), + interested_parties()); + return lb_policy; +} + +void ResolvingLoadBalancingPolicy::MaybeAddTraceMessagesForAddressChangesLocked( + bool resolution_contains_addresses, TraceStringVector* trace_strings) { + if (!resolution_contains_addresses && + previous_resolution_contained_addresses_) { + trace_strings->push_back(gpr_strdup("Address list became empty")); + } else if (resolution_contains_addresses && + !previous_resolution_contained_addresses_) { + trace_strings->push_back(gpr_strdup("Address list became non-empty")); + } + previous_resolution_contained_addresses_ = resolution_contains_addresses; +} + +void ResolvingLoadBalancingPolicy::ConcatenateAndAddChannelTraceLocked( + TraceStringVector* trace_strings) const { + if (!trace_strings->empty()) { + gpr_strvec v; + gpr_strvec_init(&v); + gpr_strvec_add(&v, gpr_strdup("Resolution event: ")); + bool is_first = 1; + for (size_t i = 0; i < trace_strings->size(); ++i) { + if (!is_first) gpr_strvec_add(&v, gpr_strdup(", ")); + is_first = false; + gpr_strvec_add(&v, (*trace_strings)[i]); + } + char* flat; + size_t flat_len = 0; + flat = gpr_strvec_flatten(&v, &flat_len); + channelz_node()->AddTraceEvent(channelz::ChannelTrace::Severity::Info, + grpc_slice_new(flat, flat_len, gpr_free)); + gpr_strvec_destroy(&v); + } +} + +void ResolvingLoadBalancingPolicy::OnResolverResultChangedLocked( + Resolver::Result result) { + // Handle race conditions. + if (resolver_ == nullptr) return; + if (GRPC_TRACE_FLAG_ENABLED(*tracer_)) { + gpr_log(GPR_INFO, "resolving_lb=%p: got resolver result", this); + } + // We only want to trace the address resolution in the follow cases: + // (a) Address resolution resulted in service config change. + // (b) Address resolution that causes number of backends to go from + // zero to non-zero. + // (c) Address resolution that causes number of backends to go from + // non-zero to zero. + // (d) Address resolution that causes a new LB policy to be created. + // + // We track a list of strings to eventually be concatenated and traced. + TraceStringVector trace_strings; + const bool resolution_contains_addresses = result.addresses.size() > 0; + // Process the resolver result. + const char* lb_policy_name = nullptr; + RefCountedPtr lb_policy_config; + bool service_config_changed = false; + char* service_config_error_string = nullptr; + if (process_resolver_result_ != nullptr) { + grpc_error* service_config_error = GRPC_ERROR_NONE; + service_config_changed = process_resolver_result_( + process_resolver_result_user_data_, &result, &lb_policy_name, + &lb_policy_config, &service_config_error); + if (service_config_error != GRPC_ERROR_NONE) { + service_config_error_string = + gpr_strdup(grpc_error_string(service_config_error)); + if (lb_policy_name == nullptr) { + // Use an empty lb_policy_name as an indicator that we received an + // invalid service config and we don't have a fallback service config. + OnResolverError(service_config_error); + } else { + GRPC_ERROR_UNREF(service_config_error); + } + } + } else { + lb_policy_name = child_policy_name_.get(); + lb_policy_config = child_lb_config_; + } + if (lb_policy_name != nullptr) { + // Create or update LB policy, as needed. + CreateOrUpdateLbPolicyLocked(lb_policy_name, lb_policy_config, + std::move(result), &trace_strings); + } + // Add channel trace event. + if (channelz_node() != nullptr) { + if (service_config_changed) { + // TODO(ncteisen): might be worth somehow including a snippet of the + // config in the trace, at the risk of bloating the trace logs. + trace_strings.push_back(gpr_strdup("Service config changed")); + } + if (service_config_error_string != nullptr) { + trace_strings.push_back(service_config_error_string); + service_config_error_string = nullptr; + } + MaybeAddTraceMessagesForAddressChangesLocked(resolution_contains_addresses, + &trace_strings); + ConcatenateAndAddChannelTraceLocked(&trace_strings); + } + gpr_free(service_config_error_string); +} + +} // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/resolving_lb_policy.h b/src/core/ext/filters/client_channel/resolving_lb_policy.h new file mode 100644 index 00000000000..0ca6c9563f9 --- /dev/null +++ b/src/core/ext/filters/client_channel/resolving_lb_policy.h @@ -0,0 +1,146 @@ +/* + * + * 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_RESOLVING_LB_POLICY_H +#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVING_LB_POLICY_H + +#include + +#include "src/core/ext/filters/client_channel/client_channel_channelz.h" +#include "src/core/ext/filters/client_channel/lb_policy.h" +#include "src/core/ext/filters/client_channel/lb_policy_factory.h" +#include "src/core/ext/filters/client_channel/resolver.h" +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/channel/channel_stack.h" +#include "src/core/lib/debug/trace.h" +#include "src/core/lib/gprpp/inlined_vector.h" +#include "src/core/lib/gprpp/orphanable.h" +#include "src/core/lib/iomgr/call_combiner.h" +#include "src/core/lib/iomgr/closure.h" +#include "src/core/lib/iomgr/polling_entity.h" +#include "src/core/lib/iomgr/pollset_set.h" +#include "src/core/lib/transport/connectivity_state.h" +#include "src/core/lib/transport/metadata_batch.h" + +namespace grpc_core { + +// An LB policy that wraps a resolver and a child LB policy to make use +// of the addresses returned by the resolver. +// +// When used in the client_channel code, the resolver will attempt to +// fetch the service config, and the child LB policy name and config +// will be determined based on the service config. +// +// When used in an LB policy implementation that needs to do another +// round of resolution before creating a child policy, the resolver does +// not fetch the service config, and the caller must pre-determine the +// child LB policy and config to use. +class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy { + public: + // If error is set when this returns, then construction failed, and + // the caller may not use the new object. + ResolvingLoadBalancingPolicy( + Args args, TraceFlag* tracer, UniquePtr target_uri, + UniquePtr child_policy_name, + RefCountedPtr child_lb_config, + grpc_error** error); + + // Private ctor, to be used by client_channel only! + // + // Synchronous callback that takes the resolver result and sets + // lb_policy_name and lb_policy_config to point to the right data. + // Returns true if the service config has changed since the last result. + // If the returned service_config_error is not none and lb_policy_name is + // empty, it means that we don't have a valid service config to use, and we + // should set the channel to be in TRANSIENT_FAILURE. + typedef bool (*ProcessResolverResultCallback)( + void* user_data, Resolver::Result* result, const char** lb_policy_name, + RefCountedPtr* lb_policy_config, + grpc_error** service_config_error); + // If error is set when this returns, then construction failed, and + // the caller may not use the new object. + ResolvingLoadBalancingPolicy( + Args args, TraceFlag* tracer, UniquePtr target_uri, + ProcessResolverResultCallback process_resolver_result, + void* process_resolver_result_user_data, grpc_error** error); + + virtual const char* name() const override { return "resolving_lb"; } + + // No-op -- should never get updates from the channel. + // TODO(roth): Need to support updating child LB policy's config for xds + // use case. + void UpdateLocked(UpdateArgs args) override {} + + void ExitIdleLocked() override; + + void ResetBackoffLocked() override; + + void FillChildRefsForChannelz( + channelz::ChildRefsList* child_subchannels, + channelz::ChildRefsList* child_channels) override; + + private: + using TraceStringVector = InlinedVector; + + class ResolverResultHandler; + class ResolvingControlHelper; + + ~ResolvingLoadBalancingPolicy(); + + grpc_error* Init(const grpc_channel_args& args); + void ShutdownLocked() override; + + void StartResolvingLocked(); + void OnResolverError(grpc_error* error); + void CreateOrUpdateLbPolicyLocked( + const char* lb_policy_name, + RefCountedPtr lb_policy_config, + Resolver::Result result, TraceStringVector* trace_strings); + OrphanablePtr CreateLbPolicyLocked( + const char* lb_policy_name, const grpc_channel_args& args, + TraceStringVector* trace_strings); + void MaybeAddTraceMessagesForAddressChangesLocked( + bool resolution_contains_addresses, TraceStringVector* trace_strings); + void ConcatenateAndAddChannelTraceLocked( + TraceStringVector* trace_strings) const; + void OnResolverResultChangedLocked(Resolver::Result result); + + // Passed in from caller at construction time. + TraceFlag* tracer_; + UniquePtr target_uri_; + ProcessResolverResultCallback process_resolver_result_ = nullptr; + void* process_resolver_result_user_data_ = nullptr; + UniquePtr child_policy_name_; + RefCountedPtr child_lb_config_; + + // Resolver and associated state. + OrphanablePtr resolver_; + bool started_resolving_ = false; + bool previous_resolution_contained_addresses_ = false; + + // Child LB policy. + OrphanablePtr lb_policy_; + OrphanablePtr pending_lb_policy_; + // Lock held when modifying the value of child_policy_ or + // pending_child_policy_. + gpr_mu lb_policy_mu_; +}; + +} // namespace grpc_core + +#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVING_LB_POLICY_H */ diff --git a/src/core/ext/filters/client_channel/server_address.cc b/src/core/ext/filters/client_channel/server_address.cc new file mode 100644 index 00000000000..c2941afbcfd --- /dev/null +++ b/src/core/ext/filters/client_channel/server_address.cc @@ -0,0 +1,55 @@ +/* + * + * 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 + +#include "src/core/ext/filters/client_channel/server_address.h" + +#include + +namespace grpc_core { + +// +// ServerAddress +// + +ServerAddress::ServerAddress(const grpc_resolved_address& address, + grpc_channel_args* args) + : address_(address), args_(args) {} + +ServerAddress::ServerAddress(const void* address, size_t address_len, + grpc_channel_args* args) + : args_(args) { + memcpy(address_.addr, address, address_len); + address_.len = static_cast(address_len); +} + +int ServerAddress::Cmp(const ServerAddress& other) const { + if (address_.len > other.address_.len) return 1; + if (address_.len < other.address_.len) return -1; + int retval = memcmp(address_.addr, other.address_.addr, address_.len); + if (retval != 0) return retval; + return grpc_channel_args_compare(args_, other.args_); +} + +bool ServerAddress::IsBalancer() const { + return grpc_channel_arg_get_bool( + grpc_channel_args_find(args_, GRPC_ARG_ADDRESS_IS_BALANCER), false); +} + +} // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/server_address.h b/src/core/ext/filters/client_channel/server_address.h new file mode 100644 index 00000000000..040cd2ee317 --- /dev/null +++ b/src/core/ext/filters/client_channel/server_address.h @@ -0,0 +1,98 @@ +/* + * + * 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_SERVER_ADDRESS_H +#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SERVER_ADDRESS_H + +#include + +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gprpp/inlined_vector.h" +#include "src/core/lib/iomgr/resolve_address.h" +#include "src/core/lib/uri/uri_parser.h" + +// Channel arg key for a bool indicating whether an address is a grpclb +// load balancer (as opposed to a backend). +#define GRPC_ARG_ADDRESS_IS_BALANCER "grpc.address_is_balancer" + +// Channel arg key for a string indicating an address's balancer name. +#define GRPC_ARG_ADDRESS_BALANCER_NAME "grpc.address_balancer_name" + +namespace grpc_core { + +// +// ServerAddress +// + +// A server address is a grpc_resolved_address with an associated set of +// channel args. Any args present here will be merged into the channel +// args when a subchannel is created for this address. +class ServerAddress { + public: + // Takes ownership of args. + ServerAddress(const grpc_resolved_address& address, grpc_channel_args* args); + ServerAddress(const void* address, size_t address_len, + grpc_channel_args* args); + + ~ServerAddress() { grpc_channel_args_destroy(args_); } + + // Copyable. + ServerAddress(const ServerAddress& other) + : address_(other.address_), args_(grpc_channel_args_copy(other.args_)) {} + ServerAddress& operator=(const ServerAddress& other) { + address_ = other.address_; + grpc_channel_args_destroy(args_); + args_ = grpc_channel_args_copy(other.args_); + return *this; + } + + // Movable. + ServerAddress(ServerAddress&& other) + : address_(other.address_), args_(other.args_) { + other.args_ = nullptr; + } + ServerAddress& operator=(ServerAddress&& other) { + address_ = other.address_; + args_ = other.args_; + other.args_ = nullptr; + return *this; + } + + bool operator==(const ServerAddress& other) const { return Cmp(other) == 0; } + + int Cmp(const ServerAddress& other) const; + + const grpc_resolved_address& address() const { return address_; } + const grpc_channel_args* args() const { return args_; } + + bool IsBalancer() const; + + private: + grpc_resolved_address address_; + grpc_channel_args* args_; +}; + +// +// ServerAddressList +// + +typedef InlinedVector ServerAddressList; + +} // namespace grpc_core + +#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SERVER_ADDRESS_H */ diff --git a/src/core/ext/filters/client_channel/service_config.cc b/src/core/ext/filters/client_channel/service_config.cc new file mode 100644 index 00000000000..86d4f7368c0 --- /dev/null +++ b/src/core/ext/filters/client_channel/service_config.cc @@ -0,0 +1,331 @@ +// +// 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 + +#include "src/core/ext/filters/client_channel/service_config.h" + +#include + +#include +#include +#include +#include + +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/json/json.h" +#include "src/core/lib/slice/slice_hash_table.h" +#include "src/core/lib/slice/slice_internal.h" +#include "src/core/lib/slice/slice_string_helpers.h" + +namespace grpc_core { + +namespace { +typedef InlinedVector, + ServiceConfig::kNumPreallocatedParsers> + ServiceConfigParserList; +ServiceConfigParserList* g_registered_parsers; +} // namespace + +RefCountedPtr ServiceConfig::Create(const char* json, + grpc_error** error) { + UniquePtr service_config_json(gpr_strdup(json)); + UniquePtr json_string(gpr_strdup(json)); + GPR_DEBUG_ASSERT(error != nullptr); + grpc_json* json_tree = grpc_json_parse_string(json_string.get()); + if (json_tree == nullptr) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "failed to parse JSON for service config"); + return nullptr; + } + return MakeRefCounted( + std::move(service_config_json), std::move(json_string), json_tree, error); +} + +ServiceConfig::ServiceConfig(UniquePtr service_config_json, + UniquePtr json_string, grpc_json* json_tree, + grpc_error** error) + : service_config_json_(std::move(service_config_json)), + json_string_(std::move(json_string)), + json_tree_(json_tree) { + GPR_DEBUG_ASSERT(error != nullptr); + if (json_tree->type != GRPC_JSON_OBJECT || json_tree->key != nullptr) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Malformed service Config JSON object"); + return; + } + grpc_error* error_list[2]; + int error_count = 0; + grpc_error* global_error = ParseGlobalParams(json_tree); + grpc_error* local_error = ParsePerMethodParams(json_tree); + if (global_error != GRPC_ERROR_NONE) { + error_list[error_count++] = global_error; + } + if (local_error != GRPC_ERROR_NONE) { + error_list[error_count++] = local_error; + } + if (error_count > 0) { + *error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + "Service config parsing error", error_list, error_count); + GRPC_ERROR_UNREF(global_error); + GRPC_ERROR_UNREF(local_error); + } +} + +grpc_error* ServiceConfig::ParseGlobalParams(const grpc_json* json_tree) { + GPR_DEBUG_ASSERT(json_tree_->type == GRPC_JSON_OBJECT); + GPR_DEBUG_ASSERT(json_tree_->key == nullptr); + InlinedVector error_list; + for (size_t i = 0; i < g_registered_parsers->size(); i++) { + grpc_error* parser_error = GRPC_ERROR_NONE; + auto parsed_obj = + (*g_registered_parsers)[i]->ParseGlobalParams(json_tree, &parser_error); + if (parser_error != GRPC_ERROR_NONE) { + error_list.push_back(parser_error); + } + parsed_global_service_config_objects_.push_back(std::move(parsed_obj)); + } + return GRPC_ERROR_CREATE_FROM_VECTOR("Global Params", &error_list); +} + +grpc_error* ServiceConfig::ParseJsonMethodConfigToServiceConfigObjectsTable( + const grpc_json* json, + SliceHashTable::Entry* entries, + size_t* idx) { + auto objs_vector = MakeUnique(); + InlinedVector error_list; + for (size_t i = 0; i < g_registered_parsers->size(); i++) { + grpc_error* parser_error = GRPC_ERROR_NONE; + auto parsed_obj = + (*g_registered_parsers)[i]->ParsePerMethodParams(json, &parser_error); + if (parser_error != GRPC_ERROR_NONE) { + error_list.push_back(parser_error); + } + objs_vector->push_back(std::move(parsed_obj)); + } + service_config_objects_vectors_storage_.push_back(std::move(objs_vector)); + const auto* vector_ptr = + service_config_objects_vectors_storage_ + [service_config_objects_vectors_storage_.size() - 1] + .get(); + // Construct list of paths. + InlinedVector, 10> paths; + for (grpc_json* child = json->child; child != nullptr; child = child->next) { + if (child->key == nullptr) continue; + if (strcmp(child->key, "name") == 0) { + if (child->type != GRPC_JSON_ARRAY) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:name error:not of type Array")); + goto wrap_error; + } + for (grpc_json* name = child->child; name != nullptr; name = name->next) { + grpc_error* parse_error = GRPC_ERROR_NONE; + UniquePtr path = ParseJsonMethodName(name, &parse_error); + if (path == nullptr) { + error_list.push_back(parse_error); + } else { + GPR_DEBUG_ASSERT(parse_error == GRPC_ERROR_NONE); + paths.push_back(std::move(path)); + } + } + } + } + if (paths.size() == 0) { + error_list.push_back( + GRPC_ERROR_CREATE_FROM_STATIC_STRING("No names specified")); + } + // Add entry for each path. + for (size_t i = 0; i < paths.size(); ++i) { + entries[*idx].key = grpc_slice_from_copied_string(paths[i].get()); + entries[*idx].value = vector_ptr; + ++*idx; + } +wrap_error: + return GRPC_ERROR_CREATE_FROM_VECTOR("methodConfig", &error_list); +} + +grpc_error* ServiceConfig::ParsePerMethodParams(const grpc_json* json_tree) { + GPR_DEBUG_ASSERT(json_tree_->type == GRPC_JSON_OBJECT); + GPR_DEBUG_ASSERT(json_tree_->key == nullptr); + SliceHashTable::Entry* entries = nullptr; + size_t num_entries = 0; + InlinedVector error_list; + for (grpc_json* field = json_tree->child; field != nullptr; + field = field->next) { + if (field->key == nullptr) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "error:Illegal key value - NULL")); + continue; + } + if (strcmp(field->key, "methodConfig") == 0) { + if (entries != nullptr) { + GPR_ASSERT(false); + } + if (field->type != GRPC_JSON_ARRAY) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:methodConfig error:not of type Array")); + } + for (grpc_json* method = field->child; method != nullptr; + method = method->next) { + int count = CountNamesInMethodConfig(method); + if (count <= 0) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:methodConfig error:No names found")); + } + num_entries += static_cast(count); + } + entries = static_cast< + SliceHashTable::Entry*>(gpr_zalloc( + num_entries * + sizeof(SliceHashTable::Entry))); + size_t idx = 0; + for (grpc_json* method = field->child; method != nullptr; + method = method->next) { + grpc_error* error = ParseJsonMethodConfigToServiceConfigObjectsTable( + method, entries, &idx); + if (error != GRPC_ERROR_NONE) { + error_list.push_back(error); + } + } + // idx might not be equal to num_entries due to parsing errors + num_entries = idx; + break; + } + } + if (entries != nullptr) { + parsed_method_service_config_objects_table_ = + SliceHashTable::Create( + num_entries, entries, nullptr); + gpr_free(entries); + } + return GRPC_ERROR_CREATE_FROM_VECTOR("Method Params", &error_list); +} + +ServiceConfig::~ServiceConfig() { grpc_json_destroy(json_tree_); } + +int ServiceConfig::CountNamesInMethodConfig(grpc_json* json) { + int num_names = 0; + for (grpc_json* field = json->child; field != nullptr; field = field->next) { + if (field->key != nullptr && strcmp(field->key, "name") == 0) { + if (field->type != GRPC_JSON_ARRAY) return -1; + for (grpc_json* name = field->child; name != nullptr; name = name->next) { + if (name->type != GRPC_JSON_OBJECT) return -1; + ++num_names; + } + } + } + return num_names; +} + +UniquePtr ServiceConfig::ParseJsonMethodName(grpc_json* json, + grpc_error** error) { + if (json->type != GRPC_JSON_OBJECT) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:name error:type is not object"); + return nullptr; + } + const char* service_name = nullptr; + const char* method_name = nullptr; + for (grpc_json* child = json->child; child != nullptr; child = child->next) { + if (child->key == nullptr) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:name error:Child entry with no key"); + return nullptr; + } + if (child->type != GRPC_JSON_STRING) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:name error:Child entry not of type string"); + return nullptr; + } + if (strcmp(child->key, "service") == 0) { + if (service_name != nullptr) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:name error: field:service error:Multiple entries"); + return nullptr; // Duplicate. + } + if (child->value == nullptr) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:name error: field:service error:empty value"); + return nullptr; + } + service_name = child->value; + } else if (strcmp(child->key, "method") == 0) { + if (method_name != nullptr) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:name error: field:method error:multiple entries"); + return nullptr; // Duplicate. + } + if (child->value == nullptr) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:name error: field:method error:empty value"); + return nullptr; + } + method_name = child->value; + } + } + if (service_name == nullptr) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:name error: field:service error:not found"); + return nullptr; // Required field. + } + char* path; + gpr_asprintf(&path, "/%s/%s", service_name, + method_name == nullptr ? "*" : method_name); + return UniquePtr(path); +} + +const ServiceConfig::ServiceConfigObjectsVector* +ServiceConfig::GetMethodServiceConfigObjectsVector(const grpc_slice& path) { + if (parsed_method_service_config_objects_table_.get() == nullptr) { + return nullptr; + } + const auto* value = parsed_method_service_config_objects_table_->Get(path); + // If we didn't find a match for the path, try looking for a wildcard + // entry (i.e., change "/service/method" to "/service/*"). + if (value == nullptr) { + char* path_str = grpc_slice_to_c_string(path); + const char* sep = strrchr(path_str, '/') + 1; + const size_t len = (size_t)(sep - path_str); + char* buf = (char*)gpr_malloc(len + 2); // '*' and NUL + memcpy(buf, path_str, len); + buf[len] = '*'; + buf[len + 1] = '\0'; + grpc_slice wildcard_path = grpc_slice_from_copied_string(buf); + gpr_free(buf); + value = parsed_method_service_config_objects_table_->Get(wildcard_path); + grpc_slice_unref_internal(wildcard_path); + gpr_free(path_str); + if (value == nullptr) return nullptr; + } + return *value; +} + +size_t ServiceConfig::RegisterParser(UniquePtr parser) { + g_registered_parsers->push_back(std::move(parser)); + return g_registered_parsers->size() - 1; +} + +void ServiceConfig::Init() { + GPR_ASSERT(g_registered_parsers == nullptr); + g_registered_parsers = New(); +} + +void ServiceConfig::Shutdown() { + Delete(g_registered_parsers); + g_registered_parsers = nullptr; +} + +} // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/service_config.h b/src/core/ext/filters/client_channel/service_config.h new file mode 100644 index 00000000000..e6f855ad934 --- /dev/null +++ b/src/core/ext/filters/client_channel/service_config.h @@ -0,0 +1,207 @@ +// +// 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. +// + +#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SERVICE_CONFIG_H +#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SERVICE_CONFIG_H + +#include + +#include +#include + +#include "src/core/lib/gprpp/inlined_vector.h" +#include "src/core/lib/gprpp/ref_counted.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" +#include "src/core/lib/iomgr/error.h" +#include "src/core/lib/json/json.h" +#include "src/core/lib/slice/slice_hash_table.h" + +// The main purpose of the code here is to parse the service config in +// JSON form, which will look like this: +// +// { +// "loadBalancingPolicy": "string", // optional +// "methodConfig": [ // array of one or more method_config objects +// { +// "name": [ // array of one or more name objects +// { +// "service": "string", // required +// "method": "string", // optional +// } +// ], +// // remaining fields are optional. +// // see https://developers.google.com/protocol-buffers/docs/proto3#json +// // for format details. +// "waitForReady": bool, +// "timeout": "duration_string", +// "maxRequestMessageBytes": "int64_string", +// "maxResponseMessageBytes": "int64_string", +// } +// ] +// } + +namespace grpc_core { + +class ServiceConfig : public RefCounted { + public: + /// This is the base class that all service config parsers MUST use to store + /// parsed service config data. + class ParsedConfig { + public: + virtual ~ParsedConfig() = default; + + GRPC_ABSTRACT_BASE_CLASS; + }; + + /// This is the base class that all service config parsers should derive from. + class Parser { + public: + virtual ~Parser() = default; + + virtual UniquePtr ParseGlobalParams(const grpc_json* json, + grpc_error** error) { + GPR_DEBUG_ASSERT(error != nullptr); + return nullptr; + } + + virtual UniquePtr ParsePerMethodParams(const grpc_json* json, + grpc_error** error) { + GPR_DEBUG_ASSERT(error != nullptr); + return nullptr; + } + + GRPC_ABSTRACT_BASE_CLASS; + }; + + static constexpr int kNumPreallocatedParsers = 4; + typedef InlinedVector, kNumPreallocatedParsers> + ServiceConfigObjectsVector; + + /// When a service config is applied to a call in the client_channel_filter, + /// we create an instance of this object and store it in the call_data for + /// client_channel. A pointer to this object is also stored in the + /// call_context, so that future filters can easily access method and global + /// parameters for the call. + class CallData { + public: + CallData() = default; + CallData(RefCountedPtr svc_cfg, const grpc_slice& path) + : service_config_(std::move(svc_cfg)) { + if (service_config_ != nullptr) { + method_params_vector_ = + service_config_->GetMethodServiceConfigObjectsVector(path); + } + } + + ServiceConfig* service_config() { return service_config_.get(); } + + ParsedConfig* GetMethodParsedObject(size_t index) const { + return method_params_vector_ != nullptr + ? (*method_params_vector_)[index].get() + : nullptr; + } + + ParsedConfig* GetGlobalParsedObject(size_t index) const { + return service_config_->GetParsedGlobalServiceConfigObject(index); + } + + private: + RefCountedPtr service_config_; + const ServiceConfigObjectsVector* method_params_vector_ = nullptr; + }; + + /// Creates a new service config from parsing \a json_string. + /// Returns null on parse error. + static RefCountedPtr Create(const char* json, + grpc_error** error); + + ~ServiceConfig(); + + const char* service_config_json() const { return service_config_json_.get(); } + + /// Retrieves the parsed global service config object at index \a index. The + /// lifetime of the returned object is tied to the lifetime of the + /// ServiceConfig object. + ParsedConfig* GetParsedGlobalServiceConfigObject(size_t index) { + GPR_DEBUG_ASSERT(index < parsed_global_service_config_objects_.size()); + return parsed_global_service_config_objects_[index].get(); + } + + /// Retrieves the vector of method service config objects for a given path \a + /// path. The lifetime of the returned vector and contained objects is tied to + /// the lifetime of the ServiceConfig object. + const ServiceConfigObjectsVector* GetMethodServiceConfigObjectsVector( + const grpc_slice& path); + + /// Globally register a service config parser. On successful registration, it + /// returns the index at which the parser was registered. On failure, -1 is + /// returned. Each new service config update will go through all the + /// registered parser. Each parser is responsible for reading the service + /// config json and returning a parsed object. This parsed object can later be + /// retrieved using the same index that was returned at registration time. + static size_t RegisterParser(UniquePtr parser); + + static void Init(); + + static void Shutdown(); + + private: + // So New() can call our private ctor. + template + friend T* New(Args&&... args); + + // Takes ownership of \a json_tree. + ServiceConfig(UniquePtr service_config_json, + UniquePtr json_string, grpc_json* json_tree, + grpc_error** error); + + // Helper functions to parse the service config + grpc_error* ParseGlobalParams(const grpc_json* json_tree); + grpc_error* ParsePerMethodParams(const grpc_json* json_tree); + + // Returns the number of names specified in the method config \a json. + static int CountNamesInMethodConfig(grpc_json* json); + + // Returns a path string for the JSON name object specified by \a json. + // Returns null on error, and stores error in \a error. + static UniquePtr ParseJsonMethodName(grpc_json* json, + grpc_error** error); + + grpc_error* ParseJsonMethodConfigToServiceConfigObjectsTable( + const grpc_json* json, + SliceHashTable::Entry* entries, + size_t* idx); + + UniquePtr service_config_json_; + UniquePtr json_string_; // Underlying storage for json_tree. + grpc_json* json_tree_; + + InlinedVector, kNumPreallocatedParsers> + parsed_global_service_config_objects_; + // A map from the method name to the service config objects vector. Note that + // we are using a raw pointer and not a unique pointer so that we can use the + // same vector for multiple names. + RefCountedPtr> + parsed_method_service_config_objects_table_; + // Storage for all the vectors that are being used in + // parsed_method_service_config_objects_table_. + InlinedVector, 32> + service_config_objects_vectors_storage_; +}; + +} // namespace grpc_core + +#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SERVICE_CONFIG_H */ diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index a56db0201b8..cd778976166 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -33,7 +33,8 @@ #include "src/core/ext/filters/client_channel/health/health_check_client.h" #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/proxy_mapper_registry.h" -#include "src/core/ext/filters/client_channel/subchannel_index.h" +#include "src/core/ext/filters/client_channel/service_config.h" +#include "src/core/ext/filters/client_channel/subchannel_pool_interface.h" #include "src/core/lib/backoff/backoff.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/connected_channel.h" @@ -41,249 +42,309 @@ #include "src/core/lib/gpr/alloc.h" #include "src/core/lib/gprpp/debug_location.h" #include "src/core/lib/gprpp/manual_constructor.h" -#include "src/core/lib/gprpp/mutex_lock.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" +#include "src/core/lib/gprpp/sync.h" #include "src/core/lib/iomgr/sockaddr_utils.h" -#include "src/core/lib/iomgr/timer.h" #include "src/core/lib/profiling/timers.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/channel_init.h" #include "src/core/lib/transport/connectivity_state.h" #include "src/core/lib/transport/error_utils.h" -#include "src/core/lib/transport/service_config.h" #include "src/core/lib/transport/status_metadata.h" #include "src/core/lib/uri/uri_parser.h" +// Strong and weak refs. #define INTERNAL_REF_BITS 16 #define STRONG_REF_MASK (~(gpr_atm)((1 << INTERNAL_REF_BITS) - 1)) +// Backoff parameters. #define GRPC_SUBCHANNEL_INITIAL_CONNECT_BACKOFF_SECONDS 1 #define GRPC_SUBCHANNEL_RECONNECT_BACKOFF_MULTIPLIER 1.6 #define GRPC_SUBCHANNEL_RECONNECT_MIN_TIMEOUT_SECONDS 20 #define GRPC_SUBCHANNEL_RECONNECT_MAX_BACKOFF_SECONDS 120 #define GRPC_SUBCHANNEL_RECONNECT_JITTER 0.2 +// Conversion between subchannel call and call stack. +#define SUBCHANNEL_CALL_TO_CALL_STACK(call) \ + (grpc_call_stack*)((char*)(call) + \ + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(SubchannelCall))) +#define CALL_STACK_TO_SUBCHANNEL_CALL(callstack) \ + (SubchannelCall*)(((char*)(call_stack)) - \ + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(SubchannelCall))) + +namespace grpc_core { + +// +// ConnectedSubchannel +// + +ConnectedSubchannel::ConnectedSubchannel( + grpc_channel_stack* channel_stack, const grpc_channel_args* args, + RefCountedPtr channelz_subchannel, + intptr_t socket_uuid) + : RefCounted(&grpc_trace_stream_refcount), + channel_stack_(channel_stack), + args_(grpc_channel_args_copy(args)), + channelz_subchannel_(std::move(channelz_subchannel)), + socket_uuid_(socket_uuid) {} + +ConnectedSubchannel::~ConnectedSubchannel() { + grpc_channel_args_destroy(args_); + GRPC_CHANNEL_STACK_UNREF(channel_stack_, "connected_subchannel_dtor"); +} + +void ConnectedSubchannel::NotifyOnStateChange( + grpc_pollset_set* interested_parties, grpc_connectivity_state* state, + grpc_closure* closure) { + grpc_transport_op* op = grpc_make_transport_op(nullptr); + grpc_channel_element* elem; + op->connectivity_state = state; + op->on_connectivity_state_change = closure; + op->bind_pollset_set = interested_parties; + elem = grpc_channel_stack_element(channel_stack_, 0); + elem->filter->start_transport_op(elem, op); +} + +void ConnectedSubchannel::Ping(grpc_closure* on_initiate, + grpc_closure* on_ack) { + grpc_transport_op* op = grpc_make_transport_op(nullptr); + grpc_channel_element* elem; + op->send_ping.on_initiate = on_initiate; + op->send_ping.on_ack = on_ack; + elem = grpc_channel_stack_element(channel_stack_, 0); + elem->filter->start_transport_op(elem, op); +} + +RefCountedPtr ConnectedSubchannel::CreateCall( + const CallArgs& args, grpc_error** error) { + const size_t allocation_size = + GetInitialCallSizeEstimate(args.parent_data_size); + RefCountedPtr call( + new (args.arena->Alloc(allocation_size)) + SubchannelCall(Ref(DEBUG_LOCATION, "subchannel_call"), args)); + grpc_call_stack* callstk = SUBCHANNEL_CALL_TO_CALL_STACK(call.get()); + const grpc_call_element_args call_args = { + callstk, /* call_stack */ + nullptr, /* server_transport_data */ + args.context, /* context */ + args.path, /* path */ + args.start_time, /* start_time */ + args.deadline, /* deadline */ + args.arena, /* arena */ + args.call_combiner /* call_combiner */ + }; + *error = grpc_call_stack_init(channel_stack_, 1, SubchannelCall::Destroy, + call.get(), &call_args); + if (GPR_UNLIKELY(*error != GRPC_ERROR_NONE)) { + const char* error_string = grpc_error_string(*error); + gpr_log(GPR_ERROR, "error: %s", error_string); + return call; + } + grpc_call_stack_set_pollset_or_pollset_set(callstk, args.pollent); + if (channelz_subchannel_ != nullptr) { + channelz_subchannel_->RecordCallStarted(); + } + return call; +} + +size_t ConnectedSubchannel::GetInitialCallSizeEstimate( + size_t parent_data_size) const { + size_t allocation_size = + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(SubchannelCall)); + if (parent_data_size > 0) { + allocation_size += + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(channel_stack_->call_stack_size) + + parent_data_size; + } else { + allocation_size += channel_stack_->call_stack_size; + } + return allocation_size; +} + +// +// SubchannelCall +// + +void SubchannelCall::StartTransportStreamOpBatch( + grpc_transport_stream_op_batch* batch) { + GPR_TIMER_SCOPE("subchannel_call_process_op", 0); + MaybeInterceptRecvTrailingMetadata(batch); + grpc_call_stack* call_stack = SUBCHANNEL_CALL_TO_CALL_STACK(this); + grpc_call_element* top_elem = grpc_call_stack_element(call_stack, 0); + GRPC_CALL_LOG_OP(GPR_INFO, top_elem, batch); + top_elem->filter->start_transport_stream_op_batch(top_elem, batch); +} + +void* SubchannelCall::GetParentData() { + grpc_channel_stack* chanstk = connected_subchannel_->channel_stack(); + return (char*)this + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(SubchannelCall)) + + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(chanstk->call_stack_size); +} + +grpc_call_stack* SubchannelCall::GetCallStack() { + return SUBCHANNEL_CALL_TO_CALL_STACK(this); +} + +void SubchannelCall::SetAfterCallStackDestroy(grpc_closure* closure) { + GPR_ASSERT(after_call_stack_destroy_ == nullptr); + GPR_ASSERT(closure != nullptr); + after_call_stack_destroy_ = closure; +} + +RefCountedPtr SubchannelCall::Ref() { + IncrementRefCount(); + return RefCountedPtr(this); +} + +RefCountedPtr SubchannelCall::Ref( + const grpc_core::DebugLocation& location, const char* reason) { + IncrementRefCount(location, reason); + return RefCountedPtr(this); +} + +void SubchannelCall::Unref() { + GRPC_CALL_STACK_UNREF(SUBCHANNEL_CALL_TO_CALL_STACK(this), ""); +} + +void SubchannelCall::Unref(const DebugLocation& location, const char* reason) { + GRPC_CALL_STACK_UNREF(SUBCHANNEL_CALL_TO_CALL_STACK(this), reason); +} + +void SubchannelCall::Destroy(void* arg, grpc_error* error) { + GPR_TIMER_SCOPE("subchannel_call_destroy", 0); + SubchannelCall* self = static_cast(arg); + // Keep some members before destroying the subchannel call. + grpc_closure* after_call_stack_destroy = self->after_call_stack_destroy_; + RefCountedPtr connected_subchannel = + std::move(self->connected_subchannel_); + // Destroy the subchannel call. + self->~SubchannelCall(); + // Destroy the call stack. This should be after destroying the subchannel + // call, because call->after_call_stack_destroy(), if not null, will free the + // call arena. + grpc_call_stack_destroy(SUBCHANNEL_CALL_TO_CALL_STACK(self), nullptr, + after_call_stack_destroy); + // Automatically reset connected_subchannel. This should be after destroying + // the call stack, because destroying call stack needs access to the channel + // stack. +} + +void SubchannelCall::MaybeInterceptRecvTrailingMetadata( + grpc_transport_stream_op_batch* batch) { + // only intercept payloads with recv trailing. + if (!batch->recv_trailing_metadata) { + return; + } + // only add interceptor is channelz is enabled. + if (connected_subchannel_->channelz_subchannel() == nullptr) { + return; + } + GRPC_CLOSURE_INIT(&recv_trailing_metadata_ready_, RecvTrailingMetadataReady, + this, grpc_schedule_on_exec_ctx); + // save some state needed for the interception callback. + GPR_ASSERT(recv_trailing_metadata_ == nullptr); + recv_trailing_metadata_ = + batch->payload->recv_trailing_metadata.recv_trailing_metadata; + original_recv_trailing_metadata_ = + batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready; + batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready = + &recv_trailing_metadata_ready_; +} + namespace { -struct state_watcher { - grpc_closure closure; - grpc_subchannel* subchannel; - grpc_connectivity_state connectivity_state; - grpc_connectivity_state last_connectivity_state; - grpc_core::OrphanablePtr health_check_client; - grpc_closure health_check_closure; - grpc_connectivity_state health_state; -}; + +// Sets *status based on the rest of the parameters. +void GetCallStatus(grpc_status_code* status, grpc_millis deadline, + grpc_metadata_batch* md_batch, grpc_error* error) { + if (error != GRPC_ERROR_NONE) { + grpc_error_get_status(error, deadline, status, nullptr, nullptr, nullptr); + } else { + if (md_batch->idx.named.grpc_status != nullptr) { + *status = grpc_get_status_code_from_metadata( + md_batch->idx.named.grpc_status->md); + } else { + *status = GRPC_STATUS_UNKNOWN; + } + } + GRPC_ERROR_UNREF(error); +} + } // namespace -typedef struct external_state_watcher { - grpc_subchannel* subchannel; - grpc_pollset_set* pollset_set; - grpc_closure* notify; - grpc_closure closure; - struct external_state_watcher* next; - struct external_state_watcher* prev; -} external_state_watcher; - -namespace grpc_core { - -class ConnectedSubchannelStateWatcher; - -} // namespace grpc_core - -struct grpc_subchannel { - grpc_connector* connector; - - /** refcount - - lower INTERNAL_REF_BITS bits are for internal references: - these do not keep the subchannel open. - - upper remaining bits are for public references: these do - keep the subchannel open */ - gpr_atm ref_pair; - - /** non-transport related channel filters */ - const grpc_channel_filter** filters; - size_t num_filters; - /** channel arguments */ - grpc_channel_args* args; - - grpc_subchannel_key* key; - - /** set during connection */ - grpc_connect_out_args connecting_result; - - /** callback for connection finishing */ - grpc_closure on_connected; - - /** callback for our alarm */ - grpc_closure on_alarm; - - /** pollset_set tracking who's interested in a connection - being setup */ - grpc_pollset_set* pollset_set; - - grpc_core::UniquePtr health_check_service_name; - - /** mutex protecting remaining elements */ - gpr_mu mu; - - /** active connection, or null */ - grpc_core::RefCountedPtr connected_subchannel; - grpc_core::OrphanablePtr - connected_subchannel_watcher; - - /** have we seen a disconnection? */ - bool disconnected; - /** are we connecting */ - bool connecting; - - /** connectivity state tracking */ - grpc_connectivity_state_tracker state_tracker; - grpc_connectivity_state_tracker state_and_health_tracker; - - external_state_watcher root_external_state_watcher; - - /** backoff state */ - grpc_core::ManualConstructor backoff; - grpc_millis next_attempt_deadline; - grpc_millis min_connect_timeout_ms; - - /** do we have an active alarm? */ - bool have_alarm; - /** have we started the backoff loop */ - bool backoff_begun; - // reset_backoff() was called while alarm was pending - bool deferred_reset_backoff; - /** our alarm */ - grpc_timer alarm; - - grpc_core::RefCountedPtr - channelz_subchannel; -}; - -struct grpc_subchannel_call { - grpc_subchannel_call(grpc_core::ConnectedSubchannel* connection, - const grpc_core::ConnectedSubchannel::CallArgs& args) - : connection(connection), deadline(args.deadline) {} - - grpc_core::ConnectedSubchannel* connection; - grpc_closure* schedule_closure_after_destroy = nullptr; - // state needed to support channelz interception of recv trailing metadata. - grpc_closure recv_trailing_metadata_ready; - grpc_closure* original_recv_trailing_metadata; - grpc_metadata_batch* recv_trailing_metadata = nullptr; - grpc_millis deadline; -}; - -static void maybe_start_connecting_locked(grpc_subchannel* c); - -static const char* subchannel_connectivity_state_change_string( - grpc_connectivity_state state) { - switch (state) { - case GRPC_CHANNEL_IDLE: - return "Subchannel state change to IDLE"; - case GRPC_CHANNEL_CONNECTING: - return "Subchannel state change to CONNECTING"; - case GRPC_CHANNEL_READY: - return "Subchannel state change to READY"; - case GRPC_CHANNEL_TRANSIENT_FAILURE: - return "Subchannel state change to TRANSIENT_FAILURE"; - case GRPC_CHANNEL_SHUTDOWN: - return "Subchannel state change to SHUTDOWN"; +void SubchannelCall::RecvTrailingMetadataReady(void* arg, grpc_error* error) { + SubchannelCall* call = static_cast(arg); + GPR_ASSERT(call->recv_trailing_metadata_ != nullptr); + grpc_status_code status = GRPC_STATUS_OK; + GetCallStatus(&status, call->deadline_, call->recv_trailing_metadata_, + GRPC_ERROR_REF(error)); + channelz::SubchannelNode* channelz_subchannel = + call->connected_subchannel_->channelz_subchannel(); + GPR_ASSERT(channelz_subchannel != nullptr); + if (status == GRPC_STATUS_OK) { + channelz_subchannel->RecordCallSucceeded(); + } else { + channelz_subchannel->RecordCallFailed(); } - GPR_UNREACHABLE_CODE(return "UNKNOWN"); + GRPC_CLOSURE_RUN(call->original_recv_trailing_metadata_, + GRPC_ERROR_REF(error)); } -static void set_subchannel_connectivity_state_locked( - grpc_subchannel* c, grpc_connectivity_state state, grpc_error* error, - const char* reason) { - if (c->channelz_subchannel != nullptr) { - c->channelz_subchannel->AddTraceEvent( - grpc_core::channelz::ChannelTrace::Severity::Info, - grpc_slice_from_static_string( - subchannel_connectivity_state_change_string(state))); - } - grpc_connectivity_state_set(&c->state_tracker, state, error, reason); +void SubchannelCall::IncrementRefCount() { + GRPC_CALL_STACK_REF(SUBCHANNEL_CALL_TO_CALL_STACK(this), ""); } -namespace grpc_core { +void SubchannelCall::IncrementRefCount(const grpc_core::DebugLocation& location, + const char* reason) { + GRPC_CALL_STACK_REF(SUBCHANNEL_CALL_TO_CALL_STACK(this), reason); +} -class ConnectedSubchannelStateWatcher - : public InternallyRefCounted { +// +// Subchannel::ConnectedSubchannelStateWatcher +// + +class Subchannel::ConnectedSubchannelStateWatcher { public: // Must be instantiated while holding c->mu. - explicit ConnectedSubchannelStateWatcher(grpc_subchannel* c) - : subchannel_(c) { + explicit ConnectedSubchannelStateWatcher(Subchannel* c) : subchannel_(c) { // Steal subchannel ref for connecting. GRPC_SUBCHANNEL_WEAK_REF(subchannel_, "state_watcher"); GRPC_SUBCHANNEL_WEAK_UNREF(subchannel_, "connecting"); // Start watching for connectivity state changes. - // Callback uses initial ref to this. GRPC_CLOSURE_INIT(&on_connectivity_changed_, OnConnectivityChanged, this, grpc_schedule_on_exec_ctx); - c->connected_subchannel->NotifyOnStateChange(c->pollset_set, - &pending_connectivity_state_, - &on_connectivity_changed_); - // Start health check if needed. - grpc_connectivity_state health_state = GRPC_CHANNEL_READY; - if (c->health_check_service_name != nullptr) { - health_check_client_ = grpc_core::MakeOrphanable( - c->health_check_service_name.get(), c->connected_subchannel, - c->pollset_set, c->channelz_subchannel); - GRPC_CLOSURE_INIT(&on_health_changed_, OnHealthChanged, this, - grpc_schedule_on_exec_ctx); - Ref().release(); // Ref for health callback tracked manually. - health_check_client_->NotifyOnHealthChange(&health_state_, - &on_health_changed_); - health_state = GRPC_CHANNEL_CONNECTING; - } - // Report initial state. - set_subchannel_connectivity_state_locked( - c, GRPC_CHANNEL_READY, GRPC_ERROR_NONE, "subchannel_connected"); - grpc_connectivity_state_set(&c->state_and_health_tracker, health_state, - GRPC_ERROR_NONE, "subchannel_connected"); + c->connected_subchannel_->NotifyOnStateChange(c->pollset_set_, + &pending_connectivity_state_, + &on_connectivity_changed_); } ~ConnectedSubchannelStateWatcher() { GRPC_SUBCHANNEL_WEAK_UNREF(subchannel_, "state_watcher"); } - void Orphan() override { health_check_client_.reset(); } - private: static void OnConnectivityChanged(void* arg, grpc_error* error) { auto* self = static_cast(arg); - grpc_subchannel* c = self->subchannel_; + Subchannel* c = self->subchannel_; { - MutexLock lock(&c->mu); + MutexLock lock(&c->mu_); switch (self->pending_connectivity_state_) { case GRPC_CHANNEL_TRANSIENT_FAILURE: case GRPC_CHANNEL_SHUTDOWN: { - if (!c->disconnected && c->connected_subchannel != nullptr) { + if (!c->disconnected_ && c->connected_subchannel_ != nullptr) { if (grpc_trace_stream_refcount.enabled()) { gpr_log(GPR_INFO, "Connected subchannel %p of subchannel %p has gone into " "%s. Attempting to reconnect.", - c->connected_subchannel.get(), c, + c->connected_subchannel_.get(), c, grpc_connectivity_state_name( self->pending_connectivity_state_)); } - c->connected_subchannel.reset(); - c->connected_subchannel_watcher.reset(); - self->last_connectivity_state_ = GRPC_CHANNEL_TRANSIENT_FAILURE; - set_subchannel_connectivity_state_locked( - c, GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(error), - "reflect_child"); - grpc_connectivity_state_set(&c->state_and_health_tracker, - GRPC_CHANNEL_TRANSIENT_FAILURE, - GRPC_ERROR_REF(error), "reflect_child"); - c->backoff_begun = false; - c->backoff->Reset(); - maybe_start_connecting_locked(c); - } else { - self->last_connectivity_state_ = GRPC_CHANNEL_SHUTDOWN; + c->connected_subchannel_.reset(); + c->SetConnectivityStateLocked(GRPC_CHANNEL_TRANSIENT_FAILURE); + c->backoff_begun_ = false; + c->backoff_.Reset(); } - self->health_check_client_.reset(); break; } default: { @@ -291,197 +352,255 @@ class ConnectedSubchannelStateWatcher // a callback for READY, because that was the state we started // this watch from. And a connected subchannel should never go // from READY to CONNECTING or IDLE. - self->last_connectivity_state_ = self->pending_connectivity_state_; - set_subchannel_connectivity_state_locked( - c, self->pending_connectivity_state_, GRPC_ERROR_REF(error), - "reflect_child"); - if (self->pending_connectivity_state_ != GRPC_CHANNEL_READY) { - grpc_connectivity_state_set(&c->state_and_health_tracker, - self->pending_connectivity_state_, - GRPC_ERROR_REF(error), "reflect_child"); - } - c->connected_subchannel->NotifyOnStateChange( + c->SetConnectivityStateLocked(self->pending_connectivity_state_); + c->connected_subchannel_->NotifyOnStateChange( nullptr, &self->pending_connectivity_state_, &self->on_connectivity_changed_); - self = nullptr; // So we don't unref below. + return; // So we don't delete ourself below. } } } + // Don't delete until we've released the lock, because this might + // cause the subchannel (which contains the lock) to be destroyed. + Delete(self); + } + + Subchannel* subchannel_; + grpc_closure on_connectivity_changed_; + grpc_connectivity_state pending_connectivity_state_ = GRPC_CHANNEL_READY; +}; + +// +// Subchannel::ConnectivityStateWatcherList +// + +void Subchannel::ConnectivityStateWatcherList::AddWatcherLocked( + UniquePtr watcher) { + watcher->next_ = head_; + head_ = watcher.release(); +} + +void Subchannel::ConnectivityStateWatcherList::RemoveWatcherLocked( + ConnectivityStateWatcher* watcher) { + for (ConnectivityStateWatcher** w = &head_; *w != nullptr; w = &(*w)->next_) { + if (*w == watcher) { + *w = watcher->next_; + Delete(watcher); + return; + } + } + GPR_UNREACHABLE_CODE(return ); +} + +void Subchannel::ConnectivityStateWatcherList::NotifyLocked( + Subchannel* subchannel, grpc_connectivity_state state) { + for (ConnectivityStateWatcher* w = head_; w != nullptr; w = w->next_) { + RefCountedPtr connected_subchannel; + if (state == GRPC_CHANNEL_READY) { + connected_subchannel = subchannel->connected_subchannel_; + } + // TODO(roth): In principle, it seems wrong to send this notification + // to the watcher while holding the subchannel's mutex, since it could + // lead to a deadlock if the watcher calls back into the subchannel + // before returning back to us. In practice, this doesn't happen, + // because the LB policy code that watches subchannels always bounces + // the notification into the client_channel control-plane combiner + // before processing it. But if we ever have any other callers here, + // we will probably need to change this. + w->OnConnectivityStateChange(state, std::move(connected_subchannel)); + } +} + +void Subchannel::ConnectivityStateWatcherList::Clear() { + while (head_ != nullptr) { + ConnectivityStateWatcher* next = head_->next_; + Delete(head_); + head_ = next; + } +} + +// +// Subchannel::HealthWatcherMap::HealthWatcher +// + +// State needed for tracking the connectivity state with a particular +// health check service name. +class Subchannel::HealthWatcherMap::HealthWatcher + : public InternallyRefCounted { + public: + HealthWatcher(Subchannel* c, UniquePtr health_check_service_name, + grpc_connectivity_state subchannel_state) + : subchannel_(c), + health_check_service_name_(std::move(health_check_service_name)), + state_(subchannel_state == GRPC_CHANNEL_READY ? GRPC_CHANNEL_CONNECTING + : subchannel_state) { + GRPC_SUBCHANNEL_WEAK_REF(subchannel_, "health_watcher"); + GRPC_CLOSURE_INIT(&on_health_changed_, OnHealthChanged, this, + grpc_schedule_on_exec_ctx); + // If the subchannel is already connected, start health checking. + if (subchannel_state == GRPC_CHANNEL_READY) StartHealthCheckingLocked(); + } + + ~HealthWatcher() { + GRPC_SUBCHANNEL_WEAK_UNREF(subchannel_, "health_watcher"); + } + + const char* health_check_service_name() const { + return health_check_service_name_.get(); + } + + grpc_connectivity_state state() const { return state_; } + + void AddWatcherLocked(grpc_connectivity_state initial_state, + UniquePtr watcher) { + if (state_ != initial_state) { + RefCountedPtr connected_subchannel; + if (state_ == GRPC_CHANNEL_READY) { + connected_subchannel = subchannel_->connected_subchannel_; + } + watcher->OnConnectivityStateChange(state_, + std::move(connected_subchannel)); + } + watcher_list_.AddWatcherLocked(std::move(watcher)); + } + + void RemoveWatcherLocked(ConnectivityStateWatcher* watcher) { + watcher_list_.RemoveWatcherLocked(watcher); + } + + bool HasWatchers() const { return !watcher_list_.empty(); } + + void NotifyLocked(grpc_connectivity_state state) { + if (state == GRPC_CHANNEL_READY) { + // If we had not already notified for CONNECTING state, do so now. + // (We may have missed this earlier, because if the transition + // from IDLE to CONNECTING to READY was too quick, the connected + // subchannel may not have sent us a notification for CONNECTING.) + if (state_ != GRPC_CHANNEL_CONNECTING) { + state_ = GRPC_CHANNEL_CONNECTING; + watcher_list_.NotifyLocked(subchannel_, state_); + } + // If we've become connected, start health checking. + StartHealthCheckingLocked(); + } else { + state_ = state; + watcher_list_.NotifyLocked(subchannel_, state_); + // We're not connected, so stop health checking. + health_check_client_.reset(); + } + } + + void Orphan() override { + watcher_list_.Clear(); + health_check_client_.reset(); + Unref(); + } + + private: + void StartHealthCheckingLocked() { + GPR_ASSERT(health_check_client_ == nullptr); + health_check_client_ = MakeOrphanable( + health_check_service_name_.get(), subchannel_->connected_subchannel_, + subchannel_->pollset_set_, subchannel_->channelz_node_); + Ref().release(); // Ref for health callback tracked manually. + health_check_client_->NotifyOnHealthChange(&state_, &on_health_changed_); + } + + static void OnHealthChanged(void* arg, grpc_error* error) { + auto* self = static_cast(arg); + Subchannel* c = self->subchannel_; + { + MutexLock lock(&c->mu_); + if (self->state_ != GRPC_CHANNEL_SHUTDOWN && + self->health_check_client_ != nullptr) { + self->watcher_list_.NotifyLocked(c, self->state_); + // Renew watch. + self->health_check_client_->NotifyOnHealthChange( + &self->state_, &self->on_health_changed_); + return; // So we don't unref below. + } + } // Don't unref until we've released the lock, because this might // cause the subchannel (which contains the lock) to be destroyed. - if (self != nullptr) self->Unref(); + self->Unref(); } - static void OnHealthChanged(void* arg, grpc_error* error) { - auto* self = static_cast(arg); - if (self->health_state_ == GRPC_CHANNEL_SHUTDOWN) { - self->Unref(); - return; - } - grpc_subchannel* c = self->subchannel_; - MutexLock lock(&c->mu); - if (self->last_connectivity_state_ == GRPC_CHANNEL_READY) { - grpc_connectivity_state_set(&c->state_and_health_tracker, - self->health_state_, GRPC_ERROR_REF(error), - "health_changed"); - } - self->health_check_client_->NotifyOnHealthChange(&self->health_state_, - &self->on_health_changed_); - } - - grpc_subchannel* subchannel_; - grpc_closure on_connectivity_changed_; - grpc_connectivity_state pending_connectivity_state_ = GRPC_CHANNEL_READY; - grpc_connectivity_state last_connectivity_state_ = GRPC_CHANNEL_READY; - grpc_core::OrphanablePtr health_check_client_; + Subchannel* subchannel_; + UniquePtr health_check_service_name_; + OrphanablePtr health_check_client_; grpc_closure on_health_changed_; - grpc_connectivity_state health_state_ = GRPC_CHANNEL_CONNECTING; + grpc_connectivity_state state_; + ConnectivityStateWatcherList watcher_list_; }; -} // namespace grpc_core +// +// Subchannel::HealthWatcherMap +// -#define SUBCHANNEL_CALL_TO_CALL_STACK(call) \ - (grpc_call_stack*)((char*)(call) + GPR_ROUND_UP_TO_ALIGNMENT_SIZE( \ - sizeof(grpc_subchannel_call))) -#define CALLSTACK_TO_SUBCHANNEL_CALL(callstack) \ - (grpc_subchannel_call*)(((char*)(call_stack)) - \ - GPR_ROUND_UP_TO_ALIGNMENT_SIZE( \ - sizeof(grpc_subchannel_call))) - -static void on_subchannel_connected(void* subchannel, grpc_error* error); - -#ifndef NDEBUG -#define REF_REASON reason -#define REF_MUTATE_EXTRA_ARGS \ - GRPC_SUBCHANNEL_REF_EXTRA_ARGS, const char* purpose -#define REF_MUTATE_PURPOSE(x) , file, line, reason, x -#else -#define REF_REASON "" -#define REF_MUTATE_EXTRA_ARGS -#define REF_MUTATE_PURPOSE(x) -#endif - -/* - * connection implementation - */ - -static void connection_destroy(void* arg, grpc_error* error) { - grpc_channel_stack* stk = static_cast(arg); - grpc_channel_stack_destroy(stk); - gpr_free(stk); -} - -/* - * grpc_subchannel implementation - */ - -static void subchannel_destroy(void* arg, grpc_error* error) { - grpc_subchannel* c = static_cast(arg); - if (c->channelz_subchannel != nullptr) { - c->channelz_subchannel->AddTraceEvent( - grpc_core::channelz::ChannelTrace::Severity::Info, - grpc_slice_from_static_string("Subchannel destroyed")); - c->channelz_subchannel->MarkSubchannelDestroyed(); - c->channelz_subchannel.reset(); +void Subchannel::HealthWatcherMap::AddWatcherLocked( + Subchannel* subchannel, grpc_connectivity_state initial_state, + UniquePtr health_check_service_name, + UniquePtr watcher) { + // If the health check service name is not already present in the map, + // add it. + auto it = map_.find(health_check_service_name.get()); + HealthWatcher* health_watcher; + if (it == map_.end()) { + const char* key = health_check_service_name.get(); + auto w = MakeOrphanable( + subchannel, std::move(health_check_service_name), subchannel->state_); + health_watcher = w.get(); + map_[key] = std::move(w); + } else { + health_watcher = it->second.get(); } - gpr_free((void*)c->filters); - c->health_check_service_name.reset(); - grpc_channel_args_destroy(c->args); - grpc_connectivity_state_destroy(&c->state_tracker); - grpc_connectivity_state_destroy(&c->state_and_health_tracker); - grpc_connector_unref(c->connector); - grpc_pollset_set_destroy(c->pollset_set); - grpc_subchannel_key_destroy(c->key); - gpr_mu_destroy(&c->mu); - gpr_free(c); + // Add the watcher to the entry. + health_watcher->AddWatcherLocked(initial_state, std::move(watcher)); } -static gpr_atm ref_mutate(grpc_subchannel* c, gpr_atm delta, - int barrier REF_MUTATE_EXTRA_ARGS) { - gpr_atm old_val = barrier ? gpr_atm_full_fetch_add(&c->ref_pair, delta) - : gpr_atm_no_barrier_fetch_add(&c->ref_pair, delta); -#ifndef NDEBUG - if (grpc_trace_stream_refcount.enabled()) { - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, - "SUBCHANNEL: %p %12s 0x%" PRIxPTR " -> 0x%" PRIxPTR " [%s]", c, - purpose, old_val, old_val + delta, reason); - } -#endif - return old_val; +void Subchannel::HealthWatcherMap::RemoveWatcherLocked( + const char* health_check_service_name, ConnectivityStateWatcher* watcher) { + auto it = map_.find(health_check_service_name); + GPR_ASSERT(it != map_.end()); + it->second->RemoveWatcherLocked(watcher); + // If we just removed the last watcher for this service name, remove + // the map entry. + if (!it->second->HasWatchers()) map_.erase(it); } -grpc_subchannel* grpc_subchannel_ref( - grpc_subchannel* c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { - gpr_atm old_refs; - old_refs = ref_mutate(c, (1 << INTERNAL_REF_BITS), - 0 REF_MUTATE_PURPOSE("STRONG_REF")); - GPR_ASSERT((old_refs & STRONG_REF_MASK) != 0); - return c; -} - -grpc_subchannel* grpc_subchannel_weak_ref( - grpc_subchannel* c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { - gpr_atm old_refs; - old_refs = ref_mutate(c, 1, 0 REF_MUTATE_PURPOSE("WEAK_REF")); - GPR_ASSERT(old_refs != 0); - return c; -} - -grpc_subchannel* grpc_subchannel_ref_from_weak_ref( - grpc_subchannel* c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { - if (!c) return nullptr; - for (;;) { - gpr_atm old_refs = gpr_atm_acq_load(&c->ref_pair); - if (old_refs >= (1 << INTERNAL_REF_BITS)) { - gpr_atm new_refs = old_refs + (1 << INTERNAL_REF_BITS); - if (gpr_atm_rel_cas(&c->ref_pair, old_refs, new_refs)) { - return c; - } - } else { - return nullptr; - } +void Subchannel::HealthWatcherMap::NotifyLocked(grpc_connectivity_state state) { + for (const auto& p : map_) { + p.second->NotifyLocked(state); } } -static void disconnect(grpc_subchannel* c) { - grpc_subchannel_index_unregister(c->key, c); - gpr_mu_lock(&c->mu); - GPR_ASSERT(!c->disconnected); - c->disconnected = true; - grpc_connector_shutdown(c->connector, GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "Subchannel disconnected")); - c->connected_subchannel.reset(); - c->connected_subchannel_watcher.reset(); - gpr_mu_unlock(&c->mu); -} - -void grpc_subchannel_unref(grpc_subchannel* c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { - gpr_atm old_refs; - // add a weak ref and subtract a strong ref (atomically) - old_refs = ref_mutate( - c, static_cast(1) - static_cast(1 << INTERNAL_REF_BITS), - 1 REF_MUTATE_PURPOSE("STRONG_UNREF")); - if ((old_refs & STRONG_REF_MASK) == (1 << INTERNAL_REF_BITS)) { - disconnect(c); +grpc_connectivity_state +Subchannel::HealthWatcherMap::CheckConnectivityStateLocked( + Subchannel* subchannel, const char* health_check_service_name) { + auto it = map_.find(health_check_service_name); + if (it == map_.end()) { + // If the health check service name is not found in the map, we're + // not currently doing a health check for that service name. If the + // subchannel's state without health checking is READY, report + // CONNECTING, since that's what we'd be in as soon as we do start a + // watch. Otherwise, report the channel's state without health checking. + return subchannel->state_ == GRPC_CHANNEL_READY ? GRPC_CHANNEL_CONNECTING + : subchannel->state_; } - GRPC_SUBCHANNEL_WEAK_UNREF(c, "strong-unref"); + HealthWatcher* health_watcher = it->second.get(); + return health_watcher->state(); } -void grpc_subchannel_weak_unref( - grpc_subchannel* c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { - gpr_atm old_refs; - old_refs = ref_mutate(c, -static_cast(1), - 1 REF_MUTATE_PURPOSE("WEAK_UNREF")); - if (old_refs == 1) { - GRPC_CLOSURE_SCHED( - GRPC_CLOSURE_CREATE(subchannel_destroy, c, grpc_schedule_on_exec_ctx), - GRPC_ERROR_NONE); - } -} +void Subchannel::HealthWatcherMap::ShutdownLocked() { map_.clear(); } -static void parse_args_for_backoff_values( - const grpc_channel_args* args, grpc_core::BackOff::Options* backoff_options, - grpc_millis* min_connect_timeout_ms) { +// +// Subchannel +// + +namespace { + +BackOff::Options ParseArgsForBackoffValues( + const grpc_channel_args* args, grpc_millis* min_connect_timeout_ms) { grpc_millis initial_backoff_ms = GRPC_SUBCHANNEL_INITIAL_CONNECT_BACKOFF_SECONDS * 1000; *min_connect_timeout_ms = @@ -518,7 +637,8 @@ static void parse_args_for_backoff_values( } } } - backoff_options->set_initial_backoff(initial_backoff_ms) + return BackOff::Options() + .set_initial_backoff(initial_backoff_ms) .set_multiplier(fixed_reconnect_backoff ? 1.0 : GRPC_SUBCHANNEL_RECONNECT_BACKOFF_MULTIPLIER) @@ -527,531 +647,248 @@ static void parse_args_for_backoff_values( .set_max_backoff(max_backoff_ms); } -namespace grpc_core { -namespace { - -struct HealthCheckParams { - UniquePtr service_name; - - static void Parse(const grpc_json* field, HealthCheckParams* params) { - if (strcmp(field->key, "healthCheckConfig") == 0) { - if (field->type != GRPC_JSON_OBJECT) return; - for (grpc_json* sub_field = field->child; sub_field != nullptr; - sub_field = sub_field->next) { - if (sub_field->key == nullptr) return; - if (strcmp(sub_field->key, "serviceName") == 0) { - if (params->service_name != nullptr) return; // Duplicate. - if (sub_field->type != GRPC_JSON_STRING) return; - params->service_name.reset(gpr_strdup(sub_field->value)); - } - } - } - } -}; - } // namespace -} // namespace grpc_core - -grpc_subchannel* grpc_subchannel_create(grpc_connector* connector, - const grpc_subchannel_args* args) { - grpc_subchannel_key* key = grpc_subchannel_key_create(args); - grpc_subchannel* c = grpc_subchannel_index_find(key); - if (c) { - grpc_subchannel_key_destroy(key); - return c; - } +Subchannel::Subchannel(SubchannelKey* key, grpc_connector* connector, + const grpc_channel_args* args) + : key_(key), + connector_(connector), + backoff_(ParseArgsForBackoffValues(args, &min_connect_timeout_ms_)) { GRPC_STATS_INC_CLIENT_SUBCHANNELS_CREATED(); - c = static_cast(gpr_zalloc(sizeof(*c))); - c->key = key; - gpr_atm_no_barrier_store(&c->ref_pair, 1 << INTERNAL_REF_BITS); - c->connector = connector; - grpc_connector_ref(c->connector); - c->num_filters = args->filter_count; - if (c->num_filters > 0) { - c->filters = static_cast( - gpr_malloc(sizeof(grpc_channel_filter*) * c->num_filters)); - memcpy((void*)c->filters, args->filters, - sizeof(grpc_channel_filter*) * c->num_filters); - } else { - c->filters = nullptr; - } - c->pollset_set = grpc_pollset_set_create(); + gpr_atm_no_barrier_store(&ref_pair_, 1 << INTERNAL_REF_BITS); + grpc_connector_ref(connector_); + pollset_set_ = grpc_pollset_set_create(); grpc_resolved_address* addr = static_cast(gpr_malloc(sizeof(*addr))); - grpc_get_subchannel_address_arg(args->args, addr); + GetAddressFromSubchannelAddressArg(args, addr); grpc_resolved_address* new_address = nullptr; grpc_channel_args* new_args = nullptr; - if (grpc_proxy_mappers_map_address(addr, args->args, &new_address, - &new_args)) { + if (grpc_proxy_mappers_map_address(addr, args, &new_address, &new_args)) { GPR_ASSERT(new_address != nullptr); gpr_free(addr); addr = new_address; } static const char* keys_to_remove[] = {GRPC_ARG_SUBCHANNEL_ADDRESS}; - grpc_arg new_arg = grpc_create_subchannel_address_arg(addr); + grpc_arg new_arg = CreateSubchannelAddressArg(addr); gpr_free(addr); - c->args = grpc_channel_args_copy_and_add_and_remove( - new_args != nullptr ? new_args : args->args, keys_to_remove, + args_ = grpc_channel_args_copy_and_add_and_remove( + new_args != nullptr ? new_args : args, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), &new_arg, 1); gpr_free(new_arg.value.string); if (new_args != nullptr) grpc_channel_args_destroy(new_args); - c->root_external_state_watcher.next = c->root_external_state_watcher.prev = - &c->root_external_state_watcher; - GRPC_CLOSURE_INIT(&c->on_connected, on_subchannel_connected, c, + GRPC_CLOSURE_INIT(&on_connecting_finished_, OnConnectingFinished, this, grpc_schedule_on_exec_ctx); - grpc_connectivity_state_init(&c->state_tracker, GRPC_CHANNEL_IDLE, - "subchannel"); - grpc_connectivity_state_init(&c->state_and_health_tracker, GRPC_CHANNEL_IDLE, - "subchannel"); - grpc_core::BackOff::Options backoff_options; - parse_args_for_backoff_values(args->args, &backoff_options, - &c->min_connect_timeout_ms); - c->backoff.Init(backoff_options); - gpr_mu_init(&c->mu); - - // Check whether we should enable health checking. - const char* service_config_json = grpc_channel_arg_get_string( - grpc_channel_args_find(c->args, GRPC_ARG_SERVICE_CONFIG)); - if (service_config_json != nullptr) { - grpc_core::UniquePtr service_config = - grpc_core::ServiceConfig::Create(service_config_json); - if (service_config != nullptr) { - grpc_core::HealthCheckParams params; - service_config->ParseGlobalParams(grpc_core::HealthCheckParams::Parse, - ¶ms); - c->health_check_service_name = std::move(params.service_name); - } - } - - const grpc_arg* arg = - grpc_channel_args_find(c->args, GRPC_ARG_ENABLE_CHANNELZ); - bool channelz_enabled = + const grpc_arg* arg = grpc_channel_args_find(args_, GRPC_ARG_ENABLE_CHANNELZ); + const bool channelz_enabled = grpc_channel_arg_get_bool(arg, GRPC_ENABLE_CHANNELZ_DEFAULT); arg = grpc_channel_args_find( - c->args, GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE); + args_, GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE); const grpc_integer_options options = { GRPC_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE_DEFAULT, 0, INT_MAX}; size_t channel_tracer_max_memory = (size_t)grpc_channel_arg_get_integer(arg, options); if (channelz_enabled) { - c->channelz_subchannel = - grpc_core::MakeRefCounted( - c, channel_tracer_max_memory); - c->channelz_subchannel->AddTraceEvent( - grpc_core::channelz::ChannelTrace::Severity::Info, - grpc_slice_from_static_string("Subchannel created")); + channelz_node_ = MakeRefCounted( + this, channel_tracer_max_memory); + channelz_node_->AddTraceEvent( + channelz::ChannelTrace::Severity::Info, + grpc_slice_from_static_string("subchannel created")); } - - return grpc_subchannel_index_register(key, c); } -grpc_core::channelz::SubchannelNode* grpc_subchannel_get_channelz_node( - grpc_subchannel* subchannel) { - return subchannel->channelz_subchannel.get(); +Subchannel::~Subchannel() { + if (channelz_node_ != nullptr) { + channelz_node_->AddTraceEvent( + channelz::ChannelTrace::Severity::Info, + grpc_slice_from_static_string("Subchannel destroyed")); + channelz_node_->MarkSubchannelDestroyed(); + } + grpc_channel_args_destroy(args_); + grpc_connector_unref(connector_); + grpc_pollset_set_destroy(pollset_set_); + Delete(key_); } -intptr_t grpc_subchannel_get_child_socket_uuid(grpc_subchannel* subchannel) { - if (subchannel->connected_subchannel != nullptr) { - return subchannel->connected_subchannel->socket_uuid(); +Subchannel* Subchannel::Create(grpc_connector* connector, + const grpc_channel_args* args) { + SubchannelKey* key = New(args); + SubchannelPoolInterface* subchannel_pool = + SubchannelPoolInterface::GetSubchannelPoolFromChannelArgs(args); + GPR_ASSERT(subchannel_pool != nullptr); + Subchannel* c = subchannel_pool->FindSubchannel(key); + if (c != nullptr) { + Delete(key); + return c; + } + c = New(key, connector, args); + // Try to register the subchannel before setting the subchannel pool. + // Otherwise, in case of a registration race, unreffing c in + // RegisterSubchannel() will cause c to be tried to be unregistered, while + // its key maps to a different subchannel. + Subchannel* registered = subchannel_pool->RegisterSubchannel(key, c); + if (registered == c) c->subchannel_pool_ = subchannel_pool->Ref(); + return registered; +} + +Subchannel* Subchannel::Ref(GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { + gpr_atm old_refs; + old_refs = RefMutate((1 << INTERNAL_REF_BITS), + 0 GRPC_SUBCHANNEL_REF_MUTATE_PURPOSE("STRONG_REF")); + GPR_ASSERT((old_refs & STRONG_REF_MASK) != 0); + return this; +} + +void Subchannel::Unref(GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { + gpr_atm old_refs; + // add a weak ref and subtract a strong ref (atomically) + old_refs = RefMutate( + static_cast(1) - static_cast(1 << INTERNAL_REF_BITS), + 1 GRPC_SUBCHANNEL_REF_MUTATE_PURPOSE("STRONG_UNREF")); + if ((old_refs & STRONG_REF_MASK) == (1 << INTERNAL_REF_BITS)) { + Disconnect(); + } + GRPC_SUBCHANNEL_WEAK_UNREF(this, "strong-unref"); +} + +Subchannel* Subchannel::WeakRef(GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { + gpr_atm old_refs; + old_refs = RefMutate(1, 0 GRPC_SUBCHANNEL_REF_MUTATE_PURPOSE("WEAK_REF")); + GPR_ASSERT(old_refs != 0); + return this; +} + +namespace { + +void subchannel_destroy(void* arg, grpc_error* error) { + Subchannel* self = static_cast(arg); + Delete(self); +} + +} // namespace + +void Subchannel::WeakUnref(GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { + gpr_atm old_refs; + old_refs = RefMutate(-static_cast(1), + 1 GRPC_SUBCHANNEL_REF_MUTATE_PURPOSE("WEAK_UNREF")); + if (old_refs == 1) { + GRPC_CLOSURE_SCHED(GRPC_CLOSURE_CREATE(subchannel_destroy, this, + grpc_schedule_on_exec_ctx), + GRPC_ERROR_NONE); + } +} + +Subchannel* Subchannel::RefFromWeakRef(GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { + for (;;) { + gpr_atm old_refs = gpr_atm_acq_load(&ref_pair_); + if (old_refs >= (1 << INTERNAL_REF_BITS)) { + gpr_atm new_refs = old_refs + (1 << INTERNAL_REF_BITS); + if (gpr_atm_rel_cas(&ref_pair_, old_refs, new_refs)) { + return this; + } + } else { + return nullptr; + } + } +} + +intptr_t Subchannel::GetChildSocketUuid() { + if (connected_subchannel_ != nullptr) { + return connected_subchannel_->socket_uuid(); } else { return 0; } } -static void continue_connect_locked(grpc_subchannel* c) { - grpc_connect_in_args args; - args.interested_parties = c->pollset_set; - const grpc_millis min_deadline = - c->min_connect_timeout_ms + grpc_core::ExecCtx::Get()->Now(); - c->next_attempt_deadline = c->backoff->NextAttemptTime(); - args.deadline = std::max(c->next_attempt_deadline, min_deadline); - args.channel_args = c->args; - set_subchannel_connectivity_state_locked(c, GRPC_CHANNEL_CONNECTING, - GRPC_ERROR_NONE, "connecting"); - grpc_connectivity_state_set(&c->state_and_health_tracker, - GRPC_CHANNEL_CONNECTING, GRPC_ERROR_NONE, - "connecting"); - grpc_connector_connect(c->connector, &args, &c->connecting_result, - &c->on_connected); -} - -grpc_connectivity_state grpc_subchannel_check_connectivity( - grpc_subchannel* c, grpc_error** error, bool inhibit_health_checks) { - gpr_mu_lock(&c->mu); - grpc_connectivity_state_tracker* tracker = - inhibit_health_checks ? &c->state_tracker : &c->state_and_health_tracker; - grpc_connectivity_state state = grpc_connectivity_state_get(tracker, error); - gpr_mu_unlock(&c->mu); - return state; -} - -static void on_external_state_watcher_done(void* arg, grpc_error* error) { - external_state_watcher* w = static_cast(arg); - grpc_closure* follow_up = w->notify; - if (w->pollset_set != nullptr) { - grpc_pollset_set_del_pollset_set(w->subchannel->pollset_set, - w->pollset_set); - } - gpr_mu_lock(&w->subchannel->mu); - w->next->prev = w->prev; - w->prev->next = w->next; - gpr_mu_unlock(&w->subchannel->mu); - GRPC_SUBCHANNEL_WEAK_UNREF(w->subchannel, "external_state_watcher"); - gpr_free(w); - GRPC_CLOSURE_SCHED(follow_up, GRPC_ERROR_REF(error)); -} - -static void on_alarm(void* arg, grpc_error* error) { - grpc_subchannel* c = static_cast(arg); - gpr_mu_lock(&c->mu); - c->have_alarm = false; - if (c->disconnected) { - error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING("Disconnected", - &error, 1); - } else if (c->deferred_reset_backoff) { - c->deferred_reset_backoff = false; - error = GRPC_ERROR_NONE; - } else { - GRPC_ERROR_REF(error); - } - if (error == GRPC_ERROR_NONE) { - gpr_log(GPR_INFO, "Failed to connect to channel, retrying"); - continue_connect_locked(c); - gpr_mu_unlock(&c->mu); - } else { - gpr_mu_unlock(&c->mu); - GRPC_SUBCHANNEL_WEAK_UNREF(c, "connecting"); - } - GRPC_ERROR_UNREF(error); -} - -static void maybe_start_connecting_locked(grpc_subchannel* c) { - if (c->disconnected) { - /* Don't try to connect if we're already disconnected */ - return; - } - if (c->connecting) { - /* Already connecting: don't restart */ - return; - } - if (c->connected_subchannel != nullptr) { - /* Already connected: don't restart */ - return; - } - if (!grpc_connectivity_state_has_watchers(&c->state_tracker) && - !grpc_connectivity_state_has_watchers(&c->state_and_health_tracker)) { - /* Nobody is interested in connecting: so don't just yet */ - return; - } - c->connecting = true; - GRPC_SUBCHANNEL_WEAK_REF(c, "connecting"); - if (!c->backoff_begun) { - c->backoff_begun = true; - continue_connect_locked(c); - } else { - GPR_ASSERT(!c->have_alarm); - c->have_alarm = true; - const grpc_millis time_til_next = - c->next_attempt_deadline - grpc_core::ExecCtx::Get()->Now(); - if (time_til_next <= 0) { - gpr_log(GPR_INFO, "Subchannel %p: Retry immediately", c); - } else { - gpr_log(GPR_INFO, "Subchannel %p: Retry in %" PRId64 " milliseconds", c, - time_til_next); - } - GRPC_CLOSURE_INIT(&c->on_alarm, on_alarm, c, grpc_schedule_on_exec_ctx); - grpc_timer_init(&c->alarm, c->next_attempt_deadline, &c->on_alarm); - } -} - -void grpc_subchannel_notify_on_state_change( - grpc_subchannel* c, grpc_pollset_set* interested_parties, - grpc_connectivity_state* state, grpc_closure* notify, - bool inhibit_health_checks) { - grpc_connectivity_state_tracker* tracker = - inhibit_health_checks ? &c->state_tracker : &c->state_and_health_tracker; - external_state_watcher* w; - if (state == nullptr) { - gpr_mu_lock(&c->mu); - for (w = c->root_external_state_watcher.next; - w != &c->root_external_state_watcher; w = w->next) { - if (w->notify == notify) { - grpc_connectivity_state_notify_on_state_change(tracker, nullptr, - &w->closure); - } - } - gpr_mu_unlock(&c->mu); - } else { - w = static_cast(gpr_malloc(sizeof(*w))); - w->subchannel = c; - w->pollset_set = interested_parties; - w->notify = notify; - GRPC_CLOSURE_INIT(&w->closure, on_external_state_watcher_done, w, - grpc_schedule_on_exec_ctx); - if (interested_parties != nullptr) { - grpc_pollset_set_add_pollset_set(c->pollset_set, interested_parties); - } - GRPC_SUBCHANNEL_WEAK_REF(c, "external_state_watcher"); - gpr_mu_lock(&c->mu); - w->next = &c->root_external_state_watcher; - w->prev = w->next->prev; - w->next->prev = w->prev->next = w; - grpc_connectivity_state_notify_on_state_change(tracker, state, &w->closure); - maybe_start_connecting_locked(c); - gpr_mu_unlock(&c->mu); - } -} - -static bool publish_transport_locked(grpc_subchannel* c) { - /* construct channel stack */ - grpc_channel_stack_builder* builder = grpc_channel_stack_builder_create(); - grpc_channel_stack_builder_set_channel_arguments( - builder, c->connecting_result.channel_args); - grpc_channel_stack_builder_set_transport(builder, - c->connecting_result.transport); - - if (!grpc_channel_init_create_stack(builder, GRPC_CLIENT_SUBCHANNEL)) { - grpc_channel_stack_builder_destroy(builder); - return false; - } - grpc_channel_stack* stk; - grpc_error* error = grpc_channel_stack_builder_finish( - builder, 0, 1, connection_destroy, nullptr, - reinterpret_cast(&stk)); - if (error != GRPC_ERROR_NONE) { - grpc_transport_destroy(c->connecting_result.transport); - gpr_log(GPR_ERROR, "error initializing subchannel stack: %s", - grpc_error_string(error)); - GRPC_ERROR_UNREF(error); - return false; - } - intptr_t socket_uuid = c->connecting_result.socket_uuid; - memset(&c->connecting_result, 0, sizeof(c->connecting_result)); - - if (c->disconnected) { - grpc_channel_stack_destroy(stk); - gpr_free(stk); - return false; - } - - /* publish */ - c->connected_subchannel.reset(grpc_core::New( - stk, c->channelz_subchannel, socket_uuid)); - gpr_log(GPR_INFO, "New connected subchannel at %p for subchannel %p", - c->connected_subchannel.get(), c); - - // Instantiate state watcher. Will clean itself up. - c->connected_subchannel_watcher = - grpc_core::MakeOrphanable(c); - - return true; -} - -static void on_subchannel_connected(void* arg, grpc_error* error) { - grpc_subchannel* c = static_cast(arg); - grpc_channel_args* delete_channel_args = c->connecting_result.channel_args; - - GRPC_SUBCHANNEL_WEAK_REF(c, "on_subchannel_connected"); - gpr_mu_lock(&c->mu); - c->connecting = false; - if (c->connecting_result.transport != nullptr && - publish_transport_locked(c)) { - /* do nothing, transport was published */ - } else if (c->disconnected) { - GRPC_SUBCHANNEL_WEAK_UNREF(c, "connecting"); - } else { - set_subchannel_connectivity_state_locked( - c, GRPC_CHANNEL_TRANSIENT_FAILURE, - grpc_error_set_int(GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Connect Failed", &error, 1), - GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE), - "connect_failed"); - grpc_connectivity_state_set( - &c->state_and_health_tracker, GRPC_CHANNEL_TRANSIENT_FAILURE, - grpc_error_set_int(GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Connect Failed", &error, 1), - GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE), - "connect_failed"); - - const char* errmsg = grpc_error_string(error); - gpr_log(GPR_INFO, "Connect failed: %s", errmsg); - - maybe_start_connecting_locked(c); - GRPC_SUBCHANNEL_WEAK_UNREF(c, "connecting"); - } - gpr_mu_unlock(&c->mu); - GRPC_SUBCHANNEL_WEAK_UNREF(c, "connected"); - grpc_channel_args_destroy(delete_channel_args); -} - -void grpc_subchannel_reset_backoff(grpc_subchannel* subchannel) { - gpr_mu_lock(&subchannel->mu); - if (subchannel->have_alarm) { - subchannel->deferred_reset_backoff = true; - grpc_timer_cancel(&subchannel->alarm); - } else { - subchannel->backoff_begun = false; - subchannel->backoff->Reset(); - maybe_start_connecting_locked(subchannel); - } - gpr_mu_unlock(&subchannel->mu); -} - -/* - * grpc_subchannel_call implementation - */ - -static void subchannel_call_destroy(void* call, grpc_error* error) { - GPR_TIMER_SCOPE("grpc_subchannel_call_unref.destroy", 0); - grpc_subchannel_call* c = static_cast(call); - grpc_core::ConnectedSubchannel* connection = c->connection; - grpc_call_stack_destroy(SUBCHANNEL_CALL_TO_CALL_STACK(c), nullptr, - c->schedule_closure_after_destroy); - connection->Unref(DEBUG_LOCATION, "subchannel_call"); - c->~grpc_subchannel_call(); -} - -void grpc_subchannel_call_set_cleanup_closure(grpc_subchannel_call* call, - grpc_closure* closure) { - GPR_ASSERT(call->schedule_closure_after_destroy == nullptr); - GPR_ASSERT(closure != nullptr); - call->schedule_closure_after_destroy = closure; -} - -grpc_subchannel_call* grpc_subchannel_call_ref( - grpc_subchannel_call* c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { - GRPC_CALL_STACK_REF(SUBCHANNEL_CALL_TO_CALL_STACK(c), REF_REASON); - return c; -} - -void grpc_subchannel_call_unref( - grpc_subchannel_call* c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { - GRPC_CALL_STACK_UNREF(SUBCHANNEL_CALL_TO_CALL_STACK(c), REF_REASON); -} - -// Sets *status based on md_batch and error. -static void get_call_status(grpc_subchannel_call* call, - grpc_metadata_batch* md_batch, grpc_error* error, - grpc_status_code* status) { - if (error != GRPC_ERROR_NONE) { - grpc_error_get_status(error, call->deadline, status, nullptr, nullptr, - nullptr); - } else { - if (md_batch->idx.named.grpc_status != nullptr) { - *status = grpc_get_status_code_from_metadata( - md_batch->idx.named.grpc_status->md); - } else { - *status = GRPC_STATUS_UNKNOWN; - } - } - GRPC_ERROR_UNREF(error); -} - -static void recv_trailing_metadata_ready(void* arg, grpc_error* error) { - grpc_subchannel_call* call = static_cast(arg); - GPR_ASSERT(call->recv_trailing_metadata != nullptr); - grpc_status_code status = GRPC_STATUS_OK; - grpc_metadata_batch* md_batch = call->recv_trailing_metadata; - get_call_status(call, md_batch, GRPC_ERROR_REF(error), &status); - grpc_core::channelz::SubchannelNode* channelz_subchannel = - call->connection->channelz_subchannel(); - GPR_ASSERT(channelz_subchannel != nullptr); - if (status == GRPC_STATUS_OK) { - channelz_subchannel->RecordCallSucceeded(); - } else { - channelz_subchannel->RecordCallFailed(); - } - GRPC_CLOSURE_RUN(call->original_recv_trailing_metadata, - GRPC_ERROR_REF(error)); -} - -// If channelz is enabled, intercept recv_trailing so that we may check the -// status and associate it to a subchannel. -static void maybe_intercept_recv_trailing_metadata( - grpc_subchannel_call* call, grpc_transport_stream_op_batch* batch) { - // only intercept payloads with recv trailing. - if (!batch->recv_trailing_metadata) { - return; - } - // only add interceptor is channelz is enabled. - if (call->connection->channelz_subchannel() == nullptr) { - return; - } - GRPC_CLOSURE_INIT(&call->recv_trailing_metadata_ready, - recv_trailing_metadata_ready, call, - grpc_schedule_on_exec_ctx); - // save some state needed for the interception callback. - GPR_ASSERT(call->recv_trailing_metadata == nullptr); - call->recv_trailing_metadata = - batch->payload->recv_trailing_metadata.recv_trailing_metadata; - call->original_recv_trailing_metadata = - batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready; - batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready = - &call->recv_trailing_metadata_ready; -} - -void grpc_subchannel_call_process_op(grpc_subchannel_call* call, - grpc_transport_stream_op_batch* batch) { - GPR_TIMER_SCOPE("grpc_subchannel_call_process_op", 0); - maybe_intercept_recv_trailing_metadata(call, batch); - grpc_call_stack* call_stack = SUBCHANNEL_CALL_TO_CALL_STACK(call); - grpc_call_element* top_elem = grpc_call_stack_element(call_stack, 0); - GRPC_CALL_LOG_OP(GPR_INFO, top_elem, batch); - top_elem->filter->start_transport_stream_op_batch(top_elem, batch); -} - -grpc_core::RefCountedPtr -grpc_subchannel_get_connected_subchannel(grpc_subchannel* c) { - gpr_mu_lock(&c->mu); - auto copy = c->connected_subchannel; - gpr_mu_unlock(&c->mu); - return copy; -} - -const grpc_subchannel_key* grpc_subchannel_get_key( - const grpc_subchannel* subchannel) { - return subchannel->key; -} - -void* grpc_connected_subchannel_call_get_parent_data( - grpc_subchannel_call* subchannel_call) { - grpc_channel_stack* chanstk = subchannel_call->connection->channel_stack(); - return (char*)subchannel_call + sizeof(grpc_subchannel_call) + - chanstk->call_stack_size; -} - -grpc_call_stack* grpc_subchannel_call_get_call_stack( - grpc_subchannel_call* subchannel_call) { - return SUBCHANNEL_CALL_TO_CALL_STACK(subchannel_call); -} - -static void grpc_uri_to_sockaddr(const char* uri_str, - grpc_resolved_address* addr) { - grpc_uri* uri = grpc_uri_parse(uri_str, 0 /* suppress_errors */); - GPR_ASSERT(uri != nullptr); - if (!grpc_parse_uri(uri, addr)) memset(addr, 0, sizeof(*addr)); - grpc_uri_destroy(uri); -} - -void grpc_get_subchannel_address_arg(const grpc_channel_args* args, - grpc_resolved_address* addr) { - const char* addr_uri_str = grpc_get_subchannel_address_uri_arg(args); - memset(addr, 0, sizeof(*addr)); - if (*addr_uri_str != '\0') { - grpc_uri_to_sockaddr(addr_uri_str, addr); - } -} - -const char* grpc_subchannel_get_target(grpc_subchannel* subchannel) { +const char* Subchannel::GetTargetAddress() { const grpc_arg* addr_arg = - grpc_channel_args_find(subchannel->args, GRPC_ARG_SUBCHANNEL_ADDRESS); + grpc_channel_args_find(args_, GRPC_ARG_SUBCHANNEL_ADDRESS); const char* addr_str = grpc_channel_arg_get_string(addr_arg); GPR_ASSERT(addr_str != nullptr); // Should have been set by LB policy. return addr_str; } -const char* grpc_get_subchannel_address_uri_arg(const grpc_channel_args* args) { +channelz::SubchannelNode* Subchannel::channelz_node() { + return channelz_node_.get(); +} + +grpc_connectivity_state Subchannel::CheckConnectivityState( + const char* health_check_service_name, + RefCountedPtr* connected_subchannel) { + MutexLock lock(&mu_); + grpc_connectivity_state state; + if (health_check_service_name == nullptr) { + state = state_; + } else { + state = health_watcher_map_.CheckConnectivityStateLocked( + this, health_check_service_name); + } + if (connected_subchannel != nullptr && state == GRPC_CHANNEL_READY) { + *connected_subchannel = connected_subchannel_; + } + return state; +} + +void Subchannel::WatchConnectivityState( + grpc_connectivity_state initial_state, + UniquePtr health_check_service_name, + UniquePtr watcher) { + MutexLock lock(&mu_); + grpc_pollset_set* interested_parties = watcher->interested_parties(); + if (interested_parties != nullptr) { + grpc_pollset_set_add_pollset_set(pollset_set_, interested_parties); + } + if (health_check_service_name == nullptr) { + if (state_ != initial_state) { + watcher->OnConnectivityStateChange(state_, connected_subchannel_); + } + watcher_list_.AddWatcherLocked(std::move(watcher)); + } else { + health_watcher_map_.AddWatcherLocked(this, initial_state, + std::move(health_check_service_name), + std::move(watcher)); + } +} + +void Subchannel::CancelConnectivityStateWatch( + const char* health_check_service_name, ConnectivityStateWatcher* watcher) { + MutexLock lock(&mu_); + grpc_pollset_set* interested_parties = watcher->interested_parties(); + if (interested_parties != nullptr) { + grpc_pollset_set_del_pollset_set(pollset_set_, interested_parties); + } + if (health_check_service_name == nullptr) { + watcher_list_.RemoveWatcherLocked(watcher); + } else { + health_watcher_map_.RemoveWatcherLocked(health_check_service_name, watcher); + } +} + +void Subchannel::AttemptToConnect() { + MutexLock lock(&mu_); + MaybeStartConnectingLocked(); +} + +void Subchannel::ResetBackoff() { + MutexLock lock(&mu_); + backoff_.Reset(); + if (have_retry_alarm_) { + retry_immediately_ = true; + grpc_timer_cancel(&retry_alarm_); + } else { + backoff_begun_ = false; + MaybeStartConnectingLocked(); + } +} + +grpc_arg Subchannel::CreateSubchannelAddressArg( + const grpc_resolved_address* addr) { + return grpc_channel_arg_string_create( + (char*)GRPC_ARG_SUBCHANNEL_ADDRESS, + addr->len > 0 ? grpc_sockaddr_to_uri(addr) : gpr_strdup("")); +} + +const char* Subchannel::GetUriFromSubchannelAddressArg( + const grpc_channel_args* args) { const grpc_arg* addr_arg = grpc_channel_args_find(args, GRPC_ARG_SUBCHANNEL_ADDRESS); const char* addr_str = grpc_channel_arg_get_string(addr_arg); @@ -1059,96 +896,239 @@ const char* grpc_get_subchannel_address_uri_arg(const grpc_channel_args* args) { return addr_str; } -grpc_arg grpc_create_subchannel_address_arg(const grpc_resolved_address* addr) { - return grpc_channel_arg_string_create( - (char*)GRPC_ARG_SUBCHANNEL_ADDRESS, - addr->len > 0 ? grpc_sockaddr_to_uri(addr) : gpr_strdup("")); +namespace { + +void UriToSockaddr(const char* uri_str, grpc_resolved_address* addr) { + grpc_uri* uri = grpc_uri_parse(uri_str, 0 /* suppress_errors */); + GPR_ASSERT(uri != nullptr); + if (!grpc_parse_uri(uri, addr)) memset(addr, 0, sizeof(*addr)); + grpc_uri_destroy(uri); } -namespace grpc_core { +} // namespace -ConnectedSubchannel::ConnectedSubchannel( - grpc_channel_stack* channel_stack, - grpc_core::RefCountedPtr - channelz_subchannel, - intptr_t socket_uuid) - : RefCountedWithTracing(&grpc_trace_stream_refcount), - channel_stack_(channel_stack), - channelz_subchannel_(std::move(channelz_subchannel)), - socket_uuid_(socket_uuid) {} - -ConnectedSubchannel::~ConnectedSubchannel() { - GRPC_CHANNEL_STACK_UNREF(channel_stack_, "connected_subchannel_dtor"); -} - -void ConnectedSubchannel::NotifyOnStateChange( - grpc_pollset_set* interested_parties, grpc_connectivity_state* state, - grpc_closure* closure) { - grpc_transport_op* op = grpc_make_transport_op(nullptr); - grpc_channel_element* elem; - op->connectivity_state = state; - op->on_connectivity_state_change = closure; - op->bind_pollset_set = interested_parties; - elem = grpc_channel_stack_element(channel_stack_, 0); - elem->filter->start_transport_op(elem, op); -} - -void ConnectedSubchannel::Ping(grpc_closure* on_initiate, - grpc_closure* on_ack) { - grpc_transport_op* op = grpc_make_transport_op(nullptr); - grpc_channel_element* elem; - op->send_ping.on_initiate = on_initiate; - op->send_ping.on_ack = on_ack; - elem = grpc_channel_stack_element(channel_stack_, 0); - elem->filter->start_transport_op(elem, op); -} - -grpc_error* ConnectedSubchannel::CreateCall(const CallArgs& args, - grpc_subchannel_call** call) { - const size_t allocation_size = - GetInitialCallSizeEstimate(args.parent_data_size); - *call = new (gpr_arena_alloc(args.arena, allocation_size)) - grpc_subchannel_call(this, args); - grpc_call_stack* callstk = SUBCHANNEL_CALL_TO_CALL_STACK(*call); - RefCountedPtr connection = - Ref(DEBUG_LOCATION, "subchannel_call"); - connection.release(); // Ref is passed to the grpc_subchannel_call object. - const grpc_call_element_args call_args = { - callstk, /* call_stack */ - nullptr, /* server_transport_data */ - args.context, /* context */ - args.path, /* path */ - args.start_time, /* start_time */ - args.deadline, /* deadline */ - args.arena, /* arena */ - args.call_combiner /* call_combiner */ - }; - grpc_error* error = grpc_call_stack_init( - channel_stack_, 1, subchannel_call_destroy, *call, &call_args); - if (GPR_UNLIKELY(error != GRPC_ERROR_NONE)) { - const char* error_string = grpc_error_string(error); - gpr_log(GPR_ERROR, "error: %s", error_string); - return error; +void Subchannel::GetAddressFromSubchannelAddressArg( + const grpc_channel_args* args, grpc_resolved_address* addr) { + const char* addr_uri_str = GetUriFromSubchannelAddressArg(args); + memset(addr, 0, sizeof(*addr)); + if (*addr_uri_str != '\0') { + UriToSockaddr(addr_uri_str, addr); } - grpc_call_stack_set_pollset_or_pollset_set(callstk, args.pollent); - if (channelz_subchannel_ != nullptr) { - channelz_subchannel_->RecordCallStarted(); - } - return GRPC_ERROR_NONE; } -size_t ConnectedSubchannel::GetInitialCallSizeEstimate( - size_t parent_data_size) const { - size_t allocation_size = - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_subchannel_call)); - if (parent_data_size > 0) { - allocation_size += - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(channel_stack_->call_stack_size) + - parent_data_size; +namespace { + +// Returns a string indicating the subchannel's connectivity state change to +// \a state. +const char* SubchannelConnectivityStateChangeString( + grpc_connectivity_state state) { + switch (state) { + case GRPC_CHANNEL_IDLE: + return "Subchannel state change to IDLE"; + case GRPC_CHANNEL_CONNECTING: + return "Subchannel state change to CONNECTING"; + case GRPC_CHANNEL_READY: + return "Subchannel state change to READY"; + case GRPC_CHANNEL_TRANSIENT_FAILURE: + return "Subchannel state change to TRANSIENT_FAILURE"; + case GRPC_CHANNEL_SHUTDOWN: + return "Subchannel state change to SHUTDOWN"; + } + GPR_UNREACHABLE_CODE(return "UNKNOWN"); +} + +} // namespace + +// Note: Must be called with a state that is different from the current state. +void Subchannel::SetConnectivityStateLocked(grpc_connectivity_state state) { + state_ = state; + if (channelz_node_ != nullptr) { + channelz_node_->AddTraceEvent( + channelz::ChannelTrace::Severity::Info, + grpc_slice_from_static_string( + SubchannelConnectivityStateChangeString(state))); + } + // Notify non-health watchers. + watcher_list_.NotifyLocked(this, state); + // Notify health watchers. + health_watcher_map_.NotifyLocked(state); +} + +void Subchannel::MaybeStartConnectingLocked() { + if (disconnected_) { + // Don't try to connect if we're already disconnected. + return; + } + if (connecting_) { + // Already connecting: don't restart. + return; + } + if (connected_subchannel_ != nullptr) { + // Already connected: don't restart. + return; + } + connecting_ = true; + GRPC_SUBCHANNEL_WEAK_REF(this, "connecting"); + if (!backoff_begun_) { + backoff_begun_ = true; + ContinueConnectingLocked(); } else { - allocation_size += channel_stack_->call_stack_size; + GPR_ASSERT(!have_retry_alarm_); + have_retry_alarm_ = true; + const grpc_millis time_til_next = + next_attempt_deadline_ - ExecCtx::Get()->Now(); + if (time_til_next <= 0) { + gpr_log(GPR_INFO, "Subchannel %p: Retry immediately", this); + } else { + gpr_log(GPR_INFO, "Subchannel %p: Retry in %" PRId64 " milliseconds", + this, time_til_next); + } + GRPC_CLOSURE_INIT(&on_retry_alarm_, OnRetryAlarm, this, + grpc_schedule_on_exec_ctx); + grpc_timer_init(&retry_alarm_, next_attempt_deadline_, &on_retry_alarm_); } - return allocation_size; +} + +void Subchannel::OnRetryAlarm(void* arg, grpc_error* error) { + Subchannel* c = static_cast(arg); + // TODO(soheilhy): Once subchannel refcounting is simplified, we can get use + // MutexLock instead of ReleasableMutexLock, here. + ReleasableMutexLock lock(&c->mu_); + c->have_retry_alarm_ = false; + if (c->disconnected_) { + error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING("Disconnected", + &error, 1); + } else if (c->retry_immediately_) { + c->retry_immediately_ = false; + error = GRPC_ERROR_NONE; + } else { + GRPC_ERROR_REF(error); + } + if (error == GRPC_ERROR_NONE) { + gpr_log(GPR_INFO, "Failed to connect to channel, retrying"); + c->ContinueConnectingLocked(); + lock.Unlock(); + } else { + lock.Unlock(); + GRPC_SUBCHANNEL_WEAK_UNREF(c, "connecting"); + } + GRPC_ERROR_UNREF(error); +} + +void Subchannel::ContinueConnectingLocked() { + grpc_connect_in_args args; + args.interested_parties = pollset_set_; + const grpc_millis min_deadline = + min_connect_timeout_ms_ + ExecCtx::Get()->Now(); + next_attempt_deadline_ = backoff_.NextAttemptTime(); + args.deadline = std::max(next_attempt_deadline_, min_deadline); + args.channel_args = args_; + SetConnectivityStateLocked(GRPC_CHANNEL_CONNECTING); + grpc_connector_connect(connector_, &args, &connecting_result_, + &on_connecting_finished_); +} + +void Subchannel::OnConnectingFinished(void* arg, grpc_error* error) { + auto* c = static_cast(arg); + grpc_channel_args* delete_channel_args = c->connecting_result_.channel_args; + GRPC_SUBCHANNEL_WEAK_REF(c, "on_connecting_finished"); + { + MutexLock lock(&c->mu_); + c->connecting_ = false; + if (c->connecting_result_.transport != nullptr && + c->PublishTransportLocked()) { + // Do nothing, transport was published. + } else if (c->disconnected_) { + GRPC_SUBCHANNEL_WEAK_UNREF(c, "connecting"); + } else { + gpr_log(GPR_INFO, "Connect failed: %s", grpc_error_string(error)); + c->SetConnectivityStateLocked(GRPC_CHANNEL_TRANSIENT_FAILURE); + GRPC_SUBCHANNEL_WEAK_UNREF(c, "connecting"); + } + } + GRPC_SUBCHANNEL_WEAK_UNREF(c, "on_connecting_finished"); + grpc_channel_args_destroy(delete_channel_args); +} + +namespace { + +void ConnectionDestroy(void* arg, grpc_error* error) { + grpc_channel_stack* stk = static_cast(arg); + grpc_channel_stack_destroy(stk); + gpr_free(stk); +} + +} // namespace + +bool Subchannel::PublishTransportLocked() { + // Construct channel stack. + grpc_channel_stack_builder* builder = grpc_channel_stack_builder_create(); + grpc_channel_stack_builder_set_channel_arguments( + builder, connecting_result_.channel_args); + grpc_channel_stack_builder_set_transport(builder, + connecting_result_.transport); + if (!grpc_channel_init_create_stack(builder, GRPC_CLIENT_SUBCHANNEL)) { + grpc_channel_stack_builder_destroy(builder); + return false; + } + grpc_channel_stack* stk; + grpc_error* error = grpc_channel_stack_builder_finish( + builder, 0, 1, ConnectionDestroy, nullptr, + reinterpret_cast(&stk)); + if (error != GRPC_ERROR_NONE) { + grpc_transport_destroy(connecting_result_.transport); + gpr_log(GPR_ERROR, "error initializing subchannel stack: %s", + grpc_error_string(error)); + GRPC_ERROR_UNREF(error); + return false; + } + intptr_t socket_uuid = connecting_result_.socket_uuid; + memset(&connecting_result_, 0, sizeof(connecting_result_)); + if (disconnected_) { + grpc_channel_stack_destroy(stk); + gpr_free(stk); + return false; + } + // Publish. + connected_subchannel_.reset( + New(stk, args_, channelz_node_, socket_uuid)); + gpr_log(GPR_INFO, "New connected subchannel at %p for subchannel %p", + connected_subchannel_.get(), this); + // Instantiate state watcher. Will clean itself up. + New(this); + // Report initial state. + SetConnectivityStateLocked(GRPC_CHANNEL_READY); + return true; +} + +void Subchannel::Disconnect() { + // The subchannel_pool is only used once here in this subchannel, so the + // access can be outside of the lock. + if (subchannel_pool_ != nullptr) { + subchannel_pool_->UnregisterSubchannel(key_); + subchannel_pool_.reset(); + } + MutexLock lock(&mu_); + GPR_ASSERT(!disconnected_); + disconnected_ = true; + grpc_connector_shutdown(connector_, GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Subchannel disconnected")); + connected_subchannel_.reset(); + health_watcher_map_.ShutdownLocked(); +} + +gpr_atm Subchannel::RefMutate( + gpr_atm delta, int barrier GRPC_SUBCHANNEL_REF_MUTATE_EXTRA_ARGS) { + gpr_atm old_val = barrier ? gpr_atm_full_fetch_add(&ref_pair_, delta) + : gpr_atm_no_barrier_fetch_add(&ref_pair_, delta); +#ifndef NDEBUG + if (grpc_trace_stream_refcount.enabled()) { + gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, + "SUBCHANNEL: %p %12s 0x%" PRIxPTR " -> 0x%" PRIxPTR " [%s]", this, + purpose, old_val, old_val + delta, reason); + } +#endif + return old_val; } } // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/subchannel.h b/src/core/ext/filters/client_channel/subchannel.h index ec3b4d86e41..e0741bb28fa 100644 --- a/src/core/ext/filters/client_channel/subchannel.h +++ b/src/core/ext/filters/client_channel/subchannel.h @@ -23,193 +23,387 @@ #include "src/core/ext/filters/client_channel/client_channel_channelz.h" #include "src/core/ext/filters/client_channel/connector.h" +#include "src/core/ext/filters/client_channel/subchannel_pool_interface.h" +#include "src/core/lib/backoff/backoff.h" #include "src/core/lib/channel/channel_stack.h" -#include "src/core/lib/gpr/arena.h" +#include "src/core/lib/gprpp/arena.h" +#include "src/core/lib/gprpp/map.h" #include "src/core/lib/gprpp/ref_counted.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" +#include "src/core/lib/gprpp/sync.h" #include "src/core/lib/iomgr/polling_entity.h" +#include "src/core/lib/iomgr/timer.h" #include "src/core/lib/transport/connectivity_state.h" #include "src/core/lib/transport/metadata.h" // Channel arg containing a grpc_resolved_address to connect to. #define GRPC_ARG_SUBCHANNEL_ADDRESS "grpc.subchannel_address" -/** A (sub-)channel that knows how to connect to exactly one target - address. Provides a target for load balancing. */ -typedef struct grpc_subchannel grpc_subchannel; -typedef struct grpc_subchannel_call grpc_subchannel_call; -typedef struct grpc_subchannel_args grpc_subchannel_args; -typedef struct grpc_subchannel_key grpc_subchannel_key; - +// For debugging refcounting. #ifndef NDEBUG -#define GRPC_SUBCHANNEL_REF(p, r) \ - grpc_subchannel_ref((p), __FILE__, __LINE__, (r)) +#define GRPC_SUBCHANNEL_REF(p, r) (p)->Ref(__FILE__, __LINE__, (r)) #define GRPC_SUBCHANNEL_REF_FROM_WEAK_REF(p, r) \ - grpc_subchannel_ref_from_weak_ref((p), __FILE__, __LINE__, (r)) -#define GRPC_SUBCHANNEL_UNREF(p, r) \ - grpc_subchannel_unref((p), __FILE__, __LINE__, (r)) -#define GRPC_SUBCHANNEL_WEAK_REF(p, r) \ - grpc_subchannel_weak_ref((p), __FILE__, __LINE__, (r)) -#define GRPC_SUBCHANNEL_WEAK_UNREF(p, r) \ - grpc_subchannel_weak_unref((p), __FILE__, __LINE__, (r)) -#define GRPC_SUBCHANNEL_CALL_REF(p, r) \ - grpc_subchannel_call_ref((p), __FILE__, __LINE__, (r)) -#define GRPC_SUBCHANNEL_CALL_UNREF(p, r) \ - grpc_subchannel_call_unref((p), __FILE__, __LINE__, (r)) + (p)->RefFromWeakRef(__FILE__, __LINE__, (r)) +#define GRPC_SUBCHANNEL_UNREF(p, r) (p)->Unref(__FILE__, __LINE__, (r)) +#define GRPC_SUBCHANNEL_WEAK_REF(p, r) (p)->WeakRef(__FILE__, __LINE__, (r)) +#define GRPC_SUBCHANNEL_WEAK_UNREF(p, r) (p)->WeakUnref(__FILE__, __LINE__, (r)) #define GRPC_SUBCHANNEL_REF_EXTRA_ARGS \ - , const char *file, int line, const char *reason + const char *file, int line, const char *reason +#define GRPC_SUBCHANNEL_REF_REASON reason +#define GRPC_SUBCHANNEL_REF_MUTATE_EXTRA_ARGS \ + , GRPC_SUBCHANNEL_REF_EXTRA_ARGS, const char* purpose +#define GRPC_SUBCHANNEL_REF_MUTATE_PURPOSE(x) , file, line, reason, x #else -#define GRPC_SUBCHANNEL_REF(p, r) grpc_subchannel_ref((p)) -#define GRPC_SUBCHANNEL_REF_FROM_WEAK_REF(p, r) \ - grpc_subchannel_ref_from_weak_ref((p)) -#define GRPC_SUBCHANNEL_UNREF(p, r) grpc_subchannel_unref((p)) -#define GRPC_SUBCHANNEL_WEAK_REF(p, r) grpc_subchannel_weak_ref((p)) -#define GRPC_SUBCHANNEL_WEAK_UNREF(p, r) grpc_subchannel_weak_unref((p)) -#define GRPC_SUBCHANNEL_CALL_REF(p, r) grpc_subchannel_call_ref((p)) -#define GRPC_SUBCHANNEL_CALL_UNREF(p, r) grpc_subchannel_call_unref((p)) +#define GRPC_SUBCHANNEL_REF(p, r) (p)->Ref() +#define GRPC_SUBCHANNEL_REF_FROM_WEAK_REF(p, r) (p)->RefFromWeakRef() +#define GRPC_SUBCHANNEL_UNREF(p, r) (p)->Unref() +#define GRPC_SUBCHANNEL_WEAK_REF(p, r) (p)->WeakRef() +#define GRPC_SUBCHANNEL_WEAK_UNREF(p, r) (p)->WeakUnref() #define GRPC_SUBCHANNEL_REF_EXTRA_ARGS +#define GRPC_SUBCHANNEL_REF_REASON "" +#define GRPC_SUBCHANNEL_REF_MUTATE_EXTRA_ARGS +#define GRPC_SUBCHANNEL_REF_MUTATE_PURPOSE(x) #endif namespace grpc_core { -class ConnectedSubchannel : public RefCountedWithTracing { +class SubchannelCall; + +class ConnectedSubchannel : public RefCounted { public: struct CallArgs { grpc_polling_entity* pollent; grpc_slice path; gpr_timespec start_time; grpc_millis deadline; - gpr_arena* arena; + Arena* arena; grpc_call_context_element* context; - grpc_call_combiner* call_combiner; + CallCombiner* call_combiner; size_t parent_data_size; }; - explicit ConnectedSubchannel( - grpc_channel_stack* channel_stack, - grpc_core::RefCountedPtr - channelz_subchannel, + ConnectedSubchannel( + grpc_channel_stack* channel_stack, const grpc_channel_args* args, + RefCountedPtr channelz_subchannel, intptr_t socket_uuid); ~ConnectedSubchannel(); - grpc_channel_stack* channel_stack() { return channel_stack_; } void NotifyOnStateChange(grpc_pollset_set* interested_parties, grpc_connectivity_state* state, grpc_closure* closure); void Ping(grpc_closure* on_initiate, grpc_closure* on_ack); - grpc_error* CreateCall(const CallArgs& args, grpc_subchannel_call** call); - channelz::SubchannelNode* channelz_subchannel() { + RefCountedPtr CreateCall(const CallArgs& args, + grpc_error** error); + + grpc_channel_stack* channel_stack() const { return channel_stack_; } + const grpc_channel_args* args() const { return args_; } + channelz::SubchannelNode* channelz_subchannel() const { return channelz_subchannel_.get(); } - intptr_t socket_uuid() { return socket_uuid_; } + intptr_t socket_uuid() const { return socket_uuid_; } size_t GetInitialCallSizeEstimate(size_t parent_data_size) const; private: grpc_channel_stack* channel_stack_; + grpc_channel_args* args_; // ref counted pointer to the channelz node in this connected subchannel's // owning subchannel. - grpc_core::RefCountedPtr - channelz_subchannel_; + RefCountedPtr channelz_subchannel_; // uuid of this subchannel's socket. 0 if this subchannel is not connected. const intptr_t socket_uuid_; }; -} // namespace grpc_core +// Implements the interface of RefCounted<>. +class SubchannelCall { + public: + SubchannelCall(RefCountedPtr connected_subchannel, + const ConnectedSubchannel::CallArgs& args) + : connected_subchannel_(std::move(connected_subchannel)), + deadline_(args.deadline) {} -grpc_subchannel* grpc_subchannel_ref( - grpc_subchannel* channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS); -grpc_subchannel* grpc_subchannel_ref_from_weak_ref( - grpc_subchannel* channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS); -void grpc_subchannel_unref( - grpc_subchannel* channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS); -grpc_subchannel* grpc_subchannel_weak_ref( - grpc_subchannel* channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS); -void grpc_subchannel_weak_unref( - grpc_subchannel* channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS); -grpc_subchannel_call* grpc_subchannel_call_ref( - grpc_subchannel_call* call GRPC_SUBCHANNEL_REF_EXTRA_ARGS); -void grpc_subchannel_call_unref( - grpc_subchannel_call* call GRPC_SUBCHANNEL_REF_EXTRA_ARGS); + // Continues processing a transport stream op batch. + void StartTransportStreamOpBatch(grpc_transport_stream_op_batch* batch); -grpc_core::channelz::SubchannelNode* grpc_subchannel_get_channelz_node( - grpc_subchannel* subchannel); + // Returns a pointer to the parent data associated with the subchannel call. + // The data will be of the size specified in \a parent_data_size field of + // the args passed to \a ConnectedSubchannel::CreateCall(). + void* GetParentData(); -intptr_t grpc_subchannel_get_child_socket_uuid(grpc_subchannel* subchannel); + // Returns the call stack of the subchannel call. + grpc_call_stack* GetCallStack(); -/** Returns a pointer to the parent data associated with \a subchannel_call. - The data will be of the size specified in \a parent_data_size - field of the args passed to \a grpc_connected_subchannel_create_call(). */ -void* grpc_connected_subchannel_call_get_parent_data( - grpc_subchannel_call* subchannel_call); + // Sets the 'then_schedule_closure' argument for call stack destruction. + // Must be called once per call. + void SetAfterCallStackDestroy(grpc_closure* closure); -/** poll the current connectivity state of a channel */ -grpc_connectivity_state grpc_subchannel_check_connectivity( - grpc_subchannel* channel, grpc_error** error, bool inhibit_health_checking); + // Interface of RefCounted<>. + RefCountedPtr Ref() GRPC_MUST_USE_RESULT; + RefCountedPtr Ref(const DebugLocation& location, + const char* reason) GRPC_MUST_USE_RESULT; + // When refcount drops to 0, destroys itself and the associated call stack, + // but does NOT free the memory because it's in the call arena. + void Unref(); + void Unref(const DebugLocation& location, const char* reason); -/** Calls notify when the connectivity state of a channel becomes different - from *state. Updates *state with the new state of the channel. */ -void grpc_subchannel_notify_on_state_change( - grpc_subchannel* channel, grpc_pollset_set* interested_parties, - grpc_connectivity_state* state, grpc_closure* notify, - bool inhibit_health_checks); + static void Destroy(void* arg, grpc_error* error); -/** retrieve the grpc_core::ConnectedSubchannel - or nullptr if not connected - * (which may happen before it initially connects or during transient failures) - * */ -grpc_core::RefCountedPtr -grpc_subchannel_get_connected_subchannel(grpc_subchannel* c); + private: + // Allow RefCountedPtr<> to access IncrementRefCount(). + template + friend class RefCountedPtr; -/** return the subchannel index key for \a subchannel */ -const grpc_subchannel_key* grpc_subchannel_get_key( - const grpc_subchannel* subchannel); + // If channelz is enabled, intercepts recv_trailing so that we may check the + // status and associate it to a subchannel. + void MaybeInterceptRecvTrailingMetadata( + grpc_transport_stream_op_batch* batch); -// Resets the connection backoff of the subchannel. -// TODO(roth): Move connection backoff out of subchannels and up into LB -// policy code (probably by adding a SubchannelGroup between -// SubchannelList and SubchannelData), at which point this method can -// go away. -void grpc_subchannel_reset_backoff(grpc_subchannel* subchannel); + static void RecvTrailingMetadataReady(void* arg, grpc_error* error); -/** continue processing a transport op */ -void grpc_subchannel_call_process_op(grpc_subchannel_call* subchannel_call, - grpc_transport_stream_op_batch* op); + // Interface of RefCounted<>. + void IncrementRefCount(); + void IncrementRefCount(const DebugLocation& location, const char* reason); -/** Must be called once per call. Sets the 'then_schedule_closure' argument for - call stack destruction. */ -void grpc_subchannel_call_set_cleanup_closure( - grpc_subchannel_call* subchannel_call, grpc_closure* closure); - -grpc_call_stack* grpc_subchannel_call_get_call_stack( - grpc_subchannel_call* subchannel_call); - -struct grpc_subchannel_args { - /* When updating this struct, also update subchannel_index.c */ - - /** Channel filters for this channel - wrapped factories will likely - want to mutate this */ - const grpc_channel_filter** filters; - /** The number of filters in the above array */ - size_t filter_count; - /** Channel arguments to be supplied to the newly created channel */ - const grpc_channel_args* args; + RefCountedPtr connected_subchannel_; + grpc_closure* after_call_stack_destroy_ = nullptr; + // State needed to support channelz interception of recv trailing metadata. + grpc_closure recv_trailing_metadata_ready_; + grpc_closure* original_recv_trailing_metadata_ = nullptr; + grpc_metadata_batch* recv_trailing_metadata_ = nullptr; + grpc_millis deadline_; }; -/** create a subchannel given a connector */ -grpc_subchannel* grpc_subchannel_create(grpc_connector* connector, - const grpc_subchannel_args* args); +// A subchannel that knows how to connect to exactly one target address. It +// provides a target for load balancing. +class Subchannel { + private: + class ConnectivityStateWatcherList; // Forward declaration. -/// Sets \a addr from \a args. -void grpc_get_subchannel_address_arg(const grpc_channel_args* args, - grpc_resolved_address* addr); + public: + class ConnectivityStateWatcher { + public: + virtual ~ConnectivityStateWatcher() = default; -const char* grpc_subchannel_get_target(grpc_subchannel* subchannel); + // Will be invoked whenever the subchannel's connectivity state + // changes. There will be only one invocation of this method on a + // given watcher instance at any given time. + // + // When the state changes to READY, connected_subchannel will + // contain a ref to the connected subchannel. When it changes from + // READY to some other state, the implementation must release its + // ref to the connected subchannel. + virtual void OnConnectivityStateChange( + grpc_connectivity_state new_state, + RefCountedPtr connected_subchannel) // NOLINT + GRPC_ABSTRACT; -/// Returns the URI string for the address to connect to. -const char* grpc_get_subchannel_address_uri_arg(const grpc_channel_args* args); + virtual grpc_pollset_set* interested_parties() GRPC_ABSTRACT; -/// Returns a new channel arg encoding the subchannel address as a string. -/// Caller is responsible for freeing the string. -grpc_arg grpc_create_subchannel_address_arg(const grpc_resolved_address* addr); + GRPC_ABSTRACT_BASE_CLASS + + private: + // For access to next_. + friend class Subchannel::ConnectivityStateWatcherList; + + ConnectivityStateWatcher* next_ = nullptr; + }; + + // The ctor and dtor are not intended to use directly. + Subchannel(SubchannelKey* key, grpc_connector* connector, + const grpc_channel_args* args); + ~Subchannel(); + + // Creates a subchannel given \a connector and \a args. + static Subchannel* Create(grpc_connector* connector, + const grpc_channel_args* args); + + // Strong and weak refcounting. + Subchannel* Ref(GRPC_SUBCHANNEL_REF_EXTRA_ARGS); + void Unref(GRPC_SUBCHANNEL_REF_EXTRA_ARGS); + Subchannel* WeakRef(GRPC_SUBCHANNEL_REF_EXTRA_ARGS); + void WeakUnref(GRPC_SUBCHANNEL_REF_EXTRA_ARGS); + // Attempts to return a strong ref when only the weak refcount is guaranteed + // non-zero. If the strong refcount is zero, does not alter the refcount and + // returns null. + Subchannel* RefFromWeakRef(GRPC_SUBCHANNEL_REF_EXTRA_ARGS); + + intptr_t GetChildSocketUuid(); + + // Gets the string representing the subchannel address. + // Caller doesn't take ownership. + const char* GetTargetAddress(); + + channelz::SubchannelNode* channelz_node(); + + // Returns the current connectivity state of the subchannel. + // If health_check_service_name is non-null, the returned connectivity + // state will be based on the state reported by the backend for that + // service name. + // If the return value is GRPC_CHANNEL_READY, also sets *connected_subchannel. + grpc_connectivity_state CheckConnectivityState( + const char* health_check_service_name, + RefCountedPtr* connected_subchannel); + + // Starts watching the subchannel's connectivity state. + // The first callback to the watcher will be delivered when the + // subchannel's connectivity state becomes a value other than + // initial_state, which may happen immediately. + // Subsequent callbacks will be delivered as the subchannel's state + // changes. + // The watcher will be destroyed either when the subchannel is + // destroyed or when CancelConnectivityStateWatch() is called. + void WatchConnectivityState(grpc_connectivity_state initial_state, + UniquePtr health_check_service_name, + UniquePtr watcher); + + // Cancels a connectivity state watch. + // If the watcher has already been destroyed, this is a no-op. + void CancelConnectivityStateWatch(const char* health_check_service_name, + ConnectivityStateWatcher* watcher); + + // Attempt to connect to the backend. Has no effect if already connected. + void AttemptToConnect(); + + // Resets the connection backoff of the subchannel. + // TODO(roth): Move connection backoff out of subchannels and up into LB + // policy code (probably by adding a SubchannelGroup between + // SubchannelList and SubchannelData), at which point this method can + // go away. + void ResetBackoff(); + + // Returns a new channel arg encoding the subchannel address as a URI + // string. Caller is responsible for freeing the string. + static grpc_arg CreateSubchannelAddressArg(const grpc_resolved_address* addr); + + // Returns the URI string from the subchannel address arg in \a args. + static const char* GetUriFromSubchannelAddressArg( + const grpc_channel_args* args); + + // Sets \a addr from the subchannel address arg in \a args. + static void GetAddressFromSubchannelAddressArg(const grpc_channel_args* args, + grpc_resolved_address* addr); + + private: + // A linked list of ConnectivityStateWatchers that are monitoring the + // subchannel's state. + class ConnectivityStateWatcherList { + public: + ~ConnectivityStateWatcherList() { Clear(); } + + void AddWatcherLocked(UniquePtr watcher); + void RemoveWatcherLocked(ConnectivityStateWatcher* watcher); + + // Notifies all watchers in the list about a change to state. + void NotifyLocked(Subchannel* subchannel, grpc_connectivity_state state); + + void Clear(); + + bool empty() const { return head_ == nullptr; } + + private: + ConnectivityStateWatcher* head_ = nullptr; + }; + + // A map that tracks ConnectivityStateWatchers using a particular health + // check service name. + // + // There is one entry in the map for each health check service name. + // Entries exist only as long as there are watchers using the + // corresponding service name. + // + // A health check client is maintained only while the subchannel is in + // state READY. + class HealthWatcherMap { + public: + void AddWatcherLocked(Subchannel* subchannel, + grpc_connectivity_state initial_state, + UniquePtr health_check_service_name, + UniquePtr watcher); + void RemoveWatcherLocked(const char* health_check_service_name, + ConnectivityStateWatcher* watcher); + + // Notifies the watcher when the subchannel's state changes. + void NotifyLocked(grpc_connectivity_state state); + + grpc_connectivity_state CheckConnectivityStateLocked( + Subchannel* subchannel, const char* health_check_service_name); + + void ShutdownLocked(); + + private: + class HealthWatcher; + + Map, StringLess> map_; + }; + + class ConnectedSubchannelStateWatcher; + + // Sets the subchannel's connectivity state to \a state. + void SetConnectivityStateLocked(grpc_connectivity_state state); + + // Methods for connection. + void MaybeStartConnectingLocked(); + static void OnRetryAlarm(void* arg, grpc_error* error); + void ContinueConnectingLocked(); + static void OnConnectingFinished(void* arg, grpc_error* error); + bool PublishTransportLocked(); + void Disconnect(); + + gpr_atm RefMutate(gpr_atm delta, + int barrier GRPC_SUBCHANNEL_REF_MUTATE_EXTRA_ARGS); + + // The subchannel pool this subchannel is in. + RefCountedPtr subchannel_pool_; + // TODO(juanlishen): Consider using args_ as key_ directly. + // Subchannel key that identifies this subchannel in the subchannel pool. + SubchannelKey* key_; + // Channel args. + grpc_channel_args* args_; + // pollset_set tracking who's interested in a connection being setup. + grpc_pollset_set* pollset_set_; + // Protects the other members. + Mutex mu_; + // Refcount + // - lower INTERNAL_REF_BITS bits are for internal references: + // these do not keep the subchannel open. + // - upper remaining bits are for public references: these do + // keep the subchannel open + gpr_atm ref_pair_; + + // Connection states. + grpc_connector* connector_ = nullptr; + // Set during connection. + grpc_connect_out_args connecting_result_; + grpc_closure on_connecting_finished_; + // Active connection, or null. + RefCountedPtr connected_subchannel_; + bool connecting_ = false; + bool disconnected_ = false; + + // Connectivity state tracking. + grpc_connectivity_state state_ = GRPC_CHANNEL_IDLE; + // The list of watchers without a health check service name. + ConnectivityStateWatcherList watcher_list_; + // The map of watchers with health check service names. + HealthWatcherMap health_watcher_map_; + + // Backoff state. + BackOff backoff_; + grpc_millis next_attempt_deadline_; + grpc_millis min_connect_timeout_ms_; + bool backoff_begun_ = false; + + // Retry alarm. + grpc_timer retry_alarm_; + grpc_closure on_retry_alarm_; + bool have_retry_alarm_ = false; + // reset_backoff() was called while alarm was pending. + bool retry_immediately_ = false; + + // Channelz tracking. + RefCountedPtr channelz_node_; +}; + +} // namespace grpc_core #endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SUBCHANNEL_H */ diff --git a/src/core/ext/filters/client_channel/subchannel_index.cc b/src/core/ext/filters/client_channel/subchannel_index.cc deleted file mode 100644 index 1c23a6c4be4..00000000000 --- a/src/core/ext/filters/client_channel/subchannel_index.cc +++ /dev/null @@ -1,255 +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. -// -// - -#include - -#include "src/core/ext/filters/client_channel/subchannel_index.h" - -#include -#include - -#include -#include - -#include "src/core/lib/avl/avl.h" -#include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/tls.h" - -// a map of subchannel_key --> subchannel, used for detecting connections -// to the same destination in order to share them -static grpc_avl g_subchannel_index; - -static gpr_mu g_mu; - -static gpr_refcount g_refcount; - -struct grpc_subchannel_key { - grpc_subchannel_args args; -}; - -static bool g_force_creation = false; - -static grpc_subchannel_key* create_key( - const grpc_subchannel_args* args, - grpc_channel_args* (*copy_channel_args)(const grpc_channel_args* args)) { - grpc_subchannel_key* k = - static_cast(gpr_malloc(sizeof(*k))); - k->args.filter_count = args->filter_count; - if (k->args.filter_count > 0) { - k->args.filters = static_cast( - gpr_malloc(sizeof(*k->args.filters) * k->args.filter_count)); - memcpy(reinterpret_cast(k->args.filters), - args->filters, sizeof(*k->args.filters) * k->args.filter_count); - } else { - k->args.filters = nullptr; - } - k->args.args = copy_channel_args(args->args); - return k; -} - -grpc_subchannel_key* grpc_subchannel_key_create( - const grpc_subchannel_args* args) { - return create_key(args, grpc_channel_args_normalize); -} - -static grpc_subchannel_key* subchannel_key_copy(grpc_subchannel_key* k) { - return create_key(&k->args, grpc_channel_args_copy); -} - -int grpc_subchannel_key_compare(const grpc_subchannel_key* a, - const grpc_subchannel_key* b) { - // To pretend the keys are different, return a non-zero value. - if (GPR_UNLIKELY(g_force_creation)) return 1; - int c = GPR_ICMP(a->args.filter_count, b->args.filter_count); - if (c != 0) return c; - if (a->args.filter_count > 0) { - c = memcmp(a->args.filters, b->args.filters, - a->args.filter_count * sizeof(*a->args.filters)); - if (c != 0) return c; - } - return grpc_channel_args_compare(a->args.args, b->args.args); -} - -void grpc_subchannel_key_destroy(grpc_subchannel_key* k) { - gpr_free(reinterpret_cast(k->args.filters)); - grpc_channel_args_destroy(const_cast(k->args.args)); - gpr_free(k); -} - -static void sck_avl_destroy(void* p, void* user_data) { - grpc_subchannel_key_destroy(static_cast(p)); -} - -static void* sck_avl_copy(void* p, void* unused) { - return subchannel_key_copy(static_cast(p)); -} - -static long sck_avl_compare(void* a, void* b, void* unused) { - return grpc_subchannel_key_compare(static_cast(a), - static_cast(b)); -} - -static void scv_avl_destroy(void* p, void* user_data) { - GRPC_SUBCHANNEL_WEAK_UNREF((grpc_subchannel*)p, "subchannel_index"); -} - -static void* scv_avl_copy(void* p, void* unused) { - GRPC_SUBCHANNEL_WEAK_REF((grpc_subchannel*)p, "subchannel_index"); - return p; -} - -static const grpc_avl_vtable subchannel_avl_vtable = { - sck_avl_destroy, // destroy_key - sck_avl_copy, // copy_key - sck_avl_compare, // compare_keys - scv_avl_destroy, // destroy_value - scv_avl_copy // copy_value -}; - -void grpc_subchannel_index_init(void) { - g_subchannel_index = grpc_avl_create(&subchannel_avl_vtable); - gpr_mu_init(&g_mu); - gpr_ref_init(&g_refcount, 1); -} - -void grpc_subchannel_index_shutdown(void) { - // TODO(juanlishen): This refcounting mechanism may lead to memory leackage. - // To solve that, we should force polling to flush any pending callbacks, then - // shutdown safely. - grpc_subchannel_index_unref(); -} - -void grpc_subchannel_index_unref(void) { - if (gpr_unref(&g_refcount)) { - gpr_mu_destroy(&g_mu); - grpc_avl_unref(g_subchannel_index, grpc_core::ExecCtx::Get()); - } -} - -void grpc_subchannel_index_ref(void) { gpr_ref_non_zero(&g_refcount); } - -grpc_subchannel* grpc_subchannel_index_find(grpc_subchannel_key* key) { - // Lock, and take a reference to the subchannel index. - // We don't need to do the search under a lock as avl's are immutable. - gpr_mu_lock(&g_mu); - grpc_avl index = grpc_avl_ref(g_subchannel_index, grpc_core::ExecCtx::Get()); - gpr_mu_unlock(&g_mu); - - grpc_subchannel* c = GRPC_SUBCHANNEL_REF_FROM_WEAK_REF( - (grpc_subchannel*)grpc_avl_get(index, key, grpc_core::ExecCtx::Get()), - "index_find"); - grpc_avl_unref(index, grpc_core::ExecCtx::Get()); - - return c; -} - -grpc_subchannel* grpc_subchannel_index_register(grpc_subchannel_key* key, - grpc_subchannel* constructed) { - grpc_subchannel* c = nullptr; - bool need_to_unref_constructed = false; - - while (c == nullptr) { - need_to_unref_constructed = false; - - // Compare and swap loop: - // - take a reference to the current index - gpr_mu_lock(&g_mu); - grpc_avl index = - grpc_avl_ref(g_subchannel_index, grpc_core::ExecCtx::Get()); - gpr_mu_unlock(&g_mu); - - // - Check to see if a subchannel already exists - c = static_cast( - grpc_avl_get(index, key, grpc_core::ExecCtx::Get())); - if (c != nullptr) { - c = GRPC_SUBCHANNEL_REF_FROM_WEAK_REF(c, "index_register"); - } - if (c != nullptr) { - // yes -> we're done - need_to_unref_constructed = true; - } else { - // no -> update the avl and compare/swap - grpc_avl updated = - grpc_avl_add(grpc_avl_ref(index, grpc_core::ExecCtx::Get()), - subchannel_key_copy(key), - GRPC_SUBCHANNEL_WEAK_REF(constructed, "index_register"), - grpc_core::ExecCtx::Get()); - - // it may happen (but it's expected to be unlikely) - // that some other thread has changed the index: - // compare/swap here to check that, and retry as necessary - gpr_mu_lock(&g_mu); - if (index.root == g_subchannel_index.root) { - GPR_SWAP(grpc_avl, updated, g_subchannel_index); - c = constructed; - } - gpr_mu_unlock(&g_mu); - - grpc_avl_unref(updated, grpc_core::ExecCtx::Get()); - } - grpc_avl_unref(index, grpc_core::ExecCtx::Get()); - } - - if (need_to_unref_constructed) { - GRPC_SUBCHANNEL_UNREF(constructed, "index_register"); - } - - return c; -} - -void grpc_subchannel_index_unregister(grpc_subchannel_key* key, - grpc_subchannel* constructed) { - bool done = false; - while (!done) { - // Compare and swap loop: - // - take a reference to the current index - gpr_mu_lock(&g_mu); - grpc_avl index = - grpc_avl_ref(g_subchannel_index, grpc_core::ExecCtx::Get()); - gpr_mu_unlock(&g_mu); - - // Check to see if this key still refers to the previously - // registered subchannel - grpc_subchannel* c = static_cast( - grpc_avl_get(index, key, grpc_core::ExecCtx::Get())); - if (c != constructed) { - grpc_avl_unref(index, grpc_core::ExecCtx::Get()); - break; - } - - // compare and swap the update (some other thread may have - // mutated the index behind us) - grpc_avl updated = - grpc_avl_remove(grpc_avl_ref(index, grpc_core::ExecCtx::Get()), key, - grpc_core::ExecCtx::Get()); - - gpr_mu_lock(&g_mu); - if (index.root == g_subchannel_index.root) { - GPR_SWAP(grpc_avl, updated, g_subchannel_index); - done = true; - } - gpr_mu_unlock(&g_mu); - - grpc_avl_unref(updated, grpc_core::ExecCtx::Get()); - grpc_avl_unref(index, grpc_core::ExecCtx::Get()); - } -} - -void grpc_subchannel_index_test_only_set_force_creation(bool force_creation) { - g_force_creation = force_creation; -} diff --git a/src/core/ext/filters/client_channel/subchannel_index.h b/src/core/ext/filters/client_channel/subchannel_index.h deleted file mode 100644 index c135613d26b..00000000000 --- a/src/core/ext/filters/client_channel/subchannel_index.h +++ /dev/null @@ -1,76 +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. - * - */ - -#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SUBCHANNEL_INDEX_H -#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SUBCHANNEL_INDEX_H - -#include - -#include "src/core/ext/filters/client_channel/subchannel.h" - -/** \file Provides an index of active subchannels so that they can be - shared amongst channels */ - -/** Create a key that can be used to uniquely identify a subchannel */ -grpc_subchannel_key* grpc_subchannel_key_create( - const grpc_subchannel_args* args); - -/** Destroy a subchannel key */ -void grpc_subchannel_key_destroy(grpc_subchannel_key* key); - -/** Given a subchannel key, find the subchannel registered for it. - Returns NULL if no such channel exists. - Thread-safe. */ -grpc_subchannel* grpc_subchannel_index_find(grpc_subchannel_key* key); - -/** Register a subchannel against a key. - Takes ownership of \a constructed. - Returns the registered subchannel. This may be different from - \a constructed in the case of a registration race. */ -grpc_subchannel* grpc_subchannel_index_register(grpc_subchannel_key* key, - grpc_subchannel* constructed); - -/** Remove \a constructed as the registered subchannel for \a key. */ -void grpc_subchannel_index_unregister(grpc_subchannel_key* key, - grpc_subchannel* constructed); - -int grpc_subchannel_key_compare(const grpc_subchannel_key* a, - const grpc_subchannel_key* b); - -/** Initialize the subchannel index (global) */ -void grpc_subchannel_index_init(void); -/** Shutdown the subchannel index (global) */ -void grpc_subchannel_index_shutdown(void); - -/** Increment the refcount (non-zero) of subchannel index (global). */ -void grpc_subchannel_index_ref(void); - -/** Decrement the refcount of subchannel index (global). If the refcount drops - to zero, unref the subchannel index and destroy its mutex. */ -void grpc_subchannel_index_unref(void); - -/** \em TEST ONLY. - * If \a force_creation is true, all keys are regarded different, resulting in - * new subchannels always being created. Otherwise, the keys will be compared as - * usual. - * - * Tests using this function \em MUST run tests with and without \a - * force_creation set. */ -void grpc_subchannel_index_test_only_set_force_creation(bool force_creation); - -#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SUBCHANNEL_INDEX_H */ diff --git a/src/core/ext/filters/client_channel/subchannel_pool_interface.cc b/src/core/ext/filters/client_channel/subchannel_pool_interface.cc new file mode 100644 index 00000000000..bb35f228b70 --- /dev/null +++ b/src/core/ext/filters/client_channel/subchannel_pool_interface.cc @@ -0,0 +1,97 @@ +// +// +// 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 + +#include "src/core/ext/filters/client_channel/subchannel_pool_interface.h" + +#include "src/core/lib/gpr/useful.h" + +// The subchannel pool to reuse subchannels. +#define GRPC_ARG_SUBCHANNEL_POOL "grpc.subchannel_pool" +// The subchannel key ID that is only used in test to make each key unique. +#define GRPC_ARG_SUBCHANNEL_KEY_TEST_ONLY_ID "grpc.subchannel_key_test_only_id" + +namespace grpc_core { + +TraceFlag grpc_subchannel_pool_trace(false, "subchannel_pool"); + +SubchannelKey::SubchannelKey(const grpc_channel_args* args) { + Init(args, grpc_channel_args_normalize); +} + +SubchannelKey::~SubchannelKey() { + grpc_channel_args_destroy(const_cast(args_)); +} + +SubchannelKey::SubchannelKey(const SubchannelKey& other) { + Init(other.args_, grpc_channel_args_copy); +} + +SubchannelKey& SubchannelKey::operator=(const SubchannelKey& other) { + grpc_channel_args_destroy(const_cast(args_)); + Init(other.args_, grpc_channel_args_copy); + return *this; +} + +int SubchannelKey::Cmp(const SubchannelKey& other) const { + return grpc_channel_args_compare(args_, other.args_); +} + +void SubchannelKey::Init( + const grpc_channel_args* args, + grpc_channel_args* (*copy_channel_args)(const grpc_channel_args* args)) { + args_ = copy_channel_args(args); +} + +namespace { + +void* arg_copy(void* p) { + auto* subchannel_pool = static_cast(p); + subchannel_pool->Ref().release(); + return p; +} + +void arg_destroy(void* p) { + auto* subchannel_pool = static_cast(p); + subchannel_pool->Unref(); +} + +int arg_cmp(void* a, void* b) { return GPR_ICMP(a, b); } + +const grpc_arg_pointer_vtable subchannel_pool_arg_vtable = { + arg_copy, arg_destroy, arg_cmp}; + +} // namespace + +grpc_arg SubchannelPoolInterface::CreateChannelArg( + SubchannelPoolInterface* subchannel_pool) { + return grpc_channel_arg_pointer_create( + const_cast(GRPC_ARG_SUBCHANNEL_POOL), subchannel_pool, + &subchannel_pool_arg_vtable); +} + +SubchannelPoolInterface* +SubchannelPoolInterface::GetSubchannelPoolFromChannelArgs( + const grpc_channel_args* args) { + const grpc_arg* arg = grpc_channel_args_find(args, GRPC_ARG_SUBCHANNEL_POOL); + if (arg == nullptr || arg->type != GRPC_ARG_POINTER) return nullptr; + return static_cast(arg->value.pointer.p); +} + +} // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/subchannel_pool_interface.h b/src/core/ext/filters/client_channel/subchannel_pool_interface.h new file mode 100644 index 00000000000..eeb56faf0c0 --- /dev/null +++ b/src/core/ext/filters/client_channel/subchannel_pool_interface.h @@ -0,0 +1,94 @@ +/* + * + * 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_SUBCHANNEL_POOL_INTERFACE_H +#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SUBCHANNEL_POOL_INTERFACE_H + +#include + +#include "src/core/lib/avl/avl.h" +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gprpp/abstract.h" +#include "src/core/lib/gprpp/ref_counted.h" + +namespace grpc_core { + +class Subchannel; + +extern TraceFlag grpc_subchannel_pool_trace; + +// A key that can uniquely identify a subchannel. +class SubchannelKey { + public: + explicit SubchannelKey(const grpc_channel_args* args); + ~SubchannelKey(); + + // Copyable. + SubchannelKey(const SubchannelKey& other); + SubchannelKey& operator=(const SubchannelKey& other); + // Not movable. + SubchannelKey(SubchannelKey&&) = delete; + SubchannelKey& operator=(SubchannelKey&&) = delete; + + int Cmp(const SubchannelKey& other) const; + + private: + // Initializes the subchannel key with the given \a args and the function to + // copy channel args. + void Init( + const grpc_channel_args* args, + grpc_channel_args* (*copy_channel_args)(const grpc_channel_args* args)); + + const grpc_channel_args* args_; +}; + +// Interface for subchannel pool. +// TODO(juanlishen): This refcounting mechanism may lead to memory leak. +// To solve that, we should force polling to flush any pending callbacks, then +// shut down safely. See https://github.com/grpc/grpc/issues/12560. +class SubchannelPoolInterface : public RefCounted { + public: + SubchannelPoolInterface() : RefCounted(&grpc_subchannel_pool_trace) {} + virtual ~SubchannelPoolInterface() {} + + // Registers a subchannel against a key. Returns the subchannel registered + // with \a key, which may be different from \a constructed because we reuse + // (instead of update) any existing subchannel already registered with \a key. + virtual Subchannel* RegisterSubchannel(SubchannelKey* key, + Subchannel* constructed) GRPC_ABSTRACT; + + // Removes the registered subchannel found by \a key. + virtual void UnregisterSubchannel(SubchannelKey* key) GRPC_ABSTRACT; + + // Finds the subchannel registered for the given subchannel key. Returns NULL + // if no such channel exists. Thread-safe. + virtual Subchannel* FindSubchannel(SubchannelKey* key) GRPC_ABSTRACT; + + // Creates a channel arg from \a subchannel pool. + static grpc_arg CreateChannelArg(SubchannelPoolInterface* subchannel_pool); + + // Gets the subchannel pool from the channel args. + static SubchannelPoolInterface* GetSubchannelPoolFromChannelArgs( + const grpc_channel_args* args); + + GRPC_ABSTRACT_BASE_CLASS +}; + +} // namespace grpc_core + +#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SUBCHANNEL_POOL_INTERFACE_H */ diff --git a/src/core/ext/filters/deadline/deadline_filter.cc b/src/core/ext/filters/deadline/deadline_filter.cc index b4cb07f0f92..20a2953e5ff 100644 --- a/src/core/ext/filters/deadline/deadline_filter.cc +++ b/src/core/ext/filters/deadline/deadline_filter.cc @@ -68,8 +68,7 @@ static void timer_callback(void* arg, grpc_error* error) { error = grpc_error_set_int( GRPC_ERROR_CREATE_FROM_STATIC_STRING("Deadline Exceeded"), GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_DEADLINE_EXCEEDED); - grpc_call_combiner_cancel(deadline_state->call_combiner, - GRPC_ERROR_REF(error)); + deadline_state->call_combiner->Cancel(GRPC_ERROR_REF(error)); GRPC_CLOSURE_INIT(&deadline_state->timer_callback, send_cancel_op_in_call_combiner, elem, grpc_schedule_on_exec_ctx); @@ -124,7 +123,7 @@ static void cancel_timer_if_needed(grpc_deadline_state* deadline_state) { deadline_state->timer_state = GRPC_DEADLINE_STATE_FINISHED; grpc_timer_cancel(&deadline_state->timer); } else { - // timer was either in STATE_INITAL (nothing to cancel) + // timer was either in STATE_INITIAL (nothing to cancel) // OR in STATE_FINISHED (again nothing to cancel) } } @@ -183,7 +182,7 @@ static void start_timer_after_init(void* arg, grpc_error* error) { grpc_deadline_state::grpc_deadline_state(grpc_call_element* elem, grpc_call_stack* call_stack, - grpc_call_combiner* call_combiner, + grpc_core::CallCombiner* call_combiner, grpc_millis deadline) : call_stack(call_stack), call_combiner(call_combiner) { // Deadline will always be infinite on servers, so the timer will only be diff --git a/src/core/ext/filters/deadline/deadline_filter.h b/src/core/ext/filters/deadline/deadline_filter.h index e37032999c6..7c4e9aaed0e 100644 --- a/src/core/ext/filters/deadline/deadline_filter.h +++ b/src/core/ext/filters/deadline/deadline_filter.h @@ -32,12 +32,13 @@ enum grpc_deadline_timer_state { // Must be the first field in the filter's call_data. struct grpc_deadline_state { grpc_deadline_state(grpc_call_element* elem, grpc_call_stack* call_stack, - grpc_call_combiner* call_combiner, grpc_millis deadline); + grpc_core::CallCombiner* call_combiner, + grpc_millis deadline); ~grpc_deadline_state(); // We take a reference to the call stack for the timer callback. grpc_call_stack* call_stack; - grpc_call_combiner* call_combiner; + grpc_core::CallCombiner* call_combiner; grpc_deadline_timer_state timer_state = GRPC_DEADLINE_STATE_INITIAL; grpc_timer timer; grpc_closure timer_callback; diff --git a/src/core/ext/filters/http/client/http_client_filter.cc b/src/core/ext/filters/http/client/http_client_filter.cc index bf9a01f659b..4ef6c1f610e 100644 --- a/src/core/ext/filters/http/client/http_client_filter.cc +++ b/src/core/ext/filters/http/client/http_client_filter.cc @@ -36,7 +36,7 @@ #define EXPECTED_CONTENT_TYPE "application/grpc" #define EXPECTED_CONTENT_TYPE_LENGTH sizeof(EXPECTED_CONTENT_TYPE) - 1 -/* default maximum size of payload eligable for GET request */ +/* default maximum size of payload eligible for GET request */ static constexpr size_t kMaxPayloadSizeForGet = 2048; static void recv_initial_metadata_ready(void* user_data, grpc_error* error); @@ -62,7 +62,7 @@ struct call_data { ~call_data() { GRPC_ERROR_UNREF(recv_initial_metadata_error); } - grpc_call_combiner* call_combiner; + grpc_core::CallCombiner* call_combiner; // State for handling send_initial_metadata ops. grpc_linked_mdelem method; grpc_linked_mdelem scheme; @@ -107,7 +107,8 @@ static grpc_error* client_filter_incoming_metadata(grpc_call_element* elem, * https://github.com/grpc/grpc/blob/master/doc/http-grpc-status-mapping.md. */ if (b->idx.named.grpc_status != nullptr || - grpc_mdelem_eq(b->idx.named.status->md, GRPC_MDELEM_STATUS_200)) { + grpc_mdelem_static_value_eq(b->idx.named.status->md, + GRPC_MDELEM_STATUS_200)) { grpc_metadata_batch_remove(b, b->idx.named.status); } else { char* val = grpc_dump_slice(GRPC_MDVALUE(b->idx.named.status->md), @@ -140,8 +141,9 @@ static grpc_error* client_filter_incoming_metadata(grpc_call_element* elem, } if (b->idx.named.content_type != nullptr) { - if (!grpc_mdelem_eq(b->idx.named.content_type->md, - GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC)) { + if (!grpc_mdelem_static_value_eq( + b->idx.named.content_type->md, + GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC)) { if (grpc_slice_buf_start_eq(GRPC_MDVALUE(b->idx.named.content_type->md), EXPECTED_CONTENT_TYPE, EXPECTED_CONTENT_TYPE_LENGTH) && diff --git a/src/core/ext/filters/http/client/http_client_filter.h b/src/core/ext/filters/http/client/http_client_filter.h index b7cef33f5c7..a2f16ddbfbe 100644 --- a/src/core/ext/filters/http/client/http_client_filter.h +++ b/src/core/ext/filters/http/client/http_client_filter.h @@ -25,7 +25,7 @@ /* Processes metadata on the client side for HTTP2 transports */ extern const grpc_channel_filter grpc_http_client_filter; -/* Channel arg to determine maximum size of payload eligable for GET request */ +/* Channel arg to determine maximum size of payload eligible for GET request */ #define GRPC_ARG_MAX_PAYLOAD_SIZE_FOR_GET "grpc.max_payload_size_for_get" #endif /* GRPC_CORE_EXT_FILTERS_HTTP_CLIENT_HTTP_CLIENT_FILTER_H */ diff --git a/src/core/ext/filters/http/client_authority_filter.cc b/src/core/ext/filters/http/client_authority_filter.cc index 6383f125944..85b30bc13ca 100644 --- a/src/core/ext/filters/http/client_authority_filter.cc +++ b/src/core/ext/filters/http/client_authority_filter.cc @@ -40,11 +40,12 @@ namespace { struct call_data { grpc_linked_mdelem authority_storage; - grpc_call_combiner* call_combiner; + grpc_core::CallCombiner* call_combiner; }; struct channel_data { grpc_slice default_authority; + grpc_mdelem default_authority_mdelem; }; void authority_start_transport_stream_op_batch( @@ -59,8 +60,7 @@ void authority_start_transport_stream_op_batch( initial_metadata->idx.named.authority == nullptr) { grpc_error* error = grpc_metadata_batch_add_head( initial_metadata, &calld->authority_storage, - grpc_mdelem_create(GRPC_MDSTR_AUTHORITY, chand->default_authority, - nullptr)); + GRPC_MDELEM_REF(chand->default_authority_mdelem)); if (error != GRPC_ERROR_NONE) { grpc_transport_stream_op_batch_finish_with_failure(batch, error, calld->call_combiner); @@ -103,6 +103,8 @@ grpc_error* init_channel_elem(grpc_channel_element* elem, } chand->default_authority = grpc_slice_intern(grpc_slice_from_static_string(default_authority_str)); + chand->default_authority_mdelem = grpc_mdelem_create( + GRPC_MDSTR_AUTHORITY, chand->default_authority, nullptr); GPR_ASSERT(!args->is_last); return GRPC_ERROR_NONE; } @@ -111,6 +113,7 @@ grpc_error* init_channel_elem(grpc_channel_element* elem, void destroy_channel_elem(grpc_channel_element* elem) { channel_data* chand = static_cast(elem->channel_data); grpc_slice_unref_internal(chand->default_authority); + GRPC_MDELEM_UNREF(chand->default_authority_mdelem); } } // namespace 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 9c8c8d9e188..d2b1f6794cd 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 @@ -29,6 +29,7 @@ #include "src/core/ext/filters/http/message_compress/message_compress_filter.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/compression/algorithm_metadata.h" +#include "src/core/lib/compression/compression_args.h" #include "src/core/lib/compression/compression_internal.h" #include "src/core/lib/compression/message_compress.h" #include "src/core/lib/gpr/string.h" @@ -71,7 +72,7 @@ struct call_data { GRPC_ERROR_UNREF(cancel_error); } - grpc_call_combiner* call_combiner; + grpc_core::CallCombiner* call_combiner; grpc_linked_mdelem compression_algorithm_storage; grpc_linked_mdelem stream_compression_algorithm_storage; grpc_linked_mdelem accept_encoding_storage; @@ -248,7 +249,7 @@ static void finish_send_message(grpc_call_element* elem) { bool did_compress = grpc_msg_compress(calld->message_compression_algorithm, &calld->slices, &tmp); if (did_compress) { - if (grpc_compression_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_compression_trace)) { const char* algo_name; const size_t before_size = calld->slices.length; const size_t after_size = tmp.length; @@ -264,7 +265,7 @@ static void finish_send_message(grpc_call_element* elem) { grpc_slice_buffer_swap(&calld->slices, &tmp); send_flags |= GRPC_WRITE_INTERNAL_COMPRESS; } else { - if (grpc_compression_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_compression_trace)) { const char* algo_name; GPR_ASSERT(grpc_message_compression_algorithm_name( calld->message_compression_algorithm, &algo_name)); diff --git a/src/core/ext/filters/http/server/http_server_filter.cc b/src/core/ext/filters/http/server/http_server_filter.cc index ce1be8370c6..028d268c7b3 100644 --- a/src/core/ext/filters/http/server/http_server_filter.cc +++ b/src/core/ext/filters/http/server/http_server_filter.cc @@ -61,7 +61,7 @@ struct call_data { } } - grpc_call_combiner* call_combiner; + grpc_core::CallCombiner* call_combiner; // Outgoing headers to add to send_initial_metadata. grpc_linked_mdelem status; @@ -131,18 +131,19 @@ static grpc_error* hs_filter_incoming_metadata(grpc_call_element* elem, static const char* error_name = "Failed processing incoming headers"; if (b->idx.named.method != nullptr) { - if (grpc_mdelem_eq(b->idx.named.method->md, GRPC_MDELEM_METHOD_POST)) { + if (grpc_mdelem_static_value_eq(b->idx.named.method->md, + GRPC_MDELEM_METHOD_POST)) { *calld->recv_initial_metadata_flags &= ~(GRPC_INITIAL_METADATA_CACHEABLE_REQUEST | GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST); - } else if (grpc_mdelem_eq(b->idx.named.method->md, - GRPC_MDELEM_METHOD_PUT)) { + } else if (grpc_mdelem_static_value_eq(b->idx.named.method->md, + GRPC_MDELEM_METHOD_PUT)) { *calld->recv_initial_metadata_flags &= ~GRPC_INITIAL_METADATA_CACHEABLE_REQUEST; *calld->recv_initial_metadata_flags |= GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST; - } else if (grpc_mdelem_eq(b->idx.named.method->md, - GRPC_MDELEM_METHOD_GET)) { + } else if (grpc_mdelem_static_value_eq(b->idx.named.method->md, + GRPC_MDELEM_METHOD_GET)) { *calld->recv_initial_metadata_flags |= GRPC_INITIAL_METADATA_CACHEABLE_REQUEST; *calld->recv_initial_metadata_flags &= @@ -163,7 +164,8 @@ static grpc_error* hs_filter_incoming_metadata(grpc_call_element* elem, } if (b->idx.named.te != nullptr) { - if (!grpc_mdelem_eq(b->idx.named.te->md, GRPC_MDELEM_TE_TRAILERS)) { + if (!grpc_mdelem_static_value_eq(b->idx.named.te->md, + GRPC_MDELEM_TE_TRAILERS)) { hs_add_error(error_name, &error, grpc_attach_md_to_error( GRPC_ERROR_CREATE_FROM_STATIC_STRING("Bad header"), @@ -178,9 +180,12 @@ static grpc_error* hs_filter_incoming_metadata(grpc_call_element* elem, } if (b->idx.named.scheme != nullptr) { - if (!grpc_mdelem_eq(b->idx.named.scheme->md, GRPC_MDELEM_SCHEME_HTTP) && - !grpc_mdelem_eq(b->idx.named.scheme->md, GRPC_MDELEM_SCHEME_HTTPS) && - !grpc_mdelem_eq(b->idx.named.scheme->md, GRPC_MDELEM_SCHEME_GRPC)) { + if (!grpc_mdelem_static_value_eq(b->idx.named.scheme->md, + GRPC_MDELEM_SCHEME_HTTP) && + !grpc_mdelem_static_value_eq(b->idx.named.scheme->md, + GRPC_MDELEM_SCHEME_HTTPS) && + !grpc_mdelem_static_value_eq(b->idx.named.scheme->md, + GRPC_MDELEM_SCHEME_GRPC)) { hs_add_error(error_name, &error, grpc_attach_md_to_error( GRPC_ERROR_CREATE_FROM_STATIC_STRING("Bad header"), @@ -196,8 +201,9 @@ static grpc_error* hs_filter_incoming_metadata(grpc_call_element* elem, } if (b->idx.named.content_type != nullptr) { - if (!grpc_mdelem_eq(b->idx.named.content_type->md, - GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC)) { + if (!grpc_mdelem_static_value_eq( + b->idx.named.content_type->md, + GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC)) { if (grpc_slice_buf_start_eq(GRPC_MDVALUE(b->idx.named.content_type->md), EXPECTED_CONTENT_TYPE, EXPECTED_CONTENT_TYPE_LENGTH) && diff --git a/src/core/ext/filters/load_reporting/server_load_reporting_filter.cc b/src/core/ext/filters/load_reporting/server_load_reporting_filter.cc index 6a7231ff7db..1d373c5b994 100644 --- a/src/core/ext/filters/load_reporting/server_load_reporting_filter.cc +++ b/src/core/ext/filters/load_reporting/server_load_reporting_filter.cc @@ -30,7 +30,7 @@ #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/context.h" #include "src/core/lib/iomgr/resolve_address.h" -#include "src/core/lib/iomgr/sockaddr_posix.h" +#include "src/core/lib/iomgr/sockaddr.h" #include "src/core/lib/iomgr/socket_utils.h" #include "src/core/lib/security/context/security_context.h" #include "src/core/lib/slice/slice_internal.h" @@ -342,8 +342,8 @@ bool MaybeAddServerLoadReportingFilter(const grpc_channel_args& args) { // time if we build with the filter target. struct ServerLoadReportingFilterStaticRegistrar { ServerLoadReportingFilterStaticRegistrar() { - static std::atomic_bool registered{false}; - if (registered) return; + static grpc_core::Atomic registered{false}; + if (registered.Load(grpc_core::MemoryOrder::ACQUIRE)) return; RegisterChannelFilter( "server_load_reporting", GRPC_SERVER_CHANNEL, INT_MAX, @@ -356,7 +356,7 @@ struct ServerLoadReportingFilterStaticRegistrar { ::grpc::load_reporter::MeasureEndBytesReceived(); ::grpc::load_reporter::MeasureEndLatencyMs(); ::grpc::load_reporter::MeasureOtherCallMetric(); - registered = true; + registered.Store(true, grpc_core::MemoryOrder::RELEASE); } } server_load_reporting_filter_static_registrar; diff --git a/src/core/ext/filters/max_age/max_age_filter.cc b/src/core/ext/filters/max_age/max_age_filter.cc index 431472609eb..f2308581c13 100644 --- a/src/core/ext/filters/max_age/max_age_filter.cc +++ b/src/core/ext/filters/max_age/max_age_filter.cc @@ -106,7 +106,7 @@ struct channel_data { +--------------------------------+----------------+---------+ MAX_IDLE_STATE_INIT: The initial and final state of 'idle_state'. The - channel has 1 or 1+ active calls, and the the timer is not set. Note that + channel has 1 or 1+ active calls, and the timer is not set. Note that we may put a virtual call to hold this state at channel initialization or shutdown, so that the channel won't enter other states. @@ -499,7 +499,10 @@ static grpc_error* init_channel_elem(grpc_channel_element* elem, } /* Destructor for channel_data. */ -static void destroy_channel_elem(grpc_channel_element* elem) {} +static void destroy_channel_elem(grpc_channel_element* elem) { + channel_data* chand = static_cast(elem->channel_data); + gpr_mu_destroy(&chand->max_age_timer_mu); +} const grpc_channel_filter grpc_max_age_filter = { grpc_call_next_op, diff --git a/src/core/ext/filters/message_size/message_size_filter.cc b/src/core/ext/filters/message_size/message_size_filter.cc index 94d6942aa4f..a973cbca121 100644 --- a/src/core/ext/filters/message_size/message_size_filter.cc +++ b/src/core/ext/filters/message_size/message_size_filter.cc @@ -26,81 +26,84 @@ #include #include +#include "src/core/ext/filters/client_channel/service_config.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/channel_stack_builder.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gprpp/ref_counted.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" +#include "src/core/lib/surface/call.h" #include "src/core/lib/surface/channel_init.h" -#include "src/core/lib/transport/service_config.h" - -typedef struct { - int max_send_size; - int max_recv_size; -} message_size_limits; - -namespace grpc_core { -namespace { - -class MessageSizeLimits : public RefCounted { - public: - static RefCountedPtr CreateFromJson(const grpc_json* json); - - const message_size_limits& limits() const { return limits_; } - - private: - // So New() can call our private ctor. - template - friend T* grpc_core::New(Args&&... args); - - MessageSizeLimits(int max_send_size, int max_recv_size) { - limits_.max_send_size = max_send_size; - limits_.max_recv_size = max_recv_size; - } - - message_size_limits limits_; -}; - -RefCountedPtr MessageSizeLimits::CreateFromJson( - const grpc_json* json) { - int max_request_message_bytes = -1; - int max_response_message_bytes = -1; - for (grpc_json* field = json->child; field != nullptr; field = field->next) { - if (field->key == nullptr) continue; - if (strcmp(field->key, "maxRequestMessageBytes") == 0) { - if (max_request_message_bytes >= 0) return nullptr; // Duplicate. - if (field->type != GRPC_JSON_STRING && field->type != GRPC_JSON_NUMBER) { - return nullptr; - } - max_request_message_bytes = gpr_parse_nonnegative_int(field->value); - if (max_request_message_bytes == -1) return nullptr; - } else if (strcmp(field->key, "maxResponseMessageBytes") == 0) { - if (max_response_message_bytes >= 0) return nullptr; // Duplicate. - if (field->type != GRPC_JSON_STRING && field->type != GRPC_JSON_NUMBER) { - return nullptr; - } - max_response_message_bytes = gpr_parse_nonnegative_int(field->value); - if (max_response_message_bytes == -1) return nullptr; - } - } - return MakeRefCounted(max_request_message_bytes, - max_response_message_bytes); -} - -} // namespace -} // namespace grpc_core static void recv_message_ready(void* user_data, grpc_error* error); static void recv_trailing_metadata_ready(void* user_data, grpc_error* error); -namespace { +namespace grpc_core { +namespace { +size_t g_message_size_parser_index; +} // namespace + +UniquePtr MessageSizeParser::ParsePerMethodParams( + const grpc_json* json, grpc_error** error) { + GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); + int max_request_message_bytes = -1; + int max_response_message_bytes = -1; + InlinedVector error_list; + for (grpc_json* field = json->child; field != nullptr; field = field->next) { + if (field->key == nullptr) continue; + if (strcmp(field->key, "maxRequestMessageBytes") == 0) { + if (max_request_message_bytes >= 0) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxRequestMessageBytes error:Duplicate entry")); + } // Duplicate, continue parsing. + if (field->type != GRPC_JSON_STRING && field->type != GRPC_JSON_NUMBER) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxRequestMessageBytes error:should be of type number")); + } else { + max_request_message_bytes = gpr_parse_nonnegative_int(field->value); + if (max_request_message_bytes == -1) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxRequestMessageBytes error:should be non-negative")); + } + } + } else if (strcmp(field->key, "maxResponseMessageBytes") == 0) { + if (max_response_message_bytes >= 0) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxResponseMessageBytes error:Duplicate entry")); + } // Duplicate, continue parsing + if (field->type != GRPC_JSON_STRING && field->type != GRPC_JSON_NUMBER) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxResponseMessageBytes error:should be of type number")); + } else { + max_response_message_bytes = gpr_parse_nonnegative_int(field->value); + if (max_response_message_bytes == -1) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxResponseMessageBytes error:should be non-negative")); + } + } + } + } + if (!error_list.empty()) { + *error = GRPC_ERROR_CREATE_FROM_VECTOR("Message size parser", &error_list); + return nullptr; + } + return UniquePtr(New( + max_request_message_bytes, max_response_message_bytes)); +} + +void MessageSizeParser::Register() { + g_message_size_parser_index = ServiceConfig::RegisterParser( + UniquePtr(New())); +} + +size_t MessageSizeParser::ParserIndex() { return g_message_size_parser_index; } +} // namespace grpc_core + +namespace { struct channel_data { - message_size_limits limits; - // Maps path names to refcounted_message_size_limits structs. - grpc_core::RefCountedPtr>> - method_limit_table; + grpc_core::MessageSizeParsedObject::message_size_limits limits; + grpc_core::RefCountedPtr svc_cfg; }; struct call_data { @@ -116,29 +119,42 @@ struct call_data { // Note: Per-method config is only available on the client, so we // apply the max request size to the send limit and the max response // size to the receive limit. - if (chand.method_limit_table != nullptr) { - grpc_core::RefCountedPtr limits = - grpc_core::ServiceConfig::MethodConfigTableLookup( - *chand.method_limit_table, args.path); - if (limits != nullptr) { - if (limits->limits().max_send_size >= 0 && - (limits->limits().max_send_size < this->limits.max_send_size || - this->limits.max_send_size < 0)) { - this->limits.max_send_size = limits->limits().max_send_size; - } - if (limits->limits().max_recv_size >= 0 && - (limits->limits().max_recv_size < this->limits.max_recv_size || - this->limits.max_recv_size < 0)) { - this->limits.max_recv_size = limits->limits().max_recv_size; - } + const grpc_core::MessageSizeParsedObject* limits = nullptr; + grpc_core::ServiceConfig::CallData* svc_cfg_call_data = nullptr; + if (args.context != nullptr) { + svc_cfg_call_data = static_cast( + args.context[GRPC_SERVICE_CONFIG_CALL_DATA].value); + } + if (svc_cfg_call_data != nullptr) { + limits = static_cast( + svc_cfg_call_data->GetMethodParsedObject( + grpc_core::MessageSizeParser::ParserIndex())); + } else if (chand.svc_cfg != nullptr) { + const auto* objs_vector = + chand.svc_cfg->GetMethodServiceConfigObjectsVector(args.path); + if (objs_vector != nullptr) { + limits = static_cast( + (*objs_vector)[grpc_core::MessageSizeParser::ParserIndex()].get()); + } + } + if (limits != nullptr) { + if (limits->limits().max_send_size >= 0 && + (limits->limits().max_send_size < this->limits.max_send_size || + this->limits.max_send_size < 0)) { + this->limits.max_send_size = limits->limits().max_send_size; + } + if (limits->limits().max_recv_size >= 0 && + (limits->limits().max_recv_size < this->limits.max_recv_size || + this->limits.max_recv_size < 0)) { + this->limits.max_recv_size = limits->limits().max_recv_size; } } } ~call_data() { GRPC_ERROR_UNREF(error); } - grpc_call_combiner* call_combiner; - message_size_limits limits; + grpc_core::CallCombiner* call_combiner; + grpc_core::MessageSizeParsedObject::message_size_limits limits; // Receive closures are chained: we inject this closure as the // recv_message_ready up-call on transport_stream_op, and remember to // call our next_recv_message_ready member after handling it. @@ -284,9 +300,9 @@ static int default_size(const grpc_channel_args* args, return without_minimal_stack; } -message_size_limits get_message_size_limits( +grpc_core::MessageSizeParsedObject::message_size_limits get_message_size_limits( const grpc_channel_args* channel_args) { - message_size_limits lim; + grpc_core::MessageSizeParsedObject::message_size_limits lim; lim.max_send_size = default_size(channel_args, GRPC_DEFAULT_MAX_SEND_MESSAGE_LENGTH); lim.max_recv_size = @@ -313,18 +329,27 @@ static grpc_error* init_channel_elem(grpc_channel_element* elem, grpc_channel_element_args* args) { GPR_ASSERT(!args->is_last); channel_data* chand = static_cast(elem->channel_data); + new (chand) channel_data(); chand->limits = get_message_size_limits(args->channel_args); - // Get method config table from channel args. + // TODO(yashykt): We only need to read GRPC_ARG_SERVICE_CONFIG in the case of + // direct channels. (Service config is otherwise stored in the call_context by + // client_channel filter.) If we ever need a second filter that also needs to + // parse GRPC_ARG_SERVICE_CONFIG, we should refactor this code and add a + // separate filter that reads GRPC_ARG_SERVICE_CONFIG and saves the parsed + // config in the call_context. const grpc_arg* channel_arg = grpc_channel_args_find(args->channel_args, GRPC_ARG_SERVICE_CONFIG); const char* service_config_str = grpc_channel_arg_get_string(channel_arg); if (service_config_str != nullptr) { - grpc_core::UniquePtr service_config = - grpc_core::ServiceConfig::Create(service_config_str); - if (service_config != nullptr) { - chand->method_limit_table = service_config->CreateMethodConfigTable( - grpc_core::MessageSizeLimits::CreateFromJson); + grpc_error* service_config_error = GRPC_ERROR_NONE; + auto svc_cfg = grpc_core::ServiceConfig::Create(service_config_str, + &service_config_error); + if (service_config_error == GRPC_ERROR_NONE) { + chand->svc_cfg = std::move(svc_cfg); + } else { + gpr_log(GPR_ERROR, "%s", grpc_error_string(service_config_error)); } + GRPC_ERROR_UNREF(service_config_error); } return GRPC_ERROR_NONE; } @@ -332,7 +357,7 @@ static grpc_error* init_channel_elem(grpc_channel_element* elem, // Destructor for channel_data. static void destroy_channel_elem(grpc_channel_element* elem) { channel_data* chand = static_cast(elem->channel_data); - chand->method_limit_table.reset(); + chand->~channel_data(); } const grpc_channel_filter grpc_message_size_filter = { @@ -348,18 +373,34 @@ const grpc_channel_filter grpc_message_size_filter = { grpc_channel_next_get_info, "message_size"}; +// Used for GRPC_CLIENT_SUBCHANNEL +static bool maybe_add_message_size_filter_subchannel( + grpc_channel_stack_builder* builder, void* arg) { + const grpc_channel_args* channel_args = + grpc_channel_stack_builder_get_channel_arguments(builder); + if (grpc_channel_args_want_minimal_stack(channel_args)) { + return true; + } + return grpc_channel_stack_builder_prepend_filter( + builder, &grpc_message_size_filter, nullptr, nullptr); +} + +// Used for GRPC_CLIENT_DIRECT_CHANNEL and GRPC_SERVER_CHANNEL. Adds the filter +// only if message size limits or service config is specified. static bool maybe_add_message_size_filter(grpc_channel_stack_builder* builder, void* arg) { const grpc_channel_args* channel_args = grpc_channel_stack_builder_get_channel_arguments(builder); bool enable = false; - message_size_limits lim = get_message_size_limits(channel_args); + grpc_core::MessageSizeParsedObject::message_size_limits lim = + get_message_size_limits(channel_args); if (lim.max_send_size != -1 || lim.max_recv_size != -1) { enable = true; } const grpc_arg* a = grpc_channel_args_find(channel_args, GRPC_ARG_SERVICE_CONFIG); - if (a != nullptr) { + const char* svc_cfg_str = grpc_channel_arg_get_string(a); + if (svc_cfg_str != nullptr) { enable = true; } if (enable) { @@ -371,15 +412,16 @@ static bool maybe_add_message_size_filter(grpc_channel_stack_builder* builder, } void grpc_message_size_filter_init(void) { - grpc_channel_init_register_stage(GRPC_CLIENT_SUBCHANNEL, - GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, - maybe_add_message_size_filter, nullptr); + grpc_channel_init_register_stage( + GRPC_CLIENT_SUBCHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, + maybe_add_message_size_filter_subchannel, nullptr); grpc_channel_init_register_stage(GRPC_CLIENT_DIRECT_CHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, maybe_add_message_size_filter, nullptr); grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, maybe_add_message_size_filter, nullptr); + grpc_core::MessageSizeParser::Register(); } void grpc_message_size_filter_shutdown(void) {} diff --git a/src/core/ext/filters/message_size/message_size_filter.h b/src/core/ext/filters/message_size/message_size_filter.h index f66636e5832..cab8bd9627f 100644 --- a/src/core/ext/filters/message_size/message_size_filter.h +++ b/src/core/ext/filters/message_size/message_size_filter.h @@ -19,8 +19,41 @@ #include +#include "src/core/ext/filters/client_channel/service_config.h" #include "src/core/lib/channel/channel_stack.h" extern const grpc_channel_filter grpc_message_size_filter; +namespace grpc_core { + +class MessageSizeParsedObject : public ServiceConfig::ParsedConfig { + public: + struct message_size_limits { + int max_send_size; + int max_recv_size; + }; + + MessageSizeParsedObject(int max_send_size, int max_recv_size) { + limits_.max_send_size = max_send_size; + limits_.max_recv_size = max_recv_size; + } + + const message_size_limits& limits() const { return limits_; } + + private: + message_size_limits limits_; +}; + +class MessageSizeParser : public ServiceConfig::Parser { + public: + UniquePtr ParsePerMethodParams( + const grpc_json* json, grpc_error** error) override; + + static void Register(); + + static size_t ParserIndex(); +}; + +} // namespace grpc_core + #endif /* GRPC_CORE_EXT_FILTERS_MESSAGE_SIZE_MESSAGE_SIZE_FILTER_H */ diff --git a/src/core/ext/transport/chttp2/alpn/alpn.h b/src/core/ext/transport/chttp2/alpn/alpn.h index 0042eafd95a..e2ffe4e405e 100644 --- a/src/core/ext/transport/chttp2/alpn/alpn.h +++ b/src/core/ext/transport/chttp2/alpn/alpn.h @@ -23,7 +23,7 @@ #include -/* Retuns 1 if the version is supported, 0 otherwise. */ +/* Returns 1 if the version is supported, 0 otherwise. */ int grpc_chttp2_is_alpn_version_supported(const char* version, size_t size); /* Returns the number of protocol versions to advertise */ diff --git a/src/core/ext/transport/chttp2/client/chttp2_connector.cc b/src/core/ext/transport/chttp2/client/chttp2_connector.cc index 60a32022f57..c324c2c9243 100644 --- a/src/core/ext/transport/chttp2/client/chttp2_connector.cc +++ b/src/core/ext/transport/chttp2/client/chttp2_connector.cc @@ -55,7 +55,7 @@ typedef struct { grpc_closure connected; - grpc_handshake_manager* handshake_mgr; + grpc_core::RefCountedPtr handshake_mgr; } chttp2_connector; static void chttp2_connector_ref(grpc_connector* con) { @@ -79,7 +79,7 @@ static void chttp2_connector_shutdown(grpc_connector* con, grpc_error* why) { gpr_mu_lock(&c->mu); c->shutdown = true; if (c->handshake_mgr != nullptr) { - grpc_handshake_manager_shutdown(c->handshake_mgr, GRPC_ERROR_REF(why)); + c->handshake_mgr->Shutdown(GRPC_ERROR_REF(why)); } // If handshaking is not yet in progress, shutdown the endpoint. // Otherwise, the handshaker will do this for us. @@ -91,7 +91,7 @@ static void chttp2_connector_shutdown(grpc_connector* con, grpc_error* why) { } static void on_handshake_done(void* arg, grpc_error* error) { - grpc_handshaker_args* args = static_cast(arg); + auto* args = static_cast(arg); chttp2_connector* c = static_cast(args->user_data); gpr_mu_lock(&c->mu); if (error != GRPC_ERROR_NONE || c->shutdown) { @@ -117,8 +117,9 @@ static void on_handshake_done(void* arg, grpc_error* error) { c->args.interested_parties); c->result->transport = grpc_create_chttp2_transport(args->args, args->endpoint, true); - c->result->socket_uuid = - grpc_chttp2_transport_get_socket_uuid(c->result->transport); + grpc_core::RefCountedPtr socket_node = + grpc_chttp2_transport_get_socket_node(c->result->transport); + c->result->socket_uuid = socket_node == nullptr ? 0 : socket_node->uuid(); GPR_ASSERT(c->result->transport); // TODO(roth): We ideally want to wait until we receive HTTP/2 // settings from the server before we consider the connection @@ -151,20 +152,20 @@ static void on_handshake_done(void* arg, grpc_error* error) { grpc_closure* notify = c->notify; c->notify = nullptr; GRPC_CLOSURE_SCHED(notify, error); - grpc_handshake_manager_destroy(c->handshake_mgr); - c->handshake_mgr = nullptr; + c->handshake_mgr.reset(); gpr_mu_unlock(&c->mu); chttp2_connector_unref(reinterpret_cast(c)); } static void start_handshake_locked(chttp2_connector* c) { - c->handshake_mgr = grpc_handshake_manager_create(); - grpc_handshakers_add(HANDSHAKER_CLIENT, c->args.channel_args, - c->args.interested_parties, c->handshake_mgr); + c->handshake_mgr = grpc_core::MakeRefCounted(); + grpc_core::HandshakerRegistry::AddHandshakers( + grpc_core::HANDSHAKER_CLIENT, c->args.channel_args, + c->args.interested_parties, c->handshake_mgr.get()); grpc_endpoint_add_to_pollset_set(c->endpoint, c->args.interested_parties); - grpc_handshake_manager_do_handshake( - c->handshake_mgr, c->endpoint, c->args.channel_args, c->args.deadline, - nullptr /* acceptor */, on_handshake_done, c); + c->handshake_mgr->DoHandshake(c->endpoint, c->args.channel_args, + c->args.deadline, nullptr /* acceptor */, + on_handshake_done, c); c->endpoint = nullptr; // Endpoint handed off to handshake manager. } @@ -201,7 +202,8 @@ static void chttp2_connector_connect(grpc_connector* con, grpc_closure* notify) { chttp2_connector* c = reinterpret_cast(con); grpc_resolved_address addr; - grpc_get_subchannel_address_arg(args->channel_args, &addr); + grpc_core::Subchannel::GetAddressFromSubchannelAddressArg(args->channel_args, + &addr); gpr_mu_lock(&c->mu); GPR_ASSERT(c->notify == nullptr); c->notify = notify; 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 e6c8c382607..0d61abd2a01 100644 --- a/src/core/ext/transport/chttp2/client/insecure/channel_create.cc +++ b/src/core/ext/transport/chttp2/client/insecure/channel_create.cc @@ -33,52 +33,53 @@ #include "src/core/lib/surface/api_trace.h" #include "src/core/lib/surface/channel.h" -static void client_channel_factory_ref( - grpc_client_channel_factory* cc_factory) {} +namespace grpc_core { -static void client_channel_factory_unref( - grpc_client_channel_factory* cc_factory) {} - -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, &final_sc_args); - grpc_connector_unref(connector); - grpc_channel_args_destroy(const_cast(final_sc_args.args)); - return s; -} - -static grpc_channel* client_channel_factory_create_channel( - grpc_client_channel_factory* cc_factory, const char* target, - grpc_client_channel_type type, const grpc_channel_args* args) { - if (target == nullptr) { - gpr_log(GPR_ERROR, "cannot create channel with NULL target name"); - return nullptr; +class Chttp2InsecureClientChannelFactory : public ClientChannelFactory { + public: + Subchannel* CreateSubchannel(const grpc_channel_args* args) override { + grpc_channel_args* new_args = + grpc_default_authority_add_if_not_present(args); + grpc_connector* connector = grpc_chttp2_connector_create(); + Subchannel* s = Subchannel::Create(connector, new_args); + grpc_connector_unref(connector); + grpc_channel_args_destroy(new_args); + return s; } - // Add channel arg containing the server URI. - grpc_core::UniquePtr canonical_target = - grpc_core::ResolverRegistry::AddDefaultPrefixIfNeeded(target); - grpc_arg arg = grpc_channel_arg_string_create( - const_cast(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); - grpc_channel* channel = - grpc_channel_create(target, new_args, GRPC_CLIENT_CHANNEL, nullptr); - grpc_channel_args_destroy(new_args); - return channel; + + grpc_channel* CreateChannel(const char* target, + const grpc_channel_args* args) override { + if (target == nullptr) { + gpr_log(GPR_ERROR, "cannot create channel with NULL target name"); + return nullptr; + } + // Add channel arg containing the server URI. + UniquePtr canonical_target = + ResolverRegistry::AddDefaultPrefixIfNeeded(target); + grpc_arg arg = grpc_channel_arg_string_create( + const_cast(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); + grpc_channel* channel = + grpc_channel_create(target, new_args, GRPC_CLIENT_CHANNEL, nullptr); + grpc_channel_args_destroy(new_args); + return channel; + } +}; + +} // namespace grpc_core + +namespace { + +grpc_core::Chttp2InsecureClientChannelFactory* g_factory; +gpr_once g_factory_once = GPR_ONCE_INIT; + +void FactoryInit() { + g_factory = grpc_core::New(); } -static const grpc_client_channel_factory_vtable client_channel_factory_vtable = - {client_channel_factory_ref, client_channel_factory_unref, - client_channel_factory_create_subchannel, - client_channel_factory_create_channel}; - -static grpc_client_channel_factory client_channel_factory = { - &client_channel_factory_vtable}; +} // namespace /* Create a client channel: Asynchronously: - resolve target @@ -93,16 +94,13 @@ grpc_channel* grpc_insecure_channel_create(const char* target, (target, args, reserved)); GPR_ASSERT(reserved == nullptr); // Add channel arg containing the client channel factory. - grpc_arg arg = - grpc_client_channel_factory_create_channel_arg(&client_channel_factory); + gpr_once_init(&g_factory_once, FactoryInit); + grpc_arg arg = grpc_core::ClientChannelFactory::CreateChannelArg(g_factory); grpc_channel_args* new_args = grpc_channel_args_copy_and_add(args, &arg, 1); // Create channel. - grpc_channel* channel = client_channel_factory_create_channel( - &client_channel_factory, target, GRPC_CLIENT_CHANNEL_TYPE_REGULAR, - new_args); + grpc_channel* channel = g_factory->CreateChannel(target, new_args); // Clean up. grpc_channel_args_destroy(new_args); - return channel != nullptr ? channel : grpc_lame_client_channel_create( target, GRPC_STATUS_INTERNAL, 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 e73eee43537..bc38ff25c79 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 @@ -40,158 +40,148 @@ #include "src/core/lib/surface/channel.h" #include "src/core/lib/uri/uri_parser.h" -static void client_channel_factory_ref( - grpc_client_channel_factory* cc_factory) {} +namespace grpc_core { -static void client_channel_factory_unref( - grpc_client_channel_factory* cc_factory) {} - -static grpc_subchannel_args* get_secure_naming_subchannel_args( - const grpc_subchannel_args* args) { - grpc_channel_credentials* channel_credentials = - grpc_channel_credentials_find_in_args(args->args); - if (channel_credentials == nullptr) { - gpr_log(GPR_ERROR, - "Can't create subchannel: channel credentials missing for secure " - "channel."); - return nullptr; - } - // Make sure security connector does not already exist in args. - if (grpc_security_connector_find_in_args(args->args) != nullptr) { - gpr_log(GPR_ERROR, - "Can't create subchannel: security connector already present in " - "channel args."); - return nullptr; - } - // To which address are we connecting? By default, use the server URI. - const grpc_arg* server_uri_arg = - grpc_channel_args_find(args->args, GRPC_ARG_SERVER_URI); - const char* server_uri_str = grpc_channel_arg_get_string(server_uri_arg); - GPR_ASSERT(server_uri_str != nullptr); - grpc_uri* server_uri = - grpc_uri_parse(server_uri_str, true /* supress errors */); - GPR_ASSERT(server_uri != nullptr); - const grpc_core::TargetAuthorityTable* target_authority_table = - grpc_core::FindTargetAuthorityTableInArgs(args->args); - grpc_core::UniquePtr authority; - if (target_authority_table != nullptr) { - // Find the authority for the target. - const char* target_uri_str = - grpc_get_subchannel_address_uri_arg(args->args); - grpc_uri* target_uri = - grpc_uri_parse(target_uri_str, false /* suppress errors */); - GPR_ASSERT(target_uri != nullptr); - if (target_uri->path[0] != '\0') { // "path" may be empty - const grpc_slice key = grpc_slice_from_static_string( - target_uri->path[0] == '/' ? target_uri->path + 1 : target_uri->path); - const grpc_core::UniquePtr* value = - target_authority_table->Get(key); - if (value != nullptr) authority.reset(gpr_strdup(value->get())); - grpc_slice_unref_internal(key); +class Chttp2SecureClientChannelFactory : public ClientChannelFactory { + public: + Subchannel* CreateSubchannel(const grpc_channel_args* args) override { + grpc_channel_args* new_args = GetSecureNamingChannelArgs(args); + if (new_args == nullptr) { + gpr_log(GPR_ERROR, + "Failed to create channel args during subchannel creation."); + return nullptr; } - grpc_uri_destroy(target_uri); + grpc_connector* connector = grpc_chttp2_connector_create(); + Subchannel* s = Subchannel::Create(connector, new_args); + grpc_connector_unref(connector); + grpc_channel_args_destroy(new_args); + return s; } - // If the authority hasn't already been set (either because no target - // 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 = - grpc_core::ResolverRegistry::GetDefaultAuthority(server_uri_str); + + grpc_channel* CreateChannel(const char* target, + const grpc_channel_args* args) override { + if (target == nullptr) { + gpr_log(GPR_ERROR, "cannot create channel with NULL target name"); + return nullptr; + } + // Add channel arg containing the server URI. + UniquePtr canonical_target = + ResolverRegistry::AddDefaultPrefixIfNeeded(target); + grpc_arg arg = grpc_channel_arg_string_create( + const_cast(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); + grpc_channel* channel = + grpc_channel_create(target, new_args, GRPC_CLIENT_CHANNEL, nullptr); + grpc_channel_args_destroy(new_args); + return channel; } - 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(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_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()); + + private: + static grpc_channel_args* GetSecureNamingChannelArgs( + const grpc_channel_args* args) { + grpc_channel_credentials* channel_credentials = + grpc_channel_credentials_find_in_args(args); + if (channel_credentials == nullptr) { + gpr_log(GPR_ERROR, + "Can't create subchannel: channel credentials missing for secure " + "channel."); + return nullptr; + } + // Make sure security connector does not already exist in args. + if (grpc_security_connector_find_in_args(args) != nullptr) { + gpr_log(GPR_ERROR, + "Can't create subchannel: security connector already present in " + "channel args."); + return nullptr; + } + // To which address are we connecting? By default, use the server URI. + 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); + grpc_uri* server_uri = + grpc_uri_parse(server_uri_str, true /* suppress errors */); + GPR_ASSERT(server_uri != nullptr); + const TargetAuthorityTable* target_authority_table = + FindTargetAuthorityTableInArgs(args); + UniquePtr authority; + if (target_authority_table != nullptr) { + // Find the authority for the target. + const char* target_uri_str = + Subchannel::GetUriFromSubchannelAddressArg(args); + grpc_uri* target_uri = + grpc_uri_parse(target_uri_str, false /* suppress errors */); + GPR_ASSERT(target_uri != nullptr); + if (target_uri->path[0] != '\0') { // "path" may be empty + const grpc_slice key = grpc_slice_from_static_string( + target_uri->path[0] == '/' ? target_uri->path + 1 + : target_uri->path); + const UniquePtr* value = target_authority_table->Get(key); + if (value != nullptr) authority.reset(gpr_strdup(value->get())); + grpc_slice_unref_internal(key); + } + grpc_uri_destroy(target_uri); + } + // If the authority hasn't already been set (either because no target + // 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 = ResolverRegistry::GetDefaultAuthority(server_uri_str); + } + grpc_arg args_to_add[2]; + size_t num_args_to_add = 0; + if (grpc_channel_args_find(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(GRPC_ARG_DEFAULT_AUTHORITY), authority.get()); + } + grpc_channel_args* args_with_authority = + grpc_channel_args_copy_and_add(args, args_to_add, num_args_to_add); + grpc_uri_destroy(server_uri); + // Create the security connector using the credentials and target name. + grpc_channel_args* new_args_from_connector = nullptr; + RefCountedPtr + subchannel_security_connector = + channel_credentials->create_security_connector( + /*call_creds=*/nullptr, authority.get(), args_with_authority, + &new_args_from_connector); + if (subchannel_security_connector == nullptr) { + 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.get()); + grpc_channel_args* new_args = grpc_channel_args_copy_and_add( + new_args_from_connector != nullptr ? new_args_from_connector + : args_with_authority, + &new_security_connector_arg, 1); + subchannel_security_connector.reset(DEBUG_LOCATION, "lb_channel_create"); + if (new_args_from_connector != nullptr) { + grpc_channel_args_destroy(new_args_from_connector); + } grpc_channel_args_destroy(args_with_authority); - return nullptr; + return new_args; } - 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_with_authority, - &new_security_connector_arg, 1); +} // namespace grpc_core - 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(gpr_malloc(sizeof(*final_sc_args))); - memcpy(final_sc_args, args, sizeof(*args)); - final_sc_args->args = new_args; - return final_sc_args; +namespace { + +grpc_core::Chttp2SecureClientChannelFactory* g_factory; +gpr_once g_factory_once = GPR_ONCE_INIT; + +void FactoryInit() { + g_factory = grpc_core::New(); } -static grpc_subchannel* client_channel_factory_create_subchannel( - grpc_client_channel_factory* cc_factory, const grpc_subchannel_args* args) { - grpc_subchannel_args* subchannel_args = - get_secure_naming_subchannel_args(args); - if (subchannel_args == nullptr) { - gpr_log( - GPR_ERROR, - "Failed to create subchannel arguments during subchannel creation."); - return nullptr; - } - grpc_connector* connector = grpc_chttp2_connector_create(); - grpc_subchannel* s = grpc_subchannel_create(connector, subchannel_args); - grpc_connector_unref(connector); - grpc_channel_args_destroy( - const_cast(subchannel_args->args)); - gpr_free(subchannel_args); - return s; -} - -static grpc_channel* client_channel_factory_create_channel( - grpc_client_channel_factory* cc_factory, const char* target, - grpc_client_channel_type type, const grpc_channel_args* args) { - if (target == nullptr) { - gpr_log(GPR_ERROR, "cannot create channel with NULL target name"); - return nullptr; - } - // Add channel arg containing the server URI. - grpc_core::UniquePtr canonical_target = - grpc_core::ResolverRegistry::AddDefaultPrefixIfNeeded(target); - grpc_arg arg = grpc_channel_arg_string_create((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); - grpc_channel* channel = - grpc_channel_create(target, new_args, GRPC_CLIENT_CHANNEL, nullptr); - grpc_channel_args_destroy(new_args); - return channel; -} - -static const grpc_client_channel_factory_vtable client_channel_factory_vtable = - {client_channel_factory_ref, client_channel_factory_unref, - client_channel_factory_create_subchannel, - client_channel_factory_create_channel}; - -static grpc_client_channel_factory client_channel_factory = { - &client_channel_factory_vtable}; +} // namespace // Create a secure client channel: // Asynchronously: - resolve target @@ -211,15 +201,15 @@ grpc_channel* grpc_secure_channel_create(grpc_channel_credentials* creds, if (creds != nullptr) { // Add channel args containing the client channel factory and channel // credentials. + gpr_once_init(&g_factory_once, FactoryInit); grpc_arg args_to_add[] = { - grpc_client_channel_factory_create_channel_arg(&client_channel_factory), + grpc_core::ClientChannelFactory::CreateChannelArg(g_factory), grpc_channel_credentials_to_arg(creds)}; grpc_channel_args* new_args = grpc_channel_args_copy_and_add( args, args_to_add, GPR_ARRAY_SIZE(args_to_add)); + new_args = creds->update_arguments(new_args); // Create channel. - channel = client_channel_factory_create_channel( - &client_channel_factory, target, GRPC_CLIENT_CHANNEL_TYPE_REGULAR, - new_args); + channel = g_factory->CreateChannel(target, new_args); // Clean up. grpc_channel_args_destroy(new_args); } diff --git a/src/core/ext/transport/chttp2/server/chttp2_server.cc b/src/core/ext/transport/chttp2/server/chttp2_server.cc index 33d2b22aa58..040ea2044b1 100644 --- a/src/core/ext/transport/chttp2/server/chttp2_server.cc +++ b/src/core/ext/transport/chttp2/server/chttp2_server.cc @@ -54,7 +54,7 @@ typedef struct { bool shutdown; grpc_closure tcp_server_shutdown_complete; grpc_closure* server_destroy_listener_done; - grpc_handshake_manager* pending_handshake_mgrs; + grpc_core::HandshakeManager* pending_handshake_mgrs; grpc_core::RefCountedPtr channelz_listen_socket; } server_state; @@ -64,7 +64,7 @@ typedef struct { server_state* svr_state; grpc_pollset* accepting_pollset; grpc_tcp_server_acceptor* acceptor; - grpc_handshake_manager* handshake_mgr; + grpc_core::RefCountedPtr handshake_mgr; // State for enforcing handshake timeout on receiving HTTP/2 settings. grpc_chttp2_transport* transport; grpc_millis deadline; @@ -112,7 +112,7 @@ static void on_receive_settings(void* arg, grpc_error* error) { } static void on_handshake_done(void* arg, grpc_error* error) { - grpc_handshaker_args* args = static_cast(arg); + auto* args = static_cast(arg); server_connection_state* connection_state = static_cast(args->user_data); gpr_mu_lock(&connection_state->svr_state->mu); @@ -149,7 +149,7 @@ static void on_handshake_done(void* arg, grpc_error* error) { grpc_server_setup_transport( connection_state->svr_state->server, transport, connection_state->accepting_pollset, args->args, - grpc_chttp2_transport_get_socket_uuid(transport), resource_user); + grpc_chttp2_transport_get_socket_node(transport), resource_user); // Use notify_on_receive_settings callback to enforce the // handshake deadline. connection_state->transport = @@ -175,11 +175,10 @@ static void on_handshake_done(void* arg, grpc_error* error) { } } } - grpc_handshake_manager_pending_list_remove( - &connection_state->svr_state->pending_handshake_mgrs, - connection_state->handshake_mgr); + connection_state->handshake_mgr->RemoveFromPendingMgrList( + &connection_state->svr_state->pending_handshake_mgrs); gpr_mu_unlock(&connection_state->svr_state->mu); - grpc_handshake_manager_destroy(connection_state->handshake_mgr); + connection_state->handshake_mgr.reset(); gpr_free(connection_state->acceptor); grpc_tcp_server_unref(connection_state->svr_state->tcp_server); server_connection_state_unref(connection_state); @@ -211,9 +210,8 @@ static void on_accept(void* arg, grpc_endpoint* tcp, gpr_free(acceptor); return; } - grpc_handshake_manager* handshake_mgr = grpc_handshake_manager_create(); - grpc_handshake_manager_pending_list_add(&state->pending_handshake_mgrs, - handshake_mgr); + auto handshake_mgr = grpc_core::MakeRefCounted(); + handshake_mgr->AddToPendingMgrList(&state->pending_handshake_mgrs); grpc_tcp_server_ref(state->tcp_server); gpr_mu_unlock(&state->mu); server_connection_state* connection_state = @@ -227,19 +225,19 @@ static void on_accept(void* arg, grpc_endpoint* tcp, connection_state->interested_parties = grpc_pollset_set_create(); grpc_pollset_set_add_pollset(connection_state->interested_parties, connection_state->accepting_pollset); - grpc_handshakers_add(HANDSHAKER_SERVER, state->args, - connection_state->interested_parties, - connection_state->handshake_mgr); + grpc_core::HandshakerRegistry::AddHandshakers( + grpc_core::HANDSHAKER_SERVER, state->args, + connection_state->interested_parties, + connection_state->handshake_mgr.get()); const grpc_arg* timeout_arg = grpc_channel_args_find(state->args, GRPC_ARG_SERVER_HANDSHAKE_TIMEOUT_MS); connection_state->deadline = grpc_core::ExecCtx::Get()->Now() + grpc_channel_arg_get_integer(timeout_arg, {120 * GPR_MS_PER_SEC, 1, INT_MAX}); - grpc_handshake_manager_do_handshake(connection_state->handshake_mgr, tcp, - state->args, connection_state->deadline, - acceptor, on_handshake_done, - connection_state); + connection_state->handshake_mgr->DoHandshake( + tcp, state->args, connection_state->deadline, acceptor, on_handshake_done, + connection_state); } /* Server callback: start listening on our ports */ @@ -260,8 +258,9 @@ static void tcp_server_shutdown_complete(void* arg, grpc_error* error) { gpr_mu_lock(&state->mu); grpc_closure* destroy_done = state->server_destroy_listener_done; GPR_ASSERT(state->shutdown); - grpc_handshake_manager_pending_list_shutdown_all( - state->pending_handshake_mgrs, GRPC_ERROR_REF(error)); + if (state->pending_handshake_mgrs != nullptr) { + state->pending_handshake_mgrs->ShutdownAllPending(GRPC_ERROR_REF(error)); + } state->channelz_listen_socket.reset(); gpr_mu_unlock(&state->mu); // Flush queued work before destroying handshaker factory, since that diff --git a/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc b/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc index b9024a87e24..c29c1e58cd9 100644 --- a/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc +++ b/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc @@ -61,7 +61,7 @@ void grpc_server_add_insecure_channel_from_fd(grpc_server* server, grpc_endpoint_add_to_pollset(server_endpoint, pollsets[i]); } - grpc_server_setup_transport(server, transport, nullptr, server_args, 0); + grpc_server_setup_transport(server, transport, nullptr, server_args, nullptr); grpc_chttp2_transport_start_reading(transport, nullptr, nullptr); } diff --git a/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.cc b/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.cc index 6689a17da63..98fdb620704 100644 --- a/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.cc +++ b/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.cc @@ -31,6 +31,7 @@ #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/handshaker.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/security/context/security_context.h" #include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/surface/api_trace.h" @@ -40,9 +41,8 @@ int grpc_server_add_secure_http2_port(grpc_server* server, const char* addr, grpc_server_credentials* creds) { grpc_core::ExecCtx exec_ctx; grpc_error* err = GRPC_ERROR_NONE; - grpc_server_security_connector* sc = nullptr; + grpc_core::RefCountedPtr sc; int port_num = 0; - grpc_security_status status; grpc_channel_args* args = nullptr; GRPC_API_TRACE( "grpc_server_add_secure_http2_port(" @@ -54,30 +54,27 @@ int grpc_server_add_secure_http2_port(grpc_server* server, const char* addr, "No credentials specified for secure server port (creds==NULL)"); goto done; } - status = grpc_server_credentials_create_security_connector(creds, &sc); - if (status != GRPC_SECURITY_OK) { + sc = creds->create_security_connector(); + if (sc == nullptr) { char* msg; gpr_asprintf(&msg, "Unable to create secure server with credentials of type %s.", - creds->type); - err = grpc_error_set_int(GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg), - GRPC_ERROR_INT_SECURITY_STATUS, status); + creds->type()); + err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); gpr_free(msg); goto done; } // Create channel args. grpc_arg args_to_add[2]; args_to_add[0] = grpc_server_credentials_to_arg(creds); - args_to_add[1] = grpc_security_connector_to_arg(&sc->base); + args_to_add[1] = grpc_security_connector_to_arg(sc.get()); args = grpc_channel_args_copy_and_add(grpc_server_get_channel_args(server), args_to_add, GPR_ARRAY_SIZE(args_to_add)); // Add server port. err = grpc_chttp2_server_add_port(server, addr, args, &port_num); done: - if (sc != nullptr) { - GRPC_SECURITY_CONNECTOR_UNREF(&sc->base, "server"); - } + sc.reset(DEBUG_LOCATION, "server"); if (err != GRPC_ERROR_NONE) { const char* msg = grpc_error_string(err); diff --git a/src/core/ext/transport/chttp2/transport/bin_decoder.cc b/src/core/ext/transport/chttp2/transport/bin_decoder.cc index b660a456521..249035d7e89 100644 --- a/src/core/ext/transport/chttp2/transport/bin_decoder.cc +++ b/src/core/ext/transport/chttp2/transport/bin_decoder.cc @@ -51,7 +51,7 @@ static uint8_t decode_table[] = { static const uint8_t tail_xtra[4] = {0, 0, 1, 2}; -static bool input_is_valid(uint8_t* input_ptr, size_t length) { +static bool input_is_valid(const uint8_t* input_ptr, size_t length) { size_t i; for (i = 0; i < length; ++i) { @@ -158,7 +158,7 @@ bool grpc_base64_decode_partial(struct grpc_base64_decode_context* ctx) { return true; } -grpc_slice grpc_chttp2_base64_decode(grpc_slice input) { +grpc_slice grpc_chttp2_base64_decode(const grpc_slice& input) { size_t input_length = GRPC_SLICE_LENGTH(input); size_t output_length = input_length / 4 * 3; struct grpc_base64_decode_context ctx; @@ -174,7 +174,7 @@ grpc_slice grpc_chttp2_base64_decode(grpc_slice input) { } if (input_length > 0) { - uint8_t* input_end = GRPC_SLICE_END_PTR(input); + const uint8_t* input_end = GRPC_SLICE_END_PTR(input); if (*(--input_end) == '=') { output_length--; if (*(--input_end) == '=') { @@ -202,7 +202,7 @@ grpc_slice grpc_chttp2_base64_decode(grpc_slice input) { return output; } -grpc_slice grpc_chttp2_base64_decode_with_length(grpc_slice input, +grpc_slice grpc_chttp2_base64_decode_with_length(const grpc_slice& input, size_t output_length) { size_t input_length = GRPC_SLICE_LENGTH(input); grpc_slice output = GRPC_SLICE_MALLOC(output_length); diff --git a/src/core/ext/transport/chttp2/transport/bin_decoder.h b/src/core/ext/transport/chttp2/transport/bin_decoder.h index 8a4d4a71790..1cbca033a1f 100644 --- a/src/core/ext/transport/chttp2/transport/bin_decoder.h +++ b/src/core/ext/transport/chttp2/transport/bin_decoder.h @@ -26,8 +26,8 @@ struct grpc_base64_decode_context { /* input/output: */ - uint8_t* input_cur; - uint8_t* input_end; + const uint8_t* input_cur; + const uint8_t* input_end; uint8_t* output_cur; uint8_t* output_end; /* Indicate if the decoder should handle the tail of input data*/ @@ -42,12 +42,12 @@ bool grpc_base64_decode_partial(struct grpc_base64_decode_context* ctx); /* base64 decode a slice with pad chars. Returns a new slice, does not take ownership of the input. Returns an empty slice if decoding is failed. */ -grpc_slice grpc_chttp2_base64_decode(grpc_slice input); +grpc_slice grpc_chttp2_base64_decode(const grpc_slice& input); /* base64 decode a slice without pad chars, data length is needed. Returns a new slice, does not take ownership of the input. Returns an empty slice if decoding is failed. */ -grpc_slice grpc_chttp2_base64_decode_with_length(grpc_slice input, +grpc_slice grpc_chttp2_base64_decode_with_length(const grpc_slice& input, size_t output_length); /* Infer the length of decoded data from encoded data. */ diff --git a/src/core/ext/transport/chttp2/transport/bin_encoder.cc b/src/core/ext/transport/chttp2/transport/bin_encoder.cc index bad29e3421c..c816aba991f 100644 --- a/src/core/ext/transport/chttp2/transport/bin_encoder.cc +++ b/src/core/ext/transport/chttp2/transport/bin_encoder.cc @@ -48,13 +48,13 @@ static const b64_huff_sym huff_alphabet[64] = { static const uint8_t tail_xtra[3] = {0, 2, 3}; -grpc_slice grpc_chttp2_base64_encode(grpc_slice input) { +grpc_slice grpc_chttp2_base64_encode(const grpc_slice& input) { size_t input_length = GRPC_SLICE_LENGTH(input); size_t input_triplets = input_length / 3; size_t tail_case = input_length % 3; size_t output_length = input_triplets * 4 + tail_xtra[tail_case]; grpc_slice output = GRPC_SLICE_MALLOC(output_length); - uint8_t* in = GRPC_SLICE_START_PTR(input); + const uint8_t* in = GRPC_SLICE_START_PTR(input); char* out = reinterpret_cast GRPC_SLICE_START_PTR(output); size_t i; @@ -92,9 +92,9 @@ grpc_slice grpc_chttp2_base64_encode(grpc_slice input) { return output; } -grpc_slice grpc_chttp2_huffman_compress(grpc_slice input) { +grpc_slice grpc_chttp2_huffman_compress(const grpc_slice& input) { size_t nbits; - uint8_t* in; + const uint8_t* in; uint8_t* out; grpc_slice output; uint32_t temp = 0; @@ -166,7 +166,8 @@ static void enc_add1(huff_out* out, uint8_t a) { enc_flush_some(out); } -grpc_slice grpc_chttp2_base64_encode_and_huffman_compress(grpc_slice input) { +grpc_slice grpc_chttp2_base64_encode_and_huffman_compress( + const grpc_slice& input) { size_t input_length = GRPC_SLICE_LENGTH(input); size_t input_triplets = input_length / 3; size_t tail_case = input_length % 3; @@ -174,7 +175,7 @@ grpc_slice grpc_chttp2_base64_encode_and_huffman_compress(grpc_slice input) { size_t max_output_bits = 11 * output_syms; size_t max_output_length = max_output_bits / 8 + (max_output_bits % 8 != 0); grpc_slice output = GRPC_SLICE_MALLOC(max_output_length); - uint8_t* in = GRPC_SLICE_START_PTR(input); + const uint8_t* in = GRPC_SLICE_START_PTR(input); uint8_t* start_out = GRPC_SLICE_START_PTR(output); huff_out out; size_t i; diff --git a/src/core/ext/transport/chttp2/transport/bin_encoder.h b/src/core/ext/transport/chttp2/transport/bin_encoder.h index 1b7bb1574af..4f7ee67bd31 100644 --- a/src/core/ext/transport/chttp2/transport/bin_encoder.h +++ b/src/core/ext/transport/chttp2/transport/bin_encoder.h @@ -25,17 +25,18 @@ /* base64 encode a slice. Returns a new slice, does not take ownership of the input */ -grpc_slice grpc_chttp2_base64_encode(grpc_slice input); +grpc_slice grpc_chttp2_base64_encode(const grpc_slice& input); /* Compress a slice with the static huffman encoder detailed in the hpack standard. Returns a new slice, does not take ownership of the input */ -grpc_slice grpc_chttp2_huffman_compress(grpc_slice input); +grpc_slice grpc_chttp2_huffman_compress(const grpc_slice& input); /* equivalent to: grpc_slice x = grpc_chttp2_base64_encode(input); grpc_slice y = grpc_chttp2_huffman_compress(x); grpc_slice_unref_internal( x); return y; */ -grpc_slice grpc_chttp2_base64_encode_and_huffman_compress(grpc_slice input); +grpc_slice grpc_chttp2_base64_encode_and_huffman_compress( + const grpc_slice& input); #endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_BIN_ENCODER_H */ diff --git a/src/core/ext/transport/chttp2/transport/chttp2_plugin.cc b/src/core/ext/transport/chttp2/transport/chttp2_plugin.cc index 531ea73e9e6..4c929d00ec9 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_plugin.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_plugin.cc @@ -20,16 +20,15 @@ #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/debug/trace.h" -#include "src/core/lib/gpr/env.h" +#include "src/core/lib/gprpp/global_config.h" #include "src/core/lib/transport/metadata.h" +GPR_GLOBAL_CONFIG_DEFINE_BOOL(grpc_experimental_disable_flow_control, false, + "Disable flow control"); + void grpc_chttp2_plugin_init(void) { - g_flow_control_enabled = true; - char* env_variable = gpr_getenv("GRPC_EXPERIMENTAL_DISABLE_FLOW_CONTROL"); - if (env_variable != nullptr) { - g_flow_control_enabled = false; - gpr_free(env_variable); - } + g_flow_control_enabled = + !GPR_GLOBAL_CONFIG_GET(grpc_experimental_disable_flow_control); } void grpc_chttp2_plugin_shutdown(void) {} diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index 978ecd59e4c..4a04b9f1939 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -1,6 +1,6 @@ /* * - * Copyright 2015 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. @@ -31,6 +31,7 @@ #include #include +#include "src/core/ext/transport/chttp2/transport/context_list.h" #include "src/core/ext/transport/chttp2/transport/frame_data.h" #include "src/core/ext/transport/chttp2/transport/internal.h" #include "src/core/ext/transport/chttp2/transport/varint.h" @@ -42,6 +43,7 @@ #include "src/core/lib/gprpp/memory.h" #include "src/core/lib/http/parser.h" #include "src/core/lib/iomgr/executor.h" +#include "src/core/lib/iomgr/iomgr.h" #include "src/core/lib/iomgr/timer.h" #include "src/core/lib/profiling/timers.h" #include "src/core/lib/slice/slice_internal.h" @@ -117,7 +119,7 @@ static void maybe_start_some_streams(grpc_chttp2_transport* t); static void connectivity_state_set(grpc_chttp2_transport* t, grpc_connectivity_state state, - grpc_error* error, const char* reason); + const char* reason); static void benign_reclaimer_locked(void* t, grpc_error* error); static void destructive_reclaimer_locked(void* t, grpc_error* error); @@ -154,6 +156,7 @@ bool g_flow_control_enabled = true; /******************************************************************************* * CONSTRUCTION/DESTRUCTION/REFCOUNTING */ + grpc_chttp2_transport::~grpc_chttp2_transport() { size_t i; @@ -168,6 +171,14 @@ grpc_chttp2_transport::~grpc_chttp2_transport() { grpc_slice_buffer_destroy_internal(&outbuf); grpc_chttp2_hpack_compressor_destroy(&hpack_compressor); + grpc_error* error = + GRPC_ERROR_CREATE_FROM_STATIC_STRING("Transport destroyed"); + // ContextList::Execute follows semantics of a callback function and does not + // take a ref on error + grpc_core::ContextList::Execute(cl, nullptr, error); + GRPC_ERROR_UNREF(error); + cl = nullptr; + grpc_slice_buffer_destroy_internal(&read_buffer); grpc_chttp2_hpack_parser_destroy(&hpack_parser); grpc_chttp2_goaway_parser_destroy(&goaway_parser); @@ -202,38 +213,6 @@ grpc_chttp2_transport::~grpc_chttp2_transport() { gpr_free(peer_string); } -#ifndef NDEBUG -void grpc_chttp2_unref_transport(grpc_chttp2_transport* t, const char* reason, - const char* file, int line) { - if (grpc_trace_chttp2_refcount.enabled()) { - gpr_atm val = gpr_atm_no_barrier_load(&t->refs.count); - gpr_log(GPR_DEBUG, "chttp2:unref:%p %" PRIdPTR "->%" PRIdPTR " %s [%s:%d]", - t, val, val - 1, reason, file, line); - } - if (!gpr_unref(&t->refs)) return; - t->~grpc_chttp2_transport(); - gpr_free(t); -} - -void grpc_chttp2_ref_transport(grpc_chttp2_transport* t, const char* reason, - const char* file, int line) { - if (grpc_trace_chttp2_refcount.enabled()) { - gpr_atm val = gpr_atm_no_barrier_load(&t->refs.count); - gpr_log(GPR_DEBUG, "chttp2: ref:%p %" PRIdPTR "->%" PRIdPTR " %s [%s:%d]", - t, val, val + 1, reason, file, line); - } - gpr_ref(&t->refs); -} -#else -void grpc_chttp2_unref_transport(grpc_chttp2_transport* t) { - if (!gpr_unref(&t->refs)) return; - t->~grpc_chttp2_transport(); - gpr_free(t); -} - -void grpc_chttp2_ref_transport(grpc_chttp2_transport* t) { gpr_ref(&t->refs); } -#endif - static const grpc_transport_vtable* get_vtable(void); /* Returns whether bdp is enabled */ @@ -485,7 +464,8 @@ static void init_keepalive_pings_if_enabled(grpc_chttp2_transport* t) { grpc_chttp2_transport::grpc_chttp2_transport( const grpc_channel_args* channel_args, grpc_endpoint* ep, bool is_client, grpc_resource_user* resource_user) - : ep(ep), + : refs(1, &grpc_trace_chttp2_refcount), + ep(ep), peer_string(grpc_endpoint_get_peer(ep)), resource_user(resource_user), combiner(grpc_combiner_create()), @@ -495,8 +475,6 @@ grpc_chttp2_transport::grpc_chttp2_transport( GPR_ASSERT(strlen(GRPC_CHTTP2_CLIENT_CONNECT_STRING) == GRPC_CHTTP2_CLIENT_CONNECT_STRLEN); base.vtable = get_vtable(); - /* one ref is for destroy */ - gpr_ref_init(&refs, 1); /* 8 is a random stab in the dark as to a good initial size: it's small enough that it shouldn't waste memory for infrequently used connections, yet large enough that the exponential growth should happen nicely when it's @@ -614,8 +592,7 @@ static void close_transport_locked(grpc_chttp2_transport* t, } GPR_ASSERT(error != GRPC_ERROR_NONE); t->closed_with_error = GRPC_ERROR_REF(error); - connectivity_state_set(t, GRPC_CHANNEL_SHUTDOWN, GRPC_ERROR_REF(error), - "close_transport"); + connectivity_state_set(t, GRPC_CHANNEL_SHUTDOWN, "close_transport"); if (t->ping_state.is_delayed_ping_timer_set) { grpc_timer_cancel(&t->ping_state.delayed_ping_timer); } @@ -667,17 +644,23 @@ void grpc_chttp2_stream_unref(grpc_chttp2_stream* s) { } #endif -grpc_chttp2_stream::grpc_chttp2_stream(grpc_chttp2_transport* t, - grpc_stream_refcount* refcount, - const void* server_data, - gpr_arena* arena) - : t(t), refcount(refcount), metadata_buffer{{arena}, {arena}} { +grpc_chttp2_stream::Reffer::Reffer(grpc_chttp2_stream* s) { /* We reserve one 'active stream' that's dropped when the stream is read-closed. The others are for Chttp2IncomingByteStreams that are actively reading */ - GRPC_CHTTP2_STREAM_REF(this, "chttp2"); - GRPC_CHTTP2_REF_TRANSPORT(t, "stream"); + GRPC_CHTTP2_STREAM_REF(s, "chttp2"); + GRPC_CHTTP2_REF_TRANSPORT(s->t, "stream"); +} +grpc_chttp2_stream::grpc_chttp2_stream(grpc_chttp2_transport* t, + grpc_stream_refcount* refcount, + const void* server_data, + grpc_core::Arena* arena) + : t(t), + refcount(refcount), + reffer(this), + metadata_buffer{grpc_chttp2_incoming_metadata_buffer(arena), + grpc_chttp2_incoming_metadata_buffer(arena)} { if (server_data) { id = static_cast((uintptr_t)server_data); *t->accepting_stream = this; @@ -696,11 +679,9 @@ grpc_chttp2_stream::grpc_chttp2_stream(grpc_chttp2_transport* t, grpc_slice_buffer_init(&frame_storage); grpc_slice_buffer_init(&unprocessed_incoming_frames_buffer); grpc_slice_buffer_init(&flow_controlled_buffer); - grpc_slice_buffer_init(&compressed_data_buffer); - grpc_slice_buffer_init(&decompressed_data_buffer); GRPC_CLOSURE_INIT(&complete_fetch_locked, ::complete_fetch_locked, this, - grpc_schedule_on_exec_ctx); + grpc_combiner_scheduler(t->combiner)); GRPC_CLOSURE_INIT(&reset_byte_stream, ::reset_byte_stream, this, grpc_combiner_scheduler(t->combiner)); } @@ -721,8 +702,13 @@ grpc_chttp2_stream::~grpc_chttp2_stream() { grpc_slice_buffer_destroy_internal(&unprocessed_incoming_frames_buffer); grpc_slice_buffer_destroy_internal(&frame_storage); - grpc_slice_buffer_destroy_internal(&compressed_data_buffer); - grpc_slice_buffer_destroy_internal(&decompressed_data_buffer); + if (stream_compression_method != GRPC_STREAM_COMPRESSION_IDENTITY_COMPRESS) { + grpc_slice_buffer_destroy_internal(&compressed_data_buffer); + } + if (stream_decompression_method != + GRPC_STREAM_COMPRESSION_IDENTITY_DECOMPRESS) { + grpc_slice_buffer_destroy_internal(&decompressed_data_buffer); + } grpc_chttp2_list_remove_stalled_by_transport(t, this); grpc_chttp2_list_remove_stalled_by_stream(t, this); @@ -758,7 +744,7 @@ grpc_chttp2_stream::~grpc_chttp2_stream() { static int init_stream(grpc_transport* gt, grpc_stream* gs, grpc_stream_refcount* refcount, const void* server_data, - gpr_arena* arena) { + grpc_core::Arena* arena) { GPR_TIMER_SCOPE("init_stream", 0); grpc_chttp2_transport* t = reinterpret_cast(gt); new (gs) grpc_chttp2_stream(t, refcount, server_data, arena); @@ -776,12 +762,15 @@ static void destroy_stream(grpc_transport* gt, grpc_stream* gs, GPR_TIMER_SCOPE("destroy_stream", 0); grpc_chttp2_transport* t = reinterpret_cast(gt); grpc_chttp2_stream* s = reinterpret_cast(gs); - - if (s->stream_compression_ctx != nullptr) { + if (s->stream_compression_method != + GRPC_STREAM_COMPRESSION_IDENTITY_COMPRESS && + s->stream_compression_ctx != nullptr) { grpc_stream_compression_context_destroy(s->stream_compression_ctx); s->stream_compression_ctx = nullptr; } - if (s->stream_decompression_ctx != nullptr) { + if (s->stream_decompression_method != + GRPC_STREAM_COMPRESSION_IDENTITY_DECOMPRESS && + s->stream_decompression_ctx != nullptr) { grpc_stream_compression_context_destroy(s->stream_decompression_ctx); s->stream_decompression_ctx = nullptr; } @@ -846,10 +835,10 @@ static const char* write_state_name(grpc_chttp2_write_state st) { static void set_write_state(grpc_chttp2_transport* t, grpc_chttp2_write_state st, const char* reason) { - 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)); + GRPC_CHTTP2_IF_TRACING( + gpr_log(GPR_INFO, "W:%p %s [%s] state %s -> %s [%s]", t, + t->is_client ? "CLIENT" : "SERVER", t->peer_string, + write_state_name(t->write_state), write_state_name(st), reason)); t->write_state = st; /* If the state is being reset back to idle, it means a write was just * finished. Make sure all the run_after_write closures are scheduled. @@ -986,24 +975,28 @@ void grpc_chttp2_mark_stream_writable(grpc_chttp2_transport* t, static grpc_closure_scheduler* write_scheduler(grpc_chttp2_transport* t, bool early_results_scheduled, bool partial_write) { + // If we're already in a background poller, don't offload this to an executor + if (grpc_iomgr_is_any_background_poller_thread()) { + return grpc_schedule_on_exec_ctx; + } /* if it's not the first write in a batch, always offload to the executor: we'll probably end up queuing against the kernel anyway, so we'll likely get better latency overall if we switch writing work elsewhere and continue with application work above */ if (!t->is_first_write_in_batch) { - return grpc_executor_scheduler(GRPC_EXECUTOR_SHORT); + return grpc_core::Executor::Scheduler(grpc_core::ExecutorJobType::SHORT); } /* equivalently, if it's a partial write, we *know* we're going to be taking a thread jump to write it because of the above, may as well do so immediately */ if (partial_write) { - return grpc_executor_scheduler(GRPC_EXECUTOR_SHORT); + return grpc_core::Executor::Scheduler(grpc_core::ExecutorJobType::SHORT); } switch (t->opt_target) { case GRPC_CHTTP2_OPTIMIZE_FOR_THROUGHPUT: /* executor gives us the largest probability of being able to batch a * write with others on this transport */ - return grpc_executor_scheduler(GRPC_EXECUTOR_SHORT); + return grpc_core::Executor::Scheduler(grpc_core::ExecutorJobType::SHORT); case GRPC_CHTTP2_OPTIMIZE_FOR_LATENCY: return grpc_schedule_on_exec_ctx; } @@ -1065,11 +1058,13 @@ static void write_action_begin_locked(void* gt, grpc_error* error_ignored) { static void write_action(void* gt, grpc_error* error) { GPR_TIMER_SCOPE("write_action", 0); grpc_chttp2_transport* t = static_cast(gt); + void* cl = t->cl; + t->cl = nullptr; grpc_endpoint_write( t->ep, &t->outbuf, GRPC_CLOSURE_INIT(&t->write_action_end_locked, write_action_end_locked, t, grpc_combiner_scheduler(t->combiner)), - nullptr); + cl); } /* Callback from the grpc_endpoint after bytes have been written by calling @@ -1078,12 +1073,15 @@ static void write_action_end_locked(void* tp, grpc_error* error) { GPR_TIMER_SCOPE("terminate_writing_with_lock", 0); grpc_chttp2_transport* t = static_cast(tp); + bool closed = false; if (error != GRPC_ERROR_NONE) { close_transport_locked(t, GRPC_ERROR_REF(error)); + closed = true; } if (t->sent_goaway_state == GRPC_CHTTP2_GOAWAY_SEND_SCHEDULED) { t->sent_goaway_state = GRPC_CHTTP2_GOAWAY_SENT; + closed = true; if (grpc_chttp2_stream_map_size(&t->stream_map) == 0) { close_transport_locked( t, GRPC_ERROR_CREATE_FROM_STATIC_STRING("goaway sent")); @@ -1102,6 +1100,14 @@ static void write_action_end_locked(void* tp, grpc_error* error) { set_write_state(t, GRPC_CHTTP2_WRITE_STATE_WRITING, "continue writing"); t->is_first_write_in_batch = false; GRPC_CHTTP2_REF_TRANSPORT(t, "writing"); + // If the transport is closed, we will retry writing on the endpoint + // and next write may contain part of the currently serialized frames. + // So, we should only call the run_after_write callbacks when the next + // write finishes, or the callbacks will be invoked when the stream is + // closed. + if (!closed) { + GRPC_CLOSURE_LIST_SCHED(&t->run_after_write); + } GRPC_CLOSURE_RUN( GRPC_CLOSURE_INIT(&t->write_action_begin_locked, write_action_begin_locked, t, @@ -1134,20 +1140,23 @@ static void queue_setting_update(grpc_chttp2_transport* t, void grpc_chttp2_add_incoming_goaway(grpc_chttp2_transport* t, uint32_t goaway_error, - grpc_slice goaway_text) { - // GRPC_CHTTP2_IF_TRACING( - // gpr_log(GPR_INFO, "got goaway [%d]: %s", goaway_error, msg)); - + const grpc_slice& goaway_text) { // Discard the error from a previous goaway frame (if any) if (t->goaway_error != GRPC_ERROR_NONE) { GRPC_ERROR_UNREF(t->goaway_error); } t->goaway_error = grpc_error_set_str( grpc_error_set_int( - GRPC_ERROR_CREATE_FROM_STATIC_STRING("GOAWAY received"), - GRPC_ERROR_INT_HTTP2_ERROR, static_cast(goaway_error)), + grpc_error_set_int( + GRPC_ERROR_CREATE_FROM_STATIC_STRING("GOAWAY received"), + GRPC_ERROR_INT_HTTP2_ERROR, static_cast(goaway_error)), + GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE), GRPC_ERROR_STR_RAW_BYTES, goaway_text); + /* We want to log this irrespective of whether http tracing is enabled */ + gpr_log(GPR_INFO, "%s: Got goaway [%d] err=%s", t->peer_string, goaway_error, + grpc_error_string(t->goaway_error)); + /* When a client receives a GOAWAY with error code ENHANCE_YOUR_CALM and debug * data equal to "too_many_pings", it should log the occurrence at a log level * that is enabled by default and double the configured KEEPALIVE_TIME used @@ -1168,8 +1177,7 @@ void grpc_chttp2_add_incoming_goaway(grpc_chttp2_transport* t, /* lie: use transient failure from the transport to indicate goaway has been * received */ - connectivity_state_set(t, GRPC_CHANNEL_TRANSIENT_FAILURE, - GRPC_ERROR_REF(t->goaway_error), "got_goaway"); + connectivity_state_set(t, GRPC_CHANNEL_TRANSIENT_FAILURE, "got_goaway"); } static void maybe_start_some_streams(grpc_chttp2_transport* t) { @@ -1191,10 +1199,8 @@ static void maybe_start_some_streams(grpc_chttp2_transport* t) { t->next_stream_id += 2; if (t->next_stream_id >= MAX_CLIENT_STREAM_ID) { - connectivity_state_set( - t, GRPC_CHANNEL_TRANSIENT_FAILURE, - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Stream IDs exhausted"), - "no_more_stream_ids"); + connectivity_state_set(t, GRPC_CHANNEL_TRANSIENT_FAILURE, + "no_more_stream_ids"); } grpc_chttp2_stream_map_add(&t->stream_map, s->id, s); @@ -1243,7 +1249,7 @@ void grpc_chttp2_complete_closure_step(grpc_chttp2_transport* t, return; } closure->next_data.scratch -= CLOSURE_BARRIER_FIRST_REF_BIT; - if (grpc_http_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_http_trace)) { const char* errstr = grpc_error_string(error); gpr_log( GPR_INFO, @@ -1270,7 +1276,9 @@ void grpc_chttp2_complete_closure_step(grpc_chttp2_transport* t, if (closure->next_data.scratch < CLOSURE_BARRIER_FIRST_REF_BIT) { if ((t->write_state == GRPC_CHTTP2_WRITE_STATE_IDLE) || !(closure->next_data.scratch & CLOSURE_BARRIER_MAY_COVER_WRITE)) { - GRPC_CLOSURE_RUN(closure, closure->error_data.error); + // Using GRPC_CLOSURE_SCHED instead of GRPC_CLOSURE_RUN to avoid running + // closures earlier than when it is safe to do so. + GRPC_CLOSURE_SCHED(closure, closure->error_data.error); } else { grpc_closure_list_append(&t->run_after_write, closure, closure->error_data.error); @@ -1280,8 +1288,8 @@ void grpc_chttp2_complete_closure_step(grpc_chttp2_transport* t, static bool contains_non_ok_status(grpc_metadata_batch* batch) { if (batch->idx.named.grpc_status != nullptr) { - return !grpc_mdelem_eq(batch->idx.named.grpc_status->md, - GRPC_MDELEM_GRPC_STATUS_0); + return !grpc_mdelem_static_value_eq(batch->idx.named.grpc_status->md, + GRPC_MDELEM_GRPC_STATUS_0); } return false; } @@ -1365,8 +1373,6 @@ static void complete_fetch_locked(void* gs, grpc_error* error) { } } -static void do_nothing(void* arg, grpc_error* error) {} - static void log_metadata(const grpc_metadata_batch* md_batch, uint32_t id, bool is_client, bool is_initial) { for (grpc_linked_mdelem* md = md_batch->list.head; md != nullptr; @@ -1393,7 +1399,9 @@ static void perform_stream_op_locked(void* stream_op, GRPC_STATS_INC_HTTP2_OP_BATCHES(); - if (grpc_http_trace.enabled()) { + s->context = op->payload->context; + s->traced = op->is_traced; + if (GRPC_TRACE_FLAG_ENABLED(grpc_http_trace)) { char* str = grpc_transport_stream_op_batch_string(op); gpr_log(GPR_INFO, "perform_stream_op_locked: %s; on_complete = %p", str, op->on_complete); @@ -1409,21 +1417,14 @@ static void perform_stream_op_locked(void* stream_op, } grpc_closure* on_complete = op->on_complete; - // TODO(roth): This is a hack needed because we use data inside of the - // closure itself to do the barrier calculation (i.e., to ensure that - // we don't schedule the closure until all ops in the batch have been - // completed). This can go away once we move to a new C++ closure API - // that provides the ability to create a barrier closure. - if (on_complete == nullptr) { - on_complete = GRPC_CLOSURE_INIT(&op->handler_private.closure, do_nothing, - nullptr, grpc_schedule_on_exec_ctx); + // on_complete will be null if and only if there are no send ops in the batch. + if (on_complete != nullptr) { + // This batch has send ops. Use final_data as a barrier until enqueue time; + // the initial counter is dropped at the end of this function. + on_complete->next_data.scratch = CLOSURE_BARRIER_FIRST_REF_BIT; + on_complete->error_data.error = GRPC_ERROR_NONE; } - /* use final_data as a barrier until enqueue time; the inital counter is - dropped at the end of this function */ - on_complete->next_data.scratch = CLOSURE_BARRIER_FIRST_REF_BIT; - on_complete->error_data.error = GRPC_ERROR_NONE; - if (op->cancel_stream) { GRPC_STATS_INC_HTTP2_OP_CANCEL(); grpc_chttp2_cancel_stream(t, s, op_payload->cancel_stream.cancel_error); @@ -1447,7 +1448,12 @@ static void perform_stream_op_locked(void* stream_op, true, &s->stream_compression_method) == 0) { s->stream_compression_method = GRPC_STREAM_COMPRESSION_IDENTITY_COMPRESS; } - + if (s->stream_compression_method != + GRPC_STREAM_COMPRESSION_IDENTITY_COMPRESS) { + s->uncompressed_data_size = 0; + s->stream_compression_ctx = nullptr; + grpc_slice_buffer_init(&s->compressed_data_buffer); + } s->send_initial_metadata_finished = add_closure_barrier(on_complete); s->send_initial_metadata = op_payload->send_initial_metadata.send_initial_metadata; @@ -1672,8 +1678,10 @@ static void perform_stream_op_locked(void* stream_op, grpc_chttp2_maybe_complete_recv_trailing_metadata(t, s); } - grpc_chttp2_complete_closure_step(t, s, &on_complete, GRPC_ERROR_NONE, - "op->on_complete"); + if (on_complete != nullptr) { + grpc_chttp2_complete_closure_step(t, s, &on_complete, GRPC_ERROR_NONE, + "op->on_complete"); + } GRPC_CHTTP2_STREAM_UNREF(s, "perform_stream_op"); } @@ -1697,7 +1705,7 @@ static void perform_stream_op(grpc_transport* gt, grpc_stream* gs, } } - if (grpc_http_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_http_trace)) { char* str = grpc_transport_stream_op_batch_string(op); gpr_log(GPR_INFO, "perform_stream_op[s=%p]: %s", s, str); gpr_free(str); @@ -1712,7 +1720,7 @@ static void perform_stream_op(grpc_transport* gt, grpc_stream* gs, } static void cancel_pings(grpc_chttp2_transport* t, grpc_error* error) { - /* callback remaining pings: they're not allowed to call into the transpot, + /* callback remaining pings: they're not allowed to call into the transport, and maybe they hold resources that need to be freed */ grpc_chttp2_ping_queue* pq = &t->ping_queue; GPR_ASSERT(error != GRPC_ERROR_NONE); @@ -1788,6 +1796,9 @@ void grpc_chttp2_ack_ping(grpc_chttp2_transport* t, uint64_t id) { } static void send_goaway(grpc_chttp2_transport* t, grpc_error* error) { + /* We want to log this irrespective of whether http tracing is enabled */ + gpr_log(GPR_INFO, "%s: Sending goaway err=%s", t->peer_string, + grpc_error_string(error)); t->sent_goaway_state = GRPC_CHTTP2_GOAWAY_SEND_SCHEDULED; grpc_http2_error_code http_error; grpc_slice slice; @@ -1861,7 +1872,7 @@ static void perform_transport_op_locked(void* stream_op, static void perform_transport_op(grpc_transport* gt, grpc_transport_op* op) { grpc_chttp2_transport* t = reinterpret_cast(gt); - if (grpc_http_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_http_trace)) { char* msg = grpc_transport_op_string(op); gpr_log(GPR_INFO, "perform_transport_op[t=%p]: %s", t, msg); gpr_free(msg); @@ -1998,27 +2009,39 @@ void grpc_chttp2_maybe_complete_recv_trailing_metadata(grpc_chttp2_transport* t, !s->seen_error && s->recv_trailing_metadata_finished != nullptr) { /* Maybe some SYNC_FLUSH data is left in frame_storage. Consume them and * maybe decompress the next 5 bytes in the stream. */ - bool end_of_context; - if (!s->stream_decompression_ctx) { - s->stream_decompression_ctx = grpc_stream_compression_context_create( - s->stream_decompression_method); - } - if (!grpc_stream_decompress( - s->stream_decompression_ctx, &s->frame_storage, - &s->unprocessed_incoming_frames_buffer, nullptr, - GRPC_HEADER_SIZE_IN_BYTES, &end_of_context)) { - grpc_slice_buffer_reset_and_unref_internal(&s->frame_storage); - grpc_slice_buffer_reset_and_unref_internal( - &s->unprocessed_incoming_frames_buffer); - s->seen_error = true; - } else { + if (s->stream_decompression_method == + GRPC_STREAM_COMPRESSION_IDENTITY_DECOMPRESS) { + grpc_slice_buffer_move_first(&s->frame_storage, + GRPC_HEADER_SIZE_IN_BYTES, + &s->unprocessed_incoming_frames_buffer); if (s->unprocessed_incoming_frames_buffer.length > 0) { s->unprocessed_incoming_frames_decompressed = true; pending_data = true; } - if (end_of_context) { - grpc_stream_compression_context_destroy(s->stream_decompression_ctx); - s->stream_decompression_ctx = nullptr; + } else { + bool end_of_context; + if (!s->stream_decompression_ctx) { + s->stream_decompression_ctx = grpc_stream_compression_context_create( + s->stream_decompression_method); + } + if (!grpc_stream_decompress( + s->stream_decompression_ctx, &s->frame_storage, + &s->unprocessed_incoming_frames_buffer, nullptr, + GRPC_HEADER_SIZE_IN_BYTES, &end_of_context)) { + grpc_slice_buffer_reset_and_unref_internal(&s->frame_storage); + grpc_slice_buffer_reset_and_unref_internal( + &s->unprocessed_incoming_frames_buffer); + s->seen_error = true; + } else { + if (s->unprocessed_incoming_frames_buffer.length > 0) { + s->unprocessed_incoming_frames_decompressed = true; + pending_data = true; + } + if (end_of_context) { + grpc_stream_compression_context_destroy( + s->stream_decompression_ctx); + s->stream_decompression_ctx = nullptr; + } } } } @@ -2473,7 +2496,6 @@ static grpc_error* try_http_parsing(grpc_chttp2_transport* t) { size_t i = 0; grpc_error* error = GRPC_ERROR_NONE; grpc_http_response response; - memset(&response, 0, sizeof(response)); grpc_http_parser_init(&parser, GRPC_HTTP_RESPONSE, &response); @@ -2568,11 +2590,16 @@ static void read_action_locked(void* tp, grpc_error* error) { } else if (t->closed_with_error == GRPC_ERROR_NONE) { keep_reading = true; GRPC_CHTTP2_REF_TRANSPORT(t, "keep_reading"); + /* Since we have read a byte, reset the keepalive timer */ + if (t->keepalive_state == GRPC_CHTTP2_KEEPALIVE_STATE_WAITING) { + grpc_timer_cancel(&t->keepalive_ping_timer); + } } grpc_slice_buffer_reset_and_unref_internal(&t->read_buffer); if (keep_reading) { - grpc_endpoint_read(t->ep, &t->read_buffer, &t->read_action_locked); + const bool urgent = t->goaway_error != GRPC_ERROR_NONE; + grpc_endpoint_read(t->ep, &t->read_buffer, &t->read_action_locked, urgent); grpc_chttp2_act_on_flowctl_action(t->flow_control->MakeAction(), t, nullptr); GRPC_CHTTP2_UNREF_TRANSPORT(t, "keep_reading"); @@ -2592,10 +2619,13 @@ static void schedule_bdp_ping_locked(grpc_chttp2_transport* t) { static void start_bdp_ping_locked(void* tp, grpc_error* error) { grpc_chttp2_transport* t = static_cast(tp); - if (grpc_http_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_http_trace)) { gpr_log(GPR_INFO, "%s: Start BDP ping err=%s", t->peer_string, grpc_error_string(error)); } + if (error != GRPC_ERROR_NONE || t->closed_with_error != GRPC_ERROR_NONE) { + return; + } /* Reset the keepalive ping timer */ if (t->keepalive_state == GRPC_CHTTP2_KEEPALIVE_STATE_WAITING) { grpc_timer_cancel(&t->keepalive_ping_timer); @@ -2605,11 +2635,11 @@ static void start_bdp_ping_locked(void* tp, grpc_error* error) { static void finish_bdp_ping_locked(void* tp, grpc_error* error) { grpc_chttp2_transport* t = static_cast(tp); - if (grpc_http_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_http_trace)) { gpr_log(GPR_INFO, "%s: Complete BDP ping err=%s", t->peer_string, grpc_error_string(error)); } - if (error != GRPC_ERROR_NONE) { + if (error != GRPC_ERROR_NONE || t->closed_with_error != GRPC_ERROR_NONE) { GRPC_CHTTP2_UNREF_TRANSPORT(t, "bdp_ping"); return; } @@ -2737,6 +2767,9 @@ static void start_keepalive_ping_locked(void* arg, grpc_error* error) { if (t->channelz_socket != nullptr) { t->channelz_socket->RecordKeepaliveSent(); } + if (GRPC_TRACE_FLAG_ENABLED(grpc_http_trace)) { + gpr_log(GPR_INFO, "%s: Start keepalive ping", t->peer_string); + } GRPC_CHTTP2_REF_TRANSPORT(t, "keepalive watchdog"); grpc_timer_init(&t->keepalive_watchdog_timer, grpc_core::ExecCtx::Get()->Now() + t->keepalive_timeout, @@ -2747,6 +2780,9 @@ static void finish_keepalive_ping_locked(void* arg, grpc_error* error) { grpc_chttp2_transport* t = static_cast(arg); if (t->keepalive_state == GRPC_CHTTP2_KEEPALIVE_STATE_PINGING) { if (error == GRPC_ERROR_NONE) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_http_trace)) { + gpr_log(GPR_INFO, "%s: Finish keepalive ping", t->peer_string); + } t->keepalive_state = GRPC_CHTTP2_KEEPALIVE_STATE_WAITING; grpc_timer_cancel(&t->keepalive_watchdog_timer); GRPC_CHTTP2_REF_TRANSPORT(t, "init keepalive ping"); @@ -2762,6 +2798,8 @@ static void keepalive_watchdog_fired_locked(void* arg, grpc_error* error) { grpc_chttp2_transport* t = static_cast(arg); if (t->keepalive_state == GRPC_CHTTP2_KEEPALIVE_STATE_PINGING) { if (error == GRPC_ERROR_NONE) { + gpr_log(GPR_ERROR, "%s: Keepalive watchdog fired. Closing transport.", + t->peer_string); t->keepalive_state = GRPC_CHTTP2_KEEPALIVE_STATE_DYING; close_transport_locked( t, grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING( @@ -2786,9 +2824,9 @@ static void keepalive_watchdog_fired_locked(void* arg, grpc_error* error) { static void connectivity_state_set(grpc_chttp2_transport* t, grpc_connectivity_state state, - grpc_error* error, const char* reason) { + const char* reason) { GRPC_CHTTP2_IF_TRACING(gpr_log(GPR_INFO, "set connectivity_state=%d", state)); - grpc_connectivity_state_set(&t->channel_callback.state_tracker, state, error, + grpc_connectivity_state_set(&t->channel_callback.state_tracker, state, reason); } @@ -2837,8 +2875,8 @@ Chttp2IncomingByteStream::Chttp2IncomingByteStream( : ByteStream(frame_size, flags), transport_(transport), stream_(stream), + refs_(2), remaining_bytes_(frame_size) { - gpr_ref_init(&refs_, 2); GRPC_ERROR_UNREF(stream->byte_stream_error); stream->byte_stream_error = GRPC_ERROR_NONE; } @@ -2863,14 +2901,6 @@ void Chttp2IncomingByteStream::Orphan() { GRPC_ERROR_NONE); } -void Chttp2IncomingByteStream::Unref() { - if (gpr_unref(&refs_)) { - Delete(this); - } -} - -void Chttp2IncomingByteStream::Ref() { gpr_ref(&refs_); } - void Chttp2IncomingByteStream::NextLocked(void* arg, grpc_error* error_ignored) { Chttp2IncomingByteStream* bs = static_cast(arg); @@ -2934,6 +2964,8 @@ bool Chttp2IncomingByteStream::Next(size_t max_size_hint, } void Chttp2IncomingByteStream::MaybeCreateStreamDecompressionCtx() { + GPR_DEBUG_ASSERT(stream_->stream_decompression_method != + GRPC_STREAM_COMPRESSION_IDENTITY_DECOMPRESS); if (!stream_->stream_decompression_ctx) { stream_->stream_decompression_ctx = grpc_stream_compression_context_create( stream_->stream_decompression_method); @@ -2944,7 +2976,9 @@ grpc_error* Chttp2IncomingByteStream::Pull(grpc_slice* slice) { GPR_TIMER_SCOPE("incoming_byte_stream_pull", 0); grpc_error* error; if (stream_->unprocessed_incoming_frames_buffer.length > 0) { - if (!stream_->unprocessed_incoming_frames_decompressed) { + if (!stream_->unprocessed_incoming_frames_decompressed && + stream_->stream_decompression_method != + GRPC_STREAM_COMPRESSION_IDENTITY_DECOMPRESS) { bool end_of_context; MaybeCreateStreamDecompressionCtx(); if (!grpc_stream_decompress(stream_->stream_decompression_ctx, @@ -2991,7 +3025,7 @@ void Chttp2IncomingByteStream::PublishError(grpc_error* error) { grpc_chttp2_cancel_stream(transport_, stream_, GRPC_ERROR_REF(error)); } -grpc_error* Chttp2IncomingByteStream::Push(grpc_slice slice, +grpc_error* Chttp2IncomingByteStream::Push(const grpc_slice& slice, grpc_slice* slice_out) { if (remaining_bytes_ < GRPC_SLICE_LENGTH(slice)) { grpc_error* error = @@ -3056,7 +3090,7 @@ static void benign_reclaimer_locked(void* arg, grpc_error* error) { grpc_chttp2_stream_map_size(&t->stream_map) == 0) { /* Channel with no active streams: send a goaway to try and make it * disconnect cleanly */ - if (grpc_resource_quota_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_resource_quota_trace)) { gpr_log(GPR_INFO, "HTTP2: %s - send goaway to free memory", t->peer_string); } @@ -3064,7 +3098,8 @@ static void benign_reclaimer_locked(void* arg, grpc_error* error) { grpc_error_set_int( 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()) { + } else if (error == GRPC_ERROR_NONE && + GRPC_TRACE_FLAG_ENABLED(grpc_resource_quota_trace)) { gpr_log(GPR_INFO, "HTTP2: %s - skip benign reclamation, there are still %" PRIdPTR " streams", @@ -3085,7 +3120,7 @@ static void destructive_reclaimer_locked(void* arg, grpc_error* error) { if (error == GRPC_ERROR_NONE && n > 0) { grpc_chttp2_stream* s = static_cast( grpc_chttp2_stream_map_rand(&t->stream_map)); - if (grpc_resource_quota_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_resource_quota_trace)) { gpr_log(GPR_INFO, "HTTP2: %s - abandon stream id %d", t->peer_string, s->id); } @@ -3177,21 +3212,18 @@ static const grpc_transport_vtable vtable = {sizeof(grpc_chttp2_stream), static const grpc_transport_vtable* get_vtable(void) { return &vtable; } -intptr_t grpc_chttp2_transport_get_socket_uuid(grpc_transport* transport) { +grpc_core::RefCountedPtr +grpc_chttp2_transport_get_socket_node(grpc_transport* transport) { grpc_chttp2_transport* t = reinterpret_cast(transport); - if (t->channelz_socket != nullptr) { - return t->channelz_socket->uuid(); - } else { - return 0; - } + return t->channelz_socket; } grpc_transport* grpc_create_chttp2_transport( const grpc_channel_args* channel_args, grpc_endpoint* ep, bool is_client, grpc_resource_user* resource_user) { - auto t = new (gpr_malloc(sizeof(grpc_chttp2_transport))) - grpc_chttp2_transport(channel_args, ep, is_client, resource_user); + auto t = grpc_core::New(channel_args, ep, is_client, + resource_user); return &t->base; } diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.h b/src/core/ext/transport/chttp2/transport/chttp2_transport.h index b3fe1c082ec..c22cfb0ad7d 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.h +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.h @@ -21,6 +21,7 @@ #include +#include "src/core/lib/channel/channelz.h" #include "src/core/lib/debug/trace.h" #include "src/core/lib/iomgr/endpoint.h" #include "src/core/lib/transport/transport.h" @@ -35,7 +36,8 @@ grpc_transport* grpc_create_chttp2_transport( const grpc_channel_args* channel_args, grpc_endpoint* ep, bool is_client, grpc_resource_user* resource_user = nullptr); -intptr_t grpc_chttp2_transport_get_socket_uuid(grpc_transport* transport); +grpc_core::RefCountedPtr +grpc_chttp2_transport_get_socket_node(grpc_transport* transport); /// Takes ownership of \a read_buffer, which (if non-NULL) contains /// leftover bytes previously read from the endpoint (e.g., by handshakers). diff --git a/src/core/ext/transport/chttp2/transport/context_list.cc b/src/core/ext/transport/chttp2/transport/context_list.cc new file mode 100644 index 00000000000..df09809067d --- /dev/null +++ b/src/core/ext/transport/chttp2/transport/context_list.cc @@ -0,0 +1,67 @@ +/* + * + * 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 + +#include "src/core/ext/transport/chttp2/transport/context_list.h" + +namespace { +void (*write_timestamps_callback_g)(void*, grpc_core::Timestamps*, + grpc_error* error) = nullptr; +void* (*get_copied_context_fn_g)(void*) = nullptr; +} // namespace + +namespace grpc_core { +void ContextList::Append(ContextList** head, grpc_chttp2_stream* s) { + if (get_copied_context_fn_g == nullptr || + write_timestamps_callback_g == nullptr) { + return; + } + /* Create a new element in the list and add it at the front */ + ContextList* elem = grpc_core::New(); + elem->trace_context_ = get_copied_context_fn_g(s->context); + elem->byte_offset_ = s->byte_counter; + elem->next_ = *head; + *head = elem; +} + +void ContextList::Execute(void* arg, grpc_core::Timestamps* ts, + grpc_error* error) { + ContextList* head = static_cast(arg); + ContextList* to_be_freed; + while (head != nullptr) { + if (write_timestamps_callback_g) { + ts->byte_offset = static_cast(head->byte_offset_); + write_timestamps_callback_g(head->trace_context_, ts, error); + } + to_be_freed = head; + head = head->next_; + grpc_core::Delete(to_be_freed); + } +} + +void grpc_http2_set_write_timestamps_callback(void (*fn)(void*, + grpc_core::Timestamps*, + grpc_error* error)) { + write_timestamps_callback_g = fn; +} + +void grpc_http2_set_fn_get_copied_context(void* (*fn)(void*)) { + get_copied_context_fn_g = fn; +} +} /* namespace grpc_core */ diff --git a/src/core/ext/transport/chttp2/transport/context_list.h b/src/core/ext/transport/chttp2/transport/context_list.h new file mode 100644 index 00000000000..5b9d2ab3784 --- /dev/null +++ b/src/core/ext/transport/chttp2/transport/context_list.h @@ -0,0 +1,53 @@ +/* + * + * 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_TRANSPORT_CONTEXT_LIST_H +#define GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_CONTEXT_LIST_H + +#include + +#include "src/core/lib/iomgr/buffer_list.h" + +#include "src/core/ext/transport/chttp2/transport/internal.h" + +namespace grpc_core { +/** A list of RPC Contexts */ +class ContextList { + public: + /* Creates a new element with \a context as the value and appends it to the + * list. */ + static void Append(ContextList** head, grpc_chttp2_stream* s); + + /* Executes a function \a fn with each context in the list and \a ts. It also + * frees up the entire list after this operation. It is intended as a callback + * and hence does not take a ref on \a error */ + static void Execute(void* arg, grpc_core::Timestamps* ts, grpc_error* error); + + private: + void* trace_context_ = nullptr; + ContextList* next_ = nullptr; + size_t byte_offset_ = 0; +}; + +void grpc_http2_set_write_timestamps_callback(void (*fn)(void*, + grpc_core::Timestamps*, + grpc_error* error)); +void grpc_http2_set_fn_get_copied_context(void* (*fn)(void*)); +} /* namespace grpc_core */ + +#endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_CONTEXT_LIST_H */ diff --git a/src/core/ext/transport/chttp2/transport/flow_control.cc b/src/core/ext/transport/chttp2/transport/flow_control.cc index 53932bcb7f5..d53475a1b61 100644 --- a/src/core/ext/transport/chttp2/transport/flow_control.cc +++ b/src/core/ext/transport/chttp2/transport/flow_control.cc @@ -111,7 +111,7 @@ void FlowControlTrace::Finish() { saw_str = gpr_leftpad("", ' ', kTracePadding); } gpr_log(GPR_DEBUG, - "%p[%u][%s] | %s | trw:%s, ttw:%s, taw:%s, srw:%s, slw:%s, saw:%s", + "%p[%u][%s] | %s | trw:%s, tlw:%s, taw:%s, srw:%s, slw:%s, saw:%s", tfc_, sfc_ != nullptr ? sfc_->stream()->id : 0, tfc_->transport()->is_client ? "cli" : "svr", reason_, trw_str, tlw_str, taw_str, srw_str, slw_str, saw_str); @@ -190,7 +190,7 @@ TransportFlowControl::TransportFlowControl(const grpc_chttp2_transport* t, uint32_t TransportFlowControl::MaybeSendUpdate(bool writing_anyway) { FlowControlTrace trace("t updt sent", this, nullptr); const uint32_t target_announced_window = - static_cast(target_window()); + static_cast(target_window()); if ((writing_anyway || announced_window_ <= target_announced_window / 2) && announced_window_ != target_announced_window) { const uint32_t announce = static_cast GPR_CLAMP( diff --git a/src/core/ext/transport/chttp2/transport/flow_control.h b/src/core/ext/transport/chttp2/transport/flow_control.h index 120fefc8b79..49e206fca3d 100644 --- a/src/core/ext/transport/chttp2/transport/flow_control.h +++ b/src/core/ext/transport/chttp2/transport/flow_control.h @@ -127,7 +127,7 @@ class FlowControlTrace { StreamFlowControl* sfc); void Finish(); - const bool enabled_ = grpc_flowctl_trace.enabled(); + const bool enabled_ = GRPC_TRACE_FLAG_ENABLED(grpc_flowctl_trace); TransportFlowControl* tfc_; StreamFlowControl* sfc_; diff --git a/src/core/ext/transport/chttp2/transport/frame_data.cc b/src/core/ext/transport/chttp2/transport/frame_data.cc index 1de00735cf3..3734c0150b7 100644 --- a/src/core/ext/transport/chttp2/transport/frame_data.cc +++ b/src/core/ext/transport/chttp2/transport/frame_data.cc @@ -104,23 +104,22 @@ grpc_error* grpc_deframe_unprocessed_incoming_frames( uint8_t* end = nullptr; uint8_t* cur = nullptr; - grpc_slice slice = grpc_slice_buffer_take_first(slices); - - beg = GRPC_SLICE_START_PTR(slice); - end = GRPC_SLICE_END_PTR(slice); + grpc_slice* slice = grpc_slice_buffer_peek_first(slices); + beg = GRPC_SLICE_START_PTR(*slice); + end = GRPC_SLICE_END_PTR(*slice); cur = beg; uint32_t message_flags; char* msg; if (cur == end) { - grpc_slice_unref_internal(slice); + grpc_slice_buffer_remove_first(slices); continue; } switch (p->state) { case GRPC_CHTTP2_DATA_ERROR: p->state = GRPC_CHTTP2_DATA_ERROR; - grpc_slice_unref_internal(slice); + grpc_slice_buffer_remove_first(slices); return GRPC_ERROR_REF(p->error); case GRPC_CHTTP2_DATA_FH_0: s->stats.incoming.framing_bytes++; @@ -138,19 +137,19 @@ grpc_error* grpc_deframe_unprocessed_incoming_frames( p->error = grpc_error_set_int(p->error, GRPC_ERROR_INT_STREAM_ID, static_cast(s->id)); gpr_free(msg); - msg = grpc_dump_slice(slice, GPR_DUMP_HEX | GPR_DUMP_ASCII); + msg = grpc_dump_slice(*slice, GPR_DUMP_HEX | GPR_DUMP_ASCII); p->error = grpc_error_set_str(p->error, GRPC_ERROR_STR_RAW_BYTES, grpc_slice_from_copied_string(msg)); gpr_free(msg); p->error = grpc_error_set_int(p->error, GRPC_ERROR_INT_OFFSET, cur - beg); p->state = GRPC_CHTTP2_DATA_ERROR; - grpc_slice_unref_internal(slice); + grpc_slice_buffer_remove_first(slices); return GRPC_ERROR_REF(p->error); } if (++cur == end) { p->state = GRPC_CHTTP2_DATA_FH_1; - grpc_slice_unref_internal(slice); + grpc_slice_buffer_remove_first(slices); continue; } /* fallthrough */ @@ -159,7 +158,7 @@ grpc_error* grpc_deframe_unprocessed_incoming_frames( p->frame_size = (static_cast(*cur)) << 24; if (++cur == end) { p->state = GRPC_CHTTP2_DATA_FH_2; - grpc_slice_unref_internal(slice); + grpc_slice_buffer_remove_first(slices); continue; } /* fallthrough */ @@ -168,7 +167,7 @@ grpc_error* grpc_deframe_unprocessed_incoming_frames( p->frame_size |= (static_cast(*cur)) << 16; if (++cur == end) { p->state = GRPC_CHTTP2_DATA_FH_3; - grpc_slice_unref_internal(slice); + grpc_slice_buffer_remove_first(slices); continue; } /* fallthrough */ @@ -177,7 +176,7 @@ grpc_error* grpc_deframe_unprocessed_incoming_frames( p->frame_size |= (static_cast(*cur)) << 8; if (++cur == end) { p->state = GRPC_CHTTP2_DATA_FH_4; - grpc_slice_unref_internal(slice); + grpc_slice_buffer_remove_first(slices); continue; } /* fallthrough */ @@ -204,19 +203,18 @@ grpc_error* grpc_deframe_unprocessed_incoming_frames( p->state = GRPC_CHTTP2_DATA_FH_0; } s->pending_byte_stream = true; - if (cur != end) { - grpc_slice_buffer_undo_take_first( - slices, grpc_slice_sub(slice, static_cast(cur - beg), - static_cast(end - beg))); + grpc_slice_buffer_sub_first(slices, static_cast(cur - beg), + static_cast(end - beg)); + } else { + grpc_slice_buffer_remove_first(slices); } - grpc_slice_unref_internal(slice); return GRPC_ERROR_NONE; case GRPC_CHTTP2_DATA_FRAME: { GPR_ASSERT(p->parsing_frame != nullptr); GPR_ASSERT(slice_out != nullptr); if (cur == end) { - grpc_slice_unref_internal(slice); + grpc_slice_buffer_remove_first(slices); continue; } uint32_t remaining = static_cast(end - cur); @@ -224,32 +222,32 @@ grpc_error* grpc_deframe_unprocessed_incoming_frames( s->stats.incoming.data_bytes += remaining; if (GRPC_ERROR_NONE != (error = p->parsing_frame->Push( - grpc_slice_sub(slice, static_cast(cur - beg), + grpc_slice_sub(*slice, static_cast(cur - beg), static_cast(end - beg)), slice_out))) { - grpc_slice_unref_internal(slice); + grpc_slice_buffer_remove_first(slices); return error; } if (GRPC_ERROR_NONE != (error = p->parsing_frame->Finished(GRPC_ERROR_NONE, true))) { - grpc_slice_unref_internal(slice); + grpc_slice_buffer_remove_first(slices); return error; } p->parsing_frame = nullptr; p->state = GRPC_CHTTP2_DATA_FH_0; - grpc_slice_unref_internal(slice); + grpc_slice_buffer_remove_first(slices); return GRPC_ERROR_NONE; } else if (remaining < p->frame_size) { s->stats.incoming.data_bytes += remaining; if (GRPC_ERROR_NONE != (error = p->parsing_frame->Push( - grpc_slice_sub(slice, static_cast(cur - beg), + grpc_slice_sub(*slice, static_cast(cur - beg), static_cast(end - beg)), slice_out))) { return error; } p->frame_size -= remaining; - grpc_slice_unref_internal(slice); + grpc_slice_buffer_remove_first(slices); return GRPC_ERROR_NONE; } else { GPR_ASSERT(remaining > p->frame_size); @@ -257,37 +255,35 @@ grpc_error* grpc_deframe_unprocessed_incoming_frames( if (GRPC_ERROR_NONE != p->parsing_frame->Push( grpc_slice_sub( - slice, static_cast(cur - beg), + *slice, static_cast(cur - beg), static_cast(cur + p->frame_size - beg)), slice_out)) { - grpc_slice_unref_internal(slice); + grpc_slice_buffer_remove_first(slices); return error; } if (GRPC_ERROR_NONE != (error = p->parsing_frame->Finished(GRPC_ERROR_NONE, true))) { - grpc_slice_unref_internal(slice); + grpc_slice_buffer_remove_first(slices); return error; } p->parsing_frame = nullptr; p->state = GRPC_CHTTP2_DATA_FH_0; cur += p->frame_size; - grpc_slice_buffer_undo_take_first( - slices, grpc_slice_sub(slice, static_cast(cur - beg), - static_cast(end - beg))); - grpc_slice_unref_internal(slice); + grpc_slice_buffer_sub_first(slices, static_cast(cur - beg), + static_cast(end - beg)); return GRPC_ERROR_NONE; } } } } - return GRPC_ERROR_NONE; } grpc_error* grpc_chttp2_data_parser_parse(void* parser, grpc_chttp2_transport* t, grpc_chttp2_stream* s, - grpc_slice slice, int is_last) { + const grpc_slice& slice, + int is_last) { if (!s->pending_byte_stream) { grpc_slice_ref_internal(slice); grpc_slice_buffer_add(&s->frame_storage, slice); diff --git a/src/core/ext/transport/chttp2/transport/frame_data.h b/src/core/ext/transport/chttp2/transport/frame_data.h index 2c5da99fa68..ec3890098ec 100644 --- a/src/core/ext/transport/chttp2/transport/frame_data.h +++ b/src/core/ext/transport/chttp2/transport/frame_data.h @@ -67,7 +67,7 @@ grpc_error* grpc_chttp2_data_parser_begin_frame(grpc_chttp2_data_parser* parser, grpc_error* grpc_chttp2_data_parser_parse(void* parser, grpc_chttp2_transport* t, grpc_chttp2_stream* s, - grpc_slice slice, int is_last); + const grpc_slice& slice, int is_last); void grpc_chttp2_encode_data(uint32_t id, grpc_slice_buffer* inbuf, uint32_t write_bytes, int is_eof, diff --git a/src/core/ext/transport/chttp2/transport/frame_goaway.cc b/src/core/ext/transport/chttp2/transport/frame_goaway.cc index 2a1dd3c3163..e901a6bdc76 100644 --- a/src/core/ext/transport/chttp2/transport/frame_goaway.cc +++ b/src/core/ext/transport/chttp2/transport/frame_goaway.cc @@ -57,10 +57,11 @@ grpc_error* grpc_chttp2_goaway_parser_begin_frame(grpc_chttp2_goaway_parser* p, grpc_error* grpc_chttp2_goaway_parser_parse(void* parser, grpc_chttp2_transport* t, grpc_chttp2_stream* s, - grpc_slice slice, int is_last) { - uint8_t* const beg = GRPC_SLICE_START_PTR(slice); - uint8_t* const end = GRPC_SLICE_END_PTR(slice); - uint8_t* cur = beg; + const grpc_slice& slice, + int is_last) { + const uint8_t* const beg = GRPC_SLICE_START_PTR(slice); + const uint8_t* const end = GRPC_SLICE_END_PTR(slice); + const uint8_t* cur = beg; grpc_chttp2_goaway_parser* p = static_cast(parser); @@ -149,7 +150,7 @@ grpc_error* grpc_chttp2_goaway_parser_parse(void* parser, } void grpc_chttp2_goaway_append(uint32_t last_stream_id, uint32_t error_code, - grpc_slice debug_data, + const grpc_slice& debug_data, grpc_slice_buffer* slice_buffer) { grpc_slice header = GRPC_SLICE_MALLOC(9 + 4 + 4); uint8_t* p = GRPC_SLICE_START_PTR(header); diff --git a/src/core/ext/transport/chttp2/transport/frame_goaway.h b/src/core/ext/transport/chttp2/transport/frame_goaway.h index 66c7a68befe..6f65bb2d604 100644 --- a/src/core/ext/transport/chttp2/transport/frame_goaway.h +++ b/src/core/ext/transport/chttp2/transport/frame_goaway.h @@ -53,10 +53,11 @@ grpc_error* grpc_chttp2_goaway_parser_begin_frame( grpc_error* grpc_chttp2_goaway_parser_parse(void* parser, grpc_chttp2_transport* t, grpc_chttp2_stream* s, - grpc_slice slice, int is_last); + const grpc_slice& slice, + int is_last); void grpc_chttp2_goaway_append(uint32_t last_stream_id, uint32_t error_code, - grpc_slice debug_data, + const grpc_slice& debug_data, grpc_slice_buffer* slice_buffer); #endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_FRAME_GOAWAY_H */ diff --git a/src/core/ext/transport/chttp2/transport/frame_ping.cc b/src/core/ext/transport/chttp2/transport/frame_ping.cc index 205826b779a..9a56bf093f4 100644 --- a/src/core/ext/transport/chttp2/transport/frame_ping.cc +++ b/src/core/ext/transport/chttp2/transport/frame_ping.cc @@ -73,10 +73,11 @@ grpc_error* grpc_chttp2_ping_parser_begin_frame(grpc_chttp2_ping_parser* parser, grpc_error* grpc_chttp2_ping_parser_parse(void* parser, grpc_chttp2_transport* t, grpc_chttp2_stream* s, - grpc_slice slice, int is_last) { - uint8_t* const beg = GRPC_SLICE_START_PTR(slice); - uint8_t* const end = GRPC_SLICE_END_PTR(slice); - uint8_t* cur = beg; + const grpc_slice& slice, + int is_last) { + const uint8_t* const beg = GRPC_SLICE_START_PTR(slice); + const uint8_t* const end = GRPC_SLICE_END_PTR(slice); + const uint8_t* cur = beg; grpc_chttp2_ping_parser* p = static_cast(parser); while (p->byte != 8 && cur != end) { diff --git a/src/core/ext/transport/chttp2/transport/frame_ping.h b/src/core/ext/transport/chttp2/transport/frame_ping.h index 55a4499ad59..915d023a34c 100644 --- a/src/core/ext/transport/chttp2/transport/frame_ping.h +++ b/src/core/ext/transport/chttp2/transport/frame_ping.h @@ -37,7 +37,7 @@ grpc_error* grpc_chttp2_ping_parser_begin_frame(grpc_chttp2_ping_parser* parser, grpc_error* grpc_chttp2_ping_parser_parse(void* parser, grpc_chttp2_transport* t, grpc_chttp2_stream* s, - grpc_slice slice, int is_last); + const grpc_slice& slice, int is_last); /* Test-only function for disabling ping ack */ void grpc_set_disable_ping_ack(bool disable_ping_ack); diff --git a/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc b/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc index a0a75345947..ccde36cbc48 100644 --- a/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc +++ b/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc @@ -74,10 +74,11 @@ grpc_error* grpc_chttp2_rst_stream_parser_begin_frame( grpc_error* grpc_chttp2_rst_stream_parser_parse(void* parser, grpc_chttp2_transport* t, grpc_chttp2_stream* s, - grpc_slice slice, int is_last) { - uint8_t* const beg = GRPC_SLICE_START_PTR(slice); - uint8_t* const end = GRPC_SLICE_END_PTR(slice); - uint8_t* cur = beg; + const grpc_slice& slice, + int is_last) { + const uint8_t* const beg = GRPC_SLICE_START_PTR(slice); + const uint8_t* const end = GRPC_SLICE_END_PTR(slice); + const uint8_t* cur = beg; grpc_chttp2_rst_stream_parser* p = static_cast(parser); diff --git a/src/core/ext/transport/chttp2/transport/frame_rst_stream.h b/src/core/ext/transport/chttp2/transport/frame_rst_stream.h index 6bcf9c44797..64707666181 100644 --- a/src/core/ext/transport/chttp2/transport/frame_rst_stream.h +++ b/src/core/ext/transport/chttp2/transport/frame_rst_stream.h @@ -38,6 +38,7 @@ grpc_error* grpc_chttp2_rst_stream_parser_begin_frame( grpc_error* grpc_chttp2_rst_stream_parser_parse(void* parser, grpc_chttp2_transport* t, grpc_chttp2_stream* s, - grpc_slice slice, int is_last); + const grpc_slice& slice, + int is_last); #endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_FRAME_RST_STREAM_H */ diff --git a/src/core/ext/transport/chttp2/transport/frame_settings.cc b/src/core/ext/transport/chttp2/transport/frame_settings.cc index 987ac0e79d0..3f84679ec31 100644 --- a/src/core/ext/transport/chttp2/transport/frame_settings.cc +++ b/src/core/ext/transport/chttp2/transport/frame_settings.cc @@ -111,7 +111,8 @@ grpc_error* grpc_chttp2_settings_parser_begin_frame( grpc_error* grpc_chttp2_settings_parser_parse(void* p, grpc_chttp2_transport* t, grpc_chttp2_stream* s, - grpc_slice slice, int is_last) { + const grpc_slice& slice, + int is_last) { grpc_chttp2_settings_parser* parser = static_cast(p); const uint8_t* cur = GRPC_SLICE_START_PTR(slice); @@ -216,19 +217,20 @@ grpc_error* grpc_chttp2_settings_parser_parse(void* p, grpc_chttp2_transport* t, parser->incoming_settings[id] != parser->value) { t->initial_window_update += static_cast(parser->value) - parser->incoming_settings[id]; - if (grpc_http_trace.enabled() || grpc_flowctl_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_http_trace) || + GRPC_TRACE_FLAG_ENABLED(grpc_flowctl_trace)) { gpr_log(GPR_INFO, "%p[%s] adding %d for initial_window change", t, t->is_client ? "cli" : "svr", static_cast(t->initial_window_update)); } } parser->incoming_settings[id] = parser->value; - if (grpc_http_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_http_trace)) { gpr_log(GPR_INFO, "CHTTP2:%s:%s: got setting %s = %d", t->is_client ? "CLI" : "SVR", t->peer_string, sp->name, parser->value); } - } else if (grpc_http_trace.enabled()) { + } else if (GRPC_TRACE_FLAG_ENABLED(grpc_http_trace)) { gpr_log(GPR_ERROR, "CHTTP2: Ignoring unknown setting %d (value %d)", parser->id, parser->value); } diff --git a/src/core/ext/transport/chttp2/transport/frame_settings.h b/src/core/ext/transport/chttp2/transport/frame_settings.h index 8d8d9b1a914..8a3ff0426b3 100644 --- a/src/core/ext/transport/chttp2/transport/frame_settings.h +++ b/src/core/ext/transport/chttp2/transport/frame_settings.h @@ -55,6 +55,7 @@ grpc_error* grpc_chttp2_settings_parser_begin_frame( grpc_error* grpc_chttp2_settings_parser_parse(void* parser, grpc_chttp2_transport* t, grpc_chttp2_stream* s, - grpc_slice slice, int is_last); + const grpc_slice& slice, + int is_last); #endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_FRAME_SETTINGS_H */ diff --git a/src/core/ext/transport/chttp2/transport/frame_window_update.cc b/src/core/ext/transport/chttp2/transport/frame_window_update.cc index 4b586dc3e7f..80e799f17f1 100644 --- a/src/core/ext/transport/chttp2/transport/frame_window_update.cc +++ b/src/core/ext/transport/chttp2/transport/frame_window_update.cc @@ -69,11 +69,11 @@ grpc_error* grpc_chttp2_window_update_parser_begin_frame( grpc_error* grpc_chttp2_window_update_parser_parse(void* parser, grpc_chttp2_transport* t, grpc_chttp2_stream* s, - grpc_slice slice, + const grpc_slice& slice, int is_last) { - uint8_t* const beg = GRPC_SLICE_START_PTR(slice); - uint8_t* const end = GRPC_SLICE_END_PTR(slice); - uint8_t* cur = beg; + const uint8_t* const beg = GRPC_SLICE_START_PTR(slice); + const uint8_t* const end = GRPC_SLICE_END_PTR(slice); + const uint8_t* cur = beg; grpc_chttp2_window_update_parser* p = static_cast(parser); @@ -88,8 +88,9 @@ grpc_error* grpc_chttp2_window_update_parser_parse(void* parser, } if (p->byte == 4) { - uint32_t received_update = p->amount; - if (received_update == 0 || (received_update & 0x80000000u)) { + // top bit is reserved and must be ignored. + uint32_t received_update = p->amount & 0x7fffffffu; + if (received_update == 0) { char* msg; gpr_asprintf(&msg, "invalid window update bytes: %d", p->amount); grpc_error* err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); diff --git a/src/core/ext/transport/chttp2/transport/frame_window_update.h b/src/core/ext/transport/chttp2/transport/frame_window_update.h index 3d2391f637d..f6721a5bc5d 100644 --- a/src/core/ext/transport/chttp2/transport/frame_window_update.h +++ b/src/core/ext/transport/chttp2/transport/frame_window_update.h @@ -39,7 +39,7 @@ grpc_error* grpc_chttp2_window_update_parser_begin_frame( grpc_error* grpc_chttp2_window_update_parser_parse(void* parser, grpc_chttp2_transport* t, grpc_chttp2_stream* s, - grpc_slice slice, + const grpc_slice& slice, int is_last); #endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_FRAME_WINDOW_UPDATE_H */ diff --git a/src/core/ext/transport/chttp2/transport/hpack_encoder.cc b/src/core/ext/transport/chttp2/transport/hpack_encoder.cc index dbe9df6ae38..d2607e97707 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +++ b/src/core/ext/transport/chttp2/transport/hpack_encoder.cc @@ -56,10 +56,10 @@ /* don't consider adding anything bigger than this to the hpack table */ #define MAX_DECODER_SPACE_USAGE 512 -static grpc_slice_refcount terminal_slice_refcount = {nullptr, nullptr}; +static grpc_slice_refcount terminal_slice_refcount; static const grpc_slice terminal_slice = { &terminal_slice_refcount, /* refcount */ - {{nullptr, 0}} /* data.refcounted */ + {{0, nullptr}} /* data.refcounted */ }; typedef struct { @@ -461,7 +461,7 @@ static void hpack_enc(grpc_chttp2_hpack_compressor* c, grpc_mdelem elem, "Reserved header (colon-prefixed) happening after regular ones."); } - if (grpc_http_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_http_trace)) { char* k = grpc_slice_to_c_string(GRPC_MDKEY(elem)); char* v = nullptr; if (grpc_is_binary_header(GRPC_MDKEY(elem))) { @@ -660,7 +660,7 @@ void grpc_chttp2_hpack_compressor_set_max_table_size( } } c->advertise_table_size_change = 1; - if (grpc_http_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_http_trace)) { 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 ccf2256974a..6e422127511 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_parser.cc +++ b/src/core/ext/transport/chttp2/transport/hpack_parser.cc @@ -624,7 +624,7 @@ static const uint8_t inverse_base64[256] = { /* emission helpers */ static grpc_error* on_hdr(grpc_chttp2_hpack_parser* p, grpc_mdelem md, int add_to_table) { - if (grpc_http_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_http_trace)) { char* k = grpc_slice_to_c_string(GRPC_MDKEY(md)); char* v = nullptr; if (grpc_is_binary_header(GRPC_MDKEY(md))) { @@ -994,7 +994,7 @@ static grpc_error* parse_lithdr_nvridx_v(grpc_chttp2_hpack_parser* p, /* finish parsing a max table size change */ static grpc_error* finish_max_tbl_size(grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end) { - if (grpc_http_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_http_trace)) { gpr_log(GPR_INFO, "MAX TABLE SIZE: %d", p->index); } grpc_error* err = @@ -1452,7 +1452,7 @@ static grpc_error* begin_parse_string(grpc_chttp2_hpack_parser* p, uint8_t binary, grpc_chttp2_hpack_parser_string* str) { if (!p->huff && binary == NOT_BINARY && - (end - cur) >= static_cast(p->strlen) && + static_cast(end - cur) >= p->strlen && p->current_slice_refcount != nullptr) { GRPC_STATS_INC_HPACK_RECV_UNCOMPRESSED(); str->copied = false; @@ -1570,16 +1570,16 @@ void grpc_chttp2_hpack_parser_destroy(grpc_chttp2_hpack_parser* p) { } grpc_error* grpc_chttp2_hpack_parser_parse(grpc_chttp2_hpack_parser* p, - grpc_slice slice) { + const grpc_slice& slice) { /* max number of bytes to parse at a time... limits call stack depth on * compilers without TCO */ #define MAX_PARSE_LENGTH 1024 p->current_slice_refcount = slice.refcount; - uint8_t* start = GRPC_SLICE_START_PTR(slice); - uint8_t* end = GRPC_SLICE_END_PTR(slice); + const uint8_t* start = GRPC_SLICE_START_PTR(slice); + const uint8_t* end = GRPC_SLICE_END_PTR(slice); grpc_error* error = GRPC_ERROR_NONE; while (start != end && error == GRPC_ERROR_NONE) { - uint8_t* target = start + GPR_MIN(MAX_PARSE_LENGTH, end - start); + const uint8_t* target = start + GPR_MIN(MAX_PARSE_LENGTH, end - start); error = p->state(p, start, target); start = target; } @@ -1616,12 +1616,19 @@ static void parse_stream_compression_md(grpc_chttp2_transport* t, s->stream_decompression_method = GRPC_STREAM_COMPRESSION_IDENTITY_DECOMPRESS; } + + if (s->stream_decompression_method != + GRPC_STREAM_COMPRESSION_IDENTITY_DECOMPRESS) { + s->stream_decompression_ctx = nullptr; + grpc_slice_buffer_init(&s->decompressed_data_buffer); + } } grpc_error* grpc_chttp2_header_parser_parse(void* hpack_parser, grpc_chttp2_transport* t, grpc_chttp2_stream* s, - grpc_slice slice, int is_last) { + const grpc_slice& slice, + int is_last) { GPR_TIMER_SCOPE("grpc_chttp2_header_parser_parse", 0); grpc_chttp2_hpack_parser* parser = static_cast(hpack_parser); diff --git a/src/core/ext/transport/chttp2/transport/hpack_parser.h b/src/core/ext/transport/chttp2/transport/hpack_parser.h index 3e05de4b925..3dc8e13bea2 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_parser.h +++ b/src/core/ext/transport/chttp2/transport/hpack_parser.h @@ -97,13 +97,14 @@ void grpc_chttp2_hpack_parser_destroy(grpc_chttp2_hpack_parser* p); void grpc_chttp2_hpack_parser_set_has_priority(grpc_chttp2_hpack_parser* p); grpc_error* grpc_chttp2_hpack_parser_parse(grpc_chttp2_hpack_parser* p, - grpc_slice slice); + const grpc_slice& slice); /* wraps grpc_chttp2_hpack_parser_parse to provide a frame level parser for the transport */ grpc_error* grpc_chttp2_header_parser_parse(void* hpack_parser, grpc_chttp2_transport* t, grpc_chttp2_stream* s, - grpc_slice slice, int is_last); + const grpc_slice& slice, + int is_last); #endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HPACK_PARSER_H */ diff --git a/src/core/ext/transport/chttp2/transport/hpack_table.cc b/src/core/ext/transport/chttp2/transport/hpack_table.cc index fcfb01872bf..16aeb49df4d 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 @@ void grpc_chttp2_hptbl_set_max_bytes(grpc_chttp2_hptbl* tbl, if (tbl->max_bytes == max_bytes) { return; } - if (grpc_http_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_http_trace)) { gpr_log(GPR_INFO, "Update hpack parser max size to %d", max_bytes); } while (tbl->mem_used > max_bytes) { @@ -270,7 +270,7 @@ grpc_error* grpc_chttp2_hptbl_set_current_table_size(grpc_chttp2_hptbl* tbl, gpr_free(msg); return err; } - if (grpc_http_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_http_trace)) { gpr_log(GPR_INFO, "Update hpack parser table size to %d", bytes); } while (tbl->mem_used > bytes) { diff --git a/src/core/ext/transport/chttp2/transport/incoming_metadata.cc b/src/core/ext/transport/chttp2/transport/incoming_metadata.cc index dca15e76803..02623c978d7 100644 --- a/src/core/ext/transport/chttp2/transport/incoming_metadata.cc +++ b/src/core/ext/transport/chttp2/transport/incoming_metadata.cc @@ -30,11 +30,15 @@ grpc_error* grpc_chttp2_incoming_metadata_buffer_add( grpc_chttp2_incoming_metadata_buffer* buffer, grpc_mdelem elem) { buffer->size += GRPC_MDELEM_LENGTH(elem); - return grpc_metadata_batch_add_tail( - &buffer->batch, - static_cast( - gpr_arena_alloc(buffer->arena, sizeof(grpc_linked_mdelem))), - elem); + grpc_linked_mdelem* storage; + if (buffer->count < buffer->kPreallocatedMDElem) { + storage = &buffer->preallocated_mdelems[buffer->count]; + buffer->count++; + } else { + storage = static_cast( + buffer->arena->Alloc(sizeof(grpc_linked_mdelem))); + } + return grpc_metadata_batch_add_tail(&buffer->batch, storage, elem); } grpc_error* grpc_chttp2_incoming_metadata_buffer_replace_or_add( diff --git a/src/core/ext/transport/chttp2/transport/incoming_metadata.h b/src/core/ext/transport/chttp2/transport/incoming_metadata.h index c551b3cc8be..b63caa1ae25 100644 --- a/src/core/ext/transport/chttp2/transport/incoming_metadata.h +++ b/src/core/ext/transport/chttp2/transport/incoming_metadata.h @@ -24,7 +24,8 @@ #include "src/core/lib/transport/transport.h" struct grpc_chttp2_incoming_metadata_buffer { - grpc_chttp2_incoming_metadata_buffer(gpr_arena* arena) : arena(arena) { + explicit grpc_chttp2_incoming_metadata_buffer(grpc_core::Arena* arena) + : arena(arena) { grpc_metadata_batch_init(&batch); batch.deadline = GRPC_MILLIS_INF_FUTURE; } @@ -32,9 +33,14 @@ struct grpc_chttp2_incoming_metadata_buffer { grpc_metadata_batch_destroy(&batch); } - gpr_arena* arena; + static constexpr size_t kPreallocatedMDElem = 10; + + grpc_core::Arena* arena; + size_t size = 0; // total size of metadata. + size_t count = 0; // minimum of count of metadata and kPreallocatedMDElem. + // These preallocated mdelems are used while count < kPreallocatedMDElem. + grpc_linked_mdelem preallocated_mdelems[kPreallocatedMDElem]; grpc_metadata_batch batch; - size_t size = 0; // total size of metadata }; void grpc_chttp2_incoming_metadata_buffer_publish( diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index 3ee408c103e..0322dc72837 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -45,6 +45,10 @@ #include "src/core/lib/transport/connectivity_state.h" #include "src/core/lib/transport/transport_impl.h" +namespace grpc_core { +class ContextList; +} + /* streams are kept in various linked lists depending on what things need to happen to them... this enum labels each list */ typedef enum { @@ -221,23 +225,27 @@ class Chttp2IncomingByteStream : public ByteStream { // TODO(roth): When I converted this class to C++, I wanted to make it // inherit from RefCounted or InternallyRefCounted instead of continuing // to use its own custom ref-counting code. However, that would require - // using multiple inheritence, which sucks in general. And to make matters + // using multiple inheritance, which sucks in general. And to make matters // worse, it causes problems with our New<> and Delete<> wrappers. // Specifically, unless RefCounted is first in the list of parent classes, // it will see a different value of the address of the object than the one // we actually allocated, in which case gpr_free() will be called on a // different address than the one we got from gpr_malloc(), thus causing a // crash. Given the fragility of depending on that, as well as a desire to - // avoid multiple inheritence in general, I've decided to leave this + // avoid multiple inheritance in general, I've decided to leave this // alone for now. We can revisit this once we're able to link against // libc++, at which point we can eliminate New<> and Delete<> and // switch to std::shared_ptr<>. - void Ref(); - void Unref(); + void Ref() { refs_.Ref(); } + void Unref() { + if (GPR_UNLIKELY(refs_.Unref())) { + grpc_core::Delete(this); + } + } void PublishError(grpc_error* error); - grpc_error* Push(grpc_slice slice, grpc_slice* slice_out); + grpc_error* Push(const grpc_slice& slice, grpc_slice* slice_out); grpc_error* Finished(grpc_error* error, bool reset_on_error); @@ -252,7 +260,7 @@ class Chttp2IncomingByteStream : public ByteStream { grpc_chttp2_transport* transport_; // Immutable. grpc_chttp2_stream* stream_; // Immutable. - gpr_refcount refs_; + grpc_core::RefCount refs_; /* Accessed only by transport thread when stream->pending_byte_stream == false * Accessed only by application thread when stream->pending_byte_stream == @@ -286,7 +294,7 @@ struct grpc_chttp2_transport { ~grpc_chttp2_transport(); grpc_transport base; /* must be first */ - gpr_refcount refs; + grpc_core::RefCount refs; grpc_endpoint* ep; char* peer_string; @@ -430,7 +438,8 @@ struct grpc_chttp2_transport { void* parser_data = nullptr; grpc_chttp2_stream* incoming_stream = nullptr; grpc_error* (*parser)(void* parser_user_data, grpc_chttp2_transport* t, - grpc_chttp2_stream* s, grpc_slice slice, int is_last); + grpc_chttp2_stream* s, const grpc_slice& slice, + int is_last); grpc_chttp2_write_cb* write_cb_pool = nullptr; @@ -481,7 +490,7 @@ struct grpc_chttp2_transport { bool keepalive_permit_without_calls = false; /** keep-alive state machine state */ grpc_chttp2_keepalive_state keepalive_state; - + grpc_core::ContextList* cl = nullptr; grpc_core::RefCountedPtr channelz_socket; uint32_t num_messages_in_next_write = 0; }; @@ -495,11 +504,18 @@ typedef enum { struct grpc_chttp2_stream { grpc_chttp2_stream(grpc_chttp2_transport* t, grpc_stream_refcount* refcount, - const void* server_data, gpr_arena* arena); + const void* server_data, grpc_core::Arena* arena); ~grpc_chttp2_stream(); + void* context; grpc_chttp2_transport* t; grpc_stream_refcount* refcount; + // Reffer is a 0-len structure, simply reffing `t` and `refcount` in its ctor + // before initializing the rest of the stream, to avoid cache misses. This + // field MUST be right after `t` and `refcount`. + struct Reffer { + explicit Reffer(grpc_chttp2_stream* s); + } reffer; grpc_closure destroy_stream; grpc_closure* destroy_stream_arg; @@ -567,10 +583,6 @@ struct grpc_chttp2_stream { grpc_slice_buffer frame_storage; /* protected by t combiner */ - /* Accessed only by transport thread when stream->pending_byte_stream == false - * Accessed only by application thread when stream->pending_byte_stream == - * true */ - grpc_slice_buffer unprocessed_incoming_frames_buffer; grpc_closure* on_next = nullptr; /* protected by t combiner */ bool pending_byte_stream = false; /* protected by t combiner */ // cached length of buffer to be used by the transport thread in cases where @@ -578,6 +590,10 @@ struct grpc_chttp2_stream { // application threads are allowed to modify // unprocessed_incoming_frames_buffer size_t unprocessed_incoming_frames_buffer_cached_length = 0; + /* Accessed only by transport thread when stream->pending_byte_stream == false + * Accessed only by application thread when stream->pending_byte_stream == + * true */ + grpc_slice_buffer unprocessed_incoming_frames_buffer; grpc_closure reset_byte_stream; grpc_error* byte_stream_error = GRPC_ERROR_NONE; /* protected by t combiner */ bool received_last_frame = false; /* protected by t combiner */ @@ -617,24 +633,33 @@ struct grpc_chttp2_stream { GRPC_STREAM_COMPRESSION_IDENTITY_COMPRESS; /* Stream decompression method to be used. */ grpc_stream_compression_method stream_decompression_method = - GRPC_STREAM_COMPRESSION_IDENTITY_COMPRESS; - /** Stream compression decompress context */ - grpc_stream_compression_context* stream_decompression_ctx = nullptr; - /** Stream compression compress context */ - grpc_stream_compression_context* stream_compression_ctx = nullptr; + GRPC_STREAM_COMPRESSION_IDENTITY_DECOMPRESS; - /** Buffer storing data that is compressed but not sent */ - grpc_slice_buffer compressed_data_buffer; - /** Amount of uncompressed bytes sent out when compressed_data_buffer is - * emptied */ - size_t uncompressed_data_size = 0; - /** Temporary buffer storing decompressed data */ - grpc_slice_buffer decompressed_data_buffer; /** Whether bytes stored in unprocessed_incoming_byte_stream is decompressed */ bool unprocessed_incoming_frames_decompressed = false; + /** Whether the bytes needs to be traced using Fathom */ + bool traced = false; /** gRPC header bytes that are already decompressed */ size_t decompressed_header_bytes = 0; + /** Byte counter for number of bytes written */ + size_t byte_counter = 0; + + /** Amount of uncompressed bytes sent out when compressed_data_buffer is + * emptied */ + size_t uncompressed_data_size; + /** Stream compression compress context */ + grpc_stream_compression_context* stream_compression_ctx; + /** Buffer storing data that is compressed but not sent */ + grpc_slice_buffer compressed_data_buffer; + + /** Stream compression decompress context */ + grpc_stream_compression_context* stream_decompression_ctx; + /** Temporary buffer storing decompressed data. + * Initialized, used, and destroyed only when stream uses (non-identity) + * compression. + */ + grpc_slice_buffer decompressed_data_buffer; }; /** Transport writing call flow: @@ -668,7 +693,7 @@ void grpc_chttp2_end_write(grpc_chttp2_transport* t, grpc_error* error); /** Process one slice of incoming data; return 1 if the connection is still viable after reading, or 0 if the connection should be torn down */ grpc_error* grpc_chttp2_perform_read(grpc_chttp2_transport* t, - grpc_slice slice); + const grpc_slice& slice); bool grpc_chttp2_list_add_writable_stream(grpc_chttp2_transport* t, grpc_chttp2_stream* s); @@ -727,7 +752,7 @@ grpc_chttp2_stream* grpc_chttp2_parsing_accept_stream(grpc_chttp2_transport* t, void grpc_chttp2_add_incoming_goaway(grpc_chttp2_transport* t, uint32_t goaway_error, - grpc_slice goaway_text); + const grpc_slice& goaway_text); void grpc_chttp2_parsing_become_skip_parser(grpc_chttp2_transport* t); @@ -746,11 +771,12 @@ void grpc_chttp2_complete_closure_step(grpc_chttp2_transport* t, // extern grpc_core::TraceFlag grpc_http_trace; // extern grpc_core::TraceFlag grpc_flowctl_trace; -#define GRPC_CHTTP2_IF_TRACING(stmt) \ - if (!(grpc_http_trace.enabled())) \ - ; \ - else \ - stmt +#define GRPC_CHTTP2_IF_TRACING(stmt) \ + do { \ + if (GRPC_TRACE_FLAG_ENABLED(grpc_http_trace)) { \ + (stmt); \ + } \ + } while (0) void grpc_chttp2_fake_status(grpc_chttp2_transport* t, grpc_chttp2_stream* stream, grpc_error* error); @@ -779,15 +805,29 @@ void grpc_chttp2_stream_unref(grpc_chttp2_stream* s); grpc_chttp2_ref_transport(t, r, __FILE__, __LINE__) #define GRPC_CHTTP2_UNREF_TRANSPORT(t, r) \ grpc_chttp2_unref_transport(t, r, __FILE__, __LINE__) -void grpc_chttp2_unref_transport(grpc_chttp2_transport* t, const char* reason, - const char* file, int line); -void grpc_chttp2_ref_transport(grpc_chttp2_transport* t, const char* reason, - const char* file, int line); +inline void grpc_chttp2_unref_transport(grpc_chttp2_transport* t, + const char* reason, const char* file, + int line) { + if (t->refs.Unref(grpc_core::DebugLocation(file, line), reason)) { + grpc_core::Delete(t); + } +} +inline void grpc_chttp2_ref_transport(grpc_chttp2_transport* t, + const char* reason, const char* file, + int line) { + t->refs.Ref(grpc_core::DebugLocation(file, line), reason); +} #else #define GRPC_CHTTP2_REF_TRANSPORT(t, r) grpc_chttp2_ref_transport(t) #define GRPC_CHTTP2_UNREF_TRANSPORT(t, r) grpc_chttp2_unref_transport(t) -void grpc_chttp2_unref_transport(grpc_chttp2_transport* t); -void grpc_chttp2_ref_transport(grpc_chttp2_transport* t); +inline void grpc_chttp2_unref_transport(grpc_chttp2_transport* t) { + if (t->refs.Unref()) { + grpc_core::Delete(t); + } +} +inline void grpc_chttp2_ref_transport(grpc_chttp2_transport* t) { + t->refs.Ref(); +} #endif void grpc_chttp2_ack_ping(grpc_chttp2_transport* t, uint64_t id); diff --git a/src/core/ext/transport/chttp2/transport/parsing.cc b/src/core/ext/transport/chttp2/transport/parsing.cc index 1ff96d3cd36..1aa6d971684 100644 --- a/src/core/ext/transport/chttp2/transport/parsing.cc +++ b/src/core/ext/transport/chttp2/transport/parsing.cc @@ -28,6 +28,7 @@ #include "src/core/lib/profiling/timers.h" #include "src/core/lib/slice/slice_string_helpers.h" +#include "src/core/lib/slice/slice_utils.h" #include "src/core/lib/transport/http2_errors.h" #include "src/core/lib/transport/static_metadata.h" #include "src/core/lib/transport/status_conversion.h" @@ -45,14 +46,14 @@ static grpc_error* init_goaway_parser(grpc_chttp2_transport* t); static grpc_error* init_skip_frame_parser(grpc_chttp2_transport* t, int is_header); -static grpc_error* parse_frame_slice(grpc_chttp2_transport* t, grpc_slice slice, - int is_last); +static grpc_error* parse_frame_slice(grpc_chttp2_transport* t, + const grpc_slice& slice, int is_last); grpc_error* grpc_chttp2_perform_read(grpc_chttp2_transport* t, - grpc_slice slice) { - uint8_t* beg = GRPC_SLICE_START_PTR(slice); - uint8_t* end = GRPC_SLICE_END_PTR(slice); - uint8_t* cur = beg; + const grpc_slice& slice) { + const uint8_t* beg = GRPC_SLICE_START_PTR(slice); + const uint8_t* end = GRPC_SLICE_END_PTR(slice); + const uint8_t* cur = beg; grpc_error* err; if (cur == end) return GRPC_ERROR_NONE; @@ -304,7 +305,7 @@ static grpc_error* init_frame_parser(grpc_chttp2_transport* t) { case GRPC_CHTTP2_FRAME_GOAWAY: return init_goaway_parser(t); default: - if (grpc_http_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_http_trace)) { gpr_log(GPR_ERROR, "Unknown frame type %02x", t->incoming_frame_type); } return init_skip_frame_parser(t, 0); @@ -312,7 +313,7 @@ static grpc_error* init_frame_parser(grpc_chttp2_transport* t) { } static grpc_error* skip_parser(void* parser, grpc_chttp2_transport* t, - grpc_chttp2_stream* s, grpc_slice slice, + grpc_chttp2_stream* s, const grpc_slice& slice, int is_last) { return GRPC_ERROR_NONE; } @@ -400,7 +401,7 @@ static void on_initial_header(void* tp, grpc_mdelem md) { grpc_chttp2_stream* s = t->incoming_stream; GPR_ASSERT(s != nullptr); - if (grpc_http_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_http_trace)) { char* key = grpc_slice_to_c_string(GRPC_MDKEY(md)); char* value = grpc_dump_slice(GRPC_MDVALUE(md), GPR_DUMP_HEX | GPR_DUMP_ASCII); @@ -410,53 +411,42 @@ static void on_initial_header(void* tp, grpc_mdelem md) { gpr_free(value); } - if (GRPC_MDELEM_STORAGE(md) == GRPC_MDELEM_STORAGE_STATIC) { - // We don't use grpc_mdelem_eq here to avoid executing additional - // instructions. The reasoning is if the payload is not equal, we already - // know that the metadata elements are not equal because the md is - // confirmed to be static. If we had used grpc_mdelem_eq here, then if the - // payloads are not equal, grpc_mdelem_eq executes more instructions to - // determine if they're equal or not. - if (md.payload == GRPC_MDELEM_GRPC_STATUS_1.payload || - md.payload == GRPC_MDELEM_GRPC_STATUS_2.payload) { - s->seen_error = true; - } - } else { - if (grpc_slice_eq(GRPC_MDKEY(md), GRPC_MDSTR_GRPC_STATUS) && - !grpc_mdelem_eq(md, GRPC_MDELEM_GRPC_STATUS_0)) { - /* TODO(ctiller): check for a status like " 0" */ - s->seen_error = true; - } - - if (grpc_slice_eq(GRPC_MDKEY(md), GRPC_MDSTR_GRPC_TIMEOUT)) { - grpc_millis* cached_timeout = static_cast( - grpc_mdelem_get_user_data(md, free_timeout)); - grpc_millis timeout; - if (cached_timeout != nullptr) { - timeout = *cached_timeout; - } else { - if (GPR_UNLIKELY( - !grpc_http2_decode_timeout(GRPC_MDVALUE(md), &timeout))) { - char* val = grpc_slice_to_c_string(GRPC_MDVALUE(md)); - gpr_log(GPR_ERROR, "Ignoring bad timeout value '%s'", val); - gpr_free(val); - timeout = GRPC_MILLIS_INF_FUTURE; - } - if (GRPC_MDELEM_IS_INTERNED(md)) { - /* store the result */ - cached_timeout = - static_cast(gpr_malloc(sizeof(grpc_millis))); - *cached_timeout = timeout; - grpc_mdelem_set_user_data(md, free_timeout, cached_timeout); - } + // If md.payload == GRPC_MDELEM_GRPC_STATUS_1 or GRPC_MDELEM_GRPC_STATUS_2, + // then we have seen an error. In fact, if it is a GRPC_STATUS and it's + // not equal to GRPC_MDELEM_GRPC_STATUS_0, then we have seen an error. + if (grpc_slice_eq_static_interned(GRPC_MDKEY(md), GRPC_MDSTR_GRPC_STATUS) && + !grpc_mdelem_static_value_eq(md, GRPC_MDELEM_GRPC_STATUS_0)) { + /* TODO(ctiller): check for a status like " 0" */ + s->seen_error = true; + } else if (grpc_slice_eq_static_interned(GRPC_MDKEY(md), + GRPC_MDSTR_GRPC_TIMEOUT)) { + grpc_millis* cached_timeout = + static_cast(grpc_mdelem_get_user_data(md, free_timeout)); + grpc_millis timeout; + if (cached_timeout != nullptr) { + timeout = *cached_timeout; + } else { + if (GPR_UNLIKELY( + !grpc_http2_decode_timeout(GRPC_MDVALUE(md), &timeout))) { + char* val = grpc_slice_to_c_string(GRPC_MDVALUE(md)); + gpr_log(GPR_ERROR, "Ignoring bad timeout value '%s'", val); + gpr_free(val); + timeout = GRPC_MILLIS_INF_FUTURE; } - if (timeout != GRPC_MILLIS_INF_FUTURE) { - grpc_chttp2_incoming_metadata_buffer_set_deadline( - &s->metadata_buffer[0], grpc_core::ExecCtx::Get()->Now() + timeout); + if (GRPC_MDELEM_IS_INTERNED(md)) { + /* store the result */ + cached_timeout = + static_cast(gpr_malloc(sizeof(grpc_millis))); + *cached_timeout = timeout; + grpc_mdelem_set_user_data(md, free_timeout, cached_timeout); } - GRPC_MDELEM_UNREF(md); - return; } + if (timeout != GRPC_MILLIS_INF_FUTURE) { + grpc_chttp2_incoming_metadata_buffer_set_deadline( + &s->metadata_buffer[0], grpc_core::ExecCtx::Get()->Now() + timeout); + } + GRPC_MDELEM_UNREF(md); + return; } const size_t new_size = s->metadata_buffer[0].size + GRPC_MDELEM_LENGTH(md); @@ -496,7 +486,7 @@ static void on_trailing_header(void* tp, grpc_mdelem md) { grpc_chttp2_stream* s = t->incoming_stream; GPR_ASSERT(s != nullptr); - if (grpc_http_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_http_trace)) { char* key = grpc_slice_to_c_string(GRPC_MDKEY(md)); char* value = grpc_dump_slice(GRPC_MDVALUE(md), GPR_DUMP_HEX | GPR_DUMP_ASCII); @@ -506,19 +496,11 @@ static void on_trailing_header(void* tp, grpc_mdelem md) { gpr_free(value); } - if (GRPC_MDELEM_STORAGE(md) == GRPC_MDELEM_STORAGE_STATIC) { - // We don't use grpc_mdelem_eq here to avoid executing additional - // instructions. The reasoning is if the payload is not equal, we already - // know that the metadata elements are not equal because the md is - // confirmed to be static. If we had used grpc_mdelem_eq here, then if the - // payloads are not equal, grpc_mdelem_eq executes more instructions to - // determine if they're equal or not. - if (md.payload == GRPC_MDELEM_GRPC_STATUS_1.payload || - md.payload == GRPC_MDELEM_GRPC_STATUS_2.payload) { - s->seen_error = true; - } - } else if (grpc_slice_eq(GRPC_MDKEY(md), GRPC_MDSTR_GRPC_STATUS) && - !grpc_mdelem_eq(md, GRPC_MDELEM_GRPC_STATUS_0)) { + // If md.payload == GRPC_MDELEM_GRPC_STATUS_1 or GRPC_MDELEM_GRPC_STATUS_2, + // then we have seen an error. In fact, if it is a GRPC_STATUS and it's + // not equal to GRPC_MDELEM_GRPC_STATUS_0, then we have seen an error. + if (grpc_slice_eq_static_interned(GRPC_MDKEY(md), GRPC_MDSTR_GRPC_STATUS) && + !grpc_mdelem_static_value_eq(md, GRPC_MDELEM_GRPC_STATUS_0)) { /* TODO(ctiller): check for a status like " 0" */ s->seen_error = true; } @@ -753,15 +735,15 @@ static grpc_error* init_settings_frame_parser(grpc_chttp2_transport* t) { return GRPC_ERROR_NONE; } -static grpc_error* parse_frame_slice(grpc_chttp2_transport* t, grpc_slice slice, - int is_last) { +static grpc_error* parse_frame_slice(grpc_chttp2_transport* t, + const grpc_slice& slice, int is_last) { grpc_chttp2_stream* s = t->incoming_stream; grpc_error* err = t->parser(t->parser_data, t, s, slice, is_last); intptr_t unused; if (GPR_LIKELY(err == GRPC_ERROR_NONE)) { return err; } else if (grpc_error_get_int(err, GRPC_ERROR_INT_STREAM_ID, &unused)) { - if (grpc_http_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_http_trace)) { const char* msg = grpc_error_string(err); gpr_log(GPR_ERROR, "%s", msg); } diff --git a/src/core/ext/transport/chttp2/transport/stream_lists.cc b/src/core/ext/transport/chttp2/transport/stream_lists.cc index 6626170a7e4..db79899dedc 100644 --- a/src/core/ext/transport/chttp2/transport/stream_lists.cc +++ b/src/core/ext/transport/chttp2/transport/stream_lists.cc @@ -67,7 +67,7 @@ static bool stream_list_pop(grpc_chttp2_transport* t, s->included[id] = 0; } *stream = s; - if (s && grpc_trace_http2_stream_state.enabled()) { + if (s && GRPC_TRACE_FLAG_ENABLED(grpc_trace_http2_stream_state)) { gpr_log(GPR_INFO, "%p[%d][%s]: pop from %s", t, s->id, t->is_client ? "cli" : "svr", stream_list_id_string(id)); } @@ -89,7 +89,7 @@ static void stream_list_remove(grpc_chttp2_transport* t, grpc_chttp2_stream* s, } else { t->lists[id].tail = s->links[id].prev; } - if (grpc_trace_http2_stream_state.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_trace_http2_stream_state)) { gpr_log(GPR_INFO, "%p[%d][%s]: remove from %s", t, s->id, t->is_client ? "cli" : "svr", stream_list_id_string(id)); } @@ -121,7 +121,7 @@ static void stream_list_add_tail(grpc_chttp2_transport* t, } t->lists[id].tail = s; s->included[id] = 1; - if (grpc_trace_http2_stream_state.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_trace_http2_stream_state)) { 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 d533989444c..f3cb390dc7a 100644 --- a/src/core/ext/transport/chttp2/transport/writing.cc +++ b/src/core/ext/transport/chttp2/transport/writing.cc @@ -18,12 +18,14 @@ #include +#include "src/core/ext/transport/chttp2/transport/context_list.h" #include "src/core/ext/transport/chttp2/transport/internal.h" #include #include +#include "src/core/lib/compression/stream_compression.h" #include "src/core/lib/debug/stats.h" #include "src/core/lib/profiling/timers.h" #include "src/core/lib/slice/slice_internal.h" @@ -51,7 +53,8 @@ static void maybe_initiate_ping(grpc_chttp2_transport* t) { } 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()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_http_trace) || + GRPC_TRACE_FLAG_ENABLED(grpc_bdp_estimator_trace)) { gpr_log(GPR_INFO, "%s: Ping delayed [%p]: already pinging", t->is_client ? "CLIENT" : "SERVER", t->peer_string); } @@ -60,7 +63,8 @@ static void maybe_initiate_ping(grpc_chttp2_transport* t) { if (t->ping_state.pings_before_data_required == 0 && 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()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_http_trace) || + GRPC_TRACE_FLAG_ENABLED(grpc_bdp_estimator_trace)) { 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, @@ -80,7 +84,8 @@ static void maybe_initiate_ping(grpc_chttp2_transport* t) { if (next_allowed_ping > now) { /* not enough elapsed time between successive pings */ - if (grpc_http_trace.enabled() || grpc_bdp_estimator_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_http_trace) || + GRPC_TRACE_FLAG_ENABLED(grpc_bdp_estimator_trace)) { gpr_log(GPR_INFO, "%s: Ping delayed [%p]: not enough time elapsed since last ping. " " Last ping %f: Next ping %f: Now %f", @@ -106,8 +111,9 @@ static void maybe_initiate_ping(grpc_chttp2_transport* t) { grpc_chttp2_ping_create(false, pq->inflight_id)); 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_INFO, "%s: Ping sent [%p]: %d/%d", + if (GRPC_TRACE_FLAG_ENABLED(grpc_http_trace) || + GRPC_TRACE_FLAG_ENABLED(grpc_bdp_estimator_trace)) { + gpr_log(GPR_INFO, "%s: Ping sent [%s]: %d/%d", t->is_client ? "CLIENT" : "SERVER", t->peer_string, t->ping_state.pings_before_data_required, t->ping_policy.max_pings_without_data); @@ -139,7 +145,7 @@ static bool update_list(grpc_chttp2_transport* t, grpc_chttp2_stream* s, static void report_stall(grpc_chttp2_transport* t, grpc_chttp2_stream* s, const char* staller) { - if (grpc_flowctl_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_flowctl_trace)) { gpr_log( GPR_DEBUG, "%s:%p stream %d moved to stalled list by %s. This is FULLY expected " @@ -149,7 +155,11 @@ static void report_stall(grpc_chttp2_transport* t, grpc_chttp2_stream* s, ":flowed=%" PRId64 ":peer_initwin=%d:t_win=%" PRId64 ":s_win=%d:s_delta=%" PRId64 "]", t->peer_string, t, s->id, staller, s->flow_controlled_buffer.length, - s->compressed_data_buffer.length, s->flow_controlled_bytes_flowed, + s->stream_compression_method == + GRPC_STREAM_COMPRESSION_IDENTITY_COMPRESS + ? 0 + : s->compressed_data_buffer.length, + s->flow_controlled_bytes_flowed, t->settings[GRPC_ACKED_SETTINGS] [GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE], t->flow_control->remote_window(), @@ -162,15 +172,6 @@ static void report_stall(grpc_chttp2_transport* t, grpc_chttp2_stream* s, } } -static bool stream_ref_if_not_destroyed(gpr_refcount* r) { - gpr_atm count; - do { - count = gpr_atm_acq_load(&r->count); - if (count == 0) return false; - } while (!gpr_atm_rel_cas(&r->count, count, count + 1)); - return true; -} - /* How many bytes would we like to put on the wire during a single syscall */ static uint32_t target_write_size(grpc_chttp2_transport* t) { return 1024 * 1024; @@ -253,7 +254,7 @@ class WriteContext { while (grpc_chttp2_list_pop_stalled_by_transport(t_, &s)) { if (t_->closed_with_error == GRPC_ERROR_NONE && grpc_chttp2_list_add_writable_stream(t_, s)) { - if (!stream_ref_if_not_destroyed(&s->refcount->refs)) { + if (!s->refcount->refs.RefIfNonZero()) { grpc_chttp2_list_remove_writable_stream(t_, s); } } @@ -333,7 +334,23 @@ class DataSendContext { bool AnyOutgoing() const { return max_outgoing() > 0; } + void FlushUncompressedBytes() { + uint32_t send_bytes = static_cast GPR_MIN( + max_outgoing(), s_->flow_controlled_buffer.length); + is_last_frame_ = send_bytes == s_->flow_controlled_buffer.length && + s_->fetching_send_message == nullptr && + s_->send_trailing_metadata != nullptr && + grpc_metadata_batch_is_empty(s_->send_trailing_metadata); + grpc_chttp2_encode_data(s_->id, &s_->flow_controlled_buffer, send_bytes, + is_last_frame_, &s_->stats.outgoing, &t_->outbuf); + s_->flow_control->SentData(send_bytes); + s_->sending_bytes += send_bytes; + } + void FlushCompressedBytes() { + GPR_DEBUG_ASSERT(s_->stream_compression_method != + GRPC_STREAM_COMPRESSION_IDENTITY_COMPRESS); + uint32_t send_bytes = static_cast GPR_MIN( max_outgoing(), s_->compressed_data_buffer.length); bool is_last_data_frame = @@ -368,6 +385,9 @@ class DataSendContext { } void CompressMoreBytes() { + GPR_DEBUG_ASSERT(s_->stream_compression_method != + GRPC_STREAM_COMPRESSION_IDENTITY_COMPRESS); + if (s_->stream_compression_ctx == nullptr) { s_->stream_compression_ctx = grpc_stream_compression_context_create(s_->stream_compression_method); @@ -425,7 +445,7 @@ class StreamWriteContext { // https://github.com/grpc/proposal/blob/master/A6-client-retries.md#when-retries-are-valid if (!t_->is_client && s_->fetching_send_message == nullptr && s_->flow_controlled_buffer.length == 0 && - s_->compressed_data_buffer.length == 0 && + compressed_data_buffer_len() == 0 && s_->send_trailing_metadata != nullptr && is_default_initial_metadata(s_->send_initial_metadata)) { ConvertInitialMetadataToTrailingMetadata(); @@ -454,6 +474,13 @@ class StreamWriteContext { "send_initial_metadata_finished"); } + bool compressed_data_buffer_len() { + return s_->stream_compression_method == + GRPC_STREAM_COMPRESSION_IDENTITY_COMPRESS + ? 0 + : s_->compressed_data_buffer.length; + } + void FlushWindowUpdates() { /* send any window updates */ const uint32_t stream_announce = s_->flow_control->MaybeSendUpdate(); @@ -470,7 +497,7 @@ class StreamWriteContext { if (!s_->sent_initial_metadata) return; if (s_->flow_controlled_buffer.length == 0 && - s_->compressed_data_buffer.length == 0) { + compressed_data_buffer_len() == 0) { return; // early out: nothing to do } @@ -487,13 +514,21 @@ class StreamWriteContext { return; // early out: nothing to do } - while ((s_->flow_controlled_buffer.length > 0 || - s_->compressed_data_buffer.length > 0) && - data_send_context.max_outgoing() > 0) { - if (s_->compressed_data_buffer.length > 0) { - data_send_context.FlushCompressedBytes(); - } else { - data_send_context.CompressMoreBytes(); + if (s_->stream_compression_method == + GRPC_STREAM_COMPRESSION_IDENTITY_COMPRESS) { + while (s_->flow_controlled_buffer.length > 0 && + data_send_context.max_outgoing() > 0) { + data_send_context.FlushUncompressedBytes(); + } + } else { + while ((s_->flow_controlled_buffer.length > 0 || + s_->compressed_data_buffer.length > 0) && + data_send_context.max_outgoing() > 0) { + if (s_->compressed_data_buffer.length > 0) { + data_send_context.FlushCompressedBytes(); + } else { + data_send_context.CompressMoreBytes(); + } } } write_context_->ResetPingClock(); @@ -503,7 +538,7 @@ class StreamWriteContext { data_send_context.CallCallbacks(); stream_became_writable_ = true; if (s_->flow_controlled_buffer.length > 0 || - s_->compressed_data_buffer.length > 0) { + compressed_data_buffer_len() > 0) { GRPC_CHTTP2_STREAM_REF(s_, "chttp2_writing:fork"); grpc_chttp2_list_add_writable_stream(t_, s_); } @@ -516,7 +551,7 @@ class StreamWriteContext { if (s_->send_trailing_metadata == nullptr) return; if (s_->fetching_send_message != nullptr) return; if (s_->flow_controlled_buffer.length != 0) return; - if (s_->compressed_data_buffer.length != 0) return; + if (compressed_data_buffer_len() != 0) return; GRPC_CHTTP2_IF_TRACING(gpr_log(GPR_INFO, "sending trailing_metadata")); if (grpc_metadata_batch_is_empty(s_->send_trailing_metadata)) { @@ -605,11 +640,18 @@ grpc_chttp2_begin_write_result grpc_chttp2_begin_write( (according to available window sizes) and add to the output buffer */ while (grpc_chttp2_stream* s = ctx.NextStream()) { StreamWriteContext stream_ctx(&ctx, s); + size_t orig_len = t->outbuf.length; stream_ctx.FlushInitialMetadata(); stream_ctx.FlushWindowUpdates(); stream_ctx.FlushData(); stream_ctx.FlushTrailingMetadata(); - + if (t->outbuf.length > orig_len) { + /* Add this stream to the list of the contexts to be traced at TCP */ + s->byte_counter += t->outbuf.length - orig_len; + if (s->traced && grpc_endpoint_can_track_err(t->ep)) { + grpc_core::ContextList::Append(&t->cl, s); + } + } if (stream_ctx.stream_became_writable()) { if (!grpc_chttp2_list_add_writing_stream(t, s)) { /* already in writing list: drop ref */ diff --git a/src/core/ext/transport/cronet/client/secure/cronet_channel_create.cc b/src/core/ext/transport/cronet/client/secure/cronet_channel_create.cc index 40a30e4a31d..6e08d27b21d 100644 --- a/src/core/ext/transport/cronet/client/secure/cronet_channel_create.cc +++ b/src/core/ext/transport/cronet/client/secure/cronet_channel_create.cc @@ -46,9 +46,21 @@ GRPCAPI grpc_channel* grpc_cronet_secure_channel_create( "grpc_create_cronet_transport: stream_engine = %p, target=%s", engine, target); + // Disable client authority filter when using Cronet + grpc_arg disable_client_authority_filter_arg; + disable_client_authority_filter_arg.key = + const_cast(GRPC_ARG_DISABLE_CLIENT_AUTHORITY_FILTER); + disable_client_authority_filter_arg.type = GRPC_ARG_INTEGER; + disable_client_authority_filter_arg.value.integer = 1; + grpc_channel_args* new_args = grpc_channel_args_copy_and_add( + args, &disable_client_authority_filter_arg, 1); + grpc_transport* ct = - grpc_create_cronet_transport(engine, target, args, reserved); + grpc_create_cronet_transport(engine, target, new_args, reserved); grpc_core::ExecCtx exec_ctx; - return grpc_channel_create(target, args, GRPC_CLIENT_DIRECT_CHANNEL, ct); + grpc_channel* channel = + grpc_channel_create(target, new_args, GRPC_CLIENT_DIRECT_CHANNEL, ct); + grpc_channel_args_destroy(new_args); + return channel; } diff --git a/src/core/ext/transport/cronet/transport/cronet_transport.cc b/src/core/ext/transport/cronet/transport/cronet_transport.cc index 349d8681d55..413de807638 100644 --- a/src/core/ext/transport/cronet/transport/cronet_transport.cc +++ b/src/core/ext/transport/cronet/transport/cronet_transport.cc @@ -29,6 +29,7 @@ #include "src/core/ext/transport/chttp2/transport/bin_encoder.h" #include "src/core/ext/transport/chttp2/transport/incoming_metadata.h" #include "src/core/ext/transport/cronet/transport/cronet_transport.h" +#include "src/core/lib/debug/trace.h" #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gprpp/manual_constructor.h" @@ -45,14 +46,12 @@ #define GRPC_HEADER_SIZE_IN_BYTES 5 #define GRPC_FLUSH_READ_SIZE 4096 -#define CRONET_LOG(...) \ - do { \ - if (grpc_cronet_trace) gpr_log(__VA_ARGS__); \ +grpc_core::TraceFlag grpc_cronet_trace(false, "cronet"); +#define CRONET_LOG(...) \ + do { \ + if (grpc_cronet_trace.enabled()) gpr_log(__VA_ARGS__); \ } while (0) -/* TODO (makdharma): Hook up into the wider tracing mechanism */ -int grpc_cronet_trace = 0; - enum e_op_result { ACTION_TAKEN_WITH_CALLBACK, ACTION_TAKEN_NO_CALLBACK, @@ -111,7 +110,7 @@ typedef struct grpc_cronet_transport grpc_cronet_transport; /* TODO (makdharma): reorder structure for memory efficiency per http://www.catb.org/esr/structure-packing/#_structure_reordering: */ struct read_state { - read_state(gpr_arena* arena) + read_state(grpc_core::Arena* arena) : trailing_metadata(arena), initial_metadata(arena) { grpc_slice_buffer_init(&read_slice_buffer); } @@ -145,7 +144,7 @@ struct write_state { /* track state of one stream op */ struct op_state { - op_state(gpr_arena* arena) : rs(arena) {} + op_state(grpc_core::Arena* arena) : rs(arena) {} bool state_op_done[OP_NUM_OPS] = {}; bool state_callback_received[OP_NUM_OPS] = {}; @@ -177,7 +176,7 @@ struct op_and_state { bool done = false; struct stream_obj* s; /* Pointer back to the stream object */ /* next op_and_state in the linked list */ - struct op_and_state* next; + struct op_and_state* next = nullptr; }; struct op_storage { @@ -187,10 +186,10 @@ struct op_storage { struct stream_obj { stream_obj(grpc_transport* gt, grpc_stream* gs, - grpc_stream_refcount* refcount, gpr_arena* arena); + grpc_stream_refcount* refcount, grpc_core::Arena* arena); ~stream_obj(); - gpr_arena* arena; + grpc_core::Arena* arena; struct op_and_state* oas = nullptr; grpc_transport_stream_op_batch* curr_op = nullptr; grpc_cronet_transport* curr_ct; @@ -324,7 +323,7 @@ static grpc_error* make_error_with_desc(int error_code, const char* desc) { inline op_and_state::op_and_state(stream_obj* s, const grpc_transport_stream_op_batch& op) - : op(op), state(s->arena), s(s), next(s->storage.head) {} + : op(op), state(s->arena), s(s) {} /* Add a new stream op to op storage. @@ -336,6 +335,7 @@ static void add_to_storage(struct stream_obj* s, in remove_from_storage */ op_and_state* new_op = grpc_core::New(s, *op); gpr_mu_lock(&s->mu); + new_op->next = storage->head; storage->head = new_op; storage->num_pending_ops++; if (op->send_message) { @@ -391,7 +391,7 @@ static void execute_from_storage(stream_obj* s) { gpr_mu_lock(&s->mu); for (struct op_and_state* curr = s->storage.head; curr != nullptr;) { CRONET_LOG(GPR_DEBUG, "calling op at %p. done = %d", curr, curr->done); - GPR_ASSERT(curr->done == 0); + GPR_ASSERT(!curr->done); enum e_op_result result = execute_stream_op(curr); CRONET_LOG(GPR_DEBUG, "execute_stream_op[%p] returns %s", curr, op_result_string(result)); @@ -400,13 +400,12 @@ static void execute_from_storage(stream_obj* s) { struct op_and_state* next = curr->next; remove_from_storage(s, curr); curr = next; - } - /* continue processing the same op if ACTION_TAKEN_WITHOUT_CALLBACK */ - if (result == NO_ACTION_POSSIBLE) { + } else if (result == NO_ACTION_POSSIBLE) { curr = curr->next; } else if (result == ACTION_TAKEN_WITH_CALLBACK) { + /* wait for the callback */ break; - } + } /* continue processing the same op if ACTION_TAKEN_WITHOUT_CALLBACK */ } gpr_mu_unlock(&s->mu); } @@ -439,6 +438,7 @@ static void convert_cronet_array_to_metadata( */ static void on_failed(bidirectional_stream* stream, int net_error) { gpr_log(GPR_ERROR, "on_failed(%p, %d)", stream, net_error); + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; grpc_core::ExecCtx exec_ctx; stream_obj* s = static_cast(stream->annotation); @@ -465,6 +465,7 @@ static void on_failed(bidirectional_stream* stream, int net_error) { */ static void on_canceled(bidirectional_stream* stream) { CRONET_LOG(GPR_DEBUG, "on_canceled(%p)", stream); + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; grpc_core::ExecCtx exec_ctx; stream_obj* s = static_cast(stream->annotation); @@ -491,6 +492,7 @@ static void on_canceled(bidirectional_stream* stream) { */ static void on_succeeded(bidirectional_stream* stream) { CRONET_LOG(GPR_DEBUG, "on_succeeded(%p)", stream); + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; grpc_core::ExecCtx exec_ctx; stream_obj* s = static_cast(stream->annotation); @@ -509,6 +511,7 @@ static void on_succeeded(bidirectional_stream* stream) { */ static void on_stream_ready(bidirectional_stream* stream) { CRONET_LOG(GPR_DEBUG, "W: on_stream_ready(%p)", stream); + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; grpc_core::ExecCtx exec_ctx; stream_obj* s = static_cast(stream->annotation); grpc_cronet_transport* t = s->curr_ct; @@ -539,6 +542,7 @@ static void on_response_headers_received( bidirectional_stream* stream, const bidirectional_stream_header_array* headers, const char* negotiated_protocol) { + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; grpc_core::ExecCtx exec_ctx; CRONET_LOG(GPR_DEBUG, "R: on_response_headers_received(%p, %p, %s)", stream, headers, negotiated_protocol); @@ -578,6 +582,7 @@ static void on_response_headers_received( Cronet callback */ static void on_write_completed(bidirectional_stream* stream, const char* data) { + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; grpc_core::ExecCtx exec_ctx; stream_obj* s = static_cast(stream->annotation); CRONET_LOG(GPR_DEBUG, "W: on_write_completed(%p, %s)", stream, data); @@ -596,6 +601,7 @@ static void on_write_completed(bidirectional_stream* stream, const char* data) { */ static void on_read_completed(bidirectional_stream* stream, char* data, int count) { + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; grpc_core::ExecCtx exec_ctx; stream_obj* s = static_cast(stream->annotation); CRONET_LOG(GPR_DEBUG, "R: on_read_completed(%p, %p, %d)", stream, data, @@ -638,6 +644,7 @@ static void on_read_completed(bidirectional_stream* stream, char* data, static void on_response_trailers_received( bidirectional_stream* stream, const bidirectional_stream_header_array* trailers) { + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; grpc_core::ExecCtx exec_ctx; CRONET_LOG(GPR_DEBUG, "R: on_response_trailers_received(%p,%p)", stream, trailers); @@ -746,15 +753,16 @@ static void convert_metadata_to_cronet_headers( } else { value = grpc_slice_to_c_string(GRPC_MDVALUE(mdelem)); } - if (grpc_slice_eq(GRPC_MDKEY(mdelem), GRPC_MDSTR_SCHEME) || - grpc_slice_eq(GRPC_MDKEY(mdelem), GRPC_MDSTR_AUTHORITY)) { + if (grpc_slice_eq_static_interned(GRPC_MDKEY(mdelem), GRPC_MDSTR_SCHEME) || + grpc_slice_eq_static_interned(GRPC_MDKEY(mdelem), + GRPC_MDSTR_AUTHORITY)) { /* Cronet populates these fields on its own */ gpr_free(key); gpr_free(value); continue; } - if (grpc_slice_eq(GRPC_MDKEY(mdelem), GRPC_MDSTR_METHOD)) { - if (grpc_slice_eq(GRPC_MDVALUE(mdelem), GRPC_MDSTR_PUT)) { + if (grpc_slice_eq_static_interned(GRPC_MDKEY(mdelem), GRPC_MDSTR_METHOD)) { + if (grpc_slice_eq_static_interned(GRPC_MDVALUE(mdelem), GRPC_MDSTR_PUT)) { *method = "PUT"; } else { /* POST method in default*/ @@ -764,7 +772,7 @@ static void convert_metadata_to_cronet_headers( gpr_free(value); continue; } - if (grpc_slice_eq(GRPC_MDKEY(mdelem), GRPC_MDSTR_PATH)) { + if (grpc_slice_eq_static_interned(GRPC_MDKEY(mdelem), GRPC_MDSTR_PATH)) { /* Create URL by appending :path value to the hostname */ gpr_asprintf(pp_url, "https://%s%s", host, value); gpr_free(key); @@ -796,7 +804,8 @@ static void parse_grpc_header(const uint8_t* data, int* length, static bool header_has_authority(grpc_linked_mdelem* head) { while (head != nullptr) { - if (grpc_slice_eq(GRPC_MDKEY(head->md), GRPC_MDSTR_AUTHORITY)) { + if (grpc_slice_eq_static_interned(GRPC_MDKEY(head->md), + GRPC_MDSTR_AUTHORITY)) { return true; } head = head->next; @@ -1361,7 +1370,8 @@ static enum e_op_result execute_stream_op(struct op_and_state* oas) { */ inline stream_obj::stream_obj(grpc_transport* gt, grpc_stream* gs, - grpc_stream_refcount* refcount, gpr_arena* arena) + grpc_stream_refcount* refcount, + grpc_core::Arena* arena) : arena(arena), curr_ct(reinterpret_cast(gt)), curr_gs(gs), @@ -1380,7 +1390,7 @@ inline stream_obj::~stream_obj() { static int init_stream(grpc_transport* gt, grpc_stream* gs, grpc_stream_refcount* refcount, const void* server_data, - gpr_arena* arena) { + grpc_core::Arena* arena) { new (gs) stream_obj(gt, gs, refcount, arena); return 0; } diff --git a/src/core/ext/transport/inproc/inproc_transport.cc b/src/core/ext/transport/inproc/inproc_transport.cc index 61968de4d58..8da89851a69 100644 --- a/src/core/ext/transport/inproc/inproc_transport.cc +++ b/src/core/ext/transport/inproc/inproc_transport.cc @@ -35,9 +35,11 @@ #include "src/core/lib/transport/error_utils.h" #include "src/core/lib/transport/transport_impl.h" -#define INPROC_LOG(...) \ - do { \ - if (grpc_inproc_trace.enabled()) gpr_log(__VA_ARGS__); \ +#define INPROC_LOG(...) \ + do { \ + if (GRPC_TRACE_FLAG_ENABLED(grpc_inproc_trace)) { \ + gpr_log(__VA_ARGS__); \ + } \ } while (0) namespace { @@ -64,6 +66,8 @@ struct shared_mu { gpr_ref_init(&refs, 2); } + ~shared_mu() { gpr_mu_destroy(&mu); } + gpr_mu mu; gpr_refcount refs; }; @@ -83,6 +87,7 @@ struct inproc_transport { ~inproc_transport() { grpc_connectivity_state_destroy(&connectivity); if (gpr_unref(&mu->refs)) { + mu->~shared_mu(); gpr_free(mu); } } @@ -117,7 +122,7 @@ struct inproc_transport { struct inproc_stream { inproc_stream(inproc_transport* t, grpc_stream_refcount* refcount, - const void* server_data, gpr_arena* arena) + const void* server_data, grpc_core::Arena* arena) : t(t), refs(refcount), arena(arena) { // Ref this stream right now for ctor and list. ref("inproc_init_stream:init"); @@ -247,7 +252,7 @@ struct inproc_stream { grpc_stream_refcount* refs; grpc_closure* closure_at_destroy = nullptr; - gpr_arena* arena; + grpc_core::Arena* arena; grpc_transport_stream_op_batch* send_message_op = nullptr; grpc_transport_stream_op_batch* send_trailing_md_op = nullptr; @@ -293,7 +298,7 @@ grpc_error* fill_in_metadata(inproc_stream* s, const grpc_metadata_batch* metadata, uint32_t flags, grpc_metadata_batch* out_md, uint32_t* outflags, bool* markfilled) { - if (grpc_inproc_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_inproc_trace)) { log_metadata(metadata, s->t->is_client, outflags != nullptr); } @@ -306,8 +311,8 @@ grpc_error* fill_in_metadata(inproc_stream* s, grpc_error* error = GRPC_ERROR_NONE; for (grpc_linked_mdelem* elem = metadata->list.head; (elem != nullptr) && (error == GRPC_ERROR_NONE); elem = elem->next) { - grpc_linked_mdelem* nelem = static_cast( - gpr_arena_alloc(s->arena, sizeof(*nelem))); + grpc_linked_mdelem* nelem = + static_cast(s->arena->Alloc(sizeof(*nelem))); nelem->md = grpc_mdelem_from_slices(grpc_slice_intern(GRPC_MDKEY(elem->md)), grpc_slice_intern(GRPC_MDVALUE(elem->md))); @@ -319,7 +324,7 @@ grpc_error* fill_in_metadata(inproc_stream* s, int init_stream(grpc_transport* gt, grpc_stream* gs, grpc_stream_refcount* refcount, const void* server_data, - gpr_arena* arena) { + grpc_core::Arena* arena) { INPROC_LOG(GPR_INFO, "init_stream %p %p %p", gt, gs, server_data); inproc_transport* t = reinterpret_cast(gt); new (gs) inproc_stream(t, refcount, server_data, arena); @@ -433,13 +438,13 @@ void fail_helper_locked(inproc_stream* s, grpc_error* error) { // since it expects that as well as no error yet grpc_metadata_batch fake_md; grpc_metadata_batch_init(&fake_md); - grpc_linked_mdelem* path_md = static_cast( - gpr_arena_alloc(s->arena, sizeof(*path_md))); + grpc_linked_mdelem* path_md = + static_cast(s->arena->Alloc(sizeof(*path_md))); path_md->md = grpc_mdelem_from_slices(g_fake_path_key, g_fake_path_value); GPR_ASSERT(grpc_metadata_batch_link_tail(&fake_md, path_md) == GRPC_ERROR_NONE); - grpc_linked_mdelem* auth_md = static_cast( - gpr_arena_alloc(s->arena, sizeof(*auth_md))); + grpc_linked_mdelem* auth_md = + static_cast(s->arena->Alloc(sizeof(*auth_md))); auth_md->md = grpc_mdelem_from_slices(g_fake_auth_key, g_fake_auth_value); GPR_ASSERT(grpc_metadata_batch_link_tail(&fake_md, auth_md) == GRPC_ERROR_NONE); @@ -904,7 +909,7 @@ void perform_stream_op(grpc_transport* gt, grpc_stream* gs, gpr_mu* mu = &s->t->mu->mu; // save aside in case s gets closed gpr_mu_lock(mu); - if (grpc_inproc_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_inproc_trace)) { if (op->send_initial_metadata) { log_metadata(op->payload->send_initial_metadata.send_initial_metadata, s->t->is_client, true); @@ -1029,6 +1034,11 @@ void perform_stream_op(grpc_transport* gt, grpc_stream* gs, } } else { if (error != GRPC_ERROR_NONE) { + // Consume any send message that was sent here but that we are not pushing + // to the other side + if (op->send_message) { + op->payload->send_message.send_message.reset(); + } // Schedule op's closures that we didn't push to op state machine if (op->recv_initial_metadata) { if (op->payload->recv_initial_metadata.trailing_metadata_available != @@ -1080,10 +1090,8 @@ void perform_stream_op(grpc_transport* gt, grpc_stream* gs, void close_transport_locked(inproc_transport* t) { 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."), - "close transport"); + grpc_connectivity_state_set(&t->connectivity, GRPC_CHANNEL_SHUTDOWN, + "close transport"); if (!t->is_closed) { t->is_closed = true; /* Also end all streams on this transport */ @@ -1236,7 +1244,7 @@ grpc_channel* grpc_inproc_channel_create(grpc_server* server, // TODO(ncteisen): design and support channelz GetSocket for inproc. grpc_server_setup_transport(server, server_transport, nullptr, server_args, - 0); + nullptr); grpc_channel* channel = grpc_channel_create( "inproc", client_args, GRPC_CLIENT_DIRECT_CHANNEL, client_transport); diff --git a/src/core/ext/upb-generated/envoy/api/v2/auth/cert.upb.c b/src/core/ext/upb-generated/envoy/api/v2/auth/cert.upb.c new file mode 100644 index 00000000000..e8a2fb32bab --- /dev/null +++ b/src/core/ext/upb-generated/envoy/api/v2/auth/cert.upb.c @@ -0,0 +1,199 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/api/v2/auth/cert.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include +#include "upb/msg.h" +#include "envoy/api/v2/auth/cert.upb.h" +#include "envoy/api/v2/core/base.upb.h" +#include "envoy/api/v2/core/config_source.upb.h" +#include "google/protobuf/wrappers.upb.h" +#include "validate/validate.upb.h" +#include "gogoproto/gogo.upb.h" + +#include "upb/port_def.inc" + +static const upb_msglayout_field envoy_api_v2_auth_TlsParameters__fields[4] = { + {1, UPB_SIZE(0, 0), 0, 0, 14, 1}, + {2, UPB_SIZE(8, 8), 0, 0, 14, 1}, + {3, UPB_SIZE(16, 16), 0, 0, 9, 3}, + {4, UPB_SIZE(20, 24), 0, 0, 9, 3}, +}; + +const upb_msglayout envoy_api_v2_auth_TlsParameters_msginit = { + NULL, + &envoy_api_v2_auth_TlsParameters__fields[0], + UPB_SIZE(24, 32), 4, false, +}; + +static const upb_msglayout *const envoy_api_v2_auth_TlsCertificate_submsgs[5] = { + &envoy_api_v2_core_DataSource_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_auth_TlsCertificate__fields[5] = { + {1, UPB_SIZE(0, 0), 0, 0, 11, 1}, + {2, UPB_SIZE(4, 8), 0, 0, 11, 1}, + {3, UPB_SIZE(8, 16), 0, 0, 11, 1}, + {4, UPB_SIZE(12, 24), 0, 0, 11, 1}, + {5, UPB_SIZE(16, 32), 0, 0, 11, 3}, +}; + +const upb_msglayout envoy_api_v2_auth_TlsCertificate_msginit = { + &envoy_api_v2_auth_TlsCertificate_submsgs[0], + &envoy_api_v2_auth_TlsCertificate__fields[0], + UPB_SIZE(20, 40), 5, false, +}; + +static const upb_msglayout *const envoy_api_v2_auth_TlsSessionTicketKeys_submsgs[1] = { + &envoy_api_v2_core_DataSource_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_auth_TlsSessionTicketKeys__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 11, 3}, +}; + +const upb_msglayout envoy_api_v2_auth_TlsSessionTicketKeys_msginit = { + &envoy_api_v2_auth_TlsSessionTicketKeys_submsgs[0], + &envoy_api_v2_auth_TlsSessionTicketKeys__fields[0], + UPB_SIZE(4, 8), 1, false, +}; + +static const upb_msglayout *const envoy_api_v2_auth_CertificateValidationContext_submsgs[4] = { + &envoy_api_v2_core_DataSource_msginit, + &google_protobuf_BoolValue_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_auth_CertificateValidationContext__fields[8] = { + {1, UPB_SIZE(4, 8), 0, 0, 11, 1}, + {2, UPB_SIZE(20, 40), 0, 0, 9, 3}, + {3, UPB_SIZE(24, 48), 0, 0, 9, 3}, + {4, UPB_SIZE(28, 56), 0, 0, 9, 3}, + {5, UPB_SIZE(8, 16), 0, 1, 11, 1}, + {6, UPB_SIZE(12, 24), 0, 1, 11, 1}, + {7, UPB_SIZE(16, 32), 0, 0, 11, 1}, + {8, UPB_SIZE(0, 0), 0, 0, 8, 1}, +}; + +const upb_msglayout envoy_api_v2_auth_CertificateValidationContext_msginit = { + &envoy_api_v2_auth_CertificateValidationContext_submsgs[0], + &envoy_api_v2_auth_CertificateValidationContext__fields[0], + UPB_SIZE(32, 64), 8, false, +}; + +static const upb_msglayout *const envoy_api_v2_auth_CommonTlsContext_submsgs[6] = { + &envoy_api_v2_auth_CertificateValidationContext_msginit, + &envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext_msginit, + &envoy_api_v2_auth_SdsSecretConfig_msginit, + &envoy_api_v2_auth_TlsCertificate_msginit, + &envoy_api_v2_auth_TlsParameters_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_auth_CommonTlsContext__fields[7] = { + {1, UPB_SIZE(0, 0), 0, 4, 11, 1}, + {2, UPB_SIZE(4, 8), 0, 3, 11, 3}, + {3, UPB_SIZE(16, 32), UPB_SIZE(-21, -41), 0, 11, 1}, + {4, UPB_SIZE(8, 16), 0, 0, 9, 3}, + {6, UPB_SIZE(12, 24), 0, 2, 11, 3}, + {7, UPB_SIZE(16, 32), UPB_SIZE(-21, -41), 2, 11, 1}, + {8, UPB_SIZE(16, 32), UPB_SIZE(-21, -41), 1, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_auth_CommonTlsContext_msginit = { + &envoy_api_v2_auth_CommonTlsContext_submsgs[0], + &envoy_api_v2_auth_CommonTlsContext__fields[0], + UPB_SIZE(24, 48), 7, false, +}; + +static const upb_msglayout *const envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext_submsgs[2] = { + &envoy_api_v2_auth_CertificateValidationContext_msginit, + &envoy_api_v2_auth_SdsSecretConfig_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext__fields[2] = { + {1, UPB_SIZE(0, 0), 0, 0, 11, 1}, + {2, UPB_SIZE(4, 8), 0, 1, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext_msginit = { + &envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext_submsgs[0], + &envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext__fields[0], + UPB_SIZE(8, 16), 2, false, +}; + +static const upb_msglayout *const envoy_api_v2_auth_UpstreamTlsContext_submsgs[1] = { + &envoy_api_v2_auth_CommonTlsContext_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_auth_UpstreamTlsContext__fields[3] = { + {1, UPB_SIZE(12, 24), 0, 0, 11, 1}, + {2, UPB_SIZE(4, 8), 0, 0, 9, 1}, + {3, UPB_SIZE(0, 0), 0, 0, 8, 1}, +}; + +const upb_msglayout envoy_api_v2_auth_UpstreamTlsContext_msginit = { + &envoy_api_v2_auth_UpstreamTlsContext_submsgs[0], + &envoy_api_v2_auth_UpstreamTlsContext__fields[0], + UPB_SIZE(16, 32), 3, false, +}; + +static const upb_msglayout *const envoy_api_v2_auth_DownstreamTlsContext_submsgs[5] = { + &envoy_api_v2_auth_CommonTlsContext_msginit, + &envoy_api_v2_auth_SdsSecretConfig_msginit, + &envoy_api_v2_auth_TlsSessionTicketKeys_msginit, + &google_protobuf_BoolValue_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_auth_DownstreamTlsContext__fields[5] = { + {1, UPB_SIZE(0, 0), 0, 0, 11, 1}, + {2, UPB_SIZE(4, 8), 0, 3, 11, 1}, + {3, UPB_SIZE(8, 16), 0, 3, 11, 1}, + {4, UPB_SIZE(12, 24), UPB_SIZE(-17, -33), 2, 11, 1}, + {5, UPB_SIZE(12, 24), UPB_SIZE(-17, -33), 1, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_auth_DownstreamTlsContext_msginit = { + &envoy_api_v2_auth_DownstreamTlsContext_submsgs[0], + &envoy_api_v2_auth_DownstreamTlsContext__fields[0], + UPB_SIZE(20, 40), 5, false, +}; + +static const upb_msglayout *const envoy_api_v2_auth_SdsSecretConfig_submsgs[1] = { + &envoy_api_v2_core_ConfigSource_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_auth_SdsSecretConfig__fields[2] = { + {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, + {2, UPB_SIZE(8, 16), 0, 0, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_auth_SdsSecretConfig_msginit = { + &envoy_api_v2_auth_SdsSecretConfig_submsgs[0], + &envoy_api_v2_auth_SdsSecretConfig__fields[0], + UPB_SIZE(16, 32), 2, false, +}; + +static const upb_msglayout *const envoy_api_v2_auth_Secret_submsgs[3] = { + &envoy_api_v2_auth_CertificateValidationContext_msginit, + &envoy_api_v2_auth_TlsCertificate_msginit, + &envoy_api_v2_auth_TlsSessionTicketKeys_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_auth_Secret__fields[4] = { + {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, + {2, UPB_SIZE(8, 16), UPB_SIZE(-13, -25), 1, 11, 1}, + {3, UPB_SIZE(8, 16), UPB_SIZE(-13, -25), 2, 11, 1}, + {4, UPB_SIZE(8, 16), UPB_SIZE(-13, -25), 0, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_auth_Secret_msginit = { + &envoy_api_v2_auth_Secret_submsgs[0], + &envoy_api_v2_auth_Secret__fields[0], + UPB_SIZE(16, 32), 4, false, +}; + +#include "upb/port_undef.inc" + diff --git a/src/core/ext/upb-generated/envoy/api/v2/auth/cert.upb.h b/src/core/ext/upb-generated/envoy/api/v2/auth/cert.upb.h new file mode 100644 index 00000000000..22379341331 --- /dev/null +++ b/src/core/ext/upb-generated/envoy/api/v2/auth/cert.upb.h @@ -0,0 +1,730 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/api/v2/auth/cert.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef ENVOY_API_V2_AUTH_CERT_PROTO_UPB_H_ +#define ENVOY_API_V2_AUTH_CERT_PROTO_UPB_H_ + +#include "upb/generated_util.h" + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +#ifdef __cplusplus +extern "C" { +#endif + +struct envoy_api_v2_auth_TlsParameters; +struct envoy_api_v2_auth_TlsCertificate; +struct envoy_api_v2_auth_TlsSessionTicketKeys; +struct envoy_api_v2_auth_CertificateValidationContext; +struct envoy_api_v2_auth_CommonTlsContext; +struct envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext; +struct envoy_api_v2_auth_UpstreamTlsContext; +struct envoy_api_v2_auth_DownstreamTlsContext; +struct envoy_api_v2_auth_SdsSecretConfig; +struct envoy_api_v2_auth_Secret; +typedef struct envoy_api_v2_auth_TlsParameters envoy_api_v2_auth_TlsParameters; +typedef struct envoy_api_v2_auth_TlsCertificate envoy_api_v2_auth_TlsCertificate; +typedef struct envoy_api_v2_auth_TlsSessionTicketKeys envoy_api_v2_auth_TlsSessionTicketKeys; +typedef struct envoy_api_v2_auth_CertificateValidationContext envoy_api_v2_auth_CertificateValidationContext; +typedef struct envoy_api_v2_auth_CommonTlsContext envoy_api_v2_auth_CommonTlsContext; +typedef struct envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext; +typedef struct envoy_api_v2_auth_UpstreamTlsContext envoy_api_v2_auth_UpstreamTlsContext; +typedef struct envoy_api_v2_auth_DownstreamTlsContext envoy_api_v2_auth_DownstreamTlsContext; +typedef struct envoy_api_v2_auth_SdsSecretConfig envoy_api_v2_auth_SdsSecretConfig; +typedef struct envoy_api_v2_auth_Secret envoy_api_v2_auth_Secret; +extern const upb_msglayout envoy_api_v2_auth_TlsParameters_msginit; +extern const upb_msglayout envoy_api_v2_auth_TlsCertificate_msginit; +extern const upb_msglayout envoy_api_v2_auth_TlsSessionTicketKeys_msginit; +extern const upb_msglayout envoy_api_v2_auth_CertificateValidationContext_msginit; +extern const upb_msglayout envoy_api_v2_auth_CommonTlsContext_msginit; +extern const upb_msglayout envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext_msginit; +extern const upb_msglayout envoy_api_v2_auth_UpstreamTlsContext_msginit; +extern const upb_msglayout envoy_api_v2_auth_DownstreamTlsContext_msginit; +extern const upb_msglayout envoy_api_v2_auth_SdsSecretConfig_msginit; +extern const upb_msglayout envoy_api_v2_auth_Secret_msginit; +struct envoy_api_v2_core_ConfigSource; +struct envoy_api_v2_core_DataSource; +struct google_protobuf_BoolValue; +extern const upb_msglayout envoy_api_v2_core_ConfigSource_msginit; +extern const upb_msglayout envoy_api_v2_core_DataSource_msginit; +extern const upb_msglayout google_protobuf_BoolValue_msginit; + +/* Enums */ + +typedef enum { + envoy_api_v2_auth_TlsParameters_TLS_AUTO = 0, + envoy_api_v2_auth_TlsParameters_TLSv1_0 = 1, + envoy_api_v2_auth_TlsParameters_TLSv1_1 = 2, + envoy_api_v2_auth_TlsParameters_TLSv1_2 = 3, + envoy_api_v2_auth_TlsParameters_TLSv1_3 = 4 +} envoy_api_v2_auth_TlsParameters_TlsProtocol; + + +/* envoy.api.v2.auth.TlsParameters */ + +UPB_INLINE envoy_api_v2_auth_TlsParameters *envoy_api_v2_auth_TlsParameters_new(upb_arena *arena) { + return (envoy_api_v2_auth_TlsParameters *)upb_msg_new(&envoy_api_v2_auth_TlsParameters_msginit, arena); +} +UPB_INLINE envoy_api_v2_auth_TlsParameters *envoy_api_v2_auth_TlsParameters_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_auth_TlsParameters *ret = envoy_api_v2_auth_TlsParameters_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_auth_TlsParameters_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_auth_TlsParameters_serialize(const envoy_api_v2_auth_TlsParameters *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_auth_TlsParameters_msginit, arena, len); +} + +UPB_INLINE int32_t envoy_api_v2_auth_TlsParameters_tls_minimum_protocol_version(const envoy_api_v2_auth_TlsParameters *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(0, 0)); } +UPB_INLINE int32_t envoy_api_v2_auth_TlsParameters_tls_maximum_protocol_version(const envoy_api_v2_auth_TlsParameters *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); } +UPB_INLINE upb_strview const* envoy_api_v2_auth_TlsParameters_cipher_suites(const envoy_api_v2_auth_TlsParameters *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(16, 16), len); } +UPB_INLINE upb_strview const* envoy_api_v2_auth_TlsParameters_ecdh_curves(const envoy_api_v2_auth_TlsParameters *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(20, 24), len); } + +UPB_INLINE void envoy_api_v2_auth_TlsParameters_set_tls_minimum_protocol_version(envoy_api_v2_auth_TlsParameters *msg, int32_t value) { + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_api_v2_auth_TlsParameters_set_tls_maximum_protocol_version(envoy_api_v2_auth_TlsParameters *msg, int32_t value) { + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE upb_strview* envoy_api_v2_auth_TlsParameters_mutable_cipher_suites(envoy_api_v2_auth_TlsParameters *msg, size_t *len) { + return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(16, 16), len); +} +UPB_INLINE upb_strview* envoy_api_v2_auth_TlsParameters_resize_cipher_suites(envoy_api_v2_auth_TlsParameters *msg, size_t len, upb_arena *arena) { + return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(16, 16), len, UPB_SIZE(8, 16), UPB_TYPE_STRING, arena); +} +UPB_INLINE bool envoy_api_v2_auth_TlsParameters_add_cipher_suites(envoy_api_v2_auth_TlsParameters *msg, upb_strview val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(16, 16), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, arena); +} +UPB_INLINE upb_strview* envoy_api_v2_auth_TlsParameters_mutable_ecdh_curves(envoy_api_v2_auth_TlsParameters *msg, size_t *len) { + return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 24), len); +} +UPB_INLINE upb_strview* envoy_api_v2_auth_TlsParameters_resize_ecdh_curves(envoy_api_v2_auth_TlsParameters *msg, size_t len, upb_arena *arena) { + return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(20, 24), len, UPB_SIZE(8, 16), UPB_TYPE_STRING, arena); +} +UPB_INLINE bool envoy_api_v2_auth_TlsParameters_add_ecdh_curves(envoy_api_v2_auth_TlsParameters *msg, upb_strview val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(20, 24), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, arena); +} + + +/* envoy.api.v2.auth.TlsCertificate */ + +UPB_INLINE envoy_api_v2_auth_TlsCertificate *envoy_api_v2_auth_TlsCertificate_new(upb_arena *arena) { + return (envoy_api_v2_auth_TlsCertificate *)upb_msg_new(&envoy_api_v2_auth_TlsCertificate_msginit, arena); +} +UPB_INLINE envoy_api_v2_auth_TlsCertificate *envoy_api_v2_auth_TlsCertificate_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_auth_TlsCertificate *ret = envoy_api_v2_auth_TlsCertificate_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_auth_TlsCertificate_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_auth_TlsCertificate_serialize(const envoy_api_v2_auth_TlsCertificate *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_auth_TlsCertificate_msginit, arena, len); +} + +UPB_INLINE const struct envoy_api_v2_core_DataSource* envoy_api_v2_auth_TlsCertificate_certificate_chain(const envoy_api_v2_auth_TlsCertificate *msg) { return UPB_FIELD_AT(msg, const struct envoy_api_v2_core_DataSource*, UPB_SIZE(0, 0)); } +UPB_INLINE const struct envoy_api_v2_core_DataSource* envoy_api_v2_auth_TlsCertificate_private_key(const envoy_api_v2_auth_TlsCertificate *msg) { return UPB_FIELD_AT(msg, const struct envoy_api_v2_core_DataSource*, UPB_SIZE(4, 8)); } +UPB_INLINE const struct envoy_api_v2_core_DataSource* envoy_api_v2_auth_TlsCertificate_password(const envoy_api_v2_auth_TlsCertificate *msg) { return UPB_FIELD_AT(msg, const struct envoy_api_v2_core_DataSource*, UPB_SIZE(8, 16)); } +UPB_INLINE const struct envoy_api_v2_core_DataSource* envoy_api_v2_auth_TlsCertificate_ocsp_staple(const envoy_api_v2_auth_TlsCertificate *msg) { return UPB_FIELD_AT(msg, const struct envoy_api_v2_core_DataSource*, UPB_SIZE(12, 24)); } +UPB_INLINE const struct envoy_api_v2_core_DataSource* const* envoy_api_v2_auth_TlsCertificate_signed_certificate_timestamp(const envoy_api_v2_auth_TlsCertificate *msg, size_t *len) { return (const struct envoy_api_v2_core_DataSource* const*)_upb_array_accessor(msg, UPB_SIZE(16, 32), len); } + +UPB_INLINE void envoy_api_v2_auth_TlsCertificate_set_certificate_chain(envoy_api_v2_auth_TlsCertificate *msg, struct envoy_api_v2_core_DataSource* value) { + UPB_FIELD_AT(msg, struct envoy_api_v2_core_DataSource*, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE struct envoy_api_v2_core_DataSource* envoy_api_v2_auth_TlsCertificate_mutable_certificate_chain(envoy_api_v2_auth_TlsCertificate *msg, upb_arena *arena) { + struct envoy_api_v2_core_DataSource* sub = (struct envoy_api_v2_core_DataSource*)envoy_api_v2_auth_TlsCertificate_certificate_chain(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_DataSource*)upb_msg_new(&envoy_api_v2_core_DataSource_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_auth_TlsCertificate_set_certificate_chain(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_auth_TlsCertificate_set_private_key(envoy_api_v2_auth_TlsCertificate *msg, struct envoy_api_v2_core_DataSource* value) { + UPB_FIELD_AT(msg, struct envoy_api_v2_core_DataSource*, UPB_SIZE(4, 8)) = value; +} +UPB_INLINE struct envoy_api_v2_core_DataSource* envoy_api_v2_auth_TlsCertificate_mutable_private_key(envoy_api_v2_auth_TlsCertificate *msg, upb_arena *arena) { + struct envoy_api_v2_core_DataSource* sub = (struct envoy_api_v2_core_DataSource*)envoy_api_v2_auth_TlsCertificate_private_key(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_DataSource*)upb_msg_new(&envoy_api_v2_core_DataSource_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_auth_TlsCertificate_set_private_key(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_auth_TlsCertificate_set_password(envoy_api_v2_auth_TlsCertificate *msg, struct envoy_api_v2_core_DataSource* value) { + UPB_FIELD_AT(msg, struct envoy_api_v2_core_DataSource*, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE struct envoy_api_v2_core_DataSource* envoy_api_v2_auth_TlsCertificate_mutable_password(envoy_api_v2_auth_TlsCertificate *msg, upb_arena *arena) { + struct envoy_api_v2_core_DataSource* sub = (struct envoy_api_v2_core_DataSource*)envoy_api_v2_auth_TlsCertificate_password(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_DataSource*)upb_msg_new(&envoy_api_v2_core_DataSource_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_auth_TlsCertificate_set_password(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_auth_TlsCertificate_set_ocsp_staple(envoy_api_v2_auth_TlsCertificate *msg, struct envoy_api_v2_core_DataSource* value) { + UPB_FIELD_AT(msg, struct envoy_api_v2_core_DataSource*, UPB_SIZE(12, 24)) = value; +} +UPB_INLINE struct envoy_api_v2_core_DataSource* envoy_api_v2_auth_TlsCertificate_mutable_ocsp_staple(envoy_api_v2_auth_TlsCertificate *msg, upb_arena *arena) { + struct envoy_api_v2_core_DataSource* sub = (struct envoy_api_v2_core_DataSource*)envoy_api_v2_auth_TlsCertificate_ocsp_staple(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_DataSource*)upb_msg_new(&envoy_api_v2_core_DataSource_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_auth_TlsCertificate_set_ocsp_staple(msg, sub); + } + return sub; +} +UPB_INLINE struct envoy_api_v2_core_DataSource** envoy_api_v2_auth_TlsCertificate_mutable_signed_certificate_timestamp(envoy_api_v2_auth_TlsCertificate *msg, size_t *len) { + return (struct envoy_api_v2_core_DataSource**)_upb_array_mutable_accessor(msg, UPB_SIZE(16, 32), len); +} +UPB_INLINE struct envoy_api_v2_core_DataSource** envoy_api_v2_auth_TlsCertificate_resize_signed_certificate_timestamp(envoy_api_v2_auth_TlsCertificate *msg, size_t len, upb_arena *arena) { + return (struct envoy_api_v2_core_DataSource**)_upb_array_resize_accessor(msg, UPB_SIZE(16, 32), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct envoy_api_v2_core_DataSource* envoy_api_v2_auth_TlsCertificate_add_signed_certificate_timestamp(envoy_api_v2_auth_TlsCertificate *msg, upb_arena *arena) { + struct envoy_api_v2_core_DataSource* sub = (struct envoy_api_v2_core_DataSource*)upb_msg_new(&envoy_api_v2_core_DataSource_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(16, 32), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} + + +/* envoy.api.v2.auth.TlsSessionTicketKeys */ + +UPB_INLINE envoy_api_v2_auth_TlsSessionTicketKeys *envoy_api_v2_auth_TlsSessionTicketKeys_new(upb_arena *arena) { + return (envoy_api_v2_auth_TlsSessionTicketKeys *)upb_msg_new(&envoy_api_v2_auth_TlsSessionTicketKeys_msginit, arena); +} +UPB_INLINE envoy_api_v2_auth_TlsSessionTicketKeys *envoy_api_v2_auth_TlsSessionTicketKeys_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_auth_TlsSessionTicketKeys *ret = envoy_api_v2_auth_TlsSessionTicketKeys_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_auth_TlsSessionTicketKeys_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_auth_TlsSessionTicketKeys_serialize(const envoy_api_v2_auth_TlsSessionTicketKeys *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_auth_TlsSessionTicketKeys_msginit, arena, len); +} + +UPB_INLINE const struct envoy_api_v2_core_DataSource* const* envoy_api_v2_auth_TlsSessionTicketKeys_keys(const envoy_api_v2_auth_TlsSessionTicketKeys *msg, size_t *len) { return (const struct envoy_api_v2_core_DataSource* const*)_upb_array_accessor(msg, UPB_SIZE(0, 0), len); } + +UPB_INLINE struct envoy_api_v2_core_DataSource** envoy_api_v2_auth_TlsSessionTicketKeys_mutable_keys(envoy_api_v2_auth_TlsSessionTicketKeys *msg, size_t *len) { + return (struct envoy_api_v2_core_DataSource**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len); +} +UPB_INLINE struct envoy_api_v2_core_DataSource** envoy_api_v2_auth_TlsSessionTicketKeys_resize_keys(envoy_api_v2_auth_TlsSessionTicketKeys *msg, size_t len, upb_arena *arena) { + return (struct envoy_api_v2_core_DataSource**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct envoy_api_v2_core_DataSource* envoy_api_v2_auth_TlsSessionTicketKeys_add_keys(envoy_api_v2_auth_TlsSessionTicketKeys *msg, upb_arena *arena) { + struct envoy_api_v2_core_DataSource* sub = (struct envoy_api_v2_core_DataSource*)upb_msg_new(&envoy_api_v2_core_DataSource_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} + + +/* envoy.api.v2.auth.CertificateValidationContext */ + +UPB_INLINE envoy_api_v2_auth_CertificateValidationContext *envoy_api_v2_auth_CertificateValidationContext_new(upb_arena *arena) { + return (envoy_api_v2_auth_CertificateValidationContext *)upb_msg_new(&envoy_api_v2_auth_CertificateValidationContext_msginit, arena); +} +UPB_INLINE envoy_api_v2_auth_CertificateValidationContext *envoy_api_v2_auth_CertificateValidationContext_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_auth_CertificateValidationContext *ret = envoy_api_v2_auth_CertificateValidationContext_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_auth_CertificateValidationContext_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_auth_CertificateValidationContext_serialize(const envoy_api_v2_auth_CertificateValidationContext *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_auth_CertificateValidationContext_msginit, arena, len); +} + +UPB_INLINE const struct envoy_api_v2_core_DataSource* envoy_api_v2_auth_CertificateValidationContext_trusted_ca(const envoy_api_v2_auth_CertificateValidationContext *msg) { return UPB_FIELD_AT(msg, const struct envoy_api_v2_core_DataSource*, UPB_SIZE(4, 8)); } +UPB_INLINE upb_strview const* envoy_api_v2_auth_CertificateValidationContext_verify_certificate_hash(const envoy_api_v2_auth_CertificateValidationContext *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(20, 40), len); } +UPB_INLINE upb_strview const* envoy_api_v2_auth_CertificateValidationContext_verify_certificate_spki(const envoy_api_v2_auth_CertificateValidationContext *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(24, 48), len); } +UPB_INLINE upb_strview const* envoy_api_v2_auth_CertificateValidationContext_verify_subject_alt_name(const envoy_api_v2_auth_CertificateValidationContext *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(28, 56), len); } +UPB_INLINE const struct google_protobuf_BoolValue* envoy_api_v2_auth_CertificateValidationContext_require_ocsp_staple(const envoy_api_v2_auth_CertificateValidationContext *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_BoolValue*, UPB_SIZE(8, 16)); } +UPB_INLINE const struct google_protobuf_BoolValue* envoy_api_v2_auth_CertificateValidationContext_require_signed_certificate_timestamp(const envoy_api_v2_auth_CertificateValidationContext *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_BoolValue*, UPB_SIZE(12, 24)); } +UPB_INLINE const struct envoy_api_v2_core_DataSource* envoy_api_v2_auth_CertificateValidationContext_crl(const envoy_api_v2_auth_CertificateValidationContext *msg) { return UPB_FIELD_AT(msg, const struct envoy_api_v2_core_DataSource*, UPB_SIZE(16, 32)); } +UPB_INLINE bool envoy_api_v2_auth_CertificateValidationContext_allow_expired_certificate(const envoy_api_v2_auth_CertificateValidationContext *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(0, 0)); } + +UPB_INLINE void envoy_api_v2_auth_CertificateValidationContext_set_trusted_ca(envoy_api_v2_auth_CertificateValidationContext *msg, struct envoy_api_v2_core_DataSource* value) { + UPB_FIELD_AT(msg, struct envoy_api_v2_core_DataSource*, UPB_SIZE(4, 8)) = value; +} +UPB_INLINE struct envoy_api_v2_core_DataSource* envoy_api_v2_auth_CertificateValidationContext_mutable_trusted_ca(envoy_api_v2_auth_CertificateValidationContext *msg, upb_arena *arena) { + struct envoy_api_v2_core_DataSource* sub = (struct envoy_api_v2_core_DataSource*)envoy_api_v2_auth_CertificateValidationContext_trusted_ca(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_DataSource*)upb_msg_new(&envoy_api_v2_core_DataSource_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_auth_CertificateValidationContext_set_trusted_ca(msg, sub); + } + return sub; +} +UPB_INLINE upb_strview* envoy_api_v2_auth_CertificateValidationContext_mutable_verify_certificate_hash(envoy_api_v2_auth_CertificateValidationContext *msg, size_t *len) { + return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 40), len); +} +UPB_INLINE upb_strview* envoy_api_v2_auth_CertificateValidationContext_resize_verify_certificate_hash(envoy_api_v2_auth_CertificateValidationContext *msg, size_t len, upb_arena *arena) { + return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(20, 40), len, UPB_SIZE(8, 16), UPB_TYPE_STRING, arena); +} +UPB_INLINE bool envoy_api_v2_auth_CertificateValidationContext_add_verify_certificate_hash(envoy_api_v2_auth_CertificateValidationContext *msg, upb_strview val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(20, 40), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, arena); +} +UPB_INLINE upb_strview* envoy_api_v2_auth_CertificateValidationContext_mutable_verify_certificate_spki(envoy_api_v2_auth_CertificateValidationContext *msg, size_t *len) { + return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 48), len); +} +UPB_INLINE upb_strview* envoy_api_v2_auth_CertificateValidationContext_resize_verify_certificate_spki(envoy_api_v2_auth_CertificateValidationContext *msg, size_t len, upb_arena *arena) { + return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(24, 48), len, UPB_SIZE(8, 16), UPB_TYPE_STRING, arena); +} +UPB_INLINE bool envoy_api_v2_auth_CertificateValidationContext_add_verify_certificate_spki(envoy_api_v2_auth_CertificateValidationContext *msg, upb_strview val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(24, 48), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, arena); +} +UPB_INLINE upb_strview* envoy_api_v2_auth_CertificateValidationContext_mutable_verify_subject_alt_name(envoy_api_v2_auth_CertificateValidationContext *msg, size_t *len) { + return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 56), len); +} +UPB_INLINE upb_strview* envoy_api_v2_auth_CertificateValidationContext_resize_verify_subject_alt_name(envoy_api_v2_auth_CertificateValidationContext *msg, size_t len, upb_arena *arena) { + return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(28, 56), len, UPB_SIZE(8, 16), UPB_TYPE_STRING, arena); +} +UPB_INLINE bool envoy_api_v2_auth_CertificateValidationContext_add_verify_subject_alt_name(envoy_api_v2_auth_CertificateValidationContext *msg, upb_strview val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(28, 56), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, arena); +} +UPB_INLINE void envoy_api_v2_auth_CertificateValidationContext_set_require_ocsp_staple(envoy_api_v2_auth_CertificateValidationContext *msg, struct google_protobuf_BoolValue* value) { + UPB_FIELD_AT(msg, struct google_protobuf_BoolValue*, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE struct google_protobuf_BoolValue* envoy_api_v2_auth_CertificateValidationContext_mutable_require_ocsp_staple(envoy_api_v2_auth_CertificateValidationContext *msg, upb_arena *arena) { + struct google_protobuf_BoolValue* sub = (struct google_protobuf_BoolValue*)envoy_api_v2_auth_CertificateValidationContext_require_ocsp_staple(msg); + if (sub == NULL) { + sub = (struct google_protobuf_BoolValue*)upb_msg_new(&google_protobuf_BoolValue_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_auth_CertificateValidationContext_set_require_ocsp_staple(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_auth_CertificateValidationContext_set_require_signed_certificate_timestamp(envoy_api_v2_auth_CertificateValidationContext *msg, struct google_protobuf_BoolValue* value) { + UPB_FIELD_AT(msg, struct google_protobuf_BoolValue*, UPB_SIZE(12, 24)) = value; +} +UPB_INLINE struct google_protobuf_BoolValue* envoy_api_v2_auth_CertificateValidationContext_mutable_require_signed_certificate_timestamp(envoy_api_v2_auth_CertificateValidationContext *msg, upb_arena *arena) { + struct google_protobuf_BoolValue* sub = (struct google_protobuf_BoolValue*)envoy_api_v2_auth_CertificateValidationContext_require_signed_certificate_timestamp(msg); + if (sub == NULL) { + sub = (struct google_protobuf_BoolValue*)upb_msg_new(&google_protobuf_BoolValue_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_auth_CertificateValidationContext_set_require_signed_certificate_timestamp(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_auth_CertificateValidationContext_set_crl(envoy_api_v2_auth_CertificateValidationContext *msg, struct envoy_api_v2_core_DataSource* value) { + UPB_FIELD_AT(msg, struct envoy_api_v2_core_DataSource*, UPB_SIZE(16, 32)) = value; +} +UPB_INLINE struct envoy_api_v2_core_DataSource* envoy_api_v2_auth_CertificateValidationContext_mutable_crl(envoy_api_v2_auth_CertificateValidationContext *msg, upb_arena *arena) { + struct envoy_api_v2_core_DataSource* sub = (struct envoy_api_v2_core_DataSource*)envoy_api_v2_auth_CertificateValidationContext_crl(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_DataSource*)upb_msg_new(&envoy_api_v2_core_DataSource_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_auth_CertificateValidationContext_set_crl(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_auth_CertificateValidationContext_set_allow_expired_certificate(envoy_api_v2_auth_CertificateValidationContext *msg, bool value) { + UPB_FIELD_AT(msg, bool, UPB_SIZE(0, 0)) = value; +} + + +/* envoy.api.v2.auth.CommonTlsContext */ + +UPB_INLINE envoy_api_v2_auth_CommonTlsContext *envoy_api_v2_auth_CommonTlsContext_new(upb_arena *arena) { + return (envoy_api_v2_auth_CommonTlsContext *)upb_msg_new(&envoy_api_v2_auth_CommonTlsContext_msginit, arena); +} +UPB_INLINE envoy_api_v2_auth_CommonTlsContext *envoy_api_v2_auth_CommonTlsContext_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_auth_CommonTlsContext *ret = envoy_api_v2_auth_CommonTlsContext_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_auth_CommonTlsContext_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_auth_CommonTlsContext_serialize(const envoy_api_v2_auth_CommonTlsContext *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_auth_CommonTlsContext_msginit, arena, len); +} + +typedef enum { + envoy_api_v2_auth_CommonTlsContext_validation_context_type_validation_context = 3, + envoy_api_v2_auth_CommonTlsContext_validation_context_type_validation_context_sds_secret_config = 7, + envoy_api_v2_auth_CommonTlsContext_validation_context_type_combined_validation_context = 8, + envoy_api_v2_auth_CommonTlsContext_validation_context_type_NOT_SET = 0, +} envoy_api_v2_auth_CommonTlsContext_validation_context_type_oneofcases; +UPB_INLINE envoy_api_v2_auth_CommonTlsContext_validation_context_type_oneofcases envoy_api_v2_auth_CommonTlsContext_validation_context_type_case(const envoy_api_v2_auth_CommonTlsContext* msg) { return UPB_FIELD_AT(msg, int, UPB_SIZE(20, 40)); } + +UPB_INLINE const envoy_api_v2_auth_TlsParameters* envoy_api_v2_auth_CommonTlsContext_tls_params(const envoy_api_v2_auth_CommonTlsContext *msg) { return UPB_FIELD_AT(msg, const envoy_api_v2_auth_TlsParameters*, UPB_SIZE(0, 0)); } +UPB_INLINE const envoy_api_v2_auth_TlsCertificate* const* envoy_api_v2_auth_CommonTlsContext_tls_certificates(const envoy_api_v2_auth_CommonTlsContext *msg, size_t *len) { return (const envoy_api_v2_auth_TlsCertificate* const*)_upb_array_accessor(msg, UPB_SIZE(4, 8), len); } +UPB_INLINE bool envoy_api_v2_auth_CommonTlsContext_has_validation_context(const envoy_api_v2_auth_CommonTlsContext *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(20, 40), 3); } +UPB_INLINE const envoy_api_v2_auth_CertificateValidationContext* envoy_api_v2_auth_CommonTlsContext_validation_context(const envoy_api_v2_auth_CommonTlsContext *msg) { return UPB_READ_ONEOF(msg, const envoy_api_v2_auth_CertificateValidationContext*, UPB_SIZE(16, 32), UPB_SIZE(20, 40), 3, NULL); } +UPB_INLINE upb_strview const* envoy_api_v2_auth_CommonTlsContext_alpn_protocols(const envoy_api_v2_auth_CommonTlsContext *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(8, 16), len); } +UPB_INLINE const envoy_api_v2_auth_SdsSecretConfig* const* envoy_api_v2_auth_CommonTlsContext_tls_certificate_sds_secret_configs(const envoy_api_v2_auth_CommonTlsContext *msg, size_t *len) { return (const envoy_api_v2_auth_SdsSecretConfig* const*)_upb_array_accessor(msg, UPB_SIZE(12, 24), len); } +UPB_INLINE bool envoy_api_v2_auth_CommonTlsContext_has_validation_context_sds_secret_config(const envoy_api_v2_auth_CommonTlsContext *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(20, 40), 7); } +UPB_INLINE const envoy_api_v2_auth_SdsSecretConfig* envoy_api_v2_auth_CommonTlsContext_validation_context_sds_secret_config(const envoy_api_v2_auth_CommonTlsContext *msg) { return UPB_READ_ONEOF(msg, const envoy_api_v2_auth_SdsSecretConfig*, UPB_SIZE(16, 32), UPB_SIZE(20, 40), 7, NULL); } +UPB_INLINE bool envoy_api_v2_auth_CommonTlsContext_has_combined_validation_context(const envoy_api_v2_auth_CommonTlsContext *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(20, 40), 8); } +UPB_INLINE const envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext* envoy_api_v2_auth_CommonTlsContext_combined_validation_context(const envoy_api_v2_auth_CommonTlsContext *msg) { return UPB_READ_ONEOF(msg, const envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext*, UPB_SIZE(16, 32), UPB_SIZE(20, 40), 8, NULL); } + +UPB_INLINE void envoy_api_v2_auth_CommonTlsContext_set_tls_params(envoy_api_v2_auth_CommonTlsContext *msg, envoy_api_v2_auth_TlsParameters* value) { + UPB_FIELD_AT(msg, envoy_api_v2_auth_TlsParameters*, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE struct envoy_api_v2_auth_TlsParameters* envoy_api_v2_auth_CommonTlsContext_mutable_tls_params(envoy_api_v2_auth_CommonTlsContext *msg, upb_arena *arena) { + struct envoy_api_v2_auth_TlsParameters* sub = (struct envoy_api_v2_auth_TlsParameters*)envoy_api_v2_auth_CommonTlsContext_tls_params(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_auth_TlsParameters*)upb_msg_new(&envoy_api_v2_auth_TlsParameters_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_auth_CommonTlsContext_set_tls_params(msg, sub); + } + return sub; +} +UPB_INLINE envoy_api_v2_auth_TlsCertificate** envoy_api_v2_auth_CommonTlsContext_mutable_tls_certificates(envoy_api_v2_auth_CommonTlsContext *msg, size_t *len) { + return (envoy_api_v2_auth_TlsCertificate**)_upb_array_mutable_accessor(msg, UPB_SIZE(4, 8), len); +} +UPB_INLINE envoy_api_v2_auth_TlsCertificate** envoy_api_v2_auth_CommonTlsContext_resize_tls_certificates(envoy_api_v2_auth_CommonTlsContext *msg, size_t len, upb_arena *arena) { + return (envoy_api_v2_auth_TlsCertificate**)_upb_array_resize_accessor(msg, UPB_SIZE(4, 8), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct envoy_api_v2_auth_TlsCertificate* envoy_api_v2_auth_CommonTlsContext_add_tls_certificates(envoy_api_v2_auth_CommonTlsContext *msg, upb_arena *arena) { + struct envoy_api_v2_auth_TlsCertificate* sub = (struct envoy_api_v2_auth_TlsCertificate*)upb_msg_new(&envoy_api_v2_auth_TlsCertificate_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(4, 8), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE void envoy_api_v2_auth_CommonTlsContext_set_validation_context(envoy_api_v2_auth_CommonTlsContext *msg, envoy_api_v2_auth_CertificateValidationContext* value) { + UPB_WRITE_ONEOF(msg, envoy_api_v2_auth_CertificateValidationContext*, UPB_SIZE(16, 32), value, UPB_SIZE(20, 40), 3); +} +UPB_INLINE struct envoy_api_v2_auth_CertificateValidationContext* envoy_api_v2_auth_CommonTlsContext_mutable_validation_context(envoy_api_v2_auth_CommonTlsContext *msg, upb_arena *arena) { + struct envoy_api_v2_auth_CertificateValidationContext* sub = (struct envoy_api_v2_auth_CertificateValidationContext*)envoy_api_v2_auth_CommonTlsContext_validation_context(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_auth_CertificateValidationContext*)upb_msg_new(&envoy_api_v2_auth_CertificateValidationContext_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_auth_CommonTlsContext_set_validation_context(msg, sub); + } + return sub; +} +UPB_INLINE upb_strview* envoy_api_v2_auth_CommonTlsContext_mutable_alpn_protocols(envoy_api_v2_auth_CommonTlsContext *msg, size_t *len) { + return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(8, 16), len); +} +UPB_INLINE upb_strview* envoy_api_v2_auth_CommonTlsContext_resize_alpn_protocols(envoy_api_v2_auth_CommonTlsContext *msg, size_t len, upb_arena *arena) { + return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(8, 16), len, UPB_SIZE(8, 16), UPB_TYPE_STRING, arena); +} +UPB_INLINE bool envoy_api_v2_auth_CommonTlsContext_add_alpn_protocols(envoy_api_v2_auth_CommonTlsContext *msg, upb_strview val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(8, 16), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, arena); +} +UPB_INLINE envoy_api_v2_auth_SdsSecretConfig** envoy_api_v2_auth_CommonTlsContext_mutable_tls_certificate_sds_secret_configs(envoy_api_v2_auth_CommonTlsContext *msg, size_t *len) { + return (envoy_api_v2_auth_SdsSecretConfig**)_upb_array_mutable_accessor(msg, UPB_SIZE(12, 24), len); +} +UPB_INLINE envoy_api_v2_auth_SdsSecretConfig** envoy_api_v2_auth_CommonTlsContext_resize_tls_certificate_sds_secret_configs(envoy_api_v2_auth_CommonTlsContext *msg, size_t len, upb_arena *arena) { + return (envoy_api_v2_auth_SdsSecretConfig**)_upb_array_resize_accessor(msg, UPB_SIZE(12, 24), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct envoy_api_v2_auth_SdsSecretConfig* envoy_api_v2_auth_CommonTlsContext_add_tls_certificate_sds_secret_configs(envoy_api_v2_auth_CommonTlsContext *msg, upb_arena *arena) { + struct envoy_api_v2_auth_SdsSecretConfig* sub = (struct envoy_api_v2_auth_SdsSecretConfig*)upb_msg_new(&envoy_api_v2_auth_SdsSecretConfig_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(12, 24), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE void envoy_api_v2_auth_CommonTlsContext_set_validation_context_sds_secret_config(envoy_api_v2_auth_CommonTlsContext *msg, envoy_api_v2_auth_SdsSecretConfig* value) { + UPB_WRITE_ONEOF(msg, envoy_api_v2_auth_SdsSecretConfig*, UPB_SIZE(16, 32), value, UPB_SIZE(20, 40), 7); +} +UPB_INLINE struct envoy_api_v2_auth_SdsSecretConfig* envoy_api_v2_auth_CommonTlsContext_mutable_validation_context_sds_secret_config(envoy_api_v2_auth_CommonTlsContext *msg, upb_arena *arena) { + struct envoy_api_v2_auth_SdsSecretConfig* sub = (struct envoy_api_v2_auth_SdsSecretConfig*)envoy_api_v2_auth_CommonTlsContext_validation_context_sds_secret_config(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_auth_SdsSecretConfig*)upb_msg_new(&envoy_api_v2_auth_SdsSecretConfig_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_auth_CommonTlsContext_set_validation_context_sds_secret_config(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_auth_CommonTlsContext_set_combined_validation_context(envoy_api_v2_auth_CommonTlsContext *msg, envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext* value) { + UPB_WRITE_ONEOF(msg, envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext*, UPB_SIZE(16, 32), value, UPB_SIZE(20, 40), 8); +} +UPB_INLINE struct envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext* envoy_api_v2_auth_CommonTlsContext_mutable_combined_validation_context(envoy_api_v2_auth_CommonTlsContext *msg, upb_arena *arena) { + struct envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext* sub = (struct envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext*)envoy_api_v2_auth_CommonTlsContext_combined_validation_context(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext*)upb_msg_new(&envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_auth_CommonTlsContext_set_combined_validation_context(msg, sub); + } + return sub; +} + + +/* envoy.api.v2.auth.CommonTlsContext.CombinedCertificateValidationContext */ + +UPB_INLINE envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext *envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext_new(upb_arena *arena) { + return (envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext *)upb_msg_new(&envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext_msginit, arena); +} +UPB_INLINE envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext *envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext *ret = envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext_serialize(const envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext_msginit, arena, len); +} + +UPB_INLINE const envoy_api_v2_auth_CertificateValidationContext* envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext_default_validation_context(const envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext *msg) { return UPB_FIELD_AT(msg, const envoy_api_v2_auth_CertificateValidationContext*, UPB_SIZE(0, 0)); } +UPB_INLINE const envoy_api_v2_auth_SdsSecretConfig* envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext_validation_context_sds_secret_config(const envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext *msg) { return UPB_FIELD_AT(msg, const envoy_api_v2_auth_SdsSecretConfig*, UPB_SIZE(4, 8)); } + +UPB_INLINE void envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext_set_default_validation_context(envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext *msg, envoy_api_v2_auth_CertificateValidationContext* value) { + UPB_FIELD_AT(msg, envoy_api_v2_auth_CertificateValidationContext*, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE struct envoy_api_v2_auth_CertificateValidationContext* envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext_mutable_default_validation_context(envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext *msg, upb_arena *arena) { + struct envoy_api_v2_auth_CertificateValidationContext* sub = (struct envoy_api_v2_auth_CertificateValidationContext*)envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext_default_validation_context(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_auth_CertificateValidationContext*)upb_msg_new(&envoy_api_v2_auth_CertificateValidationContext_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext_set_default_validation_context(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext_set_validation_context_sds_secret_config(envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext *msg, envoy_api_v2_auth_SdsSecretConfig* value) { + UPB_FIELD_AT(msg, envoy_api_v2_auth_SdsSecretConfig*, UPB_SIZE(4, 8)) = value; +} +UPB_INLINE struct envoy_api_v2_auth_SdsSecretConfig* envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext_mutable_validation_context_sds_secret_config(envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext *msg, upb_arena *arena) { + struct envoy_api_v2_auth_SdsSecretConfig* sub = (struct envoy_api_v2_auth_SdsSecretConfig*)envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext_validation_context_sds_secret_config(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_auth_SdsSecretConfig*)upb_msg_new(&envoy_api_v2_auth_SdsSecretConfig_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext_set_validation_context_sds_secret_config(msg, sub); + } + return sub; +} + + +/* envoy.api.v2.auth.UpstreamTlsContext */ + +UPB_INLINE envoy_api_v2_auth_UpstreamTlsContext *envoy_api_v2_auth_UpstreamTlsContext_new(upb_arena *arena) { + return (envoy_api_v2_auth_UpstreamTlsContext *)upb_msg_new(&envoy_api_v2_auth_UpstreamTlsContext_msginit, arena); +} +UPB_INLINE envoy_api_v2_auth_UpstreamTlsContext *envoy_api_v2_auth_UpstreamTlsContext_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_auth_UpstreamTlsContext *ret = envoy_api_v2_auth_UpstreamTlsContext_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_auth_UpstreamTlsContext_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_auth_UpstreamTlsContext_serialize(const envoy_api_v2_auth_UpstreamTlsContext *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_auth_UpstreamTlsContext_msginit, arena, len); +} + +UPB_INLINE const envoy_api_v2_auth_CommonTlsContext* envoy_api_v2_auth_UpstreamTlsContext_common_tls_context(const envoy_api_v2_auth_UpstreamTlsContext *msg) { return UPB_FIELD_AT(msg, const envoy_api_v2_auth_CommonTlsContext*, UPB_SIZE(12, 24)); } +UPB_INLINE upb_strview envoy_api_v2_auth_UpstreamTlsContext_sni(const envoy_api_v2_auth_UpstreamTlsContext *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)); } +UPB_INLINE bool envoy_api_v2_auth_UpstreamTlsContext_allow_renegotiation(const envoy_api_v2_auth_UpstreamTlsContext *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(0, 0)); } + +UPB_INLINE void envoy_api_v2_auth_UpstreamTlsContext_set_common_tls_context(envoy_api_v2_auth_UpstreamTlsContext *msg, envoy_api_v2_auth_CommonTlsContext* value) { + UPB_FIELD_AT(msg, envoy_api_v2_auth_CommonTlsContext*, UPB_SIZE(12, 24)) = value; +} +UPB_INLINE struct envoy_api_v2_auth_CommonTlsContext* envoy_api_v2_auth_UpstreamTlsContext_mutable_common_tls_context(envoy_api_v2_auth_UpstreamTlsContext *msg, upb_arena *arena) { + struct envoy_api_v2_auth_CommonTlsContext* sub = (struct envoy_api_v2_auth_CommonTlsContext*)envoy_api_v2_auth_UpstreamTlsContext_common_tls_context(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_auth_CommonTlsContext*)upb_msg_new(&envoy_api_v2_auth_CommonTlsContext_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_auth_UpstreamTlsContext_set_common_tls_context(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_auth_UpstreamTlsContext_set_sni(envoy_api_v2_auth_UpstreamTlsContext *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)) = value; +} +UPB_INLINE void envoy_api_v2_auth_UpstreamTlsContext_set_allow_renegotiation(envoy_api_v2_auth_UpstreamTlsContext *msg, bool value) { + UPB_FIELD_AT(msg, bool, UPB_SIZE(0, 0)) = value; +} + + +/* envoy.api.v2.auth.DownstreamTlsContext */ + +UPB_INLINE envoy_api_v2_auth_DownstreamTlsContext *envoy_api_v2_auth_DownstreamTlsContext_new(upb_arena *arena) { + return (envoy_api_v2_auth_DownstreamTlsContext *)upb_msg_new(&envoy_api_v2_auth_DownstreamTlsContext_msginit, arena); +} +UPB_INLINE envoy_api_v2_auth_DownstreamTlsContext *envoy_api_v2_auth_DownstreamTlsContext_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_auth_DownstreamTlsContext *ret = envoy_api_v2_auth_DownstreamTlsContext_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_auth_DownstreamTlsContext_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_auth_DownstreamTlsContext_serialize(const envoy_api_v2_auth_DownstreamTlsContext *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_auth_DownstreamTlsContext_msginit, arena, len); +} + +typedef enum { + envoy_api_v2_auth_DownstreamTlsContext_session_ticket_keys_type_session_ticket_keys = 4, + envoy_api_v2_auth_DownstreamTlsContext_session_ticket_keys_type_session_ticket_keys_sds_secret_config = 5, + envoy_api_v2_auth_DownstreamTlsContext_session_ticket_keys_type_NOT_SET = 0, +} envoy_api_v2_auth_DownstreamTlsContext_session_ticket_keys_type_oneofcases; +UPB_INLINE envoy_api_v2_auth_DownstreamTlsContext_session_ticket_keys_type_oneofcases envoy_api_v2_auth_DownstreamTlsContext_session_ticket_keys_type_case(const envoy_api_v2_auth_DownstreamTlsContext* msg) { return UPB_FIELD_AT(msg, int, UPB_SIZE(16, 32)); } + +UPB_INLINE const envoy_api_v2_auth_CommonTlsContext* envoy_api_v2_auth_DownstreamTlsContext_common_tls_context(const envoy_api_v2_auth_DownstreamTlsContext *msg) { return UPB_FIELD_AT(msg, const envoy_api_v2_auth_CommonTlsContext*, UPB_SIZE(0, 0)); } +UPB_INLINE const struct google_protobuf_BoolValue* envoy_api_v2_auth_DownstreamTlsContext_require_client_certificate(const envoy_api_v2_auth_DownstreamTlsContext *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_BoolValue*, UPB_SIZE(4, 8)); } +UPB_INLINE const struct google_protobuf_BoolValue* envoy_api_v2_auth_DownstreamTlsContext_require_sni(const envoy_api_v2_auth_DownstreamTlsContext *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_BoolValue*, UPB_SIZE(8, 16)); } +UPB_INLINE bool envoy_api_v2_auth_DownstreamTlsContext_has_session_ticket_keys(const envoy_api_v2_auth_DownstreamTlsContext *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(16, 32), 4); } +UPB_INLINE const envoy_api_v2_auth_TlsSessionTicketKeys* envoy_api_v2_auth_DownstreamTlsContext_session_ticket_keys(const envoy_api_v2_auth_DownstreamTlsContext *msg) { return UPB_READ_ONEOF(msg, const envoy_api_v2_auth_TlsSessionTicketKeys*, UPB_SIZE(12, 24), UPB_SIZE(16, 32), 4, NULL); } +UPB_INLINE bool envoy_api_v2_auth_DownstreamTlsContext_has_session_ticket_keys_sds_secret_config(const envoy_api_v2_auth_DownstreamTlsContext *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(16, 32), 5); } +UPB_INLINE const envoy_api_v2_auth_SdsSecretConfig* envoy_api_v2_auth_DownstreamTlsContext_session_ticket_keys_sds_secret_config(const envoy_api_v2_auth_DownstreamTlsContext *msg) { return UPB_READ_ONEOF(msg, const envoy_api_v2_auth_SdsSecretConfig*, UPB_SIZE(12, 24), UPB_SIZE(16, 32), 5, NULL); } + +UPB_INLINE void envoy_api_v2_auth_DownstreamTlsContext_set_common_tls_context(envoy_api_v2_auth_DownstreamTlsContext *msg, envoy_api_v2_auth_CommonTlsContext* value) { + UPB_FIELD_AT(msg, envoy_api_v2_auth_CommonTlsContext*, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE struct envoy_api_v2_auth_CommonTlsContext* envoy_api_v2_auth_DownstreamTlsContext_mutable_common_tls_context(envoy_api_v2_auth_DownstreamTlsContext *msg, upb_arena *arena) { + struct envoy_api_v2_auth_CommonTlsContext* sub = (struct envoy_api_v2_auth_CommonTlsContext*)envoy_api_v2_auth_DownstreamTlsContext_common_tls_context(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_auth_CommonTlsContext*)upb_msg_new(&envoy_api_v2_auth_CommonTlsContext_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_auth_DownstreamTlsContext_set_common_tls_context(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_auth_DownstreamTlsContext_set_require_client_certificate(envoy_api_v2_auth_DownstreamTlsContext *msg, struct google_protobuf_BoolValue* value) { + UPB_FIELD_AT(msg, struct google_protobuf_BoolValue*, UPB_SIZE(4, 8)) = value; +} +UPB_INLINE struct google_protobuf_BoolValue* envoy_api_v2_auth_DownstreamTlsContext_mutable_require_client_certificate(envoy_api_v2_auth_DownstreamTlsContext *msg, upb_arena *arena) { + struct google_protobuf_BoolValue* sub = (struct google_protobuf_BoolValue*)envoy_api_v2_auth_DownstreamTlsContext_require_client_certificate(msg); + if (sub == NULL) { + sub = (struct google_protobuf_BoolValue*)upb_msg_new(&google_protobuf_BoolValue_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_auth_DownstreamTlsContext_set_require_client_certificate(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_auth_DownstreamTlsContext_set_require_sni(envoy_api_v2_auth_DownstreamTlsContext *msg, struct google_protobuf_BoolValue* value) { + UPB_FIELD_AT(msg, struct google_protobuf_BoolValue*, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE struct google_protobuf_BoolValue* envoy_api_v2_auth_DownstreamTlsContext_mutable_require_sni(envoy_api_v2_auth_DownstreamTlsContext *msg, upb_arena *arena) { + struct google_protobuf_BoolValue* sub = (struct google_protobuf_BoolValue*)envoy_api_v2_auth_DownstreamTlsContext_require_sni(msg); + if (sub == NULL) { + sub = (struct google_protobuf_BoolValue*)upb_msg_new(&google_protobuf_BoolValue_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_auth_DownstreamTlsContext_set_require_sni(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_auth_DownstreamTlsContext_set_session_ticket_keys(envoy_api_v2_auth_DownstreamTlsContext *msg, envoy_api_v2_auth_TlsSessionTicketKeys* value) { + UPB_WRITE_ONEOF(msg, envoy_api_v2_auth_TlsSessionTicketKeys*, UPB_SIZE(12, 24), value, UPB_SIZE(16, 32), 4); +} +UPB_INLINE struct envoy_api_v2_auth_TlsSessionTicketKeys* envoy_api_v2_auth_DownstreamTlsContext_mutable_session_ticket_keys(envoy_api_v2_auth_DownstreamTlsContext *msg, upb_arena *arena) { + struct envoy_api_v2_auth_TlsSessionTicketKeys* sub = (struct envoy_api_v2_auth_TlsSessionTicketKeys*)envoy_api_v2_auth_DownstreamTlsContext_session_ticket_keys(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_auth_TlsSessionTicketKeys*)upb_msg_new(&envoy_api_v2_auth_TlsSessionTicketKeys_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_auth_DownstreamTlsContext_set_session_ticket_keys(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_auth_DownstreamTlsContext_set_session_ticket_keys_sds_secret_config(envoy_api_v2_auth_DownstreamTlsContext *msg, envoy_api_v2_auth_SdsSecretConfig* value) { + UPB_WRITE_ONEOF(msg, envoy_api_v2_auth_SdsSecretConfig*, UPB_SIZE(12, 24), value, UPB_SIZE(16, 32), 5); +} +UPB_INLINE struct envoy_api_v2_auth_SdsSecretConfig* envoy_api_v2_auth_DownstreamTlsContext_mutable_session_ticket_keys_sds_secret_config(envoy_api_v2_auth_DownstreamTlsContext *msg, upb_arena *arena) { + struct envoy_api_v2_auth_SdsSecretConfig* sub = (struct envoy_api_v2_auth_SdsSecretConfig*)envoy_api_v2_auth_DownstreamTlsContext_session_ticket_keys_sds_secret_config(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_auth_SdsSecretConfig*)upb_msg_new(&envoy_api_v2_auth_SdsSecretConfig_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_auth_DownstreamTlsContext_set_session_ticket_keys_sds_secret_config(msg, sub); + } + return sub; +} + + +/* envoy.api.v2.auth.SdsSecretConfig */ + +UPB_INLINE envoy_api_v2_auth_SdsSecretConfig *envoy_api_v2_auth_SdsSecretConfig_new(upb_arena *arena) { + return (envoy_api_v2_auth_SdsSecretConfig *)upb_msg_new(&envoy_api_v2_auth_SdsSecretConfig_msginit, arena); +} +UPB_INLINE envoy_api_v2_auth_SdsSecretConfig *envoy_api_v2_auth_SdsSecretConfig_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_auth_SdsSecretConfig *ret = envoy_api_v2_auth_SdsSecretConfig_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_auth_SdsSecretConfig_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_auth_SdsSecretConfig_serialize(const envoy_api_v2_auth_SdsSecretConfig *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_auth_SdsSecretConfig_msginit, arena, len); +} + +UPB_INLINE upb_strview envoy_api_v2_auth_SdsSecretConfig_name(const envoy_api_v2_auth_SdsSecretConfig *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } +UPB_INLINE const struct envoy_api_v2_core_ConfigSource* envoy_api_v2_auth_SdsSecretConfig_sds_config(const envoy_api_v2_auth_SdsSecretConfig *msg) { return UPB_FIELD_AT(msg, const struct envoy_api_v2_core_ConfigSource*, UPB_SIZE(8, 16)); } + +UPB_INLINE void envoy_api_v2_auth_SdsSecretConfig_set_name(envoy_api_v2_auth_SdsSecretConfig *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_api_v2_auth_SdsSecretConfig_set_sds_config(envoy_api_v2_auth_SdsSecretConfig *msg, struct envoy_api_v2_core_ConfigSource* value) { + UPB_FIELD_AT(msg, struct envoy_api_v2_core_ConfigSource*, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE struct envoy_api_v2_core_ConfigSource* envoy_api_v2_auth_SdsSecretConfig_mutable_sds_config(envoy_api_v2_auth_SdsSecretConfig *msg, upb_arena *arena) { + struct envoy_api_v2_core_ConfigSource* sub = (struct envoy_api_v2_core_ConfigSource*)envoy_api_v2_auth_SdsSecretConfig_sds_config(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_ConfigSource*)upb_msg_new(&envoy_api_v2_core_ConfigSource_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_auth_SdsSecretConfig_set_sds_config(msg, sub); + } + return sub; +} + + +/* envoy.api.v2.auth.Secret */ + +UPB_INLINE envoy_api_v2_auth_Secret *envoy_api_v2_auth_Secret_new(upb_arena *arena) { + return (envoy_api_v2_auth_Secret *)upb_msg_new(&envoy_api_v2_auth_Secret_msginit, arena); +} +UPB_INLINE envoy_api_v2_auth_Secret *envoy_api_v2_auth_Secret_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_auth_Secret *ret = envoy_api_v2_auth_Secret_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_auth_Secret_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_auth_Secret_serialize(const envoy_api_v2_auth_Secret *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_auth_Secret_msginit, arena, len); +} + +typedef enum { + envoy_api_v2_auth_Secret_type_tls_certificate = 2, + envoy_api_v2_auth_Secret_type_session_ticket_keys = 3, + envoy_api_v2_auth_Secret_type_validation_context = 4, + envoy_api_v2_auth_Secret_type_NOT_SET = 0, +} envoy_api_v2_auth_Secret_type_oneofcases; +UPB_INLINE envoy_api_v2_auth_Secret_type_oneofcases envoy_api_v2_auth_Secret_type_case(const envoy_api_v2_auth_Secret* msg) { return UPB_FIELD_AT(msg, int, UPB_SIZE(12, 24)); } + +UPB_INLINE upb_strview envoy_api_v2_auth_Secret_name(const envoy_api_v2_auth_Secret *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } +UPB_INLINE bool envoy_api_v2_auth_Secret_has_tls_certificate(const envoy_api_v2_auth_Secret *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(12, 24), 2); } +UPB_INLINE const envoy_api_v2_auth_TlsCertificate* envoy_api_v2_auth_Secret_tls_certificate(const envoy_api_v2_auth_Secret *msg) { return UPB_READ_ONEOF(msg, const envoy_api_v2_auth_TlsCertificate*, UPB_SIZE(8, 16), UPB_SIZE(12, 24), 2, NULL); } +UPB_INLINE bool envoy_api_v2_auth_Secret_has_session_ticket_keys(const envoy_api_v2_auth_Secret *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(12, 24), 3); } +UPB_INLINE const envoy_api_v2_auth_TlsSessionTicketKeys* envoy_api_v2_auth_Secret_session_ticket_keys(const envoy_api_v2_auth_Secret *msg) { return UPB_READ_ONEOF(msg, const envoy_api_v2_auth_TlsSessionTicketKeys*, UPB_SIZE(8, 16), UPB_SIZE(12, 24), 3, NULL); } +UPB_INLINE bool envoy_api_v2_auth_Secret_has_validation_context(const envoy_api_v2_auth_Secret *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(12, 24), 4); } +UPB_INLINE const envoy_api_v2_auth_CertificateValidationContext* envoy_api_v2_auth_Secret_validation_context(const envoy_api_v2_auth_Secret *msg) { return UPB_READ_ONEOF(msg, const envoy_api_v2_auth_CertificateValidationContext*, UPB_SIZE(8, 16), UPB_SIZE(12, 24), 4, NULL); } + +UPB_INLINE void envoy_api_v2_auth_Secret_set_name(envoy_api_v2_auth_Secret *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_api_v2_auth_Secret_set_tls_certificate(envoy_api_v2_auth_Secret *msg, envoy_api_v2_auth_TlsCertificate* value) { + UPB_WRITE_ONEOF(msg, envoy_api_v2_auth_TlsCertificate*, UPB_SIZE(8, 16), value, UPB_SIZE(12, 24), 2); +} +UPB_INLINE struct envoy_api_v2_auth_TlsCertificate* envoy_api_v2_auth_Secret_mutable_tls_certificate(envoy_api_v2_auth_Secret *msg, upb_arena *arena) { + struct envoy_api_v2_auth_TlsCertificate* sub = (struct envoy_api_v2_auth_TlsCertificate*)envoy_api_v2_auth_Secret_tls_certificate(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_auth_TlsCertificate*)upb_msg_new(&envoy_api_v2_auth_TlsCertificate_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_auth_Secret_set_tls_certificate(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_auth_Secret_set_session_ticket_keys(envoy_api_v2_auth_Secret *msg, envoy_api_v2_auth_TlsSessionTicketKeys* value) { + UPB_WRITE_ONEOF(msg, envoy_api_v2_auth_TlsSessionTicketKeys*, UPB_SIZE(8, 16), value, UPB_SIZE(12, 24), 3); +} +UPB_INLINE struct envoy_api_v2_auth_TlsSessionTicketKeys* envoy_api_v2_auth_Secret_mutable_session_ticket_keys(envoy_api_v2_auth_Secret *msg, upb_arena *arena) { + struct envoy_api_v2_auth_TlsSessionTicketKeys* sub = (struct envoy_api_v2_auth_TlsSessionTicketKeys*)envoy_api_v2_auth_Secret_session_ticket_keys(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_auth_TlsSessionTicketKeys*)upb_msg_new(&envoy_api_v2_auth_TlsSessionTicketKeys_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_auth_Secret_set_session_ticket_keys(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_auth_Secret_set_validation_context(envoy_api_v2_auth_Secret *msg, envoy_api_v2_auth_CertificateValidationContext* value) { + UPB_WRITE_ONEOF(msg, envoy_api_v2_auth_CertificateValidationContext*, UPB_SIZE(8, 16), value, UPB_SIZE(12, 24), 4); +} +UPB_INLINE struct envoy_api_v2_auth_CertificateValidationContext* envoy_api_v2_auth_Secret_mutable_validation_context(envoy_api_v2_auth_Secret *msg, upb_arena *arena) { + struct envoy_api_v2_auth_CertificateValidationContext* sub = (struct envoy_api_v2_auth_CertificateValidationContext*)envoy_api_v2_auth_Secret_validation_context(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_auth_CertificateValidationContext*)upb_msg_new(&envoy_api_v2_auth_CertificateValidationContext_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_auth_Secret_set_validation_context(msg, sub); + } + return sub; +} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* ENVOY_API_V2_AUTH_CERT_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/envoy/api/v2/cds.upb.c b/src/core/ext/upb-generated/envoy/api/v2/cds.upb.c new file mode 100644 index 00000000000..91a25cd220b --- /dev/null +++ b/src/core/ext/upb-generated/envoy/api/v2/cds.upb.c @@ -0,0 +1,285 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/api/v2/cds.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include +#include "upb/msg.h" +#include "envoy/api/v2/cds.upb.h" +#include "envoy/api/v2/core/address.upb.h" +#include "envoy/api/v2/auth/cert.upb.h" +#include "envoy/api/v2/core/base.upb.h" +#include "envoy/api/v2/core/config_source.upb.h" +#include "envoy/api/v2/discovery.upb.h" +#include "envoy/api/v2/core/health_check.upb.h" +#include "envoy/api/v2/core/protocol.upb.h" +#include "envoy/api/v2/cluster/circuit_breaker.upb.h" +#include "envoy/api/v2/cluster/outlier_detection.upb.h" +#include "envoy/api/v2/eds.upb.h" +#include "envoy/type/percent.upb.h" +#include "google/api/annotations.upb.h" +#include "google/protobuf/any.upb.h" +#include "google/protobuf/duration.upb.h" +#include "google/protobuf/struct.upb.h" +#include "google/protobuf/wrappers.upb.h" +#include "validate/validate.upb.h" +#include "gogoproto/gogo.upb.h" + +#include "upb/port_def.inc" + +static const upb_msglayout *const envoy_api_v2_Cluster_submsgs[26] = { + &envoy_api_v2_Cluster_CommonLbConfig_msginit, + &envoy_api_v2_Cluster_EdsClusterConfig_msginit, + &envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry_msginit, + &envoy_api_v2_Cluster_LbSubsetConfig_msginit, + &envoy_api_v2_Cluster_OriginalDstLbConfig_msginit, + &envoy_api_v2_Cluster_RingHashLbConfig_msginit, + &envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry_msginit, + &envoy_api_v2_ClusterLoadAssignment_msginit, + &envoy_api_v2_UpstreamConnectionOptions_msginit, + &envoy_api_v2_auth_UpstreamTlsContext_msginit, + &envoy_api_v2_cluster_CircuitBreakers_msginit, + &envoy_api_v2_cluster_OutlierDetection_msginit, + &envoy_api_v2_core_Address_msginit, + &envoy_api_v2_core_BindConfig_msginit, + &envoy_api_v2_core_HealthCheck_msginit, + &envoy_api_v2_core_Http1ProtocolOptions_msginit, + &envoy_api_v2_core_Http2ProtocolOptions_msginit, + &envoy_api_v2_core_HttpProtocolOptions_msginit, + &envoy_api_v2_core_Metadata_msginit, + &envoy_api_v2_core_TransportSocket_msginit, + &google_protobuf_Duration_msginit, + &google_protobuf_UInt32Value_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_Cluster__fields[34] = { + {1, UPB_SIZE(36, 40), 0, 0, 9, 1}, + {2, UPB_SIZE(0, 0), 0, 0, 14, 1}, + {3, UPB_SIZE(52, 72), 0, 1, 11, 1}, + {4, UPB_SIZE(56, 80), 0, 20, 11, 1}, + {5, UPB_SIZE(60, 88), 0, 21, 11, 1}, + {6, UPB_SIZE(8, 8), 0, 0, 14, 1}, + {7, UPB_SIZE(128, 224), 0, 12, 11, 3}, + {8, UPB_SIZE(132, 232), 0, 14, 11, 3}, + {9, UPB_SIZE(64, 96), 0, 21, 11, 1}, + {10, UPB_SIZE(68, 104), 0, 10, 11, 1}, + {11, UPB_SIZE(72, 112), 0, 9, 11, 1}, + {13, UPB_SIZE(76, 120), 0, 15, 11, 1}, + {14, UPB_SIZE(80, 128), 0, 16, 11, 1}, + {16, UPB_SIZE(84, 136), 0, 20, 11, 1}, + {17, UPB_SIZE(16, 16), 0, 0, 14, 1}, + {18, UPB_SIZE(136, 240), 0, 12, 11, 3}, + {19, UPB_SIZE(88, 144), 0, 11, 11, 1}, + {20, UPB_SIZE(92, 152), 0, 20, 11, 1}, + {21, UPB_SIZE(96, 160), 0, 13, 11, 1}, + {22, UPB_SIZE(100, 168), 0, 3, 11, 1}, + {23, UPB_SIZE(148, 264), UPB_SIZE(-153, -273), 5, 11, 1}, + {24, UPB_SIZE(104, 176), 0, 19, 11, 1}, + {25, UPB_SIZE(108, 184), 0, 18, 11, 1}, + {26, UPB_SIZE(24, 24), 0, 0, 14, 1}, + {27, UPB_SIZE(112, 192), 0, 0, 11, 1}, + {28, UPB_SIZE(44, 56), 0, 0, 9, 1}, + {29, UPB_SIZE(116, 200), 0, 17, 11, 1}, + {30, UPB_SIZE(120, 208), 0, 8, 11, 1}, + {31, UPB_SIZE(32, 32), 0, 0, 8, 1}, + {32, UPB_SIZE(33, 33), 0, 0, 8, 1}, + {33, UPB_SIZE(124, 216), 0, 7, 11, 1}, + {34, UPB_SIZE(148, 264), UPB_SIZE(-153, -273), 4, 11, 1}, + {35, UPB_SIZE(140, 248), 0, 2, 11, 3}, + {36, UPB_SIZE(144, 256), 0, 6, 11, 3}, +}; + +const upb_msglayout envoy_api_v2_Cluster_msginit = { + &envoy_api_v2_Cluster_submsgs[0], + &envoy_api_v2_Cluster__fields[0], + UPB_SIZE(160, 288), 34, false, +}; + +static const upb_msglayout *const envoy_api_v2_Cluster_EdsClusterConfig_submsgs[1] = { + &envoy_api_v2_core_ConfigSource_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_Cluster_EdsClusterConfig__fields[2] = { + {1, UPB_SIZE(8, 16), 0, 0, 11, 1}, + {2, UPB_SIZE(0, 0), 0, 0, 9, 1}, +}; + +const upb_msglayout envoy_api_v2_Cluster_EdsClusterConfig_msginit = { + &envoy_api_v2_Cluster_EdsClusterConfig_submsgs[0], + &envoy_api_v2_Cluster_EdsClusterConfig__fields[0], + UPB_SIZE(16, 32), 2, false, +}; + +static const upb_msglayout *const envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry_submsgs[1] = { + &google_protobuf_Struct_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry__fields[2] = { + {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, + {2, UPB_SIZE(8, 16), 0, 0, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry_msginit = { + &envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry_submsgs[0], + &envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry__fields[0], + UPB_SIZE(16, 32), 2, false, +}; + +static const upb_msglayout *const envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry_submsgs[1] = { + &google_protobuf_Any_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry__fields[2] = { + {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, + {2, UPB_SIZE(8, 16), 0, 0, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry_msginit = { + &envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry_submsgs[0], + &envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry__fields[0], + UPB_SIZE(16, 32), 2, false, +}; + +static const upb_msglayout *const envoy_api_v2_Cluster_LbSubsetConfig_submsgs[2] = { + &envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector_msginit, + &google_protobuf_Struct_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_Cluster_LbSubsetConfig__fields[4] = { + {1, UPB_SIZE(0, 0), 0, 0, 14, 1}, + {2, UPB_SIZE(12, 16), 0, 1, 11, 1}, + {3, UPB_SIZE(16, 24), 0, 0, 11, 3}, + {4, UPB_SIZE(8, 8), 0, 0, 8, 1}, +}; + +const upb_msglayout envoy_api_v2_Cluster_LbSubsetConfig_msginit = { + &envoy_api_v2_Cluster_LbSubsetConfig_submsgs[0], + &envoy_api_v2_Cluster_LbSubsetConfig__fields[0], + UPB_SIZE(24, 32), 4, false, +}; + +static const upb_msglayout_field envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 9, 3}, +}; + +const upb_msglayout envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector_msginit = { + NULL, + &envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector__fields[0], + UPB_SIZE(4, 8), 1, false, +}; + +static const upb_msglayout *const envoy_api_v2_Cluster_RingHashLbConfig_submsgs[2] = { + &envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1_msginit, + &google_protobuf_UInt64Value_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_Cluster_RingHashLbConfig__fields[2] = { + {1, UPB_SIZE(0, 0), 0, 1, 11, 1}, + {2, UPB_SIZE(4, 8), 0, 0, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_Cluster_RingHashLbConfig_msginit = { + &envoy_api_v2_Cluster_RingHashLbConfig_submsgs[0], + &envoy_api_v2_Cluster_RingHashLbConfig__fields[0], + UPB_SIZE(8, 16), 2, false, +}; + +static const upb_msglayout *const envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1_submsgs[1] = { + &google_protobuf_BoolValue_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1_msginit = { + &envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1_submsgs[0], + &envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1__fields[0], + UPB_SIZE(4, 8), 1, false, +}; + +static const upb_msglayout_field envoy_api_v2_Cluster_OriginalDstLbConfig__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 8, 1}, +}; + +const upb_msglayout envoy_api_v2_Cluster_OriginalDstLbConfig_msginit = { + NULL, + &envoy_api_v2_Cluster_OriginalDstLbConfig__fields[0], + UPB_SIZE(1, 1), 1, false, +}; + +static const upb_msglayout *const envoy_api_v2_Cluster_CommonLbConfig_submsgs[4] = { + &envoy_api_v2_Cluster_CommonLbConfig_LocalityWeightedLbConfig_msginit, + &envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig_msginit, + &envoy_type_Percent_msginit, + &google_protobuf_Duration_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_Cluster_CommonLbConfig__fields[4] = { + {1, UPB_SIZE(0, 0), 0, 2, 11, 1}, + {2, UPB_SIZE(8, 16), UPB_SIZE(-13, -25), 1, 11, 1}, + {3, UPB_SIZE(8, 16), UPB_SIZE(-13, -25), 0, 11, 1}, + {4, UPB_SIZE(4, 8), 0, 3, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_Cluster_CommonLbConfig_msginit = { + &envoy_api_v2_Cluster_CommonLbConfig_submsgs[0], + &envoy_api_v2_Cluster_CommonLbConfig__fields[0], + UPB_SIZE(16, 32), 4, false, +}; + +static const upb_msglayout *const envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig_submsgs[2] = { + &envoy_type_Percent_msginit, + &google_protobuf_UInt64Value_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig__fields[2] = { + {1, UPB_SIZE(0, 0), 0, 0, 11, 1}, + {2, UPB_SIZE(4, 8), 0, 1, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig_msginit = { + &envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig_submsgs[0], + &envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig__fields[0], + UPB_SIZE(8, 16), 2, false, +}; + +const upb_msglayout envoy_api_v2_Cluster_CommonLbConfig_LocalityWeightedLbConfig_msginit = { + NULL, + NULL, + UPB_SIZE(0, 0), 0, false, +}; + +static const upb_msglayout *const envoy_api_v2_UpstreamBindConfig_submsgs[1] = { + &envoy_api_v2_core_Address_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_UpstreamBindConfig__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_UpstreamBindConfig_msginit = { + &envoy_api_v2_UpstreamBindConfig_submsgs[0], + &envoy_api_v2_UpstreamBindConfig__fields[0], + UPB_SIZE(4, 8), 1, false, +}; + +static const upb_msglayout *const envoy_api_v2_UpstreamConnectionOptions_submsgs[1] = { + &envoy_api_v2_core_TcpKeepalive_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_UpstreamConnectionOptions__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_UpstreamConnectionOptions_msginit = { + &envoy_api_v2_UpstreamConnectionOptions_submsgs[0], + &envoy_api_v2_UpstreamConnectionOptions__fields[0], + UPB_SIZE(4, 8), 1, false, +}; + +#include "upb/port_undef.inc" + diff --git a/src/core/ext/upb-generated/envoy/api/v2/cds.upb.h b/src/core/ext/upb-generated/envoy/api/v2/cds.upb.h new file mode 100644 index 00000000000..e960b82506e --- /dev/null +++ b/src/core/ext/upb-generated/envoy/api/v2/cds.upb.h @@ -0,0 +1,1012 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/api/v2/cds.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef ENVOY_API_V2_CDS_PROTO_UPB_H_ +#define ENVOY_API_V2_CDS_PROTO_UPB_H_ + +#include "upb/generated_util.h" + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +#ifdef __cplusplus +extern "C" { +#endif + +struct envoy_api_v2_Cluster; +struct envoy_api_v2_Cluster_EdsClusterConfig; +struct envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry; +struct envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry; +struct envoy_api_v2_Cluster_LbSubsetConfig; +struct envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector; +struct envoy_api_v2_Cluster_RingHashLbConfig; +struct envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1; +struct envoy_api_v2_Cluster_OriginalDstLbConfig; +struct envoy_api_v2_Cluster_CommonLbConfig; +struct envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig; +struct envoy_api_v2_Cluster_CommonLbConfig_LocalityWeightedLbConfig; +struct envoy_api_v2_UpstreamBindConfig; +struct envoy_api_v2_UpstreamConnectionOptions; +typedef struct envoy_api_v2_Cluster envoy_api_v2_Cluster; +typedef struct envoy_api_v2_Cluster_EdsClusterConfig envoy_api_v2_Cluster_EdsClusterConfig; +typedef struct envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry; +typedef struct envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry; +typedef struct envoy_api_v2_Cluster_LbSubsetConfig envoy_api_v2_Cluster_LbSubsetConfig; +typedef struct envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector; +typedef struct envoy_api_v2_Cluster_RingHashLbConfig envoy_api_v2_Cluster_RingHashLbConfig; +typedef struct envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1 envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1; +typedef struct envoy_api_v2_Cluster_OriginalDstLbConfig envoy_api_v2_Cluster_OriginalDstLbConfig; +typedef struct envoy_api_v2_Cluster_CommonLbConfig envoy_api_v2_Cluster_CommonLbConfig; +typedef struct envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig; +typedef struct envoy_api_v2_Cluster_CommonLbConfig_LocalityWeightedLbConfig envoy_api_v2_Cluster_CommonLbConfig_LocalityWeightedLbConfig; +typedef struct envoy_api_v2_UpstreamBindConfig envoy_api_v2_UpstreamBindConfig; +typedef struct envoy_api_v2_UpstreamConnectionOptions envoy_api_v2_UpstreamConnectionOptions; +extern const upb_msglayout envoy_api_v2_Cluster_msginit; +extern const upb_msglayout envoy_api_v2_Cluster_EdsClusterConfig_msginit; +extern const upb_msglayout envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry_msginit; +extern const upb_msglayout envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry_msginit; +extern const upb_msglayout envoy_api_v2_Cluster_LbSubsetConfig_msginit; +extern const upb_msglayout envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector_msginit; +extern const upb_msglayout envoy_api_v2_Cluster_RingHashLbConfig_msginit; +extern const upb_msglayout envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1_msginit; +extern const upb_msglayout envoy_api_v2_Cluster_OriginalDstLbConfig_msginit; +extern const upb_msglayout envoy_api_v2_Cluster_CommonLbConfig_msginit; +extern const upb_msglayout envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig_msginit; +extern const upb_msglayout envoy_api_v2_Cluster_CommonLbConfig_LocalityWeightedLbConfig_msginit; +extern const upb_msglayout envoy_api_v2_UpstreamBindConfig_msginit; +extern const upb_msglayout envoy_api_v2_UpstreamConnectionOptions_msginit; +struct envoy_api_v2_ClusterLoadAssignment; +struct envoy_api_v2_auth_UpstreamTlsContext; +struct envoy_api_v2_cluster_CircuitBreakers; +struct envoy_api_v2_cluster_OutlierDetection; +struct envoy_api_v2_core_Address; +struct envoy_api_v2_core_BindConfig; +struct envoy_api_v2_core_ConfigSource; +struct envoy_api_v2_core_HealthCheck; +struct envoy_api_v2_core_Http1ProtocolOptions; +struct envoy_api_v2_core_Http2ProtocolOptions; +struct envoy_api_v2_core_HttpProtocolOptions; +struct envoy_api_v2_core_Metadata; +struct envoy_api_v2_core_TcpKeepalive; +struct envoy_api_v2_core_TransportSocket; +struct envoy_type_Percent; +struct google_protobuf_Any; +struct google_protobuf_BoolValue; +struct google_protobuf_Duration; +struct google_protobuf_Struct; +struct google_protobuf_UInt32Value; +struct google_protobuf_UInt64Value; +extern const upb_msglayout envoy_api_v2_ClusterLoadAssignment_msginit; +extern const upb_msglayout envoy_api_v2_auth_UpstreamTlsContext_msginit; +extern const upb_msglayout envoy_api_v2_cluster_CircuitBreakers_msginit; +extern const upb_msglayout envoy_api_v2_cluster_OutlierDetection_msginit; +extern const upb_msglayout envoy_api_v2_core_Address_msginit; +extern const upb_msglayout envoy_api_v2_core_BindConfig_msginit; +extern const upb_msglayout envoy_api_v2_core_ConfigSource_msginit; +extern const upb_msglayout envoy_api_v2_core_HealthCheck_msginit; +extern const upb_msglayout envoy_api_v2_core_Http1ProtocolOptions_msginit; +extern const upb_msglayout envoy_api_v2_core_Http2ProtocolOptions_msginit; +extern const upb_msglayout envoy_api_v2_core_HttpProtocolOptions_msginit; +extern const upb_msglayout envoy_api_v2_core_Metadata_msginit; +extern const upb_msglayout envoy_api_v2_core_TcpKeepalive_msginit; +extern const upb_msglayout envoy_api_v2_core_TransportSocket_msginit; +extern const upb_msglayout envoy_type_Percent_msginit; +extern const upb_msglayout google_protobuf_Any_msginit; +extern const upb_msglayout google_protobuf_BoolValue_msginit; +extern const upb_msglayout google_protobuf_Duration_msginit; +extern const upb_msglayout google_protobuf_Struct_msginit; +extern const upb_msglayout google_protobuf_UInt32Value_msginit; +extern const upb_msglayout google_protobuf_UInt64Value_msginit; + +/* Enums */ + +typedef enum { + envoy_api_v2_Cluster_USE_CONFIGURED_PROTOCOL = 0, + envoy_api_v2_Cluster_USE_DOWNSTREAM_PROTOCOL = 1 +} envoy_api_v2_Cluster_ClusterProtocolSelection; + +typedef enum { + envoy_api_v2_Cluster_STATIC = 0, + envoy_api_v2_Cluster_STRICT_DNS = 1, + envoy_api_v2_Cluster_LOGICAL_DNS = 2, + envoy_api_v2_Cluster_EDS = 3, + envoy_api_v2_Cluster_ORIGINAL_DST = 4 +} envoy_api_v2_Cluster_DiscoveryType; + +typedef enum { + envoy_api_v2_Cluster_AUTO = 0, + envoy_api_v2_Cluster_V4_ONLY = 1, + envoy_api_v2_Cluster_V6_ONLY = 2 +} envoy_api_v2_Cluster_DnsLookupFamily; + +typedef enum { + envoy_api_v2_Cluster_ROUND_ROBIN = 0, + envoy_api_v2_Cluster_LEAST_REQUEST = 1, + envoy_api_v2_Cluster_RING_HASH = 2, + envoy_api_v2_Cluster_RANDOM = 3, + envoy_api_v2_Cluster_ORIGINAL_DST_LB = 4, + envoy_api_v2_Cluster_MAGLEV = 5 +} envoy_api_v2_Cluster_LbPolicy; + +typedef enum { + envoy_api_v2_Cluster_LbSubsetConfig_NO_FALLBACK = 0, + envoy_api_v2_Cluster_LbSubsetConfig_ANY_ENDPOINT = 1, + envoy_api_v2_Cluster_LbSubsetConfig_DEFAULT_SUBSET = 2 +} envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetFallbackPolicy; + + +/* envoy.api.v2.Cluster */ + +UPB_INLINE envoy_api_v2_Cluster *envoy_api_v2_Cluster_new(upb_arena *arena) { + return (envoy_api_v2_Cluster *)upb_msg_new(&envoy_api_v2_Cluster_msginit, arena); +} +UPB_INLINE envoy_api_v2_Cluster *envoy_api_v2_Cluster_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_Cluster *ret = envoy_api_v2_Cluster_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_Cluster_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_Cluster_serialize(const envoy_api_v2_Cluster *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_Cluster_msginit, arena, len); +} + +typedef enum { + envoy_api_v2_Cluster_lb_config_ring_hash_lb_config = 23, + envoy_api_v2_Cluster_lb_config_original_dst_lb_config = 34, + envoy_api_v2_Cluster_lb_config_NOT_SET = 0, +} envoy_api_v2_Cluster_lb_config_oneofcases; +UPB_INLINE envoy_api_v2_Cluster_lb_config_oneofcases envoy_api_v2_Cluster_lb_config_case(const envoy_api_v2_Cluster* msg) { return UPB_FIELD_AT(msg, int, UPB_SIZE(152, 272)); } + +UPB_INLINE upb_strview envoy_api_v2_Cluster_name(const envoy_api_v2_Cluster *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(36, 40)); } +UPB_INLINE int32_t envoy_api_v2_Cluster_type(const envoy_api_v2_Cluster *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(0, 0)); } +UPB_INLINE const envoy_api_v2_Cluster_EdsClusterConfig* envoy_api_v2_Cluster_eds_cluster_config(const envoy_api_v2_Cluster *msg) { return UPB_FIELD_AT(msg, const envoy_api_v2_Cluster_EdsClusterConfig*, UPB_SIZE(52, 72)); } +UPB_INLINE const struct google_protobuf_Duration* envoy_api_v2_Cluster_connect_timeout(const envoy_api_v2_Cluster *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Duration*, UPB_SIZE(56, 80)); } +UPB_INLINE const struct google_protobuf_UInt32Value* envoy_api_v2_Cluster_per_connection_buffer_limit_bytes(const envoy_api_v2_Cluster *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt32Value*, UPB_SIZE(60, 88)); } +UPB_INLINE int32_t envoy_api_v2_Cluster_lb_policy(const envoy_api_v2_Cluster *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); } +UPB_INLINE const struct envoy_api_v2_core_Address* const* envoy_api_v2_Cluster_hosts(const envoy_api_v2_Cluster *msg, size_t *len) { return (const struct envoy_api_v2_core_Address* const*)_upb_array_accessor(msg, UPB_SIZE(128, 224), len); } +UPB_INLINE const struct envoy_api_v2_core_HealthCheck* const* envoy_api_v2_Cluster_health_checks(const envoy_api_v2_Cluster *msg, size_t *len) { return (const struct envoy_api_v2_core_HealthCheck* const*)_upb_array_accessor(msg, UPB_SIZE(132, 232), len); } +UPB_INLINE const struct google_protobuf_UInt32Value* envoy_api_v2_Cluster_max_requests_per_connection(const envoy_api_v2_Cluster *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt32Value*, UPB_SIZE(64, 96)); } +UPB_INLINE const struct envoy_api_v2_cluster_CircuitBreakers* envoy_api_v2_Cluster_circuit_breakers(const envoy_api_v2_Cluster *msg) { return UPB_FIELD_AT(msg, const struct envoy_api_v2_cluster_CircuitBreakers*, UPB_SIZE(68, 104)); } +UPB_INLINE const struct envoy_api_v2_auth_UpstreamTlsContext* envoy_api_v2_Cluster_tls_context(const envoy_api_v2_Cluster *msg) { return UPB_FIELD_AT(msg, const struct envoy_api_v2_auth_UpstreamTlsContext*, UPB_SIZE(72, 112)); } +UPB_INLINE const struct envoy_api_v2_core_Http1ProtocolOptions* envoy_api_v2_Cluster_http_protocol_options(const envoy_api_v2_Cluster *msg) { return UPB_FIELD_AT(msg, const struct envoy_api_v2_core_Http1ProtocolOptions*, UPB_SIZE(76, 120)); } +UPB_INLINE const struct envoy_api_v2_core_Http2ProtocolOptions* envoy_api_v2_Cluster_http2_protocol_options(const envoy_api_v2_Cluster *msg) { return UPB_FIELD_AT(msg, const struct envoy_api_v2_core_Http2ProtocolOptions*, UPB_SIZE(80, 128)); } +UPB_INLINE const struct google_protobuf_Duration* envoy_api_v2_Cluster_dns_refresh_rate(const envoy_api_v2_Cluster *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Duration*, UPB_SIZE(84, 136)); } +UPB_INLINE int32_t envoy_api_v2_Cluster_dns_lookup_family(const envoy_api_v2_Cluster *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(16, 16)); } +UPB_INLINE const struct envoy_api_v2_core_Address* const* envoy_api_v2_Cluster_dns_resolvers(const envoy_api_v2_Cluster *msg, size_t *len) { return (const struct envoy_api_v2_core_Address* const*)_upb_array_accessor(msg, UPB_SIZE(136, 240), len); } +UPB_INLINE const struct envoy_api_v2_cluster_OutlierDetection* envoy_api_v2_Cluster_outlier_detection(const envoy_api_v2_Cluster *msg) { return UPB_FIELD_AT(msg, const struct envoy_api_v2_cluster_OutlierDetection*, UPB_SIZE(88, 144)); } +UPB_INLINE const struct google_protobuf_Duration* envoy_api_v2_Cluster_cleanup_interval(const envoy_api_v2_Cluster *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Duration*, UPB_SIZE(92, 152)); } +UPB_INLINE const struct envoy_api_v2_core_BindConfig* envoy_api_v2_Cluster_upstream_bind_config(const envoy_api_v2_Cluster *msg) { return UPB_FIELD_AT(msg, const struct envoy_api_v2_core_BindConfig*, UPB_SIZE(96, 160)); } +UPB_INLINE const envoy_api_v2_Cluster_LbSubsetConfig* envoy_api_v2_Cluster_lb_subset_config(const envoy_api_v2_Cluster *msg) { return UPB_FIELD_AT(msg, const envoy_api_v2_Cluster_LbSubsetConfig*, UPB_SIZE(100, 168)); } +UPB_INLINE bool envoy_api_v2_Cluster_has_ring_hash_lb_config(const envoy_api_v2_Cluster *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(152, 272), 23); } +UPB_INLINE const envoy_api_v2_Cluster_RingHashLbConfig* envoy_api_v2_Cluster_ring_hash_lb_config(const envoy_api_v2_Cluster *msg) { return UPB_READ_ONEOF(msg, const envoy_api_v2_Cluster_RingHashLbConfig*, UPB_SIZE(148, 264), UPB_SIZE(152, 272), 23, NULL); } +UPB_INLINE const struct envoy_api_v2_core_TransportSocket* envoy_api_v2_Cluster_transport_socket(const envoy_api_v2_Cluster *msg) { return UPB_FIELD_AT(msg, const struct envoy_api_v2_core_TransportSocket*, UPB_SIZE(104, 176)); } +UPB_INLINE const struct envoy_api_v2_core_Metadata* envoy_api_v2_Cluster_metadata(const envoy_api_v2_Cluster *msg) { return UPB_FIELD_AT(msg, const struct envoy_api_v2_core_Metadata*, UPB_SIZE(108, 184)); } +UPB_INLINE int32_t envoy_api_v2_Cluster_protocol_selection(const envoy_api_v2_Cluster *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(24, 24)); } +UPB_INLINE const envoy_api_v2_Cluster_CommonLbConfig* envoy_api_v2_Cluster_common_lb_config(const envoy_api_v2_Cluster *msg) { return UPB_FIELD_AT(msg, const envoy_api_v2_Cluster_CommonLbConfig*, UPB_SIZE(112, 192)); } +UPB_INLINE upb_strview envoy_api_v2_Cluster_alt_stat_name(const envoy_api_v2_Cluster *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(44, 56)); } +UPB_INLINE const struct envoy_api_v2_core_HttpProtocolOptions* envoy_api_v2_Cluster_common_http_protocol_options(const envoy_api_v2_Cluster *msg) { return UPB_FIELD_AT(msg, const struct envoy_api_v2_core_HttpProtocolOptions*, UPB_SIZE(116, 200)); } +UPB_INLINE const envoy_api_v2_UpstreamConnectionOptions* envoy_api_v2_Cluster_upstream_connection_options(const envoy_api_v2_Cluster *msg) { return UPB_FIELD_AT(msg, const envoy_api_v2_UpstreamConnectionOptions*, UPB_SIZE(120, 208)); } +UPB_INLINE bool envoy_api_v2_Cluster_close_connections_on_host_health_failure(const envoy_api_v2_Cluster *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(32, 32)); } +UPB_INLINE bool envoy_api_v2_Cluster_drain_connections_on_host_removal(const envoy_api_v2_Cluster *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(33, 33)); } +UPB_INLINE const struct envoy_api_v2_ClusterLoadAssignment* envoy_api_v2_Cluster_load_assignment(const envoy_api_v2_Cluster *msg) { return UPB_FIELD_AT(msg, const struct envoy_api_v2_ClusterLoadAssignment*, UPB_SIZE(124, 216)); } +UPB_INLINE bool envoy_api_v2_Cluster_has_original_dst_lb_config(const envoy_api_v2_Cluster *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(152, 272), 34); } +UPB_INLINE const envoy_api_v2_Cluster_OriginalDstLbConfig* envoy_api_v2_Cluster_original_dst_lb_config(const envoy_api_v2_Cluster *msg) { return UPB_READ_ONEOF(msg, const envoy_api_v2_Cluster_OriginalDstLbConfig*, UPB_SIZE(148, 264), UPB_SIZE(152, 272), 34, NULL); } +UPB_INLINE const envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry* const* envoy_api_v2_Cluster_extension_protocol_options(const envoy_api_v2_Cluster *msg, size_t *len) { return (const envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry* const*)_upb_array_accessor(msg, UPB_SIZE(140, 248), len); } +UPB_INLINE const envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry* const* envoy_api_v2_Cluster_typed_extension_protocol_options(const envoy_api_v2_Cluster *msg, size_t *len) { return (const envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry* const*)_upb_array_accessor(msg, UPB_SIZE(144, 256), len); } + +UPB_INLINE void envoy_api_v2_Cluster_set_name(envoy_api_v2_Cluster *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(36, 40)) = value; +} +UPB_INLINE void envoy_api_v2_Cluster_set_type(envoy_api_v2_Cluster *msg, int32_t value) { + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_api_v2_Cluster_set_eds_cluster_config(envoy_api_v2_Cluster *msg, envoy_api_v2_Cluster_EdsClusterConfig* value) { + UPB_FIELD_AT(msg, envoy_api_v2_Cluster_EdsClusterConfig*, UPB_SIZE(52, 72)) = value; +} +UPB_INLINE struct envoy_api_v2_Cluster_EdsClusterConfig* envoy_api_v2_Cluster_mutable_eds_cluster_config(envoy_api_v2_Cluster *msg, upb_arena *arena) { + struct envoy_api_v2_Cluster_EdsClusterConfig* sub = (struct envoy_api_v2_Cluster_EdsClusterConfig*)envoy_api_v2_Cluster_eds_cluster_config(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_Cluster_EdsClusterConfig*)upb_msg_new(&envoy_api_v2_Cluster_EdsClusterConfig_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_set_eds_cluster_config(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_Cluster_set_connect_timeout(envoy_api_v2_Cluster *msg, struct google_protobuf_Duration* value) { + UPB_FIELD_AT(msg, struct google_protobuf_Duration*, UPB_SIZE(56, 80)) = value; +} +UPB_INLINE struct google_protobuf_Duration* envoy_api_v2_Cluster_mutable_connect_timeout(envoy_api_v2_Cluster *msg, upb_arena *arena) { + struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_api_v2_Cluster_connect_timeout(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Duration*)upb_msg_new(&google_protobuf_Duration_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_set_connect_timeout(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_Cluster_set_per_connection_buffer_limit_bytes(envoy_api_v2_Cluster *msg, struct google_protobuf_UInt32Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt32Value*, UPB_SIZE(60, 88)) = value; +} +UPB_INLINE struct google_protobuf_UInt32Value* envoy_api_v2_Cluster_mutable_per_connection_buffer_limit_bytes(envoy_api_v2_Cluster *msg, upb_arena *arena) { + struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_api_v2_Cluster_per_connection_buffer_limit_bytes(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt32Value*)upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_set_per_connection_buffer_limit_bytes(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_Cluster_set_lb_policy(envoy_api_v2_Cluster *msg, int32_t value) { + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE struct envoy_api_v2_core_Address** envoy_api_v2_Cluster_mutable_hosts(envoy_api_v2_Cluster *msg, size_t *len) { + return (struct envoy_api_v2_core_Address**)_upb_array_mutable_accessor(msg, UPB_SIZE(128, 224), len); +} +UPB_INLINE struct envoy_api_v2_core_Address** envoy_api_v2_Cluster_resize_hosts(envoy_api_v2_Cluster *msg, size_t len, upb_arena *arena) { + return (struct envoy_api_v2_core_Address**)_upb_array_resize_accessor(msg, UPB_SIZE(128, 224), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct envoy_api_v2_core_Address* envoy_api_v2_Cluster_add_hosts(envoy_api_v2_Cluster *msg, upb_arena *arena) { + struct envoy_api_v2_core_Address* sub = (struct envoy_api_v2_core_Address*)upb_msg_new(&envoy_api_v2_core_Address_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(128, 224), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE struct envoy_api_v2_core_HealthCheck** envoy_api_v2_Cluster_mutable_health_checks(envoy_api_v2_Cluster *msg, size_t *len) { + return (struct envoy_api_v2_core_HealthCheck**)_upb_array_mutable_accessor(msg, UPB_SIZE(132, 232), len); +} +UPB_INLINE struct envoy_api_v2_core_HealthCheck** envoy_api_v2_Cluster_resize_health_checks(envoy_api_v2_Cluster *msg, size_t len, upb_arena *arena) { + return (struct envoy_api_v2_core_HealthCheck**)_upb_array_resize_accessor(msg, UPB_SIZE(132, 232), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct envoy_api_v2_core_HealthCheck* envoy_api_v2_Cluster_add_health_checks(envoy_api_v2_Cluster *msg, upb_arena *arena) { + struct envoy_api_v2_core_HealthCheck* sub = (struct envoy_api_v2_core_HealthCheck*)upb_msg_new(&envoy_api_v2_core_HealthCheck_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(132, 232), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE void envoy_api_v2_Cluster_set_max_requests_per_connection(envoy_api_v2_Cluster *msg, struct google_protobuf_UInt32Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt32Value*, UPB_SIZE(64, 96)) = value; +} +UPB_INLINE struct google_protobuf_UInt32Value* envoy_api_v2_Cluster_mutable_max_requests_per_connection(envoy_api_v2_Cluster *msg, upb_arena *arena) { + struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_api_v2_Cluster_max_requests_per_connection(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt32Value*)upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_set_max_requests_per_connection(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_Cluster_set_circuit_breakers(envoy_api_v2_Cluster *msg, struct envoy_api_v2_cluster_CircuitBreakers* value) { + UPB_FIELD_AT(msg, struct envoy_api_v2_cluster_CircuitBreakers*, UPB_SIZE(68, 104)) = value; +} +UPB_INLINE struct envoy_api_v2_cluster_CircuitBreakers* envoy_api_v2_Cluster_mutable_circuit_breakers(envoy_api_v2_Cluster *msg, upb_arena *arena) { + struct envoy_api_v2_cluster_CircuitBreakers* sub = (struct envoy_api_v2_cluster_CircuitBreakers*)envoy_api_v2_Cluster_circuit_breakers(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_cluster_CircuitBreakers*)upb_msg_new(&envoy_api_v2_cluster_CircuitBreakers_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_set_circuit_breakers(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_Cluster_set_tls_context(envoy_api_v2_Cluster *msg, struct envoy_api_v2_auth_UpstreamTlsContext* value) { + UPB_FIELD_AT(msg, struct envoy_api_v2_auth_UpstreamTlsContext*, UPB_SIZE(72, 112)) = value; +} +UPB_INLINE struct envoy_api_v2_auth_UpstreamTlsContext* envoy_api_v2_Cluster_mutable_tls_context(envoy_api_v2_Cluster *msg, upb_arena *arena) { + struct envoy_api_v2_auth_UpstreamTlsContext* sub = (struct envoy_api_v2_auth_UpstreamTlsContext*)envoy_api_v2_Cluster_tls_context(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_auth_UpstreamTlsContext*)upb_msg_new(&envoy_api_v2_auth_UpstreamTlsContext_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_set_tls_context(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_Cluster_set_http_protocol_options(envoy_api_v2_Cluster *msg, struct envoy_api_v2_core_Http1ProtocolOptions* value) { + UPB_FIELD_AT(msg, struct envoy_api_v2_core_Http1ProtocolOptions*, UPB_SIZE(76, 120)) = value; +} +UPB_INLINE struct envoy_api_v2_core_Http1ProtocolOptions* envoy_api_v2_Cluster_mutable_http_protocol_options(envoy_api_v2_Cluster *msg, upb_arena *arena) { + struct envoy_api_v2_core_Http1ProtocolOptions* sub = (struct envoy_api_v2_core_Http1ProtocolOptions*)envoy_api_v2_Cluster_http_protocol_options(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_Http1ProtocolOptions*)upb_msg_new(&envoy_api_v2_core_Http1ProtocolOptions_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_set_http_protocol_options(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_Cluster_set_http2_protocol_options(envoy_api_v2_Cluster *msg, struct envoy_api_v2_core_Http2ProtocolOptions* value) { + UPB_FIELD_AT(msg, struct envoy_api_v2_core_Http2ProtocolOptions*, UPB_SIZE(80, 128)) = value; +} +UPB_INLINE struct envoy_api_v2_core_Http2ProtocolOptions* envoy_api_v2_Cluster_mutable_http2_protocol_options(envoy_api_v2_Cluster *msg, upb_arena *arena) { + struct envoy_api_v2_core_Http2ProtocolOptions* sub = (struct envoy_api_v2_core_Http2ProtocolOptions*)envoy_api_v2_Cluster_http2_protocol_options(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_Http2ProtocolOptions*)upb_msg_new(&envoy_api_v2_core_Http2ProtocolOptions_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_set_http2_protocol_options(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_Cluster_set_dns_refresh_rate(envoy_api_v2_Cluster *msg, struct google_protobuf_Duration* value) { + UPB_FIELD_AT(msg, struct google_protobuf_Duration*, UPB_SIZE(84, 136)) = value; +} +UPB_INLINE struct google_protobuf_Duration* envoy_api_v2_Cluster_mutable_dns_refresh_rate(envoy_api_v2_Cluster *msg, upb_arena *arena) { + struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_api_v2_Cluster_dns_refresh_rate(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Duration*)upb_msg_new(&google_protobuf_Duration_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_set_dns_refresh_rate(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_Cluster_set_dns_lookup_family(envoy_api_v2_Cluster *msg, int32_t value) { + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(16, 16)) = value; +} +UPB_INLINE struct envoy_api_v2_core_Address** envoy_api_v2_Cluster_mutable_dns_resolvers(envoy_api_v2_Cluster *msg, size_t *len) { + return (struct envoy_api_v2_core_Address**)_upb_array_mutable_accessor(msg, UPB_SIZE(136, 240), len); +} +UPB_INLINE struct envoy_api_v2_core_Address** envoy_api_v2_Cluster_resize_dns_resolvers(envoy_api_v2_Cluster *msg, size_t len, upb_arena *arena) { + return (struct envoy_api_v2_core_Address**)_upb_array_resize_accessor(msg, UPB_SIZE(136, 240), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct envoy_api_v2_core_Address* envoy_api_v2_Cluster_add_dns_resolvers(envoy_api_v2_Cluster *msg, upb_arena *arena) { + struct envoy_api_v2_core_Address* sub = (struct envoy_api_v2_core_Address*)upb_msg_new(&envoy_api_v2_core_Address_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(136, 240), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE void envoy_api_v2_Cluster_set_outlier_detection(envoy_api_v2_Cluster *msg, struct envoy_api_v2_cluster_OutlierDetection* value) { + UPB_FIELD_AT(msg, struct envoy_api_v2_cluster_OutlierDetection*, UPB_SIZE(88, 144)) = value; +} +UPB_INLINE struct envoy_api_v2_cluster_OutlierDetection* envoy_api_v2_Cluster_mutable_outlier_detection(envoy_api_v2_Cluster *msg, upb_arena *arena) { + struct envoy_api_v2_cluster_OutlierDetection* sub = (struct envoy_api_v2_cluster_OutlierDetection*)envoy_api_v2_Cluster_outlier_detection(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_cluster_OutlierDetection*)upb_msg_new(&envoy_api_v2_cluster_OutlierDetection_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_set_outlier_detection(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_Cluster_set_cleanup_interval(envoy_api_v2_Cluster *msg, struct google_protobuf_Duration* value) { + UPB_FIELD_AT(msg, struct google_protobuf_Duration*, UPB_SIZE(92, 152)) = value; +} +UPB_INLINE struct google_protobuf_Duration* envoy_api_v2_Cluster_mutable_cleanup_interval(envoy_api_v2_Cluster *msg, upb_arena *arena) { + struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_api_v2_Cluster_cleanup_interval(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Duration*)upb_msg_new(&google_protobuf_Duration_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_set_cleanup_interval(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_Cluster_set_upstream_bind_config(envoy_api_v2_Cluster *msg, struct envoy_api_v2_core_BindConfig* value) { + UPB_FIELD_AT(msg, struct envoy_api_v2_core_BindConfig*, UPB_SIZE(96, 160)) = value; +} +UPB_INLINE struct envoy_api_v2_core_BindConfig* envoy_api_v2_Cluster_mutable_upstream_bind_config(envoy_api_v2_Cluster *msg, upb_arena *arena) { + struct envoy_api_v2_core_BindConfig* sub = (struct envoy_api_v2_core_BindConfig*)envoy_api_v2_Cluster_upstream_bind_config(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_BindConfig*)upb_msg_new(&envoy_api_v2_core_BindConfig_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_set_upstream_bind_config(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_Cluster_set_lb_subset_config(envoy_api_v2_Cluster *msg, envoy_api_v2_Cluster_LbSubsetConfig* value) { + UPB_FIELD_AT(msg, envoy_api_v2_Cluster_LbSubsetConfig*, UPB_SIZE(100, 168)) = value; +} +UPB_INLINE struct envoy_api_v2_Cluster_LbSubsetConfig* envoy_api_v2_Cluster_mutable_lb_subset_config(envoy_api_v2_Cluster *msg, upb_arena *arena) { + struct envoy_api_v2_Cluster_LbSubsetConfig* sub = (struct envoy_api_v2_Cluster_LbSubsetConfig*)envoy_api_v2_Cluster_lb_subset_config(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_Cluster_LbSubsetConfig*)upb_msg_new(&envoy_api_v2_Cluster_LbSubsetConfig_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_set_lb_subset_config(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_Cluster_set_ring_hash_lb_config(envoy_api_v2_Cluster *msg, envoy_api_v2_Cluster_RingHashLbConfig* value) { + UPB_WRITE_ONEOF(msg, envoy_api_v2_Cluster_RingHashLbConfig*, UPB_SIZE(148, 264), value, UPB_SIZE(152, 272), 23); +} +UPB_INLINE struct envoy_api_v2_Cluster_RingHashLbConfig* envoy_api_v2_Cluster_mutable_ring_hash_lb_config(envoy_api_v2_Cluster *msg, upb_arena *arena) { + struct envoy_api_v2_Cluster_RingHashLbConfig* sub = (struct envoy_api_v2_Cluster_RingHashLbConfig*)envoy_api_v2_Cluster_ring_hash_lb_config(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_Cluster_RingHashLbConfig*)upb_msg_new(&envoy_api_v2_Cluster_RingHashLbConfig_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_set_ring_hash_lb_config(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_Cluster_set_transport_socket(envoy_api_v2_Cluster *msg, struct envoy_api_v2_core_TransportSocket* value) { + UPB_FIELD_AT(msg, struct envoy_api_v2_core_TransportSocket*, UPB_SIZE(104, 176)) = value; +} +UPB_INLINE struct envoy_api_v2_core_TransportSocket* envoy_api_v2_Cluster_mutable_transport_socket(envoy_api_v2_Cluster *msg, upb_arena *arena) { + struct envoy_api_v2_core_TransportSocket* sub = (struct envoy_api_v2_core_TransportSocket*)envoy_api_v2_Cluster_transport_socket(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_TransportSocket*)upb_msg_new(&envoy_api_v2_core_TransportSocket_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_set_transport_socket(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_Cluster_set_metadata(envoy_api_v2_Cluster *msg, struct envoy_api_v2_core_Metadata* value) { + UPB_FIELD_AT(msg, struct envoy_api_v2_core_Metadata*, UPB_SIZE(108, 184)) = value; +} +UPB_INLINE struct envoy_api_v2_core_Metadata* envoy_api_v2_Cluster_mutable_metadata(envoy_api_v2_Cluster *msg, upb_arena *arena) { + struct envoy_api_v2_core_Metadata* sub = (struct envoy_api_v2_core_Metadata*)envoy_api_v2_Cluster_metadata(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_Metadata*)upb_msg_new(&envoy_api_v2_core_Metadata_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_set_metadata(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_Cluster_set_protocol_selection(envoy_api_v2_Cluster *msg, int32_t value) { + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(24, 24)) = value; +} +UPB_INLINE void envoy_api_v2_Cluster_set_common_lb_config(envoy_api_v2_Cluster *msg, envoy_api_v2_Cluster_CommonLbConfig* value) { + UPB_FIELD_AT(msg, envoy_api_v2_Cluster_CommonLbConfig*, UPB_SIZE(112, 192)) = value; +} +UPB_INLINE struct envoy_api_v2_Cluster_CommonLbConfig* envoy_api_v2_Cluster_mutable_common_lb_config(envoy_api_v2_Cluster *msg, upb_arena *arena) { + struct envoy_api_v2_Cluster_CommonLbConfig* sub = (struct envoy_api_v2_Cluster_CommonLbConfig*)envoy_api_v2_Cluster_common_lb_config(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_Cluster_CommonLbConfig*)upb_msg_new(&envoy_api_v2_Cluster_CommonLbConfig_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_set_common_lb_config(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_Cluster_set_alt_stat_name(envoy_api_v2_Cluster *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(44, 56)) = value; +} +UPB_INLINE void envoy_api_v2_Cluster_set_common_http_protocol_options(envoy_api_v2_Cluster *msg, struct envoy_api_v2_core_HttpProtocolOptions* value) { + UPB_FIELD_AT(msg, struct envoy_api_v2_core_HttpProtocolOptions*, UPB_SIZE(116, 200)) = value; +} +UPB_INLINE struct envoy_api_v2_core_HttpProtocolOptions* envoy_api_v2_Cluster_mutable_common_http_protocol_options(envoy_api_v2_Cluster *msg, upb_arena *arena) { + struct envoy_api_v2_core_HttpProtocolOptions* sub = (struct envoy_api_v2_core_HttpProtocolOptions*)envoy_api_v2_Cluster_common_http_protocol_options(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_HttpProtocolOptions*)upb_msg_new(&envoy_api_v2_core_HttpProtocolOptions_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_set_common_http_protocol_options(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_Cluster_set_upstream_connection_options(envoy_api_v2_Cluster *msg, envoy_api_v2_UpstreamConnectionOptions* value) { + UPB_FIELD_AT(msg, envoy_api_v2_UpstreamConnectionOptions*, UPB_SIZE(120, 208)) = value; +} +UPB_INLINE struct envoy_api_v2_UpstreamConnectionOptions* envoy_api_v2_Cluster_mutable_upstream_connection_options(envoy_api_v2_Cluster *msg, upb_arena *arena) { + struct envoy_api_v2_UpstreamConnectionOptions* sub = (struct envoy_api_v2_UpstreamConnectionOptions*)envoy_api_v2_Cluster_upstream_connection_options(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_UpstreamConnectionOptions*)upb_msg_new(&envoy_api_v2_UpstreamConnectionOptions_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_set_upstream_connection_options(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_Cluster_set_close_connections_on_host_health_failure(envoy_api_v2_Cluster *msg, bool value) { + UPB_FIELD_AT(msg, bool, UPB_SIZE(32, 32)) = value; +} +UPB_INLINE void envoy_api_v2_Cluster_set_drain_connections_on_host_removal(envoy_api_v2_Cluster *msg, bool value) { + UPB_FIELD_AT(msg, bool, UPB_SIZE(33, 33)) = value; +} +UPB_INLINE void envoy_api_v2_Cluster_set_load_assignment(envoy_api_v2_Cluster *msg, struct envoy_api_v2_ClusterLoadAssignment* value) { + UPB_FIELD_AT(msg, struct envoy_api_v2_ClusterLoadAssignment*, UPB_SIZE(124, 216)) = value; +} +UPB_INLINE struct envoy_api_v2_ClusterLoadAssignment* envoy_api_v2_Cluster_mutable_load_assignment(envoy_api_v2_Cluster *msg, upb_arena *arena) { + struct envoy_api_v2_ClusterLoadAssignment* sub = (struct envoy_api_v2_ClusterLoadAssignment*)envoy_api_v2_Cluster_load_assignment(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_ClusterLoadAssignment*)upb_msg_new(&envoy_api_v2_ClusterLoadAssignment_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_set_load_assignment(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_Cluster_set_original_dst_lb_config(envoy_api_v2_Cluster *msg, envoy_api_v2_Cluster_OriginalDstLbConfig* value) { + UPB_WRITE_ONEOF(msg, envoy_api_v2_Cluster_OriginalDstLbConfig*, UPB_SIZE(148, 264), value, UPB_SIZE(152, 272), 34); +} +UPB_INLINE struct envoy_api_v2_Cluster_OriginalDstLbConfig* envoy_api_v2_Cluster_mutable_original_dst_lb_config(envoy_api_v2_Cluster *msg, upb_arena *arena) { + struct envoy_api_v2_Cluster_OriginalDstLbConfig* sub = (struct envoy_api_v2_Cluster_OriginalDstLbConfig*)envoy_api_v2_Cluster_original_dst_lb_config(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_Cluster_OriginalDstLbConfig*)upb_msg_new(&envoy_api_v2_Cluster_OriginalDstLbConfig_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_set_original_dst_lb_config(msg, sub); + } + return sub; +} +UPB_INLINE envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry** envoy_api_v2_Cluster_mutable_extension_protocol_options(envoy_api_v2_Cluster *msg, size_t *len) { + return (envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry**)_upb_array_mutable_accessor(msg, UPB_SIZE(140, 248), len); +} +UPB_INLINE envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry** envoy_api_v2_Cluster_resize_extension_protocol_options(envoy_api_v2_Cluster *msg, size_t len, upb_arena *arena) { + return (envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry**)_upb_array_resize_accessor(msg, UPB_SIZE(140, 248), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry* envoy_api_v2_Cluster_add_extension_protocol_options(envoy_api_v2_Cluster *msg, upb_arena *arena) { + struct envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry* sub = (struct envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry*)upb_msg_new(&envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(140, 248), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry** envoy_api_v2_Cluster_mutable_typed_extension_protocol_options(envoy_api_v2_Cluster *msg, size_t *len) { + return (envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry**)_upb_array_mutable_accessor(msg, UPB_SIZE(144, 256), len); +} +UPB_INLINE envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry** envoy_api_v2_Cluster_resize_typed_extension_protocol_options(envoy_api_v2_Cluster *msg, size_t len, upb_arena *arena) { + return (envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry**)_upb_array_resize_accessor(msg, UPB_SIZE(144, 256), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry* envoy_api_v2_Cluster_add_typed_extension_protocol_options(envoy_api_v2_Cluster *msg, upb_arena *arena) { + struct envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry* sub = (struct envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry*)upb_msg_new(&envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(144, 256), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} + + +/* envoy.api.v2.Cluster.EdsClusterConfig */ + +UPB_INLINE envoy_api_v2_Cluster_EdsClusterConfig *envoy_api_v2_Cluster_EdsClusterConfig_new(upb_arena *arena) { + return (envoy_api_v2_Cluster_EdsClusterConfig *)upb_msg_new(&envoy_api_v2_Cluster_EdsClusterConfig_msginit, arena); +} +UPB_INLINE envoy_api_v2_Cluster_EdsClusterConfig *envoy_api_v2_Cluster_EdsClusterConfig_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_Cluster_EdsClusterConfig *ret = envoy_api_v2_Cluster_EdsClusterConfig_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_Cluster_EdsClusterConfig_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_Cluster_EdsClusterConfig_serialize(const envoy_api_v2_Cluster_EdsClusterConfig *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_Cluster_EdsClusterConfig_msginit, arena, len); +} + +UPB_INLINE const struct envoy_api_v2_core_ConfigSource* envoy_api_v2_Cluster_EdsClusterConfig_eds_config(const envoy_api_v2_Cluster_EdsClusterConfig *msg) { return UPB_FIELD_AT(msg, const struct envoy_api_v2_core_ConfigSource*, UPB_SIZE(8, 16)); } +UPB_INLINE upb_strview envoy_api_v2_Cluster_EdsClusterConfig_service_name(const envoy_api_v2_Cluster_EdsClusterConfig *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } + +UPB_INLINE void envoy_api_v2_Cluster_EdsClusterConfig_set_eds_config(envoy_api_v2_Cluster_EdsClusterConfig *msg, struct envoy_api_v2_core_ConfigSource* value) { + UPB_FIELD_AT(msg, struct envoy_api_v2_core_ConfigSource*, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE struct envoy_api_v2_core_ConfigSource* envoy_api_v2_Cluster_EdsClusterConfig_mutable_eds_config(envoy_api_v2_Cluster_EdsClusterConfig *msg, upb_arena *arena) { + struct envoy_api_v2_core_ConfigSource* sub = (struct envoy_api_v2_core_ConfigSource*)envoy_api_v2_Cluster_EdsClusterConfig_eds_config(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_ConfigSource*)upb_msg_new(&envoy_api_v2_core_ConfigSource_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_EdsClusterConfig_set_eds_config(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_Cluster_EdsClusterConfig_set_service_name(envoy_api_v2_Cluster_EdsClusterConfig *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} + + +/* envoy.api.v2.Cluster.ExtensionProtocolOptionsEntry */ + +UPB_INLINE envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry *envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry_new(upb_arena *arena) { + return (envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry *)upb_msg_new(&envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry_msginit, arena); +} +UPB_INLINE envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry *envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry *ret = envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry_serialize(const envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry_msginit, arena, len); +} + +UPB_INLINE upb_strview envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry_key(const envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } +UPB_INLINE const struct google_protobuf_Struct* envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry_value(const envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Struct*, UPB_SIZE(8, 16)); } + +UPB_INLINE void envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry_set_key(envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry_set_value(envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry *msg, struct google_protobuf_Struct* value) { + UPB_FIELD_AT(msg, struct google_protobuf_Struct*, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE struct google_protobuf_Struct* envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry_mutable_value(envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry *msg, upb_arena *arena) { + struct google_protobuf_Struct* sub = (struct google_protobuf_Struct*)envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry_value(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Struct*)upb_msg_new(&google_protobuf_Struct_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry_set_value(msg, sub); + } + return sub; +} + + +/* envoy.api.v2.Cluster.TypedExtensionProtocolOptionsEntry */ + +UPB_INLINE envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry *envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry_new(upb_arena *arena) { + return (envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry *)upb_msg_new(&envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry_msginit, arena); +} +UPB_INLINE envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry *envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry *ret = envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry_serialize(const envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry_msginit, arena, len); +} + +UPB_INLINE upb_strview envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry_key(const envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } +UPB_INLINE const struct google_protobuf_Any* envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry_value(const envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Any*, UPB_SIZE(8, 16)); } + +UPB_INLINE void envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry_set_key(envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry_set_value(envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry *msg, struct google_protobuf_Any* value) { + UPB_FIELD_AT(msg, struct google_protobuf_Any*, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE struct google_protobuf_Any* envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry_mutable_value(envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry *msg, upb_arena *arena) { + struct google_protobuf_Any* sub = (struct google_protobuf_Any*)envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry_value(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Any*)upb_msg_new(&google_protobuf_Any_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry_set_value(msg, sub); + } + return sub; +} + + +/* envoy.api.v2.Cluster.LbSubsetConfig */ + +UPB_INLINE envoy_api_v2_Cluster_LbSubsetConfig *envoy_api_v2_Cluster_LbSubsetConfig_new(upb_arena *arena) { + return (envoy_api_v2_Cluster_LbSubsetConfig *)upb_msg_new(&envoy_api_v2_Cluster_LbSubsetConfig_msginit, arena); +} +UPB_INLINE envoy_api_v2_Cluster_LbSubsetConfig *envoy_api_v2_Cluster_LbSubsetConfig_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_Cluster_LbSubsetConfig *ret = envoy_api_v2_Cluster_LbSubsetConfig_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_Cluster_LbSubsetConfig_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_Cluster_LbSubsetConfig_serialize(const envoy_api_v2_Cluster_LbSubsetConfig *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_Cluster_LbSubsetConfig_msginit, arena, len); +} + +UPB_INLINE int32_t envoy_api_v2_Cluster_LbSubsetConfig_fallback_policy(const envoy_api_v2_Cluster_LbSubsetConfig *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(0, 0)); } +UPB_INLINE const struct google_protobuf_Struct* envoy_api_v2_Cluster_LbSubsetConfig_default_subset(const envoy_api_v2_Cluster_LbSubsetConfig *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Struct*, UPB_SIZE(12, 16)); } +UPB_INLINE const envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector* const* envoy_api_v2_Cluster_LbSubsetConfig_subset_selectors(const envoy_api_v2_Cluster_LbSubsetConfig *msg, size_t *len) { return (const envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector* const*)_upb_array_accessor(msg, UPB_SIZE(16, 24), len); } +UPB_INLINE bool envoy_api_v2_Cluster_LbSubsetConfig_locality_weight_aware(const envoy_api_v2_Cluster_LbSubsetConfig *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(8, 8)); } + +UPB_INLINE void envoy_api_v2_Cluster_LbSubsetConfig_set_fallback_policy(envoy_api_v2_Cluster_LbSubsetConfig *msg, int32_t value) { + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_api_v2_Cluster_LbSubsetConfig_set_default_subset(envoy_api_v2_Cluster_LbSubsetConfig *msg, struct google_protobuf_Struct* value) { + UPB_FIELD_AT(msg, struct google_protobuf_Struct*, UPB_SIZE(12, 16)) = value; +} +UPB_INLINE struct google_protobuf_Struct* envoy_api_v2_Cluster_LbSubsetConfig_mutable_default_subset(envoy_api_v2_Cluster_LbSubsetConfig *msg, upb_arena *arena) { + struct google_protobuf_Struct* sub = (struct google_protobuf_Struct*)envoy_api_v2_Cluster_LbSubsetConfig_default_subset(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Struct*)upb_msg_new(&google_protobuf_Struct_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_LbSubsetConfig_set_default_subset(msg, sub); + } + return sub; +} +UPB_INLINE envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector** envoy_api_v2_Cluster_LbSubsetConfig_mutable_subset_selectors(envoy_api_v2_Cluster_LbSubsetConfig *msg, size_t *len) { + return (envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector**)_upb_array_mutable_accessor(msg, UPB_SIZE(16, 24), len); +} +UPB_INLINE envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector** envoy_api_v2_Cluster_LbSubsetConfig_resize_subset_selectors(envoy_api_v2_Cluster_LbSubsetConfig *msg, size_t len, upb_arena *arena) { + return (envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector**)_upb_array_resize_accessor(msg, UPB_SIZE(16, 24), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector* envoy_api_v2_Cluster_LbSubsetConfig_add_subset_selectors(envoy_api_v2_Cluster_LbSubsetConfig *msg, upb_arena *arena) { + struct envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector* sub = (struct envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector*)upb_msg_new(&envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(16, 24), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE void envoy_api_v2_Cluster_LbSubsetConfig_set_locality_weight_aware(envoy_api_v2_Cluster_LbSubsetConfig *msg, bool value) { + UPB_FIELD_AT(msg, bool, UPB_SIZE(8, 8)) = value; +} + + +/* envoy.api.v2.Cluster.LbSubsetConfig.LbSubsetSelector */ + +UPB_INLINE envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector *envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector_new(upb_arena *arena) { + return (envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector *)upb_msg_new(&envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector_msginit, arena); +} +UPB_INLINE envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector *envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector *ret = envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector_serialize(const envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector_msginit, arena, len); +} + +UPB_INLINE upb_strview const* envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector_keys(const envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(0, 0), len); } + +UPB_INLINE upb_strview* envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector_mutable_keys(envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector *msg, size_t *len) { + return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len); +} +UPB_INLINE upb_strview* envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector_resize_keys(envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector *msg, size_t len, upb_arena *arena) { + return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_SIZE(8, 16), UPB_TYPE_STRING, arena); +} +UPB_INLINE bool envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector_add_keys(envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector *msg, upb_strview val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(0, 0), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, arena); +} + + +/* envoy.api.v2.Cluster.RingHashLbConfig */ + +UPB_INLINE envoy_api_v2_Cluster_RingHashLbConfig *envoy_api_v2_Cluster_RingHashLbConfig_new(upb_arena *arena) { + return (envoy_api_v2_Cluster_RingHashLbConfig *)upb_msg_new(&envoy_api_v2_Cluster_RingHashLbConfig_msginit, arena); +} +UPB_INLINE envoy_api_v2_Cluster_RingHashLbConfig *envoy_api_v2_Cluster_RingHashLbConfig_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_Cluster_RingHashLbConfig *ret = envoy_api_v2_Cluster_RingHashLbConfig_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_Cluster_RingHashLbConfig_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_Cluster_RingHashLbConfig_serialize(const envoy_api_v2_Cluster_RingHashLbConfig *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_Cluster_RingHashLbConfig_msginit, arena, len); +} + +UPB_INLINE const struct google_protobuf_UInt64Value* envoy_api_v2_Cluster_RingHashLbConfig_minimum_ring_size(const envoy_api_v2_Cluster_RingHashLbConfig *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt64Value*, UPB_SIZE(0, 0)); } +UPB_INLINE const envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1* envoy_api_v2_Cluster_RingHashLbConfig_deprecated_v1(const envoy_api_v2_Cluster_RingHashLbConfig *msg) { return UPB_FIELD_AT(msg, const envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1*, UPB_SIZE(4, 8)); } + +UPB_INLINE void envoy_api_v2_Cluster_RingHashLbConfig_set_minimum_ring_size(envoy_api_v2_Cluster_RingHashLbConfig *msg, struct google_protobuf_UInt64Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt64Value*, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE struct google_protobuf_UInt64Value* envoy_api_v2_Cluster_RingHashLbConfig_mutable_minimum_ring_size(envoy_api_v2_Cluster_RingHashLbConfig *msg, upb_arena *arena) { + struct google_protobuf_UInt64Value* sub = (struct google_protobuf_UInt64Value*)envoy_api_v2_Cluster_RingHashLbConfig_minimum_ring_size(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt64Value*)upb_msg_new(&google_protobuf_UInt64Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_RingHashLbConfig_set_minimum_ring_size(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_Cluster_RingHashLbConfig_set_deprecated_v1(envoy_api_v2_Cluster_RingHashLbConfig *msg, envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1* value) { + UPB_FIELD_AT(msg, envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1*, UPB_SIZE(4, 8)) = value; +} +UPB_INLINE struct envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1* envoy_api_v2_Cluster_RingHashLbConfig_mutable_deprecated_v1(envoy_api_v2_Cluster_RingHashLbConfig *msg, upb_arena *arena) { + struct envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1* sub = (struct envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1*)envoy_api_v2_Cluster_RingHashLbConfig_deprecated_v1(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1*)upb_msg_new(&envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_RingHashLbConfig_set_deprecated_v1(msg, sub); + } + return sub; +} + + +/* envoy.api.v2.Cluster.RingHashLbConfig.DeprecatedV1 */ + +UPB_INLINE envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1 *envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1_new(upb_arena *arena) { + return (envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1 *)upb_msg_new(&envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1_msginit, arena); +} +UPB_INLINE envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1 *envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1 *ret = envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1_serialize(const envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1 *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1_msginit, arena, len); +} + +UPB_INLINE const struct google_protobuf_BoolValue* envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1_use_std_hash(const envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1 *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_BoolValue*, UPB_SIZE(0, 0)); } + +UPB_INLINE void envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1_set_use_std_hash(envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1 *msg, struct google_protobuf_BoolValue* value) { + UPB_FIELD_AT(msg, struct google_protobuf_BoolValue*, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE struct google_protobuf_BoolValue* envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1_mutable_use_std_hash(envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1 *msg, upb_arena *arena) { + struct google_protobuf_BoolValue* sub = (struct google_protobuf_BoolValue*)envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1_use_std_hash(msg); + if (sub == NULL) { + sub = (struct google_protobuf_BoolValue*)upb_msg_new(&google_protobuf_BoolValue_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1_set_use_std_hash(msg, sub); + } + return sub; +} + + +/* envoy.api.v2.Cluster.OriginalDstLbConfig */ + +UPB_INLINE envoy_api_v2_Cluster_OriginalDstLbConfig *envoy_api_v2_Cluster_OriginalDstLbConfig_new(upb_arena *arena) { + return (envoy_api_v2_Cluster_OriginalDstLbConfig *)upb_msg_new(&envoy_api_v2_Cluster_OriginalDstLbConfig_msginit, arena); +} +UPB_INLINE envoy_api_v2_Cluster_OriginalDstLbConfig *envoy_api_v2_Cluster_OriginalDstLbConfig_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_Cluster_OriginalDstLbConfig *ret = envoy_api_v2_Cluster_OriginalDstLbConfig_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_Cluster_OriginalDstLbConfig_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_Cluster_OriginalDstLbConfig_serialize(const envoy_api_v2_Cluster_OriginalDstLbConfig *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_Cluster_OriginalDstLbConfig_msginit, arena, len); +} + +UPB_INLINE bool envoy_api_v2_Cluster_OriginalDstLbConfig_use_http_header(const envoy_api_v2_Cluster_OriginalDstLbConfig *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(0, 0)); } + +UPB_INLINE void envoy_api_v2_Cluster_OriginalDstLbConfig_set_use_http_header(envoy_api_v2_Cluster_OriginalDstLbConfig *msg, bool value) { + UPB_FIELD_AT(msg, bool, UPB_SIZE(0, 0)) = value; +} + + +/* envoy.api.v2.Cluster.CommonLbConfig */ + +UPB_INLINE envoy_api_v2_Cluster_CommonLbConfig *envoy_api_v2_Cluster_CommonLbConfig_new(upb_arena *arena) { + return (envoy_api_v2_Cluster_CommonLbConfig *)upb_msg_new(&envoy_api_v2_Cluster_CommonLbConfig_msginit, arena); +} +UPB_INLINE envoy_api_v2_Cluster_CommonLbConfig *envoy_api_v2_Cluster_CommonLbConfig_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_Cluster_CommonLbConfig *ret = envoy_api_v2_Cluster_CommonLbConfig_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_Cluster_CommonLbConfig_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_Cluster_CommonLbConfig_serialize(const envoy_api_v2_Cluster_CommonLbConfig *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_Cluster_CommonLbConfig_msginit, arena, len); +} + +typedef enum { + envoy_api_v2_Cluster_CommonLbConfig_locality_config_specifier_zone_aware_lb_config = 2, + envoy_api_v2_Cluster_CommonLbConfig_locality_config_specifier_locality_weighted_lb_config = 3, + envoy_api_v2_Cluster_CommonLbConfig_locality_config_specifier_NOT_SET = 0, +} envoy_api_v2_Cluster_CommonLbConfig_locality_config_specifier_oneofcases; +UPB_INLINE envoy_api_v2_Cluster_CommonLbConfig_locality_config_specifier_oneofcases envoy_api_v2_Cluster_CommonLbConfig_locality_config_specifier_case(const envoy_api_v2_Cluster_CommonLbConfig* msg) { return UPB_FIELD_AT(msg, int, UPB_SIZE(12, 24)); } + +UPB_INLINE const struct envoy_type_Percent* envoy_api_v2_Cluster_CommonLbConfig_healthy_panic_threshold(const envoy_api_v2_Cluster_CommonLbConfig *msg) { return UPB_FIELD_AT(msg, const struct envoy_type_Percent*, UPB_SIZE(0, 0)); } +UPB_INLINE bool envoy_api_v2_Cluster_CommonLbConfig_has_zone_aware_lb_config(const envoy_api_v2_Cluster_CommonLbConfig *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(12, 24), 2); } +UPB_INLINE const envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig* envoy_api_v2_Cluster_CommonLbConfig_zone_aware_lb_config(const envoy_api_v2_Cluster_CommonLbConfig *msg) { return UPB_READ_ONEOF(msg, const envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig*, UPB_SIZE(8, 16), UPB_SIZE(12, 24), 2, NULL); } +UPB_INLINE bool envoy_api_v2_Cluster_CommonLbConfig_has_locality_weighted_lb_config(const envoy_api_v2_Cluster_CommonLbConfig *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(12, 24), 3); } +UPB_INLINE const envoy_api_v2_Cluster_CommonLbConfig_LocalityWeightedLbConfig* envoy_api_v2_Cluster_CommonLbConfig_locality_weighted_lb_config(const envoy_api_v2_Cluster_CommonLbConfig *msg) { return UPB_READ_ONEOF(msg, const envoy_api_v2_Cluster_CommonLbConfig_LocalityWeightedLbConfig*, UPB_SIZE(8, 16), UPB_SIZE(12, 24), 3, NULL); } +UPB_INLINE const struct google_protobuf_Duration* envoy_api_v2_Cluster_CommonLbConfig_update_merge_window(const envoy_api_v2_Cluster_CommonLbConfig *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Duration*, UPB_SIZE(4, 8)); } + +UPB_INLINE void envoy_api_v2_Cluster_CommonLbConfig_set_healthy_panic_threshold(envoy_api_v2_Cluster_CommonLbConfig *msg, struct envoy_type_Percent* value) { + UPB_FIELD_AT(msg, struct envoy_type_Percent*, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE struct envoy_type_Percent* envoy_api_v2_Cluster_CommonLbConfig_mutable_healthy_panic_threshold(envoy_api_v2_Cluster_CommonLbConfig *msg, upb_arena *arena) { + struct envoy_type_Percent* sub = (struct envoy_type_Percent*)envoy_api_v2_Cluster_CommonLbConfig_healthy_panic_threshold(msg); + if (sub == NULL) { + sub = (struct envoy_type_Percent*)upb_msg_new(&envoy_type_Percent_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_CommonLbConfig_set_healthy_panic_threshold(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_Cluster_CommonLbConfig_set_zone_aware_lb_config(envoy_api_v2_Cluster_CommonLbConfig *msg, envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig* value) { + UPB_WRITE_ONEOF(msg, envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig*, UPB_SIZE(8, 16), value, UPB_SIZE(12, 24), 2); +} +UPB_INLINE struct envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig* envoy_api_v2_Cluster_CommonLbConfig_mutable_zone_aware_lb_config(envoy_api_v2_Cluster_CommonLbConfig *msg, upb_arena *arena) { + struct envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig* sub = (struct envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig*)envoy_api_v2_Cluster_CommonLbConfig_zone_aware_lb_config(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig*)upb_msg_new(&envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_CommonLbConfig_set_zone_aware_lb_config(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_Cluster_CommonLbConfig_set_locality_weighted_lb_config(envoy_api_v2_Cluster_CommonLbConfig *msg, envoy_api_v2_Cluster_CommonLbConfig_LocalityWeightedLbConfig* value) { + UPB_WRITE_ONEOF(msg, envoy_api_v2_Cluster_CommonLbConfig_LocalityWeightedLbConfig*, UPB_SIZE(8, 16), value, UPB_SIZE(12, 24), 3); +} +UPB_INLINE struct envoy_api_v2_Cluster_CommonLbConfig_LocalityWeightedLbConfig* envoy_api_v2_Cluster_CommonLbConfig_mutable_locality_weighted_lb_config(envoy_api_v2_Cluster_CommonLbConfig *msg, upb_arena *arena) { + struct envoy_api_v2_Cluster_CommonLbConfig_LocalityWeightedLbConfig* sub = (struct envoy_api_v2_Cluster_CommonLbConfig_LocalityWeightedLbConfig*)envoy_api_v2_Cluster_CommonLbConfig_locality_weighted_lb_config(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_Cluster_CommonLbConfig_LocalityWeightedLbConfig*)upb_msg_new(&envoy_api_v2_Cluster_CommonLbConfig_LocalityWeightedLbConfig_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_CommonLbConfig_set_locality_weighted_lb_config(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_Cluster_CommonLbConfig_set_update_merge_window(envoy_api_v2_Cluster_CommonLbConfig *msg, struct google_protobuf_Duration* value) { + UPB_FIELD_AT(msg, struct google_protobuf_Duration*, UPB_SIZE(4, 8)) = value; +} +UPB_INLINE struct google_protobuf_Duration* envoy_api_v2_Cluster_CommonLbConfig_mutable_update_merge_window(envoy_api_v2_Cluster_CommonLbConfig *msg, upb_arena *arena) { + struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_api_v2_Cluster_CommonLbConfig_update_merge_window(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Duration*)upb_msg_new(&google_protobuf_Duration_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_CommonLbConfig_set_update_merge_window(msg, sub); + } + return sub; +} + + +/* envoy.api.v2.Cluster.CommonLbConfig.ZoneAwareLbConfig */ + +UPB_INLINE envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig *envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig_new(upb_arena *arena) { + return (envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig *)upb_msg_new(&envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig_msginit, arena); +} +UPB_INLINE envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig *envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig *ret = envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig_serialize(const envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig_msginit, arena, len); +} + +UPB_INLINE const struct envoy_type_Percent* envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig_routing_enabled(const envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig *msg) { return UPB_FIELD_AT(msg, const struct envoy_type_Percent*, UPB_SIZE(0, 0)); } +UPB_INLINE const struct google_protobuf_UInt64Value* envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig_min_cluster_size(const envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt64Value*, UPB_SIZE(4, 8)); } + +UPB_INLINE void envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig_set_routing_enabled(envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig *msg, struct envoy_type_Percent* value) { + UPB_FIELD_AT(msg, struct envoy_type_Percent*, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE struct envoy_type_Percent* envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig_mutable_routing_enabled(envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig *msg, upb_arena *arena) { + struct envoy_type_Percent* sub = (struct envoy_type_Percent*)envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig_routing_enabled(msg); + if (sub == NULL) { + sub = (struct envoy_type_Percent*)upb_msg_new(&envoy_type_Percent_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig_set_routing_enabled(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig_set_min_cluster_size(envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig *msg, struct google_protobuf_UInt64Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt64Value*, UPB_SIZE(4, 8)) = value; +} +UPB_INLINE struct google_protobuf_UInt64Value* envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig_mutable_min_cluster_size(envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig *msg, upb_arena *arena) { + struct google_protobuf_UInt64Value* sub = (struct google_protobuf_UInt64Value*)envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig_min_cluster_size(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt64Value*)upb_msg_new(&google_protobuf_UInt64Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig_set_min_cluster_size(msg, sub); + } + return sub; +} + + +/* envoy.api.v2.Cluster.CommonLbConfig.LocalityWeightedLbConfig */ + +UPB_INLINE envoy_api_v2_Cluster_CommonLbConfig_LocalityWeightedLbConfig *envoy_api_v2_Cluster_CommonLbConfig_LocalityWeightedLbConfig_new(upb_arena *arena) { + return (envoy_api_v2_Cluster_CommonLbConfig_LocalityWeightedLbConfig *)upb_msg_new(&envoy_api_v2_Cluster_CommonLbConfig_LocalityWeightedLbConfig_msginit, arena); +} +UPB_INLINE envoy_api_v2_Cluster_CommonLbConfig_LocalityWeightedLbConfig *envoy_api_v2_Cluster_CommonLbConfig_LocalityWeightedLbConfig_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_Cluster_CommonLbConfig_LocalityWeightedLbConfig *ret = envoy_api_v2_Cluster_CommonLbConfig_LocalityWeightedLbConfig_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_Cluster_CommonLbConfig_LocalityWeightedLbConfig_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_Cluster_CommonLbConfig_LocalityWeightedLbConfig_serialize(const envoy_api_v2_Cluster_CommonLbConfig_LocalityWeightedLbConfig *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_Cluster_CommonLbConfig_LocalityWeightedLbConfig_msginit, arena, len); +} + + + + +/* envoy.api.v2.UpstreamBindConfig */ + +UPB_INLINE envoy_api_v2_UpstreamBindConfig *envoy_api_v2_UpstreamBindConfig_new(upb_arena *arena) { + return (envoy_api_v2_UpstreamBindConfig *)upb_msg_new(&envoy_api_v2_UpstreamBindConfig_msginit, arena); +} +UPB_INLINE envoy_api_v2_UpstreamBindConfig *envoy_api_v2_UpstreamBindConfig_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_UpstreamBindConfig *ret = envoy_api_v2_UpstreamBindConfig_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_UpstreamBindConfig_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_UpstreamBindConfig_serialize(const envoy_api_v2_UpstreamBindConfig *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_UpstreamBindConfig_msginit, arena, len); +} + +UPB_INLINE const struct envoy_api_v2_core_Address* envoy_api_v2_UpstreamBindConfig_source_address(const envoy_api_v2_UpstreamBindConfig *msg) { return UPB_FIELD_AT(msg, const struct envoy_api_v2_core_Address*, UPB_SIZE(0, 0)); } + +UPB_INLINE void envoy_api_v2_UpstreamBindConfig_set_source_address(envoy_api_v2_UpstreamBindConfig *msg, struct envoy_api_v2_core_Address* value) { + UPB_FIELD_AT(msg, struct envoy_api_v2_core_Address*, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE struct envoy_api_v2_core_Address* envoy_api_v2_UpstreamBindConfig_mutable_source_address(envoy_api_v2_UpstreamBindConfig *msg, upb_arena *arena) { + struct envoy_api_v2_core_Address* sub = (struct envoy_api_v2_core_Address*)envoy_api_v2_UpstreamBindConfig_source_address(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_Address*)upb_msg_new(&envoy_api_v2_core_Address_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_UpstreamBindConfig_set_source_address(msg, sub); + } + return sub; +} + + +/* envoy.api.v2.UpstreamConnectionOptions */ + +UPB_INLINE envoy_api_v2_UpstreamConnectionOptions *envoy_api_v2_UpstreamConnectionOptions_new(upb_arena *arena) { + return (envoy_api_v2_UpstreamConnectionOptions *)upb_msg_new(&envoy_api_v2_UpstreamConnectionOptions_msginit, arena); +} +UPB_INLINE envoy_api_v2_UpstreamConnectionOptions *envoy_api_v2_UpstreamConnectionOptions_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_UpstreamConnectionOptions *ret = envoy_api_v2_UpstreamConnectionOptions_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_UpstreamConnectionOptions_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_UpstreamConnectionOptions_serialize(const envoy_api_v2_UpstreamConnectionOptions *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_UpstreamConnectionOptions_msginit, arena, len); +} + +UPB_INLINE const struct envoy_api_v2_core_TcpKeepalive* envoy_api_v2_UpstreamConnectionOptions_tcp_keepalive(const envoy_api_v2_UpstreamConnectionOptions *msg) { return UPB_FIELD_AT(msg, const struct envoy_api_v2_core_TcpKeepalive*, UPB_SIZE(0, 0)); } + +UPB_INLINE void envoy_api_v2_UpstreamConnectionOptions_set_tcp_keepalive(envoy_api_v2_UpstreamConnectionOptions *msg, struct envoy_api_v2_core_TcpKeepalive* value) { + UPB_FIELD_AT(msg, struct envoy_api_v2_core_TcpKeepalive*, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE struct envoy_api_v2_core_TcpKeepalive* envoy_api_v2_UpstreamConnectionOptions_mutable_tcp_keepalive(envoy_api_v2_UpstreamConnectionOptions *msg, upb_arena *arena) { + struct envoy_api_v2_core_TcpKeepalive* sub = (struct envoy_api_v2_core_TcpKeepalive*)envoy_api_v2_UpstreamConnectionOptions_tcp_keepalive(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_TcpKeepalive*)upb_msg_new(&envoy_api_v2_core_TcpKeepalive_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_UpstreamConnectionOptions_set_tcp_keepalive(msg, sub); + } + return sub; +} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* ENVOY_API_V2_CDS_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/envoy/api/v2/cluster/circuit_breaker.upb.c b/src/core/ext/upb-generated/envoy/api/v2/cluster/circuit_breaker.upb.c new file mode 100644 index 00000000000..d16f2ce2afb --- /dev/null +++ b/src/core/ext/upb-generated/envoy/api/v2/cluster/circuit_breaker.upb.c @@ -0,0 +1,51 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/api/v2/cluster/circuit_breaker.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include +#include "upb/msg.h" +#include "envoy/api/v2/cluster/circuit_breaker.upb.h" +#include "envoy/api/v2/core/base.upb.h" +#include "google/protobuf/wrappers.upb.h" +#include "gogoproto/gogo.upb.h" + +#include "upb/port_def.inc" + +static const upb_msglayout *const envoy_api_v2_cluster_CircuitBreakers_submsgs[1] = { + &envoy_api_v2_cluster_CircuitBreakers_Thresholds_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_cluster_CircuitBreakers__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 11, 3}, +}; + +const upb_msglayout envoy_api_v2_cluster_CircuitBreakers_msginit = { + &envoy_api_v2_cluster_CircuitBreakers_submsgs[0], + &envoy_api_v2_cluster_CircuitBreakers__fields[0], + UPB_SIZE(4, 8), 1, false, +}; + +static const upb_msglayout *const envoy_api_v2_cluster_CircuitBreakers_Thresholds_submsgs[4] = { + &google_protobuf_UInt32Value_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_cluster_CircuitBreakers_Thresholds__fields[5] = { + {1, UPB_SIZE(0, 0), 0, 0, 14, 1}, + {2, UPB_SIZE(8, 8), 0, 0, 11, 1}, + {3, UPB_SIZE(12, 16), 0, 0, 11, 1}, + {4, UPB_SIZE(16, 24), 0, 0, 11, 1}, + {5, UPB_SIZE(20, 32), 0, 0, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_cluster_CircuitBreakers_Thresholds_msginit = { + &envoy_api_v2_cluster_CircuitBreakers_Thresholds_submsgs[0], + &envoy_api_v2_cluster_CircuitBreakers_Thresholds__fields[0], + UPB_SIZE(24, 40), 5, false, +}; + +#include "upb/port_undef.inc" + diff --git a/src/core/ext/upb-generated/envoy/api/v2/cluster/circuit_breaker.upb.h b/src/core/ext/upb-generated/envoy/api/v2/cluster/circuit_breaker.upb.h new file mode 100644 index 00000000000..45fd07230b0 --- /dev/null +++ b/src/core/ext/upb-generated/envoy/api/v2/cluster/circuit_breaker.upb.h @@ -0,0 +1,143 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/api/v2/cluster/circuit_breaker.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef ENVOY_API_V2_CLUSTER_CIRCUIT_BREAKER_PROTO_UPB_H_ +#define ENVOY_API_V2_CLUSTER_CIRCUIT_BREAKER_PROTO_UPB_H_ + +#include "upb/generated_util.h" + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +#ifdef __cplusplus +extern "C" { +#endif + +struct envoy_api_v2_cluster_CircuitBreakers; +struct envoy_api_v2_cluster_CircuitBreakers_Thresholds; +typedef struct envoy_api_v2_cluster_CircuitBreakers envoy_api_v2_cluster_CircuitBreakers; +typedef struct envoy_api_v2_cluster_CircuitBreakers_Thresholds envoy_api_v2_cluster_CircuitBreakers_Thresholds; +extern const upb_msglayout envoy_api_v2_cluster_CircuitBreakers_msginit; +extern const upb_msglayout envoy_api_v2_cluster_CircuitBreakers_Thresholds_msginit; +struct google_protobuf_UInt32Value; +extern const upb_msglayout google_protobuf_UInt32Value_msginit; + +/* Enums */ + + +/* envoy.api.v2.cluster.CircuitBreakers */ + +UPB_INLINE envoy_api_v2_cluster_CircuitBreakers *envoy_api_v2_cluster_CircuitBreakers_new(upb_arena *arena) { + return (envoy_api_v2_cluster_CircuitBreakers *)upb_msg_new(&envoy_api_v2_cluster_CircuitBreakers_msginit, arena); +} +UPB_INLINE envoy_api_v2_cluster_CircuitBreakers *envoy_api_v2_cluster_CircuitBreakers_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_cluster_CircuitBreakers *ret = envoy_api_v2_cluster_CircuitBreakers_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_cluster_CircuitBreakers_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_cluster_CircuitBreakers_serialize(const envoy_api_v2_cluster_CircuitBreakers *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_cluster_CircuitBreakers_msginit, arena, len); +} + +UPB_INLINE const envoy_api_v2_cluster_CircuitBreakers_Thresholds* const* envoy_api_v2_cluster_CircuitBreakers_thresholds(const envoy_api_v2_cluster_CircuitBreakers *msg, size_t *len) { return (const envoy_api_v2_cluster_CircuitBreakers_Thresholds* const*)_upb_array_accessor(msg, UPB_SIZE(0, 0), len); } + +UPB_INLINE envoy_api_v2_cluster_CircuitBreakers_Thresholds** envoy_api_v2_cluster_CircuitBreakers_mutable_thresholds(envoy_api_v2_cluster_CircuitBreakers *msg, size_t *len) { + return (envoy_api_v2_cluster_CircuitBreakers_Thresholds**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len); +} +UPB_INLINE envoy_api_v2_cluster_CircuitBreakers_Thresholds** envoy_api_v2_cluster_CircuitBreakers_resize_thresholds(envoy_api_v2_cluster_CircuitBreakers *msg, size_t len, upb_arena *arena) { + return (envoy_api_v2_cluster_CircuitBreakers_Thresholds**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct envoy_api_v2_cluster_CircuitBreakers_Thresholds* envoy_api_v2_cluster_CircuitBreakers_add_thresholds(envoy_api_v2_cluster_CircuitBreakers *msg, upb_arena *arena) { + struct envoy_api_v2_cluster_CircuitBreakers_Thresholds* sub = (struct envoy_api_v2_cluster_CircuitBreakers_Thresholds*)upb_msg_new(&envoy_api_v2_cluster_CircuitBreakers_Thresholds_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} + + +/* envoy.api.v2.cluster.CircuitBreakers.Thresholds */ + +UPB_INLINE envoy_api_v2_cluster_CircuitBreakers_Thresholds *envoy_api_v2_cluster_CircuitBreakers_Thresholds_new(upb_arena *arena) { + return (envoy_api_v2_cluster_CircuitBreakers_Thresholds *)upb_msg_new(&envoy_api_v2_cluster_CircuitBreakers_Thresholds_msginit, arena); +} +UPB_INLINE envoy_api_v2_cluster_CircuitBreakers_Thresholds *envoy_api_v2_cluster_CircuitBreakers_Thresholds_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_cluster_CircuitBreakers_Thresholds *ret = envoy_api_v2_cluster_CircuitBreakers_Thresholds_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_cluster_CircuitBreakers_Thresholds_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_cluster_CircuitBreakers_Thresholds_serialize(const envoy_api_v2_cluster_CircuitBreakers_Thresholds *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_cluster_CircuitBreakers_Thresholds_msginit, arena, len); +} + +UPB_INLINE int32_t envoy_api_v2_cluster_CircuitBreakers_Thresholds_priority(const envoy_api_v2_cluster_CircuitBreakers_Thresholds *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(0, 0)); } +UPB_INLINE const struct google_protobuf_UInt32Value* envoy_api_v2_cluster_CircuitBreakers_Thresholds_max_connections(const envoy_api_v2_cluster_CircuitBreakers_Thresholds *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt32Value*, UPB_SIZE(8, 8)); } +UPB_INLINE const struct google_protobuf_UInt32Value* envoy_api_v2_cluster_CircuitBreakers_Thresholds_max_pending_requests(const envoy_api_v2_cluster_CircuitBreakers_Thresholds *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt32Value*, UPB_SIZE(12, 16)); } +UPB_INLINE const struct google_protobuf_UInt32Value* envoy_api_v2_cluster_CircuitBreakers_Thresholds_max_requests(const envoy_api_v2_cluster_CircuitBreakers_Thresholds *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt32Value*, UPB_SIZE(16, 24)); } +UPB_INLINE const struct google_protobuf_UInt32Value* envoy_api_v2_cluster_CircuitBreakers_Thresholds_max_retries(const envoy_api_v2_cluster_CircuitBreakers_Thresholds *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt32Value*, UPB_SIZE(20, 32)); } + +UPB_INLINE void envoy_api_v2_cluster_CircuitBreakers_Thresholds_set_priority(envoy_api_v2_cluster_CircuitBreakers_Thresholds *msg, int32_t value) { + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_api_v2_cluster_CircuitBreakers_Thresholds_set_max_connections(envoy_api_v2_cluster_CircuitBreakers_Thresholds *msg, struct google_protobuf_UInt32Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt32Value*, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE struct google_protobuf_UInt32Value* envoy_api_v2_cluster_CircuitBreakers_Thresholds_mutable_max_connections(envoy_api_v2_cluster_CircuitBreakers_Thresholds *msg, upb_arena *arena) { + struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_api_v2_cluster_CircuitBreakers_Thresholds_max_connections(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt32Value*)upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_cluster_CircuitBreakers_Thresholds_set_max_connections(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_cluster_CircuitBreakers_Thresholds_set_max_pending_requests(envoy_api_v2_cluster_CircuitBreakers_Thresholds *msg, struct google_protobuf_UInt32Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt32Value*, UPB_SIZE(12, 16)) = value; +} +UPB_INLINE struct google_protobuf_UInt32Value* envoy_api_v2_cluster_CircuitBreakers_Thresholds_mutable_max_pending_requests(envoy_api_v2_cluster_CircuitBreakers_Thresholds *msg, upb_arena *arena) { + struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_api_v2_cluster_CircuitBreakers_Thresholds_max_pending_requests(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt32Value*)upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_cluster_CircuitBreakers_Thresholds_set_max_pending_requests(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_cluster_CircuitBreakers_Thresholds_set_max_requests(envoy_api_v2_cluster_CircuitBreakers_Thresholds *msg, struct google_protobuf_UInt32Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt32Value*, UPB_SIZE(16, 24)) = value; +} +UPB_INLINE struct google_protobuf_UInt32Value* envoy_api_v2_cluster_CircuitBreakers_Thresholds_mutable_max_requests(envoy_api_v2_cluster_CircuitBreakers_Thresholds *msg, upb_arena *arena) { + struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_api_v2_cluster_CircuitBreakers_Thresholds_max_requests(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt32Value*)upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_cluster_CircuitBreakers_Thresholds_set_max_requests(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_cluster_CircuitBreakers_Thresholds_set_max_retries(envoy_api_v2_cluster_CircuitBreakers_Thresholds *msg, struct google_protobuf_UInt32Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt32Value*, UPB_SIZE(20, 32)) = value; +} +UPB_INLINE struct google_protobuf_UInt32Value* envoy_api_v2_cluster_CircuitBreakers_Thresholds_mutable_max_retries(envoy_api_v2_cluster_CircuitBreakers_Thresholds *msg, upb_arena *arena) { + struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_api_v2_cluster_CircuitBreakers_Thresholds_max_retries(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt32Value*)upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_cluster_CircuitBreakers_Thresholds_set_max_retries(msg, sub); + } + return sub; +} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* ENVOY_API_V2_CLUSTER_CIRCUIT_BREAKER_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/envoy/api/v2/cluster/outlier_detection.upb.c b/src/core/ext/upb-generated/envoy/api/v2/cluster/outlier_detection.upb.c new file mode 100644 index 00000000000..7158a8b8809 --- /dev/null +++ b/src/core/ext/upb-generated/envoy/api/v2/cluster/outlier_detection.upb.c @@ -0,0 +1,45 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/api/v2/cluster/outlier_detection.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include +#include "upb/msg.h" +#include "envoy/api/v2/cluster/outlier_detection.upb.h" +#include "google/protobuf/duration.upb.h" +#include "google/protobuf/wrappers.upb.h" +#include "validate/validate.upb.h" +#include "gogoproto/gogo.upb.h" + +#include "upb/port_def.inc" + +static const upb_msglayout *const envoy_api_v2_cluster_OutlierDetection_submsgs[11] = { + &google_protobuf_Duration_msginit, + &google_protobuf_UInt32Value_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_cluster_OutlierDetection__fields[11] = { + {1, UPB_SIZE(0, 0), 0, 1, 11, 1}, + {2, UPB_SIZE(4, 8), 0, 0, 11, 1}, + {3, UPB_SIZE(8, 16), 0, 0, 11, 1}, + {4, UPB_SIZE(12, 24), 0, 1, 11, 1}, + {5, UPB_SIZE(16, 32), 0, 1, 11, 1}, + {6, UPB_SIZE(20, 40), 0, 1, 11, 1}, + {7, UPB_SIZE(24, 48), 0, 1, 11, 1}, + {8, UPB_SIZE(28, 56), 0, 1, 11, 1}, + {9, UPB_SIZE(32, 64), 0, 1, 11, 1}, + {10, UPB_SIZE(36, 72), 0, 1, 11, 1}, + {11, UPB_SIZE(40, 80), 0, 1, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_cluster_OutlierDetection_msginit = { + &envoy_api_v2_cluster_OutlierDetection_submsgs[0], + &envoy_api_v2_cluster_OutlierDetection__fields[0], + UPB_SIZE(44, 88), 11, false, +}; + +#include "upb/port_undef.inc" + diff --git a/src/core/ext/upb-generated/envoy/api/v2/cluster/outlier_detection.upb.h b/src/core/ext/upb-generated/envoy/api/v2/cluster/outlier_detection.upb.h new file mode 100644 index 00000000000..06fa49f6fd7 --- /dev/null +++ b/src/core/ext/upb-generated/envoy/api/v2/cluster/outlier_detection.upb.h @@ -0,0 +1,199 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/api/v2/cluster/outlier_detection.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef ENVOY_API_V2_CLUSTER_OUTLIER_DETECTION_PROTO_UPB_H_ +#define ENVOY_API_V2_CLUSTER_OUTLIER_DETECTION_PROTO_UPB_H_ + +#include "upb/generated_util.h" + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +#ifdef __cplusplus +extern "C" { +#endif + +struct envoy_api_v2_cluster_OutlierDetection; +typedef struct envoy_api_v2_cluster_OutlierDetection envoy_api_v2_cluster_OutlierDetection; +extern const upb_msglayout envoy_api_v2_cluster_OutlierDetection_msginit; +struct google_protobuf_Duration; +struct google_protobuf_UInt32Value; +extern const upb_msglayout google_protobuf_Duration_msginit; +extern const upb_msglayout google_protobuf_UInt32Value_msginit; + +/* Enums */ + + +/* envoy.api.v2.cluster.OutlierDetection */ + +UPB_INLINE envoy_api_v2_cluster_OutlierDetection *envoy_api_v2_cluster_OutlierDetection_new(upb_arena *arena) { + return (envoy_api_v2_cluster_OutlierDetection *)upb_msg_new(&envoy_api_v2_cluster_OutlierDetection_msginit, arena); +} +UPB_INLINE envoy_api_v2_cluster_OutlierDetection *envoy_api_v2_cluster_OutlierDetection_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_cluster_OutlierDetection *ret = envoy_api_v2_cluster_OutlierDetection_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_cluster_OutlierDetection_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_cluster_OutlierDetection_serialize(const envoy_api_v2_cluster_OutlierDetection *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_cluster_OutlierDetection_msginit, arena, len); +} + +UPB_INLINE const struct google_protobuf_UInt32Value* envoy_api_v2_cluster_OutlierDetection_consecutive_5xx(const envoy_api_v2_cluster_OutlierDetection *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt32Value*, UPB_SIZE(0, 0)); } +UPB_INLINE const struct google_protobuf_Duration* envoy_api_v2_cluster_OutlierDetection_interval(const envoy_api_v2_cluster_OutlierDetection *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Duration*, UPB_SIZE(4, 8)); } +UPB_INLINE const struct google_protobuf_Duration* envoy_api_v2_cluster_OutlierDetection_base_ejection_time(const envoy_api_v2_cluster_OutlierDetection *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Duration*, UPB_SIZE(8, 16)); } +UPB_INLINE const struct google_protobuf_UInt32Value* envoy_api_v2_cluster_OutlierDetection_max_ejection_percent(const envoy_api_v2_cluster_OutlierDetection *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt32Value*, UPB_SIZE(12, 24)); } +UPB_INLINE const struct google_protobuf_UInt32Value* envoy_api_v2_cluster_OutlierDetection_enforcing_consecutive_5xx(const envoy_api_v2_cluster_OutlierDetection *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt32Value*, UPB_SIZE(16, 32)); } +UPB_INLINE const struct google_protobuf_UInt32Value* envoy_api_v2_cluster_OutlierDetection_enforcing_success_rate(const envoy_api_v2_cluster_OutlierDetection *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt32Value*, UPB_SIZE(20, 40)); } +UPB_INLINE const struct google_protobuf_UInt32Value* envoy_api_v2_cluster_OutlierDetection_success_rate_minimum_hosts(const envoy_api_v2_cluster_OutlierDetection *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt32Value*, UPB_SIZE(24, 48)); } +UPB_INLINE const struct google_protobuf_UInt32Value* envoy_api_v2_cluster_OutlierDetection_success_rate_request_volume(const envoy_api_v2_cluster_OutlierDetection *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt32Value*, UPB_SIZE(28, 56)); } +UPB_INLINE const struct google_protobuf_UInt32Value* envoy_api_v2_cluster_OutlierDetection_success_rate_stdev_factor(const envoy_api_v2_cluster_OutlierDetection *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt32Value*, UPB_SIZE(32, 64)); } +UPB_INLINE const struct google_protobuf_UInt32Value* envoy_api_v2_cluster_OutlierDetection_consecutive_gateway_failure(const envoy_api_v2_cluster_OutlierDetection *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt32Value*, UPB_SIZE(36, 72)); } +UPB_INLINE const struct google_protobuf_UInt32Value* envoy_api_v2_cluster_OutlierDetection_enforcing_consecutive_gateway_failure(const envoy_api_v2_cluster_OutlierDetection *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt32Value*, UPB_SIZE(40, 80)); } + +UPB_INLINE void envoy_api_v2_cluster_OutlierDetection_set_consecutive_5xx(envoy_api_v2_cluster_OutlierDetection *msg, struct google_protobuf_UInt32Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt32Value*, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE struct google_protobuf_UInt32Value* envoy_api_v2_cluster_OutlierDetection_mutable_consecutive_5xx(envoy_api_v2_cluster_OutlierDetection *msg, upb_arena *arena) { + struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_api_v2_cluster_OutlierDetection_consecutive_5xx(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt32Value*)upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_cluster_OutlierDetection_set_consecutive_5xx(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_cluster_OutlierDetection_set_interval(envoy_api_v2_cluster_OutlierDetection *msg, struct google_protobuf_Duration* value) { + UPB_FIELD_AT(msg, struct google_protobuf_Duration*, UPB_SIZE(4, 8)) = value; +} +UPB_INLINE struct google_protobuf_Duration* envoy_api_v2_cluster_OutlierDetection_mutable_interval(envoy_api_v2_cluster_OutlierDetection *msg, upb_arena *arena) { + struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_api_v2_cluster_OutlierDetection_interval(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Duration*)upb_msg_new(&google_protobuf_Duration_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_cluster_OutlierDetection_set_interval(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_cluster_OutlierDetection_set_base_ejection_time(envoy_api_v2_cluster_OutlierDetection *msg, struct google_protobuf_Duration* value) { + UPB_FIELD_AT(msg, struct google_protobuf_Duration*, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE struct google_protobuf_Duration* envoy_api_v2_cluster_OutlierDetection_mutable_base_ejection_time(envoy_api_v2_cluster_OutlierDetection *msg, upb_arena *arena) { + struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_api_v2_cluster_OutlierDetection_base_ejection_time(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Duration*)upb_msg_new(&google_protobuf_Duration_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_cluster_OutlierDetection_set_base_ejection_time(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_cluster_OutlierDetection_set_max_ejection_percent(envoy_api_v2_cluster_OutlierDetection *msg, struct google_protobuf_UInt32Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt32Value*, UPB_SIZE(12, 24)) = value; +} +UPB_INLINE struct google_protobuf_UInt32Value* envoy_api_v2_cluster_OutlierDetection_mutable_max_ejection_percent(envoy_api_v2_cluster_OutlierDetection *msg, upb_arena *arena) { + struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_api_v2_cluster_OutlierDetection_max_ejection_percent(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt32Value*)upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_cluster_OutlierDetection_set_max_ejection_percent(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_cluster_OutlierDetection_set_enforcing_consecutive_5xx(envoy_api_v2_cluster_OutlierDetection *msg, struct google_protobuf_UInt32Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt32Value*, UPB_SIZE(16, 32)) = value; +} +UPB_INLINE struct google_protobuf_UInt32Value* envoy_api_v2_cluster_OutlierDetection_mutable_enforcing_consecutive_5xx(envoy_api_v2_cluster_OutlierDetection *msg, upb_arena *arena) { + struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_api_v2_cluster_OutlierDetection_enforcing_consecutive_5xx(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt32Value*)upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_cluster_OutlierDetection_set_enforcing_consecutive_5xx(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_cluster_OutlierDetection_set_enforcing_success_rate(envoy_api_v2_cluster_OutlierDetection *msg, struct google_protobuf_UInt32Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt32Value*, UPB_SIZE(20, 40)) = value; +} +UPB_INLINE struct google_protobuf_UInt32Value* envoy_api_v2_cluster_OutlierDetection_mutable_enforcing_success_rate(envoy_api_v2_cluster_OutlierDetection *msg, upb_arena *arena) { + struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_api_v2_cluster_OutlierDetection_enforcing_success_rate(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt32Value*)upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_cluster_OutlierDetection_set_enforcing_success_rate(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_cluster_OutlierDetection_set_success_rate_minimum_hosts(envoy_api_v2_cluster_OutlierDetection *msg, struct google_protobuf_UInt32Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt32Value*, UPB_SIZE(24, 48)) = value; +} +UPB_INLINE struct google_protobuf_UInt32Value* envoy_api_v2_cluster_OutlierDetection_mutable_success_rate_minimum_hosts(envoy_api_v2_cluster_OutlierDetection *msg, upb_arena *arena) { + struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_api_v2_cluster_OutlierDetection_success_rate_minimum_hosts(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt32Value*)upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_cluster_OutlierDetection_set_success_rate_minimum_hosts(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_cluster_OutlierDetection_set_success_rate_request_volume(envoy_api_v2_cluster_OutlierDetection *msg, struct google_protobuf_UInt32Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt32Value*, UPB_SIZE(28, 56)) = value; +} +UPB_INLINE struct google_protobuf_UInt32Value* envoy_api_v2_cluster_OutlierDetection_mutable_success_rate_request_volume(envoy_api_v2_cluster_OutlierDetection *msg, upb_arena *arena) { + struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_api_v2_cluster_OutlierDetection_success_rate_request_volume(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt32Value*)upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_cluster_OutlierDetection_set_success_rate_request_volume(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_cluster_OutlierDetection_set_success_rate_stdev_factor(envoy_api_v2_cluster_OutlierDetection *msg, struct google_protobuf_UInt32Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt32Value*, UPB_SIZE(32, 64)) = value; +} +UPB_INLINE struct google_protobuf_UInt32Value* envoy_api_v2_cluster_OutlierDetection_mutable_success_rate_stdev_factor(envoy_api_v2_cluster_OutlierDetection *msg, upb_arena *arena) { + struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_api_v2_cluster_OutlierDetection_success_rate_stdev_factor(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt32Value*)upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_cluster_OutlierDetection_set_success_rate_stdev_factor(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_cluster_OutlierDetection_set_consecutive_gateway_failure(envoy_api_v2_cluster_OutlierDetection *msg, struct google_protobuf_UInt32Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt32Value*, UPB_SIZE(36, 72)) = value; +} +UPB_INLINE struct google_protobuf_UInt32Value* envoy_api_v2_cluster_OutlierDetection_mutable_consecutive_gateway_failure(envoy_api_v2_cluster_OutlierDetection *msg, upb_arena *arena) { + struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_api_v2_cluster_OutlierDetection_consecutive_gateway_failure(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt32Value*)upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_cluster_OutlierDetection_set_consecutive_gateway_failure(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_cluster_OutlierDetection_set_enforcing_consecutive_gateway_failure(envoy_api_v2_cluster_OutlierDetection *msg, struct google_protobuf_UInt32Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt32Value*, UPB_SIZE(40, 80)) = value; +} +UPB_INLINE struct google_protobuf_UInt32Value* envoy_api_v2_cluster_OutlierDetection_mutable_enforcing_consecutive_gateway_failure(envoy_api_v2_cluster_OutlierDetection *msg, upb_arena *arena) { + struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_api_v2_cluster_OutlierDetection_enforcing_consecutive_gateway_failure(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt32Value*)upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_cluster_OutlierDetection_set_enforcing_consecutive_gateway_failure(msg, sub); + } + return sub; +} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* ENVOY_API_V2_CLUSTER_OUTLIER_DETECTION_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/envoy/api/v2/core/address.upb.c b/src/core/ext/upb-generated/envoy/api/v2/core/address.upb.c new file mode 100644 index 00000000000..5a37e5785c3 --- /dev/null +++ b/src/core/ext/upb-generated/envoy/api/v2/core/address.upb.c @@ -0,0 +1,110 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/api/v2/core/address.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include +#include "upb/msg.h" +#include "envoy/api/v2/core/address.upb.h" +#include "envoy/api/v2/core/base.upb.h" +#include "google/protobuf/wrappers.upb.h" +#include "validate/validate.upb.h" +#include "gogoproto/gogo.upb.h" + +#include "upb/port_def.inc" + +static const upb_msglayout_field envoy_api_v2_core_Pipe__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, +}; + +const upb_msglayout envoy_api_v2_core_Pipe_msginit = { + NULL, + &envoy_api_v2_core_Pipe__fields[0], + UPB_SIZE(8, 16), 1, false, +}; + +static const upb_msglayout_field envoy_api_v2_core_SocketAddress__fields[6] = { + {1, UPB_SIZE(0, 0), 0, 0, 14, 1}, + {2, UPB_SIZE(12, 16), 0, 0, 9, 1}, + {3, UPB_SIZE(28, 48), UPB_SIZE(-37, -65), 0, 13, 1}, + {4, UPB_SIZE(28, 48), UPB_SIZE(-37, -65), 0, 9, 1}, + {5, UPB_SIZE(20, 32), 0, 0, 9, 1}, + {6, UPB_SIZE(8, 8), 0, 0, 8, 1}, +}; + +const upb_msglayout envoy_api_v2_core_SocketAddress_msginit = { + NULL, + &envoy_api_v2_core_SocketAddress__fields[0], + UPB_SIZE(40, 80), 6, false, +}; + +static const upb_msglayout *const envoy_api_v2_core_TcpKeepalive_submsgs[3] = { + &google_protobuf_UInt32Value_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_core_TcpKeepalive__fields[3] = { + {1, UPB_SIZE(0, 0), 0, 0, 11, 1}, + {2, UPB_SIZE(4, 8), 0, 0, 11, 1}, + {3, UPB_SIZE(8, 16), 0, 0, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_core_TcpKeepalive_msginit = { + &envoy_api_v2_core_TcpKeepalive_submsgs[0], + &envoy_api_v2_core_TcpKeepalive__fields[0], + UPB_SIZE(12, 24), 3, false, +}; + +static const upb_msglayout *const envoy_api_v2_core_BindConfig_submsgs[3] = { + &envoy_api_v2_core_SocketAddress_msginit, + &envoy_api_v2_core_SocketOption_msginit, + &google_protobuf_BoolValue_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_core_BindConfig__fields[3] = { + {1, UPB_SIZE(0, 0), 0, 0, 11, 1}, + {2, UPB_SIZE(4, 8), 0, 2, 11, 1}, + {3, UPB_SIZE(8, 16), 0, 1, 11, 3}, +}; + +const upb_msglayout envoy_api_v2_core_BindConfig_msginit = { + &envoy_api_v2_core_BindConfig_submsgs[0], + &envoy_api_v2_core_BindConfig__fields[0], + UPB_SIZE(12, 24), 3, false, +}; + +static const upb_msglayout *const envoy_api_v2_core_Address_submsgs[2] = { + &envoy_api_v2_core_Pipe_msginit, + &envoy_api_v2_core_SocketAddress_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_core_Address__fields[2] = { + {1, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 1, 11, 1}, + {2, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 0, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_core_Address_msginit = { + &envoy_api_v2_core_Address_submsgs[0], + &envoy_api_v2_core_Address__fields[0], + UPB_SIZE(8, 16), 2, false, +}; + +static const upb_msglayout *const envoy_api_v2_core_CidrRange_submsgs[1] = { + &google_protobuf_UInt32Value_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_core_CidrRange__fields[2] = { + {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, + {2, UPB_SIZE(8, 16), 0, 0, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_core_CidrRange_msginit = { + &envoy_api_v2_core_CidrRange_submsgs[0], + &envoy_api_v2_core_CidrRange__fields[0], + UPB_SIZE(16, 32), 2, false, +}; + +#include "upb/port_undef.inc" + diff --git a/src/core/ext/upb-generated/envoy/api/v2/core/address.upb.h b/src/core/ext/upb-generated/envoy/api/v2/core/address.upb.h new file mode 100644 index 00000000000..8e0f8a28656 --- /dev/null +++ b/src/core/ext/upb-generated/envoy/api/v2/core/address.upb.h @@ -0,0 +1,326 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/api/v2/core/address.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef ENVOY_API_V2_CORE_ADDRESS_PROTO_UPB_H_ +#define ENVOY_API_V2_CORE_ADDRESS_PROTO_UPB_H_ + +#include "upb/generated_util.h" + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +#ifdef __cplusplus +extern "C" { +#endif + +struct envoy_api_v2_core_Pipe; +struct envoy_api_v2_core_SocketAddress; +struct envoy_api_v2_core_TcpKeepalive; +struct envoy_api_v2_core_BindConfig; +struct envoy_api_v2_core_Address; +struct envoy_api_v2_core_CidrRange; +typedef struct envoy_api_v2_core_Pipe envoy_api_v2_core_Pipe; +typedef struct envoy_api_v2_core_SocketAddress envoy_api_v2_core_SocketAddress; +typedef struct envoy_api_v2_core_TcpKeepalive envoy_api_v2_core_TcpKeepalive; +typedef struct envoy_api_v2_core_BindConfig envoy_api_v2_core_BindConfig; +typedef struct envoy_api_v2_core_Address envoy_api_v2_core_Address; +typedef struct envoy_api_v2_core_CidrRange envoy_api_v2_core_CidrRange; +extern const upb_msglayout envoy_api_v2_core_Pipe_msginit; +extern const upb_msglayout envoy_api_v2_core_SocketAddress_msginit; +extern const upb_msglayout envoy_api_v2_core_TcpKeepalive_msginit; +extern const upb_msglayout envoy_api_v2_core_BindConfig_msginit; +extern const upb_msglayout envoy_api_v2_core_Address_msginit; +extern const upb_msglayout envoy_api_v2_core_CidrRange_msginit; +struct envoy_api_v2_core_SocketOption; +struct google_protobuf_BoolValue; +struct google_protobuf_UInt32Value; +extern const upb_msglayout envoy_api_v2_core_SocketOption_msginit; +extern const upb_msglayout google_protobuf_BoolValue_msginit; +extern const upb_msglayout google_protobuf_UInt32Value_msginit; + +/* Enums */ + +typedef enum { + envoy_api_v2_core_SocketAddress_TCP = 0, + envoy_api_v2_core_SocketAddress_UDP = 1 +} envoy_api_v2_core_SocketAddress_Protocol; + + +/* envoy.api.v2.core.Pipe */ + +UPB_INLINE envoy_api_v2_core_Pipe *envoy_api_v2_core_Pipe_new(upb_arena *arena) { + return (envoy_api_v2_core_Pipe *)upb_msg_new(&envoy_api_v2_core_Pipe_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_Pipe *envoy_api_v2_core_Pipe_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_Pipe *ret = envoy_api_v2_core_Pipe_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_Pipe_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_Pipe_serialize(const envoy_api_v2_core_Pipe *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_Pipe_msginit, arena, len); +} + +UPB_INLINE upb_strview envoy_api_v2_core_Pipe_path(const envoy_api_v2_core_Pipe *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } + +UPB_INLINE void envoy_api_v2_core_Pipe_set_path(envoy_api_v2_core_Pipe *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} + + +/* envoy.api.v2.core.SocketAddress */ + +UPB_INLINE envoy_api_v2_core_SocketAddress *envoy_api_v2_core_SocketAddress_new(upb_arena *arena) { + return (envoy_api_v2_core_SocketAddress *)upb_msg_new(&envoy_api_v2_core_SocketAddress_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_SocketAddress *envoy_api_v2_core_SocketAddress_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_SocketAddress *ret = envoy_api_v2_core_SocketAddress_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_SocketAddress_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_SocketAddress_serialize(const envoy_api_v2_core_SocketAddress *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_SocketAddress_msginit, arena, len); +} + +typedef enum { + envoy_api_v2_core_SocketAddress_port_specifier_port_value = 3, + envoy_api_v2_core_SocketAddress_port_specifier_named_port = 4, + envoy_api_v2_core_SocketAddress_port_specifier_NOT_SET = 0, +} envoy_api_v2_core_SocketAddress_port_specifier_oneofcases; +UPB_INLINE envoy_api_v2_core_SocketAddress_port_specifier_oneofcases envoy_api_v2_core_SocketAddress_port_specifier_case(const envoy_api_v2_core_SocketAddress* msg) { return UPB_FIELD_AT(msg, int, UPB_SIZE(36, 64)); } + +UPB_INLINE int32_t envoy_api_v2_core_SocketAddress_protocol(const envoy_api_v2_core_SocketAddress *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(0, 0)); } +UPB_INLINE upb_strview envoy_api_v2_core_SocketAddress_address(const envoy_api_v2_core_SocketAddress *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(12, 16)); } +UPB_INLINE bool envoy_api_v2_core_SocketAddress_has_port_value(const envoy_api_v2_core_SocketAddress *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(36, 64), 3); } +UPB_INLINE uint32_t envoy_api_v2_core_SocketAddress_port_value(const envoy_api_v2_core_SocketAddress *msg) { return UPB_READ_ONEOF(msg, uint32_t, UPB_SIZE(28, 48), UPB_SIZE(36, 64), 3, 0); } +UPB_INLINE bool envoy_api_v2_core_SocketAddress_has_named_port(const envoy_api_v2_core_SocketAddress *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(36, 64), 4); } +UPB_INLINE upb_strview envoy_api_v2_core_SocketAddress_named_port(const envoy_api_v2_core_SocketAddress *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(28, 48), UPB_SIZE(36, 64), 4, upb_strview_make("", strlen(""))); } +UPB_INLINE upb_strview envoy_api_v2_core_SocketAddress_resolver_name(const envoy_api_v2_core_SocketAddress *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(20, 32)); } +UPB_INLINE bool envoy_api_v2_core_SocketAddress_ipv4_compat(const envoy_api_v2_core_SocketAddress *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(8, 8)); } + +UPB_INLINE void envoy_api_v2_core_SocketAddress_set_protocol(envoy_api_v2_core_SocketAddress *msg, int32_t value) { + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_api_v2_core_SocketAddress_set_address(envoy_api_v2_core_SocketAddress *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(12, 16)) = value; +} +UPB_INLINE void envoy_api_v2_core_SocketAddress_set_port_value(envoy_api_v2_core_SocketAddress *msg, uint32_t value) { + UPB_WRITE_ONEOF(msg, uint32_t, UPB_SIZE(28, 48), value, UPB_SIZE(36, 64), 3); +} +UPB_INLINE void envoy_api_v2_core_SocketAddress_set_named_port(envoy_api_v2_core_SocketAddress *msg, upb_strview value) { + UPB_WRITE_ONEOF(msg, upb_strview, UPB_SIZE(28, 48), value, UPB_SIZE(36, 64), 4); +} +UPB_INLINE void envoy_api_v2_core_SocketAddress_set_resolver_name(envoy_api_v2_core_SocketAddress *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(20, 32)) = value; +} +UPB_INLINE void envoy_api_v2_core_SocketAddress_set_ipv4_compat(envoy_api_v2_core_SocketAddress *msg, bool value) { + UPB_FIELD_AT(msg, bool, UPB_SIZE(8, 8)) = value; +} + + +/* envoy.api.v2.core.TcpKeepalive */ + +UPB_INLINE envoy_api_v2_core_TcpKeepalive *envoy_api_v2_core_TcpKeepalive_new(upb_arena *arena) { + return (envoy_api_v2_core_TcpKeepalive *)upb_msg_new(&envoy_api_v2_core_TcpKeepalive_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_TcpKeepalive *envoy_api_v2_core_TcpKeepalive_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_TcpKeepalive *ret = envoy_api_v2_core_TcpKeepalive_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_TcpKeepalive_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_TcpKeepalive_serialize(const envoy_api_v2_core_TcpKeepalive *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_TcpKeepalive_msginit, arena, len); +} + +UPB_INLINE const struct google_protobuf_UInt32Value* envoy_api_v2_core_TcpKeepalive_keepalive_probes(const envoy_api_v2_core_TcpKeepalive *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt32Value*, UPB_SIZE(0, 0)); } +UPB_INLINE const struct google_protobuf_UInt32Value* envoy_api_v2_core_TcpKeepalive_keepalive_time(const envoy_api_v2_core_TcpKeepalive *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt32Value*, UPB_SIZE(4, 8)); } +UPB_INLINE const struct google_protobuf_UInt32Value* envoy_api_v2_core_TcpKeepalive_keepalive_interval(const envoy_api_v2_core_TcpKeepalive *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt32Value*, UPB_SIZE(8, 16)); } + +UPB_INLINE void envoy_api_v2_core_TcpKeepalive_set_keepalive_probes(envoy_api_v2_core_TcpKeepalive *msg, struct google_protobuf_UInt32Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt32Value*, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE struct google_protobuf_UInt32Value* envoy_api_v2_core_TcpKeepalive_mutable_keepalive_probes(envoy_api_v2_core_TcpKeepalive *msg, upb_arena *arena) { + struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_api_v2_core_TcpKeepalive_keepalive_probes(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt32Value*)upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_TcpKeepalive_set_keepalive_probes(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_TcpKeepalive_set_keepalive_time(envoy_api_v2_core_TcpKeepalive *msg, struct google_protobuf_UInt32Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt32Value*, UPB_SIZE(4, 8)) = value; +} +UPB_INLINE struct google_protobuf_UInt32Value* envoy_api_v2_core_TcpKeepalive_mutable_keepalive_time(envoy_api_v2_core_TcpKeepalive *msg, upb_arena *arena) { + struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_api_v2_core_TcpKeepalive_keepalive_time(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt32Value*)upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_TcpKeepalive_set_keepalive_time(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_TcpKeepalive_set_keepalive_interval(envoy_api_v2_core_TcpKeepalive *msg, struct google_protobuf_UInt32Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt32Value*, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE struct google_protobuf_UInt32Value* envoy_api_v2_core_TcpKeepalive_mutable_keepalive_interval(envoy_api_v2_core_TcpKeepalive *msg, upb_arena *arena) { + struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_api_v2_core_TcpKeepalive_keepalive_interval(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt32Value*)upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_TcpKeepalive_set_keepalive_interval(msg, sub); + } + return sub; +} + + +/* envoy.api.v2.core.BindConfig */ + +UPB_INLINE envoy_api_v2_core_BindConfig *envoy_api_v2_core_BindConfig_new(upb_arena *arena) { + return (envoy_api_v2_core_BindConfig *)upb_msg_new(&envoy_api_v2_core_BindConfig_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_BindConfig *envoy_api_v2_core_BindConfig_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_BindConfig *ret = envoy_api_v2_core_BindConfig_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_BindConfig_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_BindConfig_serialize(const envoy_api_v2_core_BindConfig *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_BindConfig_msginit, arena, len); +} + +UPB_INLINE const envoy_api_v2_core_SocketAddress* envoy_api_v2_core_BindConfig_source_address(const envoy_api_v2_core_BindConfig *msg) { return UPB_FIELD_AT(msg, const envoy_api_v2_core_SocketAddress*, UPB_SIZE(0, 0)); } +UPB_INLINE const struct google_protobuf_BoolValue* envoy_api_v2_core_BindConfig_freebind(const envoy_api_v2_core_BindConfig *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_BoolValue*, UPB_SIZE(4, 8)); } +UPB_INLINE const struct envoy_api_v2_core_SocketOption* const* envoy_api_v2_core_BindConfig_socket_options(const envoy_api_v2_core_BindConfig *msg, size_t *len) { return (const struct envoy_api_v2_core_SocketOption* const*)_upb_array_accessor(msg, UPB_SIZE(8, 16), len); } + +UPB_INLINE void envoy_api_v2_core_BindConfig_set_source_address(envoy_api_v2_core_BindConfig *msg, envoy_api_v2_core_SocketAddress* value) { + UPB_FIELD_AT(msg, envoy_api_v2_core_SocketAddress*, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE struct envoy_api_v2_core_SocketAddress* envoy_api_v2_core_BindConfig_mutable_source_address(envoy_api_v2_core_BindConfig *msg, upb_arena *arena) { + struct envoy_api_v2_core_SocketAddress* sub = (struct envoy_api_v2_core_SocketAddress*)envoy_api_v2_core_BindConfig_source_address(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_SocketAddress*)upb_msg_new(&envoy_api_v2_core_SocketAddress_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_BindConfig_set_source_address(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_BindConfig_set_freebind(envoy_api_v2_core_BindConfig *msg, struct google_protobuf_BoolValue* value) { + UPB_FIELD_AT(msg, struct google_protobuf_BoolValue*, UPB_SIZE(4, 8)) = value; +} +UPB_INLINE struct google_protobuf_BoolValue* envoy_api_v2_core_BindConfig_mutable_freebind(envoy_api_v2_core_BindConfig *msg, upb_arena *arena) { + struct google_protobuf_BoolValue* sub = (struct google_protobuf_BoolValue*)envoy_api_v2_core_BindConfig_freebind(msg); + if (sub == NULL) { + sub = (struct google_protobuf_BoolValue*)upb_msg_new(&google_protobuf_BoolValue_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_BindConfig_set_freebind(msg, sub); + } + return sub; +} +UPB_INLINE struct envoy_api_v2_core_SocketOption** envoy_api_v2_core_BindConfig_mutable_socket_options(envoy_api_v2_core_BindConfig *msg, size_t *len) { + return (struct envoy_api_v2_core_SocketOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(8, 16), len); +} +UPB_INLINE struct envoy_api_v2_core_SocketOption** envoy_api_v2_core_BindConfig_resize_socket_options(envoy_api_v2_core_BindConfig *msg, size_t len, upb_arena *arena) { + return (struct envoy_api_v2_core_SocketOption**)_upb_array_resize_accessor(msg, UPB_SIZE(8, 16), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct envoy_api_v2_core_SocketOption* envoy_api_v2_core_BindConfig_add_socket_options(envoy_api_v2_core_BindConfig *msg, upb_arena *arena) { + struct envoy_api_v2_core_SocketOption* sub = (struct envoy_api_v2_core_SocketOption*)upb_msg_new(&envoy_api_v2_core_SocketOption_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(8, 16), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} + + +/* envoy.api.v2.core.Address */ + +UPB_INLINE envoy_api_v2_core_Address *envoy_api_v2_core_Address_new(upb_arena *arena) { + return (envoy_api_v2_core_Address *)upb_msg_new(&envoy_api_v2_core_Address_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_Address *envoy_api_v2_core_Address_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_Address *ret = envoy_api_v2_core_Address_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_Address_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_Address_serialize(const envoy_api_v2_core_Address *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_Address_msginit, arena, len); +} + +typedef enum { + envoy_api_v2_core_Address_address_socket_address = 1, + envoy_api_v2_core_Address_address_pipe = 2, + envoy_api_v2_core_Address_address_NOT_SET = 0, +} envoy_api_v2_core_Address_address_oneofcases; +UPB_INLINE envoy_api_v2_core_Address_address_oneofcases envoy_api_v2_core_Address_address_case(const envoy_api_v2_core_Address* msg) { return UPB_FIELD_AT(msg, int, UPB_SIZE(4, 8)); } + +UPB_INLINE bool envoy_api_v2_core_Address_has_socket_address(const envoy_api_v2_core_Address *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 1); } +UPB_INLINE const envoy_api_v2_core_SocketAddress* envoy_api_v2_core_Address_socket_address(const envoy_api_v2_core_Address *msg) { return UPB_READ_ONEOF(msg, const envoy_api_v2_core_SocketAddress*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 1, NULL); } +UPB_INLINE bool envoy_api_v2_core_Address_has_pipe(const envoy_api_v2_core_Address *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 2); } +UPB_INLINE const envoy_api_v2_core_Pipe* envoy_api_v2_core_Address_pipe(const envoy_api_v2_core_Address *msg) { return UPB_READ_ONEOF(msg, const envoy_api_v2_core_Pipe*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 2, NULL); } + +UPB_INLINE void envoy_api_v2_core_Address_set_socket_address(envoy_api_v2_core_Address *msg, envoy_api_v2_core_SocketAddress* value) { + UPB_WRITE_ONEOF(msg, envoy_api_v2_core_SocketAddress*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 1); +} +UPB_INLINE struct envoy_api_v2_core_SocketAddress* envoy_api_v2_core_Address_mutable_socket_address(envoy_api_v2_core_Address *msg, upb_arena *arena) { + struct envoy_api_v2_core_SocketAddress* sub = (struct envoy_api_v2_core_SocketAddress*)envoy_api_v2_core_Address_socket_address(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_SocketAddress*)upb_msg_new(&envoy_api_v2_core_SocketAddress_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_Address_set_socket_address(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_Address_set_pipe(envoy_api_v2_core_Address *msg, envoy_api_v2_core_Pipe* value) { + UPB_WRITE_ONEOF(msg, envoy_api_v2_core_Pipe*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 2); +} +UPB_INLINE struct envoy_api_v2_core_Pipe* envoy_api_v2_core_Address_mutable_pipe(envoy_api_v2_core_Address *msg, upb_arena *arena) { + struct envoy_api_v2_core_Pipe* sub = (struct envoy_api_v2_core_Pipe*)envoy_api_v2_core_Address_pipe(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_Pipe*)upb_msg_new(&envoy_api_v2_core_Pipe_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_Address_set_pipe(msg, sub); + } + return sub; +} + + +/* envoy.api.v2.core.CidrRange */ + +UPB_INLINE envoy_api_v2_core_CidrRange *envoy_api_v2_core_CidrRange_new(upb_arena *arena) { + return (envoy_api_v2_core_CidrRange *)upb_msg_new(&envoy_api_v2_core_CidrRange_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_CidrRange *envoy_api_v2_core_CidrRange_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_CidrRange *ret = envoy_api_v2_core_CidrRange_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_CidrRange_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_CidrRange_serialize(const envoy_api_v2_core_CidrRange *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_CidrRange_msginit, arena, len); +} + +UPB_INLINE upb_strview envoy_api_v2_core_CidrRange_address_prefix(const envoy_api_v2_core_CidrRange *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } +UPB_INLINE const struct google_protobuf_UInt32Value* envoy_api_v2_core_CidrRange_prefix_len(const envoy_api_v2_core_CidrRange *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt32Value*, UPB_SIZE(8, 16)); } + +UPB_INLINE void envoy_api_v2_core_CidrRange_set_address_prefix(envoy_api_v2_core_CidrRange *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_api_v2_core_CidrRange_set_prefix_len(envoy_api_v2_core_CidrRange *msg, struct google_protobuf_UInt32Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt32Value*, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE struct google_protobuf_UInt32Value* envoy_api_v2_core_CidrRange_mutable_prefix_len(envoy_api_v2_core_CidrRange *msg, upb_arena *arena) { + struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_api_v2_core_CidrRange_prefix_len(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt32Value*)upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_CidrRange_set_prefix_len(msg, sub); + } + return sub; +} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* ENVOY_API_V2_CORE_ADDRESS_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/envoy/api/v2/core/base.upb.c b/src/core/ext/upb-generated/envoy/api/v2/core/base.upb.c new file mode 100644 index 00000000000..1e5c9190381 --- /dev/null +++ b/src/core/ext/upb-generated/envoy/api/v2/core/base.upb.c @@ -0,0 +1,179 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/api/v2/core/base.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include +#include "upb/msg.h" +#include "envoy/api/v2/core/base.upb.h" +#include "google/protobuf/any.upb.h" +#include "google/protobuf/struct.upb.h" +#include "google/protobuf/wrappers.upb.h" +#include "validate/validate.upb.h" +#include "gogoproto/gogo.upb.h" +#include "envoy/type/percent.upb.h" + +#include "upb/port_def.inc" + +static const upb_msglayout_field envoy_api_v2_core_Locality__fields[3] = { + {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, + {2, UPB_SIZE(8, 16), 0, 0, 9, 1}, + {3, UPB_SIZE(16, 32), 0, 0, 9, 1}, +}; + +const upb_msglayout envoy_api_v2_core_Locality_msginit = { + NULL, + &envoy_api_v2_core_Locality__fields[0], + UPB_SIZE(24, 48), 3, false, +}; + +static const upb_msglayout *const envoy_api_v2_core_Node_submsgs[2] = { + &envoy_api_v2_core_Locality_msginit, + &google_protobuf_Struct_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_core_Node__fields[5] = { + {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, + {2, UPB_SIZE(8, 16), 0, 0, 9, 1}, + {3, UPB_SIZE(24, 48), 0, 1, 11, 1}, + {4, UPB_SIZE(28, 56), 0, 0, 11, 1}, + {5, UPB_SIZE(16, 32), 0, 0, 9, 1}, +}; + +const upb_msglayout envoy_api_v2_core_Node_msginit = { + &envoy_api_v2_core_Node_submsgs[0], + &envoy_api_v2_core_Node__fields[0], + UPB_SIZE(32, 64), 5, false, +}; + +static const upb_msglayout *const envoy_api_v2_core_Metadata_submsgs[1] = { + &envoy_api_v2_core_Metadata_FilterMetadataEntry_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_core_Metadata__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 11, 3}, +}; + +const upb_msglayout envoy_api_v2_core_Metadata_msginit = { + &envoy_api_v2_core_Metadata_submsgs[0], + &envoy_api_v2_core_Metadata__fields[0], + UPB_SIZE(4, 8), 1, false, +}; + +static const upb_msglayout *const envoy_api_v2_core_Metadata_FilterMetadataEntry_submsgs[1] = { + &google_protobuf_Struct_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_core_Metadata_FilterMetadataEntry__fields[2] = { + {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, + {2, UPB_SIZE(8, 16), 0, 0, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_core_Metadata_FilterMetadataEntry_msginit = { + &envoy_api_v2_core_Metadata_FilterMetadataEntry_submsgs[0], + &envoy_api_v2_core_Metadata_FilterMetadataEntry__fields[0], + UPB_SIZE(16, 32), 2, false, +}; + +static const upb_msglayout_field envoy_api_v2_core_RuntimeUInt32__fields[2] = { + {2, UPB_SIZE(0, 0), 0, 0, 13, 1}, + {3, UPB_SIZE(4, 8), 0, 0, 9, 1}, +}; + +const upb_msglayout envoy_api_v2_core_RuntimeUInt32_msginit = { + NULL, + &envoy_api_v2_core_RuntimeUInt32__fields[0], + UPB_SIZE(16, 32), 2, false, +}; + +static const upb_msglayout_field envoy_api_v2_core_HeaderValue__fields[2] = { + {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, + {2, UPB_SIZE(8, 16), 0, 0, 9, 1}, +}; + +const upb_msglayout envoy_api_v2_core_HeaderValue_msginit = { + NULL, + &envoy_api_v2_core_HeaderValue__fields[0], + UPB_SIZE(16, 32), 2, false, +}; + +static const upb_msglayout *const envoy_api_v2_core_HeaderValueOption_submsgs[2] = { + &envoy_api_v2_core_HeaderValue_msginit, + &google_protobuf_BoolValue_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_core_HeaderValueOption__fields[2] = { + {1, UPB_SIZE(0, 0), 0, 0, 11, 1}, + {2, UPB_SIZE(4, 8), 0, 1, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_core_HeaderValueOption_msginit = { + &envoy_api_v2_core_HeaderValueOption_submsgs[0], + &envoy_api_v2_core_HeaderValueOption__fields[0], + UPB_SIZE(8, 16), 2, false, +}; + +static const upb_msglayout_field envoy_api_v2_core_DataSource__fields[3] = { + {1, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 0, 9, 1}, + {2, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 0, 12, 1}, + {3, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 0, 9, 1}, +}; + +const upb_msglayout envoy_api_v2_core_DataSource_msginit = { + NULL, + &envoy_api_v2_core_DataSource__fields[0], + UPB_SIZE(16, 32), 3, false, +}; + +static const upb_msglayout *const envoy_api_v2_core_TransportSocket_submsgs[2] = { + &google_protobuf_Any_msginit, + &google_protobuf_Struct_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_core_TransportSocket__fields[3] = { + {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, + {2, UPB_SIZE(8, 16), UPB_SIZE(-13, -25), 1, 11, 1}, + {3, UPB_SIZE(8, 16), UPB_SIZE(-13, -25), 0, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_core_TransportSocket_msginit = { + &envoy_api_v2_core_TransportSocket_submsgs[0], + &envoy_api_v2_core_TransportSocket__fields[0], + UPB_SIZE(16, 32), 3, false, +}; + +static const upb_msglayout_field envoy_api_v2_core_SocketOption__fields[6] = { + {1, UPB_SIZE(24, 24), 0, 0, 9, 1}, + {2, UPB_SIZE(0, 0), 0, 0, 3, 1}, + {3, UPB_SIZE(8, 8), 0, 0, 3, 1}, + {4, UPB_SIZE(32, 40), UPB_SIZE(-41, -57), 0, 3, 1}, + {5, UPB_SIZE(32, 40), UPB_SIZE(-41, -57), 0, 12, 1}, + {6, UPB_SIZE(16, 16), 0, 0, 14, 1}, +}; + +const upb_msglayout envoy_api_v2_core_SocketOption_msginit = { + NULL, + &envoy_api_v2_core_SocketOption__fields[0], + UPB_SIZE(48, 64), 6, false, +}; + +static const upb_msglayout *const envoy_api_v2_core_RuntimeFractionalPercent_submsgs[1] = { + &envoy_type_FractionalPercent_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_core_RuntimeFractionalPercent__fields[2] = { + {1, UPB_SIZE(8, 16), 0, 0, 11, 1}, + {2, UPB_SIZE(0, 0), 0, 0, 9, 1}, +}; + +const upb_msglayout envoy_api_v2_core_RuntimeFractionalPercent_msginit = { + &envoy_api_v2_core_RuntimeFractionalPercent_submsgs[0], + &envoy_api_v2_core_RuntimeFractionalPercent__fields[0], + UPB_SIZE(16, 32), 2, false, +}; + +#include "upb/port_undef.inc" + diff --git a/src/core/ext/upb-generated/envoy/api/v2/core/base.upb.h b/src/core/ext/upb-generated/envoy/api/v2/core/base.upb.h new file mode 100644 index 00000000000..41d0dd096ac --- /dev/null +++ b/src/core/ext/upb-generated/envoy/api/v2/core/base.upb.h @@ -0,0 +1,508 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/api/v2/core/base.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef ENVOY_API_V2_CORE_BASE_PROTO_UPB_H_ +#define ENVOY_API_V2_CORE_BASE_PROTO_UPB_H_ + +#include "upb/generated_util.h" + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +#ifdef __cplusplus +extern "C" { +#endif + +struct envoy_api_v2_core_Locality; +struct envoy_api_v2_core_Node; +struct envoy_api_v2_core_Metadata; +struct envoy_api_v2_core_Metadata_FilterMetadataEntry; +struct envoy_api_v2_core_RuntimeUInt32; +struct envoy_api_v2_core_HeaderValue; +struct envoy_api_v2_core_HeaderValueOption; +struct envoy_api_v2_core_DataSource; +struct envoy_api_v2_core_TransportSocket; +struct envoy_api_v2_core_SocketOption; +struct envoy_api_v2_core_RuntimeFractionalPercent; +typedef struct envoy_api_v2_core_Locality envoy_api_v2_core_Locality; +typedef struct envoy_api_v2_core_Node envoy_api_v2_core_Node; +typedef struct envoy_api_v2_core_Metadata envoy_api_v2_core_Metadata; +typedef struct envoy_api_v2_core_Metadata_FilterMetadataEntry envoy_api_v2_core_Metadata_FilterMetadataEntry; +typedef struct envoy_api_v2_core_RuntimeUInt32 envoy_api_v2_core_RuntimeUInt32; +typedef struct envoy_api_v2_core_HeaderValue envoy_api_v2_core_HeaderValue; +typedef struct envoy_api_v2_core_HeaderValueOption envoy_api_v2_core_HeaderValueOption; +typedef struct envoy_api_v2_core_DataSource envoy_api_v2_core_DataSource; +typedef struct envoy_api_v2_core_TransportSocket envoy_api_v2_core_TransportSocket; +typedef struct envoy_api_v2_core_SocketOption envoy_api_v2_core_SocketOption; +typedef struct envoy_api_v2_core_RuntimeFractionalPercent envoy_api_v2_core_RuntimeFractionalPercent; +extern const upb_msglayout envoy_api_v2_core_Locality_msginit; +extern const upb_msglayout envoy_api_v2_core_Node_msginit; +extern const upb_msglayout envoy_api_v2_core_Metadata_msginit; +extern const upb_msglayout envoy_api_v2_core_Metadata_FilterMetadataEntry_msginit; +extern const upb_msglayout envoy_api_v2_core_RuntimeUInt32_msginit; +extern const upb_msglayout envoy_api_v2_core_HeaderValue_msginit; +extern const upb_msglayout envoy_api_v2_core_HeaderValueOption_msginit; +extern const upb_msglayout envoy_api_v2_core_DataSource_msginit; +extern const upb_msglayout envoy_api_v2_core_TransportSocket_msginit; +extern const upb_msglayout envoy_api_v2_core_SocketOption_msginit; +extern const upb_msglayout envoy_api_v2_core_RuntimeFractionalPercent_msginit; +struct envoy_type_FractionalPercent; +struct google_protobuf_Any; +struct google_protobuf_BoolValue; +struct google_protobuf_Struct; +extern const upb_msglayout envoy_type_FractionalPercent_msginit; +extern const upb_msglayout google_protobuf_Any_msginit; +extern const upb_msglayout google_protobuf_BoolValue_msginit; +extern const upb_msglayout google_protobuf_Struct_msginit; + +/* Enums */ + +typedef enum { + envoy_api_v2_core_METHOD_UNSPECIFIED = 0, + envoy_api_v2_core_GET = 1, + envoy_api_v2_core_HEAD = 2, + envoy_api_v2_core_POST = 3, + envoy_api_v2_core_PUT = 4, + envoy_api_v2_core_DELETE = 5, + envoy_api_v2_core_CONNECT = 6, + envoy_api_v2_core_OPTIONS = 7, + envoy_api_v2_core_TRACE = 8 +} envoy_api_v2_core_RequestMethod; + +typedef enum { + envoy_api_v2_core_DEFAULT = 0, + envoy_api_v2_core_HIGH = 1 +} envoy_api_v2_core_RoutingPriority; + +typedef enum { + envoy_api_v2_core_SocketOption_STATE_PREBIND = 0, + envoy_api_v2_core_SocketOption_STATE_BOUND = 1, + envoy_api_v2_core_SocketOption_STATE_LISTENING = 2 +} envoy_api_v2_core_SocketOption_SocketState; + + +/* envoy.api.v2.core.Locality */ + +UPB_INLINE envoy_api_v2_core_Locality *envoy_api_v2_core_Locality_new(upb_arena *arena) { + return (envoy_api_v2_core_Locality *)upb_msg_new(&envoy_api_v2_core_Locality_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_Locality *envoy_api_v2_core_Locality_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_Locality *ret = envoy_api_v2_core_Locality_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_Locality_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_Locality_serialize(const envoy_api_v2_core_Locality *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_Locality_msginit, arena, len); +} + +UPB_INLINE upb_strview envoy_api_v2_core_Locality_region(const envoy_api_v2_core_Locality *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } +UPB_INLINE upb_strview envoy_api_v2_core_Locality_zone(const envoy_api_v2_core_Locality *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 16)); } +UPB_INLINE upb_strview envoy_api_v2_core_Locality_sub_zone(const envoy_api_v2_core_Locality *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(16, 32)); } + +UPB_INLINE void envoy_api_v2_core_Locality_set_region(envoy_api_v2_core_Locality *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_api_v2_core_Locality_set_zone(envoy_api_v2_core_Locality *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE void envoy_api_v2_core_Locality_set_sub_zone(envoy_api_v2_core_Locality *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(16, 32)) = value; +} + + +/* envoy.api.v2.core.Node */ + +UPB_INLINE envoy_api_v2_core_Node *envoy_api_v2_core_Node_new(upb_arena *arena) { + return (envoy_api_v2_core_Node *)upb_msg_new(&envoy_api_v2_core_Node_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_Node *envoy_api_v2_core_Node_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_Node *ret = envoy_api_v2_core_Node_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_Node_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_Node_serialize(const envoy_api_v2_core_Node *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_Node_msginit, arena, len); +} + +UPB_INLINE upb_strview envoy_api_v2_core_Node_id(const envoy_api_v2_core_Node *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } +UPB_INLINE upb_strview envoy_api_v2_core_Node_cluster(const envoy_api_v2_core_Node *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 16)); } +UPB_INLINE const struct google_protobuf_Struct* envoy_api_v2_core_Node_metadata(const envoy_api_v2_core_Node *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Struct*, UPB_SIZE(24, 48)); } +UPB_INLINE const envoy_api_v2_core_Locality* envoy_api_v2_core_Node_locality(const envoy_api_v2_core_Node *msg) { return UPB_FIELD_AT(msg, const envoy_api_v2_core_Locality*, UPB_SIZE(28, 56)); } +UPB_INLINE upb_strview envoy_api_v2_core_Node_build_version(const envoy_api_v2_core_Node *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(16, 32)); } + +UPB_INLINE void envoy_api_v2_core_Node_set_id(envoy_api_v2_core_Node *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_api_v2_core_Node_set_cluster(envoy_api_v2_core_Node *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE void envoy_api_v2_core_Node_set_metadata(envoy_api_v2_core_Node *msg, struct google_protobuf_Struct* value) { + UPB_FIELD_AT(msg, struct google_protobuf_Struct*, UPB_SIZE(24, 48)) = value; +} +UPB_INLINE struct google_protobuf_Struct* envoy_api_v2_core_Node_mutable_metadata(envoy_api_v2_core_Node *msg, upb_arena *arena) { + struct google_protobuf_Struct* sub = (struct google_protobuf_Struct*)envoy_api_v2_core_Node_metadata(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Struct*)upb_msg_new(&google_protobuf_Struct_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_Node_set_metadata(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_Node_set_locality(envoy_api_v2_core_Node *msg, envoy_api_v2_core_Locality* value) { + UPB_FIELD_AT(msg, envoy_api_v2_core_Locality*, UPB_SIZE(28, 56)) = value; +} +UPB_INLINE struct envoy_api_v2_core_Locality* envoy_api_v2_core_Node_mutable_locality(envoy_api_v2_core_Node *msg, upb_arena *arena) { + struct envoy_api_v2_core_Locality* sub = (struct envoy_api_v2_core_Locality*)envoy_api_v2_core_Node_locality(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_Locality*)upb_msg_new(&envoy_api_v2_core_Locality_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_Node_set_locality(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_Node_set_build_version(envoy_api_v2_core_Node *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(16, 32)) = value; +} + + +/* envoy.api.v2.core.Metadata */ + +UPB_INLINE envoy_api_v2_core_Metadata *envoy_api_v2_core_Metadata_new(upb_arena *arena) { + return (envoy_api_v2_core_Metadata *)upb_msg_new(&envoy_api_v2_core_Metadata_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_Metadata *envoy_api_v2_core_Metadata_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_Metadata *ret = envoy_api_v2_core_Metadata_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_Metadata_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_Metadata_serialize(const envoy_api_v2_core_Metadata *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_Metadata_msginit, arena, len); +} + +UPB_INLINE const envoy_api_v2_core_Metadata_FilterMetadataEntry* const* envoy_api_v2_core_Metadata_filter_metadata(const envoy_api_v2_core_Metadata *msg, size_t *len) { return (const envoy_api_v2_core_Metadata_FilterMetadataEntry* const*)_upb_array_accessor(msg, UPB_SIZE(0, 0), len); } + +UPB_INLINE envoy_api_v2_core_Metadata_FilterMetadataEntry** envoy_api_v2_core_Metadata_mutable_filter_metadata(envoy_api_v2_core_Metadata *msg, size_t *len) { + return (envoy_api_v2_core_Metadata_FilterMetadataEntry**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len); +} +UPB_INLINE envoy_api_v2_core_Metadata_FilterMetadataEntry** envoy_api_v2_core_Metadata_resize_filter_metadata(envoy_api_v2_core_Metadata *msg, size_t len, upb_arena *arena) { + return (envoy_api_v2_core_Metadata_FilterMetadataEntry**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct envoy_api_v2_core_Metadata_FilterMetadataEntry* envoy_api_v2_core_Metadata_add_filter_metadata(envoy_api_v2_core_Metadata *msg, upb_arena *arena) { + struct envoy_api_v2_core_Metadata_FilterMetadataEntry* sub = (struct envoy_api_v2_core_Metadata_FilterMetadataEntry*)upb_msg_new(&envoy_api_v2_core_Metadata_FilterMetadataEntry_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} + + +/* envoy.api.v2.core.Metadata.FilterMetadataEntry */ + +UPB_INLINE envoy_api_v2_core_Metadata_FilterMetadataEntry *envoy_api_v2_core_Metadata_FilterMetadataEntry_new(upb_arena *arena) { + return (envoy_api_v2_core_Metadata_FilterMetadataEntry *)upb_msg_new(&envoy_api_v2_core_Metadata_FilterMetadataEntry_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_Metadata_FilterMetadataEntry *envoy_api_v2_core_Metadata_FilterMetadataEntry_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_Metadata_FilterMetadataEntry *ret = envoy_api_v2_core_Metadata_FilterMetadataEntry_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_Metadata_FilterMetadataEntry_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_Metadata_FilterMetadataEntry_serialize(const envoy_api_v2_core_Metadata_FilterMetadataEntry *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_Metadata_FilterMetadataEntry_msginit, arena, len); +} + +UPB_INLINE upb_strview envoy_api_v2_core_Metadata_FilterMetadataEntry_key(const envoy_api_v2_core_Metadata_FilterMetadataEntry *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } +UPB_INLINE const struct google_protobuf_Struct* envoy_api_v2_core_Metadata_FilterMetadataEntry_value(const envoy_api_v2_core_Metadata_FilterMetadataEntry *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Struct*, UPB_SIZE(8, 16)); } + +UPB_INLINE void envoy_api_v2_core_Metadata_FilterMetadataEntry_set_key(envoy_api_v2_core_Metadata_FilterMetadataEntry *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_api_v2_core_Metadata_FilterMetadataEntry_set_value(envoy_api_v2_core_Metadata_FilterMetadataEntry *msg, struct google_protobuf_Struct* value) { + UPB_FIELD_AT(msg, struct google_protobuf_Struct*, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE struct google_protobuf_Struct* envoy_api_v2_core_Metadata_FilterMetadataEntry_mutable_value(envoy_api_v2_core_Metadata_FilterMetadataEntry *msg, upb_arena *arena) { + struct google_protobuf_Struct* sub = (struct google_protobuf_Struct*)envoy_api_v2_core_Metadata_FilterMetadataEntry_value(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Struct*)upb_msg_new(&google_protobuf_Struct_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_Metadata_FilterMetadataEntry_set_value(msg, sub); + } + return sub; +} + + +/* envoy.api.v2.core.RuntimeUInt32 */ + +UPB_INLINE envoy_api_v2_core_RuntimeUInt32 *envoy_api_v2_core_RuntimeUInt32_new(upb_arena *arena) { + return (envoy_api_v2_core_RuntimeUInt32 *)upb_msg_new(&envoy_api_v2_core_RuntimeUInt32_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_RuntimeUInt32 *envoy_api_v2_core_RuntimeUInt32_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_RuntimeUInt32 *ret = envoy_api_v2_core_RuntimeUInt32_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_RuntimeUInt32_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_RuntimeUInt32_serialize(const envoy_api_v2_core_RuntimeUInt32 *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_RuntimeUInt32_msginit, arena, len); +} + +UPB_INLINE uint32_t envoy_api_v2_core_RuntimeUInt32_default_value(const envoy_api_v2_core_RuntimeUInt32 *msg) { return UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(0, 0)); } +UPB_INLINE upb_strview envoy_api_v2_core_RuntimeUInt32_runtime_key(const envoy_api_v2_core_RuntimeUInt32 *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)); } + +UPB_INLINE void envoy_api_v2_core_RuntimeUInt32_set_default_value(envoy_api_v2_core_RuntimeUInt32 *msg, uint32_t value) { + UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_api_v2_core_RuntimeUInt32_set_runtime_key(envoy_api_v2_core_RuntimeUInt32 *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)) = value; +} + + +/* envoy.api.v2.core.HeaderValue */ + +UPB_INLINE envoy_api_v2_core_HeaderValue *envoy_api_v2_core_HeaderValue_new(upb_arena *arena) { + return (envoy_api_v2_core_HeaderValue *)upb_msg_new(&envoy_api_v2_core_HeaderValue_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_HeaderValue *envoy_api_v2_core_HeaderValue_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_HeaderValue *ret = envoy_api_v2_core_HeaderValue_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_HeaderValue_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_HeaderValue_serialize(const envoy_api_v2_core_HeaderValue *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_HeaderValue_msginit, arena, len); +} + +UPB_INLINE upb_strview envoy_api_v2_core_HeaderValue_key(const envoy_api_v2_core_HeaderValue *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } +UPB_INLINE upb_strview envoy_api_v2_core_HeaderValue_value(const envoy_api_v2_core_HeaderValue *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 16)); } + +UPB_INLINE void envoy_api_v2_core_HeaderValue_set_key(envoy_api_v2_core_HeaderValue *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_api_v2_core_HeaderValue_set_value(envoy_api_v2_core_HeaderValue *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 16)) = value; +} + + +/* envoy.api.v2.core.HeaderValueOption */ + +UPB_INLINE envoy_api_v2_core_HeaderValueOption *envoy_api_v2_core_HeaderValueOption_new(upb_arena *arena) { + return (envoy_api_v2_core_HeaderValueOption *)upb_msg_new(&envoy_api_v2_core_HeaderValueOption_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_HeaderValueOption *envoy_api_v2_core_HeaderValueOption_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_HeaderValueOption *ret = envoy_api_v2_core_HeaderValueOption_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_HeaderValueOption_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_HeaderValueOption_serialize(const envoy_api_v2_core_HeaderValueOption *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_HeaderValueOption_msginit, arena, len); +} + +UPB_INLINE const envoy_api_v2_core_HeaderValue* envoy_api_v2_core_HeaderValueOption_header(const envoy_api_v2_core_HeaderValueOption *msg) { return UPB_FIELD_AT(msg, const envoy_api_v2_core_HeaderValue*, UPB_SIZE(0, 0)); } +UPB_INLINE const struct google_protobuf_BoolValue* envoy_api_v2_core_HeaderValueOption_append(const envoy_api_v2_core_HeaderValueOption *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_BoolValue*, UPB_SIZE(4, 8)); } + +UPB_INLINE void envoy_api_v2_core_HeaderValueOption_set_header(envoy_api_v2_core_HeaderValueOption *msg, envoy_api_v2_core_HeaderValue* value) { + UPB_FIELD_AT(msg, envoy_api_v2_core_HeaderValue*, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE struct envoy_api_v2_core_HeaderValue* envoy_api_v2_core_HeaderValueOption_mutable_header(envoy_api_v2_core_HeaderValueOption *msg, upb_arena *arena) { + struct envoy_api_v2_core_HeaderValue* sub = (struct envoy_api_v2_core_HeaderValue*)envoy_api_v2_core_HeaderValueOption_header(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_HeaderValue*)upb_msg_new(&envoy_api_v2_core_HeaderValue_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_HeaderValueOption_set_header(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_HeaderValueOption_set_append(envoy_api_v2_core_HeaderValueOption *msg, struct google_protobuf_BoolValue* value) { + UPB_FIELD_AT(msg, struct google_protobuf_BoolValue*, UPB_SIZE(4, 8)) = value; +} +UPB_INLINE struct google_protobuf_BoolValue* envoy_api_v2_core_HeaderValueOption_mutable_append(envoy_api_v2_core_HeaderValueOption *msg, upb_arena *arena) { + struct google_protobuf_BoolValue* sub = (struct google_protobuf_BoolValue*)envoy_api_v2_core_HeaderValueOption_append(msg); + if (sub == NULL) { + sub = (struct google_protobuf_BoolValue*)upb_msg_new(&google_protobuf_BoolValue_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_HeaderValueOption_set_append(msg, sub); + } + return sub; +} + + +/* envoy.api.v2.core.DataSource */ + +UPB_INLINE envoy_api_v2_core_DataSource *envoy_api_v2_core_DataSource_new(upb_arena *arena) { + return (envoy_api_v2_core_DataSource *)upb_msg_new(&envoy_api_v2_core_DataSource_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_DataSource *envoy_api_v2_core_DataSource_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_DataSource *ret = envoy_api_v2_core_DataSource_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_DataSource_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_DataSource_serialize(const envoy_api_v2_core_DataSource *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_DataSource_msginit, arena, len); +} + +typedef enum { + envoy_api_v2_core_DataSource_specifier_filename = 1, + envoy_api_v2_core_DataSource_specifier_inline_bytes = 2, + envoy_api_v2_core_DataSource_specifier_inline_string = 3, + envoy_api_v2_core_DataSource_specifier_NOT_SET = 0, +} envoy_api_v2_core_DataSource_specifier_oneofcases; +UPB_INLINE envoy_api_v2_core_DataSource_specifier_oneofcases envoy_api_v2_core_DataSource_specifier_case(const envoy_api_v2_core_DataSource* msg) { return UPB_FIELD_AT(msg, int, UPB_SIZE(8, 16)); } + +UPB_INLINE bool envoy_api_v2_core_DataSource_has_filename(const envoy_api_v2_core_DataSource *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(8, 16), 1); } +UPB_INLINE upb_strview envoy_api_v2_core_DataSource_filename(const envoy_api_v2_core_DataSource *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 1, upb_strview_make("", strlen(""))); } +UPB_INLINE bool envoy_api_v2_core_DataSource_has_inline_bytes(const envoy_api_v2_core_DataSource *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(8, 16), 2); } +UPB_INLINE upb_strview envoy_api_v2_core_DataSource_inline_bytes(const envoy_api_v2_core_DataSource *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 2, upb_strview_make("", strlen(""))); } +UPB_INLINE bool envoy_api_v2_core_DataSource_has_inline_string(const envoy_api_v2_core_DataSource *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(8, 16), 3); } +UPB_INLINE upb_strview envoy_api_v2_core_DataSource_inline_string(const envoy_api_v2_core_DataSource *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 3, upb_strview_make("", strlen(""))); } + +UPB_INLINE void envoy_api_v2_core_DataSource_set_filename(envoy_api_v2_core_DataSource *msg, upb_strview value) { + UPB_WRITE_ONEOF(msg, upb_strview, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), 1); +} +UPB_INLINE void envoy_api_v2_core_DataSource_set_inline_bytes(envoy_api_v2_core_DataSource *msg, upb_strview value) { + UPB_WRITE_ONEOF(msg, upb_strview, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), 2); +} +UPB_INLINE void envoy_api_v2_core_DataSource_set_inline_string(envoy_api_v2_core_DataSource *msg, upb_strview value) { + UPB_WRITE_ONEOF(msg, upb_strview, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), 3); +} + + +/* envoy.api.v2.core.TransportSocket */ + +UPB_INLINE envoy_api_v2_core_TransportSocket *envoy_api_v2_core_TransportSocket_new(upb_arena *arena) { + return (envoy_api_v2_core_TransportSocket *)upb_msg_new(&envoy_api_v2_core_TransportSocket_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_TransportSocket *envoy_api_v2_core_TransportSocket_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_TransportSocket *ret = envoy_api_v2_core_TransportSocket_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_TransportSocket_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_TransportSocket_serialize(const envoy_api_v2_core_TransportSocket *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_TransportSocket_msginit, arena, len); +} + +typedef enum { + envoy_api_v2_core_TransportSocket_config_type_config = 2, + envoy_api_v2_core_TransportSocket_config_type_typed_config = 3, + envoy_api_v2_core_TransportSocket_config_type_NOT_SET = 0, +} envoy_api_v2_core_TransportSocket_config_type_oneofcases; +UPB_INLINE envoy_api_v2_core_TransportSocket_config_type_oneofcases envoy_api_v2_core_TransportSocket_config_type_case(const envoy_api_v2_core_TransportSocket* msg) { return UPB_FIELD_AT(msg, int, UPB_SIZE(12, 24)); } + +UPB_INLINE upb_strview envoy_api_v2_core_TransportSocket_name(const envoy_api_v2_core_TransportSocket *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } +UPB_INLINE bool envoy_api_v2_core_TransportSocket_has_config(const envoy_api_v2_core_TransportSocket *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(12, 24), 2); } +UPB_INLINE const struct google_protobuf_Struct* envoy_api_v2_core_TransportSocket_config(const envoy_api_v2_core_TransportSocket *msg) { return UPB_READ_ONEOF(msg, const struct google_protobuf_Struct*, UPB_SIZE(8, 16), UPB_SIZE(12, 24), 2, NULL); } +UPB_INLINE bool envoy_api_v2_core_TransportSocket_has_typed_config(const envoy_api_v2_core_TransportSocket *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(12, 24), 3); } +UPB_INLINE const struct google_protobuf_Any* envoy_api_v2_core_TransportSocket_typed_config(const envoy_api_v2_core_TransportSocket *msg) { return UPB_READ_ONEOF(msg, const struct google_protobuf_Any*, UPB_SIZE(8, 16), UPB_SIZE(12, 24), 3, NULL); } + +UPB_INLINE void envoy_api_v2_core_TransportSocket_set_name(envoy_api_v2_core_TransportSocket *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_api_v2_core_TransportSocket_set_config(envoy_api_v2_core_TransportSocket *msg, struct google_protobuf_Struct* value) { + UPB_WRITE_ONEOF(msg, struct google_protobuf_Struct*, UPB_SIZE(8, 16), value, UPB_SIZE(12, 24), 2); +} +UPB_INLINE struct google_protobuf_Struct* envoy_api_v2_core_TransportSocket_mutable_config(envoy_api_v2_core_TransportSocket *msg, upb_arena *arena) { + struct google_protobuf_Struct* sub = (struct google_protobuf_Struct*)envoy_api_v2_core_TransportSocket_config(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Struct*)upb_msg_new(&google_protobuf_Struct_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_TransportSocket_set_config(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_TransportSocket_set_typed_config(envoy_api_v2_core_TransportSocket *msg, struct google_protobuf_Any* value) { + UPB_WRITE_ONEOF(msg, struct google_protobuf_Any*, UPB_SIZE(8, 16), value, UPB_SIZE(12, 24), 3); +} +UPB_INLINE struct google_protobuf_Any* envoy_api_v2_core_TransportSocket_mutable_typed_config(envoy_api_v2_core_TransportSocket *msg, upb_arena *arena) { + struct google_protobuf_Any* sub = (struct google_protobuf_Any*)envoy_api_v2_core_TransportSocket_typed_config(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Any*)upb_msg_new(&google_protobuf_Any_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_TransportSocket_set_typed_config(msg, sub); + } + return sub; +} + + +/* envoy.api.v2.core.SocketOption */ + +UPB_INLINE envoy_api_v2_core_SocketOption *envoy_api_v2_core_SocketOption_new(upb_arena *arena) { + return (envoy_api_v2_core_SocketOption *)upb_msg_new(&envoy_api_v2_core_SocketOption_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_SocketOption *envoy_api_v2_core_SocketOption_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_SocketOption *ret = envoy_api_v2_core_SocketOption_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_SocketOption_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_SocketOption_serialize(const envoy_api_v2_core_SocketOption *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_SocketOption_msginit, arena, len); +} + +typedef enum { + envoy_api_v2_core_SocketOption_value_int_value = 4, + envoy_api_v2_core_SocketOption_value_buf_value = 5, + envoy_api_v2_core_SocketOption_value_NOT_SET = 0, +} envoy_api_v2_core_SocketOption_value_oneofcases; +UPB_INLINE envoy_api_v2_core_SocketOption_value_oneofcases envoy_api_v2_core_SocketOption_value_case(const envoy_api_v2_core_SocketOption* msg) { return UPB_FIELD_AT(msg, int, UPB_SIZE(40, 56)); } + +UPB_INLINE upb_strview envoy_api_v2_core_SocketOption_description(const envoy_api_v2_core_SocketOption *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(24, 24)); } +UPB_INLINE int64_t envoy_api_v2_core_SocketOption_level(const envoy_api_v2_core_SocketOption *msg) { return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(0, 0)); } +UPB_INLINE int64_t envoy_api_v2_core_SocketOption_name(const envoy_api_v2_core_SocketOption *msg) { return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(8, 8)); } +UPB_INLINE bool envoy_api_v2_core_SocketOption_has_int_value(const envoy_api_v2_core_SocketOption *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(40, 56), 4); } +UPB_INLINE int64_t envoy_api_v2_core_SocketOption_int_value(const envoy_api_v2_core_SocketOption *msg) { return UPB_READ_ONEOF(msg, int64_t, UPB_SIZE(32, 40), UPB_SIZE(40, 56), 4, 0); } +UPB_INLINE bool envoy_api_v2_core_SocketOption_has_buf_value(const envoy_api_v2_core_SocketOption *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(40, 56), 5); } +UPB_INLINE upb_strview envoy_api_v2_core_SocketOption_buf_value(const envoy_api_v2_core_SocketOption *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(32, 40), UPB_SIZE(40, 56), 5, upb_strview_make("", strlen(""))); } +UPB_INLINE int32_t envoy_api_v2_core_SocketOption_state(const envoy_api_v2_core_SocketOption *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(16, 16)); } + +UPB_INLINE void envoy_api_v2_core_SocketOption_set_description(envoy_api_v2_core_SocketOption *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(24, 24)) = value; +} +UPB_INLINE void envoy_api_v2_core_SocketOption_set_level(envoy_api_v2_core_SocketOption *msg, int64_t value) { + UPB_FIELD_AT(msg, int64_t, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_api_v2_core_SocketOption_set_name(envoy_api_v2_core_SocketOption *msg, int64_t value) { + UPB_FIELD_AT(msg, int64_t, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE void envoy_api_v2_core_SocketOption_set_int_value(envoy_api_v2_core_SocketOption *msg, int64_t value) { + UPB_WRITE_ONEOF(msg, int64_t, UPB_SIZE(32, 40), value, UPB_SIZE(40, 56), 4); +} +UPB_INLINE void envoy_api_v2_core_SocketOption_set_buf_value(envoy_api_v2_core_SocketOption *msg, upb_strview value) { + UPB_WRITE_ONEOF(msg, upb_strview, UPB_SIZE(32, 40), value, UPB_SIZE(40, 56), 5); +} +UPB_INLINE void envoy_api_v2_core_SocketOption_set_state(envoy_api_v2_core_SocketOption *msg, int32_t value) { + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(16, 16)) = value; +} + + +/* envoy.api.v2.core.RuntimeFractionalPercent */ + +UPB_INLINE envoy_api_v2_core_RuntimeFractionalPercent *envoy_api_v2_core_RuntimeFractionalPercent_new(upb_arena *arena) { + return (envoy_api_v2_core_RuntimeFractionalPercent *)upb_msg_new(&envoy_api_v2_core_RuntimeFractionalPercent_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_RuntimeFractionalPercent *envoy_api_v2_core_RuntimeFractionalPercent_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_RuntimeFractionalPercent *ret = envoy_api_v2_core_RuntimeFractionalPercent_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_RuntimeFractionalPercent_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_RuntimeFractionalPercent_serialize(const envoy_api_v2_core_RuntimeFractionalPercent *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_RuntimeFractionalPercent_msginit, arena, len); +} + +UPB_INLINE const struct envoy_type_FractionalPercent* envoy_api_v2_core_RuntimeFractionalPercent_default_value(const envoy_api_v2_core_RuntimeFractionalPercent *msg) { return UPB_FIELD_AT(msg, const struct envoy_type_FractionalPercent*, UPB_SIZE(8, 16)); } +UPB_INLINE upb_strview envoy_api_v2_core_RuntimeFractionalPercent_runtime_key(const envoy_api_v2_core_RuntimeFractionalPercent *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } + +UPB_INLINE void envoy_api_v2_core_RuntimeFractionalPercent_set_default_value(envoy_api_v2_core_RuntimeFractionalPercent *msg, struct envoy_type_FractionalPercent* value) { + UPB_FIELD_AT(msg, struct envoy_type_FractionalPercent*, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE struct envoy_type_FractionalPercent* envoy_api_v2_core_RuntimeFractionalPercent_mutable_default_value(envoy_api_v2_core_RuntimeFractionalPercent *msg, upb_arena *arena) { + struct envoy_type_FractionalPercent* sub = (struct envoy_type_FractionalPercent*)envoy_api_v2_core_RuntimeFractionalPercent_default_value(msg); + if (sub == NULL) { + sub = (struct envoy_type_FractionalPercent*)upb_msg_new(&envoy_type_FractionalPercent_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_RuntimeFractionalPercent_set_default_value(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_RuntimeFractionalPercent_set_runtime_key(envoy_api_v2_core_RuntimeFractionalPercent *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* ENVOY_API_V2_CORE_BASE_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/envoy/api/v2/core/config_source.upb.c b/src/core/ext/upb-generated/envoy/api/v2/core/config_source.upb.c new file mode 100644 index 00000000000..b36d02aeb81 --- /dev/null +++ b/src/core/ext/upb-generated/envoy/api/v2/core/config_source.upb.c @@ -0,0 +1,81 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/api/v2/core/config_source.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include +#include "upb/msg.h" +#include "envoy/api/v2/core/config_source.upb.h" +#include "envoy/api/v2/core/grpc_service.upb.h" +#include "google/protobuf/duration.upb.h" +#include "google/protobuf/wrappers.upb.h" +#include "validate/validate.upb.h" +#include "gogoproto/gogo.upb.h" + +#include "upb/port_def.inc" + +static const upb_msglayout *const envoy_api_v2_core_ApiConfigSource_submsgs[4] = { + &envoy_api_v2_core_GrpcService_msginit, + &envoy_api_v2_core_RateLimitSettings_msginit, + &google_protobuf_Duration_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_core_ApiConfigSource__fields[6] = { + {1, UPB_SIZE(0, 0), 0, 0, 14, 1}, + {2, UPB_SIZE(20, 32), 0, 0, 9, 3}, + {3, UPB_SIZE(8, 8), 0, 2, 11, 1}, + {4, UPB_SIZE(24, 40), 0, 0, 11, 3}, + {5, UPB_SIZE(12, 16), 0, 2, 11, 1}, + {6, UPB_SIZE(16, 24), 0, 1, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_core_ApiConfigSource_msginit = { + &envoy_api_v2_core_ApiConfigSource_submsgs[0], + &envoy_api_v2_core_ApiConfigSource__fields[0], + UPB_SIZE(32, 48), 6, false, +}; + +const upb_msglayout envoy_api_v2_core_AggregatedConfigSource_msginit = { + NULL, + NULL, + UPB_SIZE(0, 0), 0, false, +}; + +static const upb_msglayout *const envoy_api_v2_core_RateLimitSettings_submsgs[2] = { + &google_protobuf_DoubleValue_msginit, + &google_protobuf_UInt32Value_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_core_RateLimitSettings__fields[2] = { + {1, UPB_SIZE(0, 0), 0, 1, 11, 1}, + {2, UPB_SIZE(4, 8), 0, 0, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_core_RateLimitSettings_msginit = { + &envoy_api_v2_core_RateLimitSettings_submsgs[0], + &envoy_api_v2_core_RateLimitSettings__fields[0], + UPB_SIZE(8, 16), 2, false, +}; + +static const upb_msglayout *const envoy_api_v2_core_ConfigSource_submsgs[2] = { + &envoy_api_v2_core_AggregatedConfigSource_msginit, + &envoy_api_v2_core_ApiConfigSource_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_core_ConfigSource__fields[3] = { + {1, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 0, 9, 1}, + {2, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 1, 11, 1}, + {3, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 0, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_core_ConfigSource_msginit = { + &envoy_api_v2_core_ConfigSource_submsgs[0], + &envoy_api_v2_core_ConfigSource__fields[0], + UPB_SIZE(16, 32), 3, false, +}; + +#include "upb/port_undef.inc" + diff --git a/src/core/ext/upb-generated/envoy/api/v2/core/config_source.upb.h b/src/core/ext/upb-generated/envoy/api/v2/core/config_source.upb.h new file mode 100644 index 00000000000..2b03b134c8e --- /dev/null +++ b/src/core/ext/upb-generated/envoy/api/v2/core/config_source.upb.h @@ -0,0 +1,258 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/api/v2/core/config_source.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef ENVOY_API_V2_CORE_CONFIG_SOURCE_PROTO_UPB_H_ +#define ENVOY_API_V2_CORE_CONFIG_SOURCE_PROTO_UPB_H_ + +#include "upb/generated_util.h" + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +#ifdef __cplusplus +extern "C" { +#endif + +struct envoy_api_v2_core_ApiConfigSource; +struct envoy_api_v2_core_AggregatedConfigSource; +struct envoy_api_v2_core_RateLimitSettings; +struct envoy_api_v2_core_ConfigSource; +typedef struct envoy_api_v2_core_ApiConfigSource envoy_api_v2_core_ApiConfigSource; +typedef struct envoy_api_v2_core_AggregatedConfigSource envoy_api_v2_core_AggregatedConfigSource; +typedef struct envoy_api_v2_core_RateLimitSettings envoy_api_v2_core_RateLimitSettings; +typedef struct envoy_api_v2_core_ConfigSource envoy_api_v2_core_ConfigSource; +extern const upb_msglayout envoy_api_v2_core_ApiConfigSource_msginit; +extern const upb_msglayout envoy_api_v2_core_AggregatedConfigSource_msginit; +extern const upb_msglayout envoy_api_v2_core_RateLimitSettings_msginit; +extern const upb_msglayout envoy_api_v2_core_ConfigSource_msginit; +struct envoy_api_v2_core_GrpcService; +struct google_protobuf_DoubleValue; +struct google_protobuf_Duration; +struct google_protobuf_UInt32Value; +extern const upb_msglayout envoy_api_v2_core_GrpcService_msginit; +extern const upb_msglayout google_protobuf_DoubleValue_msginit; +extern const upb_msglayout google_protobuf_Duration_msginit; +extern const upb_msglayout google_protobuf_UInt32Value_msginit; + +/* Enums */ + +typedef enum { + envoy_api_v2_core_ApiConfigSource_REST_LEGACY = 0, + envoy_api_v2_core_ApiConfigSource_REST = 1, + envoy_api_v2_core_ApiConfigSource_GRPC = 2 +} envoy_api_v2_core_ApiConfigSource_ApiType; + + +/* envoy.api.v2.core.ApiConfigSource */ + +UPB_INLINE envoy_api_v2_core_ApiConfigSource *envoy_api_v2_core_ApiConfigSource_new(upb_arena *arena) { + return (envoy_api_v2_core_ApiConfigSource *)upb_msg_new(&envoy_api_v2_core_ApiConfigSource_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_ApiConfigSource *envoy_api_v2_core_ApiConfigSource_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_ApiConfigSource *ret = envoy_api_v2_core_ApiConfigSource_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_ApiConfigSource_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_ApiConfigSource_serialize(const envoy_api_v2_core_ApiConfigSource *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_ApiConfigSource_msginit, arena, len); +} + +UPB_INLINE int32_t envoy_api_v2_core_ApiConfigSource_api_type(const envoy_api_v2_core_ApiConfigSource *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(0, 0)); } +UPB_INLINE upb_strview const* envoy_api_v2_core_ApiConfigSource_cluster_names(const envoy_api_v2_core_ApiConfigSource *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(20, 32), len); } +UPB_INLINE const struct google_protobuf_Duration* envoy_api_v2_core_ApiConfigSource_refresh_delay(const envoy_api_v2_core_ApiConfigSource *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Duration*, UPB_SIZE(8, 8)); } +UPB_INLINE const struct envoy_api_v2_core_GrpcService* const* envoy_api_v2_core_ApiConfigSource_grpc_services(const envoy_api_v2_core_ApiConfigSource *msg, size_t *len) { return (const struct envoy_api_v2_core_GrpcService* const*)_upb_array_accessor(msg, UPB_SIZE(24, 40), len); } +UPB_INLINE const struct google_protobuf_Duration* envoy_api_v2_core_ApiConfigSource_request_timeout(const envoy_api_v2_core_ApiConfigSource *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Duration*, UPB_SIZE(12, 16)); } +UPB_INLINE const envoy_api_v2_core_RateLimitSettings* envoy_api_v2_core_ApiConfigSource_rate_limit_settings(const envoy_api_v2_core_ApiConfigSource *msg) { return UPB_FIELD_AT(msg, const envoy_api_v2_core_RateLimitSettings*, UPB_SIZE(16, 24)); } + +UPB_INLINE void envoy_api_v2_core_ApiConfigSource_set_api_type(envoy_api_v2_core_ApiConfigSource *msg, int32_t value) { + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE upb_strview* envoy_api_v2_core_ApiConfigSource_mutable_cluster_names(envoy_api_v2_core_ApiConfigSource *msg, size_t *len) { + return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 32), len); +} +UPB_INLINE upb_strview* envoy_api_v2_core_ApiConfigSource_resize_cluster_names(envoy_api_v2_core_ApiConfigSource *msg, size_t len, upb_arena *arena) { + return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(20, 32), len, UPB_SIZE(8, 16), UPB_TYPE_STRING, arena); +} +UPB_INLINE bool envoy_api_v2_core_ApiConfigSource_add_cluster_names(envoy_api_v2_core_ApiConfigSource *msg, upb_strview val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(20, 32), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, arena); +} +UPB_INLINE void envoy_api_v2_core_ApiConfigSource_set_refresh_delay(envoy_api_v2_core_ApiConfigSource *msg, struct google_protobuf_Duration* value) { + UPB_FIELD_AT(msg, struct google_protobuf_Duration*, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE struct google_protobuf_Duration* envoy_api_v2_core_ApiConfigSource_mutable_refresh_delay(envoy_api_v2_core_ApiConfigSource *msg, upb_arena *arena) { + struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_api_v2_core_ApiConfigSource_refresh_delay(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Duration*)upb_msg_new(&google_protobuf_Duration_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_ApiConfigSource_set_refresh_delay(msg, sub); + } + return sub; +} +UPB_INLINE struct envoy_api_v2_core_GrpcService** envoy_api_v2_core_ApiConfigSource_mutable_grpc_services(envoy_api_v2_core_ApiConfigSource *msg, size_t *len) { + return (struct envoy_api_v2_core_GrpcService**)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 40), len); +} +UPB_INLINE struct envoy_api_v2_core_GrpcService** envoy_api_v2_core_ApiConfigSource_resize_grpc_services(envoy_api_v2_core_ApiConfigSource *msg, size_t len, upb_arena *arena) { + return (struct envoy_api_v2_core_GrpcService**)_upb_array_resize_accessor(msg, UPB_SIZE(24, 40), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct envoy_api_v2_core_GrpcService* envoy_api_v2_core_ApiConfigSource_add_grpc_services(envoy_api_v2_core_ApiConfigSource *msg, upb_arena *arena) { + struct envoy_api_v2_core_GrpcService* sub = (struct envoy_api_v2_core_GrpcService*)upb_msg_new(&envoy_api_v2_core_GrpcService_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(24, 40), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE void envoy_api_v2_core_ApiConfigSource_set_request_timeout(envoy_api_v2_core_ApiConfigSource *msg, struct google_protobuf_Duration* value) { + UPB_FIELD_AT(msg, struct google_protobuf_Duration*, UPB_SIZE(12, 16)) = value; +} +UPB_INLINE struct google_protobuf_Duration* envoy_api_v2_core_ApiConfigSource_mutable_request_timeout(envoy_api_v2_core_ApiConfigSource *msg, upb_arena *arena) { + struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_api_v2_core_ApiConfigSource_request_timeout(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Duration*)upb_msg_new(&google_protobuf_Duration_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_ApiConfigSource_set_request_timeout(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_ApiConfigSource_set_rate_limit_settings(envoy_api_v2_core_ApiConfigSource *msg, envoy_api_v2_core_RateLimitSettings* value) { + UPB_FIELD_AT(msg, envoy_api_v2_core_RateLimitSettings*, UPB_SIZE(16, 24)) = value; +} +UPB_INLINE struct envoy_api_v2_core_RateLimitSettings* envoy_api_v2_core_ApiConfigSource_mutable_rate_limit_settings(envoy_api_v2_core_ApiConfigSource *msg, upb_arena *arena) { + struct envoy_api_v2_core_RateLimitSettings* sub = (struct envoy_api_v2_core_RateLimitSettings*)envoy_api_v2_core_ApiConfigSource_rate_limit_settings(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_RateLimitSettings*)upb_msg_new(&envoy_api_v2_core_RateLimitSettings_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_ApiConfigSource_set_rate_limit_settings(msg, sub); + } + return sub; +} + + +/* envoy.api.v2.core.AggregatedConfigSource */ + +UPB_INLINE envoy_api_v2_core_AggregatedConfigSource *envoy_api_v2_core_AggregatedConfigSource_new(upb_arena *arena) { + return (envoy_api_v2_core_AggregatedConfigSource *)upb_msg_new(&envoy_api_v2_core_AggregatedConfigSource_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_AggregatedConfigSource *envoy_api_v2_core_AggregatedConfigSource_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_AggregatedConfigSource *ret = envoy_api_v2_core_AggregatedConfigSource_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_AggregatedConfigSource_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_AggregatedConfigSource_serialize(const envoy_api_v2_core_AggregatedConfigSource *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_AggregatedConfigSource_msginit, arena, len); +} + + + + +/* envoy.api.v2.core.RateLimitSettings */ + +UPB_INLINE envoy_api_v2_core_RateLimitSettings *envoy_api_v2_core_RateLimitSettings_new(upb_arena *arena) { + return (envoy_api_v2_core_RateLimitSettings *)upb_msg_new(&envoy_api_v2_core_RateLimitSettings_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_RateLimitSettings *envoy_api_v2_core_RateLimitSettings_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_RateLimitSettings *ret = envoy_api_v2_core_RateLimitSettings_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_RateLimitSettings_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_RateLimitSettings_serialize(const envoy_api_v2_core_RateLimitSettings *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_RateLimitSettings_msginit, arena, len); +} + +UPB_INLINE const struct google_protobuf_UInt32Value* envoy_api_v2_core_RateLimitSettings_max_tokens(const envoy_api_v2_core_RateLimitSettings *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt32Value*, UPB_SIZE(0, 0)); } +UPB_INLINE const struct google_protobuf_DoubleValue* envoy_api_v2_core_RateLimitSettings_fill_rate(const envoy_api_v2_core_RateLimitSettings *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_DoubleValue*, UPB_SIZE(4, 8)); } + +UPB_INLINE void envoy_api_v2_core_RateLimitSettings_set_max_tokens(envoy_api_v2_core_RateLimitSettings *msg, struct google_protobuf_UInt32Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt32Value*, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE struct google_protobuf_UInt32Value* envoy_api_v2_core_RateLimitSettings_mutable_max_tokens(envoy_api_v2_core_RateLimitSettings *msg, upb_arena *arena) { + struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_api_v2_core_RateLimitSettings_max_tokens(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt32Value*)upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_RateLimitSettings_set_max_tokens(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_RateLimitSettings_set_fill_rate(envoy_api_v2_core_RateLimitSettings *msg, struct google_protobuf_DoubleValue* value) { + UPB_FIELD_AT(msg, struct google_protobuf_DoubleValue*, UPB_SIZE(4, 8)) = value; +} +UPB_INLINE struct google_protobuf_DoubleValue* envoy_api_v2_core_RateLimitSettings_mutable_fill_rate(envoy_api_v2_core_RateLimitSettings *msg, upb_arena *arena) { + struct google_protobuf_DoubleValue* sub = (struct google_protobuf_DoubleValue*)envoy_api_v2_core_RateLimitSettings_fill_rate(msg); + if (sub == NULL) { + sub = (struct google_protobuf_DoubleValue*)upb_msg_new(&google_protobuf_DoubleValue_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_RateLimitSettings_set_fill_rate(msg, sub); + } + return sub; +} + + +/* envoy.api.v2.core.ConfigSource */ + +UPB_INLINE envoy_api_v2_core_ConfigSource *envoy_api_v2_core_ConfigSource_new(upb_arena *arena) { + return (envoy_api_v2_core_ConfigSource *)upb_msg_new(&envoy_api_v2_core_ConfigSource_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_ConfigSource *envoy_api_v2_core_ConfigSource_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_ConfigSource *ret = envoy_api_v2_core_ConfigSource_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_ConfigSource_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_ConfigSource_serialize(const envoy_api_v2_core_ConfigSource *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_ConfigSource_msginit, arena, len); +} + +typedef enum { + envoy_api_v2_core_ConfigSource_config_source_specifier_path = 1, + envoy_api_v2_core_ConfigSource_config_source_specifier_api_config_source = 2, + envoy_api_v2_core_ConfigSource_config_source_specifier_ads = 3, + envoy_api_v2_core_ConfigSource_config_source_specifier_NOT_SET = 0, +} envoy_api_v2_core_ConfigSource_config_source_specifier_oneofcases; +UPB_INLINE envoy_api_v2_core_ConfigSource_config_source_specifier_oneofcases envoy_api_v2_core_ConfigSource_config_source_specifier_case(const envoy_api_v2_core_ConfigSource* msg) { return UPB_FIELD_AT(msg, int, UPB_SIZE(8, 16)); } + +UPB_INLINE bool envoy_api_v2_core_ConfigSource_has_path(const envoy_api_v2_core_ConfigSource *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(8, 16), 1); } +UPB_INLINE upb_strview envoy_api_v2_core_ConfigSource_path(const envoy_api_v2_core_ConfigSource *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 1, upb_strview_make("", strlen(""))); } +UPB_INLINE bool envoy_api_v2_core_ConfigSource_has_api_config_source(const envoy_api_v2_core_ConfigSource *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(8, 16), 2); } +UPB_INLINE const envoy_api_v2_core_ApiConfigSource* envoy_api_v2_core_ConfigSource_api_config_source(const envoy_api_v2_core_ConfigSource *msg) { return UPB_READ_ONEOF(msg, const envoy_api_v2_core_ApiConfigSource*, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 2, NULL); } +UPB_INLINE bool envoy_api_v2_core_ConfigSource_has_ads(const envoy_api_v2_core_ConfigSource *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(8, 16), 3); } +UPB_INLINE const envoy_api_v2_core_AggregatedConfigSource* envoy_api_v2_core_ConfigSource_ads(const envoy_api_v2_core_ConfigSource *msg) { return UPB_READ_ONEOF(msg, const envoy_api_v2_core_AggregatedConfigSource*, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 3, NULL); } + +UPB_INLINE void envoy_api_v2_core_ConfigSource_set_path(envoy_api_v2_core_ConfigSource *msg, upb_strview value) { + UPB_WRITE_ONEOF(msg, upb_strview, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), 1); +} +UPB_INLINE void envoy_api_v2_core_ConfigSource_set_api_config_source(envoy_api_v2_core_ConfigSource *msg, envoy_api_v2_core_ApiConfigSource* value) { + UPB_WRITE_ONEOF(msg, envoy_api_v2_core_ApiConfigSource*, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), 2); +} +UPB_INLINE struct envoy_api_v2_core_ApiConfigSource* envoy_api_v2_core_ConfigSource_mutable_api_config_source(envoy_api_v2_core_ConfigSource *msg, upb_arena *arena) { + struct envoy_api_v2_core_ApiConfigSource* sub = (struct envoy_api_v2_core_ApiConfigSource*)envoy_api_v2_core_ConfigSource_api_config_source(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_ApiConfigSource*)upb_msg_new(&envoy_api_v2_core_ApiConfigSource_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_ConfigSource_set_api_config_source(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_ConfigSource_set_ads(envoy_api_v2_core_ConfigSource *msg, envoy_api_v2_core_AggregatedConfigSource* value) { + UPB_WRITE_ONEOF(msg, envoy_api_v2_core_AggregatedConfigSource*, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), 3); +} +UPB_INLINE struct envoy_api_v2_core_AggregatedConfigSource* envoy_api_v2_core_ConfigSource_mutable_ads(envoy_api_v2_core_ConfigSource *msg, upb_arena *arena) { + struct envoy_api_v2_core_AggregatedConfigSource* sub = (struct envoy_api_v2_core_AggregatedConfigSource*)envoy_api_v2_core_ConfigSource_ads(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_AggregatedConfigSource*)upb_msg_new(&envoy_api_v2_core_AggregatedConfigSource_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_ConfigSource_set_ads(msg, sub); + } + return sub; +} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* ENVOY_API_V2_CORE_CONFIG_SOURCE_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/envoy/api/v2/core/grpc_service.upb.c b/src/core/ext/upb-generated/envoy/api/v2/core/grpc_service.upb.c new file mode 100644 index 00000000000..e0c32f7eaf6 --- /dev/null +++ b/src/core/ext/upb-generated/envoy/api/v2/core/grpc_service.upb.c @@ -0,0 +1,175 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/api/v2/core/grpc_service.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include +#include "upb/msg.h" +#include "envoy/api/v2/core/grpc_service.upb.h" +#include "envoy/api/v2/core/base.upb.h" +#include "google/protobuf/any.upb.h" +#include "google/protobuf/duration.upb.h" +#include "google/protobuf/struct.upb.h" +#include "google/protobuf/empty.upb.h" +#include "validate/validate.upb.h" +#include "gogoproto/gogo.upb.h" + +#include "upb/port_def.inc" + +static const upb_msglayout *const envoy_api_v2_core_GrpcService_submsgs[4] = { + &envoy_api_v2_core_GrpcService_EnvoyGrpc_msginit, + &envoy_api_v2_core_GrpcService_GoogleGrpc_msginit, + &envoy_api_v2_core_HeaderValue_msginit, + &google_protobuf_Duration_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_core_GrpcService__fields[4] = { + {1, UPB_SIZE(8, 16), UPB_SIZE(-13, -25), 0, 11, 1}, + {2, UPB_SIZE(8, 16), UPB_SIZE(-13, -25), 1, 11, 1}, + {3, UPB_SIZE(0, 0), 0, 3, 11, 1}, + {5, UPB_SIZE(4, 8), 0, 2, 11, 3}, +}; + +const upb_msglayout envoy_api_v2_core_GrpcService_msginit = { + &envoy_api_v2_core_GrpcService_submsgs[0], + &envoy_api_v2_core_GrpcService__fields[0], + UPB_SIZE(16, 32), 4, false, +}; + +static const upb_msglayout_field envoy_api_v2_core_GrpcService_EnvoyGrpc__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, +}; + +const upb_msglayout envoy_api_v2_core_GrpcService_EnvoyGrpc_msginit = { + NULL, + &envoy_api_v2_core_GrpcService_EnvoyGrpc__fields[0], + UPB_SIZE(8, 16), 1, false, +}; + +static const upb_msglayout *const envoy_api_v2_core_GrpcService_GoogleGrpc_submsgs[3] = { + &envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_msginit, + &envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_msginit, + &google_protobuf_Struct_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_core_GrpcService_GoogleGrpc__fields[6] = { + {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, + {2, UPB_SIZE(24, 48), 0, 1, 11, 1}, + {3, UPB_SIZE(32, 64), 0, 0, 11, 3}, + {4, UPB_SIZE(8, 16), 0, 0, 9, 1}, + {5, UPB_SIZE(16, 32), 0, 0, 9, 1}, + {6, UPB_SIZE(28, 56), 0, 2, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_core_GrpcService_GoogleGrpc_msginit = { + &envoy_api_v2_core_GrpcService_GoogleGrpc_submsgs[0], + &envoy_api_v2_core_GrpcService_GoogleGrpc__fields[0], + UPB_SIZE(40, 80), 6, false, +}; + +static const upb_msglayout *const envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials_submsgs[3] = { + &envoy_api_v2_core_DataSource_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials__fields[3] = { + {1, UPB_SIZE(0, 0), 0, 0, 11, 1}, + {2, UPB_SIZE(4, 8), 0, 0, 11, 1}, + {3, UPB_SIZE(8, 16), 0, 0, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials_msginit = { + &envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials_submsgs[0], + &envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials__fields[0], + UPB_SIZE(12, 24), 3, false, +}; + +const upb_msglayout envoy_api_v2_core_GrpcService_GoogleGrpc_GoogleLocalCredentials_msginit = { + NULL, + NULL, + UPB_SIZE(0, 0), 0, false, +}; + +static const upb_msglayout *const envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_submsgs[3] = { + &envoy_api_v2_core_GrpcService_GoogleGrpc_GoogleLocalCredentials_msginit, + &envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials_msginit, + &google_protobuf_Empty_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials__fields[3] = { + {1, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 1, 11, 1}, + {2, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 2, 11, 1}, + {3, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 0, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_msginit = { + &envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_submsgs[0], + &envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials__fields[0], + UPB_SIZE(8, 16), 3, false, +}; + +static const upb_msglayout *const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_submsgs[4] = { + &envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials_msginit, + &envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_msginit, + &envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials_msginit, + &google_protobuf_Empty_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials__fields[6] = { + {1, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 0, 9, 1}, + {2, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 3, 11, 1}, + {3, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 0, 9, 1}, + {4, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 2, 11, 1}, + {5, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 0, 11, 1}, + {6, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 1, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_msginit = { + &envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_submsgs[0], + &envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials__fields[0], + UPB_SIZE(16, 32), 6, false, +}; + +static const upb_msglayout_field envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials__fields[2] = { + {1, UPB_SIZE(8, 8), 0, 0, 9, 1}, + {2, UPB_SIZE(0, 0), 0, 0, 4, 1}, +}; + +const upb_msglayout envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials_msginit = { + NULL, + &envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials__fields[0], + UPB_SIZE(16, 32), 2, false, +}; + +static const upb_msglayout_field envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials__fields[2] = { + {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, + {2, UPB_SIZE(8, 16), 0, 0, 9, 1}, +}; + +const upb_msglayout envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials_msginit = { + NULL, + &envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials__fields[0], + UPB_SIZE(16, 32), 2, false, +}; + +static const upb_msglayout *const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_submsgs[2] = { + &google_protobuf_Any_msginit, + &google_protobuf_Struct_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin__fields[3] = { + {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, + {2, UPB_SIZE(8, 16), UPB_SIZE(-13, -25), 1, 11, 1}, + {3, UPB_SIZE(8, 16), UPB_SIZE(-13, -25), 0, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_msginit = { + &envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_submsgs[0], + &envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin__fields[0], + UPB_SIZE(16, 32), 3, false, +}; + +#include "upb/port_undef.inc" + diff --git a/src/core/ext/upb-generated/envoy/api/v2/core/grpc_service.upb.h b/src/core/ext/upb-generated/envoy/api/v2/core/grpc_service.upb.h new file mode 100644 index 00000000000..8369c026dc7 --- /dev/null +++ b/src/core/ext/upb-generated/envoy/api/v2/core/grpc_service.upb.h @@ -0,0 +1,574 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/api/v2/core/grpc_service.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef ENVOY_API_V2_CORE_GRPC_SERVICE_PROTO_UPB_H_ +#define ENVOY_API_V2_CORE_GRPC_SERVICE_PROTO_UPB_H_ + +#include "upb/generated_util.h" + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +#ifdef __cplusplus +extern "C" { +#endif + +struct envoy_api_v2_core_GrpcService; +struct envoy_api_v2_core_GrpcService_EnvoyGrpc; +struct envoy_api_v2_core_GrpcService_GoogleGrpc; +struct envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials; +struct envoy_api_v2_core_GrpcService_GoogleGrpc_GoogleLocalCredentials; +struct envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials; +struct envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials; +struct envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials; +struct envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials; +struct envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin; +typedef struct envoy_api_v2_core_GrpcService envoy_api_v2_core_GrpcService; +typedef struct envoy_api_v2_core_GrpcService_EnvoyGrpc envoy_api_v2_core_GrpcService_EnvoyGrpc; +typedef struct envoy_api_v2_core_GrpcService_GoogleGrpc envoy_api_v2_core_GrpcService_GoogleGrpc; +typedef struct envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials; +typedef struct envoy_api_v2_core_GrpcService_GoogleGrpc_GoogleLocalCredentials envoy_api_v2_core_GrpcService_GoogleGrpc_GoogleLocalCredentials; +typedef struct envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials; +typedef struct envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials; +typedef struct envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials; +typedef struct envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials; +typedef struct envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin; +extern const upb_msglayout envoy_api_v2_core_GrpcService_msginit; +extern const upb_msglayout envoy_api_v2_core_GrpcService_EnvoyGrpc_msginit; +extern const upb_msglayout envoy_api_v2_core_GrpcService_GoogleGrpc_msginit; +extern const upb_msglayout envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials_msginit; +extern const upb_msglayout envoy_api_v2_core_GrpcService_GoogleGrpc_GoogleLocalCredentials_msginit; +extern const upb_msglayout envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_msginit; +extern const upb_msglayout envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_msginit; +extern const upb_msglayout envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials_msginit; +extern const upb_msglayout envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials_msginit; +extern const upb_msglayout envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_msginit; +struct envoy_api_v2_core_DataSource; +struct envoy_api_v2_core_HeaderValue; +struct google_protobuf_Any; +struct google_protobuf_Duration; +struct google_protobuf_Empty; +struct google_protobuf_Struct; +extern const upb_msglayout envoy_api_v2_core_DataSource_msginit; +extern const upb_msglayout envoy_api_v2_core_HeaderValue_msginit; +extern const upb_msglayout google_protobuf_Any_msginit; +extern const upb_msglayout google_protobuf_Duration_msginit; +extern const upb_msglayout google_protobuf_Empty_msginit; +extern const upb_msglayout google_protobuf_Struct_msginit; + +/* Enums */ + + +/* envoy.api.v2.core.GrpcService */ + +UPB_INLINE envoy_api_v2_core_GrpcService *envoy_api_v2_core_GrpcService_new(upb_arena *arena) { + return (envoy_api_v2_core_GrpcService *)upb_msg_new(&envoy_api_v2_core_GrpcService_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_GrpcService *envoy_api_v2_core_GrpcService_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_GrpcService *ret = envoy_api_v2_core_GrpcService_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_GrpcService_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_GrpcService_serialize(const envoy_api_v2_core_GrpcService *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_GrpcService_msginit, arena, len); +} + +typedef enum { + envoy_api_v2_core_GrpcService_target_specifier_envoy_grpc = 1, + envoy_api_v2_core_GrpcService_target_specifier_google_grpc = 2, + envoy_api_v2_core_GrpcService_target_specifier_NOT_SET = 0, +} envoy_api_v2_core_GrpcService_target_specifier_oneofcases; +UPB_INLINE envoy_api_v2_core_GrpcService_target_specifier_oneofcases envoy_api_v2_core_GrpcService_target_specifier_case(const envoy_api_v2_core_GrpcService* msg) { return UPB_FIELD_AT(msg, int, UPB_SIZE(12, 24)); } + +UPB_INLINE bool envoy_api_v2_core_GrpcService_has_envoy_grpc(const envoy_api_v2_core_GrpcService *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(12, 24), 1); } +UPB_INLINE const envoy_api_v2_core_GrpcService_EnvoyGrpc* envoy_api_v2_core_GrpcService_envoy_grpc(const envoy_api_v2_core_GrpcService *msg) { return UPB_READ_ONEOF(msg, const envoy_api_v2_core_GrpcService_EnvoyGrpc*, UPB_SIZE(8, 16), UPB_SIZE(12, 24), 1, NULL); } +UPB_INLINE bool envoy_api_v2_core_GrpcService_has_google_grpc(const envoy_api_v2_core_GrpcService *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(12, 24), 2); } +UPB_INLINE const envoy_api_v2_core_GrpcService_GoogleGrpc* envoy_api_v2_core_GrpcService_google_grpc(const envoy_api_v2_core_GrpcService *msg) { return UPB_READ_ONEOF(msg, const envoy_api_v2_core_GrpcService_GoogleGrpc*, UPB_SIZE(8, 16), UPB_SIZE(12, 24), 2, NULL); } +UPB_INLINE const struct google_protobuf_Duration* envoy_api_v2_core_GrpcService_timeout(const envoy_api_v2_core_GrpcService *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Duration*, UPB_SIZE(0, 0)); } +UPB_INLINE const struct envoy_api_v2_core_HeaderValue* const* envoy_api_v2_core_GrpcService_initial_metadata(const envoy_api_v2_core_GrpcService *msg, size_t *len) { return (const struct envoy_api_v2_core_HeaderValue* const*)_upb_array_accessor(msg, UPB_SIZE(4, 8), len); } + +UPB_INLINE void envoy_api_v2_core_GrpcService_set_envoy_grpc(envoy_api_v2_core_GrpcService *msg, envoy_api_v2_core_GrpcService_EnvoyGrpc* value) { + UPB_WRITE_ONEOF(msg, envoy_api_v2_core_GrpcService_EnvoyGrpc*, UPB_SIZE(8, 16), value, UPB_SIZE(12, 24), 1); +} +UPB_INLINE struct envoy_api_v2_core_GrpcService_EnvoyGrpc* envoy_api_v2_core_GrpcService_mutable_envoy_grpc(envoy_api_v2_core_GrpcService *msg, upb_arena *arena) { + struct envoy_api_v2_core_GrpcService_EnvoyGrpc* sub = (struct envoy_api_v2_core_GrpcService_EnvoyGrpc*)envoy_api_v2_core_GrpcService_envoy_grpc(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_GrpcService_EnvoyGrpc*)upb_msg_new(&envoy_api_v2_core_GrpcService_EnvoyGrpc_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_GrpcService_set_envoy_grpc(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_GrpcService_set_google_grpc(envoy_api_v2_core_GrpcService *msg, envoy_api_v2_core_GrpcService_GoogleGrpc* value) { + UPB_WRITE_ONEOF(msg, envoy_api_v2_core_GrpcService_GoogleGrpc*, UPB_SIZE(8, 16), value, UPB_SIZE(12, 24), 2); +} +UPB_INLINE struct envoy_api_v2_core_GrpcService_GoogleGrpc* envoy_api_v2_core_GrpcService_mutable_google_grpc(envoy_api_v2_core_GrpcService *msg, upb_arena *arena) { + struct envoy_api_v2_core_GrpcService_GoogleGrpc* sub = (struct envoy_api_v2_core_GrpcService_GoogleGrpc*)envoy_api_v2_core_GrpcService_google_grpc(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_GrpcService_GoogleGrpc*)upb_msg_new(&envoy_api_v2_core_GrpcService_GoogleGrpc_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_GrpcService_set_google_grpc(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_GrpcService_set_timeout(envoy_api_v2_core_GrpcService *msg, struct google_protobuf_Duration* value) { + UPB_FIELD_AT(msg, struct google_protobuf_Duration*, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE struct google_protobuf_Duration* envoy_api_v2_core_GrpcService_mutable_timeout(envoy_api_v2_core_GrpcService *msg, upb_arena *arena) { + struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_api_v2_core_GrpcService_timeout(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Duration*)upb_msg_new(&google_protobuf_Duration_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_GrpcService_set_timeout(msg, sub); + } + return sub; +} +UPB_INLINE struct envoy_api_v2_core_HeaderValue** envoy_api_v2_core_GrpcService_mutable_initial_metadata(envoy_api_v2_core_GrpcService *msg, size_t *len) { + return (struct envoy_api_v2_core_HeaderValue**)_upb_array_mutable_accessor(msg, UPB_SIZE(4, 8), len); +} +UPB_INLINE struct envoy_api_v2_core_HeaderValue** envoy_api_v2_core_GrpcService_resize_initial_metadata(envoy_api_v2_core_GrpcService *msg, size_t len, upb_arena *arena) { + return (struct envoy_api_v2_core_HeaderValue**)_upb_array_resize_accessor(msg, UPB_SIZE(4, 8), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct envoy_api_v2_core_HeaderValue* envoy_api_v2_core_GrpcService_add_initial_metadata(envoy_api_v2_core_GrpcService *msg, upb_arena *arena) { + struct envoy_api_v2_core_HeaderValue* sub = (struct envoy_api_v2_core_HeaderValue*)upb_msg_new(&envoy_api_v2_core_HeaderValue_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(4, 8), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} + + +/* envoy.api.v2.core.GrpcService.EnvoyGrpc */ + +UPB_INLINE envoy_api_v2_core_GrpcService_EnvoyGrpc *envoy_api_v2_core_GrpcService_EnvoyGrpc_new(upb_arena *arena) { + return (envoy_api_v2_core_GrpcService_EnvoyGrpc *)upb_msg_new(&envoy_api_v2_core_GrpcService_EnvoyGrpc_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_GrpcService_EnvoyGrpc *envoy_api_v2_core_GrpcService_EnvoyGrpc_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_GrpcService_EnvoyGrpc *ret = envoy_api_v2_core_GrpcService_EnvoyGrpc_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_GrpcService_EnvoyGrpc_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_GrpcService_EnvoyGrpc_serialize(const envoy_api_v2_core_GrpcService_EnvoyGrpc *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_GrpcService_EnvoyGrpc_msginit, arena, len); +} + +UPB_INLINE upb_strview envoy_api_v2_core_GrpcService_EnvoyGrpc_cluster_name(const envoy_api_v2_core_GrpcService_EnvoyGrpc *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } + +UPB_INLINE void envoy_api_v2_core_GrpcService_EnvoyGrpc_set_cluster_name(envoy_api_v2_core_GrpcService_EnvoyGrpc *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} + + +/* envoy.api.v2.core.GrpcService.GoogleGrpc */ + +UPB_INLINE envoy_api_v2_core_GrpcService_GoogleGrpc *envoy_api_v2_core_GrpcService_GoogleGrpc_new(upb_arena *arena) { + return (envoy_api_v2_core_GrpcService_GoogleGrpc *)upb_msg_new(&envoy_api_v2_core_GrpcService_GoogleGrpc_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_GrpcService_GoogleGrpc *envoy_api_v2_core_GrpcService_GoogleGrpc_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_GrpcService_GoogleGrpc *ret = envoy_api_v2_core_GrpcService_GoogleGrpc_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_GrpcService_GoogleGrpc_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_GrpcService_GoogleGrpc_serialize(const envoy_api_v2_core_GrpcService_GoogleGrpc *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_GrpcService_GoogleGrpc_msginit, arena, len); +} + +UPB_INLINE upb_strview envoy_api_v2_core_GrpcService_GoogleGrpc_target_uri(const envoy_api_v2_core_GrpcService_GoogleGrpc *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } +UPB_INLINE const envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials* envoy_api_v2_core_GrpcService_GoogleGrpc_channel_credentials(const envoy_api_v2_core_GrpcService_GoogleGrpc *msg) { return UPB_FIELD_AT(msg, const envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials*, UPB_SIZE(24, 48)); } +UPB_INLINE const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials* const* envoy_api_v2_core_GrpcService_GoogleGrpc_call_credentials(const envoy_api_v2_core_GrpcService_GoogleGrpc *msg, size_t *len) { return (const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials* const*)_upb_array_accessor(msg, UPB_SIZE(32, 64), len); } +UPB_INLINE upb_strview envoy_api_v2_core_GrpcService_GoogleGrpc_stat_prefix(const envoy_api_v2_core_GrpcService_GoogleGrpc *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 16)); } +UPB_INLINE upb_strview envoy_api_v2_core_GrpcService_GoogleGrpc_credentials_factory_name(const envoy_api_v2_core_GrpcService_GoogleGrpc *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(16, 32)); } +UPB_INLINE const struct google_protobuf_Struct* envoy_api_v2_core_GrpcService_GoogleGrpc_config(const envoy_api_v2_core_GrpcService_GoogleGrpc *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Struct*, UPB_SIZE(28, 56)); } + +UPB_INLINE void envoy_api_v2_core_GrpcService_GoogleGrpc_set_target_uri(envoy_api_v2_core_GrpcService_GoogleGrpc *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_api_v2_core_GrpcService_GoogleGrpc_set_channel_credentials(envoy_api_v2_core_GrpcService_GoogleGrpc *msg, envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials* value) { + UPB_FIELD_AT(msg, envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials*, UPB_SIZE(24, 48)) = value; +} +UPB_INLINE struct envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials* envoy_api_v2_core_GrpcService_GoogleGrpc_mutable_channel_credentials(envoy_api_v2_core_GrpcService_GoogleGrpc *msg, upb_arena *arena) { + struct envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials* sub = (struct envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials*)envoy_api_v2_core_GrpcService_GoogleGrpc_channel_credentials(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials*)upb_msg_new(&envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_GrpcService_GoogleGrpc_set_channel_credentials(msg, sub); + } + return sub; +} +UPB_INLINE envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials** envoy_api_v2_core_GrpcService_GoogleGrpc_mutable_call_credentials(envoy_api_v2_core_GrpcService_GoogleGrpc *msg, size_t *len) { + return (envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials**)_upb_array_mutable_accessor(msg, UPB_SIZE(32, 64), len); +} +UPB_INLINE envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials** envoy_api_v2_core_GrpcService_GoogleGrpc_resize_call_credentials(envoy_api_v2_core_GrpcService_GoogleGrpc *msg, size_t len, upb_arena *arena) { + return (envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials**)_upb_array_resize_accessor(msg, UPB_SIZE(32, 64), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials* envoy_api_v2_core_GrpcService_GoogleGrpc_add_call_credentials(envoy_api_v2_core_GrpcService_GoogleGrpc *msg, upb_arena *arena) { + struct envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials* sub = (struct envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials*)upb_msg_new(&envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(32, 64), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE void envoy_api_v2_core_GrpcService_GoogleGrpc_set_stat_prefix(envoy_api_v2_core_GrpcService_GoogleGrpc *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE void envoy_api_v2_core_GrpcService_GoogleGrpc_set_credentials_factory_name(envoy_api_v2_core_GrpcService_GoogleGrpc *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(16, 32)) = value; +} +UPB_INLINE void envoy_api_v2_core_GrpcService_GoogleGrpc_set_config(envoy_api_v2_core_GrpcService_GoogleGrpc *msg, struct google_protobuf_Struct* value) { + UPB_FIELD_AT(msg, struct google_protobuf_Struct*, UPB_SIZE(28, 56)) = value; +} +UPB_INLINE struct google_protobuf_Struct* envoy_api_v2_core_GrpcService_GoogleGrpc_mutable_config(envoy_api_v2_core_GrpcService_GoogleGrpc *msg, upb_arena *arena) { + struct google_protobuf_Struct* sub = (struct google_protobuf_Struct*)envoy_api_v2_core_GrpcService_GoogleGrpc_config(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Struct*)upb_msg_new(&google_protobuf_Struct_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_GrpcService_GoogleGrpc_set_config(msg, sub); + } + return sub; +} + + +/* envoy.api.v2.core.GrpcService.GoogleGrpc.SslCredentials */ + +UPB_INLINE envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials *envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials_new(upb_arena *arena) { + return (envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials *)upb_msg_new(&envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials *envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials *ret = envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials_serialize(const envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials_msginit, arena, len); +} + +UPB_INLINE const struct envoy_api_v2_core_DataSource* envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials_root_certs(const envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials *msg) { return UPB_FIELD_AT(msg, const struct envoy_api_v2_core_DataSource*, UPB_SIZE(0, 0)); } +UPB_INLINE const struct envoy_api_v2_core_DataSource* envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials_private_key(const envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials *msg) { return UPB_FIELD_AT(msg, const struct envoy_api_v2_core_DataSource*, UPB_SIZE(4, 8)); } +UPB_INLINE const struct envoy_api_v2_core_DataSource* envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials_cert_chain(const envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials *msg) { return UPB_FIELD_AT(msg, const struct envoy_api_v2_core_DataSource*, UPB_SIZE(8, 16)); } + +UPB_INLINE void envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials_set_root_certs(envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials *msg, struct envoy_api_v2_core_DataSource* value) { + UPB_FIELD_AT(msg, struct envoy_api_v2_core_DataSource*, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE struct envoy_api_v2_core_DataSource* envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials_mutable_root_certs(envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials *msg, upb_arena *arena) { + struct envoy_api_v2_core_DataSource* sub = (struct envoy_api_v2_core_DataSource*)envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials_root_certs(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_DataSource*)upb_msg_new(&envoy_api_v2_core_DataSource_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials_set_root_certs(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials_set_private_key(envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials *msg, struct envoy_api_v2_core_DataSource* value) { + UPB_FIELD_AT(msg, struct envoy_api_v2_core_DataSource*, UPB_SIZE(4, 8)) = value; +} +UPB_INLINE struct envoy_api_v2_core_DataSource* envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials_mutable_private_key(envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials *msg, upb_arena *arena) { + struct envoy_api_v2_core_DataSource* sub = (struct envoy_api_v2_core_DataSource*)envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials_private_key(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_DataSource*)upb_msg_new(&envoy_api_v2_core_DataSource_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials_set_private_key(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials_set_cert_chain(envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials *msg, struct envoy_api_v2_core_DataSource* value) { + UPB_FIELD_AT(msg, struct envoy_api_v2_core_DataSource*, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE struct envoy_api_v2_core_DataSource* envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials_mutable_cert_chain(envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials *msg, upb_arena *arena) { + struct envoy_api_v2_core_DataSource* sub = (struct envoy_api_v2_core_DataSource*)envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials_cert_chain(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_DataSource*)upb_msg_new(&envoy_api_v2_core_DataSource_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials_set_cert_chain(msg, sub); + } + return sub; +} + + +/* envoy.api.v2.core.GrpcService.GoogleGrpc.GoogleLocalCredentials */ + +UPB_INLINE envoy_api_v2_core_GrpcService_GoogleGrpc_GoogleLocalCredentials *envoy_api_v2_core_GrpcService_GoogleGrpc_GoogleLocalCredentials_new(upb_arena *arena) { + return (envoy_api_v2_core_GrpcService_GoogleGrpc_GoogleLocalCredentials *)upb_msg_new(&envoy_api_v2_core_GrpcService_GoogleGrpc_GoogleLocalCredentials_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_GrpcService_GoogleGrpc_GoogleLocalCredentials *envoy_api_v2_core_GrpcService_GoogleGrpc_GoogleLocalCredentials_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_GrpcService_GoogleGrpc_GoogleLocalCredentials *ret = envoy_api_v2_core_GrpcService_GoogleGrpc_GoogleLocalCredentials_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_GrpcService_GoogleGrpc_GoogleLocalCredentials_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_GrpcService_GoogleGrpc_GoogleLocalCredentials_serialize(const envoy_api_v2_core_GrpcService_GoogleGrpc_GoogleLocalCredentials *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_GrpcService_GoogleGrpc_GoogleLocalCredentials_msginit, arena, len); +} + + + + +/* envoy.api.v2.core.GrpcService.GoogleGrpc.ChannelCredentials */ + +UPB_INLINE envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials *envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_new(upb_arena *arena) { + return (envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials *)upb_msg_new(&envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials *envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials *ret = envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_serialize(const envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_msginit, arena, len); +} + +typedef enum { + envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_credential_specifier_ssl_credentials = 1, + envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_credential_specifier_google_default = 2, + envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_credential_specifier_local_credentials = 3, + envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_credential_specifier_NOT_SET = 0, +} envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_credential_specifier_oneofcases; +UPB_INLINE envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_credential_specifier_oneofcases envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_credential_specifier_case(const envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials* msg) { return UPB_FIELD_AT(msg, int, UPB_SIZE(4, 8)); } + +UPB_INLINE bool envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_has_ssl_credentials(const envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 1); } +UPB_INLINE const envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials* envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_ssl_credentials(const envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials *msg) { return UPB_READ_ONEOF(msg, const envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 1, NULL); } +UPB_INLINE bool envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_has_google_default(const envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 2); } +UPB_INLINE const struct google_protobuf_Empty* envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_google_default(const envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials *msg) { return UPB_READ_ONEOF(msg, const struct google_protobuf_Empty*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 2, NULL); } +UPB_INLINE bool envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_has_local_credentials(const envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 3); } +UPB_INLINE const envoy_api_v2_core_GrpcService_GoogleGrpc_GoogleLocalCredentials* envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_local_credentials(const envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials *msg) { return UPB_READ_ONEOF(msg, const envoy_api_v2_core_GrpcService_GoogleGrpc_GoogleLocalCredentials*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 3, NULL); } + +UPB_INLINE void envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_set_ssl_credentials(envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials *msg, envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials* value) { + UPB_WRITE_ONEOF(msg, envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 1); +} +UPB_INLINE struct envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials* envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_mutable_ssl_credentials(envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials *msg, upb_arena *arena) { + struct envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials* sub = (struct envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials*)envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_ssl_credentials(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials*)upb_msg_new(&envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_set_ssl_credentials(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_set_google_default(envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials *msg, struct google_protobuf_Empty* value) { + UPB_WRITE_ONEOF(msg, struct google_protobuf_Empty*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 2); +} +UPB_INLINE struct google_protobuf_Empty* envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_mutable_google_default(envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials *msg, upb_arena *arena) { + struct google_protobuf_Empty* sub = (struct google_protobuf_Empty*)envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_google_default(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Empty*)upb_msg_new(&google_protobuf_Empty_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_set_google_default(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_set_local_credentials(envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials *msg, envoy_api_v2_core_GrpcService_GoogleGrpc_GoogleLocalCredentials* value) { + UPB_WRITE_ONEOF(msg, envoy_api_v2_core_GrpcService_GoogleGrpc_GoogleLocalCredentials*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 3); +} +UPB_INLINE struct envoy_api_v2_core_GrpcService_GoogleGrpc_GoogleLocalCredentials* envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_mutable_local_credentials(envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials *msg, upb_arena *arena) { + struct envoy_api_v2_core_GrpcService_GoogleGrpc_GoogleLocalCredentials* sub = (struct envoy_api_v2_core_GrpcService_GoogleGrpc_GoogleLocalCredentials*)envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_local_credentials(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_GrpcService_GoogleGrpc_GoogleLocalCredentials*)upb_msg_new(&envoy_api_v2_core_GrpcService_GoogleGrpc_GoogleLocalCredentials_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_set_local_credentials(msg, sub); + } + return sub; +} + + +/* envoy.api.v2.core.GrpcService.GoogleGrpc.CallCredentials */ + +UPB_INLINE envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials *envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_new(upb_arena *arena) { + return (envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials *)upb_msg_new(&envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials *envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials *ret = envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_serialize(const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_msginit, arena, len); +} + +typedef enum { + envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_credential_specifier_access_token = 1, + envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_credential_specifier_google_compute_engine = 2, + envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_credential_specifier_google_refresh_token = 3, + envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_credential_specifier_service_account_jwt_access = 4, + envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_credential_specifier_google_iam = 5, + envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_credential_specifier_from_plugin = 6, + envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_credential_specifier_NOT_SET = 0, +} envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_credential_specifier_oneofcases; +UPB_INLINE envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_credential_specifier_oneofcases envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_credential_specifier_case(const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials* msg) { return UPB_FIELD_AT(msg, int, UPB_SIZE(8, 16)); } + +UPB_INLINE bool envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_has_access_token(const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(8, 16), 1); } +UPB_INLINE upb_strview envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_access_token(const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 1, upb_strview_make("", strlen(""))); } +UPB_INLINE bool envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_has_google_compute_engine(const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(8, 16), 2); } +UPB_INLINE const struct google_protobuf_Empty* envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_google_compute_engine(const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials *msg) { return UPB_READ_ONEOF(msg, const struct google_protobuf_Empty*, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 2, NULL); } +UPB_INLINE bool envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_has_google_refresh_token(const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(8, 16), 3); } +UPB_INLINE upb_strview envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_google_refresh_token(const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 3, upb_strview_make("", strlen(""))); } +UPB_INLINE bool envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_has_service_account_jwt_access(const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(8, 16), 4); } +UPB_INLINE const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials* envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_service_account_jwt_access(const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials *msg) { return UPB_READ_ONEOF(msg, const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials*, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 4, NULL); } +UPB_INLINE bool envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_has_google_iam(const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(8, 16), 5); } +UPB_INLINE const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials* envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_google_iam(const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials *msg) { return UPB_READ_ONEOF(msg, const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials*, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 5, NULL); } +UPB_INLINE bool envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_has_from_plugin(const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(8, 16), 6); } +UPB_INLINE const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin* envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_from_plugin(const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials *msg) { return UPB_READ_ONEOF(msg, const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin*, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 6, NULL); } + +UPB_INLINE void envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_set_access_token(envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials *msg, upb_strview value) { + UPB_WRITE_ONEOF(msg, upb_strview, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), 1); +} +UPB_INLINE void envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_set_google_compute_engine(envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials *msg, struct google_protobuf_Empty* value) { + UPB_WRITE_ONEOF(msg, struct google_protobuf_Empty*, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), 2); +} +UPB_INLINE struct google_protobuf_Empty* envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_mutable_google_compute_engine(envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials *msg, upb_arena *arena) { + struct google_protobuf_Empty* sub = (struct google_protobuf_Empty*)envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_google_compute_engine(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Empty*)upb_msg_new(&google_protobuf_Empty_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_set_google_compute_engine(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_set_google_refresh_token(envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials *msg, upb_strview value) { + UPB_WRITE_ONEOF(msg, upb_strview, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), 3); +} +UPB_INLINE void envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_set_service_account_jwt_access(envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials *msg, envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials* value) { + UPB_WRITE_ONEOF(msg, envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials*, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), 4); +} +UPB_INLINE struct envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials* envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_mutable_service_account_jwt_access(envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials *msg, upb_arena *arena) { + struct envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials* sub = (struct envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials*)envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_service_account_jwt_access(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials*)upb_msg_new(&envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_set_service_account_jwt_access(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_set_google_iam(envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials *msg, envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials* value) { + UPB_WRITE_ONEOF(msg, envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials*, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), 5); +} +UPB_INLINE struct envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials* envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_mutable_google_iam(envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials *msg, upb_arena *arena) { + struct envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials* sub = (struct envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials*)envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_google_iam(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials*)upb_msg_new(&envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_set_google_iam(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_set_from_plugin(envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials *msg, envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin* value) { + UPB_WRITE_ONEOF(msg, envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin*, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), 6); +} +UPB_INLINE struct envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin* envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_mutable_from_plugin(envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials *msg, upb_arena *arena) { + struct envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin* sub = (struct envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin*)envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_from_plugin(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin*)upb_msg_new(&envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_set_from_plugin(msg, sub); + } + return sub; +} + + +/* envoy.api.v2.core.GrpcService.GoogleGrpc.CallCredentials.ServiceAccountJWTAccessCredentials */ + +UPB_INLINE envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials *envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials_new(upb_arena *arena) { + return (envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials *)upb_msg_new(&envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials *envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials *ret = envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials_serialize(const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials_msginit, arena, len); +} + +UPB_INLINE upb_strview envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials_json_key(const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 8)); } +UPB_INLINE uint64_t envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials_token_lifetime_seconds(const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(0, 0)); } + +UPB_INLINE void envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials_set_json_key(envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE void envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials_set_token_lifetime_seconds(envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials *msg, uint64_t value) { + UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(0, 0)) = value; +} + + +/* envoy.api.v2.core.GrpcService.GoogleGrpc.CallCredentials.GoogleIAMCredentials */ + +UPB_INLINE envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials *envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials_new(upb_arena *arena) { + return (envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials *)upb_msg_new(&envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials *envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials *ret = envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials_serialize(const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials_msginit, arena, len); +} + +UPB_INLINE upb_strview envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials_authorization_token(const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } +UPB_INLINE upb_strview envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials_authority_selector(const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 16)); } + +UPB_INLINE void envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials_set_authorization_token(envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials_set_authority_selector(envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 16)) = value; +} + + +/* envoy.api.v2.core.GrpcService.GoogleGrpc.CallCredentials.MetadataCredentialsFromPlugin */ + +UPB_INLINE envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin *envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_new(upb_arena *arena) { + return (envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin *)upb_msg_new(&envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin *envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin *ret = envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_serialize(const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_msginit, arena, len); +} + +typedef enum { + envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_config_type_config = 2, + envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_config_type_typed_config = 3, + envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_config_type_NOT_SET = 0, +} envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_config_type_oneofcases; +UPB_INLINE envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_config_type_oneofcases envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_config_type_case(const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin* msg) { return UPB_FIELD_AT(msg, int, UPB_SIZE(12, 24)); } + +UPB_INLINE upb_strview envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_name(const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } +UPB_INLINE bool envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_has_config(const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(12, 24), 2); } +UPB_INLINE const struct google_protobuf_Struct* envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_config(const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin *msg) { return UPB_READ_ONEOF(msg, const struct google_protobuf_Struct*, UPB_SIZE(8, 16), UPB_SIZE(12, 24), 2, NULL); } +UPB_INLINE bool envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_has_typed_config(const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(12, 24), 3); } +UPB_INLINE const struct google_protobuf_Any* envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_typed_config(const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin *msg) { return UPB_READ_ONEOF(msg, const struct google_protobuf_Any*, UPB_SIZE(8, 16), UPB_SIZE(12, 24), 3, NULL); } + +UPB_INLINE void envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_set_name(envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_set_config(envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin *msg, struct google_protobuf_Struct* value) { + UPB_WRITE_ONEOF(msg, struct google_protobuf_Struct*, UPB_SIZE(8, 16), value, UPB_SIZE(12, 24), 2); +} +UPB_INLINE struct google_protobuf_Struct* envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_mutable_config(envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin *msg, upb_arena *arena) { + struct google_protobuf_Struct* sub = (struct google_protobuf_Struct*)envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_config(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Struct*)upb_msg_new(&google_protobuf_Struct_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_set_config(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_set_typed_config(envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin *msg, struct google_protobuf_Any* value) { + UPB_WRITE_ONEOF(msg, struct google_protobuf_Any*, UPB_SIZE(8, 16), value, UPB_SIZE(12, 24), 3); +} +UPB_INLINE struct google_protobuf_Any* envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_mutable_typed_config(envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin *msg, upb_arena *arena) { + struct google_protobuf_Any* sub = (struct google_protobuf_Any*)envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_typed_config(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Any*)upb_msg_new(&google_protobuf_Any_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_set_typed_config(msg, sub); + } + return sub; +} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* ENVOY_API_V2_CORE_GRPC_SERVICE_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/envoy/api/v2/core/health_check.upb.c b/src/core/ext/upb-generated/envoy/api/v2/core/health_check.upb.c new file mode 100644 index 00000000000..a6dcd52d45b --- /dev/null +++ b/src/core/ext/upb-generated/envoy/api/v2/core/health_check.upb.c @@ -0,0 +1,144 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/api/v2/core/health_check.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include +#include "upb/msg.h" +#include "envoy/api/v2/core/health_check.upb.h" +#include "envoy/api/v2/core/base.upb.h" +#include "google/protobuf/any.upb.h" +#include "google/protobuf/duration.upb.h" +#include "google/protobuf/struct.upb.h" +#include "google/protobuf/wrappers.upb.h" +#include "validate/validate.upb.h" +#include "gogoproto/gogo.upb.h" + +#include "upb/port_def.inc" + +static const upb_msglayout *const envoy_api_v2_core_HealthCheck_submsgs[15] = { + &envoy_api_v2_core_HealthCheck_CustomHealthCheck_msginit, + &envoy_api_v2_core_HealthCheck_GrpcHealthCheck_msginit, + &envoy_api_v2_core_HealthCheck_HttpHealthCheck_msginit, + &envoy_api_v2_core_HealthCheck_TcpHealthCheck_msginit, + &google_protobuf_BoolValue_msginit, + &google_protobuf_Duration_msginit, + &google_protobuf_UInt32Value_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_core_HealthCheck__fields[17] = { + {1, UPB_SIZE(12, 24), 0, 5, 11, 1}, + {2, UPB_SIZE(16, 32), 0, 5, 11, 1}, + {3, UPB_SIZE(20, 40), 0, 5, 11, 1}, + {4, UPB_SIZE(24, 48), 0, 6, 11, 1}, + {5, UPB_SIZE(28, 56), 0, 6, 11, 1}, + {6, UPB_SIZE(32, 64), 0, 6, 11, 1}, + {7, UPB_SIZE(36, 72), 0, 4, 11, 1}, + {8, UPB_SIZE(56, 112), UPB_SIZE(-61, -121), 2, 11, 1}, + {9, UPB_SIZE(56, 112), UPB_SIZE(-61, -121), 3, 11, 1}, + {11, UPB_SIZE(56, 112), UPB_SIZE(-61, -121), 1, 11, 1}, + {12, UPB_SIZE(40, 80), 0, 5, 11, 1}, + {13, UPB_SIZE(56, 112), UPB_SIZE(-61, -121), 0, 11, 1}, + {14, UPB_SIZE(44, 88), 0, 5, 11, 1}, + {15, UPB_SIZE(48, 96), 0, 5, 11, 1}, + {16, UPB_SIZE(52, 104), 0, 5, 11, 1}, + {17, UPB_SIZE(4, 8), 0, 0, 9, 1}, + {18, UPB_SIZE(0, 0), 0, 0, 13, 1}, +}; + +const upb_msglayout envoy_api_v2_core_HealthCheck_msginit = { + &envoy_api_v2_core_HealthCheck_submsgs[0], + &envoy_api_v2_core_HealthCheck__fields[0], + UPB_SIZE(64, 128), 17, false, +}; + +static const upb_msglayout_field envoy_api_v2_core_HealthCheck_Payload__fields[2] = { + {1, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 0, 9, 1}, + {2, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 0, 12, 1}, +}; + +const upb_msglayout envoy_api_v2_core_HealthCheck_Payload_msginit = { + NULL, + &envoy_api_v2_core_HealthCheck_Payload__fields[0], + UPB_SIZE(16, 32), 2, false, +}; + +static const upb_msglayout *const envoy_api_v2_core_HealthCheck_HttpHealthCheck_submsgs[3] = { + &envoy_api_v2_core_HeaderValueOption_msginit, + &envoy_api_v2_core_HealthCheck_Payload_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_core_HealthCheck_HttpHealthCheck__fields[8] = { + {1, UPB_SIZE(4, 8), 0, 0, 9, 1}, + {2, UPB_SIZE(12, 24), 0, 0, 9, 1}, + {3, UPB_SIZE(28, 56), 0, 1, 11, 1}, + {4, UPB_SIZE(32, 64), 0, 1, 11, 1}, + {5, UPB_SIZE(20, 40), 0, 0, 9, 1}, + {6, UPB_SIZE(36, 72), 0, 0, 11, 3}, + {7, UPB_SIZE(0, 0), 0, 0, 8, 1}, + {8, UPB_SIZE(40, 80), 0, 0, 9, 3}, +}; + +const upb_msglayout envoy_api_v2_core_HealthCheck_HttpHealthCheck_msginit = { + &envoy_api_v2_core_HealthCheck_HttpHealthCheck_submsgs[0], + &envoy_api_v2_core_HealthCheck_HttpHealthCheck__fields[0], + UPB_SIZE(48, 96), 8, false, +}; + +static const upb_msglayout *const envoy_api_v2_core_HealthCheck_TcpHealthCheck_submsgs[2] = { + &envoy_api_v2_core_HealthCheck_Payload_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_core_HealthCheck_TcpHealthCheck__fields[2] = { + {1, UPB_SIZE(0, 0), 0, 0, 11, 1}, + {2, UPB_SIZE(4, 8), 0, 0, 11, 3}, +}; + +const upb_msglayout envoy_api_v2_core_HealthCheck_TcpHealthCheck_msginit = { + &envoy_api_v2_core_HealthCheck_TcpHealthCheck_submsgs[0], + &envoy_api_v2_core_HealthCheck_TcpHealthCheck__fields[0], + UPB_SIZE(8, 16), 2, false, +}; + +static const upb_msglayout_field envoy_api_v2_core_HealthCheck_RedisHealthCheck__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, +}; + +const upb_msglayout envoy_api_v2_core_HealthCheck_RedisHealthCheck_msginit = { + NULL, + &envoy_api_v2_core_HealthCheck_RedisHealthCheck__fields[0], + UPB_SIZE(8, 16), 1, false, +}; + +static const upb_msglayout_field envoy_api_v2_core_HealthCheck_GrpcHealthCheck__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, +}; + +const upb_msglayout envoy_api_v2_core_HealthCheck_GrpcHealthCheck_msginit = { + NULL, + &envoy_api_v2_core_HealthCheck_GrpcHealthCheck__fields[0], + UPB_SIZE(8, 16), 1, false, +}; + +static const upb_msglayout *const envoy_api_v2_core_HealthCheck_CustomHealthCheck_submsgs[2] = { + &google_protobuf_Any_msginit, + &google_protobuf_Struct_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_core_HealthCheck_CustomHealthCheck__fields[3] = { + {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, + {2, UPB_SIZE(8, 16), UPB_SIZE(-13, -25), 1, 11, 1}, + {3, UPB_SIZE(8, 16), UPB_SIZE(-13, -25), 0, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_core_HealthCheck_CustomHealthCheck_msginit = { + &envoy_api_v2_core_HealthCheck_CustomHealthCheck_submsgs[0], + &envoy_api_v2_core_HealthCheck_CustomHealthCheck__fields[0], + UPB_SIZE(16, 32), 3, false, +}; + +#include "upb/port_undef.inc" + diff --git a/src/core/ext/upb-generated/envoy/api/v2/core/health_check.upb.h b/src/core/ext/upb-generated/envoy/api/v2/core/health_check.upb.h new file mode 100644 index 00000000000..7db04bf3e73 --- /dev/null +++ b/src/core/ext/upb-generated/envoy/api/v2/core/health_check.upb.h @@ -0,0 +1,560 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/api/v2/core/health_check.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef ENVOY_API_V2_CORE_HEALTH_CHECK_PROTO_UPB_H_ +#define ENVOY_API_V2_CORE_HEALTH_CHECK_PROTO_UPB_H_ + +#include "upb/generated_util.h" + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +#ifdef __cplusplus +extern "C" { +#endif + +struct envoy_api_v2_core_HealthCheck; +struct envoy_api_v2_core_HealthCheck_Payload; +struct envoy_api_v2_core_HealthCheck_HttpHealthCheck; +struct envoy_api_v2_core_HealthCheck_TcpHealthCheck; +struct envoy_api_v2_core_HealthCheck_RedisHealthCheck; +struct envoy_api_v2_core_HealthCheck_GrpcHealthCheck; +struct envoy_api_v2_core_HealthCheck_CustomHealthCheck; +typedef struct envoy_api_v2_core_HealthCheck envoy_api_v2_core_HealthCheck; +typedef struct envoy_api_v2_core_HealthCheck_Payload envoy_api_v2_core_HealthCheck_Payload; +typedef struct envoy_api_v2_core_HealthCheck_HttpHealthCheck envoy_api_v2_core_HealthCheck_HttpHealthCheck; +typedef struct envoy_api_v2_core_HealthCheck_TcpHealthCheck envoy_api_v2_core_HealthCheck_TcpHealthCheck; +typedef struct envoy_api_v2_core_HealthCheck_RedisHealthCheck envoy_api_v2_core_HealthCheck_RedisHealthCheck; +typedef struct envoy_api_v2_core_HealthCheck_GrpcHealthCheck envoy_api_v2_core_HealthCheck_GrpcHealthCheck; +typedef struct envoy_api_v2_core_HealthCheck_CustomHealthCheck envoy_api_v2_core_HealthCheck_CustomHealthCheck; +extern const upb_msglayout envoy_api_v2_core_HealthCheck_msginit; +extern const upb_msglayout envoy_api_v2_core_HealthCheck_Payload_msginit; +extern const upb_msglayout envoy_api_v2_core_HealthCheck_HttpHealthCheck_msginit; +extern const upb_msglayout envoy_api_v2_core_HealthCheck_TcpHealthCheck_msginit; +extern const upb_msglayout envoy_api_v2_core_HealthCheck_RedisHealthCheck_msginit; +extern const upb_msglayout envoy_api_v2_core_HealthCheck_GrpcHealthCheck_msginit; +extern const upb_msglayout envoy_api_v2_core_HealthCheck_CustomHealthCheck_msginit; +struct envoy_api_v2_core_HeaderValueOption; +struct google_protobuf_Any; +struct google_protobuf_BoolValue; +struct google_protobuf_Duration; +struct google_protobuf_Struct; +struct google_protobuf_UInt32Value; +extern const upb_msglayout envoy_api_v2_core_HeaderValueOption_msginit; +extern const upb_msglayout google_protobuf_Any_msginit; +extern const upb_msglayout google_protobuf_BoolValue_msginit; +extern const upb_msglayout google_protobuf_Duration_msginit; +extern const upb_msglayout google_protobuf_Struct_msginit; +extern const upb_msglayout google_protobuf_UInt32Value_msginit; + +/* Enums */ + +typedef enum { + envoy_api_v2_core_UNKNOWN = 0, + envoy_api_v2_core_HEALTHY = 1, + envoy_api_v2_core_UNHEALTHY = 2, + envoy_api_v2_core_DRAINING = 3, + envoy_api_v2_core_TIMEOUT = 4 +} envoy_api_v2_core_HealthStatus; + + +/* envoy.api.v2.core.HealthCheck */ + +UPB_INLINE envoy_api_v2_core_HealthCheck *envoy_api_v2_core_HealthCheck_new(upb_arena *arena) { + return (envoy_api_v2_core_HealthCheck *)upb_msg_new(&envoy_api_v2_core_HealthCheck_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_HealthCheck *envoy_api_v2_core_HealthCheck_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_HealthCheck *ret = envoy_api_v2_core_HealthCheck_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_HealthCheck_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_HealthCheck_serialize(const envoy_api_v2_core_HealthCheck *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_HealthCheck_msginit, arena, len); +} + +typedef enum { + envoy_api_v2_core_HealthCheck_health_checker_http_health_check = 8, + envoy_api_v2_core_HealthCheck_health_checker_tcp_health_check = 9, + envoy_api_v2_core_HealthCheck_health_checker_grpc_health_check = 11, + envoy_api_v2_core_HealthCheck_health_checker_custom_health_check = 13, + envoy_api_v2_core_HealthCheck_health_checker_NOT_SET = 0, +} envoy_api_v2_core_HealthCheck_health_checker_oneofcases; +UPB_INLINE envoy_api_v2_core_HealthCheck_health_checker_oneofcases envoy_api_v2_core_HealthCheck_health_checker_case(const envoy_api_v2_core_HealthCheck* msg) { return UPB_FIELD_AT(msg, int, UPB_SIZE(60, 120)); } + +UPB_INLINE const struct google_protobuf_Duration* envoy_api_v2_core_HealthCheck_timeout(const envoy_api_v2_core_HealthCheck *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Duration*, UPB_SIZE(12, 24)); } +UPB_INLINE const struct google_protobuf_Duration* envoy_api_v2_core_HealthCheck_interval(const envoy_api_v2_core_HealthCheck *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Duration*, UPB_SIZE(16, 32)); } +UPB_INLINE const struct google_protobuf_Duration* envoy_api_v2_core_HealthCheck_interval_jitter(const envoy_api_v2_core_HealthCheck *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Duration*, UPB_SIZE(20, 40)); } +UPB_INLINE const struct google_protobuf_UInt32Value* envoy_api_v2_core_HealthCheck_unhealthy_threshold(const envoy_api_v2_core_HealthCheck *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt32Value*, UPB_SIZE(24, 48)); } +UPB_INLINE const struct google_protobuf_UInt32Value* envoy_api_v2_core_HealthCheck_healthy_threshold(const envoy_api_v2_core_HealthCheck *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt32Value*, UPB_SIZE(28, 56)); } +UPB_INLINE const struct google_protobuf_UInt32Value* envoy_api_v2_core_HealthCheck_alt_port(const envoy_api_v2_core_HealthCheck *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt32Value*, UPB_SIZE(32, 64)); } +UPB_INLINE const struct google_protobuf_BoolValue* envoy_api_v2_core_HealthCheck_reuse_connection(const envoy_api_v2_core_HealthCheck *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_BoolValue*, UPB_SIZE(36, 72)); } +UPB_INLINE bool envoy_api_v2_core_HealthCheck_has_http_health_check(const envoy_api_v2_core_HealthCheck *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(60, 120), 8); } +UPB_INLINE const envoy_api_v2_core_HealthCheck_HttpHealthCheck* envoy_api_v2_core_HealthCheck_http_health_check(const envoy_api_v2_core_HealthCheck *msg) { return UPB_READ_ONEOF(msg, const envoy_api_v2_core_HealthCheck_HttpHealthCheck*, UPB_SIZE(56, 112), UPB_SIZE(60, 120), 8, NULL); } +UPB_INLINE bool envoy_api_v2_core_HealthCheck_has_tcp_health_check(const envoy_api_v2_core_HealthCheck *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(60, 120), 9); } +UPB_INLINE const envoy_api_v2_core_HealthCheck_TcpHealthCheck* envoy_api_v2_core_HealthCheck_tcp_health_check(const envoy_api_v2_core_HealthCheck *msg) { return UPB_READ_ONEOF(msg, const envoy_api_v2_core_HealthCheck_TcpHealthCheck*, UPB_SIZE(56, 112), UPB_SIZE(60, 120), 9, NULL); } +UPB_INLINE bool envoy_api_v2_core_HealthCheck_has_grpc_health_check(const envoy_api_v2_core_HealthCheck *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(60, 120), 11); } +UPB_INLINE const envoy_api_v2_core_HealthCheck_GrpcHealthCheck* envoy_api_v2_core_HealthCheck_grpc_health_check(const envoy_api_v2_core_HealthCheck *msg) { return UPB_READ_ONEOF(msg, const envoy_api_v2_core_HealthCheck_GrpcHealthCheck*, UPB_SIZE(56, 112), UPB_SIZE(60, 120), 11, NULL); } +UPB_INLINE const struct google_protobuf_Duration* envoy_api_v2_core_HealthCheck_no_traffic_interval(const envoy_api_v2_core_HealthCheck *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Duration*, UPB_SIZE(40, 80)); } +UPB_INLINE bool envoy_api_v2_core_HealthCheck_has_custom_health_check(const envoy_api_v2_core_HealthCheck *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(60, 120), 13); } +UPB_INLINE const envoy_api_v2_core_HealthCheck_CustomHealthCheck* envoy_api_v2_core_HealthCheck_custom_health_check(const envoy_api_v2_core_HealthCheck *msg) { return UPB_READ_ONEOF(msg, const envoy_api_v2_core_HealthCheck_CustomHealthCheck*, UPB_SIZE(56, 112), UPB_SIZE(60, 120), 13, NULL); } +UPB_INLINE const struct google_protobuf_Duration* envoy_api_v2_core_HealthCheck_unhealthy_interval(const envoy_api_v2_core_HealthCheck *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Duration*, UPB_SIZE(44, 88)); } +UPB_INLINE const struct google_protobuf_Duration* envoy_api_v2_core_HealthCheck_unhealthy_edge_interval(const envoy_api_v2_core_HealthCheck *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Duration*, UPB_SIZE(48, 96)); } +UPB_INLINE const struct google_protobuf_Duration* envoy_api_v2_core_HealthCheck_healthy_edge_interval(const envoy_api_v2_core_HealthCheck *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Duration*, UPB_SIZE(52, 104)); } +UPB_INLINE upb_strview envoy_api_v2_core_HealthCheck_event_log_path(const envoy_api_v2_core_HealthCheck *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)); } +UPB_INLINE uint32_t envoy_api_v2_core_HealthCheck_interval_jitter_percent(const envoy_api_v2_core_HealthCheck *msg) { return UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(0, 0)); } + +UPB_INLINE void envoy_api_v2_core_HealthCheck_set_timeout(envoy_api_v2_core_HealthCheck *msg, struct google_protobuf_Duration* value) { + UPB_FIELD_AT(msg, struct google_protobuf_Duration*, UPB_SIZE(12, 24)) = value; +} +UPB_INLINE struct google_protobuf_Duration* envoy_api_v2_core_HealthCheck_mutable_timeout(envoy_api_v2_core_HealthCheck *msg, upb_arena *arena) { + struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_api_v2_core_HealthCheck_timeout(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Duration*)upb_msg_new(&google_protobuf_Duration_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_HealthCheck_set_timeout(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_HealthCheck_set_interval(envoy_api_v2_core_HealthCheck *msg, struct google_protobuf_Duration* value) { + UPB_FIELD_AT(msg, struct google_protobuf_Duration*, UPB_SIZE(16, 32)) = value; +} +UPB_INLINE struct google_protobuf_Duration* envoy_api_v2_core_HealthCheck_mutable_interval(envoy_api_v2_core_HealthCheck *msg, upb_arena *arena) { + struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_api_v2_core_HealthCheck_interval(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Duration*)upb_msg_new(&google_protobuf_Duration_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_HealthCheck_set_interval(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_HealthCheck_set_interval_jitter(envoy_api_v2_core_HealthCheck *msg, struct google_protobuf_Duration* value) { + UPB_FIELD_AT(msg, struct google_protobuf_Duration*, UPB_SIZE(20, 40)) = value; +} +UPB_INLINE struct google_protobuf_Duration* envoy_api_v2_core_HealthCheck_mutable_interval_jitter(envoy_api_v2_core_HealthCheck *msg, upb_arena *arena) { + struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_api_v2_core_HealthCheck_interval_jitter(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Duration*)upb_msg_new(&google_protobuf_Duration_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_HealthCheck_set_interval_jitter(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_HealthCheck_set_unhealthy_threshold(envoy_api_v2_core_HealthCheck *msg, struct google_protobuf_UInt32Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt32Value*, UPB_SIZE(24, 48)) = value; +} +UPB_INLINE struct google_protobuf_UInt32Value* envoy_api_v2_core_HealthCheck_mutable_unhealthy_threshold(envoy_api_v2_core_HealthCheck *msg, upb_arena *arena) { + struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_api_v2_core_HealthCheck_unhealthy_threshold(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt32Value*)upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_HealthCheck_set_unhealthy_threshold(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_HealthCheck_set_healthy_threshold(envoy_api_v2_core_HealthCheck *msg, struct google_protobuf_UInt32Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt32Value*, UPB_SIZE(28, 56)) = value; +} +UPB_INLINE struct google_protobuf_UInt32Value* envoy_api_v2_core_HealthCheck_mutable_healthy_threshold(envoy_api_v2_core_HealthCheck *msg, upb_arena *arena) { + struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_api_v2_core_HealthCheck_healthy_threshold(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt32Value*)upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_HealthCheck_set_healthy_threshold(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_HealthCheck_set_alt_port(envoy_api_v2_core_HealthCheck *msg, struct google_protobuf_UInt32Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt32Value*, UPB_SIZE(32, 64)) = value; +} +UPB_INLINE struct google_protobuf_UInt32Value* envoy_api_v2_core_HealthCheck_mutable_alt_port(envoy_api_v2_core_HealthCheck *msg, upb_arena *arena) { + struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_api_v2_core_HealthCheck_alt_port(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt32Value*)upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_HealthCheck_set_alt_port(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_HealthCheck_set_reuse_connection(envoy_api_v2_core_HealthCheck *msg, struct google_protobuf_BoolValue* value) { + UPB_FIELD_AT(msg, struct google_protobuf_BoolValue*, UPB_SIZE(36, 72)) = value; +} +UPB_INLINE struct google_protobuf_BoolValue* envoy_api_v2_core_HealthCheck_mutable_reuse_connection(envoy_api_v2_core_HealthCheck *msg, upb_arena *arena) { + struct google_protobuf_BoolValue* sub = (struct google_protobuf_BoolValue*)envoy_api_v2_core_HealthCheck_reuse_connection(msg); + if (sub == NULL) { + sub = (struct google_protobuf_BoolValue*)upb_msg_new(&google_protobuf_BoolValue_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_HealthCheck_set_reuse_connection(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_HealthCheck_set_http_health_check(envoy_api_v2_core_HealthCheck *msg, envoy_api_v2_core_HealthCheck_HttpHealthCheck* value) { + UPB_WRITE_ONEOF(msg, envoy_api_v2_core_HealthCheck_HttpHealthCheck*, UPB_SIZE(56, 112), value, UPB_SIZE(60, 120), 8); +} +UPB_INLINE struct envoy_api_v2_core_HealthCheck_HttpHealthCheck* envoy_api_v2_core_HealthCheck_mutable_http_health_check(envoy_api_v2_core_HealthCheck *msg, upb_arena *arena) { + struct envoy_api_v2_core_HealthCheck_HttpHealthCheck* sub = (struct envoy_api_v2_core_HealthCheck_HttpHealthCheck*)envoy_api_v2_core_HealthCheck_http_health_check(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_HealthCheck_HttpHealthCheck*)upb_msg_new(&envoy_api_v2_core_HealthCheck_HttpHealthCheck_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_HealthCheck_set_http_health_check(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_HealthCheck_set_tcp_health_check(envoy_api_v2_core_HealthCheck *msg, envoy_api_v2_core_HealthCheck_TcpHealthCheck* value) { + UPB_WRITE_ONEOF(msg, envoy_api_v2_core_HealthCheck_TcpHealthCheck*, UPB_SIZE(56, 112), value, UPB_SIZE(60, 120), 9); +} +UPB_INLINE struct envoy_api_v2_core_HealthCheck_TcpHealthCheck* envoy_api_v2_core_HealthCheck_mutable_tcp_health_check(envoy_api_v2_core_HealthCheck *msg, upb_arena *arena) { + struct envoy_api_v2_core_HealthCheck_TcpHealthCheck* sub = (struct envoy_api_v2_core_HealthCheck_TcpHealthCheck*)envoy_api_v2_core_HealthCheck_tcp_health_check(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_HealthCheck_TcpHealthCheck*)upb_msg_new(&envoy_api_v2_core_HealthCheck_TcpHealthCheck_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_HealthCheck_set_tcp_health_check(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_HealthCheck_set_grpc_health_check(envoy_api_v2_core_HealthCheck *msg, envoy_api_v2_core_HealthCheck_GrpcHealthCheck* value) { + UPB_WRITE_ONEOF(msg, envoy_api_v2_core_HealthCheck_GrpcHealthCheck*, UPB_SIZE(56, 112), value, UPB_SIZE(60, 120), 11); +} +UPB_INLINE struct envoy_api_v2_core_HealthCheck_GrpcHealthCheck* envoy_api_v2_core_HealthCheck_mutable_grpc_health_check(envoy_api_v2_core_HealthCheck *msg, upb_arena *arena) { + struct envoy_api_v2_core_HealthCheck_GrpcHealthCheck* sub = (struct envoy_api_v2_core_HealthCheck_GrpcHealthCheck*)envoy_api_v2_core_HealthCheck_grpc_health_check(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_HealthCheck_GrpcHealthCheck*)upb_msg_new(&envoy_api_v2_core_HealthCheck_GrpcHealthCheck_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_HealthCheck_set_grpc_health_check(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_HealthCheck_set_no_traffic_interval(envoy_api_v2_core_HealthCheck *msg, struct google_protobuf_Duration* value) { + UPB_FIELD_AT(msg, struct google_protobuf_Duration*, UPB_SIZE(40, 80)) = value; +} +UPB_INLINE struct google_protobuf_Duration* envoy_api_v2_core_HealthCheck_mutable_no_traffic_interval(envoy_api_v2_core_HealthCheck *msg, upb_arena *arena) { + struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_api_v2_core_HealthCheck_no_traffic_interval(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Duration*)upb_msg_new(&google_protobuf_Duration_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_HealthCheck_set_no_traffic_interval(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_HealthCheck_set_custom_health_check(envoy_api_v2_core_HealthCheck *msg, envoy_api_v2_core_HealthCheck_CustomHealthCheck* value) { + UPB_WRITE_ONEOF(msg, envoy_api_v2_core_HealthCheck_CustomHealthCheck*, UPB_SIZE(56, 112), value, UPB_SIZE(60, 120), 13); +} +UPB_INLINE struct envoy_api_v2_core_HealthCheck_CustomHealthCheck* envoy_api_v2_core_HealthCheck_mutable_custom_health_check(envoy_api_v2_core_HealthCheck *msg, upb_arena *arena) { + struct envoy_api_v2_core_HealthCheck_CustomHealthCheck* sub = (struct envoy_api_v2_core_HealthCheck_CustomHealthCheck*)envoy_api_v2_core_HealthCheck_custom_health_check(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_HealthCheck_CustomHealthCheck*)upb_msg_new(&envoy_api_v2_core_HealthCheck_CustomHealthCheck_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_HealthCheck_set_custom_health_check(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_HealthCheck_set_unhealthy_interval(envoy_api_v2_core_HealthCheck *msg, struct google_protobuf_Duration* value) { + UPB_FIELD_AT(msg, struct google_protobuf_Duration*, UPB_SIZE(44, 88)) = value; +} +UPB_INLINE struct google_protobuf_Duration* envoy_api_v2_core_HealthCheck_mutable_unhealthy_interval(envoy_api_v2_core_HealthCheck *msg, upb_arena *arena) { + struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_api_v2_core_HealthCheck_unhealthy_interval(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Duration*)upb_msg_new(&google_protobuf_Duration_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_HealthCheck_set_unhealthy_interval(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_HealthCheck_set_unhealthy_edge_interval(envoy_api_v2_core_HealthCheck *msg, struct google_protobuf_Duration* value) { + UPB_FIELD_AT(msg, struct google_protobuf_Duration*, UPB_SIZE(48, 96)) = value; +} +UPB_INLINE struct google_protobuf_Duration* envoy_api_v2_core_HealthCheck_mutable_unhealthy_edge_interval(envoy_api_v2_core_HealthCheck *msg, upb_arena *arena) { + struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_api_v2_core_HealthCheck_unhealthy_edge_interval(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Duration*)upb_msg_new(&google_protobuf_Duration_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_HealthCheck_set_unhealthy_edge_interval(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_HealthCheck_set_healthy_edge_interval(envoy_api_v2_core_HealthCheck *msg, struct google_protobuf_Duration* value) { + UPB_FIELD_AT(msg, struct google_protobuf_Duration*, UPB_SIZE(52, 104)) = value; +} +UPB_INLINE struct google_protobuf_Duration* envoy_api_v2_core_HealthCheck_mutable_healthy_edge_interval(envoy_api_v2_core_HealthCheck *msg, upb_arena *arena) { + struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_api_v2_core_HealthCheck_healthy_edge_interval(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Duration*)upb_msg_new(&google_protobuf_Duration_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_HealthCheck_set_healthy_edge_interval(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_HealthCheck_set_event_log_path(envoy_api_v2_core_HealthCheck *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)) = value; +} +UPB_INLINE void envoy_api_v2_core_HealthCheck_set_interval_jitter_percent(envoy_api_v2_core_HealthCheck *msg, uint32_t value) { + UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(0, 0)) = value; +} + + +/* envoy.api.v2.core.HealthCheck.Payload */ + +UPB_INLINE envoy_api_v2_core_HealthCheck_Payload *envoy_api_v2_core_HealthCheck_Payload_new(upb_arena *arena) { + return (envoy_api_v2_core_HealthCheck_Payload *)upb_msg_new(&envoy_api_v2_core_HealthCheck_Payload_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_HealthCheck_Payload *envoy_api_v2_core_HealthCheck_Payload_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_HealthCheck_Payload *ret = envoy_api_v2_core_HealthCheck_Payload_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_HealthCheck_Payload_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_HealthCheck_Payload_serialize(const envoy_api_v2_core_HealthCheck_Payload *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_HealthCheck_Payload_msginit, arena, len); +} + +typedef enum { + envoy_api_v2_core_HealthCheck_Payload_payload_text = 1, + envoy_api_v2_core_HealthCheck_Payload_payload_binary = 2, + envoy_api_v2_core_HealthCheck_Payload_payload_NOT_SET = 0, +} envoy_api_v2_core_HealthCheck_Payload_payload_oneofcases; +UPB_INLINE envoy_api_v2_core_HealthCheck_Payload_payload_oneofcases envoy_api_v2_core_HealthCheck_Payload_payload_case(const envoy_api_v2_core_HealthCheck_Payload* msg) { return UPB_FIELD_AT(msg, int, UPB_SIZE(8, 16)); } + +UPB_INLINE bool envoy_api_v2_core_HealthCheck_Payload_has_text(const envoy_api_v2_core_HealthCheck_Payload *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(8, 16), 1); } +UPB_INLINE upb_strview envoy_api_v2_core_HealthCheck_Payload_text(const envoy_api_v2_core_HealthCheck_Payload *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 1, upb_strview_make("", strlen(""))); } +UPB_INLINE bool envoy_api_v2_core_HealthCheck_Payload_has_binary(const envoy_api_v2_core_HealthCheck_Payload *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(8, 16), 2); } +UPB_INLINE upb_strview envoy_api_v2_core_HealthCheck_Payload_binary(const envoy_api_v2_core_HealthCheck_Payload *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 2, upb_strview_make("", strlen(""))); } + +UPB_INLINE void envoy_api_v2_core_HealthCheck_Payload_set_text(envoy_api_v2_core_HealthCheck_Payload *msg, upb_strview value) { + UPB_WRITE_ONEOF(msg, upb_strview, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), 1); +} +UPB_INLINE void envoy_api_v2_core_HealthCheck_Payload_set_binary(envoy_api_v2_core_HealthCheck_Payload *msg, upb_strview value) { + UPB_WRITE_ONEOF(msg, upb_strview, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), 2); +} + + +/* envoy.api.v2.core.HealthCheck.HttpHealthCheck */ + +UPB_INLINE envoy_api_v2_core_HealthCheck_HttpHealthCheck *envoy_api_v2_core_HealthCheck_HttpHealthCheck_new(upb_arena *arena) { + return (envoy_api_v2_core_HealthCheck_HttpHealthCheck *)upb_msg_new(&envoy_api_v2_core_HealthCheck_HttpHealthCheck_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_HealthCheck_HttpHealthCheck *envoy_api_v2_core_HealthCheck_HttpHealthCheck_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_HealthCheck_HttpHealthCheck *ret = envoy_api_v2_core_HealthCheck_HttpHealthCheck_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_HealthCheck_HttpHealthCheck_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_HealthCheck_HttpHealthCheck_serialize(const envoy_api_v2_core_HealthCheck_HttpHealthCheck *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_HealthCheck_HttpHealthCheck_msginit, arena, len); +} + +UPB_INLINE upb_strview envoy_api_v2_core_HealthCheck_HttpHealthCheck_host(const envoy_api_v2_core_HealthCheck_HttpHealthCheck *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)); } +UPB_INLINE upb_strview envoy_api_v2_core_HealthCheck_HttpHealthCheck_path(const envoy_api_v2_core_HealthCheck_HttpHealthCheck *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(12, 24)); } +UPB_INLINE const envoy_api_v2_core_HealthCheck_Payload* envoy_api_v2_core_HealthCheck_HttpHealthCheck_send(const envoy_api_v2_core_HealthCheck_HttpHealthCheck *msg) { return UPB_FIELD_AT(msg, const envoy_api_v2_core_HealthCheck_Payload*, UPB_SIZE(28, 56)); } +UPB_INLINE const envoy_api_v2_core_HealthCheck_Payload* envoy_api_v2_core_HealthCheck_HttpHealthCheck_receive(const envoy_api_v2_core_HealthCheck_HttpHealthCheck *msg) { return UPB_FIELD_AT(msg, const envoy_api_v2_core_HealthCheck_Payload*, UPB_SIZE(32, 64)); } +UPB_INLINE upb_strview envoy_api_v2_core_HealthCheck_HttpHealthCheck_service_name(const envoy_api_v2_core_HealthCheck_HttpHealthCheck *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(20, 40)); } +UPB_INLINE const struct envoy_api_v2_core_HeaderValueOption* const* envoy_api_v2_core_HealthCheck_HttpHealthCheck_request_headers_to_add(const envoy_api_v2_core_HealthCheck_HttpHealthCheck *msg, size_t *len) { return (const struct envoy_api_v2_core_HeaderValueOption* const*)_upb_array_accessor(msg, UPB_SIZE(36, 72), len); } +UPB_INLINE bool envoy_api_v2_core_HealthCheck_HttpHealthCheck_use_http2(const envoy_api_v2_core_HealthCheck_HttpHealthCheck *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(0, 0)); } +UPB_INLINE upb_strview const* envoy_api_v2_core_HealthCheck_HttpHealthCheck_request_headers_to_remove(const envoy_api_v2_core_HealthCheck_HttpHealthCheck *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(40, 80), len); } + +UPB_INLINE void envoy_api_v2_core_HealthCheck_HttpHealthCheck_set_host(envoy_api_v2_core_HealthCheck_HttpHealthCheck *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)) = value; +} +UPB_INLINE void envoy_api_v2_core_HealthCheck_HttpHealthCheck_set_path(envoy_api_v2_core_HealthCheck_HttpHealthCheck *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(12, 24)) = value; +} +UPB_INLINE void envoy_api_v2_core_HealthCheck_HttpHealthCheck_set_send(envoy_api_v2_core_HealthCheck_HttpHealthCheck *msg, envoy_api_v2_core_HealthCheck_Payload* value) { + UPB_FIELD_AT(msg, envoy_api_v2_core_HealthCheck_Payload*, UPB_SIZE(28, 56)) = value; +} +UPB_INLINE struct envoy_api_v2_core_HealthCheck_Payload* envoy_api_v2_core_HealthCheck_HttpHealthCheck_mutable_send(envoy_api_v2_core_HealthCheck_HttpHealthCheck *msg, upb_arena *arena) { + struct envoy_api_v2_core_HealthCheck_Payload* sub = (struct envoy_api_v2_core_HealthCheck_Payload*)envoy_api_v2_core_HealthCheck_HttpHealthCheck_send(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_HealthCheck_Payload*)upb_msg_new(&envoy_api_v2_core_HealthCheck_Payload_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_HealthCheck_HttpHealthCheck_set_send(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_HealthCheck_HttpHealthCheck_set_receive(envoy_api_v2_core_HealthCheck_HttpHealthCheck *msg, envoy_api_v2_core_HealthCheck_Payload* value) { + UPB_FIELD_AT(msg, envoy_api_v2_core_HealthCheck_Payload*, UPB_SIZE(32, 64)) = value; +} +UPB_INLINE struct envoy_api_v2_core_HealthCheck_Payload* envoy_api_v2_core_HealthCheck_HttpHealthCheck_mutable_receive(envoy_api_v2_core_HealthCheck_HttpHealthCheck *msg, upb_arena *arena) { + struct envoy_api_v2_core_HealthCheck_Payload* sub = (struct envoy_api_v2_core_HealthCheck_Payload*)envoy_api_v2_core_HealthCheck_HttpHealthCheck_receive(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_HealthCheck_Payload*)upb_msg_new(&envoy_api_v2_core_HealthCheck_Payload_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_HealthCheck_HttpHealthCheck_set_receive(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_HealthCheck_HttpHealthCheck_set_service_name(envoy_api_v2_core_HealthCheck_HttpHealthCheck *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(20, 40)) = value; +} +UPB_INLINE struct envoy_api_v2_core_HeaderValueOption** envoy_api_v2_core_HealthCheck_HttpHealthCheck_mutable_request_headers_to_add(envoy_api_v2_core_HealthCheck_HttpHealthCheck *msg, size_t *len) { + return (struct envoy_api_v2_core_HeaderValueOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(36, 72), len); +} +UPB_INLINE struct envoy_api_v2_core_HeaderValueOption** envoy_api_v2_core_HealthCheck_HttpHealthCheck_resize_request_headers_to_add(envoy_api_v2_core_HealthCheck_HttpHealthCheck *msg, size_t len, upb_arena *arena) { + return (struct envoy_api_v2_core_HeaderValueOption**)_upb_array_resize_accessor(msg, UPB_SIZE(36, 72), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct envoy_api_v2_core_HeaderValueOption* envoy_api_v2_core_HealthCheck_HttpHealthCheck_add_request_headers_to_add(envoy_api_v2_core_HealthCheck_HttpHealthCheck *msg, upb_arena *arena) { + struct envoy_api_v2_core_HeaderValueOption* sub = (struct envoy_api_v2_core_HeaderValueOption*)upb_msg_new(&envoy_api_v2_core_HeaderValueOption_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(36, 72), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE void envoy_api_v2_core_HealthCheck_HttpHealthCheck_set_use_http2(envoy_api_v2_core_HealthCheck_HttpHealthCheck *msg, bool value) { + UPB_FIELD_AT(msg, bool, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE upb_strview* envoy_api_v2_core_HealthCheck_HttpHealthCheck_mutable_request_headers_to_remove(envoy_api_v2_core_HealthCheck_HttpHealthCheck *msg, size_t *len) { + return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(40, 80), len); +} +UPB_INLINE upb_strview* envoy_api_v2_core_HealthCheck_HttpHealthCheck_resize_request_headers_to_remove(envoy_api_v2_core_HealthCheck_HttpHealthCheck *msg, size_t len, upb_arena *arena) { + return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(40, 80), len, UPB_SIZE(8, 16), UPB_TYPE_STRING, arena); +} +UPB_INLINE bool envoy_api_v2_core_HealthCheck_HttpHealthCheck_add_request_headers_to_remove(envoy_api_v2_core_HealthCheck_HttpHealthCheck *msg, upb_strview val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(40, 80), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, arena); +} + + +/* envoy.api.v2.core.HealthCheck.TcpHealthCheck */ + +UPB_INLINE envoy_api_v2_core_HealthCheck_TcpHealthCheck *envoy_api_v2_core_HealthCheck_TcpHealthCheck_new(upb_arena *arena) { + return (envoy_api_v2_core_HealthCheck_TcpHealthCheck *)upb_msg_new(&envoy_api_v2_core_HealthCheck_TcpHealthCheck_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_HealthCheck_TcpHealthCheck *envoy_api_v2_core_HealthCheck_TcpHealthCheck_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_HealthCheck_TcpHealthCheck *ret = envoy_api_v2_core_HealthCheck_TcpHealthCheck_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_HealthCheck_TcpHealthCheck_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_HealthCheck_TcpHealthCheck_serialize(const envoy_api_v2_core_HealthCheck_TcpHealthCheck *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_HealthCheck_TcpHealthCheck_msginit, arena, len); +} + +UPB_INLINE const envoy_api_v2_core_HealthCheck_Payload* envoy_api_v2_core_HealthCheck_TcpHealthCheck_send(const envoy_api_v2_core_HealthCheck_TcpHealthCheck *msg) { return UPB_FIELD_AT(msg, const envoy_api_v2_core_HealthCheck_Payload*, UPB_SIZE(0, 0)); } +UPB_INLINE const envoy_api_v2_core_HealthCheck_Payload* const* envoy_api_v2_core_HealthCheck_TcpHealthCheck_receive(const envoy_api_v2_core_HealthCheck_TcpHealthCheck *msg, size_t *len) { return (const envoy_api_v2_core_HealthCheck_Payload* const*)_upb_array_accessor(msg, UPB_SIZE(4, 8), len); } + +UPB_INLINE void envoy_api_v2_core_HealthCheck_TcpHealthCheck_set_send(envoy_api_v2_core_HealthCheck_TcpHealthCheck *msg, envoy_api_v2_core_HealthCheck_Payload* value) { + UPB_FIELD_AT(msg, envoy_api_v2_core_HealthCheck_Payload*, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE struct envoy_api_v2_core_HealthCheck_Payload* envoy_api_v2_core_HealthCheck_TcpHealthCheck_mutable_send(envoy_api_v2_core_HealthCheck_TcpHealthCheck *msg, upb_arena *arena) { + struct envoy_api_v2_core_HealthCheck_Payload* sub = (struct envoy_api_v2_core_HealthCheck_Payload*)envoy_api_v2_core_HealthCheck_TcpHealthCheck_send(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_HealthCheck_Payload*)upb_msg_new(&envoy_api_v2_core_HealthCheck_Payload_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_HealthCheck_TcpHealthCheck_set_send(msg, sub); + } + return sub; +} +UPB_INLINE envoy_api_v2_core_HealthCheck_Payload** envoy_api_v2_core_HealthCheck_TcpHealthCheck_mutable_receive(envoy_api_v2_core_HealthCheck_TcpHealthCheck *msg, size_t *len) { + return (envoy_api_v2_core_HealthCheck_Payload**)_upb_array_mutable_accessor(msg, UPB_SIZE(4, 8), len); +} +UPB_INLINE envoy_api_v2_core_HealthCheck_Payload** envoy_api_v2_core_HealthCheck_TcpHealthCheck_resize_receive(envoy_api_v2_core_HealthCheck_TcpHealthCheck *msg, size_t len, upb_arena *arena) { + return (envoy_api_v2_core_HealthCheck_Payload**)_upb_array_resize_accessor(msg, UPB_SIZE(4, 8), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct envoy_api_v2_core_HealthCheck_Payload* envoy_api_v2_core_HealthCheck_TcpHealthCheck_add_receive(envoy_api_v2_core_HealthCheck_TcpHealthCheck *msg, upb_arena *arena) { + struct envoy_api_v2_core_HealthCheck_Payload* sub = (struct envoy_api_v2_core_HealthCheck_Payload*)upb_msg_new(&envoy_api_v2_core_HealthCheck_Payload_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(4, 8), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} + + +/* envoy.api.v2.core.HealthCheck.RedisHealthCheck */ + +UPB_INLINE envoy_api_v2_core_HealthCheck_RedisHealthCheck *envoy_api_v2_core_HealthCheck_RedisHealthCheck_new(upb_arena *arena) { + return (envoy_api_v2_core_HealthCheck_RedisHealthCheck *)upb_msg_new(&envoy_api_v2_core_HealthCheck_RedisHealthCheck_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_HealthCheck_RedisHealthCheck *envoy_api_v2_core_HealthCheck_RedisHealthCheck_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_HealthCheck_RedisHealthCheck *ret = envoy_api_v2_core_HealthCheck_RedisHealthCheck_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_HealthCheck_RedisHealthCheck_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_HealthCheck_RedisHealthCheck_serialize(const envoy_api_v2_core_HealthCheck_RedisHealthCheck *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_HealthCheck_RedisHealthCheck_msginit, arena, len); +} + +UPB_INLINE upb_strview envoy_api_v2_core_HealthCheck_RedisHealthCheck_key(const envoy_api_v2_core_HealthCheck_RedisHealthCheck *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } + +UPB_INLINE void envoy_api_v2_core_HealthCheck_RedisHealthCheck_set_key(envoy_api_v2_core_HealthCheck_RedisHealthCheck *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} + + +/* envoy.api.v2.core.HealthCheck.GrpcHealthCheck */ + +UPB_INLINE envoy_api_v2_core_HealthCheck_GrpcHealthCheck *envoy_api_v2_core_HealthCheck_GrpcHealthCheck_new(upb_arena *arena) { + return (envoy_api_v2_core_HealthCheck_GrpcHealthCheck *)upb_msg_new(&envoy_api_v2_core_HealthCheck_GrpcHealthCheck_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_HealthCheck_GrpcHealthCheck *envoy_api_v2_core_HealthCheck_GrpcHealthCheck_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_HealthCheck_GrpcHealthCheck *ret = envoy_api_v2_core_HealthCheck_GrpcHealthCheck_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_HealthCheck_GrpcHealthCheck_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_HealthCheck_GrpcHealthCheck_serialize(const envoy_api_v2_core_HealthCheck_GrpcHealthCheck *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_HealthCheck_GrpcHealthCheck_msginit, arena, len); +} + +UPB_INLINE upb_strview envoy_api_v2_core_HealthCheck_GrpcHealthCheck_service_name(const envoy_api_v2_core_HealthCheck_GrpcHealthCheck *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } + +UPB_INLINE void envoy_api_v2_core_HealthCheck_GrpcHealthCheck_set_service_name(envoy_api_v2_core_HealthCheck_GrpcHealthCheck *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} + + +/* envoy.api.v2.core.HealthCheck.CustomHealthCheck */ + +UPB_INLINE envoy_api_v2_core_HealthCheck_CustomHealthCheck *envoy_api_v2_core_HealthCheck_CustomHealthCheck_new(upb_arena *arena) { + return (envoy_api_v2_core_HealthCheck_CustomHealthCheck *)upb_msg_new(&envoy_api_v2_core_HealthCheck_CustomHealthCheck_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_HealthCheck_CustomHealthCheck *envoy_api_v2_core_HealthCheck_CustomHealthCheck_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_HealthCheck_CustomHealthCheck *ret = envoy_api_v2_core_HealthCheck_CustomHealthCheck_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_HealthCheck_CustomHealthCheck_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_HealthCheck_CustomHealthCheck_serialize(const envoy_api_v2_core_HealthCheck_CustomHealthCheck *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_HealthCheck_CustomHealthCheck_msginit, arena, len); +} + +typedef enum { + envoy_api_v2_core_HealthCheck_CustomHealthCheck_config_type_config = 2, + envoy_api_v2_core_HealthCheck_CustomHealthCheck_config_type_typed_config = 3, + envoy_api_v2_core_HealthCheck_CustomHealthCheck_config_type_NOT_SET = 0, +} envoy_api_v2_core_HealthCheck_CustomHealthCheck_config_type_oneofcases; +UPB_INLINE envoy_api_v2_core_HealthCheck_CustomHealthCheck_config_type_oneofcases envoy_api_v2_core_HealthCheck_CustomHealthCheck_config_type_case(const envoy_api_v2_core_HealthCheck_CustomHealthCheck* msg) { return UPB_FIELD_AT(msg, int, UPB_SIZE(12, 24)); } + +UPB_INLINE upb_strview envoy_api_v2_core_HealthCheck_CustomHealthCheck_name(const envoy_api_v2_core_HealthCheck_CustomHealthCheck *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } +UPB_INLINE bool envoy_api_v2_core_HealthCheck_CustomHealthCheck_has_config(const envoy_api_v2_core_HealthCheck_CustomHealthCheck *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(12, 24), 2); } +UPB_INLINE const struct google_protobuf_Struct* envoy_api_v2_core_HealthCheck_CustomHealthCheck_config(const envoy_api_v2_core_HealthCheck_CustomHealthCheck *msg) { return UPB_READ_ONEOF(msg, const struct google_protobuf_Struct*, UPB_SIZE(8, 16), UPB_SIZE(12, 24), 2, NULL); } +UPB_INLINE bool envoy_api_v2_core_HealthCheck_CustomHealthCheck_has_typed_config(const envoy_api_v2_core_HealthCheck_CustomHealthCheck *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(12, 24), 3); } +UPB_INLINE const struct google_protobuf_Any* envoy_api_v2_core_HealthCheck_CustomHealthCheck_typed_config(const envoy_api_v2_core_HealthCheck_CustomHealthCheck *msg) { return UPB_READ_ONEOF(msg, const struct google_protobuf_Any*, UPB_SIZE(8, 16), UPB_SIZE(12, 24), 3, NULL); } + +UPB_INLINE void envoy_api_v2_core_HealthCheck_CustomHealthCheck_set_name(envoy_api_v2_core_HealthCheck_CustomHealthCheck *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_api_v2_core_HealthCheck_CustomHealthCheck_set_config(envoy_api_v2_core_HealthCheck_CustomHealthCheck *msg, struct google_protobuf_Struct* value) { + UPB_WRITE_ONEOF(msg, struct google_protobuf_Struct*, UPB_SIZE(8, 16), value, UPB_SIZE(12, 24), 2); +} +UPB_INLINE struct google_protobuf_Struct* envoy_api_v2_core_HealthCheck_CustomHealthCheck_mutable_config(envoy_api_v2_core_HealthCheck_CustomHealthCheck *msg, upb_arena *arena) { + struct google_protobuf_Struct* sub = (struct google_protobuf_Struct*)envoy_api_v2_core_HealthCheck_CustomHealthCheck_config(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Struct*)upb_msg_new(&google_protobuf_Struct_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_HealthCheck_CustomHealthCheck_set_config(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_HealthCheck_CustomHealthCheck_set_typed_config(envoy_api_v2_core_HealthCheck_CustomHealthCheck *msg, struct google_protobuf_Any* value) { + UPB_WRITE_ONEOF(msg, struct google_protobuf_Any*, UPB_SIZE(8, 16), value, UPB_SIZE(12, 24), 3); +} +UPB_INLINE struct google_protobuf_Any* envoy_api_v2_core_HealthCheck_CustomHealthCheck_mutable_typed_config(envoy_api_v2_core_HealthCheck_CustomHealthCheck *msg, upb_arena *arena) { + struct google_protobuf_Any* sub = (struct google_protobuf_Any*)envoy_api_v2_core_HealthCheck_CustomHealthCheck_typed_config(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Any*)upb_msg_new(&google_protobuf_Any_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_HealthCheck_CustomHealthCheck_set_typed_config(msg, sub); + } + return sub; +} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* ENVOY_API_V2_CORE_HEALTH_CHECK_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/envoy/api/v2/core/protocol.upb.c b/src/core/ext/upb-generated/envoy/api/v2/core/protocol.upb.c new file mode 100644 index 00000000000..fa8855d20b9 --- /dev/null +++ b/src/core/ext/upb-generated/envoy/api/v2/core/protocol.upb.c @@ -0,0 +1,88 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/api/v2/core/protocol.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include +#include "upb/msg.h" +#include "envoy/api/v2/core/protocol.upb.h" +#include "google/protobuf/duration.upb.h" +#include "google/protobuf/wrappers.upb.h" +#include "validate/validate.upb.h" +#include "gogoproto/gogo.upb.h" + +#include "upb/port_def.inc" + +const upb_msglayout envoy_api_v2_core_TcpProtocolOptions_msginit = { + NULL, + NULL, + UPB_SIZE(0, 0), 0, false, +}; + +static const upb_msglayout *const envoy_api_v2_core_HttpProtocolOptions_submsgs[1] = { + &google_protobuf_Duration_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_core_HttpProtocolOptions__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_core_HttpProtocolOptions_msginit = { + &envoy_api_v2_core_HttpProtocolOptions_submsgs[0], + &envoy_api_v2_core_HttpProtocolOptions__fields[0], + UPB_SIZE(4, 8), 1, false, +}; + +static const upb_msglayout *const envoy_api_v2_core_Http1ProtocolOptions_submsgs[1] = { + &google_protobuf_BoolValue_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_core_Http1ProtocolOptions__fields[3] = { + {1, UPB_SIZE(12, 24), 0, 0, 11, 1}, + {2, UPB_SIZE(0, 0), 0, 0, 8, 1}, + {3, UPB_SIZE(4, 8), 0, 0, 9, 1}, +}; + +const upb_msglayout envoy_api_v2_core_Http1ProtocolOptions_msginit = { + &envoy_api_v2_core_Http1ProtocolOptions_submsgs[0], + &envoy_api_v2_core_Http1ProtocolOptions__fields[0], + UPB_SIZE(16, 32), 3, false, +}; + +static const upb_msglayout *const envoy_api_v2_core_Http2ProtocolOptions_submsgs[4] = { + &google_protobuf_UInt32Value_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_core_Http2ProtocolOptions__fields[5] = { + {1, UPB_SIZE(4, 8), 0, 0, 11, 1}, + {2, UPB_SIZE(8, 16), 0, 0, 11, 1}, + {3, UPB_SIZE(12, 24), 0, 0, 11, 1}, + {4, UPB_SIZE(16, 32), 0, 0, 11, 1}, + {5, UPB_SIZE(0, 0), 0, 0, 8, 1}, +}; + +const upb_msglayout envoy_api_v2_core_Http2ProtocolOptions_msginit = { + &envoy_api_v2_core_Http2ProtocolOptions_submsgs[0], + &envoy_api_v2_core_Http2ProtocolOptions__fields[0], + UPB_SIZE(20, 40), 5, false, +}; + +static const upb_msglayout *const envoy_api_v2_core_GrpcProtocolOptions_submsgs[1] = { + &envoy_api_v2_core_Http2ProtocolOptions_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_core_GrpcProtocolOptions__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_core_GrpcProtocolOptions_msginit = { + &envoy_api_v2_core_GrpcProtocolOptions_submsgs[0], + &envoy_api_v2_core_GrpcProtocolOptions__fields[0], + UPB_SIZE(4, 8), 1, false, +}; + +#include "upb/port_undef.inc" + diff --git a/src/core/ext/upb-generated/envoy/api/v2/core/protocol.upb.h b/src/core/ext/upb-generated/envoy/api/v2/core/protocol.upb.h new file mode 100644 index 00000000000..db352e43d87 --- /dev/null +++ b/src/core/ext/upb-generated/envoy/api/v2/core/protocol.upb.h @@ -0,0 +1,237 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/api/v2/core/protocol.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef ENVOY_API_V2_CORE_PROTOCOL_PROTO_UPB_H_ +#define ENVOY_API_V2_CORE_PROTOCOL_PROTO_UPB_H_ + +#include "upb/generated_util.h" + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +#ifdef __cplusplus +extern "C" { +#endif + +struct envoy_api_v2_core_TcpProtocolOptions; +struct envoy_api_v2_core_HttpProtocolOptions; +struct envoy_api_v2_core_Http1ProtocolOptions; +struct envoy_api_v2_core_Http2ProtocolOptions; +struct envoy_api_v2_core_GrpcProtocolOptions; +typedef struct envoy_api_v2_core_TcpProtocolOptions envoy_api_v2_core_TcpProtocolOptions; +typedef struct envoy_api_v2_core_HttpProtocolOptions envoy_api_v2_core_HttpProtocolOptions; +typedef struct envoy_api_v2_core_Http1ProtocolOptions envoy_api_v2_core_Http1ProtocolOptions; +typedef struct envoy_api_v2_core_Http2ProtocolOptions envoy_api_v2_core_Http2ProtocolOptions; +typedef struct envoy_api_v2_core_GrpcProtocolOptions envoy_api_v2_core_GrpcProtocolOptions; +extern const upb_msglayout envoy_api_v2_core_TcpProtocolOptions_msginit; +extern const upb_msglayout envoy_api_v2_core_HttpProtocolOptions_msginit; +extern const upb_msglayout envoy_api_v2_core_Http1ProtocolOptions_msginit; +extern const upb_msglayout envoy_api_v2_core_Http2ProtocolOptions_msginit; +extern const upb_msglayout envoy_api_v2_core_GrpcProtocolOptions_msginit; +struct google_protobuf_BoolValue; +struct google_protobuf_Duration; +struct google_protobuf_UInt32Value; +extern const upb_msglayout google_protobuf_BoolValue_msginit; +extern const upb_msglayout google_protobuf_Duration_msginit; +extern const upb_msglayout google_protobuf_UInt32Value_msginit; + +/* Enums */ + + +/* envoy.api.v2.core.TcpProtocolOptions */ + +UPB_INLINE envoy_api_v2_core_TcpProtocolOptions *envoy_api_v2_core_TcpProtocolOptions_new(upb_arena *arena) { + return (envoy_api_v2_core_TcpProtocolOptions *)upb_msg_new(&envoy_api_v2_core_TcpProtocolOptions_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_TcpProtocolOptions *envoy_api_v2_core_TcpProtocolOptions_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_TcpProtocolOptions *ret = envoy_api_v2_core_TcpProtocolOptions_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_TcpProtocolOptions_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_TcpProtocolOptions_serialize(const envoy_api_v2_core_TcpProtocolOptions *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_TcpProtocolOptions_msginit, arena, len); +} + + + + +/* envoy.api.v2.core.HttpProtocolOptions */ + +UPB_INLINE envoy_api_v2_core_HttpProtocolOptions *envoy_api_v2_core_HttpProtocolOptions_new(upb_arena *arena) { + return (envoy_api_v2_core_HttpProtocolOptions *)upb_msg_new(&envoy_api_v2_core_HttpProtocolOptions_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_HttpProtocolOptions *envoy_api_v2_core_HttpProtocolOptions_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_HttpProtocolOptions *ret = envoy_api_v2_core_HttpProtocolOptions_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_HttpProtocolOptions_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_HttpProtocolOptions_serialize(const envoy_api_v2_core_HttpProtocolOptions *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_HttpProtocolOptions_msginit, arena, len); +} + +UPB_INLINE const struct google_protobuf_Duration* envoy_api_v2_core_HttpProtocolOptions_idle_timeout(const envoy_api_v2_core_HttpProtocolOptions *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Duration*, UPB_SIZE(0, 0)); } + +UPB_INLINE void envoy_api_v2_core_HttpProtocolOptions_set_idle_timeout(envoy_api_v2_core_HttpProtocolOptions *msg, struct google_protobuf_Duration* value) { + UPB_FIELD_AT(msg, struct google_protobuf_Duration*, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE struct google_protobuf_Duration* envoy_api_v2_core_HttpProtocolOptions_mutable_idle_timeout(envoy_api_v2_core_HttpProtocolOptions *msg, upb_arena *arena) { + struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_api_v2_core_HttpProtocolOptions_idle_timeout(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Duration*)upb_msg_new(&google_protobuf_Duration_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_HttpProtocolOptions_set_idle_timeout(msg, sub); + } + return sub; +} + + +/* envoy.api.v2.core.Http1ProtocolOptions */ + +UPB_INLINE envoy_api_v2_core_Http1ProtocolOptions *envoy_api_v2_core_Http1ProtocolOptions_new(upb_arena *arena) { + return (envoy_api_v2_core_Http1ProtocolOptions *)upb_msg_new(&envoy_api_v2_core_Http1ProtocolOptions_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_Http1ProtocolOptions *envoy_api_v2_core_Http1ProtocolOptions_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_Http1ProtocolOptions *ret = envoy_api_v2_core_Http1ProtocolOptions_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_Http1ProtocolOptions_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_Http1ProtocolOptions_serialize(const envoy_api_v2_core_Http1ProtocolOptions *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_Http1ProtocolOptions_msginit, arena, len); +} + +UPB_INLINE const struct google_protobuf_BoolValue* envoy_api_v2_core_Http1ProtocolOptions_allow_absolute_url(const envoy_api_v2_core_Http1ProtocolOptions *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_BoolValue*, UPB_SIZE(12, 24)); } +UPB_INLINE bool envoy_api_v2_core_Http1ProtocolOptions_accept_http_10(const envoy_api_v2_core_Http1ProtocolOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(0, 0)); } +UPB_INLINE upb_strview envoy_api_v2_core_Http1ProtocolOptions_default_host_for_http_10(const envoy_api_v2_core_Http1ProtocolOptions *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)); } + +UPB_INLINE void envoy_api_v2_core_Http1ProtocolOptions_set_allow_absolute_url(envoy_api_v2_core_Http1ProtocolOptions *msg, struct google_protobuf_BoolValue* value) { + UPB_FIELD_AT(msg, struct google_protobuf_BoolValue*, UPB_SIZE(12, 24)) = value; +} +UPB_INLINE struct google_protobuf_BoolValue* envoy_api_v2_core_Http1ProtocolOptions_mutable_allow_absolute_url(envoy_api_v2_core_Http1ProtocolOptions *msg, upb_arena *arena) { + struct google_protobuf_BoolValue* sub = (struct google_protobuf_BoolValue*)envoy_api_v2_core_Http1ProtocolOptions_allow_absolute_url(msg); + if (sub == NULL) { + sub = (struct google_protobuf_BoolValue*)upb_msg_new(&google_protobuf_BoolValue_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_Http1ProtocolOptions_set_allow_absolute_url(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_Http1ProtocolOptions_set_accept_http_10(envoy_api_v2_core_Http1ProtocolOptions *msg, bool value) { + UPB_FIELD_AT(msg, bool, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_api_v2_core_Http1ProtocolOptions_set_default_host_for_http_10(envoy_api_v2_core_Http1ProtocolOptions *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)) = value; +} + + +/* envoy.api.v2.core.Http2ProtocolOptions */ + +UPB_INLINE envoy_api_v2_core_Http2ProtocolOptions *envoy_api_v2_core_Http2ProtocolOptions_new(upb_arena *arena) { + return (envoy_api_v2_core_Http2ProtocolOptions *)upb_msg_new(&envoy_api_v2_core_Http2ProtocolOptions_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_Http2ProtocolOptions *envoy_api_v2_core_Http2ProtocolOptions_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_Http2ProtocolOptions *ret = envoy_api_v2_core_Http2ProtocolOptions_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_Http2ProtocolOptions_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_Http2ProtocolOptions_serialize(const envoy_api_v2_core_Http2ProtocolOptions *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_Http2ProtocolOptions_msginit, arena, len); +} + +UPB_INLINE const struct google_protobuf_UInt32Value* envoy_api_v2_core_Http2ProtocolOptions_hpack_table_size(const envoy_api_v2_core_Http2ProtocolOptions *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt32Value*, UPB_SIZE(4, 8)); } +UPB_INLINE const struct google_protobuf_UInt32Value* envoy_api_v2_core_Http2ProtocolOptions_max_concurrent_streams(const envoy_api_v2_core_Http2ProtocolOptions *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt32Value*, UPB_SIZE(8, 16)); } +UPB_INLINE const struct google_protobuf_UInt32Value* envoy_api_v2_core_Http2ProtocolOptions_initial_stream_window_size(const envoy_api_v2_core_Http2ProtocolOptions *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt32Value*, UPB_SIZE(12, 24)); } +UPB_INLINE const struct google_protobuf_UInt32Value* envoy_api_v2_core_Http2ProtocolOptions_initial_connection_window_size(const envoy_api_v2_core_Http2ProtocolOptions *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt32Value*, UPB_SIZE(16, 32)); } +UPB_INLINE bool envoy_api_v2_core_Http2ProtocolOptions_allow_connect(const envoy_api_v2_core_Http2ProtocolOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(0, 0)); } + +UPB_INLINE void envoy_api_v2_core_Http2ProtocolOptions_set_hpack_table_size(envoy_api_v2_core_Http2ProtocolOptions *msg, struct google_protobuf_UInt32Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt32Value*, UPB_SIZE(4, 8)) = value; +} +UPB_INLINE struct google_protobuf_UInt32Value* envoy_api_v2_core_Http2ProtocolOptions_mutable_hpack_table_size(envoy_api_v2_core_Http2ProtocolOptions *msg, upb_arena *arena) { + struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_api_v2_core_Http2ProtocolOptions_hpack_table_size(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt32Value*)upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_Http2ProtocolOptions_set_hpack_table_size(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_Http2ProtocolOptions_set_max_concurrent_streams(envoy_api_v2_core_Http2ProtocolOptions *msg, struct google_protobuf_UInt32Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt32Value*, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE struct google_protobuf_UInt32Value* envoy_api_v2_core_Http2ProtocolOptions_mutable_max_concurrent_streams(envoy_api_v2_core_Http2ProtocolOptions *msg, upb_arena *arena) { + struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_api_v2_core_Http2ProtocolOptions_max_concurrent_streams(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt32Value*)upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_Http2ProtocolOptions_set_max_concurrent_streams(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_Http2ProtocolOptions_set_initial_stream_window_size(envoy_api_v2_core_Http2ProtocolOptions *msg, struct google_protobuf_UInt32Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt32Value*, UPB_SIZE(12, 24)) = value; +} +UPB_INLINE struct google_protobuf_UInt32Value* envoy_api_v2_core_Http2ProtocolOptions_mutable_initial_stream_window_size(envoy_api_v2_core_Http2ProtocolOptions *msg, upb_arena *arena) { + struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_api_v2_core_Http2ProtocolOptions_initial_stream_window_size(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt32Value*)upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_Http2ProtocolOptions_set_initial_stream_window_size(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_Http2ProtocolOptions_set_initial_connection_window_size(envoy_api_v2_core_Http2ProtocolOptions *msg, struct google_protobuf_UInt32Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt32Value*, UPB_SIZE(16, 32)) = value; +} +UPB_INLINE struct google_protobuf_UInt32Value* envoy_api_v2_core_Http2ProtocolOptions_mutable_initial_connection_window_size(envoy_api_v2_core_Http2ProtocolOptions *msg, upb_arena *arena) { + struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_api_v2_core_Http2ProtocolOptions_initial_connection_window_size(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt32Value*)upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_Http2ProtocolOptions_set_initial_connection_window_size(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_Http2ProtocolOptions_set_allow_connect(envoy_api_v2_core_Http2ProtocolOptions *msg, bool value) { + UPB_FIELD_AT(msg, bool, UPB_SIZE(0, 0)) = value; +} + + +/* envoy.api.v2.core.GrpcProtocolOptions */ + +UPB_INLINE envoy_api_v2_core_GrpcProtocolOptions *envoy_api_v2_core_GrpcProtocolOptions_new(upb_arena *arena) { + return (envoy_api_v2_core_GrpcProtocolOptions *)upb_msg_new(&envoy_api_v2_core_GrpcProtocolOptions_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_GrpcProtocolOptions *envoy_api_v2_core_GrpcProtocolOptions_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_GrpcProtocolOptions *ret = envoy_api_v2_core_GrpcProtocolOptions_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_GrpcProtocolOptions_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_GrpcProtocolOptions_serialize(const envoy_api_v2_core_GrpcProtocolOptions *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_GrpcProtocolOptions_msginit, arena, len); +} + +UPB_INLINE const envoy_api_v2_core_Http2ProtocolOptions* envoy_api_v2_core_GrpcProtocolOptions_http2_protocol_options(const envoy_api_v2_core_GrpcProtocolOptions *msg) { return UPB_FIELD_AT(msg, const envoy_api_v2_core_Http2ProtocolOptions*, UPB_SIZE(0, 0)); } + +UPB_INLINE void envoy_api_v2_core_GrpcProtocolOptions_set_http2_protocol_options(envoy_api_v2_core_GrpcProtocolOptions *msg, envoy_api_v2_core_Http2ProtocolOptions* value) { + UPB_FIELD_AT(msg, envoy_api_v2_core_Http2ProtocolOptions*, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE struct envoy_api_v2_core_Http2ProtocolOptions* envoy_api_v2_core_GrpcProtocolOptions_mutable_http2_protocol_options(envoy_api_v2_core_GrpcProtocolOptions *msg, upb_arena *arena) { + struct envoy_api_v2_core_Http2ProtocolOptions* sub = (struct envoy_api_v2_core_Http2ProtocolOptions*)envoy_api_v2_core_GrpcProtocolOptions_http2_protocol_options(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_Http2ProtocolOptions*)upb_msg_new(&envoy_api_v2_core_Http2ProtocolOptions_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_GrpcProtocolOptions_set_http2_protocol_options(msg, sub); + } + return sub; +} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* ENVOY_API_V2_CORE_PROTOCOL_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/envoy/api/v2/discovery.upb.c b/src/core/ext/upb-generated/envoy/api/v2/discovery.upb.c new file mode 100644 index 00000000000..2f67f55a8a3 --- /dev/null +++ b/src/core/ext/upb-generated/envoy/api/v2/discovery.upb.c @@ -0,0 +1,123 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/api/v2/discovery.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include +#include "upb/msg.h" +#include "envoy/api/v2/discovery.upb.h" +#include "envoy/api/v2/core/base.upb.h" +#include "google/protobuf/any.upb.h" +#include "google/rpc/status.upb.h" +#include "gogoproto/gogo.upb.h" + +#include "upb/port_def.inc" + +static const upb_msglayout *const envoy_api_v2_DiscoveryRequest_submsgs[2] = { + &envoy_api_v2_core_Node_msginit, + &google_rpc_Status_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_DiscoveryRequest__fields[6] = { + {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, + {2, UPB_SIZE(24, 48), 0, 0, 11, 1}, + {3, UPB_SIZE(32, 64), 0, 0, 9, 3}, + {4, UPB_SIZE(8, 16), 0, 0, 9, 1}, + {5, UPB_SIZE(16, 32), 0, 0, 9, 1}, + {6, UPB_SIZE(28, 56), 0, 1, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_DiscoveryRequest_msginit = { + &envoy_api_v2_DiscoveryRequest_submsgs[0], + &envoy_api_v2_DiscoveryRequest__fields[0], + UPB_SIZE(40, 80), 6, false, +}; + +static const upb_msglayout *const envoy_api_v2_DiscoveryResponse_submsgs[1] = { + &google_protobuf_Any_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_DiscoveryResponse__fields[5] = { + {1, UPB_SIZE(4, 8), 0, 0, 9, 1}, + {2, UPB_SIZE(28, 56), 0, 0, 11, 3}, + {3, UPB_SIZE(0, 0), 0, 0, 8, 1}, + {4, UPB_SIZE(12, 24), 0, 0, 9, 1}, + {5, UPB_SIZE(20, 40), 0, 0, 9, 1}, +}; + +const upb_msglayout envoy_api_v2_DiscoveryResponse_msginit = { + &envoy_api_v2_DiscoveryResponse_submsgs[0], + &envoy_api_v2_DiscoveryResponse__fields[0], + UPB_SIZE(32, 64), 5, false, +}; + +static const upb_msglayout *const envoy_api_v2_IncrementalDiscoveryRequest_submsgs[3] = { + &envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry_msginit, + &envoy_api_v2_core_Node_msginit, + &google_rpc_Status_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_IncrementalDiscoveryRequest__fields[7] = { + {1, UPB_SIZE(16, 32), 0, 1, 11, 1}, + {2, UPB_SIZE(0, 0), 0, 0, 9, 1}, + {3, UPB_SIZE(24, 48), 0, 0, 9, 3}, + {4, UPB_SIZE(28, 56), 0, 0, 9, 3}, + {5, UPB_SIZE(32, 64), 0, 0, 11, 3}, + {6, UPB_SIZE(8, 16), 0, 0, 9, 1}, + {7, UPB_SIZE(20, 40), 0, 2, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_IncrementalDiscoveryRequest_msginit = { + &envoy_api_v2_IncrementalDiscoveryRequest_submsgs[0], + &envoy_api_v2_IncrementalDiscoveryRequest__fields[0], + UPB_SIZE(40, 80), 7, false, +}; + +static const upb_msglayout_field envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry__fields[2] = { + {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, + {2, UPB_SIZE(8, 16), 0, 0, 9, 1}, +}; + +const upb_msglayout envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry_msginit = { + NULL, + &envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry__fields[0], + UPB_SIZE(16, 32), 2, false, +}; + +static const upb_msglayout *const envoy_api_v2_IncrementalDiscoveryResponse_submsgs[1] = { + &envoy_api_v2_Resource_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_IncrementalDiscoveryResponse__fields[4] = { + {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, + {2, UPB_SIZE(16, 32), 0, 0, 11, 3}, + {5, UPB_SIZE(8, 16), 0, 0, 9, 1}, + {6, UPB_SIZE(20, 40), 0, 0, 9, 3}, +}; + +const upb_msglayout envoy_api_v2_IncrementalDiscoveryResponse_msginit = { + &envoy_api_v2_IncrementalDiscoveryResponse_submsgs[0], + &envoy_api_v2_IncrementalDiscoveryResponse__fields[0], + UPB_SIZE(24, 48), 4, false, +}; + +static const upb_msglayout *const envoy_api_v2_Resource_submsgs[1] = { + &google_protobuf_Any_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_Resource__fields[2] = { + {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, + {2, UPB_SIZE(8, 16), 0, 0, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_Resource_msginit = { + &envoy_api_v2_Resource_submsgs[0], + &envoy_api_v2_Resource__fields[0], + UPB_SIZE(16, 32), 2, false, +}; + +#include "upb/port_undef.inc" + diff --git a/src/core/ext/upb-generated/envoy/api/v2/discovery.upb.h b/src/core/ext/upb-generated/envoy/api/v2/discovery.upb.h new file mode 100644 index 00000000000..7044ea956bf --- /dev/null +++ b/src/core/ext/upb-generated/envoy/api/v2/discovery.upb.h @@ -0,0 +1,360 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/api/v2/discovery.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef ENVOY_API_V2_DISCOVERY_PROTO_UPB_H_ +#define ENVOY_API_V2_DISCOVERY_PROTO_UPB_H_ + +#include "upb/generated_util.h" + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +#ifdef __cplusplus +extern "C" { +#endif + +struct envoy_api_v2_DiscoveryRequest; +struct envoy_api_v2_DiscoveryResponse; +struct envoy_api_v2_IncrementalDiscoveryRequest; +struct envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry; +struct envoy_api_v2_IncrementalDiscoveryResponse; +struct envoy_api_v2_Resource; +typedef struct envoy_api_v2_DiscoveryRequest envoy_api_v2_DiscoveryRequest; +typedef struct envoy_api_v2_DiscoveryResponse envoy_api_v2_DiscoveryResponse; +typedef struct envoy_api_v2_IncrementalDiscoveryRequest envoy_api_v2_IncrementalDiscoveryRequest; +typedef struct envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry; +typedef struct envoy_api_v2_IncrementalDiscoveryResponse envoy_api_v2_IncrementalDiscoveryResponse; +typedef struct envoy_api_v2_Resource envoy_api_v2_Resource; +extern const upb_msglayout envoy_api_v2_DiscoveryRequest_msginit; +extern const upb_msglayout envoy_api_v2_DiscoveryResponse_msginit; +extern const upb_msglayout envoy_api_v2_IncrementalDiscoveryRequest_msginit; +extern const upb_msglayout envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry_msginit; +extern const upb_msglayout envoy_api_v2_IncrementalDiscoveryResponse_msginit; +extern const upb_msglayout envoy_api_v2_Resource_msginit; +struct envoy_api_v2_core_Node; +struct google_protobuf_Any; +struct google_rpc_Status; +extern const upb_msglayout envoy_api_v2_core_Node_msginit; +extern const upb_msglayout google_protobuf_Any_msginit; +extern const upb_msglayout google_rpc_Status_msginit; + +/* Enums */ + + +/* envoy.api.v2.DiscoveryRequest */ + +UPB_INLINE envoy_api_v2_DiscoveryRequest *envoy_api_v2_DiscoveryRequest_new(upb_arena *arena) { + return (envoy_api_v2_DiscoveryRequest *)upb_msg_new(&envoy_api_v2_DiscoveryRequest_msginit, arena); +} +UPB_INLINE envoy_api_v2_DiscoveryRequest *envoy_api_v2_DiscoveryRequest_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_DiscoveryRequest *ret = envoy_api_v2_DiscoveryRequest_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_DiscoveryRequest_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_DiscoveryRequest_serialize(const envoy_api_v2_DiscoveryRequest *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_DiscoveryRequest_msginit, arena, len); +} + +UPB_INLINE upb_strview envoy_api_v2_DiscoveryRequest_version_info(const envoy_api_v2_DiscoveryRequest *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } +UPB_INLINE const struct envoy_api_v2_core_Node* envoy_api_v2_DiscoveryRequest_node(const envoy_api_v2_DiscoveryRequest *msg) { return UPB_FIELD_AT(msg, const struct envoy_api_v2_core_Node*, UPB_SIZE(24, 48)); } +UPB_INLINE upb_strview const* envoy_api_v2_DiscoveryRequest_resource_names(const envoy_api_v2_DiscoveryRequest *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(32, 64), len); } +UPB_INLINE upb_strview envoy_api_v2_DiscoveryRequest_type_url(const envoy_api_v2_DiscoveryRequest *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 16)); } +UPB_INLINE upb_strview envoy_api_v2_DiscoveryRequest_response_nonce(const envoy_api_v2_DiscoveryRequest *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(16, 32)); } +UPB_INLINE const struct google_rpc_Status* envoy_api_v2_DiscoveryRequest_error_detail(const envoy_api_v2_DiscoveryRequest *msg) { return UPB_FIELD_AT(msg, const struct google_rpc_Status*, UPB_SIZE(28, 56)); } + +UPB_INLINE void envoy_api_v2_DiscoveryRequest_set_version_info(envoy_api_v2_DiscoveryRequest *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_api_v2_DiscoveryRequest_set_node(envoy_api_v2_DiscoveryRequest *msg, struct envoy_api_v2_core_Node* value) { + UPB_FIELD_AT(msg, struct envoy_api_v2_core_Node*, UPB_SIZE(24, 48)) = value; +} +UPB_INLINE struct envoy_api_v2_core_Node* envoy_api_v2_DiscoveryRequest_mutable_node(envoy_api_v2_DiscoveryRequest *msg, upb_arena *arena) { + struct envoy_api_v2_core_Node* sub = (struct envoy_api_v2_core_Node*)envoy_api_v2_DiscoveryRequest_node(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_Node*)upb_msg_new(&envoy_api_v2_core_Node_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_DiscoveryRequest_set_node(msg, sub); + } + return sub; +} +UPB_INLINE upb_strview* envoy_api_v2_DiscoveryRequest_mutable_resource_names(envoy_api_v2_DiscoveryRequest *msg, size_t *len) { + return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(32, 64), len); +} +UPB_INLINE upb_strview* envoy_api_v2_DiscoveryRequest_resize_resource_names(envoy_api_v2_DiscoveryRequest *msg, size_t len, upb_arena *arena) { + return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(32, 64), len, UPB_SIZE(8, 16), UPB_TYPE_STRING, arena); +} +UPB_INLINE bool envoy_api_v2_DiscoveryRequest_add_resource_names(envoy_api_v2_DiscoveryRequest *msg, upb_strview val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(32, 64), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, arena); +} +UPB_INLINE void envoy_api_v2_DiscoveryRequest_set_type_url(envoy_api_v2_DiscoveryRequest *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE void envoy_api_v2_DiscoveryRequest_set_response_nonce(envoy_api_v2_DiscoveryRequest *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(16, 32)) = value; +} +UPB_INLINE void envoy_api_v2_DiscoveryRequest_set_error_detail(envoy_api_v2_DiscoveryRequest *msg, struct google_rpc_Status* value) { + UPB_FIELD_AT(msg, struct google_rpc_Status*, UPB_SIZE(28, 56)) = value; +} +UPB_INLINE struct google_rpc_Status* envoy_api_v2_DiscoveryRequest_mutable_error_detail(envoy_api_v2_DiscoveryRequest *msg, upb_arena *arena) { + struct google_rpc_Status* sub = (struct google_rpc_Status*)envoy_api_v2_DiscoveryRequest_error_detail(msg); + if (sub == NULL) { + sub = (struct google_rpc_Status*)upb_msg_new(&google_rpc_Status_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_DiscoveryRequest_set_error_detail(msg, sub); + } + return sub; +} + + +/* envoy.api.v2.DiscoveryResponse */ + +UPB_INLINE envoy_api_v2_DiscoveryResponse *envoy_api_v2_DiscoveryResponse_new(upb_arena *arena) { + return (envoy_api_v2_DiscoveryResponse *)upb_msg_new(&envoy_api_v2_DiscoveryResponse_msginit, arena); +} +UPB_INLINE envoy_api_v2_DiscoveryResponse *envoy_api_v2_DiscoveryResponse_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_DiscoveryResponse *ret = envoy_api_v2_DiscoveryResponse_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_DiscoveryResponse_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_DiscoveryResponse_serialize(const envoy_api_v2_DiscoveryResponse *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_DiscoveryResponse_msginit, arena, len); +} + +UPB_INLINE upb_strview envoy_api_v2_DiscoveryResponse_version_info(const envoy_api_v2_DiscoveryResponse *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)); } +UPB_INLINE const struct google_protobuf_Any* const* envoy_api_v2_DiscoveryResponse_resources(const envoy_api_v2_DiscoveryResponse *msg, size_t *len) { return (const struct google_protobuf_Any* const*)_upb_array_accessor(msg, UPB_SIZE(28, 56), len); } +UPB_INLINE bool envoy_api_v2_DiscoveryResponse_canary(const envoy_api_v2_DiscoveryResponse *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(0, 0)); } +UPB_INLINE upb_strview envoy_api_v2_DiscoveryResponse_type_url(const envoy_api_v2_DiscoveryResponse *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(12, 24)); } +UPB_INLINE upb_strview envoy_api_v2_DiscoveryResponse_nonce(const envoy_api_v2_DiscoveryResponse *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(20, 40)); } + +UPB_INLINE void envoy_api_v2_DiscoveryResponse_set_version_info(envoy_api_v2_DiscoveryResponse *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)) = value; +} +UPB_INLINE struct google_protobuf_Any** envoy_api_v2_DiscoveryResponse_mutable_resources(envoy_api_v2_DiscoveryResponse *msg, size_t *len) { + return (struct google_protobuf_Any**)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 56), len); +} +UPB_INLINE struct google_protobuf_Any** envoy_api_v2_DiscoveryResponse_resize_resources(envoy_api_v2_DiscoveryResponse *msg, size_t len, upb_arena *arena) { + return (struct google_protobuf_Any**)_upb_array_resize_accessor(msg, UPB_SIZE(28, 56), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_Any* envoy_api_v2_DiscoveryResponse_add_resources(envoy_api_v2_DiscoveryResponse *msg, upb_arena *arena) { + struct google_protobuf_Any* sub = (struct google_protobuf_Any*)upb_msg_new(&google_protobuf_Any_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(28, 56), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE void envoy_api_v2_DiscoveryResponse_set_canary(envoy_api_v2_DiscoveryResponse *msg, bool value) { + UPB_FIELD_AT(msg, bool, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_api_v2_DiscoveryResponse_set_type_url(envoy_api_v2_DiscoveryResponse *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(12, 24)) = value; +} +UPB_INLINE void envoy_api_v2_DiscoveryResponse_set_nonce(envoy_api_v2_DiscoveryResponse *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(20, 40)) = value; +} + + +/* envoy.api.v2.IncrementalDiscoveryRequest */ + +UPB_INLINE envoy_api_v2_IncrementalDiscoveryRequest *envoy_api_v2_IncrementalDiscoveryRequest_new(upb_arena *arena) { + return (envoy_api_v2_IncrementalDiscoveryRequest *)upb_msg_new(&envoy_api_v2_IncrementalDiscoveryRequest_msginit, arena); +} +UPB_INLINE envoy_api_v2_IncrementalDiscoveryRequest *envoy_api_v2_IncrementalDiscoveryRequest_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_IncrementalDiscoveryRequest *ret = envoy_api_v2_IncrementalDiscoveryRequest_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_IncrementalDiscoveryRequest_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_IncrementalDiscoveryRequest_serialize(const envoy_api_v2_IncrementalDiscoveryRequest *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_IncrementalDiscoveryRequest_msginit, arena, len); +} + +UPB_INLINE const struct envoy_api_v2_core_Node* envoy_api_v2_IncrementalDiscoveryRequest_node(const envoy_api_v2_IncrementalDiscoveryRequest *msg) { return UPB_FIELD_AT(msg, const struct envoy_api_v2_core_Node*, UPB_SIZE(16, 32)); } +UPB_INLINE upb_strview envoy_api_v2_IncrementalDiscoveryRequest_type_url(const envoy_api_v2_IncrementalDiscoveryRequest *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } +UPB_INLINE upb_strview const* envoy_api_v2_IncrementalDiscoveryRequest_resource_names_subscribe(const envoy_api_v2_IncrementalDiscoveryRequest *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(24, 48), len); } +UPB_INLINE upb_strview const* envoy_api_v2_IncrementalDiscoveryRequest_resource_names_unsubscribe(const envoy_api_v2_IncrementalDiscoveryRequest *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(28, 56), len); } +UPB_INLINE const envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry* const* envoy_api_v2_IncrementalDiscoveryRequest_initial_resource_versions(const envoy_api_v2_IncrementalDiscoveryRequest *msg, size_t *len) { return (const envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry* const*)_upb_array_accessor(msg, UPB_SIZE(32, 64), len); } +UPB_INLINE upb_strview envoy_api_v2_IncrementalDiscoveryRequest_response_nonce(const envoy_api_v2_IncrementalDiscoveryRequest *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 16)); } +UPB_INLINE const struct google_rpc_Status* envoy_api_v2_IncrementalDiscoveryRequest_error_detail(const envoy_api_v2_IncrementalDiscoveryRequest *msg) { return UPB_FIELD_AT(msg, const struct google_rpc_Status*, UPB_SIZE(20, 40)); } + +UPB_INLINE void envoy_api_v2_IncrementalDiscoveryRequest_set_node(envoy_api_v2_IncrementalDiscoveryRequest *msg, struct envoy_api_v2_core_Node* value) { + UPB_FIELD_AT(msg, struct envoy_api_v2_core_Node*, UPB_SIZE(16, 32)) = value; +} +UPB_INLINE struct envoy_api_v2_core_Node* envoy_api_v2_IncrementalDiscoveryRequest_mutable_node(envoy_api_v2_IncrementalDiscoveryRequest *msg, upb_arena *arena) { + struct envoy_api_v2_core_Node* sub = (struct envoy_api_v2_core_Node*)envoy_api_v2_IncrementalDiscoveryRequest_node(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_Node*)upb_msg_new(&envoy_api_v2_core_Node_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_IncrementalDiscoveryRequest_set_node(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_IncrementalDiscoveryRequest_set_type_url(envoy_api_v2_IncrementalDiscoveryRequest *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE upb_strview* envoy_api_v2_IncrementalDiscoveryRequest_mutable_resource_names_subscribe(envoy_api_v2_IncrementalDiscoveryRequest *msg, size_t *len) { + return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 48), len); +} +UPB_INLINE upb_strview* envoy_api_v2_IncrementalDiscoveryRequest_resize_resource_names_subscribe(envoy_api_v2_IncrementalDiscoveryRequest *msg, size_t len, upb_arena *arena) { + return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(24, 48), len, UPB_SIZE(8, 16), UPB_TYPE_STRING, arena); +} +UPB_INLINE bool envoy_api_v2_IncrementalDiscoveryRequest_add_resource_names_subscribe(envoy_api_v2_IncrementalDiscoveryRequest *msg, upb_strview val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(24, 48), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, arena); +} +UPB_INLINE upb_strview* envoy_api_v2_IncrementalDiscoveryRequest_mutable_resource_names_unsubscribe(envoy_api_v2_IncrementalDiscoveryRequest *msg, size_t *len) { + return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 56), len); +} +UPB_INLINE upb_strview* envoy_api_v2_IncrementalDiscoveryRequest_resize_resource_names_unsubscribe(envoy_api_v2_IncrementalDiscoveryRequest *msg, size_t len, upb_arena *arena) { + return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(28, 56), len, UPB_SIZE(8, 16), UPB_TYPE_STRING, arena); +} +UPB_INLINE bool envoy_api_v2_IncrementalDiscoveryRequest_add_resource_names_unsubscribe(envoy_api_v2_IncrementalDiscoveryRequest *msg, upb_strview val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(28, 56), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, arena); +} +UPB_INLINE envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry** envoy_api_v2_IncrementalDiscoveryRequest_mutable_initial_resource_versions(envoy_api_v2_IncrementalDiscoveryRequest *msg, size_t *len) { + return (envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry**)_upb_array_mutable_accessor(msg, UPB_SIZE(32, 64), len); +} +UPB_INLINE envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry** envoy_api_v2_IncrementalDiscoveryRequest_resize_initial_resource_versions(envoy_api_v2_IncrementalDiscoveryRequest *msg, size_t len, upb_arena *arena) { + return (envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry**)_upb_array_resize_accessor(msg, UPB_SIZE(32, 64), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry* envoy_api_v2_IncrementalDiscoveryRequest_add_initial_resource_versions(envoy_api_v2_IncrementalDiscoveryRequest *msg, upb_arena *arena) { + struct envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry* sub = (struct envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry*)upb_msg_new(&envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(32, 64), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE void envoy_api_v2_IncrementalDiscoveryRequest_set_response_nonce(envoy_api_v2_IncrementalDiscoveryRequest *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE void envoy_api_v2_IncrementalDiscoveryRequest_set_error_detail(envoy_api_v2_IncrementalDiscoveryRequest *msg, struct google_rpc_Status* value) { + UPB_FIELD_AT(msg, struct google_rpc_Status*, UPB_SIZE(20, 40)) = value; +} +UPB_INLINE struct google_rpc_Status* envoy_api_v2_IncrementalDiscoveryRequest_mutable_error_detail(envoy_api_v2_IncrementalDiscoveryRequest *msg, upb_arena *arena) { + struct google_rpc_Status* sub = (struct google_rpc_Status*)envoy_api_v2_IncrementalDiscoveryRequest_error_detail(msg); + if (sub == NULL) { + sub = (struct google_rpc_Status*)upb_msg_new(&google_rpc_Status_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_IncrementalDiscoveryRequest_set_error_detail(msg, sub); + } + return sub; +} + + +/* envoy.api.v2.IncrementalDiscoveryRequest.InitialResourceVersionsEntry */ + +UPB_INLINE envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry *envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry_new(upb_arena *arena) { + return (envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry *)upb_msg_new(&envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry_msginit, arena); +} +UPB_INLINE envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry *envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry *ret = envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry_serialize(const envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry_msginit, arena, len); +} + +UPB_INLINE upb_strview envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry_key(const envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } +UPB_INLINE upb_strview envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry_value(const envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 16)); } + +UPB_INLINE void envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry_set_key(envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry_set_value(envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 16)) = value; +} + + +/* envoy.api.v2.IncrementalDiscoveryResponse */ + +UPB_INLINE envoy_api_v2_IncrementalDiscoveryResponse *envoy_api_v2_IncrementalDiscoveryResponse_new(upb_arena *arena) { + return (envoy_api_v2_IncrementalDiscoveryResponse *)upb_msg_new(&envoy_api_v2_IncrementalDiscoveryResponse_msginit, arena); +} +UPB_INLINE envoy_api_v2_IncrementalDiscoveryResponse *envoy_api_v2_IncrementalDiscoveryResponse_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_IncrementalDiscoveryResponse *ret = envoy_api_v2_IncrementalDiscoveryResponse_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_IncrementalDiscoveryResponse_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_IncrementalDiscoveryResponse_serialize(const envoy_api_v2_IncrementalDiscoveryResponse *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_IncrementalDiscoveryResponse_msginit, arena, len); +} + +UPB_INLINE upb_strview envoy_api_v2_IncrementalDiscoveryResponse_system_version_info(const envoy_api_v2_IncrementalDiscoveryResponse *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } +UPB_INLINE const envoy_api_v2_Resource* const* envoy_api_v2_IncrementalDiscoveryResponse_resources(const envoy_api_v2_IncrementalDiscoveryResponse *msg, size_t *len) { return (const envoy_api_v2_Resource* const*)_upb_array_accessor(msg, UPB_SIZE(16, 32), len); } +UPB_INLINE upb_strview envoy_api_v2_IncrementalDiscoveryResponse_nonce(const envoy_api_v2_IncrementalDiscoveryResponse *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 16)); } +UPB_INLINE upb_strview const* envoy_api_v2_IncrementalDiscoveryResponse_removed_resources(const envoy_api_v2_IncrementalDiscoveryResponse *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(20, 40), len); } + +UPB_INLINE void envoy_api_v2_IncrementalDiscoveryResponse_set_system_version_info(envoy_api_v2_IncrementalDiscoveryResponse *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE envoy_api_v2_Resource** envoy_api_v2_IncrementalDiscoveryResponse_mutable_resources(envoy_api_v2_IncrementalDiscoveryResponse *msg, size_t *len) { + return (envoy_api_v2_Resource**)_upb_array_mutable_accessor(msg, UPB_SIZE(16, 32), len); +} +UPB_INLINE envoy_api_v2_Resource** envoy_api_v2_IncrementalDiscoveryResponse_resize_resources(envoy_api_v2_IncrementalDiscoveryResponse *msg, size_t len, upb_arena *arena) { + return (envoy_api_v2_Resource**)_upb_array_resize_accessor(msg, UPB_SIZE(16, 32), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct envoy_api_v2_Resource* envoy_api_v2_IncrementalDiscoveryResponse_add_resources(envoy_api_v2_IncrementalDiscoveryResponse *msg, upb_arena *arena) { + struct envoy_api_v2_Resource* sub = (struct envoy_api_v2_Resource*)upb_msg_new(&envoy_api_v2_Resource_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(16, 32), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE void envoy_api_v2_IncrementalDiscoveryResponse_set_nonce(envoy_api_v2_IncrementalDiscoveryResponse *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE upb_strview* envoy_api_v2_IncrementalDiscoveryResponse_mutable_removed_resources(envoy_api_v2_IncrementalDiscoveryResponse *msg, size_t *len) { + return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 40), len); +} +UPB_INLINE upb_strview* envoy_api_v2_IncrementalDiscoveryResponse_resize_removed_resources(envoy_api_v2_IncrementalDiscoveryResponse *msg, size_t len, upb_arena *arena) { + return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(20, 40), len, UPB_SIZE(8, 16), UPB_TYPE_STRING, arena); +} +UPB_INLINE bool envoy_api_v2_IncrementalDiscoveryResponse_add_removed_resources(envoy_api_v2_IncrementalDiscoveryResponse *msg, upb_strview val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(20, 40), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, arena); +} + + +/* envoy.api.v2.Resource */ + +UPB_INLINE envoy_api_v2_Resource *envoy_api_v2_Resource_new(upb_arena *arena) { + return (envoy_api_v2_Resource *)upb_msg_new(&envoy_api_v2_Resource_msginit, arena); +} +UPB_INLINE envoy_api_v2_Resource *envoy_api_v2_Resource_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_Resource *ret = envoy_api_v2_Resource_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_Resource_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_Resource_serialize(const envoy_api_v2_Resource *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_Resource_msginit, arena, len); +} + +UPB_INLINE upb_strview envoy_api_v2_Resource_version(const envoy_api_v2_Resource *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } +UPB_INLINE const struct google_protobuf_Any* envoy_api_v2_Resource_resource(const envoy_api_v2_Resource *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Any*, UPB_SIZE(8, 16)); } + +UPB_INLINE void envoy_api_v2_Resource_set_version(envoy_api_v2_Resource *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_api_v2_Resource_set_resource(envoy_api_v2_Resource *msg, struct google_protobuf_Any* value) { + UPB_FIELD_AT(msg, struct google_protobuf_Any*, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE struct google_protobuf_Any* envoy_api_v2_Resource_mutable_resource(envoy_api_v2_Resource *msg, upb_arena *arena) { + struct google_protobuf_Any* sub = (struct google_protobuf_Any*)envoy_api_v2_Resource_resource(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Any*)upb_msg_new(&google_protobuf_Any_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Resource_set_resource(msg, sub); + } + return sub; +} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* ENVOY_API_V2_DISCOVERY_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/envoy/api/v2/eds.upb.c b/src/core/ext/upb-generated/envoy/api/v2/eds.upb.c new file mode 100644 index 00000000000..d6f074b0879 --- /dev/null +++ b/src/core/ext/upb-generated/envoy/api/v2/eds.upb.c @@ -0,0 +1,71 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/api/v2/eds.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include +#include "upb/msg.h" +#include "envoy/api/v2/eds.upb.h" +#include "envoy/api/v2/discovery.upb.h" +#include "envoy/api/v2/endpoint/endpoint.upb.h" +#include "envoy/type/percent.upb.h" +#include "google/api/annotations.upb.h" +#include "validate/validate.upb.h" +#include "gogoproto/gogo.upb.h" +#include "google/protobuf/wrappers.upb.h" + +#include "upb/port_def.inc" + +static const upb_msglayout *const envoy_api_v2_ClusterLoadAssignment_submsgs[2] = { + &envoy_api_v2_ClusterLoadAssignment_Policy_msginit, + &envoy_api_v2_endpoint_LocalityLbEndpoints_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_ClusterLoadAssignment__fields[3] = { + {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, + {2, UPB_SIZE(12, 24), 0, 1, 11, 3}, + {4, UPB_SIZE(8, 16), 0, 0, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_ClusterLoadAssignment_msginit = { + &envoy_api_v2_ClusterLoadAssignment_submsgs[0], + &envoy_api_v2_ClusterLoadAssignment__fields[0], + UPB_SIZE(16, 32), 3, false, +}; + +static const upb_msglayout *const envoy_api_v2_ClusterLoadAssignment_Policy_submsgs[2] = { + &envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload_msginit, + &google_protobuf_UInt32Value_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_ClusterLoadAssignment_Policy__fields[2] = { + {2, UPB_SIZE(4, 8), 0, 0, 11, 3}, + {3, UPB_SIZE(0, 0), 0, 1, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_ClusterLoadAssignment_Policy_msginit = { + &envoy_api_v2_ClusterLoadAssignment_Policy_submsgs[0], + &envoy_api_v2_ClusterLoadAssignment_Policy__fields[0], + UPB_SIZE(8, 16), 2, false, +}; + +static const upb_msglayout *const envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload_submsgs[1] = { + &envoy_type_FractionalPercent_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload__fields[2] = { + {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, + {2, UPB_SIZE(8, 16), 0, 0, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload_msginit = { + &envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload_submsgs[0], + &envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload__fields[0], + UPB_SIZE(16, 32), 2, false, +}; + +#include "upb/port_undef.inc" + diff --git a/src/core/ext/upb-generated/envoy/api/v2/eds.upb.h b/src/core/ext/upb-generated/envoy/api/v2/eds.upb.h new file mode 100644 index 00000000000..a9b6f5f9c3d --- /dev/null +++ b/src/core/ext/upb-generated/envoy/api/v2/eds.upb.h @@ -0,0 +1,171 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/api/v2/eds.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef ENVOY_API_V2_EDS_PROTO_UPB_H_ +#define ENVOY_API_V2_EDS_PROTO_UPB_H_ + +#include "upb/generated_util.h" + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +#ifdef __cplusplus +extern "C" { +#endif + +struct envoy_api_v2_ClusterLoadAssignment; +struct envoy_api_v2_ClusterLoadAssignment_Policy; +struct envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload; +typedef struct envoy_api_v2_ClusterLoadAssignment envoy_api_v2_ClusterLoadAssignment; +typedef struct envoy_api_v2_ClusterLoadAssignment_Policy envoy_api_v2_ClusterLoadAssignment_Policy; +typedef struct envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload; +extern const upb_msglayout envoy_api_v2_ClusterLoadAssignment_msginit; +extern const upb_msglayout envoy_api_v2_ClusterLoadAssignment_Policy_msginit; +extern const upb_msglayout envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload_msginit; +struct envoy_api_v2_endpoint_LocalityLbEndpoints; +struct envoy_type_FractionalPercent; +struct google_protobuf_UInt32Value; +extern const upb_msglayout envoy_api_v2_endpoint_LocalityLbEndpoints_msginit; +extern const upb_msglayout envoy_type_FractionalPercent_msginit; +extern const upb_msglayout google_protobuf_UInt32Value_msginit; + +/* Enums */ + + +/* envoy.api.v2.ClusterLoadAssignment */ + +UPB_INLINE envoy_api_v2_ClusterLoadAssignment *envoy_api_v2_ClusterLoadAssignment_new(upb_arena *arena) { + return (envoy_api_v2_ClusterLoadAssignment *)upb_msg_new(&envoy_api_v2_ClusterLoadAssignment_msginit, arena); +} +UPB_INLINE envoy_api_v2_ClusterLoadAssignment *envoy_api_v2_ClusterLoadAssignment_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_ClusterLoadAssignment *ret = envoy_api_v2_ClusterLoadAssignment_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_ClusterLoadAssignment_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_ClusterLoadAssignment_serialize(const envoy_api_v2_ClusterLoadAssignment *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_ClusterLoadAssignment_msginit, arena, len); +} + +UPB_INLINE upb_strview envoy_api_v2_ClusterLoadAssignment_cluster_name(const envoy_api_v2_ClusterLoadAssignment *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } +UPB_INLINE const struct envoy_api_v2_endpoint_LocalityLbEndpoints* const* envoy_api_v2_ClusterLoadAssignment_endpoints(const envoy_api_v2_ClusterLoadAssignment *msg, size_t *len) { return (const struct envoy_api_v2_endpoint_LocalityLbEndpoints* const*)_upb_array_accessor(msg, UPB_SIZE(12, 24), len); } +UPB_INLINE const envoy_api_v2_ClusterLoadAssignment_Policy* envoy_api_v2_ClusterLoadAssignment_policy(const envoy_api_v2_ClusterLoadAssignment *msg) { return UPB_FIELD_AT(msg, const envoy_api_v2_ClusterLoadAssignment_Policy*, UPB_SIZE(8, 16)); } + +UPB_INLINE void envoy_api_v2_ClusterLoadAssignment_set_cluster_name(envoy_api_v2_ClusterLoadAssignment *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE struct envoy_api_v2_endpoint_LocalityLbEndpoints** envoy_api_v2_ClusterLoadAssignment_mutable_endpoints(envoy_api_v2_ClusterLoadAssignment *msg, size_t *len) { + return (struct envoy_api_v2_endpoint_LocalityLbEndpoints**)_upb_array_mutable_accessor(msg, UPB_SIZE(12, 24), len); +} +UPB_INLINE struct envoy_api_v2_endpoint_LocalityLbEndpoints** envoy_api_v2_ClusterLoadAssignment_resize_endpoints(envoy_api_v2_ClusterLoadAssignment *msg, size_t len, upb_arena *arena) { + return (struct envoy_api_v2_endpoint_LocalityLbEndpoints**)_upb_array_resize_accessor(msg, UPB_SIZE(12, 24), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct envoy_api_v2_endpoint_LocalityLbEndpoints* envoy_api_v2_ClusterLoadAssignment_add_endpoints(envoy_api_v2_ClusterLoadAssignment *msg, upb_arena *arena) { + struct envoy_api_v2_endpoint_LocalityLbEndpoints* sub = (struct envoy_api_v2_endpoint_LocalityLbEndpoints*)upb_msg_new(&envoy_api_v2_endpoint_LocalityLbEndpoints_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(12, 24), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE void envoy_api_v2_ClusterLoadAssignment_set_policy(envoy_api_v2_ClusterLoadAssignment *msg, envoy_api_v2_ClusterLoadAssignment_Policy* value) { + UPB_FIELD_AT(msg, envoy_api_v2_ClusterLoadAssignment_Policy*, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE struct envoy_api_v2_ClusterLoadAssignment_Policy* envoy_api_v2_ClusterLoadAssignment_mutable_policy(envoy_api_v2_ClusterLoadAssignment *msg, upb_arena *arena) { + struct envoy_api_v2_ClusterLoadAssignment_Policy* sub = (struct envoy_api_v2_ClusterLoadAssignment_Policy*)envoy_api_v2_ClusterLoadAssignment_policy(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_ClusterLoadAssignment_Policy*)upb_msg_new(&envoy_api_v2_ClusterLoadAssignment_Policy_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_ClusterLoadAssignment_set_policy(msg, sub); + } + return sub; +} + + +/* envoy.api.v2.ClusterLoadAssignment.Policy */ + +UPB_INLINE envoy_api_v2_ClusterLoadAssignment_Policy *envoy_api_v2_ClusterLoadAssignment_Policy_new(upb_arena *arena) { + return (envoy_api_v2_ClusterLoadAssignment_Policy *)upb_msg_new(&envoy_api_v2_ClusterLoadAssignment_Policy_msginit, arena); +} +UPB_INLINE envoy_api_v2_ClusterLoadAssignment_Policy *envoy_api_v2_ClusterLoadAssignment_Policy_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_ClusterLoadAssignment_Policy *ret = envoy_api_v2_ClusterLoadAssignment_Policy_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_ClusterLoadAssignment_Policy_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_ClusterLoadAssignment_Policy_serialize(const envoy_api_v2_ClusterLoadAssignment_Policy *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_ClusterLoadAssignment_Policy_msginit, arena, len); +} + +UPB_INLINE const envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload* const* envoy_api_v2_ClusterLoadAssignment_Policy_drop_overloads(const envoy_api_v2_ClusterLoadAssignment_Policy *msg, size_t *len) { return (const envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload* const*)_upb_array_accessor(msg, UPB_SIZE(4, 8), len); } +UPB_INLINE const struct google_protobuf_UInt32Value* envoy_api_v2_ClusterLoadAssignment_Policy_overprovisioning_factor(const envoy_api_v2_ClusterLoadAssignment_Policy *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt32Value*, UPB_SIZE(0, 0)); } + +UPB_INLINE envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload** envoy_api_v2_ClusterLoadAssignment_Policy_mutable_drop_overloads(envoy_api_v2_ClusterLoadAssignment_Policy *msg, size_t *len) { + return (envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload**)_upb_array_mutable_accessor(msg, UPB_SIZE(4, 8), len); +} +UPB_INLINE envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload** envoy_api_v2_ClusterLoadAssignment_Policy_resize_drop_overloads(envoy_api_v2_ClusterLoadAssignment_Policy *msg, size_t len, upb_arena *arena) { + return (envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload**)_upb_array_resize_accessor(msg, UPB_SIZE(4, 8), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload* envoy_api_v2_ClusterLoadAssignment_Policy_add_drop_overloads(envoy_api_v2_ClusterLoadAssignment_Policy *msg, upb_arena *arena) { + struct envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload* sub = (struct envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload*)upb_msg_new(&envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(4, 8), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE void envoy_api_v2_ClusterLoadAssignment_Policy_set_overprovisioning_factor(envoy_api_v2_ClusterLoadAssignment_Policy *msg, struct google_protobuf_UInt32Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt32Value*, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE struct google_protobuf_UInt32Value* envoy_api_v2_ClusterLoadAssignment_Policy_mutable_overprovisioning_factor(envoy_api_v2_ClusterLoadAssignment_Policy *msg, upb_arena *arena) { + struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_api_v2_ClusterLoadAssignment_Policy_overprovisioning_factor(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt32Value*)upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_ClusterLoadAssignment_Policy_set_overprovisioning_factor(msg, sub); + } + return sub; +} + + +/* envoy.api.v2.ClusterLoadAssignment.Policy.DropOverload */ + +UPB_INLINE envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload *envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload_new(upb_arena *arena) { + return (envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload *)upb_msg_new(&envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload_msginit, arena); +} +UPB_INLINE envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload *envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload *ret = envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload_serialize(const envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload_msginit, arena, len); +} + +UPB_INLINE upb_strview envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload_category(const envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } +UPB_INLINE const struct envoy_type_FractionalPercent* envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload_drop_percentage(const envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload *msg) { return UPB_FIELD_AT(msg, const struct envoy_type_FractionalPercent*, UPB_SIZE(8, 16)); } + +UPB_INLINE void envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload_set_category(envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload_set_drop_percentage(envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload *msg, struct envoy_type_FractionalPercent* value) { + UPB_FIELD_AT(msg, struct envoy_type_FractionalPercent*, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE struct envoy_type_FractionalPercent* envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload_mutable_drop_percentage(envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload *msg, upb_arena *arena) { + struct envoy_type_FractionalPercent* sub = (struct envoy_type_FractionalPercent*)envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload_drop_percentage(msg); + if (sub == NULL) { + sub = (struct envoy_type_FractionalPercent*)upb_msg_new(&envoy_type_FractionalPercent_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload_set_drop_percentage(msg, sub); + } + return sub; +} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* ENVOY_API_V2_EDS_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/envoy/api/v2/endpoint/endpoint.upb.c b/src/core/ext/upb-generated/envoy/api/v2/endpoint/endpoint.upb.c new file mode 100644 index 00000000000..4cc9d7dd445 --- /dev/null +++ b/src/core/ext/upb-generated/envoy/api/v2/endpoint/endpoint.upb.c @@ -0,0 +1,86 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/api/v2/endpoint/endpoint.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include +#include "upb/msg.h" +#include "envoy/api/v2/endpoint/endpoint.upb.h" +#include "envoy/api/v2/core/address.upb.h" +#include "envoy/api/v2/core/base.upb.h" +#include "envoy/api/v2/core/health_check.upb.h" +#include "google/protobuf/wrappers.upb.h" +#include "validate/validate.upb.h" +#include "gogoproto/gogo.upb.h" + +#include "upb/port_def.inc" + +static const upb_msglayout *const envoy_api_v2_endpoint_Endpoint_submsgs[2] = { + &envoy_api_v2_core_Address_msginit, + &envoy_api_v2_endpoint_Endpoint_HealthCheckConfig_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_endpoint_Endpoint__fields[2] = { + {1, UPB_SIZE(0, 0), 0, 0, 11, 1}, + {2, UPB_SIZE(4, 8), 0, 1, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_endpoint_Endpoint_msginit = { + &envoy_api_v2_endpoint_Endpoint_submsgs[0], + &envoy_api_v2_endpoint_Endpoint__fields[0], + UPB_SIZE(8, 16), 2, false, +}; + +static const upb_msglayout_field envoy_api_v2_endpoint_Endpoint_HealthCheckConfig__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 13, 1}, +}; + +const upb_msglayout envoy_api_v2_endpoint_Endpoint_HealthCheckConfig_msginit = { + NULL, + &envoy_api_v2_endpoint_Endpoint_HealthCheckConfig__fields[0], + UPB_SIZE(4, 4), 1, false, +}; + +static const upb_msglayout *const envoy_api_v2_endpoint_LbEndpoint_submsgs[3] = { + &envoy_api_v2_core_Metadata_msginit, + &envoy_api_v2_endpoint_Endpoint_msginit, + &google_protobuf_UInt32Value_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_endpoint_LbEndpoint__fields[4] = { + {1, UPB_SIZE(8, 8), 0, 1, 11, 1}, + {2, UPB_SIZE(0, 0), 0, 0, 14, 1}, + {3, UPB_SIZE(12, 16), 0, 0, 11, 1}, + {4, UPB_SIZE(16, 24), 0, 2, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_endpoint_LbEndpoint_msginit = { + &envoy_api_v2_endpoint_LbEndpoint_submsgs[0], + &envoy_api_v2_endpoint_LbEndpoint__fields[0], + UPB_SIZE(24, 32), 4, false, +}; + +static const upb_msglayout *const envoy_api_v2_endpoint_LocalityLbEndpoints_submsgs[3] = { + &envoy_api_v2_core_Locality_msginit, + &envoy_api_v2_endpoint_LbEndpoint_msginit, + &google_protobuf_UInt32Value_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_endpoint_LocalityLbEndpoints__fields[4] = { + {1, UPB_SIZE(4, 8), 0, 0, 11, 1}, + {2, UPB_SIZE(12, 24), 0, 1, 11, 3}, + {3, UPB_SIZE(8, 16), 0, 2, 11, 1}, + {5, UPB_SIZE(0, 0), 0, 0, 13, 1}, +}; + +const upb_msglayout envoy_api_v2_endpoint_LocalityLbEndpoints_msginit = { + &envoy_api_v2_endpoint_LocalityLbEndpoints_submsgs[0], + &envoy_api_v2_endpoint_LocalityLbEndpoints__fields[0], + UPB_SIZE(16, 32), 4, false, +}; + +#include "upb/port_undef.inc" + diff --git a/src/core/ext/upb-generated/envoy/api/v2/endpoint/endpoint.upb.h b/src/core/ext/upb-generated/envoy/api/v2/endpoint/endpoint.upb.h new file mode 100644 index 00000000000..4fd6341d3c4 --- /dev/null +++ b/src/core/ext/upb-generated/envoy/api/v2/endpoint/endpoint.upb.h @@ -0,0 +1,234 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/api/v2/endpoint/endpoint.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef ENVOY_API_V2_ENDPOINT_ENDPOINT_PROTO_UPB_H_ +#define ENVOY_API_V2_ENDPOINT_ENDPOINT_PROTO_UPB_H_ + +#include "upb/generated_util.h" + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +#ifdef __cplusplus +extern "C" { +#endif + +struct envoy_api_v2_endpoint_Endpoint; +struct envoy_api_v2_endpoint_Endpoint_HealthCheckConfig; +struct envoy_api_v2_endpoint_LbEndpoint; +struct envoy_api_v2_endpoint_LocalityLbEndpoints; +typedef struct envoy_api_v2_endpoint_Endpoint envoy_api_v2_endpoint_Endpoint; +typedef struct envoy_api_v2_endpoint_Endpoint_HealthCheckConfig envoy_api_v2_endpoint_Endpoint_HealthCheckConfig; +typedef struct envoy_api_v2_endpoint_LbEndpoint envoy_api_v2_endpoint_LbEndpoint; +typedef struct envoy_api_v2_endpoint_LocalityLbEndpoints envoy_api_v2_endpoint_LocalityLbEndpoints; +extern const upb_msglayout envoy_api_v2_endpoint_Endpoint_msginit; +extern const upb_msglayout envoy_api_v2_endpoint_Endpoint_HealthCheckConfig_msginit; +extern const upb_msglayout envoy_api_v2_endpoint_LbEndpoint_msginit; +extern const upb_msglayout envoy_api_v2_endpoint_LocalityLbEndpoints_msginit; +struct envoy_api_v2_core_Address; +struct envoy_api_v2_core_Locality; +struct envoy_api_v2_core_Metadata; +struct google_protobuf_UInt32Value; +extern const upb_msglayout envoy_api_v2_core_Address_msginit; +extern const upb_msglayout envoy_api_v2_core_Locality_msginit; +extern const upb_msglayout envoy_api_v2_core_Metadata_msginit; +extern const upb_msglayout google_protobuf_UInt32Value_msginit; + +/* Enums */ + + +/* envoy.api.v2.endpoint.Endpoint */ + +UPB_INLINE envoy_api_v2_endpoint_Endpoint *envoy_api_v2_endpoint_Endpoint_new(upb_arena *arena) { + return (envoy_api_v2_endpoint_Endpoint *)upb_msg_new(&envoy_api_v2_endpoint_Endpoint_msginit, arena); +} +UPB_INLINE envoy_api_v2_endpoint_Endpoint *envoy_api_v2_endpoint_Endpoint_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_endpoint_Endpoint *ret = envoy_api_v2_endpoint_Endpoint_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_endpoint_Endpoint_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_endpoint_Endpoint_serialize(const envoy_api_v2_endpoint_Endpoint *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_endpoint_Endpoint_msginit, arena, len); +} + +UPB_INLINE const struct envoy_api_v2_core_Address* envoy_api_v2_endpoint_Endpoint_address(const envoy_api_v2_endpoint_Endpoint *msg) { return UPB_FIELD_AT(msg, const struct envoy_api_v2_core_Address*, UPB_SIZE(0, 0)); } +UPB_INLINE const envoy_api_v2_endpoint_Endpoint_HealthCheckConfig* envoy_api_v2_endpoint_Endpoint_health_check_config(const envoy_api_v2_endpoint_Endpoint *msg) { return UPB_FIELD_AT(msg, const envoy_api_v2_endpoint_Endpoint_HealthCheckConfig*, UPB_SIZE(4, 8)); } + +UPB_INLINE void envoy_api_v2_endpoint_Endpoint_set_address(envoy_api_v2_endpoint_Endpoint *msg, struct envoy_api_v2_core_Address* value) { + UPB_FIELD_AT(msg, struct envoy_api_v2_core_Address*, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE struct envoy_api_v2_core_Address* envoy_api_v2_endpoint_Endpoint_mutable_address(envoy_api_v2_endpoint_Endpoint *msg, upb_arena *arena) { + struct envoy_api_v2_core_Address* sub = (struct envoy_api_v2_core_Address*)envoy_api_v2_endpoint_Endpoint_address(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_Address*)upb_msg_new(&envoy_api_v2_core_Address_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_endpoint_Endpoint_set_address(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_endpoint_Endpoint_set_health_check_config(envoy_api_v2_endpoint_Endpoint *msg, envoy_api_v2_endpoint_Endpoint_HealthCheckConfig* value) { + UPB_FIELD_AT(msg, envoy_api_v2_endpoint_Endpoint_HealthCheckConfig*, UPB_SIZE(4, 8)) = value; +} +UPB_INLINE struct envoy_api_v2_endpoint_Endpoint_HealthCheckConfig* envoy_api_v2_endpoint_Endpoint_mutable_health_check_config(envoy_api_v2_endpoint_Endpoint *msg, upb_arena *arena) { + struct envoy_api_v2_endpoint_Endpoint_HealthCheckConfig* sub = (struct envoy_api_v2_endpoint_Endpoint_HealthCheckConfig*)envoy_api_v2_endpoint_Endpoint_health_check_config(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_endpoint_Endpoint_HealthCheckConfig*)upb_msg_new(&envoy_api_v2_endpoint_Endpoint_HealthCheckConfig_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_endpoint_Endpoint_set_health_check_config(msg, sub); + } + return sub; +} + + +/* envoy.api.v2.endpoint.Endpoint.HealthCheckConfig */ + +UPB_INLINE envoy_api_v2_endpoint_Endpoint_HealthCheckConfig *envoy_api_v2_endpoint_Endpoint_HealthCheckConfig_new(upb_arena *arena) { + return (envoy_api_v2_endpoint_Endpoint_HealthCheckConfig *)upb_msg_new(&envoy_api_v2_endpoint_Endpoint_HealthCheckConfig_msginit, arena); +} +UPB_INLINE envoy_api_v2_endpoint_Endpoint_HealthCheckConfig *envoy_api_v2_endpoint_Endpoint_HealthCheckConfig_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_endpoint_Endpoint_HealthCheckConfig *ret = envoy_api_v2_endpoint_Endpoint_HealthCheckConfig_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_endpoint_Endpoint_HealthCheckConfig_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_endpoint_Endpoint_HealthCheckConfig_serialize(const envoy_api_v2_endpoint_Endpoint_HealthCheckConfig *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_endpoint_Endpoint_HealthCheckConfig_msginit, arena, len); +} + +UPB_INLINE uint32_t envoy_api_v2_endpoint_Endpoint_HealthCheckConfig_port_value(const envoy_api_v2_endpoint_Endpoint_HealthCheckConfig *msg) { return UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(0, 0)); } + +UPB_INLINE void envoy_api_v2_endpoint_Endpoint_HealthCheckConfig_set_port_value(envoy_api_v2_endpoint_Endpoint_HealthCheckConfig *msg, uint32_t value) { + UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(0, 0)) = value; +} + + +/* envoy.api.v2.endpoint.LbEndpoint */ + +UPB_INLINE envoy_api_v2_endpoint_LbEndpoint *envoy_api_v2_endpoint_LbEndpoint_new(upb_arena *arena) { + return (envoy_api_v2_endpoint_LbEndpoint *)upb_msg_new(&envoy_api_v2_endpoint_LbEndpoint_msginit, arena); +} +UPB_INLINE envoy_api_v2_endpoint_LbEndpoint *envoy_api_v2_endpoint_LbEndpoint_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_endpoint_LbEndpoint *ret = envoy_api_v2_endpoint_LbEndpoint_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_endpoint_LbEndpoint_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_endpoint_LbEndpoint_serialize(const envoy_api_v2_endpoint_LbEndpoint *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_endpoint_LbEndpoint_msginit, arena, len); +} + +UPB_INLINE const envoy_api_v2_endpoint_Endpoint* envoy_api_v2_endpoint_LbEndpoint_endpoint(const envoy_api_v2_endpoint_LbEndpoint *msg) { return UPB_FIELD_AT(msg, const envoy_api_v2_endpoint_Endpoint*, UPB_SIZE(8, 8)); } +UPB_INLINE int32_t envoy_api_v2_endpoint_LbEndpoint_health_status(const envoy_api_v2_endpoint_LbEndpoint *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(0, 0)); } +UPB_INLINE const struct envoy_api_v2_core_Metadata* envoy_api_v2_endpoint_LbEndpoint_metadata(const envoy_api_v2_endpoint_LbEndpoint *msg) { return UPB_FIELD_AT(msg, const struct envoy_api_v2_core_Metadata*, UPB_SIZE(12, 16)); } +UPB_INLINE const struct google_protobuf_UInt32Value* envoy_api_v2_endpoint_LbEndpoint_load_balancing_weight(const envoy_api_v2_endpoint_LbEndpoint *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt32Value*, UPB_SIZE(16, 24)); } + +UPB_INLINE void envoy_api_v2_endpoint_LbEndpoint_set_endpoint(envoy_api_v2_endpoint_LbEndpoint *msg, envoy_api_v2_endpoint_Endpoint* value) { + UPB_FIELD_AT(msg, envoy_api_v2_endpoint_Endpoint*, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE struct envoy_api_v2_endpoint_Endpoint* envoy_api_v2_endpoint_LbEndpoint_mutable_endpoint(envoy_api_v2_endpoint_LbEndpoint *msg, upb_arena *arena) { + struct envoy_api_v2_endpoint_Endpoint* sub = (struct envoy_api_v2_endpoint_Endpoint*)envoy_api_v2_endpoint_LbEndpoint_endpoint(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_endpoint_Endpoint*)upb_msg_new(&envoy_api_v2_endpoint_Endpoint_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_endpoint_LbEndpoint_set_endpoint(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_endpoint_LbEndpoint_set_health_status(envoy_api_v2_endpoint_LbEndpoint *msg, int32_t value) { + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_api_v2_endpoint_LbEndpoint_set_metadata(envoy_api_v2_endpoint_LbEndpoint *msg, struct envoy_api_v2_core_Metadata* value) { + UPB_FIELD_AT(msg, struct envoy_api_v2_core_Metadata*, UPB_SIZE(12, 16)) = value; +} +UPB_INLINE struct envoy_api_v2_core_Metadata* envoy_api_v2_endpoint_LbEndpoint_mutable_metadata(envoy_api_v2_endpoint_LbEndpoint *msg, upb_arena *arena) { + struct envoy_api_v2_core_Metadata* sub = (struct envoy_api_v2_core_Metadata*)envoy_api_v2_endpoint_LbEndpoint_metadata(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_Metadata*)upb_msg_new(&envoy_api_v2_core_Metadata_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_endpoint_LbEndpoint_set_metadata(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_endpoint_LbEndpoint_set_load_balancing_weight(envoy_api_v2_endpoint_LbEndpoint *msg, struct google_protobuf_UInt32Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt32Value*, UPB_SIZE(16, 24)) = value; +} +UPB_INLINE struct google_protobuf_UInt32Value* envoy_api_v2_endpoint_LbEndpoint_mutable_load_balancing_weight(envoy_api_v2_endpoint_LbEndpoint *msg, upb_arena *arena) { + struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_api_v2_endpoint_LbEndpoint_load_balancing_weight(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt32Value*)upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_endpoint_LbEndpoint_set_load_balancing_weight(msg, sub); + } + return sub; +} + + +/* envoy.api.v2.endpoint.LocalityLbEndpoints */ + +UPB_INLINE envoy_api_v2_endpoint_LocalityLbEndpoints *envoy_api_v2_endpoint_LocalityLbEndpoints_new(upb_arena *arena) { + return (envoy_api_v2_endpoint_LocalityLbEndpoints *)upb_msg_new(&envoy_api_v2_endpoint_LocalityLbEndpoints_msginit, arena); +} +UPB_INLINE envoy_api_v2_endpoint_LocalityLbEndpoints *envoy_api_v2_endpoint_LocalityLbEndpoints_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_endpoint_LocalityLbEndpoints *ret = envoy_api_v2_endpoint_LocalityLbEndpoints_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_endpoint_LocalityLbEndpoints_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_endpoint_LocalityLbEndpoints_serialize(const envoy_api_v2_endpoint_LocalityLbEndpoints *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_endpoint_LocalityLbEndpoints_msginit, arena, len); +} + +UPB_INLINE const struct envoy_api_v2_core_Locality* envoy_api_v2_endpoint_LocalityLbEndpoints_locality(const envoy_api_v2_endpoint_LocalityLbEndpoints *msg) { return UPB_FIELD_AT(msg, const struct envoy_api_v2_core_Locality*, UPB_SIZE(4, 8)); } +UPB_INLINE const envoy_api_v2_endpoint_LbEndpoint* const* envoy_api_v2_endpoint_LocalityLbEndpoints_lb_endpoints(const envoy_api_v2_endpoint_LocalityLbEndpoints *msg, size_t *len) { return (const envoy_api_v2_endpoint_LbEndpoint* const*)_upb_array_accessor(msg, UPB_SIZE(12, 24), len); } +UPB_INLINE const struct google_protobuf_UInt32Value* envoy_api_v2_endpoint_LocalityLbEndpoints_load_balancing_weight(const envoy_api_v2_endpoint_LocalityLbEndpoints *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt32Value*, UPB_SIZE(8, 16)); } +UPB_INLINE uint32_t envoy_api_v2_endpoint_LocalityLbEndpoints_priority(const envoy_api_v2_endpoint_LocalityLbEndpoints *msg) { return UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(0, 0)); } + +UPB_INLINE void envoy_api_v2_endpoint_LocalityLbEndpoints_set_locality(envoy_api_v2_endpoint_LocalityLbEndpoints *msg, struct envoy_api_v2_core_Locality* value) { + UPB_FIELD_AT(msg, struct envoy_api_v2_core_Locality*, UPB_SIZE(4, 8)) = value; +} +UPB_INLINE struct envoy_api_v2_core_Locality* envoy_api_v2_endpoint_LocalityLbEndpoints_mutable_locality(envoy_api_v2_endpoint_LocalityLbEndpoints *msg, upb_arena *arena) { + struct envoy_api_v2_core_Locality* sub = (struct envoy_api_v2_core_Locality*)envoy_api_v2_endpoint_LocalityLbEndpoints_locality(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_Locality*)upb_msg_new(&envoy_api_v2_core_Locality_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_endpoint_LocalityLbEndpoints_set_locality(msg, sub); + } + return sub; +} +UPB_INLINE envoy_api_v2_endpoint_LbEndpoint** envoy_api_v2_endpoint_LocalityLbEndpoints_mutable_lb_endpoints(envoy_api_v2_endpoint_LocalityLbEndpoints *msg, size_t *len) { + return (envoy_api_v2_endpoint_LbEndpoint**)_upb_array_mutable_accessor(msg, UPB_SIZE(12, 24), len); +} +UPB_INLINE envoy_api_v2_endpoint_LbEndpoint** envoy_api_v2_endpoint_LocalityLbEndpoints_resize_lb_endpoints(envoy_api_v2_endpoint_LocalityLbEndpoints *msg, size_t len, upb_arena *arena) { + return (envoy_api_v2_endpoint_LbEndpoint**)_upb_array_resize_accessor(msg, UPB_SIZE(12, 24), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct envoy_api_v2_endpoint_LbEndpoint* envoy_api_v2_endpoint_LocalityLbEndpoints_add_lb_endpoints(envoy_api_v2_endpoint_LocalityLbEndpoints *msg, upb_arena *arena) { + struct envoy_api_v2_endpoint_LbEndpoint* sub = (struct envoy_api_v2_endpoint_LbEndpoint*)upb_msg_new(&envoy_api_v2_endpoint_LbEndpoint_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(12, 24), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE void envoy_api_v2_endpoint_LocalityLbEndpoints_set_load_balancing_weight(envoy_api_v2_endpoint_LocalityLbEndpoints *msg, struct google_protobuf_UInt32Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt32Value*, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE struct google_protobuf_UInt32Value* envoy_api_v2_endpoint_LocalityLbEndpoints_mutable_load_balancing_weight(envoy_api_v2_endpoint_LocalityLbEndpoints *msg, upb_arena *arena) { + struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_api_v2_endpoint_LocalityLbEndpoints_load_balancing_weight(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt32Value*)upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_endpoint_LocalityLbEndpoints_set_load_balancing_weight(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_endpoint_LocalityLbEndpoints_set_priority(envoy_api_v2_endpoint_LocalityLbEndpoints *msg, uint32_t value) { + UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(0, 0)) = value; +} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* ENVOY_API_V2_ENDPOINT_ENDPOINT_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/envoy/api/v2/endpoint/load_report.upb.c b/src/core/ext/upb-generated/envoy/api/v2/endpoint/load_report.upb.c new file mode 100644 index 00000000000..2af77c59efb --- /dev/null +++ b/src/core/ext/upb-generated/envoy/api/v2/endpoint/load_report.upb.c @@ -0,0 +1,105 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/api/v2/endpoint/load_report.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include +#include "upb/msg.h" +#include "envoy/api/v2/endpoint/load_report.upb.h" +#include "envoy/api/v2/core/address.upb.h" +#include "envoy/api/v2/core/base.upb.h" +#include "google/protobuf/duration.upb.h" +#include "validate/validate.upb.h" +#include "gogoproto/gogo.upb.h" + +#include "upb/port_def.inc" + +static const upb_msglayout *const envoy_api_v2_endpoint_UpstreamLocalityStats_submsgs[3] = { + &envoy_api_v2_core_Locality_msginit, + &envoy_api_v2_endpoint_EndpointLoadMetricStats_msginit, + &envoy_api_v2_endpoint_UpstreamEndpointStats_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_endpoint_UpstreamLocalityStats__fields[7] = { + {1, UPB_SIZE(28, 32), 0, 0, 11, 1}, + {2, UPB_SIZE(0, 0), 0, 0, 4, 1}, + {3, UPB_SIZE(8, 8), 0, 0, 4, 1}, + {4, UPB_SIZE(16, 16), 0, 0, 4, 1}, + {5, UPB_SIZE(32, 40), 0, 1, 11, 3}, + {6, UPB_SIZE(24, 24), 0, 0, 13, 1}, + {7, UPB_SIZE(36, 48), 0, 2, 11, 3}, +}; + +const upb_msglayout envoy_api_v2_endpoint_UpstreamLocalityStats_msginit = { + &envoy_api_v2_endpoint_UpstreamLocalityStats_submsgs[0], + &envoy_api_v2_endpoint_UpstreamLocalityStats__fields[0], + UPB_SIZE(40, 56), 7, false, +}; + +static const upb_msglayout *const envoy_api_v2_endpoint_UpstreamEndpointStats_submsgs[2] = { + &envoy_api_v2_core_Address_msginit, + &envoy_api_v2_endpoint_EndpointLoadMetricStats_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_endpoint_UpstreamEndpointStats__fields[5] = { + {1, UPB_SIZE(24, 24), 0, 0, 11, 1}, + {2, UPB_SIZE(0, 0), 0, 0, 4, 1}, + {3, UPB_SIZE(8, 8), 0, 0, 4, 1}, + {4, UPB_SIZE(16, 16), 0, 0, 4, 1}, + {5, UPB_SIZE(28, 32), 0, 1, 11, 3}, +}; + +const upb_msglayout envoy_api_v2_endpoint_UpstreamEndpointStats_msginit = { + &envoy_api_v2_endpoint_UpstreamEndpointStats_submsgs[0], + &envoy_api_v2_endpoint_UpstreamEndpointStats__fields[0], + UPB_SIZE(32, 40), 5, false, +}; + +static const upb_msglayout_field envoy_api_v2_endpoint_EndpointLoadMetricStats__fields[3] = { + {1, UPB_SIZE(16, 16), 0, 0, 9, 1}, + {2, UPB_SIZE(0, 0), 0, 0, 4, 1}, + {3, UPB_SIZE(8, 8), 0, 0, 1, 1}, +}; + +const upb_msglayout envoy_api_v2_endpoint_EndpointLoadMetricStats_msginit = { + NULL, + &envoy_api_v2_endpoint_EndpointLoadMetricStats__fields[0], + UPB_SIZE(24, 32), 3, false, +}; + +static const upb_msglayout *const envoy_api_v2_endpoint_ClusterStats_submsgs[3] = { + &envoy_api_v2_endpoint_ClusterStats_DroppedRequests_msginit, + &envoy_api_v2_endpoint_UpstreamLocalityStats_msginit, + &google_protobuf_Duration_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_endpoint_ClusterStats__fields[5] = { + {1, UPB_SIZE(8, 8), 0, 0, 9, 1}, + {2, UPB_SIZE(20, 32), 0, 1, 11, 3}, + {3, UPB_SIZE(0, 0), 0, 0, 4, 1}, + {4, UPB_SIZE(16, 24), 0, 2, 11, 1}, + {5, UPB_SIZE(24, 40), 0, 0, 11, 3}, +}; + +const upb_msglayout envoy_api_v2_endpoint_ClusterStats_msginit = { + &envoy_api_v2_endpoint_ClusterStats_submsgs[0], + &envoy_api_v2_endpoint_ClusterStats__fields[0], + UPB_SIZE(32, 48), 5, false, +}; + +static const upb_msglayout_field envoy_api_v2_endpoint_ClusterStats_DroppedRequests__fields[2] = { + {1, UPB_SIZE(8, 8), 0, 0, 9, 1}, + {2, UPB_SIZE(0, 0), 0, 0, 4, 1}, +}; + +const upb_msglayout envoy_api_v2_endpoint_ClusterStats_DroppedRequests_msginit = { + NULL, + &envoy_api_v2_endpoint_ClusterStats_DroppedRequests__fields[0], + UPB_SIZE(16, 32), 2, false, +}; + +#include "upb/port_undef.inc" + diff --git a/src/core/ext/upb-generated/envoy/api/v2/endpoint/load_report.upb.h b/src/core/ext/upb-generated/envoy/api/v2/endpoint/load_report.upb.h new file mode 100644 index 00000000000..7ee2129f436 --- /dev/null +++ b/src/core/ext/upb-generated/envoy/api/v2/endpoint/load_report.upb.h @@ -0,0 +1,299 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/api/v2/endpoint/load_report.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef ENVOY_API_V2_ENDPOINT_LOAD_REPORT_PROTO_UPB_H_ +#define ENVOY_API_V2_ENDPOINT_LOAD_REPORT_PROTO_UPB_H_ + +#include "upb/generated_util.h" + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +#ifdef __cplusplus +extern "C" { +#endif + +struct envoy_api_v2_endpoint_UpstreamLocalityStats; +struct envoy_api_v2_endpoint_UpstreamEndpointStats; +struct envoy_api_v2_endpoint_EndpointLoadMetricStats; +struct envoy_api_v2_endpoint_ClusterStats; +struct envoy_api_v2_endpoint_ClusterStats_DroppedRequests; +typedef struct envoy_api_v2_endpoint_UpstreamLocalityStats envoy_api_v2_endpoint_UpstreamLocalityStats; +typedef struct envoy_api_v2_endpoint_UpstreamEndpointStats envoy_api_v2_endpoint_UpstreamEndpointStats; +typedef struct envoy_api_v2_endpoint_EndpointLoadMetricStats envoy_api_v2_endpoint_EndpointLoadMetricStats; +typedef struct envoy_api_v2_endpoint_ClusterStats envoy_api_v2_endpoint_ClusterStats; +typedef struct envoy_api_v2_endpoint_ClusterStats_DroppedRequests envoy_api_v2_endpoint_ClusterStats_DroppedRequests; +extern const upb_msglayout envoy_api_v2_endpoint_UpstreamLocalityStats_msginit; +extern const upb_msglayout envoy_api_v2_endpoint_UpstreamEndpointStats_msginit; +extern const upb_msglayout envoy_api_v2_endpoint_EndpointLoadMetricStats_msginit; +extern const upb_msglayout envoy_api_v2_endpoint_ClusterStats_msginit; +extern const upb_msglayout envoy_api_v2_endpoint_ClusterStats_DroppedRequests_msginit; +struct envoy_api_v2_core_Address; +struct envoy_api_v2_core_Locality; +struct google_protobuf_Duration; +extern const upb_msglayout envoy_api_v2_core_Address_msginit; +extern const upb_msglayout envoy_api_v2_core_Locality_msginit; +extern const upb_msglayout google_protobuf_Duration_msginit; + +/* Enums */ + + +/* envoy.api.v2.endpoint.UpstreamLocalityStats */ + +UPB_INLINE envoy_api_v2_endpoint_UpstreamLocalityStats *envoy_api_v2_endpoint_UpstreamLocalityStats_new(upb_arena *arena) { + return (envoy_api_v2_endpoint_UpstreamLocalityStats *)upb_msg_new(&envoy_api_v2_endpoint_UpstreamLocalityStats_msginit, arena); +} +UPB_INLINE envoy_api_v2_endpoint_UpstreamLocalityStats *envoy_api_v2_endpoint_UpstreamLocalityStats_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_endpoint_UpstreamLocalityStats *ret = envoy_api_v2_endpoint_UpstreamLocalityStats_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_endpoint_UpstreamLocalityStats_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_endpoint_UpstreamLocalityStats_serialize(const envoy_api_v2_endpoint_UpstreamLocalityStats *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_endpoint_UpstreamLocalityStats_msginit, arena, len); +} + +UPB_INLINE const struct envoy_api_v2_core_Locality* envoy_api_v2_endpoint_UpstreamLocalityStats_locality(const envoy_api_v2_endpoint_UpstreamLocalityStats *msg) { return UPB_FIELD_AT(msg, const struct envoy_api_v2_core_Locality*, UPB_SIZE(28, 32)); } +UPB_INLINE uint64_t envoy_api_v2_endpoint_UpstreamLocalityStats_total_successful_requests(const envoy_api_v2_endpoint_UpstreamLocalityStats *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(0, 0)); } +UPB_INLINE uint64_t envoy_api_v2_endpoint_UpstreamLocalityStats_total_requests_in_progress(const envoy_api_v2_endpoint_UpstreamLocalityStats *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(8, 8)); } +UPB_INLINE uint64_t envoy_api_v2_endpoint_UpstreamLocalityStats_total_error_requests(const envoy_api_v2_endpoint_UpstreamLocalityStats *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(16, 16)); } +UPB_INLINE const envoy_api_v2_endpoint_EndpointLoadMetricStats* const* envoy_api_v2_endpoint_UpstreamLocalityStats_load_metric_stats(const envoy_api_v2_endpoint_UpstreamLocalityStats *msg, size_t *len) { return (const envoy_api_v2_endpoint_EndpointLoadMetricStats* const*)_upb_array_accessor(msg, UPB_SIZE(32, 40), len); } +UPB_INLINE uint32_t envoy_api_v2_endpoint_UpstreamLocalityStats_priority(const envoy_api_v2_endpoint_UpstreamLocalityStats *msg) { return UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(24, 24)); } +UPB_INLINE const envoy_api_v2_endpoint_UpstreamEndpointStats* const* envoy_api_v2_endpoint_UpstreamLocalityStats_upstream_endpoint_stats(const envoy_api_v2_endpoint_UpstreamLocalityStats *msg, size_t *len) { return (const envoy_api_v2_endpoint_UpstreamEndpointStats* const*)_upb_array_accessor(msg, UPB_SIZE(36, 48), len); } + +UPB_INLINE void envoy_api_v2_endpoint_UpstreamLocalityStats_set_locality(envoy_api_v2_endpoint_UpstreamLocalityStats *msg, struct envoy_api_v2_core_Locality* value) { + UPB_FIELD_AT(msg, struct envoy_api_v2_core_Locality*, UPB_SIZE(28, 32)) = value; +} +UPB_INLINE struct envoy_api_v2_core_Locality* envoy_api_v2_endpoint_UpstreamLocalityStats_mutable_locality(envoy_api_v2_endpoint_UpstreamLocalityStats *msg, upb_arena *arena) { + struct envoy_api_v2_core_Locality* sub = (struct envoy_api_v2_core_Locality*)envoy_api_v2_endpoint_UpstreamLocalityStats_locality(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_Locality*)upb_msg_new(&envoy_api_v2_core_Locality_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_endpoint_UpstreamLocalityStats_set_locality(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_endpoint_UpstreamLocalityStats_set_total_successful_requests(envoy_api_v2_endpoint_UpstreamLocalityStats *msg, uint64_t value) { + UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_api_v2_endpoint_UpstreamLocalityStats_set_total_requests_in_progress(envoy_api_v2_endpoint_UpstreamLocalityStats *msg, uint64_t value) { + UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE void envoy_api_v2_endpoint_UpstreamLocalityStats_set_total_error_requests(envoy_api_v2_endpoint_UpstreamLocalityStats *msg, uint64_t value) { + UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(16, 16)) = value; +} +UPB_INLINE envoy_api_v2_endpoint_EndpointLoadMetricStats** envoy_api_v2_endpoint_UpstreamLocalityStats_mutable_load_metric_stats(envoy_api_v2_endpoint_UpstreamLocalityStats *msg, size_t *len) { + return (envoy_api_v2_endpoint_EndpointLoadMetricStats**)_upb_array_mutable_accessor(msg, UPB_SIZE(32, 40), len); +} +UPB_INLINE envoy_api_v2_endpoint_EndpointLoadMetricStats** envoy_api_v2_endpoint_UpstreamLocalityStats_resize_load_metric_stats(envoy_api_v2_endpoint_UpstreamLocalityStats *msg, size_t len, upb_arena *arena) { + return (envoy_api_v2_endpoint_EndpointLoadMetricStats**)_upb_array_resize_accessor(msg, UPB_SIZE(32, 40), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct envoy_api_v2_endpoint_EndpointLoadMetricStats* envoy_api_v2_endpoint_UpstreamLocalityStats_add_load_metric_stats(envoy_api_v2_endpoint_UpstreamLocalityStats *msg, upb_arena *arena) { + struct envoy_api_v2_endpoint_EndpointLoadMetricStats* sub = (struct envoy_api_v2_endpoint_EndpointLoadMetricStats*)upb_msg_new(&envoy_api_v2_endpoint_EndpointLoadMetricStats_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(32, 40), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE void envoy_api_v2_endpoint_UpstreamLocalityStats_set_priority(envoy_api_v2_endpoint_UpstreamLocalityStats *msg, uint32_t value) { + UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(24, 24)) = value; +} +UPB_INLINE envoy_api_v2_endpoint_UpstreamEndpointStats** envoy_api_v2_endpoint_UpstreamLocalityStats_mutable_upstream_endpoint_stats(envoy_api_v2_endpoint_UpstreamLocalityStats *msg, size_t *len) { + return (envoy_api_v2_endpoint_UpstreamEndpointStats**)_upb_array_mutable_accessor(msg, UPB_SIZE(36, 48), len); +} +UPB_INLINE envoy_api_v2_endpoint_UpstreamEndpointStats** envoy_api_v2_endpoint_UpstreamLocalityStats_resize_upstream_endpoint_stats(envoy_api_v2_endpoint_UpstreamLocalityStats *msg, size_t len, upb_arena *arena) { + return (envoy_api_v2_endpoint_UpstreamEndpointStats**)_upb_array_resize_accessor(msg, UPB_SIZE(36, 48), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct envoy_api_v2_endpoint_UpstreamEndpointStats* envoy_api_v2_endpoint_UpstreamLocalityStats_add_upstream_endpoint_stats(envoy_api_v2_endpoint_UpstreamLocalityStats *msg, upb_arena *arena) { + struct envoy_api_v2_endpoint_UpstreamEndpointStats* sub = (struct envoy_api_v2_endpoint_UpstreamEndpointStats*)upb_msg_new(&envoy_api_v2_endpoint_UpstreamEndpointStats_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(36, 48), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} + + +/* envoy.api.v2.endpoint.UpstreamEndpointStats */ + +UPB_INLINE envoy_api_v2_endpoint_UpstreamEndpointStats *envoy_api_v2_endpoint_UpstreamEndpointStats_new(upb_arena *arena) { + return (envoy_api_v2_endpoint_UpstreamEndpointStats *)upb_msg_new(&envoy_api_v2_endpoint_UpstreamEndpointStats_msginit, arena); +} +UPB_INLINE envoy_api_v2_endpoint_UpstreamEndpointStats *envoy_api_v2_endpoint_UpstreamEndpointStats_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_endpoint_UpstreamEndpointStats *ret = envoy_api_v2_endpoint_UpstreamEndpointStats_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_endpoint_UpstreamEndpointStats_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_endpoint_UpstreamEndpointStats_serialize(const envoy_api_v2_endpoint_UpstreamEndpointStats *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_endpoint_UpstreamEndpointStats_msginit, arena, len); +} + +UPB_INLINE const struct envoy_api_v2_core_Address* envoy_api_v2_endpoint_UpstreamEndpointStats_address(const envoy_api_v2_endpoint_UpstreamEndpointStats *msg) { return UPB_FIELD_AT(msg, const struct envoy_api_v2_core_Address*, UPB_SIZE(24, 24)); } +UPB_INLINE uint64_t envoy_api_v2_endpoint_UpstreamEndpointStats_total_successful_requests(const envoy_api_v2_endpoint_UpstreamEndpointStats *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(0, 0)); } +UPB_INLINE uint64_t envoy_api_v2_endpoint_UpstreamEndpointStats_total_requests_in_progress(const envoy_api_v2_endpoint_UpstreamEndpointStats *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(8, 8)); } +UPB_INLINE uint64_t envoy_api_v2_endpoint_UpstreamEndpointStats_total_error_requests(const envoy_api_v2_endpoint_UpstreamEndpointStats *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(16, 16)); } +UPB_INLINE const envoy_api_v2_endpoint_EndpointLoadMetricStats* const* envoy_api_v2_endpoint_UpstreamEndpointStats_load_metric_stats(const envoy_api_v2_endpoint_UpstreamEndpointStats *msg, size_t *len) { return (const envoy_api_v2_endpoint_EndpointLoadMetricStats* const*)_upb_array_accessor(msg, UPB_SIZE(28, 32), len); } + +UPB_INLINE void envoy_api_v2_endpoint_UpstreamEndpointStats_set_address(envoy_api_v2_endpoint_UpstreamEndpointStats *msg, struct envoy_api_v2_core_Address* value) { + UPB_FIELD_AT(msg, struct envoy_api_v2_core_Address*, UPB_SIZE(24, 24)) = value; +} +UPB_INLINE struct envoy_api_v2_core_Address* envoy_api_v2_endpoint_UpstreamEndpointStats_mutable_address(envoy_api_v2_endpoint_UpstreamEndpointStats *msg, upb_arena *arena) { + struct envoy_api_v2_core_Address* sub = (struct envoy_api_v2_core_Address*)envoy_api_v2_endpoint_UpstreamEndpointStats_address(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_Address*)upb_msg_new(&envoy_api_v2_core_Address_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_endpoint_UpstreamEndpointStats_set_address(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_endpoint_UpstreamEndpointStats_set_total_successful_requests(envoy_api_v2_endpoint_UpstreamEndpointStats *msg, uint64_t value) { + UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_api_v2_endpoint_UpstreamEndpointStats_set_total_requests_in_progress(envoy_api_v2_endpoint_UpstreamEndpointStats *msg, uint64_t value) { + UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE void envoy_api_v2_endpoint_UpstreamEndpointStats_set_total_error_requests(envoy_api_v2_endpoint_UpstreamEndpointStats *msg, uint64_t value) { + UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(16, 16)) = value; +} +UPB_INLINE envoy_api_v2_endpoint_EndpointLoadMetricStats** envoy_api_v2_endpoint_UpstreamEndpointStats_mutable_load_metric_stats(envoy_api_v2_endpoint_UpstreamEndpointStats *msg, size_t *len) { + return (envoy_api_v2_endpoint_EndpointLoadMetricStats**)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 32), len); +} +UPB_INLINE envoy_api_v2_endpoint_EndpointLoadMetricStats** envoy_api_v2_endpoint_UpstreamEndpointStats_resize_load_metric_stats(envoy_api_v2_endpoint_UpstreamEndpointStats *msg, size_t len, upb_arena *arena) { + return (envoy_api_v2_endpoint_EndpointLoadMetricStats**)_upb_array_resize_accessor(msg, UPB_SIZE(28, 32), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct envoy_api_v2_endpoint_EndpointLoadMetricStats* envoy_api_v2_endpoint_UpstreamEndpointStats_add_load_metric_stats(envoy_api_v2_endpoint_UpstreamEndpointStats *msg, upb_arena *arena) { + struct envoy_api_v2_endpoint_EndpointLoadMetricStats* sub = (struct envoy_api_v2_endpoint_EndpointLoadMetricStats*)upb_msg_new(&envoy_api_v2_endpoint_EndpointLoadMetricStats_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(28, 32), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} + + +/* envoy.api.v2.endpoint.EndpointLoadMetricStats */ + +UPB_INLINE envoy_api_v2_endpoint_EndpointLoadMetricStats *envoy_api_v2_endpoint_EndpointLoadMetricStats_new(upb_arena *arena) { + return (envoy_api_v2_endpoint_EndpointLoadMetricStats *)upb_msg_new(&envoy_api_v2_endpoint_EndpointLoadMetricStats_msginit, arena); +} +UPB_INLINE envoy_api_v2_endpoint_EndpointLoadMetricStats *envoy_api_v2_endpoint_EndpointLoadMetricStats_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_endpoint_EndpointLoadMetricStats *ret = envoy_api_v2_endpoint_EndpointLoadMetricStats_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_endpoint_EndpointLoadMetricStats_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_endpoint_EndpointLoadMetricStats_serialize(const envoy_api_v2_endpoint_EndpointLoadMetricStats *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_endpoint_EndpointLoadMetricStats_msginit, arena, len); +} + +UPB_INLINE upb_strview envoy_api_v2_endpoint_EndpointLoadMetricStats_metric_name(const envoy_api_v2_endpoint_EndpointLoadMetricStats *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(16, 16)); } +UPB_INLINE uint64_t envoy_api_v2_endpoint_EndpointLoadMetricStats_num_requests_finished_with_metric(const envoy_api_v2_endpoint_EndpointLoadMetricStats *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(0, 0)); } +UPB_INLINE double envoy_api_v2_endpoint_EndpointLoadMetricStats_total_metric_value(const envoy_api_v2_endpoint_EndpointLoadMetricStats *msg) { return UPB_FIELD_AT(msg, double, UPB_SIZE(8, 8)); } + +UPB_INLINE void envoy_api_v2_endpoint_EndpointLoadMetricStats_set_metric_name(envoy_api_v2_endpoint_EndpointLoadMetricStats *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(16, 16)) = value; +} +UPB_INLINE void envoy_api_v2_endpoint_EndpointLoadMetricStats_set_num_requests_finished_with_metric(envoy_api_v2_endpoint_EndpointLoadMetricStats *msg, uint64_t value) { + UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_api_v2_endpoint_EndpointLoadMetricStats_set_total_metric_value(envoy_api_v2_endpoint_EndpointLoadMetricStats *msg, double value) { + UPB_FIELD_AT(msg, double, UPB_SIZE(8, 8)) = value; +} + + +/* envoy.api.v2.endpoint.ClusterStats */ + +UPB_INLINE envoy_api_v2_endpoint_ClusterStats *envoy_api_v2_endpoint_ClusterStats_new(upb_arena *arena) { + return (envoy_api_v2_endpoint_ClusterStats *)upb_msg_new(&envoy_api_v2_endpoint_ClusterStats_msginit, arena); +} +UPB_INLINE envoy_api_v2_endpoint_ClusterStats *envoy_api_v2_endpoint_ClusterStats_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_endpoint_ClusterStats *ret = envoy_api_v2_endpoint_ClusterStats_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_endpoint_ClusterStats_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_endpoint_ClusterStats_serialize(const envoy_api_v2_endpoint_ClusterStats *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_endpoint_ClusterStats_msginit, arena, len); +} + +UPB_INLINE upb_strview envoy_api_v2_endpoint_ClusterStats_cluster_name(const envoy_api_v2_endpoint_ClusterStats *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 8)); } +UPB_INLINE const envoy_api_v2_endpoint_UpstreamLocalityStats* const* envoy_api_v2_endpoint_ClusterStats_upstream_locality_stats(const envoy_api_v2_endpoint_ClusterStats *msg, size_t *len) { return (const envoy_api_v2_endpoint_UpstreamLocalityStats* const*)_upb_array_accessor(msg, UPB_SIZE(20, 32), len); } +UPB_INLINE uint64_t envoy_api_v2_endpoint_ClusterStats_total_dropped_requests(const envoy_api_v2_endpoint_ClusterStats *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(0, 0)); } +UPB_INLINE const struct google_protobuf_Duration* envoy_api_v2_endpoint_ClusterStats_load_report_interval(const envoy_api_v2_endpoint_ClusterStats *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Duration*, UPB_SIZE(16, 24)); } +UPB_INLINE const envoy_api_v2_endpoint_ClusterStats_DroppedRequests* const* envoy_api_v2_endpoint_ClusterStats_dropped_requests(const envoy_api_v2_endpoint_ClusterStats *msg, size_t *len) { return (const envoy_api_v2_endpoint_ClusterStats_DroppedRequests* const*)_upb_array_accessor(msg, UPB_SIZE(24, 40), len); } + +UPB_INLINE void envoy_api_v2_endpoint_ClusterStats_set_cluster_name(envoy_api_v2_endpoint_ClusterStats *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE envoy_api_v2_endpoint_UpstreamLocalityStats** envoy_api_v2_endpoint_ClusterStats_mutable_upstream_locality_stats(envoy_api_v2_endpoint_ClusterStats *msg, size_t *len) { + return (envoy_api_v2_endpoint_UpstreamLocalityStats**)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 32), len); +} +UPB_INLINE envoy_api_v2_endpoint_UpstreamLocalityStats** envoy_api_v2_endpoint_ClusterStats_resize_upstream_locality_stats(envoy_api_v2_endpoint_ClusterStats *msg, size_t len, upb_arena *arena) { + return (envoy_api_v2_endpoint_UpstreamLocalityStats**)_upb_array_resize_accessor(msg, UPB_SIZE(20, 32), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct envoy_api_v2_endpoint_UpstreamLocalityStats* envoy_api_v2_endpoint_ClusterStats_add_upstream_locality_stats(envoy_api_v2_endpoint_ClusterStats *msg, upb_arena *arena) { + struct envoy_api_v2_endpoint_UpstreamLocalityStats* sub = (struct envoy_api_v2_endpoint_UpstreamLocalityStats*)upb_msg_new(&envoy_api_v2_endpoint_UpstreamLocalityStats_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(20, 32), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE void envoy_api_v2_endpoint_ClusterStats_set_total_dropped_requests(envoy_api_v2_endpoint_ClusterStats *msg, uint64_t value) { + UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_api_v2_endpoint_ClusterStats_set_load_report_interval(envoy_api_v2_endpoint_ClusterStats *msg, struct google_protobuf_Duration* value) { + UPB_FIELD_AT(msg, struct google_protobuf_Duration*, UPB_SIZE(16, 24)) = value; +} +UPB_INLINE struct google_protobuf_Duration* envoy_api_v2_endpoint_ClusterStats_mutable_load_report_interval(envoy_api_v2_endpoint_ClusterStats *msg, upb_arena *arena) { + struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_api_v2_endpoint_ClusterStats_load_report_interval(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Duration*)upb_msg_new(&google_protobuf_Duration_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_endpoint_ClusterStats_set_load_report_interval(msg, sub); + } + return sub; +} +UPB_INLINE envoy_api_v2_endpoint_ClusterStats_DroppedRequests** envoy_api_v2_endpoint_ClusterStats_mutable_dropped_requests(envoy_api_v2_endpoint_ClusterStats *msg, size_t *len) { + return (envoy_api_v2_endpoint_ClusterStats_DroppedRequests**)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 40), len); +} +UPB_INLINE envoy_api_v2_endpoint_ClusterStats_DroppedRequests** envoy_api_v2_endpoint_ClusterStats_resize_dropped_requests(envoy_api_v2_endpoint_ClusterStats *msg, size_t len, upb_arena *arena) { + return (envoy_api_v2_endpoint_ClusterStats_DroppedRequests**)_upb_array_resize_accessor(msg, UPB_SIZE(24, 40), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct envoy_api_v2_endpoint_ClusterStats_DroppedRequests* envoy_api_v2_endpoint_ClusterStats_add_dropped_requests(envoy_api_v2_endpoint_ClusterStats *msg, upb_arena *arena) { + struct envoy_api_v2_endpoint_ClusterStats_DroppedRequests* sub = (struct envoy_api_v2_endpoint_ClusterStats_DroppedRequests*)upb_msg_new(&envoy_api_v2_endpoint_ClusterStats_DroppedRequests_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(24, 40), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} + + +/* envoy.api.v2.endpoint.ClusterStats.DroppedRequests */ + +UPB_INLINE envoy_api_v2_endpoint_ClusterStats_DroppedRequests *envoy_api_v2_endpoint_ClusterStats_DroppedRequests_new(upb_arena *arena) { + return (envoy_api_v2_endpoint_ClusterStats_DroppedRequests *)upb_msg_new(&envoy_api_v2_endpoint_ClusterStats_DroppedRequests_msginit, arena); +} +UPB_INLINE envoy_api_v2_endpoint_ClusterStats_DroppedRequests *envoy_api_v2_endpoint_ClusterStats_DroppedRequests_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_endpoint_ClusterStats_DroppedRequests *ret = envoy_api_v2_endpoint_ClusterStats_DroppedRequests_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_endpoint_ClusterStats_DroppedRequests_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_endpoint_ClusterStats_DroppedRequests_serialize(const envoy_api_v2_endpoint_ClusterStats_DroppedRequests *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_endpoint_ClusterStats_DroppedRequests_msginit, arena, len); +} + +UPB_INLINE upb_strview envoy_api_v2_endpoint_ClusterStats_DroppedRequests_category(const envoy_api_v2_endpoint_ClusterStats_DroppedRequests *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 8)); } +UPB_INLINE uint64_t envoy_api_v2_endpoint_ClusterStats_DroppedRequests_dropped_count(const envoy_api_v2_endpoint_ClusterStats_DroppedRequests *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(0, 0)); } + +UPB_INLINE void envoy_api_v2_endpoint_ClusterStats_DroppedRequests_set_category(envoy_api_v2_endpoint_ClusterStats_DroppedRequests *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE void envoy_api_v2_endpoint_ClusterStats_DroppedRequests_set_dropped_count(envoy_api_v2_endpoint_ClusterStats_DroppedRequests *msg, uint64_t value) { + UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(0, 0)) = value; +} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* ENVOY_API_V2_ENDPOINT_LOAD_REPORT_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/envoy/service/discovery/v2/ads.upb.c b/src/core/ext/upb-generated/envoy/service/discovery/v2/ads.upb.c new file mode 100644 index 00000000000..5611346c3fd --- /dev/null +++ b/src/core/ext/upb-generated/envoy/service/discovery/v2/ads.upb.c @@ -0,0 +1,23 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/service/discovery/v2/ads.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include +#include "upb/msg.h" +#include "envoy/service/discovery/v2/ads.upb.h" +#include "envoy/api/v2/discovery.upb.h" + +#include "upb/port_def.inc" + +const upb_msglayout envoy_service_discovery_v2_AdsDummy_msginit = { + NULL, + NULL, + UPB_SIZE(0, 0), 0, false, +}; + +#include "upb/port_undef.inc" + diff --git a/src/core/ext/upb-generated/envoy/service/discovery/v2/ads.upb.h b/src/core/ext/upb-generated/envoy/service/discovery/v2/ads.upb.h new file mode 100644 index 00000000000..d5f1b90a032 --- /dev/null +++ b/src/core/ext/upb-generated/envoy/service/discovery/v2/ads.upb.h @@ -0,0 +1,52 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/service/discovery/v2/ads.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef ENVOY_SERVICE_DISCOVERY_V2_ADS_PROTO_UPB_H_ +#define ENVOY_SERVICE_DISCOVERY_V2_ADS_PROTO_UPB_H_ + +#include "upb/generated_util.h" + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +#ifdef __cplusplus +extern "C" { +#endif + +struct envoy_service_discovery_v2_AdsDummy; +typedef struct envoy_service_discovery_v2_AdsDummy envoy_service_discovery_v2_AdsDummy; +extern const upb_msglayout envoy_service_discovery_v2_AdsDummy_msginit; + +/* Enums */ + + +/* envoy.service.discovery.v2.AdsDummy */ + +UPB_INLINE envoy_service_discovery_v2_AdsDummy *envoy_service_discovery_v2_AdsDummy_new(upb_arena *arena) { + return (envoy_service_discovery_v2_AdsDummy *)upb_msg_new(&envoy_service_discovery_v2_AdsDummy_msginit, arena); +} +UPB_INLINE envoy_service_discovery_v2_AdsDummy *envoy_service_discovery_v2_AdsDummy_parsenew(upb_strview buf, upb_arena *arena) { + envoy_service_discovery_v2_AdsDummy *ret = envoy_service_discovery_v2_AdsDummy_new(arena); + return (ret && upb_decode(buf, ret, &envoy_service_discovery_v2_AdsDummy_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_service_discovery_v2_AdsDummy_serialize(const envoy_service_discovery_v2_AdsDummy *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_service_discovery_v2_AdsDummy_msginit, arena, len); +} + + + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* ENVOY_SERVICE_DISCOVERY_V2_ADS_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/envoy/service/load_stats/v2/lrs.upb.c b/src/core/ext/upb-generated/envoy/service/load_stats/v2/lrs.upb.c new file mode 100644 index 00000000000..a6e4bd2d18b --- /dev/null +++ b/src/core/ext/upb-generated/envoy/service/load_stats/v2/lrs.upb.c @@ -0,0 +1,52 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/service/load_stats/v2/lrs.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include +#include "upb/msg.h" +#include "envoy/service/load_stats/v2/lrs.upb.h" +#include "envoy/api/v2/core/base.upb.h" +#include "envoy/api/v2/endpoint/load_report.upb.h" +#include "google/protobuf/duration.upb.h" +#include "validate/validate.upb.h" + +#include "upb/port_def.inc" + +static const upb_msglayout *const envoy_service_load_stats_v2_LoadStatsRequest_submsgs[2] = { + &envoy_api_v2_core_Node_msginit, + &envoy_api_v2_endpoint_ClusterStats_msginit, +}; + +static const upb_msglayout_field envoy_service_load_stats_v2_LoadStatsRequest__fields[2] = { + {1, UPB_SIZE(0, 0), 0, 0, 11, 1}, + {2, UPB_SIZE(4, 8), 0, 1, 11, 3}, +}; + +const upb_msglayout envoy_service_load_stats_v2_LoadStatsRequest_msginit = { + &envoy_service_load_stats_v2_LoadStatsRequest_submsgs[0], + &envoy_service_load_stats_v2_LoadStatsRequest__fields[0], + UPB_SIZE(8, 16), 2, false, +}; + +static const upb_msglayout *const envoy_service_load_stats_v2_LoadStatsResponse_submsgs[1] = { + &google_protobuf_Duration_msginit, +}; + +static const upb_msglayout_field envoy_service_load_stats_v2_LoadStatsResponse__fields[3] = { + {1, UPB_SIZE(8, 16), 0, 0, 9, 3}, + {2, UPB_SIZE(4, 8), 0, 0, 11, 1}, + {3, UPB_SIZE(0, 0), 0, 0, 8, 1}, +}; + +const upb_msglayout envoy_service_load_stats_v2_LoadStatsResponse_msginit = { + &envoy_service_load_stats_v2_LoadStatsResponse_submsgs[0], + &envoy_service_load_stats_v2_LoadStatsResponse__fields[0], + UPB_SIZE(12, 24), 3, false, +}; + +#include "upb/port_undef.inc" + diff --git a/src/core/ext/upb-generated/envoy/service/load_stats/v2/lrs.upb.h b/src/core/ext/upb-generated/envoy/service/load_stats/v2/lrs.upb.h new file mode 100644 index 00000000000..99db767a8a1 --- /dev/null +++ b/src/core/ext/upb-generated/envoy/service/load_stats/v2/lrs.upb.h @@ -0,0 +1,132 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/service/load_stats/v2/lrs.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef ENVOY_SERVICE_LOAD_STATS_V2_LRS_PROTO_UPB_H_ +#define ENVOY_SERVICE_LOAD_STATS_V2_LRS_PROTO_UPB_H_ + +#include "upb/generated_util.h" + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +#ifdef __cplusplus +extern "C" { +#endif + +struct envoy_service_load_stats_v2_LoadStatsRequest; +struct envoy_service_load_stats_v2_LoadStatsResponse; +typedef struct envoy_service_load_stats_v2_LoadStatsRequest envoy_service_load_stats_v2_LoadStatsRequest; +typedef struct envoy_service_load_stats_v2_LoadStatsResponse envoy_service_load_stats_v2_LoadStatsResponse; +extern const upb_msglayout envoy_service_load_stats_v2_LoadStatsRequest_msginit; +extern const upb_msglayout envoy_service_load_stats_v2_LoadStatsResponse_msginit; +struct envoy_api_v2_core_Node; +struct envoy_api_v2_endpoint_ClusterStats; +struct google_protobuf_Duration; +extern const upb_msglayout envoy_api_v2_core_Node_msginit; +extern const upb_msglayout envoy_api_v2_endpoint_ClusterStats_msginit; +extern const upb_msglayout google_protobuf_Duration_msginit; + +/* Enums */ + + +/* envoy.service.load_stats.v2.LoadStatsRequest */ + +UPB_INLINE envoy_service_load_stats_v2_LoadStatsRequest *envoy_service_load_stats_v2_LoadStatsRequest_new(upb_arena *arena) { + return (envoy_service_load_stats_v2_LoadStatsRequest *)upb_msg_new(&envoy_service_load_stats_v2_LoadStatsRequest_msginit, arena); +} +UPB_INLINE envoy_service_load_stats_v2_LoadStatsRequest *envoy_service_load_stats_v2_LoadStatsRequest_parsenew(upb_strview buf, upb_arena *arena) { + envoy_service_load_stats_v2_LoadStatsRequest *ret = envoy_service_load_stats_v2_LoadStatsRequest_new(arena); + return (ret && upb_decode(buf, ret, &envoy_service_load_stats_v2_LoadStatsRequest_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_service_load_stats_v2_LoadStatsRequest_serialize(const envoy_service_load_stats_v2_LoadStatsRequest *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_service_load_stats_v2_LoadStatsRequest_msginit, arena, len); +} + +UPB_INLINE const struct envoy_api_v2_core_Node* envoy_service_load_stats_v2_LoadStatsRequest_node(const envoy_service_load_stats_v2_LoadStatsRequest *msg) { return UPB_FIELD_AT(msg, const struct envoy_api_v2_core_Node*, UPB_SIZE(0, 0)); } +UPB_INLINE const struct envoy_api_v2_endpoint_ClusterStats* const* envoy_service_load_stats_v2_LoadStatsRequest_cluster_stats(const envoy_service_load_stats_v2_LoadStatsRequest *msg, size_t *len) { return (const struct envoy_api_v2_endpoint_ClusterStats* const*)_upb_array_accessor(msg, UPB_SIZE(4, 8), len); } + +UPB_INLINE void envoy_service_load_stats_v2_LoadStatsRequest_set_node(envoy_service_load_stats_v2_LoadStatsRequest *msg, struct envoy_api_v2_core_Node* value) { + UPB_FIELD_AT(msg, struct envoy_api_v2_core_Node*, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE struct envoy_api_v2_core_Node* envoy_service_load_stats_v2_LoadStatsRequest_mutable_node(envoy_service_load_stats_v2_LoadStatsRequest *msg, upb_arena *arena) { + struct envoy_api_v2_core_Node* sub = (struct envoy_api_v2_core_Node*)envoy_service_load_stats_v2_LoadStatsRequest_node(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_Node*)upb_msg_new(&envoy_api_v2_core_Node_msginit, arena); + if (!sub) return NULL; + envoy_service_load_stats_v2_LoadStatsRequest_set_node(msg, sub); + } + return sub; +} +UPB_INLINE struct envoy_api_v2_endpoint_ClusterStats** envoy_service_load_stats_v2_LoadStatsRequest_mutable_cluster_stats(envoy_service_load_stats_v2_LoadStatsRequest *msg, size_t *len) { + return (struct envoy_api_v2_endpoint_ClusterStats**)_upb_array_mutable_accessor(msg, UPB_SIZE(4, 8), len); +} +UPB_INLINE struct envoy_api_v2_endpoint_ClusterStats** envoy_service_load_stats_v2_LoadStatsRequest_resize_cluster_stats(envoy_service_load_stats_v2_LoadStatsRequest *msg, size_t len, upb_arena *arena) { + return (struct envoy_api_v2_endpoint_ClusterStats**)_upb_array_resize_accessor(msg, UPB_SIZE(4, 8), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct envoy_api_v2_endpoint_ClusterStats* envoy_service_load_stats_v2_LoadStatsRequest_add_cluster_stats(envoy_service_load_stats_v2_LoadStatsRequest *msg, upb_arena *arena) { + struct envoy_api_v2_endpoint_ClusterStats* sub = (struct envoy_api_v2_endpoint_ClusterStats*)upb_msg_new(&envoy_api_v2_endpoint_ClusterStats_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(4, 8), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} + + +/* envoy.service.load_stats.v2.LoadStatsResponse */ + +UPB_INLINE envoy_service_load_stats_v2_LoadStatsResponse *envoy_service_load_stats_v2_LoadStatsResponse_new(upb_arena *arena) { + return (envoy_service_load_stats_v2_LoadStatsResponse *)upb_msg_new(&envoy_service_load_stats_v2_LoadStatsResponse_msginit, arena); +} +UPB_INLINE envoy_service_load_stats_v2_LoadStatsResponse *envoy_service_load_stats_v2_LoadStatsResponse_parsenew(upb_strview buf, upb_arena *arena) { + envoy_service_load_stats_v2_LoadStatsResponse *ret = envoy_service_load_stats_v2_LoadStatsResponse_new(arena); + return (ret && upb_decode(buf, ret, &envoy_service_load_stats_v2_LoadStatsResponse_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_service_load_stats_v2_LoadStatsResponse_serialize(const envoy_service_load_stats_v2_LoadStatsResponse *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_service_load_stats_v2_LoadStatsResponse_msginit, arena, len); +} + +UPB_INLINE upb_strview const* envoy_service_load_stats_v2_LoadStatsResponse_clusters(const envoy_service_load_stats_v2_LoadStatsResponse *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(8, 16), len); } +UPB_INLINE const struct google_protobuf_Duration* envoy_service_load_stats_v2_LoadStatsResponse_load_reporting_interval(const envoy_service_load_stats_v2_LoadStatsResponse *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Duration*, UPB_SIZE(4, 8)); } +UPB_INLINE bool envoy_service_load_stats_v2_LoadStatsResponse_report_endpoint_granularity(const envoy_service_load_stats_v2_LoadStatsResponse *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(0, 0)); } + +UPB_INLINE upb_strview* envoy_service_load_stats_v2_LoadStatsResponse_mutable_clusters(envoy_service_load_stats_v2_LoadStatsResponse *msg, size_t *len) { + return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(8, 16), len); +} +UPB_INLINE upb_strview* envoy_service_load_stats_v2_LoadStatsResponse_resize_clusters(envoy_service_load_stats_v2_LoadStatsResponse *msg, size_t len, upb_arena *arena) { + return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(8, 16), len, UPB_SIZE(8, 16), UPB_TYPE_STRING, arena); +} +UPB_INLINE bool envoy_service_load_stats_v2_LoadStatsResponse_add_clusters(envoy_service_load_stats_v2_LoadStatsResponse *msg, upb_strview val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(8, 16), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, arena); +} +UPB_INLINE void envoy_service_load_stats_v2_LoadStatsResponse_set_load_reporting_interval(envoy_service_load_stats_v2_LoadStatsResponse *msg, struct google_protobuf_Duration* value) { + UPB_FIELD_AT(msg, struct google_protobuf_Duration*, UPB_SIZE(4, 8)) = value; +} +UPB_INLINE struct google_protobuf_Duration* envoy_service_load_stats_v2_LoadStatsResponse_mutable_load_reporting_interval(envoy_service_load_stats_v2_LoadStatsResponse *msg, upb_arena *arena) { + struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_service_load_stats_v2_LoadStatsResponse_load_reporting_interval(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Duration*)upb_msg_new(&google_protobuf_Duration_msginit, arena); + if (!sub) return NULL; + envoy_service_load_stats_v2_LoadStatsResponse_set_load_reporting_interval(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_service_load_stats_v2_LoadStatsResponse_set_report_endpoint_granularity(envoy_service_load_stats_v2_LoadStatsResponse *msg, bool value) { + UPB_FIELD_AT(msg, bool, UPB_SIZE(0, 0)) = value; +} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* ENVOY_SERVICE_LOAD_STATS_V2_LRS_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/envoy/type/percent.upb.c b/src/core/ext/upb-generated/envoy/type/percent.upb.c new file mode 100644 index 00000000000..0ef0ae176e2 --- /dev/null +++ b/src/core/ext/upb-generated/envoy/type/percent.upb.c @@ -0,0 +1,39 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/type/percent.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include +#include "upb/msg.h" +#include "envoy/type/percent.upb.h" +#include "validate/validate.upb.h" +#include "gogoproto/gogo.upb.h" + +#include "upb/port_def.inc" + +static const upb_msglayout_field envoy_type_Percent__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 1, 1}, +}; + +const upb_msglayout envoy_type_Percent_msginit = { + NULL, + &envoy_type_Percent__fields[0], + UPB_SIZE(8, 8), 1, false, +}; + +static const upb_msglayout_field envoy_type_FractionalPercent__fields[2] = { + {1, UPB_SIZE(8, 8), 0, 0, 13, 1}, + {2, UPB_SIZE(0, 0), 0, 0, 14, 1}, +}; + +const upb_msglayout envoy_type_FractionalPercent_msginit = { + NULL, + &envoy_type_FractionalPercent__fields[0], + UPB_SIZE(16, 16), 2, false, +}; + +#include "upb/port_undef.inc" + diff --git a/src/core/ext/upb-generated/envoy/type/percent.upb.h b/src/core/ext/upb-generated/envoy/type/percent.upb.h new file mode 100644 index 00000000000..13df96a610c --- /dev/null +++ b/src/core/ext/upb-generated/envoy/type/percent.upb.h @@ -0,0 +1,89 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/type/percent.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef ENVOY_TYPE_PERCENT_PROTO_UPB_H_ +#define ENVOY_TYPE_PERCENT_PROTO_UPB_H_ + +#include "upb/generated_util.h" + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +#ifdef __cplusplus +extern "C" { +#endif + +struct envoy_type_Percent; +struct envoy_type_FractionalPercent; +typedef struct envoy_type_Percent envoy_type_Percent; +typedef struct envoy_type_FractionalPercent envoy_type_FractionalPercent; +extern const upb_msglayout envoy_type_Percent_msginit; +extern const upb_msglayout envoy_type_FractionalPercent_msginit; + +/* Enums */ + +typedef enum { + envoy_type_FractionalPercent_HUNDRED = 0, + envoy_type_FractionalPercent_TEN_THOUSAND = 1, + envoy_type_FractionalPercent_MILLION = 2 +} envoy_type_FractionalPercent_DenominatorType; + + +/* envoy.type.Percent */ + +UPB_INLINE envoy_type_Percent *envoy_type_Percent_new(upb_arena *arena) { + return (envoy_type_Percent *)upb_msg_new(&envoy_type_Percent_msginit, arena); +} +UPB_INLINE envoy_type_Percent *envoy_type_Percent_parsenew(upb_strview buf, upb_arena *arena) { + envoy_type_Percent *ret = envoy_type_Percent_new(arena); + return (ret && upb_decode(buf, ret, &envoy_type_Percent_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_type_Percent_serialize(const envoy_type_Percent *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_type_Percent_msginit, arena, len); +} + +UPB_INLINE double envoy_type_Percent_value(const envoy_type_Percent *msg) { return UPB_FIELD_AT(msg, double, UPB_SIZE(0, 0)); } + +UPB_INLINE void envoy_type_Percent_set_value(envoy_type_Percent *msg, double value) { + UPB_FIELD_AT(msg, double, UPB_SIZE(0, 0)) = value; +} + + +/* envoy.type.FractionalPercent */ + +UPB_INLINE envoy_type_FractionalPercent *envoy_type_FractionalPercent_new(upb_arena *arena) { + return (envoy_type_FractionalPercent *)upb_msg_new(&envoy_type_FractionalPercent_msginit, arena); +} +UPB_INLINE envoy_type_FractionalPercent *envoy_type_FractionalPercent_parsenew(upb_strview buf, upb_arena *arena) { + envoy_type_FractionalPercent *ret = envoy_type_FractionalPercent_new(arena); + return (ret && upb_decode(buf, ret, &envoy_type_FractionalPercent_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_type_FractionalPercent_serialize(const envoy_type_FractionalPercent *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_type_FractionalPercent_msginit, arena, len); +} + +UPB_INLINE uint32_t envoy_type_FractionalPercent_numerator(const envoy_type_FractionalPercent *msg) { return UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(8, 8)); } +UPB_INLINE int32_t envoy_type_FractionalPercent_denominator(const envoy_type_FractionalPercent *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(0, 0)); } + +UPB_INLINE void envoy_type_FractionalPercent_set_numerator(envoy_type_FractionalPercent *msg, uint32_t value) { + UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE void envoy_type_FractionalPercent_set_denominator(envoy_type_FractionalPercent *msg, int32_t value) { + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(0, 0)) = value; +} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* ENVOY_TYPE_PERCENT_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/envoy/type/range.upb.c b/src/core/ext/upb-generated/envoy/type/range.upb.c new file mode 100644 index 00000000000..2e71b82611e --- /dev/null +++ b/src/core/ext/upb-generated/envoy/type/range.upb.c @@ -0,0 +1,39 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/type/range.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include +#include "upb/msg.h" +#include "envoy/type/range.upb.h" +#include "gogoproto/gogo.upb.h" + +#include "upb/port_def.inc" + +static const upb_msglayout_field envoy_type_Int64Range__fields[2] = { + {1, UPB_SIZE(0, 0), 0, 0, 3, 1}, + {2, UPB_SIZE(8, 8), 0, 0, 3, 1}, +}; + +const upb_msglayout envoy_type_Int64Range_msginit = { + NULL, + &envoy_type_Int64Range__fields[0], + UPB_SIZE(16, 16), 2, false, +}; + +static const upb_msglayout_field envoy_type_DoubleRange__fields[2] = { + {1, UPB_SIZE(0, 0), 0, 0, 1, 1}, + {2, UPB_SIZE(8, 8), 0, 0, 1, 1}, +}; + +const upb_msglayout envoy_type_DoubleRange_msginit = { + NULL, + &envoy_type_DoubleRange__fields[0], + UPB_SIZE(16, 16), 2, false, +}; + +#include "upb/port_undef.inc" + diff --git a/src/core/ext/upb-generated/envoy/type/range.upb.h b/src/core/ext/upb-generated/envoy/type/range.upb.h new file mode 100644 index 00000000000..de1846a1300 --- /dev/null +++ b/src/core/ext/upb-generated/envoy/type/range.upb.h @@ -0,0 +1,87 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/type/range.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef ENVOY_TYPE_RANGE_PROTO_UPB_H_ +#define ENVOY_TYPE_RANGE_PROTO_UPB_H_ + +#include "upb/generated_util.h" + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +#ifdef __cplusplus +extern "C" { +#endif + +struct envoy_type_Int64Range; +struct envoy_type_DoubleRange; +typedef struct envoy_type_Int64Range envoy_type_Int64Range; +typedef struct envoy_type_DoubleRange envoy_type_DoubleRange; +extern const upb_msglayout envoy_type_Int64Range_msginit; +extern const upb_msglayout envoy_type_DoubleRange_msginit; + +/* Enums */ + + +/* envoy.type.Int64Range */ + +UPB_INLINE envoy_type_Int64Range *envoy_type_Int64Range_new(upb_arena *arena) { + return (envoy_type_Int64Range *)upb_msg_new(&envoy_type_Int64Range_msginit, arena); +} +UPB_INLINE envoy_type_Int64Range *envoy_type_Int64Range_parsenew(upb_strview buf, upb_arena *arena) { + envoy_type_Int64Range *ret = envoy_type_Int64Range_new(arena); + return (ret && upb_decode(buf, ret, &envoy_type_Int64Range_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_type_Int64Range_serialize(const envoy_type_Int64Range *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_type_Int64Range_msginit, arena, len); +} + +UPB_INLINE int64_t envoy_type_Int64Range_start(const envoy_type_Int64Range *msg) { return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(0, 0)); } +UPB_INLINE int64_t envoy_type_Int64Range_end(const envoy_type_Int64Range *msg) { return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(8, 8)); } + +UPB_INLINE void envoy_type_Int64Range_set_start(envoy_type_Int64Range *msg, int64_t value) { + UPB_FIELD_AT(msg, int64_t, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_type_Int64Range_set_end(envoy_type_Int64Range *msg, int64_t value) { + UPB_FIELD_AT(msg, int64_t, UPB_SIZE(8, 8)) = value; +} + + +/* envoy.type.DoubleRange */ + +UPB_INLINE envoy_type_DoubleRange *envoy_type_DoubleRange_new(upb_arena *arena) { + return (envoy_type_DoubleRange *)upb_msg_new(&envoy_type_DoubleRange_msginit, arena); +} +UPB_INLINE envoy_type_DoubleRange *envoy_type_DoubleRange_parsenew(upb_strview buf, upb_arena *arena) { + envoy_type_DoubleRange *ret = envoy_type_DoubleRange_new(arena); + return (ret && upb_decode(buf, ret, &envoy_type_DoubleRange_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_type_DoubleRange_serialize(const envoy_type_DoubleRange *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_type_DoubleRange_msginit, arena, len); +} + +UPB_INLINE double envoy_type_DoubleRange_start(const envoy_type_DoubleRange *msg) { return UPB_FIELD_AT(msg, double, UPB_SIZE(0, 0)); } +UPB_INLINE double envoy_type_DoubleRange_end(const envoy_type_DoubleRange *msg) { return UPB_FIELD_AT(msg, double, UPB_SIZE(8, 8)); } + +UPB_INLINE void envoy_type_DoubleRange_set_start(envoy_type_DoubleRange *msg, double value) { + UPB_FIELD_AT(msg, double, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_type_DoubleRange_set_end(envoy_type_DoubleRange *msg, double value) { + UPB_FIELD_AT(msg, double, UPB_SIZE(8, 8)) = value; +} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* ENVOY_TYPE_RANGE_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/gogoproto/gogo.upb.c b/src/core/ext/upb-generated/gogoproto/gogo.upb.c new file mode 100644 index 00000000000..7517fdcbbe8 --- /dev/null +++ b/src/core/ext/upb-generated/gogoproto/gogo.upb.c @@ -0,0 +1,17 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * gogoproto/gogo.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include +#include "upb/msg.h" +#include "gogoproto/gogo.upb.h" +#include "google/protobuf/descriptor.upb.h" + +#include "upb/port_def.inc" + +#include "upb/port_undef.inc" + diff --git a/src/core/ext/upb-generated/gogoproto/gogo.upb.h b/src/core/ext/upb-generated/gogoproto/gogo.upb.h new file mode 100644 index 00000000000..6b3dda647ee --- /dev/null +++ b/src/core/ext/upb-generated/gogoproto/gogo.upb.h @@ -0,0 +1,33 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * gogoproto/gogo.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef GOGOPROTO_GOGO_PROTO_UPB_H_ +#define GOGOPROTO_GOGO_PROTO_UPB_H_ + +#include "upb/generated_util.h" + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +#ifdef __cplusplus +extern "C" { +#endif + + +/* Enums */ + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* GOGOPROTO_GOGO_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/google/api/annotations.upb.c b/src/core/ext/upb-generated/google/api/annotations.upb.c new file mode 100644 index 00000000000..a1385cc3e70 --- /dev/null +++ b/src/core/ext/upb-generated/google/api/annotations.upb.c @@ -0,0 +1,18 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * google/api/annotations.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include +#include "upb/msg.h" +#include "google/api/annotations.upb.h" +#include "google/api/http.upb.h" +#include "google/protobuf/descriptor.upb.h" + +#include "upb/port_def.inc" + +#include "upb/port_undef.inc" + diff --git a/src/core/ext/upb-generated/google/api/annotations.upb.h b/src/core/ext/upb-generated/google/api/annotations.upb.h new file mode 100644 index 00000000000..5a49fffdd22 --- /dev/null +++ b/src/core/ext/upb-generated/google/api/annotations.upb.h @@ -0,0 +1,33 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * google/api/annotations.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef GOOGLE_API_ANNOTATIONS_PROTO_UPB_H_ +#define GOOGLE_API_ANNOTATIONS_PROTO_UPB_H_ + +#include "upb/generated_util.h" + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +#ifdef __cplusplus +extern "C" { +#endif + + +/* Enums */ + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* GOOGLE_API_ANNOTATIONS_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/google/api/http.upb.c b/src/core/ext/upb-generated/google/api/http.upb.c new file mode 100644 index 00000000000..8ad07dcd9fd --- /dev/null +++ b/src/core/ext/upb-generated/google/api/http.upb.c @@ -0,0 +1,66 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * google/api/http.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include +#include "upb/msg.h" +#include "google/api/http.upb.h" + +#include "upb/port_def.inc" + +static const upb_msglayout *const google_api_Http_submsgs[1] = { + &google_api_HttpRule_msginit, +}; + +static const upb_msglayout_field google_api_Http__fields[2] = { + {1, UPB_SIZE(4, 8), 0, 0, 11, 3}, + {2, UPB_SIZE(0, 0), 0, 0, 8, 1}, +}; + +const upb_msglayout google_api_Http_msginit = { + &google_api_Http_submsgs[0], + &google_api_Http__fields[0], + UPB_SIZE(8, 16), 2, false, +}; + +static const upb_msglayout *const google_api_HttpRule_submsgs[2] = { + &google_api_CustomHttpPattern_msginit, + &google_api_HttpRule_msginit, +}; + +static const upb_msglayout_field google_api_HttpRule__fields[10] = { + {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, + {2, UPB_SIZE(28, 56), UPB_SIZE(-37, -73), 0, 9, 1}, + {3, UPB_SIZE(28, 56), UPB_SIZE(-37, -73), 0, 9, 1}, + {4, UPB_SIZE(28, 56), UPB_SIZE(-37, -73), 0, 9, 1}, + {5, UPB_SIZE(28, 56), UPB_SIZE(-37, -73), 0, 9, 1}, + {6, UPB_SIZE(28, 56), UPB_SIZE(-37, -73), 0, 9, 1}, + {7, UPB_SIZE(8, 16), 0, 0, 9, 1}, + {8, UPB_SIZE(28, 56), UPB_SIZE(-37, -73), 0, 11, 1}, + {11, UPB_SIZE(24, 48), 0, 1, 11, 3}, + {12, UPB_SIZE(16, 32), 0, 0, 9, 1}, +}; + +const upb_msglayout google_api_HttpRule_msginit = { + &google_api_HttpRule_submsgs[0], + &google_api_HttpRule__fields[0], + UPB_SIZE(40, 80), 10, false, +}; + +static const upb_msglayout_field google_api_CustomHttpPattern__fields[2] = { + {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, + {2, UPB_SIZE(8, 16), 0, 0, 9, 1}, +}; + +const upb_msglayout google_api_CustomHttpPattern_msginit = { + NULL, + &google_api_CustomHttpPattern__fields[0], + UPB_SIZE(16, 32), 2, false, +}; + +#include "upb/port_undef.inc" + diff --git a/src/core/ext/upb-generated/google/api/http.upb.h b/src/core/ext/upb-generated/google/api/http.upb.h new file mode 100644 index 00000000000..d8bda895b86 --- /dev/null +++ b/src/core/ext/upb-generated/google/api/http.upb.h @@ -0,0 +1,192 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * google/api/http.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef GOOGLE_API_HTTP_PROTO_UPB_H_ +#define GOOGLE_API_HTTP_PROTO_UPB_H_ + +#include "upb/generated_util.h" + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +#ifdef __cplusplus +extern "C" { +#endif + +struct google_api_Http; +struct google_api_HttpRule; +struct google_api_CustomHttpPattern; +typedef struct google_api_Http google_api_Http; +typedef struct google_api_HttpRule google_api_HttpRule; +typedef struct google_api_CustomHttpPattern google_api_CustomHttpPattern; +extern const upb_msglayout google_api_Http_msginit; +extern const upb_msglayout google_api_HttpRule_msginit; +extern const upb_msglayout google_api_CustomHttpPattern_msginit; + +/* Enums */ + + +/* google.api.Http */ + +UPB_INLINE google_api_Http *google_api_Http_new(upb_arena *arena) { + return (google_api_Http *)upb_msg_new(&google_api_Http_msginit, arena); +} +UPB_INLINE google_api_Http *google_api_Http_parsenew(upb_strview buf, upb_arena *arena) { + google_api_Http *ret = google_api_Http_new(arena); + return (ret && upb_decode(buf, ret, &google_api_Http_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_api_Http_serialize(const google_api_Http *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_api_Http_msginit, arena, len); +} + +UPB_INLINE const google_api_HttpRule* const* google_api_Http_rules(const google_api_Http *msg, size_t *len) { return (const google_api_HttpRule* const*)_upb_array_accessor(msg, UPB_SIZE(4, 8), len); } +UPB_INLINE bool google_api_Http_fully_decode_reserved_expansion(const google_api_Http *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(0, 0)); } + +UPB_INLINE google_api_HttpRule** google_api_Http_mutable_rules(google_api_Http *msg, size_t *len) { + return (google_api_HttpRule**)_upb_array_mutable_accessor(msg, UPB_SIZE(4, 8), len); +} +UPB_INLINE google_api_HttpRule** google_api_Http_resize_rules(google_api_Http *msg, size_t len, upb_arena *arena) { + return (google_api_HttpRule**)_upb_array_resize_accessor(msg, UPB_SIZE(4, 8), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_api_HttpRule* google_api_Http_add_rules(google_api_Http *msg, upb_arena *arena) { + struct google_api_HttpRule* sub = (struct google_api_HttpRule*)upb_msg_new(&google_api_HttpRule_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(4, 8), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE void google_api_Http_set_fully_decode_reserved_expansion(google_api_Http *msg, bool value) { + UPB_FIELD_AT(msg, bool, UPB_SIZE(0, 0)) = value; +} + + +/* google.api.HttpRule */ + +UPB_INLINE google_api_HttpRule *google_api_HttpRule_new(upb_arena *arena) { + return (google_api_HttpRule *)upb_msg_new(&google_api_HttpRule_msginit, arena); +} +UPB_INLINE google_api_HttpRule *google_api_HttpRule_parsenew(upb_strview buf, upb_arena *arena) { + google_api_HttpRule *ret = google_api_HttpRule_new(arena); + return (ret && upb_decode(buf, ret, &google_api_HttpRule_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_api_HttpRule_serialize(const google_api_HttpRule *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_api_HttpRule_msginit, arena, len); +} + +typedef enum { + google_api_HttpRule_pattern_get = 2, + google_api_HttpRule_pattern_put = 3, + google_api_HttpRule_pattern_post = 4, + google_api_HttpRule_pattern_delete = 5, + google_api_HttpRule_pattern_patch = 6, + google_api_HttpRule_pattern_custom = 8, + google_api_HttpRule_pattern_NOT_SET = 0, +} google_api_HttpRule_pattern_oneofcases; +UPB_INLINE google_api_HttpRule_pattern_oneofcases google_api_HttpRule_pattern_case(const google_api_HttpRule* msg) { return UPB_FIELD_AT(msg, int, UPB_SIZE(36, 72)); } + +UPB_INLINE upb_strview google_api_HttpRule_selector(const google_api_HttpRule *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } +UPB_INLINE bool google_api_HttpRule_has_get(const google_api_HttpRule *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(36, 72), 2); } +UPB_INLINE upb_strview google_api_HttpRule_get(const google_api_HttpRule *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(28, 56), UPB_SIZE(36, 72), 2, upb_strview_make("", strlen(""))); } +UPB_INLINE bool google_api_HttpRule_has_put(const google_api_HttpRule *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(36, 72), 3); } +UPB_INLINE upb_strview google_api_HttpRule_put(const google_api_HttpRule *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(28, 56), UPB_SIZE(36, 72), 3, upb_strview_make("", strlen(""))); } +UPB_INLINE bool google_api_HttpRule_has_post(const google_api_HttpRule *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(36, 72), 4); } +UPB_INLINE upb_strview google_api_HttpRule_post(const google_api_HttpRule *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(28, 56), UPB_SIZE(36, 72), 4, upb_strview_make("", strlen(""))); } +UPB_INLINE bool google_api_HttpRule_has_delete(const google_api_HttpRule *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(36, 72), 5); } +UPB_INLINE upb_strview google_api_HttpRule_delete(const google_api_HttpRule *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(28, 56), UPB_SIZE(36, 72), 5, upb_strview_make("", strlen(""))); } +UPB_INLINE bool google_api_HttpRule_has_patch(const google_api_HttpRule *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(36, 72), 6); } +UPB_INLINE upb_strview google_api_HttpRule_patch(const google_api_HttpRule *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(28, 56), UPB_SIZE(36, 72), 6, upb_strview_make("", strlen(""))); } +UPB_INLINE upb_strview google_api_HttpRule_body(const google_api_HttpRule *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 16)); } +UPB_INLINE bool google_api_HttpRule_has_custom(const google_api_HttpRule *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(36, 72), 8); } +UPB_INLINE const google_api_CustomHttpPattern* google_api_HttpRule_custom(const google_api_HttpRule *msg) { return UPB_READ_ONEOF(msg, const google_api_CustomHttpPattern*, UPB_SIZE(28, 56), UPB_SIZE(36, 72), 8, NULL); } +UPB_INLINE const google_api_HttpRule* const* google_api_HttpRule_additional_bindings(const google_api_HttpRule *msg, size_t *len) { return (const google_api_HttpRule* const*)_upb_array_accessor(msg, UPB_SIZE(24, 48), len); } +UPB_INLINE upb_strview google_api_HttpRule_response_body(const google_api_HttpRule *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(16, 32)); } + +UPB_INLINE void google_api_HttpRule_set_selector(google_api_HttpRule *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void google_api_HttpRule_set_get(google_api_HttpRule *msg, upb_strview value) { + UPB_WRITE_ONEOF(msg, upb_strview, UPB_SIZE(28, 56), value, UPB_SIZE(36, 72), 2); +} +UPB_INLINE void google_api_HttpRule_set_put(google_api_HttpRule *msg, upb_strview value) { + UPB_WRITE_ONEOF(msg, upb_strview, UPB_SIZE(28, 56), value, UPB_SIZE(36, 72), 3); +} +UPB_INLINE void google_api_HttpRule_set_post(google_api_HttpRule *msg, upb_strview value) { + UPB_WRITE_ONEOF(msg, upb_strview, UPB_SIZE(28, 56), value, UPB_SIZE(36, 72), 4); +} +UPB_INLINE void google_api_HttpRule_set_delete(google_api_HttpRule *msg, upb_strview value) { + UPB_WRITE_ONEOF(msg, upb_strview, UPB_SIZE(28, 56), value, UPB_SIZE(36, 72), 5); +} +UPB_INLINE void google_api_HttpRule_set_patch(google_api_HttpRule *msg, upb_strview value) { + UPB_WRITE_ONEOF(msg, upb_strview, UPB_SIZE(28, 56), value, UPB_SIZE(36, 72), 6); +} +UPB_INLINE void google_api_HttpRule_set_body(google_api_HttpRule *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE void google_api_HttpRule_set_custom(google_api_HttpRule *msg, google_api_CustomHttpPattern* value) { + UPB_WRITE_ONEOF(msg, google_api_CustomHttpPattern*, UPB_SIZE(28, 56), value, UPB_SIZE(36, 72), 8); +} +UPB_INLINE struct google_api_CustomHttpPattern* google_api_HttpRule_mutable_custom(google_api_HttpRule *msg, upb_arena *arena) { + struct google_api_CustomHttpPattern* sub = (struct google_api_CustomHttpPattern*)google_api_HttpRule_custom(msg); + if (sub == NULL) { + sub = (struct google_api_CustomHttpPattern*)upb_msg_new(&google_api_CustomHttpPattern_msginit, arena); + if (!sub) return NULL; + google_api_HttpRule_set_custom(msg, sub); + } + return sub; +} +UPB_INLINE google_api_HttpRule** google_api_HttpRule_mutable_additional_bindings(google_api_HttpRule *msg, size_t *len) { + return (google_api_HttpRule**)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 48), len); +} +UPB_INLINE google_api_HttpRule** google_api_HttpRule_resize_additional_bindings(google_api_HttpRule *msg, size_t len, upb_arena *arena) { + return (google_api_HttpRule**)_upb_array_resize_accessor(msg, UPB_SIZE(24, 48), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_api_HttpRule* google_api_HttpRule_add_additional_bindings(google_api_HttpRule *msg, upb_arena *arena) { + struct google_api_HttpRule* sub = (struct google_api_HttpRule*)upb_msg_new(&google_api_HttpRule_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(24, 48), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE void google_api_HttpRule_set_response_body(google_api_HttpRule *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(16, 32)) = value; +} + + +/* google.api.CustomHttpPattern */ + +UPB_INLINE google_api_CustomHttpPattern *google_api_CustomHttpPattern_new(upb_arena *arena) { + return (google_api_CustomHttpPattern *)upb_msg_new(&google_api_CustomHttpPattern_msginit, arena); +} +UPB_INLINE google_api_CustomHttpPattern *google_api_CustomHttpPattern_parsenew(upb_strview buf, upb_arena *arena) { + google_api_CustomHttpPattern *ret = google_api_CustomHttpPattern_new(arena); + return (ret && upb_decode(buf, ret, &google_api_CustomHttpPattern_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_api_CustomHttpPattern_serialize(const google_api_CustomHttpPattern *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_api_CustomHttpPattern_msginit, arena, len); +} + +UPB_INLINE upb_strview google_api_CustomHttpPattern_kind(const google_api_CustomHttpPattern *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } +UPB_INLINE upb_strview google_api_CustomHttpPattern_path(const google_api_CustomHttpPattern *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 16)); } + +UPB_INLINE void google_api_CustomHttpPattern_set_kind(google_api_CustomHttpPattern *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void google_api_CustomHttpPattern_set_path(google_api_CustomHttpPattern *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 16)) = value; +} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* GOOGLE_API_HTTP_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/google/protobuf/any.upb.c b/src/core/ext/upb-generated/google/protobuf/any.upb.c new file mode 100644 index 00000000000..14badf797c1 --- /dev/null +++ b/src/core/ext/upb-generated/google/protobuf/any.upb.c @@ -0,0 +1,27 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * google/protobuf/any.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include +#include "upb/msg.h" +#include "google/protobuf/any.upb.h" + +#include "upb/port_def.inc" + +static const upb_msglayout_field google_protobuf_Any__fields[2] = { + {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, + {2, UPB_SIZE(8, 16), 0, 0, 12, 1}, +}; + +const upb_msglayout google_protobuf_Any_msginit = { + NULL, + &google_protobuf_Any__fields[0], + UPB_SIZE(16, 32), 2, false, +}; + +#include "upb/port_undef.inc" + diff --git a/src/core/ext/upb-generated/google/protobuf/any.upb.h b/src/core/ext/upb-generated/google/protobuf/any.upb.h new file mode 100644 index 00000000000..877e5bd606d --- /dev/null +++ b/src/core/ext/upb-generated/google/protobuf/any.upb.h @@ -0,0 +1,60 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * google/protobuf/any.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef GOOGLE_PROTOBUF_ANY_PROTO_UPB_H_ +#define GOOGLE_PROTOBUF_ANY_PROTO_UPB_H_ + +#include "upb/generated_util.h" + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +#ifdef __cplusplus +extern "C" { +#endif + +struct google_protobuf_Any; +typedef struct google_protobuf_Any google_protobuf_Any; +extern const upb_msglayout google_protobuf_Any_msginit; + +/* Enums */ + + +/* google.protobuf.Any */ + +UPB_INLINE google_protobuf_Any *google_protobuf_Any_new(upb_arena *arena) { + return (google_protobuf_Any *)upb_msg_new(&google_protobuf_Any_msginit, arena); +} +UPB_INLINE google_protobuf_Any *google_protobuf_Any_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_Any *ret = google_protobuf_Any_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_Any_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_Any_serialize(const google_protobuf_Any *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_Any_msginit, arena, len); +} + +UPB_INLINE upb_strview google_protobuf_Any_type_url(const google_protobuf_Any *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } +UPB_INLINE upb_strview google_protobuf_Any_value(const google_protobuf_Any *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 16)); } + +UPB_INLINE void google_protobuf_Any_set_type_url(google_protobuf_Any *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void google_protobuf_Any_set_value(google_protobuf_Any *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 16)) = value; +} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* GOOGLE_PROTOBUF_ANY_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/google/protobuf/descriptor.upb.c b/src/core/ext/upb-generated/google/protobuf/descriptor.upb.c new file mode 100644 index 00000000000..61b9299bb43 --- /dev/null +++ b/src/core/ext/upb-generated/google/protobuf/descriptor.upb.c @@ -0,0 +1,485 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * google/protobuf/descriptor.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include +#include "upb/msg.h" +#include "google/protobuf/descriptor.upb.h" + +#include "upb/port_def.inc" + +static const upb_msglayout *const google_protobuf_FileDescriptorSet_submsgs[1] = { + &google_protobuf_FileDescriptorProto_msginit, +}; + +static const upb_msglayout_field google_protobuf_FileDescriptorSet__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 11, 3}, +}; + +const upb_msglayout google_protobuf_FileDescriptorSet_msginit = { + &google_protobuf_FileDescriptorSet_submsgs[0], + &google_protobuf_FileDescriptorSet__fields[0], + UPB_SIZE(4, 8), 1, false, +}; + +static const upb_msglayout *const google_protobuf_FileDescriptorProto_submsgs[6] = { + &google_protobuf_DescriptorProto_msginit, + &google_protobuf_EnumDescriptorProto_msginit, + &google_protobuf_FieldDescriptorProto_msginit, + &google_protobuf_FileOptions_msginit, + &google_protobuf_ServiceDescriptorProto_msginit, + &google_protobuf_SourceCodeInfo_msginit, +}; + +static const upb_msglayout_field google_protobuf_FileDescriptorProto__fields[12] = { + {1, UPB_SIZE(4, 8), 1, 0, 9, 1}, + {2, UPB_SIZE(12, 24), 2, 0, 9, 1}, + {3, UPB_SIZE(36, 72), 0, 0, 9, 3}, + {4, UPB_SIZE(40, 80), 0, 0, 11, 3}, + {5, UPB_SIZE(44, 88), 0, 1, 11, 3}, + {6, UPB_SIZE(48, 96), 0, 4, 11, 3}, + {7, UPB_SIZE(52, 104), 0, 2, 11, 3}, + {8, UPB_SIZE(28, 56), 4, 3, 11, 1}, + {9, UPB_SIZE(32, 64), 5, 5, 11, 1}, + {10, UPB_SIZE(56, 112), 0, 0, 5, 3}, + {11, UPB_SIZE(60, 120), 0, 0, 5, 3}, + {12, UPB_SIZE(20, 40), 3, 0, 9, 1}, +}; + +const upb_msglayout google_protobuf_FileDescriptorProto_msginit = { + &google_protobuf_FileDescriptorProto_submsgs[0], + &google_protobuf_FileDescriptorProto__fields[0], + UPB_SIZE(64, 128), 12, false, +}; + +static const upb_msglayout *const google_protobuf_DescriptorProto_submsgs[8] = { + &google_protobuf_DescriptorProto_msginit, + &google_protobuf_DescriptorProto_ExtensionRange_msginit, + &google_protobuf_DescriptorProto_ReservedRange_msginit, + &google_protobuf_EnumDescriptorProto_msginit, + &google_protobuf_FieldDescriptorProto_msginit, + &google_protobuf_MessageOptions_msginit, + &google_protobuf_OneofDescriptorProto_msginit, +}; + +static const upb_msglayout_field google_protobuf_DescriptorProto__fields[10] = { + {1, UPB_SIZE(4, 8), 1, 0, 9, 1}, + {2, UPB_SIZE(16, 32), 0, 4, 11, 3}, + {3, UPB_SIZE(20, 40), 0, 0, 11, 3}, + {4, UPB_SIZE(24, 48), 0, 3, 11, 3}, + {5, UPB_SIZE(28, 56), 0, 1, 11, 3}, + {6, UPB_SIZE(32, 64), 0, 4, 11, 3}, + {7, UPB_SIZE(12, 24), 2, 5, 11, 1}, + {8, UPB_SIZE(36, 72), 0, 6, 11, 3}, + {9, UPB_SIZE(40, 80), 0, 2, 11, 3}, + {10, UPB_SIZE(44, 88), 0, 0, 9, 3}, +}; + +const upb_msglayout google_protobuf_DescriptorProto_msginit = { + &google_protobuf_DescriptorProto_submsgs[0], + &google_protobuf_DescriptorProto__fields[0], + UPB_SIZE(48, 96), 10, false, +}; + +static const upb_msglayout *const google_protobuf_DescriptorProto_ExtensionRange_submsgs[1] = { + &google_protobuf_ExtensionRangeOptions_msginit, +}; + +static const upb_msglayout_field google_protobuf_DescriptorProto_ExtensionRange__fields[3] = { + {1, UPB_SIZE(4, 4), 1, 0, 5, 1}, + {2, UPB_SIZE(8, 8), 2, 0, 5, 1}, + {3, UPB_SIZE(12, 16), 3, 0, 11, 1}, +}; + +const upb_msglayout google_protobuf_DescriptorProto_ExtensionRange_msginit = { + &google_protobuf_DescriptorProto_ExtensionRange_submsgs[0], + &google_protobuf_DescriptorProto_ExtensionRange__fields[0], + UPB_SIZE(16, 24), 3, false, +}; + +static const upb_msglayout_field google_protobuf_DescriptorProto_ReservedRange__fields[2] = { + {1, UPB_SIZE(4, 4), 1, 0, 5, 1}, + {2, UPB_SIZE(8, 8), 2, 0, 5, 1}, +}; + +const upb_msglayout google_protobuf_DescriptorProto_ReservedRange_msginit = { + NULL, + &google_protobuf_DescriptorProto_ReservedRange__fields[0], + UPB_SIZE(12, 12), 2, false, +}; + +static const upb_msglayout *const google_protobuf_ExtensionRangeOptions_submsgs[1] = { + &google_protobuf_UninterpretedOption_msginit, +}; + +static const upb_msglayout_field google_protobuf_ExtensionRangeOptions__fields[1] = { + {999, UPB_SIZE(0, 0), 0, 0, 11, 3}, +}; + +const upb_msglayout google_protobuf_ExtensionRangeOptions_msginit = { + &google_protobuf_ExtensionRangeOptions_submsgs[0], + &google_protobuf_ExtensionRangeOptions__fields[0], + UPB_SIZE(4, 8), 1, false, +}; + +static const upb_msglayout *const google_protobuf_FieldDescriptorProto_submsgs[1] = { + &google_protobuf_FieldOptions_msginit, +}; + +static const upb_msglayout_field google_protobuf_FieldDescriptorProto__fields[10] = { + {1, UPB_SIZE(32, 32), 5, 0, 9, 1}, + {2, UPB_SIZE(40, 48), 6, 0, 9, 1}, + {3, UPB_SIZE(24, 24), 3, 0, 5, 1}, + {4, UPB_SIZE(8, 8), 1, 0, 14, 1}, + {5, UPB_SIZE(16, 16), 2, 0, 14, 1}, + {6, UPB_SIZE(48, 64), 7, 0, 9, 1}, + {7, UPB_SIZE(56, 80), 8, 0, 9, 1}, + {8, UPB_SIZE(72, 112), 10, 0, 11, 1}, + {9, UPB_SIZE(28, 28), 4, 0, 5, 1}, + {10, UPB_SIZE(64, 96), 9, 0, 9, 1}, +}; + +const upb_msglayout google_protobuf_FieldDescriptorProto_msginit = { + &google_protobuf_FieldDescriptorProto_submsgs[0], + &google_protobuf_FieldDescriptorProto__fields[0], + UPB_SIZE(80, 128), 10, false, +}; + +static const upb_msglayout *const google_protobuf_OneofDescriptorProto_submsgs[1] = { + &google_protobuf_OneofOptions_msginit, +}; + +static const upb_msglayout_field google_protobuf_OneofDescriptorProto__fields[2] = { + {1, UPB_SIZE(4, 8), 1, 0, 9, 1}, + {2, UPB_SIZE(12, 24), 2, 0, 11, 1}, +}; + +const upb_msglayout google_protobuf_OneofDescriptorProto_msginit = { + &google_protobuf_OneofDescriptorProto_submsgs[0], + &google_protobuf_OneofDescriptorProto__fields[0], + UPB_SIZE(16, 32), 2, false, +}; + +static const upb_msglayout *const google_protobuf_EnumDescriptorProto_submsgs[3] = { + &google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit, + &google_protobuf_EnumOptions_msginit, + &google_protobuf_EnumValueDescriptorProto_msginit, +}; + +static const upb_msglayout_field google_protobuf_EnumDescriptorProto__fields[5] = { + {1, UPB_SIZE(4, 8), 1, 0, 9, 1}, + {2, UPB_SIZE(16, 32), 0, 2, 11, 3}, + {3, UPB_SIZE(12, 24), 2, 1, 11, 1}, + {4, UPB_SIZE(20, 40), 0, 0, 11, 3}, + {5, UPB_SIZE(24, 48), 0, 0, 9, 3}, +}; + +const upb_msglayout google_protobuf_EnumDescriptorProto_msginit = { + &google_protobuf_EnumDescriptorProto_submsgs[0], + &google_protobuf_EnumDescriptorProto__fields[0], + UPB_SIZE(32, 64), 5, false, +}; + +static const upb_msglayout_field google_protobuf_EnumDescriptorProto_EnumReservedRange__fields[2] = { + {1, UPB_SIZE(4, 4), 1, 0, 5, 1}, + {2, UPB_SIZE(8, 8), 2, 0, 5, 1}, +}; + +const upb_msglayout google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit = { + NULL, + &google_protobuf_EnumDescriptorProto_EnumReservedRange__fields[0], + UPB_SIZE(12, 12), 2, false, +}; + +static const upb_msglayout *const google_protobuf_EnumValueDescriptorProto_submsgs[1] = { + &google_protobuf_EnumValueOptions_msginit, +}; + +static const upb_msglayout_field google_protobuf_EnumValueDescriptorProto__fields[3] = { + {1, UPB_SIZE(8, 8), 2, 0, 9, 1}, + {2, UPB_SIZE(4, 4), 1, 0, 5, 1}, + {3, UPB_SIZE(16, 24), 3, 0, 11, 1}, +}; + +const upb_msglayout google_protobuf_EnumValueDescriptorProto_msginit = { + &google_protobuf_EnumValueDescriptorProto_submsgs[0], + &google_protobuf_EnumValueDescriptorProto__fields[0], + UPB_SIZE(24, 32), 3, false, +}; + +static const upb_msglayout *const google_protobuf_ServiceDescriptorProto_submsgs[2] = { + &google_protobuf_MethodDescriptorProto_msginit, + &google_protobuf_ServiceOptions_msginit, +}; + +static const upb_msglayout_field google_protobuf_ServiceDescriptorProto__fields[3] = { + {1, UPB_SIZE(4, 8), 1, 0, 9, 1}, + {2, UPB_SIZE(16, 32), 0, 0, 11, 3}, + {3, UPB_SIZE(12, 24), 2, 1, 11, 1}, +}; + +const upb_msglayout google_protobuf_ServiceDescriptorProto_msginit = { + &google_protobuf_ServiceDescriptorProto_submsgs[0], + &google_protobuf_ServiceDescriptorProto__fields[0], + UPB_SIZE(24, 48), 3, false, +}; + +static const upb_msglayout *const google_protobuf_MethodDescriptorProto_submsgs[1] = { + &google_protobuf_MethodOptions_msginit, +}; + +static const upb_msglayout_field google_protobuf_MethodDescriptorProto__fields[6] = { + {1, UPB_SIZE(4, 8), 3, 0, 9, 1}, + {2, UPB_SIZE(12, 24), 4, 0, 9, 1}, + {3, UPB_SIZE(20, 40), 5, 0, 9, 1}, + {4, UPB_SIZE(28, 56), 6, 0, 11, 1}, + {5, UPB_SIZE(1, 1), 1, 0, 8, 1}, + {6, UPB_SIZE(2, 2), 2, 0, 8, 1}, +}; + +const upb_msglayout google_protobuf_MethodDescriptorProto_msginit = { + &google_protobuf_MethodDescriptorProto_submsgs[0], + &google_protobuf_MethodDescriptorProto__fields[0], + UPB_SIZE(32, 64), 6, false, +}; + +static const upb_msglayout *const google_protobuf_FileOptions_submsgs[1] = { + &google_protobuf_UninterpretedOption_msginit, +}; + +static const upb_msglayout_field google_protobuf_FileOptions__fields[21] = { + {1, UPB_SIZE(28, 32), 11, 0, 9, 1}, + {8, UPB_SIZE(36, 48), 12, 0, 9, 1}, + {9, UPB_SIZE(8, 8), 1, 0, 14, 1}, + {10, UPB_SIZE(16, 16), 2, 0, 8, 1}, + {11, UPB_SIZE(44, 64), 13, 0, 9, 1}, + {16, UPB_SIZE(17, 17), 3, 0, 8, 1}, + {17, UPB_SIZE(18, 18), 4, 0, 8, 1}, + {18, UPB_SIZE(19, 19), 5, 0, 8, 1}, + {20, UPB_SIZE(20, 20), 6, 0, 8, 1}, + {23, UPB_SIZE(21, 21), 7, 0, 8, 1}, + {27, UPB_SIZE(22, 22), 8, 0, 8, 1}, + {31, UPB_SIZE(23, 23), 9, 0, 8, 1}, + {36, UPB_SIZE(52, 80), 14, 0, 9, 1}, + {37, UPB_SIZE(60, 96), 15, 0, 9, 1}, + {39, UPB_SIZE(68, 112), 16, 0, 9, 1}, + {40, UPB_SIZE(76, 128), 17, 0, 9, 1}, + {41, UPB_SIZE(84, 144), 18, 0, 9, 1}, + {42, UPB_SIZE(24, 24), 10, 0, 8, 1}, + {44, UPB_SIZE(92, 160), 19, 0, 9, 1}, + {45, UPB_SIZE(100, 176), 20, 0, 9, 1}, + {999, UPB_SIZE(108, 192), 0, 0, 11, 3}, +}; + +const upb_msglayout google_protobuf_FileOptions_msginit = { + &google_protobuf_FileOptions_submsgs[0], + &google_protobuf_FileOptions__fields[0], + UPB_SIZE(112, 208), 21, false, +}; + +static const upb_msglayout *const google_protobuf_MessageOptions_submsgs[1] = { + &google_protobuf_UninterpretedOption_msginit, +}; + +static const upb_msglayout_field google_protobuf_MessageOptions__fields[5] = { + {1, UPB_SIZE(1, 1), 1, 0, 8, 1}, + {2, UPB_SIZE(2, 2), 2, 0, 8, 1}, + {3, UPB_SIZE(3, 3), 3, 0, 8, 1}, + {7, UPB_SIZE(4, 4), 4, 0, 8, 1}, + {999, UPB_SIZE(8, 8), 0, 0, 11, 3}, +}; + +const upb_msglayout google_protobuf_MessageOptions_msginit = { + &google_protobuf_MessageOptions_submsgs[0], + &google_protobuf_MessageOptions__fields[0], + UPB_SIZE(12, 16), 5, false, +}; + +static const upb_msglayout *const google_protobuf_FieldOptions_submsgs[1] = { + &google_protobuf_UninterpretedOption_msginit, +}; + +static const upb_msglayout_field google_protobuf_FieldOptions__fields[7] = { + {1, UPB_SIZE(8, 8), 1, 0, 14, 1}, + {2, UPB_SIZE(24, 24), 3, 0, 8, 1}, + {3, UPB_SIZE(25, 25), 4, 0, 8, 1}, + {5, UPB_SIZE(26, 26), 5, 0, 8, 1}, + {6, UPB_SIZE(16, 16), 2, 0, 14, 1}, + {10, UPB_SIZE(27, 27), 6, 0, 8, 1}, + {999, UPB_SIZE(28, 32), 0, 0, 11, 3}, +}; + +const upb_msglayout google_protobuf_FieldOptions_msginit = { + &google_protobuf_FieldOptions_submsgs[0], + &google_protobuf_FieldOptions__fields[0], + UPB_SIZE(32, 40), 7, false, +}; + +static const upb_msglayout *const google_protobuf_OneofOptions_submsgs[1] = { + &google_protobuf_UninterpretedOption_msginit, +}; + +static const upb_msglayout_field google_protobuf_OneofOptions__fields[1] = { + {999, UPB_SIZE(0, 0), 0, 0, 11, 3}, +}; + +const upb_msglayout google_protobuf_OneofOptions_msginit = { + &google_protobuf_OneofOptions_submsgs[0], + &google_protobuf_OneofOptions__fields[0], + UPB_SIZE(4, 8), 1, false, +}; + +static const upb_msglayout *const google_protobuf_EnumOptions_submsgs[1] = { + &google_protobuf_UninterpretedOption_msginit, +}; + +static const upb_msglayout_field google_protobuf_EnumOptions__fields[3] = { + {2, UPB_SIZE(1, 1), 1, 0, 8, 1}, + {3, UPB_SIZE(2, 2), 2, 0, 8, 1}, + {999, UPB_SIZE(4, 8), 0, 0, 11, 3}, +}; + +const upb_msglayout google_protobuf_EnumOptions_msginit = { + &google_protobuf_EnumOptions_submsgs[0], + &google_protobuf_EnumOptions__fields[0], + UPB_SIZE(8, 16), 3, false, +}; + +static const upb_msglayout *const google_protobuf_EnumValueOptions_submsgs[1] = { + &google_protobuf_UninterpretedOption_msginit, +}; + +static const upb_msglayout_field google_protobuf_EnumValueOptions__fields[2] = { + {1, UPB_SIZE(1, 1), 1, 0, 8, 1}, + {999, UPB_SIZE(4, 8), 0, 0, 11, 3}, +}; + +const upb_msglayout google_protobuf_EnumValueOptions_msginit = { + &google_protobuf_EnumValueOptions_submsgs[0], + &google_protobuf_EnumValueOptions__fields[0], + UPB_SIZE(8, 16), 2, false, +}; + +static const upb_msglayout *const google_protobuf_ServiceOptions_submsgs[1] = { + &google_protobuf_UninterpretedOption_msginit, +}; + +static const upb_msglayout_field google_protobuf_ServiceOptions__fields[2] = { + {33, UPB_SIZE(1, 1), 1, 0, 8, 1}, + {999, UPB_SIZE(4, 8), 0, 0, 11, 3}, +}; + +const upb_msglayout google_protobuf_ServiceOptions_msginit = { + &google_protobuf_ServiceOptions_submsgs[0], + &google_protobuf_ServiceOptions__fields[0], + UPB_SIZE(8, 16), 2, false, +}; + +static const upb_msglayout *const google_protobuf_MethodOptions_submsgs[1] = { + &google_protobuf_UninterpretedOption_msginit, +}; + +static const upb_msglayout_field google_protobuf_MethodOptions__fields[3] = { + {33, UPB_SIZE(16, 16), 2, 0, 8, 1}, + {34, UPB_SIZE(8, 8), 1, 0, 14, 1}, + {999, UPB_SIZE(20, 24), 0, 0, 11, 3}, +}; + +const upb_msglayout google_protobuf_MethodOptions_msginit = { + &google_protobuf_MethodOptions_submsgs[0], + &google_protobuf_MethodOptions__fields[0], + UPB_SIZE(24, 32), 3, false, +}; + +static const upb_msglayout *const google_protobuf_UninterpretedOption_submsgs[1] = { + &google_protobuf_UninterpretedOption_NamePart_msginit, +}; + +static const upb_msglayout_field google_protobuf_UninterpretedOption__fields[7] = { + {2, UPB_SIZE(56, 80), 0, 0, 11, 3}, + {3, UPB_SIZE(32, 32), 4, 0, 9, 1}, + {4, UPB_SIZE(8, 8), 1, 0, 4, 1}, + {5, UPB_SIZE(16, 16), 2, 0, 3, 1}, + {6, UPB_SIZE(24, 24), 3, 0, 1, 1}, + {7, UPB_SIZE(40, 48), 5, 0, 12, 1}, + {8, UPB_SIZE(48, 64), 6, 0, 9, 1}, +}; + +const upb_msglayout google_protobuf_UninterpretedOption_msginit = { + &google_protobuf_UninterpretedOption_submsgs[0], + &google_protobuf_UninterpretedOption__fields[0], + UPB_SIZE(64, 96), 7, false, +}; + +static const upb_msglayout_field google_protobuf_UninterpretedOption_NamePart__fields[2] = { + {1, UPB_SIZE(4, 8), 2, 0, 9, 2}, + {2, UPB_SIZE(1, 1), 1, 0, 8, 2}, +}; + +const upb_msglayout google_protobuf_UninterpretedOption_NamePart_msginit = { + NULL, + &google_protobuf_UninterpretedOption_NamePart__fields[0], + UPB_SIZE(16, 32), 2, false, +}; + +static const upb_msglayout *const google_protobuf_SourceCodeInfo_submsgs[1] = { + &google_protobuf_SourceCodeInfo_Location_msginit, +}; + +static const upb_msglayout_field google_protobuf_SourceCodeInfo__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 11, 3}, +}; + +const upb_msglayout google_protobuf_SourceCodeInfo_msginit = { + &google_protobuf_SourceCodeInfo_submsgs[0], + &google_protobuf_SourceCodeInfo__fields[0], + UPB_SIZE(4, 8), 1, false, +}; + +static const upb_msglayout_field google_protobuf_SourceCodeInfo_Location__fields[5] = { + {1, UPB_SIZE(20, 40), 0, 0, 5, 3}, + {2, UPB_SIZE(24, 48), 0, 0, 5, 3}, + {3, UPB_SIZE(4, 8), 1, 0, 9, 1}, + {4, UPB_SIZE(12, 24), 2, 0, 9, 1}, + {6, UPB_SIZE(28, 56), 0, 0, 9, 3}, +}; + +const upb_msglayout google_protobuf_SourceCodeInfo_Location_msginit = { + NULL, + &google_protobuf_SourceCodeInfo_Location__fields[0], + UPB_SIZE(32, 64), 5, false, +}; + +static const upb_msglayout *const google_protobuf_GeneratedCodeInfo_submsgs[1] = { + &google_protobuf_GeneratedCodeInfo_Annotation_msginit, +}; + +static const upb_msglayout_field google_protobuf_GeneratedCodeInfo__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 11, 3}, +}; + +const upb_msglayout google_protobuf_GeneratedCodeInfo_msginit = { + &google_protobuf_GeneratedCodeInfo_submsgs[0], + &google_protobuf_GeneratedCodeInfo__fields[0], + UPB_SIZE(4, 8), 1, false, +}; + +static const upb_msglayout_field google_protobuf_GeneratedCodeInfo_Annotation__fields[4] = { + {1, UPB_SIZE(20, 32), 0, 0, 5, 3}, + {2, UPB_SIZE(12, 16), 3, 0, 9, 1}, + {3, UPB_SIZE(4, 4), 1, 0, 5, 1}, + {4, UPB_SIZE(8, 8), 2, 0, 5, 1}, +}; + +const upb_msglayout google_protobuf_GeneratedCodeInfo_Annotation_msginit = { + NULL, + &google_protobuf_GeneratedCodeInfo_Annotation__fields[0], + UPB_SIZE(24, 48), 4, false, +}; + +#include "upb/port_undef.inc" + diff --git a/src/core/ext/upb-generated/google/protobuf/descriptor.upb.h b/src/core/ext/upb-generated/google/protobuf/descriptor.upb.h new file mode 100644 index 00000000000..11868b28f1f --- /dev/null +++ b/src/core/ext/upb-generated/google/protobuf/descriptor.upb.h @@ -0,0 +1,1692 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * google/protobuf/descriptor.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef GOOGLE_PROTOBUF_DESCRIPTOR_PROTO_UPB_H_ +#define GOOGLE_PROTOBUF_DESCRIPTOR_PROTO_UPB_H_ + +#include "upb/generated_util.h" + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +#ifdef __cplusplus +extern "C" { +#endif + +struct google_protobuf_FileDescriptorSet; +struct google_protobuf_FileDescriptorProto; +struct google_protobuf_DescriptorProto; +struct google_protobuf_DescriptorProto_ExtensionRange; +struct google_protobuf_DescriptorProto_ReservedRange; +struct google_protobuf_ExtensionRangeOptions; +struct google_protobuf_FieldDescriptorProto; +struct google_protobuf_OneofDescriptorProto; +struct google_protobuf_EnumDescriptorProto; +struct google_protobuf_EnumDescriptorProto_EnumReservedRange; +struct google_protobuf_EnumValueDescriptorProto; +struct google_protobuf_ServiceDescriptorProto; +struct google_protobuf_MethodDescriptorProto; +struct google_protobuf_FileOptions; +struct google_protobuf_MessageOptions; +struct google_protobuf_FieldOptions; +struct google_protobuf_OneofOptions; +struct google_protobuf_EnumOptions; +struct google_protobuf_EnumValueOptions; +struct google_protobuf_ServiceOptions; +struct google_protobuf_MethodOptions; +struct google_protobuf_UninterpretedOption; +struct google_protobuf_UninterpretedOption_NamePart; +struct google_protobuf_SourceCodeInfo; +struct google_protobuf_SourceCodeInfo_Location; +struct google_protobuf_GeneratedCodeInfo; +struct google_protobuf_GeneratedCodeInfo_Annotation; +typedef struct google_protobuf_FileDescriptorSet google_protobuf_FileDescriptorSet; +typedef struct google_protobuf_FileDescriptorProto google_protobuf_FileDescriptorProto; +typedef struct google_protobuf_DescriptorProto google_protobuf_DescriptorProto; +typedef struct google_protobuf_DescriptorProto_ExtensionRange google_protobuf_DescriptorProto_ExtensionRange; +typedef struct google_protobuf_DescriptorProto_ReservedRange google_protobuf_DescriptorProto_ReservedRange; +typedef struct google_protobuf_ExtensionRangeOptions google_protobuf_ExtensionRangeOptions; +typedef struct google_protobuf_FieldDescriptorProto google_protobuf_FieldDescriptorProto; +typedef struct google_protobuf_OneofDescriptorProto google_protobuf_OneofDescriptorProto; +typedef struct google_protobuf_EnumDescriptorProto google_protobuf_EnumDescriptorProto; +typedef struct google_protobuf_EnumDescriptorProto_EnumReservedRange google_protobuf_EnumDescriptorProto_EnumReservedRange; +typedef struct google_protobuf_EnumValueDescriptorProto google_protobuf_EnumValueDescriptorProto; +typedef struct google_protobuf_ServiceDescriptorProto google_protobuf_ServiceDescriptorProto; +typedef struct google_protobuf_MethodDescriptorProto google_protobuf_MethodDescriptorProto; +typedef struct google_protobuf_FileOptions google_protobuf_FileOptions; +typedef struct google_protobuf_MessageOptions google_protobuf_MessageOptions; +typedef struct google_protobuf_FieldOptions google_protobuf_FieldOptions; +typedef struct google_protobuf_OneofOptions google_protobuf_OneofOptions; +typedef struct google_protobuf_EnumOptions google_protobuf_EnumOptions; +typedef struct google_protobuf_EnumValueOptions google_protobuf_EnumValueOptions; +typedef struct google_protobuf_ServiceOptions google_protobuf_ServiceOptions; +typedef struct google_protobuf_MethodOptions google_protobuf_MethodOptions; +typedef struct google_protobuf_UninterpretedOption google_protobuf_UninterpretedOption; +typedef struct google_protobuf_UninterpretedOption_NamePart google_protobuf_UninterpretedOption_NamePart; +typedef struct google_protobuf_SourceCodeInfo google_protobuf_SourceCodeInfo; +typedef struct google_protobuf_SourceCodeInfo_Location google_protobuf_SourceCodeInfo_Location; +typedef struct google_protobuf_GeneratedCodeInfo google_protobuf_GeneratedCodeInfo; +typedef struct google_protobuf_GeneratedCodeInfo_Annotation google_protobuf_GeneratedCodeInfo_Annotation; +extern const upb_msglayout google_protobuf_FileDescriptorSet_msginit; +extern const upb_msglayout google_protobuf_FileDescriptorProto_msginit; +extern const upb_msglayout google_protobuf_DescriptorProto_msginit; +extern const upb_msglayout google_protobuf_DescriptorProto_ExtensionRange_msginit; +extern const upb_msglayout google_protobuf_DescriptorProto_ReservedRange_msginit; +extern const upb_msglayout google_protobuf_ExtensionRangeOptions_msginit; +extern const upb_msglayout google_protobuf_FieldDescriptorProto_msginit; +extern const upb_msglayout google_protobuf_OneofDescriptorProto_msginit; +extern const upb_msglayout google_protobuf_EnumDescriptorProto_msginit; +extern const upb_msglayout google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit; +extern const upb_msglayout google_protobuf_EnumValueDescriptorProto_msginit; +extern const upb_msglayout google_protobuf_ServiceDescriptorProto_msginit; +extern const upb_msglayout google_protobuf_MethodDescriptorProto_msginit; +extern const upb_msglayout google_protobuf_FileOptions_msginit; +extern const upb_msglayout google_protobuf_MessageOptions_msginit; +extern const upb_msglayout google_protobuf_FieldOptions_msginit; +extern const upb_msglayout google_protobuf_OneofOptions_msginit; +extern const upb_msglayout google_protobuf_EnumOptions_msginit; +extern const upb_msglayout google_protobuf_EnumValueOptions_msginit; +extern const upb_msglayout google_protobuf_ServiceOptions_msginit; +extern const upb_msglayout google_protobuf_MethodOptions_msginit; +extern const upb_msglayout google_protobuf_UninterpretedOption_msginit; +extern const upb_msglayout google_protobuf_UninterpretedOption_NamePart_msginit; +extern const upb_msglayout google_protobuf_SourceCodeInfo_msginit; +extern const upb_msglayout google_protobuf_SourceCodeInfo_Location_msginit; +extern const upb_msglayout google_protobuf_GeneratedCodeInfo_msginit; +extern const upb_msglayout google_protobuf_GeneratedCodeInfo_Annotation_msginit; + +/* Enums */ + +typedef enum { + google_protobuf_FieldDescriptorProto_LABEL_OPTIONAL = 1, + google_protobuf_FieldDescriptorProto_LABEL_REQUIRED = 2, + google_protobuf_FieldDescriptorProto_LABEL_REPEATED = 3 +} google_protobuf_FieldDescriptorProto_Label; + +typedef enum { + google_protobuf_FieldDescriptorProto_TYPE_DOUBLE = 1, + google_protobuf_FieldDescriptorProto_TYPE_FLOAT = 2, + google_protobuf_FieldDescriptorProto_TYPE_INT64 = 3, + google_protobuf_FieldDescriptorProto_TYPE_UINT64 = 4, + google_protobuf_FieldDescriptorProto_TYPE_INT32 = 5, + google_protobuf_FieldDescriptorProto_TYPE_FIXED64 = 6, + google_protobuf_FieldDescriptorProto_TYPE_FIXED32 = 7, + google_protobuf_FieldDescriptorProto_TYPE_BOOL = 8, + google_protobuf_FieldDescriptorProto_TYPE_STRING = 9, + google_protobuf_FieldDescriptorProto_TYPE_GROUP = 10, + google_protobuf_FieldDescriptorProto_TYPE_MESSAGE = 11, + google_protobuf_FieldDescriptorProto_TYPE_BYTES = 12, + google_protobuf_FieldDescriptorProto_TYPE_UINT32 = 13, + google_protobuf_FieldDescriptorProto_TYPE_ENUM = 14, + google_protobuf_FieldDescriptorProto_TYPE_SFIXED32 = 15, + google_protobuf_FieldDescriptorProto_TYPE_SFIXED64 = 16, + google_protobuf_FieldDescriptorProto_TYPE_SINT32 = 17, + google_protobuf_FieldDescriptorProto_TYPE_SINT64 = 18 +} google_protobuf_FieldDescriptorProto_Type; + +typedef enum { + google_protobuf_FieldOptions_STRING = 0, + google_protobuf_FieldOptions_CORD = 1, + google_protobuf_FieldOptions_STRING_PIECE = 2 +} google_protobuf_FieldOptions_CType; + +typedef enum { + google_protobuf_FieldOptions_JS_NORMAL = 0, + google_protobuf_FieldOptions_JS_STRING = 1, + google_protobuf_FieldOptions_JS_NUMBER = 2 +} google_protobuf_FieldOptions_JSType; + +typedef enum { + google_protobuf_FileOptions_SPEED = 1, + google_protobuf_FileOptions_CODE_SIZE = 2, + google_protobuf_FileOptions_LITE_RUNTIME = 3 +} google_protobuf_FileOptions_OptimizeMode; + +typedef enum { + google_protobuf_MethodOptions_IDEMPOTENCY_UNKNOWN = 0, + google_protobuf_MethodOptions_NO_SIDE_EFFECTS = 1, + google_protobuf_MethodOptions_IDEMPOTENT = 2 +} google_protobuf_MethodOptions_IdempotencyLevel; + + +/* google.protobuf.FileDescriptorSet */ + +UPB_INLINE google_protobuf_FileDescriptorSet *google_protobuf_FileDescriptorSet_new(upb_arena *arena) { + return (google_protobuf_FileDescriptorSet *)upb_msg_new(&google_protobuf_FileDescriptorSet_msginit, arena); +} +UPB_INLINE google_protobuf_FileDescriptorSet *google_protobuf_FileDescriptorSet_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_FileDescriptorSet *ret = google_protobuf_FileDescriptorSet_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_FileDescriptorSet_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_FileDescriptorSet_serialize(const google_protobuf_FileDescriptorSet *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_FileDescriptorSet_msginit, arena, len); +} + +UPB_INLINE const google_protobuf_FileDescriptorProto* const* google_protobuf_FileDescriptorSet_file(const google_protobuf_FileDescriptorSet *msg, size_t *len) { return (const google_protobuf_FileDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(0, 0), len); } + +UPB_INLINE google_protobuf_FileDescriptorProto** google_protobuf_FileDescriptorSet_mutable_file(google_protobuf_FileDescriptorSet *msg, size_t *len) { + return (google_protobuf_FileDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len); +} +UPB_INLINE google_protobuf_FileDescriptorProto** google_protobuf_FileDescriptorSet_resize_file(google_protobuf_FileDescriptorSet *msg, size_t len, upb_arena *arena) { + return (google_protobuf_FileDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_FileDescriptorProto* google_protobuf_FileDescriptorSet_add_file(google_protobuf_FileDescriptorSet *msg, upb_arena *arena) { + struct google_protobuf_FileDescriptorProto* sub = (struct google_protobuf_FileDescriptorProto*)upb_msg_new(&google_protobuf_FileDescriptorProto_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} + + +/* google.protobuf.FileDescriptorProto */ + +UPB_INLINE google_protobuf_FileDescriptorProto *google_protobuf_FileDescriptorProto_new(upb_arena *arena) { + return (google_protobuf_FileDescriptorProto *)upb_msg_new(&google_protobuf_FileDescriptorProto_msginit, arena); +} +UPB_INLINE google_protobuf_FileDescriptorProto *google_protobuf_FileDescriptorProto_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_FileDescriptorProto *ret = google_protobuf_FileDescriptorProto_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_FileDescriptorProto_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_FileDescriptorProto_serialize(const google_protobuf_FileDescriptorProto *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_FileDescriptorProto_msginit, arena, len); +} + +UPB_INLINE bool google_protobuf_FileDescriptorProto_has_name(const google_protobuf_FileDescriptorProto *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE upb_strview google_protobuf_FileDescriptorProto_name(const google_protobuf_FileDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)); } +UPB_INLINE bool google_protobuf_FileDescriptorProto_has_package(const google_protobuf_FileDescriptorProto *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE upb_strview google_protobuf_FileDescriptorProto_package(const google_protobuf_FileDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(12, 24)); } +UPB_INLINE upb_strview const* google_protobuf_FileDescriptorProto_dependency(const google_protobuf_FileDescriptorProto *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(36, 72), len); } +UPB_INLINE const google_protobuf_DescriptorProto* const* google_protobuf_FileDescriptorProto_message_type(const google_protobuf_FileDescriptorProto *msg, size_t *len) { return (const google_protobuf_DescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(40, 80), len); } +UPB_INLINE const google_protobuf_EnumDescriptorProto* const* google_protobuf_FileDescriptorProto_enum_type(const google_protobuf_FileDescriptorProto *msg, size_t *len) { return (const google_protobuf_EnumDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(44, 88), len); } +UPB_INLINE const google_protobuf_ServiceDescriptorProto* const* google_protobuf_FileDescriptorProto_service(const google_protobuf_FileDescriptorProto *msg, size_t *len) { return (const google_protobuf_ServiceDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(48, 96), len); } +UPB_INLINE const google_protobuf_FieldDescriptorProto* const* google_protobuf_FileDescriptorProto_extension(const google_protobuf_FileDescriptorProto *msg, size_t *len) { return (const google_protobuf_FieldDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(52, 104), len); } +UPB_INLINE bool google_protobuf_FileDescriptorProto_has_options(const google_protobuf_FileDescriptorProto *msg) { return _upb_has_field(msg, 4); } +UPB_INLINE const google_protobuf_FileOptions* google_protobuf_FileDescriptorProto_options(const google_protobuf_FileDescriptorProto *msg) { return UPB_FIELD_AT(msg, const google_protobuf_FileOptions*, UPB_SIZE(28, 56)); } +UPB_INLINE bool google_protobuf_FileDescriptorProto_has_source_code_info(const google_protobuf_FileDescriptorProto *msg) { return _upb_has_field(msg, 5); } +UPB_INLINE const google_protobuf_SourceCodeInfo* google_protobuf_FileDescriptorProto_source_code_info(const google_protobuf_FileDescriptorProto *msg) { return UPB_FIELD_AT(msg, const google_protobuf_SourceCodeInfo*, UPB_SIZE(32, 64)); } +UPB_INLINE int32_t const* google_protobuf_FileDescriptorProto_public_dependency(const google_protobuf_FileDescriptorProto *msg, size_t *len) { return (int32_t const*)_upb_array_accessor(msg, UPB_SIZE(56, 112), len); } +UPB_INLINE int32_t const* google_protobuf_FileDescriptorProto_weak_dependency(const google_protobuf_FileDescriptorProto *msg, size_t *len) { return (int32_t const*)_upb_array_accessor(msg, UPB_SIZE(60, 120), len); } +UPB_INLINE bool google_protobuf_FileDescriptorProto_has_syntax(const google_protobuf_FileDescriptorProto *msg) { return _upb_has_field(msg, 3); } +UPB_INLINE upb_strview google_protobuf_FileDescriptorProto_syntax(const google_protobuf_FileDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(20, 40)); } + +UPB_INLINE void google_protobuf_FileDescriptorProto_set_name(google_protobuf_FileDescriptorProto *msg, upb_strview value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)) = value; +} +UPB_INLINE void google_protobuf_FileDescriptorProto_set_package(google_protobuf_FileDescriptorProto *msg, upb_strview value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(12, 24)) = value; +} +UPB_INLINE upb_strview* google_protobuf_FileDescriptorProto_mutable_dependency(google_protobuf_FileDescriptorProto *msg, size_t *len) { + return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(36, 72), len); +} +UPB_INLINE upb_strview* google_protobuf_FileDescriptorProto_resize_dependency(google_protobuf_FileDescriptorProto *msg, size_t len, upb_arena *arena) { + return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(36, 72), len, UPB_SIZE(8, 16), UPB_TYPE_STRING, arena); +} +UPB_INLINE bool google_protobuf_FileDescriptorProto_add_dependency(google_protobuf_FileDescriptorProto *msg, upb_strview val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(36, 72), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, arena); +} +UPB_INLINE google_protobuf_DescriptorProto** google_protobuf_FileDescriptorProto_mutable_message_type(google_protobuf_FileDescriptorProto *msg, size_t *len) { + return (google_protobuf_DescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(40, 80), len); +} +UPB_INLINE google_protobuf_DescriptorProto** google_protobuf_FileDescriptorProto_resize_message_type(google_protobuf_FileDescriptorProto *msg, size_t len, upb_arena *arena) { + return (google_protobuf_DescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(40, 80), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_DescriptorProto* google_protobuf_FileDescriptorProto_add_message_type(google_protobuf_FileDescriptorProto *msg, upb_arena *arena) { + struct google_protobuf_DescriptorProto* sub = (struct google_protobuf_DescriptorProto*)upb_msg_new(&google_protobuf_DescriptorProto_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(40, 80), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE google_protobuf_EnumDescriptorProto** google_protobuf_FileDescriptorProto_mutable_enum_type(google_protobuf_FileDescriptorProto *msg, size_t *len) { + return (google_protobuf_EnumDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(44, 88), len); +} +UPB_INLINE google_protobuf_EnumDescriptorProto** google_protobuf_FileDescriptorProto_resize_enum_type(google_protobuf_FileDescriptorProto *msg, size_t len, upb_arena *arena) { + return (google_protobuf_EnumDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(44, 88), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_EnumDescriptorProto* google_protobuf_FileDescriptorProto_add_enum_type(google_protobuf_FileDescriptorProto *msg, upb_arena *arena) { + struct google_protobuf_EnumDescriptorProto* sub = (struct google_protobuf_EnumDescriptorProto*)upb_msg_new(&google_protobuf_EnumDescriptorProto_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(44, 88), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE google_protobuf_ServiceDescriptorProto** google_protobuf_FileDescriptorProto_mutable_service(google_protobuf_FileDescriptorProto *msg, size_t *len) { + return (google_protobuf_ServiceDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(48, 96), len); +} +UPB_INLINE google_protobuf_ServiceDescriptorProto** google_protobuf_FileDescriptorProto_resize_service(google_protobuf_FileDescriptorProto *msg, size_t len, upb_arena *arena) { + return (google_protobuf_ServiceDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(48, 96), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_ServiceDescriptorProto* google_protobuf_FileDescriptorProto_add_service(google_protobuf_FileDescriptorProto *msg, upb_arena *arena) { + struct google_protobuf_ServiceDescriptorProto* sub = (struct google_protobuf_ServiceDescriptorProto*)upb_msg_new(&google_protobuf_ServiceDescriptorProto_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(48, 96), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_FileDescriptorProto_mutable_extension(google_protobuf_FileDescriptorProto *msg, size_t *len) { + return (google_protobuf_FieldDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(52, 104), len); +} +UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_FileDescriptorProto_resize_extension(google_protobuf_FileDescriptorProto *msg, size_t len, upb_arena *arena) { + return (google_protobuf_FieldDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(52, 104), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_FieldDescriptorProto* google_protobuf_FileDescriptorProto_add_extension(google_protobuf_FileDescriptorProto *msg, upb_arena *arena) { + struct google_protobuf_FieldDescriptorProto* sub = (struct google_protobuf_FieldDescriptorProto*)upb_msg_new(&google_protobuf_FieldDescriptorProto_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(52, 104), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE void google_protobuf_FileDescriptorProto_set_options(google_protobuf_FileDescriptorProto *msg, google_protobuf_FileOptions* value) { + _upb_sethas(msg, 4); + UPB_FIELD_AT(msg, google_protobuf_FileOptions*, UPB_SIZE(28, 56)) = value; +} +UPB_INLINE struct google_protobuf_FileOptions* google_protobuf_FileDescriptorProto_mutable_options(google_protobuf_FileDescriptorProto *msg, upb_arena *arena) { + struct google_protobuf_FileOptions* sub = (struct google_protobuf_FileOptions*)google_protobuf_FileDescriptorProto_options(msg); + if (sub == NULL) { + sub = (struct google_protobuf_FileOptions*)upb_msg_new(&google_protobuf_FileOptions_msginit, arena); + if (!sub) return NULL; + google_protobuf_FileDescriptorProto_set_options(msg, sub); + } + return sub; +} +UPB_INLINE void google_protobuf_FileDescriptorProto_set_source_code_info(google_protobuf_FileDescriptorProto *msg, google_protobuf_SourceCodeInfo* value) { + _upb_sethas(msg, 5); + UPB_FIELD_AT(msg, google_protobuf_SourceCodeInfo*, UPB_SIZE(32, 64)) = value; +} +UPB_INLINE struct google_protobuf_SourceCodeInfo* google_protobuf_FileDescriptorProto_mutable_source_code_info(google_protobuf_FileDescriptorProto *msg, upb_arena *arena) { + struct google_protobuf_SourceCodeInfo* sub = (struct google_protobuf_SourceCodeInfo*)google_protobuf_FileDescriptorProto_source_code_info(msg); + if (sub == NULL) { + sub = (struct google_protobuf_SourceCodeInfo*)upb_msg_new(&google_protobuf_SourceCodeInfo_msginit, arena); + if (!sub) return NULL; + google_protobuf_FileDescriptorProto_set_source_code_info(msg, sub); + } + return sub; +} +UPB_INLINE int32_t* google_protobuf_FileDescriptorProto_mutable_public_dependency(google_protobuf_FileDescriptorProto *msg, size_t *len) { + return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(56, 112), len); +} +UPB_INLINE int32_t* google_protobuf_FileDescriptorProto_resize_public_dependency(google_protobuf_FileDescriptorProto *msg, size_t len, upb_arena *arena) { + return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(56, 112), len, UPB_SIZE(4, 4), UPB_TYPE_INT32, arena); +} +UPB_INLINE bool google_protobuf_FileDescriptorProto_add_public_dependency(google_protobuf_FileDescriptorProto *msg, int32_t val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(56, 112), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val, arena); +} +UPB_INLINE int32_t* google_protobuf_FileDescriptorProto_mutable_weak_dependency(google_protobuf_FileDescriptorProto *msg, size_t *len) { + return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(60, 120), len); +} +UPB_INLINE int32_t* google_protobuf_FileDescriptorProto_resize_weak_dependency(google_protobuf_FileDescriptorProto *msg, size_t len, upb_arena *arena) { + return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(60, 120), len, UPB_SIZE(4, 4), UPB_TYPE_INT32, arena); +} +UPB_INLINE bool google_protobuf_FileDescriptorProto_add_weak_dependency(google_protobuf_FileDescriptorProto *msg, int32_t val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(60, 120), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val, arena); +} +UPB_INLINE void google_protobuf_FileDescriptorProto_set_syntax(google_protobuf_FileDescriptorProto *msg, upb_strview value) { + _upb_sethas(msg, 3); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(20, 40)) = value; +} + + +/* google.protobuf.DescriptorProto */ + +UPB_INLINE google_protobuf_DescriptorProto *google_protobuf_DescriptorProto_new(upb_arena *arena) { + return (google_protobuf_DescriptorProto *)upb_msg_new(&google_protobuf_DescriptorProto_msginit, arena); +} +UPB_INLINE google_protobuf_DescriptorProto *google_protobuf_DescriptorProto_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_DescriptorProto *ret = google_protobuf_DescriptorProto_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_DescriptorProto_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_DescriptorProto_serialize(const google_protobuf_DescriptorProto *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_DescriptorProto_msginit, arena, len); +} + +UPB_INLINE bool google_protobuf_DescriptorProto_has_name(const google_protobuf_DescriptorProto *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE upb_strview google_protobuf_DescriptorProto_name(const google_protobuf_DescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)); } +UPB_INLINE const google_protobuf_FieldDescriptorProto* const* google_protobuf_DescriptorProto_field(const google_protobuf_DescriptorProto *msg, size_t *len) { return (const google_protobuf_FieldDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(16, 32), len); } +UPB_INLINE const google_protobuf_DescriptorProto* const* google_protobuf_DescriptorProto_nested_type(const google_protobuf_DescriptorProto *msg, size_t *len) { return (const google_protobuf_DescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(20, 40), len); } +UPB_INLINE const google_protobuf_EnumDescriptorProto* const* google_protobuf_DescriptorProto_enum_type(const google_protobuf_DescriptorProto *msg, size_t *len) { return (const google_protobuf_EnumDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(24, 48), len); } +UPB_INLINE const google_protobuf_DescriptorProto_ExtensionRange* const* google_protobuf_DescriptorProto_extension_range(const google_protobuf_DescriptorProto *msg, size_t *len) { return (const google_protobuf_DescriptorProto_ExtensionRange* const*)_upb_array_accessor(msg, UPB_SIZE(28, 56), len); } +UPB_INLINE const google_protobuf_FieldDescriptorProto* const* google_protobuf_DescriptorProto_extension(const google_protobuf_DescriptorProto *msg, size_t *len) { return (const google_protobuf_FieldDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(32, 64), len); } +UPB_INLINE bool google_protobuf_DescriptorProto_has_options(const google_protobuf_DescriptorProto *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE const google_protobuf_MessageOptions* google_protobuf_DescriptorProto_options(const google_protobuf_DescriptorProto *msg) { return UPB_FIELD_AT(msg, const google_protobuf_MessageOptions*, UPB_SIZE(12, 24)); } +UPB_INLINE const google_protobuf_OneofDescriptorProto* const* google_protobuf_DescriptorProto_oneof_decl(const google_protobuf_DescriptorProto *msg, size_t *len) { return (const google_protobuf_OneofDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(36, 72), len); } +UPB_INLINE const google_protobuf_DescriptorProto_ReservedRange* const* google_protobuf_DescriptorProto_reserved_range(const google_protobuf_DescriptorProto *msg, size_t *len) { return (const google_protobuf_DescriptorProto_ReservedRange* const*)_upb_array_accessor(msg, UPB_SIZE(40, 80), len); } +UPB_INLINE upb_strview const* google_protobuf_DescriptorProto_reserved_name(const google_protobuf_DescriptorProto *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(44, 88), len); } + +UPB_INLINE void google_protobuf_DescriptorProto_set_name(google_protobuf_DescriptorProto *msg, upb_strview value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)) = value; +} +UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_DescriptorProto_mutable_field(google_protobuf_DescriptorProto *msg, size_t *len) { + return (google_protobuf_FieldDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(16, 32), len); +} +UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_DescriptorProto_resize_field(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) { + return (google_protobuf_FieldDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(16, 32), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_FieldDescriptorProto* google_protobuf_DescriptorProto_add_field(google_protobuf_DescriptorProto *msg, upb_arena *arena) { + struct google_protobuf_FieldDescriptorProto* sub = (struct google_protobuf_FieldDescriptorProto*)upb_msg_new(&google_protobuf_FieldDescriptorProto_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(16, 32), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE google_protobuf_DescriptorProto** google_protobuf_DescriptorProto_mutable_nested_type(google_protobuf_DescriptorProto *msg, size_t *len) { + return (google_protobuf_DescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 40), len); +} +UPB_INLINE google_protobuf_DescriptorProto** google_protobuf_DescriptorProto_resize_nested_type(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) { + return (google_protobuf_DescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(20, 40), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_DescriptorProto* google_protobuf_DescriptorProto_add_nested_type(google_protobuf_DescriptorProto *msg, upb_arena *arena) { + struct google_protobuf_DescriptorProto* sub = (struct google_protobuf_DescriptorProto*)upb_msg_new(&google_protobuf_DescriptorProto_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(20, 40), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE google_protobuf_EnumDescriptorProto** google_protobuf_DescriptorProto_mutable_enum_type(google_protobuf_DescriptorProto *msg, size_t *len) { + return (google_protobuf_EnumDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 48), len); +} +UPB_INLINE google_protobuf_EnumDescriptorProto** google_protobuf_DescriptorProto_resize_enum_type(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) { + return (google_protobuf_EnumDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(24, 48), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_EnumDescriptorProto* google_protobuf_DescriptorProto_add_enum_type(google_protobuf_DescriptorProto *msg, upb_arena *arena) { + struct google_protobuf_EnumDescriptorProto* sub = (struct google_protobuf_EnumDescriptorProto*)upb_msg_new(&google_protobuf_EnumDescriptorProto_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(24, 48), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange** google_protobuf_DescriptorProto_mutable_extension_range(google_protobuf_DescriptorProto *msg, size_t *len) { + return (google_protobuf_DescriptorProto_ExtensionRange**)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 56), len); +} +UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange** google_protobuf_DescriptorProto_resize_extension_range(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) { + return (google_protobuf_DescriptorProto_ExtensionRange**)_upb_array_resize_accessor(msg, UPB_SIZE(28, 56), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_DescriptorProto_ExtensionRange* google_protobuf_DescriptorProto_add_extension_range(google_protobuf_DescriptorProto *msg, upb_arena *arena) { + struct google_protobuf_DescriptorProto_ExtensionRange* sub = (struct google_protobuf_DescriptorProto_ExtensionRange*)upb_msg_new(&google_protobuf_DescriptorProto_ExtensionRange_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(28, 56), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_DescriptorProto_mutable_extension(google_protobuf_DescriptorProto *msg, size_t *len) { + return (google_protobuf_FieldDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(32, 64), len); +} +UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_DescriptorProto_resize_extension(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) { + return (google_protobuf_FieldDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(32, 64), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_FieldDescriptorProto* google_protobuf_DescriptorProto_add_extension(google_protobuf_DescriptorProto *msg, upb_arena *arena) { + struct google_protobuf_FieldDescriptorProto* sub = (struct google_protobuf_FieldDescriptorProto*)upb_msg_new(&google_protobuf_FieldDescriptorProto_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(32, 64), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE void google_protobuf_DescriptorProto_set_options(google_protobuf_DescriptorProto *msg, google_protobuf_MessageOptions* value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, google_protobuf_MessageOptions*, UPB_SIZE(12, 24)) = value; +} +UPB_INLINE struct google_protobuf_MessageOptions* google_protobuf_DescriptorProto_mutable_options(google_protobuf_DescriptorProto *msg, upb_arena *arena) { + struct google_protobuf_MessageOptions* sub = (struct google_protobuf_MessageOptions*)google_protobuf_DescriptorProto_options(msg); + if (sub == NULL) { + sub = (struct google_protobuf_MessageOptions*)upb_msg_new(&google_protobuf_MessageOptions_msginit, arena); + if (!sub) return NULL; + google_protobuf_DescriptorProto_set_options(msg, sub); + } + return sub; +} +UPB_INLINE google_protobuf_OneofDescriptorProto** google_protobuf_DescriptorProto_mutable_oneof_decl(google_protobuf_DescriptorProto *msg, size_t *len) { + return (google_protobuf_OneofDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(36, 72), len); +} +UPB_INLINE google_protobuf_OneofDescriptorProto** google_protobuf_DescriptorProto_resize_oneof_decl(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) { + return (google_protobuf_OneofDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(36, 72), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_OneofDescriptorProto* google_protobuf_DescriptorProto_add_oneof_decl(google_protobuf_DescriptorProto *msg, upb_arena *arena) { + struct google_protobuf_OneofDescriptorProto* sub = (struct google_protobuf_OneofDescriptorProto*)upb_msg_new(&google_protobuf_OneofDescriptorProto_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(36, 72), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE google_protobuf_DescriptorProto_ReservedRange** google_protobuf_DescriptorProto_mutable_reserved_range(google_protobuf_DescriptorProto *msg, size_t *len) { + return (google_protobuf_DescriptorProto_ReservedRange**)_upb_array_mutable_accessor(msg, UPB_SIZE(40, 80), len); +} +UPB_INLINE google_protobuf_DescriptorProto_ReservedRange** google_protobuf_DescriptorProto_resize_reserved_range(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) { + return (google_protobuf_DescriptorProto_ReservedRange**)_upb_array_resize_accessor(msg, UPB_SIZE(40, 80), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_DescriptorProto_ReservedRange* google_protobuf_DescriptorProto_add_reserved_range(google_protobuf_DescriptorProto *msg, upb_arena *arena) { + struct google_protobuf_DescriptorProto_ReservedRange* sub = (struct google_protobuf_DescriptorProto_ReservedRange*)upb_msg_new(&google_protobuf_DescriptorProto_ReservedRange_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(40, 80), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE upb_strview* google_protobuf_DescriptorProto_mutable_reserved_name(google_protobuf_DescriptorProto *msg, size_t *len) { + return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(44, 88), len); +} +UPB_INLINE upb_strview* google_protobuf_DescriptorProto_resize_reserved_name(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) { + return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(44, 88), len, UPB_SIZE(8, 16), UPB_TYPE_STRING, arena); +} +UPB_INLINE bool google_protobuf_DescriptorProto_add_reserved_name(google_protobuf_DescriptorProto *msg, upb_strview val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(44, 88), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, arena); +} + + +/* google.protobuf.DescriptorProto.ExtensionRange */ + +UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange *google_protobuf_DescriptorProto_ExtensionRange_new(upb_arena *arena) { + return (google_protobuf_DescriptorProto_ExtensionRange *)upb_msg_new(&google_protobuf_DescriptorProto_ExtensionRange_msginit, arena); +} +UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange *google_protobuf_DescriptorProto_ExtensionRange_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_DescriptorProto_ExtensionRange *ret = google_protobuf_DescriptorProto_ExtensionRange_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_DescriptorProto_ExtensionRange_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_DescriptorProto_ExtensionRange_serialize(const google_protobuf_DescriptorProto_ExtensionRange *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_DescriptorProto_ExtensionRange_msginit, arena, len); +} + +UPB_INLINE bool google_protobuf_DescriptorProto_ExtensionRange_has_start(const google_protobuf_DescriptorProto_ExtensionRange *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE int32_t google_protobuf_DescriptorProto_ExtensionRange_start(const google_protobuf_DescriptorProto_ExtensionRange *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)); } +UPB_INLINE bool google_protobuf_DescriptorProto_ExtensionRange_has_end(const google_protobuf_DescriptorProto_ExtensionRange *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE int32_t google_protobuf_DescriptorProto_ExtensionRange_end(const google_protobuf_DescriptorProto_ExtensionRange *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); } +UPB_INLINE bool google_protobuf_DescriptorProto_ExtensionRange_has_options(const google_protobuf_DescriptorProto_ExtensionRange *msg) { return _upb_has_field(msg, 3); } +UPB_INLINE const google_protobuf_ExtensionRangeOptions* google_protobuf_DescriptorProto_ExtensionRange_options(const google_protobuf_DescriptorProto_ExtensionRange *msg) { return UPB_FIELD_AT(msg, const google_protobuf_ExtensionRangeOptions*, UPB_SIZE(12, 16)); } + +UPB_INLINE void google_protobuf_DescriptorProto_ExtensionRange_set_start(google_protobuf_DescriptorProto_ExtensionRange *msg, int32_t value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)) = value; +} +UPB_INLINE void google_protobuf_DescriptorProto_ExtensionRange_set_end(google_protobuf_DescriptorProto_ExtensionRange *msg, int32_t value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE void google_protobuf_DescriptorProto_ExtensionRange_set_options(google_protobuf_DescriptorProto_ExtensionRange *msg, google_protobuf_ExtensionRangeOptions* value) { + _upb_sethas(msg, 3); + UPB_FIELD_AT(msg, google_protobuf_ExtensionRangeOptions*, UPB_SIZE(12, 16)) = value; +} +UPB_INLINE struct google_protobuf_ExtensionRangeOptions* google_protobuf_DescriptorProto_ExtensionRange_mutable_options(google_protobuf_DescriptorProto_ExtensionRange *msg, upb_arena *arena) { + struct google_protobuf_ExtensionRangeOptions* sub = (struct google_protobuf_ExtensionRangeOptions*)google_protobuf_DescriptorProto_ExtensionRange_options(msg); + if (sub == NULL) { + sub = (struct google_protobuf_ExtensionRangeOptions*)upb_msg_new(&google_protobuf_ExtensionRangeOptions_msginit, arena); + if (!sub) return NULL; + google_protobuf_DescriptorProto_ExtensionRange_set_options(msg, sub); + } + return sub; +} + + +/* google.protobuf.DescriptorProto.ReservedRange */ + +UPB_INLINE google_protobuf_DescriptorProto_ReservedRange *google_protobuf_DescriptorProto_ReservedRange_new(upb_arena *arena) { + return (google_protobuf_DescriptorProto_ReservedRange *)upb_msg_new(&google_protobuf_DescriptorProto_ReservedRange_msginit, arena); +} +UPB_INLINE google_protobuf_DescriptorProto_ReservedRange *google_protobuf_DescriptorProto_ReservedRange_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_DescriptorProto_ReservedRange *ret = google_protobuf_DescriptorProto_ReservedRange_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_DescriptorProto_ReservedRange_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_DescriptorProto_ReservedRange_serialize(const google_protobuf_DescriptorProto_ReservedRange *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_DescriptorProto_ReservedRange_msginit, arena, len); +} + +UPB_INLINE bool google_protobuf_DescriptorProto_ReservedRange_has_start(const google_protobuf_DescriptorProto_ReservedRange *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE int32_t google_protobuf_DescriptorProto_ReservedRange_start(const google_protobuf_DescriptorProto_ReservedRange *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)); } +UPB_INLINE bool google_protobuf_DescriptorProto_ReservedRange_has_end(const google_protobuf_DescriptorProto_ReservedRange *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE int32_t google_protobuf_DescriptorProto_ReservedRange_end(const google_protobuf_DescriptorProto_ReservedRange *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); } + +UPB_INLINE void google_protobuf_DescriptorProto_ReservedRange_set_start(google_protobuf_DescriptorProto_ReservedRange *msg, int32_t value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)) = value; +} +UPB_INLINE void google_protobuf_DescriptorProto_ReservedRange_set_end(google_protobuf_DescriptorProto_ReservedRange *msg, int32_t value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value; +} + + +/* google.protobuf.ExtensionRangeOptions */ + +UPB_INLINE google_protobuf_ExtensionRangeOptions *google_protobuf_ExtensionRangeOptions_new(upb_arena *arena) { + return (google_protobuf_ExtensionRangeOptions *)upb_msg_new(&google_protobuf_ExtensionRangeOptions_msginit, arena); +} +UPB_INLINE google_protobuf_ExtensionRangeOptions *google_protobuf_ExtensionRangeOptions_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_ExtensionRangeOptions *ret = google_protobuf_ExtensionRangeOptions_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_ExtensionRangeOptions_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_ExtensionRangeOptions_serialize(const google_protobuf_ExtensionRangeOptions *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_ExtensionRangeOptions_msginit, arena, len); +} + +UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_ExtensionRangeOptions_uninterpreted_option(const google_protobuf_ExtensionRangeOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(0, 0), len); } + +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_ExtensionRangeOptions_mutable_uninterpreted_option(google_protobuf_ExtensionRangeOptions *msg, size_t *len) { + return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len); +} +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_ExtensionRangeOptions_resize_uninterpreted_option(google_protobuf_ExtensionRangeOptions *msg, size_t len, upb_arena *arena) { + return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_ExtensionRangeOptions_add_uninterpreted_option(google_protobuf_ExtensionRangeOptions *msg, upb_arena *arena) { + struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} + + +/* google.protobuf.FieldDescriptorProto */ + +UPB_INLINE google_protobuf_FieldDescriptorProto *google_protobuf_FieldDescriptorProto_new(upb_arena *arena) { + return (google_protobuf_FieldDescriptorProto *)upb_msg_new(&google_protobuf_FieldDescriptorProto_msginit, arena); +} +UPB_INLINE google_protobuf_FieldDescriptorProto *google_protobuf_FieldDescriptorProto_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_FieldDescriptorProto *ret = google_protobuf_FieldDescriptorProto_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_FieldDescriptorProto_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_FieldDescriptorProto_serialize(const google_protobuf_FieldDescriptorProto *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_FieldDescriptorProto_msginit, arena, len); +} + +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_name(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 5); } +UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_name(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(32, 32)); } +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_extendee(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 6); } +UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_extendee(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(40, 48)); } +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_number(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 3); } +UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_number(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(24, 24)); } +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_label(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_label(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); } +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_type(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_type(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(16, 16)); } +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_type_name(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 7); } +UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_type_name(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(48, 64)); } +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_default_value(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 8); } +UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_default_value(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(56, 80)); } +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_options(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 10); } +UPB_INLINE const google_protobuf_FieldOptions* google_protobuf_FieldDescriptorProto_options(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, const google_protobuf_FieldOptions*, UPB_SIZE(72, 112)); } +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_oneof_index(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 4); } +UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_oneof_index(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(28, 28)); } +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_json_name(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 9); } +UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_json_name(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(64, 96)); } + +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_name(google_protobuf_FieldDescriptorProto *msg, upb_strview value) { + _upb_sethas(msg, 5); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(32, 32)) = value; +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_extendee(google_protobuf_FieldDescriptorProto *msg, upb_strview value) { + _upb_sethas(msg, 6); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(40, 48)) = value; +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_number(google_protobuf_FieldDescriptorProto *msg, int32_t value) { + _upb_sethas(msg, 3); + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(24, 24)) = value; +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_label(google_protobuf_FieldDescriptorProto *msg, int32_t value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_type(google_protobuf_FieldDescriptorProto *msg, int32_t value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(16, 16)) = value; +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_type_name(google_protobuf_FieldDescriptorProto *msg, upb_strview value) { + _upb_sethas(msg, 7); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(48, 64)) = value; +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_default_value(google_protobuf_FieldDescriptorProto *msg, upb_strview value) { + _upb_sethas(msg, 8); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(56, 80)) = value; +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_options(google_protobuf_FieldDescriptorProto *msg, google_protobuf_FieldOptions* value) { + _upb_sethas(msg, 10); + UPB_FIELD_AT(msg, google_protobuf_FieldOptions*, UPB_SIZE(72, 112)) = value; +} +UPB_INLINE struct google_protobuf_FieldOptions* google_protobuf_FieldDescriptorProto_mutable_options(google_protobuf_FieldDescriptorProto *msg, upb_arena *arena) { + struct google_protobuf_FieldOptions* sub = (struct google_protobuf_FieldOptions*)google_protobuf_FieldDescriptorProto_options(msg); + if (sub == NULL) { + sub = (struct google_protobuf_FieldOptions*)upb_msg_new(&google_protobuf_FieldOptions_msginit, arena); + if (!sub) return NULL; + google_protobuf_FieldDescriptorProto_set_options(msg, sub); + } + return sub; +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_oneof_index(google_protobuf_FieldDescriptorProto *msg, int32_t value) { + _upb_sethas(msg, 4); + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(28, 28)) = value; +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_json_name(google_protobuf_FieldDescriptorProto *msg, upb_strview value) { + _upb_sethas(msg, 9); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(64, 96)) = value; +} + + +/* google.protobuf.OneofDescriptorProto */ + +UPB_INLINE google_protobuf_OneofDescriptorProto *google_protobuf_OneofDescriptorProto_new(upb_arena *arena) { + return (google_protobuf_OneofDescriptorProto *)upb_msg_new(&google_protobuf_OneofDescriptorProto_msginit, arena); +} +UPB_INLINE google_protobuf_OneofDescriptorProto *google_protobuf_OneofDescriptorProto_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_OneofDescriptorProto *ret = google_protobuf_OneofDescriptorProto_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_OneofDescriptorProto_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_OneofDescriptorProto_serialize(const google_protobuf_OneofDescriptorProto *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_OneofDescriptorProto_msginit, arena, len); +} + +UPB_INLINE bool google_protobuf_OneofDescriptorProto_has_name(const google_protobuf_OneofDescriptorProto *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE upb_strview google_protobuf_OneofDescriptorProto_name(const google_protobuf_OneofDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)); } +UPB_INLINE bool google_protobuf_OneofDescriptorProto_has_options(const google_protobuf_OneofDescriptorProto *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE const google_protobuf_OneofOptions* google_protobuf_OneofDescriptorProto_options(const google_protobuf_OneofDescriptorProto *msg) { return UPB_FIELD_AT(msg, const google_protobuf_OneofOptions*, UPB_SIZE(12, 24)); } + +UPB_INLINE void google_protobuf_OneofDescriptorProto_set_name(google_protobuf_OneofDescriptorProto *msg, upb_strview value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)) = value; +} +UPB_INLINE void google_protobuf_OneofDescriptorProto_set_options(google_protobuf_OneofDescriptorProto *msg, google_protobuf_OneofOptions* value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, google_protobuf_OneofOptions*, UPB_SIZE(12, 24)) = value; +} +UPB_INLINE struct google_protobuf_OneofOptions* google_protobuf_OneofDescriptorProto_mutable_options(google_protobuf_OneofDescriptorProto *msg, upb_arena *arena) { + struct google_protobuf_OneofOptions* sub = (struct google_protobuf_OneofOptions*)google_protobuf_OneofDescriptorProto_options(msg); + if (sub == NULL) { + sub = (struct google_protobuf_OneofOptions*)upb_msg_new(&google_protobuf_OneofOptions_msginit, arena); + if (!sub) return NULL; + google_protobuf_OneofDescriptorProto_set_options(msg, sub); + } + return sub; +} + + +/* google.protobuf.EnumDescriptorProto */ + +UPB_INLINE google_protobuf_EnumDescriptorProto *google_protobuf_EnumDescriptorProto_new(upb_arena *arena) { + return (google_protobuf_EnumDescriptorProto *)upb_msg_new(&google_protobuf_EnumDescriptorProto_msginit, arena); +} +UPB_INLINE google_protobuf_EnumDescriptorProto *google_protobuf_EnumDescriptorProto_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_EnumDescriptorProto *ret = google_protobuf_EnumDescriptorProto_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_EnumDescriptorProto_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_EnumDescriptorProto_serialize(const google_protobuf_EnumDescriptorProto *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_EnumDescriptorProto_msginit, arena, len); +} + +UPB_INLINE bool google_protobuf_EnumDescriptorProto_has_name(const google_protobuf_EnumDescriptorProto *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE upb_strview google_protobuf_EnumDescriptorProto_name(const google_protobuf_EnumDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)); } +UPB_INLINE const google_protobuf_EnumValueDescriptorProto* const* google_protobuf_EnumDescriptorProto_value(const google_protobuf_EnumDescriptorProto *msg, size_t *len) { return (const google_protobuf_EnumValueDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(16, 32), len); } +UPB_INLINE bool google_protobuf_EnumDescriptorProto_has_options(const google_protobuf_EnumDescriptorProto *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE const google_protobuf_EnumOptions* google_protobuf_EnumDescriptorProto_options(const google_protobuf_EnumDescriptorProto *msg) { return UPB_FIELD_AT(msg, const google_protobuf_EnumOptions*, UPB_SIZE(12, 24)); } +UPB_INLINE const google_protobuf_EnumDescriptorProto_EnumReservedRange* const* google_protobuf_EnumDescriptorProto_reserved_range(const google_protobuf_EnumDescriptorProto *msg, size_t *len) { return (const google_protobuf_EnumDescriptorProto_EnumReservedRange* const*)_upb_array_accessor(msg, UPB_SIZE(20, 40), len); } +UPB_INLINE upb_strview const* google_protobuf_EnumDescriptorProto_reserved_name(const google_protobuf_EnumDescriptorProto *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(24, 48), len); } + +UPB_INLINE void google_protobuf_EnumDescriptorProto_set_name(google_protobuf_EnumDescriptorProto *msg, upb_strview value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)) = value; +} +UPB_INLINE google_protobuf_EnumValueDescriptorProto** google_protobuf_EnumDescriptorProto_mutable_value(google_protobuf_EnumDescriptorProto *msg, size_t *len) { + return (google_protobuf_EnumValueDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(16, 32), len); +} +UPB_INLINE google_protobuf_EnumValueDescriptorProto** google_protobuf_EnumDescriptorProto_resize_value(google_protobuf_EnumDescriptorProto *msg, size_t len, upb_arena *arena) { + return (google_protobuf_EnumValueDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(16, 32), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_EnumValueDescriptorProto* google_protobuf_EnumDescriptorProto_add_value(google_protobuf_EnumDescriptorProto *msg, upb_arena *arena) { + struct google_protobuf_EnumValueDescriptorProto* sub = (struct google_protobuf_EnumValueDescriptorProto*)upb_msg_new(&google_protobuf_EnumValueDescriptorProto_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(16, 32), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE void google_protobuf_EnumDescriptorProto_set_options(google_protobuf_EnumDescriptorProto *msg, google_protobuf_EnumOptions* value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, google_protobuf_EnumOptions*, UPB_SIZE(12, 24)) = value; +} +UPB_INLINE struct google_protobuf_EnumOptions* google_protobuf_EnumDescriptorProto_mutable_options(google_protobuf_EnumDescriptorProto *msg, upb_arena *arena) { + struct google_protobuf_EnumOptions* sub = (struct google_protobuf_EnumOptions*)google_protobuf_EnumDescriptorProto_options(msg); + if (sub == NULL) { + sub = (struct google_protobuf_EnumOptions*)upb_msg_new(&google_protobuf_EnumOptions_msginit, arena); + if (!sub) return NULL; + google_protobuf_EnumDescriptorProto_set_options(msg, sub); + } + return sub; +} +UPB_INLINE google_protobuf_EnumDescriptorProto_EnumReservedRange** google_protobuf_EnumDescriptorProto_mutable_reserved_range(google_protobuf_EnumDescriptorProto *msg, size_t *len) { + return (google_protobuf_EnumDescriptorProto_EnumReservedRange**)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 40), len); +} +UPB_INLINE google_protobuf_EnumDescriptorProto_EnumReservedRange** google_protobuf_EnumDescriptorProto_resize_reserved_range(google_protobuf_EnumDescriptorProto *msg, size_t len, upb_arena *arena) { + return (google_protobuf_EnumDescriptorProto_EnumReservedRange**)_upb_array_resize_accessor(msg, UPB_SIZE(20, 40), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_EnumDescriptorProto_EnumReservedRange* google_protobuf_EnumDescriptorProto_add_reserved_range(google_protobuf_EnumDescriptorProto *msg, upb_arena *arena) { + struct google_protobuf_EnumDescriptorProto_EnumReservedRange* sub = (struct google_protobuf_EnumDescriptorProto_EnumReservedRange*)upb_msg_new(&google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(20, 40), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE upb_strview* google_protobuf_EnumDescriptorProto_mutable_reserved_name(google_protobuf_EnumDescriptorProto *msg, size_t *len) { + return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 48), len); +} +UPB_INLINE upb_strview* google_protobuf_EnumDescriptorProto_resize_reserved_name(google_protobuf_EnumDescriptorProto *msg, size_t len, upb_arena *arena) { + return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(24, 48), len, UPB_SIZE(8, 16), UPB_TYPE_STRING, arena); +} +UPB_INLINE bool google_protobuf_EnumDescriptorProto_add_reserved_name(google_protobuf_EnumDescriptorProto *msg, upb_strview val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(24, 48), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, arena); +} + + +/* google.protobuf.EnumDescriptorProto.EnumReservedRange */ + +UPB_INLINE google_protobuf_EnumDescriptorProto_EnumReservedRange *google_protobuf_EnumDescriptorProto_EnumReservedRange_new(upb_arena *arena) { + return (google_protobuf_EnumDescriptorProto_EnumReservedRange *)upb_msg_new(&google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit, arena); +} +UPB_INLINE google_protobuf_EnumDescriptorProto_EnumReservedRange *google_protobuf_EnumDescriptorProto_EnumReservedRange_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_EnumDescriptorProto_EnumReservedRange *ret = google_protobuf_EnumDescriptorProto_EnumReservedRange_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_EnumDescriptorProto_EnumReservedRange_serialize(const google_protobuf_EnumDescriptorProto_EnumReservedRange *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit, arena, len); +} + +UPB_INLINE bool google_protobuf_EnumDescriptorProto_EnumReservedRange_has_start(const google_protobuf_EnumDescriptorProto_EnumReservedRange *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE int32_t google_protobuf_EnumDescriptorProto_EnumReservedRange_start(const google_protobuf_EnumDescriptorProto_EnumReservedRange *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)); } +UPB_INLINE bool google_protobuf_EnumDescriptorProto_EnumReservedRange_has_end(const google_protobuf_EnumDescriptorProto_EnumReservedRange *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE int32_t google_protobuf_EnumDescriptorProto_EnumReservedRange_end(const google_protobuf_EnumDescriptorProto_EnumReservedRange *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); } + +UPB_INLINE void google_protobuf_EnumDescriptorProto_EnumReservedRange_set_start(google_protobuf_EnumDescriptorProto_EnumReservedRange *msg, int32_t value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)) = value; +} +UPB_INLINE void google_protobuf_EnumDescriptorProto_EnumReservedRange_set_end(google_protobuf_EnumDescriptorProto_EnumReservedRange *msg, int32_t value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value; +} + + +/* google.protobuf.EnumValueDescriptorProto */ + +UPB_INLINE google_protobuf_EnumValueDescriptorProto *google_protobuf_EnumValueDescriptorProto_new(upb_arena *arena) { + return (google_protobuf_EnumValueDescriptorProto *)upb_msg_new(&google_protobuf_EnumValueDescriptorProto_msginit, arena); +} +UPB_INLINE google_protobuf_EnumValueDescriptorProto *google_protobuf_EnumValueDescriptorProto_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_EnumValueDescriptorProto *ret = google_protobuf_EnumValueDescriptorProto_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_EnumValueDescriptorProto_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_EnumValueDescriptorProto_serialize(const google_protobuf_EnumValueDescriptorProto *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_EnumValueDescriptorProto_msginit, arena, len); +} + +UPB_INLINE bool google_protobuf_EnumValueDescriptorProto_has_name(const google_protobuf_EnumValueDescriptorProto *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE upb_strview google_protobuf_EnumValueDescriptorProto_name(const google_protobuf_EnumValueDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 8)); } +UPB_INLINE bool google_protobuf_EnumValueDescriptorProto_has_number(const google_protobuf_EnumValueDescriptorProto *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE int32_t google_protobuf_EnumValueDescriptorProto_number(const google_protobuf_EnumValueDescriptorProto *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)); } +UPB_INLINE bool google_protobuf_EnumValueDescriptorProto_has_options(const google_protobuf_EnumValueDescriptorProto *msg) { return _upb_has_field(msg, 3); } +UPB_INLINE const google_protobuf_EnumValueOptions* google_protobuf_EnumValueDescriptorProto_options(const google_protobuf_EnumValueDescriptorProto *msg) { return UPB_FIELD_AT(msg, const google_protobuf_EnumValueOptions*, UPB_SIZE(16, 24)); } + +UPB_INLINE void google_protobuf_EnumValueDescriptorProto_set_name(google_protobuf_EnumValueDescriptorProto *msg, upb_strview value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE void google_protobuf_EnumValueDescriptorProto_set_number(google_protobuf_EnumValueDescriptorProto *msg, int32_t value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)) = value; +} +UPB_INLINE void google_protobuf_EnumValueDescriptorProto_set_options(google_protobuf_EnumValueDescriptorProto *msg, google_protobuf_EnumValueOptions* value) { + _upb_sethas(msg, 3); + UPB_FIELD_AT(msg, google_protobuf_EnumValueOptions*, UPB_SIZE(16, 24)) = value; +} +UPB_INLINE struct google_protobuf_EnumValueOptions* google_protobuf_EnumValueDescriptorProto_mutable_options(google_protobuf_EnumValueDescriptorProto *msg, upb_arena *arena) { + struct google_protobuf_EnumValueOptions* sub = (struct google_protobuf_EnumValueOptions*)google_protobuf_EnumValueDescriptorProto_options(msg); + if (sub == NULL) { + sub = (struct google_protobuf_EnumValueOptions*)upb_msg_new(&google_protobuf_EnumValueOptions_msginit, arena); + if (!sub) return NULL; + google_protobuf_EnumValueDescriptorProto_set_options(msg, sub); + } + return sub; +} + + +/* google.protobuf.ServiceDescriptorProto */ + +UPB_INLINE google_protobuf_ServiceDescriptorProto *google_protobuf_ServiceDescriptorProto_new(upb_arena *arena) { + return (google_protobuf_ServiceDescriptorProto *)upb_msg_new(&google_protobuf_ServiceDescriptorProto_msginit, arena); +} +UPB_INLINE google_protobuf_ServiceDescriptorProto *google_protobuf_ServiceDescriptorProto_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_ServiceDescriptorProto *ret = google_protobuf_ServiceDescriptorProto_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_ServiceDescriptorProto_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_ServiceDescriptorProto_serialize(const google_protobuf_ServiceDescriptorProto *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_ServiceDescriptorProto_msginit, arena, len); +} + +UPB_INLINE bool google_protobuf_ServiceDescriptorProto_has_name(const google_protobuf_ServiceDescriptorProto *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE upb_strview google_protobuf_ServiceDescriptorProto_name(const google_protobuf_ServiceDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)); } +UPB_INLINE const google_protobuf_MethodDescriptorProto* const* google_protobuf_ServiceDescriptorProto_method(const google_protobuf_ServiceDescriptorProto *msg, size_t *len) { return (const google_protobuf_MethodDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(16, 32), len); } +UPB_INLINE bool google_protobuf_ServiceDescriptorProto_has_options(const google_protobuf_ServiceDescriptorProto *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE const google_protobuf_ServiceOptions* google_protobuf_ServiceDescriptorProto_options(const google_protobuf_ServiceDescriptorProto *msg) { return UPB_FIELD_AT(msg, const google_protobuf_ServiceOptions*, UPB_SIZE(12, 24)); } + +UPB_INLINE void google_protobuf_ServiceDescriptorProto_set_name(google_protobuf_ServiceDescriptorProto *msg, upb_strview value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)) = value; +} +UPB_INLINE google_protobuf_MethodDescriptorProto** google_protobuf_ServiceDescriptorProto_mutable_method(google_protobuf_ServiceDescriptorProto *msg, size_t *len) { + return (google_protobuf_MethodDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(16, 32), len); +} +UPB_INLINE google_protobuf_MethodDescriptorProto** google_protobuf_ServiceDescriptorProto_resize_method(google_protobuf_ServiceDescriptorProto *msg, size_t len, upb_arena *arena) { + return (google_protobuf_MethodDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(16, 32), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_MethodDescriptorProto* google_protobuf_ServiceDescriptorProto_add_method(google_protobuf_ServiceDescriptorProto *msg, upb_arena *arena) { + struct google_protobuf_MethodDescriptorProto* sub = (struct google_protobuf_MethodDescriptorProto*)upb_msg_new(&google_protobuf_MethodDescriptorProto_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(16, 32), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE void google_protobuf_ServiceDescriptorProto_set_options(google_protobuf_ServiceDescriptorProto *msg, google_protobuf_ServiceOptions* value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, google_protobuf_ServiceOptions*, UPB_SIZE(12, 24)) = value; +} +UPB_INLINE struct google_protobuf_ServiceOptions* google_protobuf_ServiceDescriptorProto_mutable_options(google_protobuf_ServiceDescriptorProto *msg, upb_arena *arena) { + struct google_protobuf_ServiceOptions* sub = (struct google_protobuf_ServiceOptions*)google_protobuf_ServiceDescriptorProto_options(msg); + if (sub == NULL) { + sub = (struct google_protobuf_ServiceOptions*)upb_msg_new(&google_protobuf_ServiceOptions_msginit, arena); + if (!sub) return NULL; + google_protobuf_ServiceDescriptorProto_set_options(msg, sub); + } + return sub; +} + + +/* google.protobuf.MethodDescriptorProto */ + +UPB_INLINE google_protobuf_MethodDescriptorProto *google_protobuf_MethodDescriptorProto_new(upb_arena *arena) { + return (google_protobuf_MethodDescriptorProto *)upb_msg_new(&google_protobuf_MethodDescriptorProto_msginit, arena); +} +UPB_INLINE google_protobuf_MethodDescriptorProto *google_protobuf_MethodDescriptorProto_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_MethodDescriptorProto *ret = google_protobuf_MethodDescriptorProto_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_MethodDescriptorProto_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_MethodDescriptorProto_serialize(const google_protobuf_MethodDescriptorProto *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_MethodDescriptorProto_msginit, arena, len); +} + +UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_name(const google_protobuf_MethodDescriptorProto *msg) { return _upb_has_field(msg, 3); } +UPB_INLINE upb_strview google_protobuf_MethodDescriptorProto_name(const google_protobuf_MethodDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)); } +UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_input_type(const google_protobuf_MethodDescriptorProto *msg) { return _upb_has_field(msg, 4); } +UPB_INLINE upb_strview google_protobuf_MethodDescriptorProto_input_type(const google_protobuf_MethodDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(12, 24)); } +UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_output_type(const google_protobuf_MethodDescriptorProto *msg) { return _upb_has_field(msg, 5); } +UPB_INLINE upb_strview google_protobuf_MethodDescriptorProto_output_type(const google_protobuf_MethodDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(20, 40)); } +UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_options(const google_protobuf_MethodDescriptorProto *msg) { return _upb_has_field(msg, 6); } +UPB_INLINE const google_protobuf_MethodOptions* google_protobuf_MethodDescriptorProto_options(const google_protobuf_MethodDescriptorProto *msg) { return UPB_FIELD_AT(msg, const google_protobuf_MethodOptions*, UPB_SIZE(28, 56)); } +UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_client_streaming(const google_protobuf_MethodDescriptorProto *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE bool google_protobuf_MethodDescriptorProto_client_streaming(const google_protobuf_MethodDescriptorProto *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)); } +UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_server_streaming(const google_protobuf_MethodDescriptorProto *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE bool google_protobuf_MethodDescriptorProto_server_streaming(const google_protobuf_MethodDescriptorProto *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(2, 2)); } + +UPB_INLINE void google_protobuf_MethodDescriptorProto_set_name(google_protobuf_MethodDescriptorProto *msg, upb_strview value) { + _upb_sethas(msg, 3); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)) = value; +} +UPB_INLINE void google_protobuf_MethodDescriptorProto_set_input_type(google_protobuf_MethodDescriptorProto *msg, upb_strview value) { + _upb_sethas(msg, 4); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(12, 24)) = value; +} +UPB_INLINE void google_protobuf_MethodDescriptorProto_set_output_type(google_protobuf_MethodDescriptorProto *msg, upb_strview value) { + _upb_sethas(msg, 5); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(20, 40)) = value; +} +UPB_INLINE void google_protobuf_MethodDescriptorProto_set_options(google_protobuf_MethodDescriptorProto *msg, google_protobuf_MethodOptions* value) { + _upb_sethas(msg, 6); + UPB_FIELD_AT(msg, google_protobuf_MethodOptions*, UPB_SIZE(28, 56)) = value; +} +UPB_INLINE struct google_protobuf_MethodOptions* google_protobuf_MethodDescriptorProto_mutable_options(google_protobuf_MethodDescriptorProto *msg, upb_arena *arena) { + struct google_protobuf_MethodOptions* sub = (struct google_protobuf_MethodOptions*)google_protobuf_MethodDescriptorProto_options(msg); + if (sub == NULL) { + sub = (struct google_protobuf_MethodOptions*)upb_msg_new(&google_protobuf_MethodOptions_msginit, arena); + if (!sub) return NULL; + google_protobuf_MethodDescriptorProto_set_options(msg, sub); + } + return sub; +} +UPB_INLINE void google_protobuf_MethodDescriptorProto_set_client_streaming(google_protobuf_MethodDescriptorProto *msg, bool value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)) = value; +} +UPB_INLINE void google_protobuf_MethodDescriptorProto_set_server_streaming(google_protobuf_MethodDescriptorProto *msg, bool value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, bool, UPB_SIZE(2, 2)) = value; +} + + +/* google.protobuf.FileOptions */ + +UPB_INLINE google_protobuf_FileOptions *google_protobuf_FileOptions_new(upb_arena *arena) { + return (google_protobuf_FileOptions *)upb_msg_new(&google_protobuf_FileOptions_msginit, arena); +} +UPB_INLINE google_protobuf_FileOptions *google_protobuf_FileOptions_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_FileOptions *ret = google_protobuf_FileOptions_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_FileOptions_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_FileOptions_serialize(const google_protobuf_FileOptions *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_FileOptions_msginit, arena, len); +} + +UPB_INLINE bool google_protobuf_FileOptions_has_java_package(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 11); } +UPB_INLINE upb_strview google_protobuf_FileOptions_java_package(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(28, 32)); } +UPB_INLINE bool google_protobuf_FileOptions_has_java_outer_classname(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 12); } +UPB_INLINE upb_strview google_protobuf_FileOptions_java_outer_classname(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(36, 48)); } +UPB_INLINE bool google_protobuf_FileOptions_has_optimize_for(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE int32_t google_protobuf_FileOptions_optimize_for(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); } +UPB_INLINE bool google_protobuf_FileOptions_has_java_multiple_files(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE bool google_protobuf_FileOptions_java_multiple_files(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(16, 16)); } +UPB_INLINE bool google_protobuf_FileOptions_has_go_package(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 13); } +UPB_INLINE upb_strview google_protobuf_FileOptions_go_package(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(44, 64)); } +UPB_INLINE bool google_protobuf_FileOptions_has_cc_generic_services(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 3); } +UPB_INLINE bool google_protobuf_FileOptions_cc_generic_services(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(17, 17)); } +UPB_INLINE bool google_protobuf_FileOptions_has_java_generic_services(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 4); } +UPB_INLINE bool google_protobuf_FileOptions_java_generic_services(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(18, 18)); } +UPB_INLINE bool google_protobuf_FileOptions_has_py_generic_services(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 5); } +UPB_INLINE bool google_protobuf_FileOptions_py_generic_services(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(19, 19)); } +UPB_INLINE bool google_protobuf_FileOptions_has_java_generate_equals_and_hash(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 6); } +UPB_INLINE bool google_protobuf_FileOptions_java_generate_equals_and_hash(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(20, 20)); } +UPB_INLINE bool google_protobuf_FileOptions_has_deprecated(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 7); } +UPB_INLINE bool google_protobuf_FileOptions_deprecated(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(21, 21)); } +UPB_INLINE bool google_protobuf_FileOptions_has_java_string_check_utf8(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 8); } +UPB_INLINE bool google_protobuf_FileOptions_java_string_check_utf8(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(22, 22)); } +UPB_INLINE bool google_protobuf_FileOptions_has_cc_enable_arenas(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 9); } +UPB_INLINE bool google_protobuf_FileOptions_cc_enable_arenas(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(23, 23)); } +UPB_INLINE bool google_protobuf_FileOptions_has_objc_class_prefix(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 14); } +UPB_INLINE upb_strview google_protobuf_FileOptions_objc_class_prefix(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(52, 80)); } +UPB_INLINE bool google_protobuf_FileOptions_has_csharp_namespace(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 15); } +UPB_INLINE upb_strview google_protobuf_FileOptions_csharp_namespace(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(60, 96)); } +UPB_INLINE bool google_protobuf_FileOptions_has_swift_prefix(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 16); } +UPB_INLINE upb_strview google_protobuf_FileOptions_swift_prefix(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(68, 112)); } +UPB_INLINE bool google_protobuf_FileOptions_has_php_class_prefix(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 17); } +UPB_INLINE upb_strview google_protobuf_FileOptions_php_class_prefix(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(76, 128)); } +UPB_INLINE bool google_protobuf_FileOptions_has_php_namespace(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 18); } +UPB_INLINE upb_strview google_protobuf_FileOptions_php_namespace(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(84, 144)); } +UPB_INLINE bool google_protobuf_FileOptions_has_php_generic_services(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 10); } +UPB_INLINE bool google_protobuf_FileOptions_php_generic_services(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(24, 24)); } +UPB_INLINE bool google_protobuf_FileOptions_has_php_metadata_namespace(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 19); } +UPB_INLINE upb_strview google_protobuf_FileOptions_php_metadata_namespace(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(92, 160)); } +UPB_INLINE bool google_protobuf_FileOptions_has_ruby_package(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 20); } +UPB_INLINE upb_strview google_protobuf_FileOptions_ruby_package(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(100, 176)); } +UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_FileOptions_uninterpreted_option(const google_protobuf_FileOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(108, 192), len); } + +UPB_INLINE void google_protobuf_FileOptions_set_java_package(google_protobuf_FileOptions *msg, upb_strview value) { + _upb_sethas(msg, 11); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(28, 32)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_java_outer_classname(google_protobuf_FileOptions *msg, upb_strview value) { + _upb_sethas(msg, 12); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(36, 48)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_optimize_for(google_protobuf_FileOptions *msg, int32_t value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_java_multiple_files(google_protobuf_FileOptions *msg, bool value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, bool, UPB_SIZE(16, 16)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_go_package(google_protobuf_FileOptions *msg, upb_strview value) { + _upb_sethas(msg, 13); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(44, 64)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_cc_generic_services(google_protobuf_FileOptions *msg, bool value) { + _upb_sethas(msg, 3); + UPB_FIELD_AT(msg, bool, UPB_SIZE(17, 17)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_java_generic_services(google_protobuf_FileOptions *msg, bool value) { + _upb_sethas(msg, 4); + UPB_FIELD_AT(msg, bool, UPB_SIZE(18, 18)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_py_generic_services(google_protobuf_FileOptions *msg, bool value) { + _upb_sethas(msg, 5); + UPB_FIELD_AT(msg, bool, UPB_SIZE(19, 19)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_java_generate_equals_and_hash(google_protobuf_FileOptions *msg, bool value) { + _upb_sethas(msg, 6); + UPB_FIELD_AT(msg, bool, UPB_SIZE(20, 20)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_deprecated(google_protobuf_FileOptions *msg, bool value) { + _upb_sethas(msg, 7); + UPB_FIELD_AT(msg, bool, UPB_SIZE(21, 21)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_java_string_check_utf8(google_protobuf_FileOptions *msg, bool value) { + _upb_sethas(msg, 8); + UPB_FIELD_AT(msg, bool, UPB_SIZE(22, 22)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_cc_enable_arenas(google_protobuf_FileOptions *msg, bool value) { + _upb_sethas(msg, 9); + UPB_FIELD_AT(msg, bool, UPB_SIZE(23, 23)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_objc_class_prefix(google_protobuf_FileOptions *msg, upb_strview value) { + _upb_sethas(msg, 14); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(52, 80)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_csharp_namespace(google_protobuf_FileOptions *msg, upb_strview value) { + _upb_sethas(msg, 15); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(60, 96)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_swift_prefix(google_protobuf_FileOptions *msg, upb_strview value) { + _upb_sethas(msg, 16); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(68, 112)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_php_class_prefix(google_protobuf_FileOptions *msg, upb_strview value) { + _upb_sethas(msg, 17); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(76, 128)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_php_namespace(google_protobuf_FileOptions *msg, upb_strview value) { + _upb_sethas(msg, 18); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(84, 144)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_php_generic_services(google_protobuf_FileOptions *msg, bool value) { + _upb_sethas(msg, 10); + UPB_FIELD_AT(msg, bool, UPB_SIZE(24, 24)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_php_metadata_namespace(google_protobuf_FileOptions *msg, upb_strview value) { + _upb_sethas(msg, 19); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(92, 160)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_ruby_package(google_protobuf_FileOptions *msg, upb_strview value) { + _upb_sethas(msg, 20); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(100, 176)) = value; +} +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_FileOptions_mutable_uninterpreted_option(google_protobuf_FileOptions *msg, size_t *len) { + return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(108, 192), len); +} +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_FileOptions_resize_uninterpreted_option(google_protobuf_FileOptions *msg, size_t len, upb_arena *arena) { + return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(108, 192), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_FileOptions_add_uninterpreted_option(google_protobuf_FileOptions *msg, upb_arena *arena) { + struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(108, 192), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} + + +/* google.protobuf.MessageOptions */ + +UPB_INLINE google_protobuf_MessageOptions *google_protobuf_MessageOptions_new(upb_arena *arena) { + return (google_protobuf_MessageOptions *)upb_msg_new(&google_protobuf_MessageOptions_msginit, arena); +} +UPB_INLINE google_protobuf_MessageOptions *google_protobuf_MessageOptions_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_MessageOptions *ret = google_protobuf_MessageOptions_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_MessageOptions_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_MessageOptions_serialize(const google_protobuf_MessageOptions *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_MessageOptions_msginit, arena, len); +} + +UPB_INLINE bool google_protobuf_MessageOptions_has_message_set_wire_format(const google_protobuf_MessageOptions *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE bool google_protobuf_MessageOptions_message_set_wire_format(const google_protobuf_MessageOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)); } +UPB_INLINE bool google_protobuf_MessageOptions_has_no_standard_descriptor_accessor(const google_protobuf_MessageOptions *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE bool google_protobuf_MessageOptions_no_standard_descriptor_accessor(const google_protobuf_MessageOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(2, 2)); } +UPB_INLINE bool google_protobuf_MessageOptions_has_deprecated(const google_protobuf_MessageOptions *msg) { return _upb_has_field(msg, 3); } +UPB_INLINE bool google_protobuf_MessageOptions_deprecated(const google_protobuf_MessageOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(3, 3)); } +UPB_INLINE bool google_protobuf_MessageOptions_has_map_entry(const google_protobuf_MessageOptions *msg) { return _upb_has_field(msg, 4); } +UPB_INLINE bool google_protobuf_MessageOptions_map_entry(const google_protobuf_MessageOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(4, 4)); } +UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_MessageOptions_uninterpreted_option(const google_protobuf_MessageOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(8, 8), len); } + +UPB_INLINE void google_protobuf_MessageOptions_set_message_set_wire_format(google_protobuf_MessageOptions *msg, bool value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)) = value; +} +UPB_INLINE void google_protobuf_MessageOptions_set_no_standard_descriptor_accessor(google_protobuf_MessageOptions *msg, bool value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, bool, UPB_SIZE(2, 2)) = value; +} +UPB_INLINE void google_protobuf_MessageOptions_set_deprecated(google_protobuf_MessageOptions *msg, bool value) { + _upb_sethas(msg, 3); + UPB_FIELD_AT(msg, bool, UPB_SIZE(3, 3)) = value; +} +UPB_INLINE void google_protobuf_MessageOptions_set_map_entry(google_protobuf_MessageOptions *msg, bool value) { + _upb_sethas(msg, 4); + UPB_FIELD_AT(msg, bool, UPB_SIZE(4, 4)) = value; +} +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_MessageOptions_mutable_uninterpreted_option(google_protobuf_MessageOptions *msg, size_t *len) { + return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(8, 8), len); +} +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_MessageOptions_resize_uninterpreted_option(google_protobuf_MessageOptions *msg, size_t len, upb_arena *arena) { + return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(8, 8), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_MessageOptions_add_uninterpreted_option(google_protobuf_MessageOptions *msg, upb_arena *arena) { + struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(8, 8), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} + + +/* google.protobuf.FieldOptions */ + +UPB_INLINE google_protobuf_FieldOptions *google_protobuf_FieldOptions_new(upb_arena *arena) { + return (google_protobuf_FieldOptions *)upb_msg_new(&google_protobuf_FieldOptions_msginit, arena); +} +UPB_INLINE google_protobuf_FieldOptions *google_protobuf_FieldOptions_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_FieldOptions *ret = google_protobuf_FieldOptions_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_FieldOptions_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_FieldOptions_serialize(const google_protobuf_FieldOptions *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_FieldOptions_msginit, arena, len); +} + +UPB_INLINE bool google_protobuf_FieldOptions_has_ctype(const google_protobuf_FieldOptions *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE int32_t google_protobuf_FieldOptions_ctype(const google_protobuf_FieldOptions *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); } +UPB_INLINE bool google_protobuf_FieldOptions_has_packed(const google_protobuf_FieldOptions *msg) { return _upb_has_field(msg, 3); } +UPB_INLINE bool google_protobuf_FieldOptions_packed(const google_protobuf_FieldOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(24, 24)); } +UPB_INLINE bool google_protobuf_FieldOptions_has_deprecated(const google_protobuf_FieldOptions *msg) { return _upb_has_field(msg, 4); } +UPB_INLINE bool google_protobuf_FieldOptions_deprecated(const google_protobuf_FieldOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(25, 25)); } +UPB_INLINE bool google_protobuf_FieldOptions_has_lazy(const google_protobuf_FieldOptions *msg) { return _upb_has_field(msg, 5); } +UPB_INLINE bool google_protobuf_FieldOptions_lazy(const google_protobuf_FieldOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(26, 26)); } +UPB_INLINE bool google_protobuf_FieldOptions_has_jstype(const google_protobuf_FieldOptions *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE int32_t google_protobuf_FieldOptions_jstype(const google_protobuf_FieldOptions *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(16, 16)); } +UPB_INLINE bool google_protobuf_FieldOptions_has_weak(const google_protobuf_FieldOptions *msg) { return _upb_has_field(msg, 6); } +UPB_INLINE bool google_protobuf_FieldOptions_weak(const google_protobuf_FieldOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(27, 27)); } +UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_FieldOptions_uninterpreted_option(const google_protobuf_FieldOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(28, 32), len); } + +UPB_INLINE void google_protobuf_FieldOptions_set_ctype(google_protobuf_FieldOptions *msg, int32_t value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE void google_protobuf_FieldOptions_set_packed(google_protobuf_FieldOptions *msg, bool value) { + _upb_sethas(msg, 3); + UPB_FIELD_AT(msg, bool, UPB_SIZE(24, 24)) = value; +} +UPB_INLINE void google_protobuf_FieldOptions_set_deprecated(google_protobuf_FieldOptions *msg, bool value) { + _upb_sethas(msg, 4); + UPB_FIELD_AT(msg, bool, UPB_SIZE(25, 25)) = value; +} +UPB_INLINE void google_protobuf_FieldOptions_set_lazy(google_protobuf_FieldOptions *msg, bool value) { + _upb_sethas(msg, 5); + UPB_FIELD_AT(msg, bool, UPB_SIZE(26, 26)) = value; +} +UPB_INLINE void google_protobuf_FieldOptions_set_jstype(google_protobuf_FieldOptions *msg, int32_t value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(16, 16)) = value; +} +UPB_INLINE void google_protobuf_FieldOptions_set_weak(google_protobuf_FieldOptions *msg, bool value) { + _upb_sethas(msg, 6); + UPB_FIELD_AT(msg, bool, UPB_SIZE(27, 27)) = value; +} +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_FieldOptions_mutable_uninterpreted_option(google_protobuf_FieldOptions *msg, size_t *len) { + return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 32), len); +} +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_FieldOptions_resize_uninterpreted_option(google_protobuf_FieldOptions *msg, size_t len, upb_arena *arena) { + return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(28, 32), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_FieldOptions_add_uninterpreted_option(google_protobuf_FieldOptions *msg, upb_arena *arena) { + struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(28, 32), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} + + +/* google.protobuf.OneofOptions */ + +UPB_INLINE google_protobuf_OneofOptions *google_protobuf_OneofOptions_new(upb_arena *arena) { + return (google_protobuf_OneofOptions *)upb_msg_new(&google_protobuf_OneofOptions_msginit, arena); +} +UPB_INLINE google_protobuf_OneofOptions *google_protobuf_OneofOptions_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_OneofOptions *ret = google_protobuf_OneofOptions_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_OneofOptions_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_OneofOptions_serialize(const google_protobuf_OneofOptions *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_OneofOptions_msginit, arena, len); +} + +UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_OneofOptions_uninterpreted_option(const google_protobuf_OneofOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(0, 0), len); } + +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_OneofOptions_mutable_uninterpreted_option(google_protobuf_OneofOptions *msg, size_t *len) { + return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len); +} +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_OneofOptions_resize_uninterpreted_option(google_protobuf_OneofOptions *msg, size_t len, upb_arena *arena) { + return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_OneofOptions_add_uninterpreted_option(google_protobuf_OneofOptions *msg, upb_arena *arena) { + struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} + + +/* google.protobuf.EnumOptions */ + +UPB_INLINE google_protobuf_EnumOptions *google_protobuf_EnumOptions_new(upb_arena *arena) { + return (google_protobuf_EnumOptions *)upb_msg_new(&google_protobuf_EnumOptions_msginit, arena); +} +UPB_INLINE google_protobuf_EnumOptions *google_protobuf_EnumOptions_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_EnumOptions *ret = google_protobuf_EnumOptions_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_EnumOptions_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_EnumOptions_serialize(const google_protobuf_EnumOptions *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_EnumOptions_msginit, arena, len); +} + +UPB_INLINE bool google_protobuf_EnumOptions_has_allow_alias(const google_protobuf_EnumOptions *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE bool google_protobuf_EnumOptions_allow_alias(const google_protobuf_EnumOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)); } +UPB_INLINE bool google_protobuf_EnumOptions_has_deprecated(const google_protobuf_EnumOptions *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE bool google_protobuf_EnumOptions_deprecated(const google_protobuf_EnumOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(2, 2)); } +UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_EnumOptions_uninterpreted_option(const google_protobuf_EnumOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(4, 8), len); } + +UPB_INLINE void google_protobuf_EnumOptions_set_allow_alias(google_protobuf_EnumOptions *msg, bool value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)) = value; +} +UPB_INLINE void google_protobuf_EnumOptions_set_deprecated(google_protobuf_EnumOptions *msg, bool value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, bool, UPB_SIZE(2, 2)) = value; +} +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_EnumOptions_mutable_uninterpreted_option(google_protobuf_EnumOptions *msg, size_t *len) { + return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(4, 8), len); +} +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_EnumOptions_resize_uninterpreted_option(google_protobuf_EnumOptions *msg, size_t len, upb_arena *arena) { + return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(4, 8), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_EnumOptions_add_uninterpreted_option(google_protobuf_EnumOptions *msg, upb_arena *arena) { + struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(4, 8), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} + + +/* google.protobuf.EnumValueOptions */ + +UPB_INLINE google_protobuf_EnumValueOptions *google_protobuf_EnumValueOptions_new(upb_arena *arena) { + return (google_protobuf_EnumValueOptions *)upb_msg_new(&google_protobuf_EnumValueOptions_msginit, arena); +} +UPB_INLINE google_protobuf_EnumValueOptions *google_protobuf_EnumValueOptions_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_EnumValueOptions *ret = google_protobuf_EnumValueOptions_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_EnumValueOptions_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_EnumValueOptions_serialize(const google_protobuf_EnumValueOptions *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_EnumValueOptions_msginit, arena, len); +} + +UPB_INLINE bool google_protobuf_EnumValueOptions_has_deprecated(const google_protobuf_EnumValueOptions *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE bool google_protobuf_EnumValueOptions_deprecated(const google_protobuf_EnumValueOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)); } +UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_EnumValueOptions_uninterpreted_option(const google_protobuf_EnumValueOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(4, 8), len); } + +UPB_INLINE void google_protobuf_EnumValueOptions_set_deprecated(google_protobuf_EnumValueOptions *msg, bool value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)) = value; +} +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_EnumValueOptions_mutable_uninterpreted_option(google_protobuf_EnumValueOptions *msg, size_t *len) { + return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(4, 8), len); +} +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_EnumValueOptions_resize_uninterpreted_option(google_protobuf_EnumValueOptions *msg, size_t len, upb_arena *arena) { + return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(4, 8), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_EnumValueOptions_add_uninterpreted_option(google_protobuf_EnumValueOptions *msg, upb_arena *arena) { + struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(4, 8), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} + + +/* google.protobuf.ServiceOptions */ + +UPB_INLINE google_protobuf_ServiceOptions *google_protobuf_ServiceOptions_new(upb_arena *arena) { + return (google_protobuf_ServiceOptions *)upb_msg_new(&google_protobuf_ServiceOptions_msginit, arena); +} +UPB_INLINE google_protobuf_ServiceOptions *google_protobuf_ServiceOptions_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_ServiceOptions *ret = google_protobuf_ServiceOptions_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_ServiceOptions_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_ServiceOptions_serialize(const google_protobuf_ServiceOptions *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_ServiceOptions_msginit, arena, len); +} + +UPB_INLINE bool google_protobuf_ServiceOptions_has_deprecated(const google_protobuf_ServiceOptions *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE bool google_protobuf_ServiceOptions_deprecated(const google_protobuf_ServiceOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)); } +UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_ServiceOptions_uninterpreted_option(const google_protobuf_ServiceOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(4, 8), len); } + +UPB_INLINE void google_protobuf_ServiceOptions_set_deprecated(google_protobuf_ServiceOptions *msg, bool value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)) = value; +} +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_ServiceOptions_mutable_uninterpreted_option(google_protobuf_ServiceOptions *msg, size_t *len) { + return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(4, 8), len); +} +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_ServiceOptions_resize_uninterpreted_option(google_protobuf_ServiceOptions *msg, size_t len, upb_arena *arena) { + return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(4, 8), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_ServiceOptions_add_uninterpreted_option(google_protobuf_ServiceOptions *msg, upb_arena *arena) { + struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(4, 8), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} + + +/* google.protobuf.MethodOptions */ + +UPB_INLINE google_protobuf_MethodOptions *google_protobuf_MethodOptions_new(upb_arena *arena) { + return (google_protobuf_MethodOptions *)upb_msg_new(&google_protobuf_MethodOptions_msginit, arena); +} +UPB_INLINE google_protobuf_MethodOptions *google_protobuf_MethodOptions_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_MethodOptions *ret = google_protobuf_MethodOptions_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_MethodOptions_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_MethodOptions_serialize(const google_protobuf_MethodOptions *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_MethodOptions_msginit, arena, len); +} + +UPB_INLINE bool google_protobuf_MethodOptions_has_deprecated(const google_protobuf_MethodOptions *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE bool google_protobuf_MethodOptions_deprecated(const google_protobuf_MethodOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(16, 16)); } +UPB_INLINE bool google_protobuf_MethodOptions_has_idempotency_level(const google_protobuf_MethodOptions *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE int32_t google_protobuf_MethodOptions_idempotency_level(const google_protobuf_MethodOptions *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); } +UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_MethodOptions_uninterpreted_option(const google_protobuf_MethodOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(20, 24), len); } + +UPB_INLINE void google_protobuf_MethodOptions_set_deprecated(google_protobuf_MethodOptions *msg, bool value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, bool, UPB_SIZE(16, 16)) = value; +} +UPB_INLINE void google_protobuf_MethodOptions_set_idempotency_level(google_protobuf_MethodOptions *msg, int32_t value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_MethodOptions_mutable_uninterpreted_option(google_protobuf_MethodOptions *msg, size_t *len) { + return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 24), len); +} +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_MethodOptions_resize_uninterpreted_option(google_protobuf_MethodOptions *msg, size_t len, upb_arena *arena) { + return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(20, 24), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_MethodOptions_add_uninterpreted_option(google_protobuf_MethodOptions *msg, upb_arena *arena) { + struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(20, 24), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} + + +/* google.protobuf.UninterpretedOption */ + +UPB_INLINE google_protobuf_UninterpretedOption *google_protobuf_UninterpretedOption_new(upb_arena *arena) { + return (google_protobuf_UninterpretedOption *)upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena); +} +UPB_INLINE google_protobuf_UninterpretedOption *google_protobuf_UninterpretedOption_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_UninterpretedOption *ret = google_protobuf_UninterpretedOption_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_UninterpretedOption_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_UninterpretedOption_serialize(const google_protobuf_UninterpretedOption *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_UninterpretedOption_msginit, arena, len); +} + +UPB_INLINE const google_protobuf_UninterpretedOption_NamePart* const* google_protobuf_UninterpretedOption_name(const google_protobuf_UninterpretedOption *msg, size_t *len) { return (const google_protobuf_UninterpretedOption_NamePart* const*)_upb_array_accessor(msg, UPB_SIZE(56, 80), len); } +UPB_INLINE bool google_protobuf_UninterpretedOption_has_identifier_value(const google_protobuf_UninterpretedOption *msg) { return _upb_has_field(msg, 4); } +UPB_INLINE upb_strview google_protobuf_UninterpretedOption_identifier_value(const google_protobuf_UninterpretedOption *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(32, 32)); } +UPB_INLINE bool google_protobuf_UninterpretedOption_has_positive_int_value(const google_protobuf_UninterpretedOption *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE uint64_t google_protobuf_UninterpretedOption_positive_int_value(const google_protobuf_UninterpretedOption *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(8, 8)); } +UPB_INLINE bool google_protobuf_UninterpretedOption_has_negative_int_value(const google_protobuf_UninterpretedOption *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE int64_t google_protobuf_UninterpretedOption_negative_int_value(const google_protobuf_UninterpretedOption *msg) { return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(16, 16)); } +UPB_INLINE bool google_protobuf_UninterpretedOption_has_double_value(const google_protobuf_UninterpretedOption *msg) { return _upb_has_field(msg, 3); } +UPB_INLINE double google_protobuf_UninterpretedOption_double_value(const google_protobuf_UninterpretedOption *msg) { return UPB_FIELD_AT(msg, double, UPB_SIZE(24, 24)); } +UPB_INLINE bool google_protobuf_UninterpretedOption_has_string_value(const google_protobuf_UninterpretedOption *msg) { return _upb_has_field(msg, 5); } +UPB_INLINE upb_strview google_protobuf_UninterpretedOption_string_value(const google_protobuf_UninterpretedOption *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(40, 48)); } +UPB_INLINE bool google_protobuf_UninterpretedOption_has_aggregate_value(const google_protobuf_UninterpretedOption *msg) { return _upb_has_field(msg, 6); } +UPB_INLINE upb_strview google_protobuf_UninterpretedOption_aggregate_value(const google_protobuf_UninterpretedOption *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(48, 64)); } + +UPB_INLINE google_protobuf_UninterpretedOption_NamePart** google_protobuf_UninterpretedOption_mutable_name(google_protobuf_UninterpretedOption *msg, size_t *len) { + return (google_protobuf_UninterpretedOption_NamePart**)_upb_array_mutable_accessor(msg, UPB_SIZE(56, 80), len); +} +UPB_INLINE google_protobuf_UninterpretedOption_NamePart** google_protobuf_UninterpretedOption_resize_name(google_protobuf_UninterpretedOption *msg, size_t len, upb_arena *arena) { + return (google_protobuf_UninterpretedOption_NamePart**)_upb_array_resize_accessor(msg, UPB_SIZE(56, 80), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_UninterpretedOption_NamePart* google_protobuf_UninterpretedOption_add_name(google_protobuf_UninterpretedOption *msg, upb_arena *arena) { + struct google_protobuf_UninterpretedOption_NamePart* sub = (struct google_protobuf_UninterpretedOption_NamePart*)upb_msg_new(&google_protobuf_UninterpretedOption_NamePart_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(56, 80), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE void google_protobuf_UninterpretedOption_set_identifier_value(google_protobuf_UninterpretedOption *msg, upb_strview value) { + _upb_sethas(msg, 4); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(32, 32)) = value; +} +UPB_INLINE void google_protobuf_UninterpretedOption_set_positive_int_value(google_protobuf_UninterpretedOption *msg, uint64_t value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE void google_protobuf_UninterpretedOption_set_negative_int_value(google_protobuf_UninterpretedOption *msg, int64_t value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, int64_t, UPB_SIZE(16, 16)) = value; +} +UPB_INLINE void google_protobuf_UninterpretedOption_set_double_value(google_protobuf_UninterpretedOption *msg, double value) { + _upb_sethas(msg, 3); + UPB_FIELD_AT(msg, double, UPB_SIZE(24, 24)) = value; +} +UPB_INLINE void google_protobuf_UninterpretedOption_set_string_value(google_protobuf_UninterpretedOption *msg, upb_strview value) { + _upb_sethas(msg, 5); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(40, 48)) = value; +} +UPB_INLINE void google_protobuf_UninterpretedOption_set_aggregate_value(google_protobuf_UninterpretedOption *msg, upb_strview value) { + _upb_sethas(msg, 6); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(48, 64)) = value; +} + + +/* google.protobuf.UninterpretedOption.NamePart */ + +UPB_INLINE google_protobuf_UninterpretedOption_NamePart *google_protobuf_UninterpretedOption_NamePart_new(upb_arena *arena) { + return (google_protobuf_UninterpretedOption_NamePart *)upb_msg_new(&google_protobuf_UninterpretedOption_NamePart_msginit, arena); +} +UPB_INLINE google_protobuf_UninterpretedOption_NamePart *google_protobuf_UninterpretedOption_NamePart_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_UninterpretedOption_NamePart *ret = google_protobuf_UninterpretedOption_NamePart_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_UninterpretedOption_NamePart_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_UninterpretedOption_NamePart_serialize(const google_protobuf_UninterpretedOption_NamePart *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_UninterpretedOption_NamePart_msginit, arena, len); +} + +UPB_INLINE bool google_protobuf_UninterpretedOption_NamePart_has_name_part(const google_protobuf_UninterpretedOption_NamePart *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE upb_strview google_protobuf_UninterpretedOption_NamePart_name_part(const google_protobuf_UninterpretedOption_NamePart *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)); } +UPB_INLINE bool google_protobuf_UninterpretedOption_NamePart_has_is_extension(const google_protobuf_UninterpretedOption_NamePart *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE bool google_protobuf_UninterpretedOption_NamePart_is_extension(const google_protobuf_UninterpretedOption_NamePart *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)); } + +UPB_INLINE void google_protobuf_UninterpretedOption_NamePart_set_name_part(google_protobuf_UninterpretedOption_NamePart *msg, upb_strview value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)) = value; +} +UPB_INLINE void google_protobuf_UninterpretedOption_NamePart_set_is_extension(google_protobuf_UninterpretedOption_NamePart *msg, bool value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)) = value; +} + + +/* google.protobuf.SourceCodeInfo */ + +UPB_INLINE google_protobuf_SourceCodeInfo *google_protobuf_SourceCodeInfo_new(upb_arena *arena) { + return (google_protobuf_SourceCodeInfo *)upb_msg_new(&google_protobuf_SourceCodeInfo_msginit, arena); +} +UPB_INLINE google_protobuf_SourceCodeInfo *google_protobuf_SourceCodeInfo_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_SourceCodeInfo *ret = google_protobuf_SourceCodeInfo_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_SourceCodeInfo_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_SourceCodeInfo_serialize(const google_protobuf_SourceCodeInfo *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_SourceCodeInfo_msginit, arena, len); +} + +UPB_INLINE const google_protobuf_SourceCodeInfo_Location* const* google_protobuf_SourceCodeInfo_location(const google_protobuf_SourceCodeInfo *msg, size_t *len) { return (const google_protobuf_SourceCodeInfo_Location* const*)_upb_array_accessor(msg, UPB_SIZE(0, 0), len); } + +UPB_INLINE google_protobuf_SourceCodeInfo_Location** google_protobuf_SourceCodeInfo_mutable_location(google_protobuf_SourceCodeInfo *msg, size_t *len) { + return (google_protobuf_SourceCodeInfo_Location**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len); +} +UPB_INLINE google_protobuf_SourceCodeInfo_Location** google_protobuf_SourceCodeInfo_resize_location(google_protobuf_SourceCodeInfo *msg, size_t len, upb_arena *arena) { + return (google_protobuf_SourceCodeInfo_Location**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_SourceCodeInfo_Location* google_protobuf_SourceCodeInfo_add_location(google_protobuf_SourceCodeInfo *msg, upb_arena *arena) { + struct google_protobuf_SourceCodeInfo_Location* sub = (struct google_protobuf_SourceCodeInfo_Location*)upb_msg_new(&google_protobuf_SourceCodeInfo_Location_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} + + +/* google.protobuf.SourceCodeInfo.Location */ + +UPB_INLINE google_protobuf_SourceCodeInfo_Location *google_protobuf_SourceCodeInfo_Location_new(upb_arena *arena) { + return (google_protobuf_SourceCodeInfo_Location *)upb_msg_new(&google_protobuf_SourceCodeInfo_Location_msginit, arena); +} +UPB_INLINE google_protobuf_SourceCodeInfo_Location *google_protobuf_SourceCodeInfo_Location_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_SourceCodeInfo_Location *ret = google_protobuf_SourceCodeInfo_Location_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_SourceCodeInfo_Location_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_SourceCodeInfo_Location_serialize(const google_protobuf_SourceCodeInfo_Location *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_SourceCodeInfo_Location_msginit, arena, len); +} + +UPB_INLINE int32_t const* google_protobuf_SourceCodeInfo_Location_path(const google_protobuf_SourceCodeInfo_Location *msg, size_t *len) { return (int32_t const*)_upb_array_accessor(msg, UPB_SIZE(20, 40), len); } +UPB_INLINE int32_t const* google_protobuf_SourceCodeInfo_Location_span(const google_protobuf_SourceCodeInfo_Location *msg, size_t *len) { return (int32_t const*)_upb_array_accessor(msg, UPB_SIZE(24, 48), len); } +UPB_INLINE bool google_protobuf_SourceCodeInfo_Location_has_leading_comments(const google_protobuf_SourceCodeInfo_Location *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE upb_strview google_protobuf_SourceCodeInfo_Location_leading_comments(const google_protobuf_SourceCodeInfo_Location *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)); } +UPB_INLINE bool google_protobuf_SourceCodeInfo_Location_has_trailing_comments(const google_protobuf_SourceCodeInfo_Location *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE upb_strview google_protobuf_SourceCodeInfo_Location_trailing_comments(const google_protobuf_SourceCodeInfo_Location *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(12, 24)); } +UPB_INLINE upb_strview const* google_protobuf_SourceCodeInfo_Location_leading_detached_comments(const google_protobuf_SourceCodeInfo_Location *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(28, 56), len); } + +UPB_INLINE int32_t* google_protobuf_SourceCodeInfo_Location_mutable_path(google_protobuf_SourceCodeInfo_Location *msg, size_t *len) { + return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 40), len); +} +UPB_INLINE int32_t* google_protobuf_SourceCodeInfo_Location_resize_path(google_protobuf_SourceCodeInfo_Location *msg, size_t len, upb_arena *arena) { + return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(20, 40), len, UPB_SIZE(4, 4), UPB_TYPE_INT32, arena); +} +UPB_INLINE bool google_protobuf_SourceCodeInfo_Location_add_path(google_protobuf_SourceCodeInfo_Location *msg, int32_t val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(20, 40), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val, arena); +} +UPB_INLINE int32_t* google_protobuf_SourceCodeInfo_Location_mutable_span(google_protobuf_SourceCodeInfo_Location *msg, size_t *len) { + return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 48), len); +} +UPB_INLINE int32_t* google_protobuf_SourceCodeInfo_Location_resize_span(google_protobuf_SourceCodeInfo_Location *msg, size_t len, upb_arena *arena) { + return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(24, 48), len, UPB_SIZE(4, 4), UPB_TYPE_INT32, arena); +} +UPB_INLINE bool google_protobuf_SourceCodeInfo_Location_add_span(google_protobuf_SourceCodeInfo_Location *msg, int32_t val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(24, 48), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val, arena); +} +UPB_INLINE void google_protobuf_SourceCodeInfo_Location_set_leading_comments(google_protobuf_SourceCodeInfo_Location *msg, upb_strview value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)) = value; +} +UPB_INLINE void google_protobuf_SourceCodeInfo_Location_set_trailing_comments(google_protobuf_SourceCodeInfo_Location *msg, upb_strview value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(12, 24)) = value; +} +UPB_INLINE upb_strview* google_protobuf_SourceCodeInfo_Location_mutable_leading_detached_comments(google_protobuf_SourceCodeInfo_Location *msg, size_t *len) { + return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 56), len); +} +UPB_INLINE upb_strview* google_protobuf_SourceCodeInfo_Location_resize_leading_detached_comments(google_protobuf_SourceCodeInfo_Location *msg, size_t len, upb_arena *arena) { + return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(28, 56), len, UPB_SIZE(8, 16), UPB_TYPE_STRING, arena); +} +UPB_INLINE bool google_protobuf_SourceCodeInfo_Location_add_leading_detached_comments(google_protobuf_SourceCodeInfo_Location *msg, upb_strview val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(28, 56), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, arena); +} + + +/* google.protobuf.GeneratedCodeInfo */ + +UPB_INLINE google_protobuf_GeneratedCodeInfo *google_protobuf_GeneratedCodeInfo_new(upb_arena *arena) { + return (google_protobuf_GeneratedCodeInfo *)upb_msg_new(&google_protobuf_GeneratedCodeInfo_msginit, arena); +} +UPB_INLINE google_protobuf_GeneratedCodeInfo *google_protobuf_GeneratedCodeInfo_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_GeneratedCodeInfo *ret = google_protobuf_GeneratedCodeInfo_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_GeneratedCodeInfo_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_GeneratedCodeInfo_serialize(const google_protobuf_GeneratedCodeInfo *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_GeneratedCodeInfo_msginit, arena, len); +} + +UPB_INLINE const google_protobuf_GeneratedCodeInfo_Annotation* const* google_protobuf_GeneratedCodeInfo_annotation(const google_protobuf_GeneratedCodeInfo *msg, size_t *len) { return (const google_protobuf_GeneratedCodeInfo_Annotation* const*)_upb_array_accessor(msg, UPB_SIZE(0, 0), len); } + +UPB_INLINE google_protobuf_GeneratedCodeInfo_Annotation** google_protobuf_GeneratedCodeInfo_mutable_annotation(google_protobuf_GeneratedCodeInfo *msg, size_t *len) { + return (google_protobuf_GeneratedCodeInfo_Annotation**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len); +} +UPB_INLINE google_protobuf_GeneratedCodeInfo_Annotation** google_protobuf_GeneratedCodeInfo_resize_annotation(google_protobuf_GeneratedCodeInfo *msg, size_t len, upb_arena *arena) { + return (google_protobuf_GeneratedCodeInfo_Annotation**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_GeneratedCodeInfo_Annotation* google_protobuf_GeneratedCodeInfo_add_annotation(google_protobuf_GeneratedCodeInfo *msg, upb_arena *arena) { + struct google_protobuf_GeneratedCodeInfo_Annotation* sub = (struct google_protobuf_GeneratedCodeInfo_Annotation*)upb_msg_new(&google_protobuf_GeneratedCodeInfo_Annotation_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} + + +/* google.protobuf.GeneratedCodeInfo.Annotation */ + +UPB_INLINE google_protobuf_GeneratedCodeInfo_Annotation *google_protobuf_GeneratedCodeInfo_Annotation_new(upb_arena *arena) { + return (google_protobuf_GeneratedCodeInfo_Annotation *)upb_msg_new(&google_protobuf_GeneratedCodeInfo_Annotation_msginit, arena); +} +UPB_INLINE google_protobuf_GeneratedCodeInfo_Annotation *google_protobuf_GeneratedCodeInfo_Annotation_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_GeneratedCodeInfo_Annotation *ret = google_protobuf_GeneratedCodeInfo_Annotation_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_GeneratedCodeInfo_Annotation_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_GeneratedCodeInfo_Annotation_serialize(const google_protobuf_GeneratedCodeInfo_Annotation *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_GeneratedCodeInfo_Annotation_msginit, arena, len); +} + +UPB_INLINE int32_t const* google_protobuf_GeneratedCodeInfo_Annotation_path(const google_protobuf_GeneratedCodeInfo_Annotation *msg, size_t *len) { return (int32_t const*)_upb_array_accessor(msg, UPB_SIZE(20, 32), len); } +UPB_INLINE bool google_protobuf_GeneratedCodeInfo_Annotation_has_source_file(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return _upb_has_field(msg, 3); } +UPB_INLINE upb_strview google_protobuf_GeneratedCodeInfo_Annotation_source_file(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(12, 16)); } +UPB_INLINE bool google_protobuf_GeneratedCodeInfo_Annotation_has_begin(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE int32_t google_protobuf_GeneratedCodeInfo_Annotation_begin(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)); } +UPB_INLINE bool google_protobuf_GeneratedCodeInfo_Annotation_has_end(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE int32_t google_protobuf_GeneratedCodeInfo_Annotation_end(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); } + +UPB_INLINE int32_t* google_protobuf_GeneratedCodeInfo_Annotation_mutable_path(google_protobuf_GeneratedCodeInfo_Annotation *msg, size_t *len) { + return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 32), len); +} +UPB_INLINE int32_t* google_protobuf_GeneratedCodeInfo_Annotation_resize_path(google_protobuf_GeneratedCodeInfo_Annotation *msg, size_t len, upb_arena *arena) { + return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(20, 32), len, UPB_SIZE(4, 4), UPB_TYPE_INT32, arena); +} +UPB_INLINE bool google_protobuf_GeneratedCodeInfo_Annotation_add_path(google_protobuf_GeneratedCodeInfo_Annotation *msg, int32_t val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(20, 32), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val, arena); +} +UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_set_source_file(google_protobuf_GeneratedCodeInfo_Annotation *msg, upb_strview value) { + _upb_sethas(msg, 3); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(12, 16)) = value; +} +UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_set_begin(google_protobuf_GeneratedCodeInfo_Annotation *msg, int32_t value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)) = value; +} +UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_set_end(google_protobuf_GeneratedCodeInfo_Annotation *msg, int32_t value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value; +} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* GOOGLE_PROTOBUF_DESCRIPTOR_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/google/protobuf/duration.upb.c b/src/core/ext/upb-generated/google/protobuf/duration.upb.c new file mode 100644 index 00000000000..7384c06cf27 --- /dev/null +++ b/src/core/ext/upb-generated/google/protobuf/duration.upb.c @@ -0,0 +1,27 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * google/protobuf/duration.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include +#include "upb/msg.h" +#include "google/protobuf/duration.upb.h" + +#include "upb/port_def.inc" + +static const upb_msglayout_field google_protobuf_Duration__fields[2] = { + {1, UPB_SIZE(0, 0), 0, 0, 3, 1}, + {2, UPB_SIZE(8, 8), 0, 0, 5, 1}, +}; + +const upb_msglayout google_protobuf_Duration_msginit = { + NULL, + &google_protobuf_Duration__fields[0], + UPB_SIZE(16, 16), 2, false, +}; + +#include "upb/port_undef.inc" + diff --git a/src/core/ext/upb-generated/google/protobuf/duration.upb.h b/src/core/ext/upb-generated/google/protobuf/duration.upb.h new file mode 100644 index 00000000000..bb116dcc89a --- /dev/null +++ b/src/core/ext/upb-generated/google/protobuf/duration.upb.h @@ -0,0 +1,60 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * google/protobuf/duration.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef GOOGLE_PROTOBUF_DURATION_PROTO_UPB_H_ +#define GOOGLE_PROTOBUF_DURATION_PROTO_UPB_H_ + +#include "upb/generated_util.h" + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +#ifdef __cplusplus +extern "C" { +#endif + +struct google_protobuf_Duration; +typedef struct google_protobuf_Duration google_protobuf_Duration; +extern const upb_msglayout google_protobuf_Duration_msginit; + +/* Enums */ + + +/* google.protobuf.Duration */ + +UPB_INLINE google_protobuf_Duration *google_protobuf_Duration_new(upb_arena *arena) { + return (google_protobuf_Duration *)upb_msg_new(&google_protobuf_Duration_msginit, arena); +} +UPB_INLINE google_protobuf_Duration *google_protobuf_Duration_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_Duration *ret = google_protobuf_Duration_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_Duration_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_Duration_serialize(const google_protobuf_Duration *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_Duration_msginit, arena, len); +} + +UPB_INLINE int64_t google_protobuf_Duration_seconds(const google_protobuf_Duration *msg) { return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(0, 0)); } +UPB_INLINE int32_t google_protobuf_Duration_nanos(const google_protobuf_Duration *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); } + +UPB_INLINE void google_protobuf_Duration_set_seconds(google_protobuf_Duration *msg, int64_t value) { + UPB_FIELD_AT(msg, int64_t, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void google_protobuf_Duration_set_nanos(google_protobuf_Duration *msg, int32_t value) { + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value; +} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* GOOGLE_PROTOBUF_DURATION_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/google/protobuf/empty.upb.c b/src/core/ext/upb-generated/google/protobuf/empty.upb.c new file mode 100644 index 00000000000..51ac7ed26c3 --- /dev/null +++ b/src/core/ext/upb-generated/google/protobuf/empty.upb.c @@ -0,0 +1,22 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * google/protobuf/empty.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include +#include "upb/msg.h" +#include "google/protobuf/empty.upb.h" + +#include "upb/port_def.inc" + +const upb_msglayout google_protobuf_Empty_msginit = { + NULL, + NULL, + UPB_SIZE(0, 0), 0, false, +}; + +#include "upb/port_undef.inc" + diff --git a/src/core/ext/upb-generated/google/protobuf/empty.upb.h b/src/core/ext/upb-generated/google/protobuf/empty.upb.h new file mode 100644 index 00000000000..43b2edd8cc0 --- /dev/null +++ b/src/core/ext/upb-generated/google/protobuf/empty.upb.h @@ -0,0 +1,52 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * google/protobuf/empty.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef GOOGLE_PROTOBUF_EMPTY_PROTO_UPB_H_ +#define GOOGLE_PROTOBUF_EMPTY_PROTO_UPB_H_ + +#include "upb/generated_util.h" + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +#ifdef __cplusplus +extern "C" { +#endif + +struct google_protobuf_Empty; +typedef struct google_protobuf_Empty google_protobuf_Empty; +extern const upb_msglayout google_protobuf_Empty_msginit; + +/* Enums */ + + +/* google.protobuf.Empty */ + +UPB_INLINE google_protobuf_Empty *google_protobuf_Empty_new(upb_arena *arena) { + return (google_protobuf_Empty *)upb_msg_new(&google_protobuf_Empty_msginit, arena); +} +UPB_INLINE google_protobuf_Empty *google_protobuf_Empty_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_Empty *ret = google_protobuf_Empty_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_Empty_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_Empty_serialize(const google_protobuf_Empty *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_Empty_msginit, arena, len); +} + + + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* GOOGLE_PROTOBUF_EMPTY_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/google/protobuf/struct.upb.c b/src/core/ext/upb-generated/google/protobuf/struct.upb.c new file mode 100644 index 00000000000..5c199fc5771 --- /dev/null +++ b/src/core/ext/upb-generated/google/protobuf/struct.upb.c @@ -0,0 +1,79 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * google/protobuf/struct.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include +#include "upb/msg.h" +#include "google/protobuf/struct.upb.h" + +#include "upb/port_def.inc" + +static const upb_msglayout *const google_protobuf_Struct_submsgs[1] = { + &google_protobuf_Struct_FieldsEntry_msginit, +}; + +static const upb_msglayout_field google_protobuf_Struct__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 11, 3}, +}; + +const upb_msglayout google_protobuf_Struct_msginit = { + &google_protobuf_Struct_submsgs[0], + &google_protobuf_Struct__fields[0], + UPB_SIZE(4, 8), 1, false, +}; + +static const upb_msglayout *const google_protobuf_Struct_FieldsEntry_submsgs[1] = { + &google_protobuf_Value_msginit, +}; + +static const upb_msglayout_field google_protobuf_Struct_FieldsEntry__fields[2] = { + {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, + {2, UPB_SIZE(8, 16), 0, 0, 11, 1}, +}; + +const upb_msglayout google_protobuf_Struct_FieldsEntry_msginit = { + &google_protobuf_Struct_FieldsEntry_submsgs[0], + &google_protobuf_Struct_FieldsEntry__fields[0], + UPB_SIZE(16, 32), 2, false, +}; + +static const upb_msglayout *const google_protobuf_Value_submsgs[2] = { + &google_protobuf_ListValue_msginit, + &google_protobuf_Struct_msginit, +}; + +static const upb_msglayout_field google_protobuf_Value__fields[6] = { + {1, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 0, 14, 1}, + {2, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 0, 1, 1}, + {3, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 0, 9, 1}, + {4, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 0, 8, 1}, + {5, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 1, 11, 1}, + {6, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 0, 11, 1}, +}; + +const upb_msglayout google_protobuf_Value_msginit = { + &google_protobuf_Value_submsgs[0], + &google_protobuf_Value__fields[0], + UPB_SIZE(16, 32), 6, false, +}; + +static const upb_msglayout *const google_protobuf_ListValue_submsgs[1] = { + &google_protobuf_Value_msginit, +}; + +static const upb_msglayout_field google_protobuf_ListValue__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 11, 3}, +}; + +const upb_msglayout google_protobuf_ListValue_msginit = { + &google_protobuf_ListValue_submsgs[0], + &google_protobuf_ListValue__fields[0], + UPB_SIZE(4, 8), 1, false, +}; + +#include "upb/port_undef.inc" + diff --git a/src/core/ext/upb-generated/google/protobuf/struct.upb.h b/src/core/ext/upb-generated/google/protobuf/struct.upb.h new file mode 100644 index 00000000000..da5da203457 --- /dev/null +++ b/src/core/ext/upb-generated/google/protobuf/struct.upb.h @@ -0,0 +1,217 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * google/protobuf/struct.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef GOOGLE_PROTOBUF_STRUCT_PROTO_UPB_H_ +#define GOOGLE_PROTOBUF_STRUCT_PROTO_UPB_H_ + +#include "upb/generated_util.h" + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +#ifdef __cplusplus +extern "C" { +#endif + +struct google_protobuf_Struct; +struct google_protobuf_Struct_FieldsEntry; +struct google_protobuf_Value; +struct google_protobuf_ListValue; +typedef struct google_protobuf_Struct google_protobuf_Struct; +typedef struct google_protobuf_Struct_FieldsEntry google_protobuf_Struct_FieldsEntry; +typedef struct google_protobuf_Value google_protobuf_Value; +typedef struct google_protobuf_ListValue google_protobuf_ListValue; +extern const upb_msglayout google_protobuf_Struct_msginit; +extern const upb_msglayout google_protobuf_Struct_FieldsEntry_msginit; +extern const upb_msglayout google_protobuf_Value_msginit; +extern const upb_msglayout google_protobuf_ListValue_msginit; + +/* Enums */ + +typedef enum { + google_protobuf_NULL_VALUE = 0 +} google_protobuf_NullValue; + + +/* google.protobuf.Struct */ + +UPB_INLINE google_protobuf_Struct *google_protobuf_Struct_new(upb_arena *arena) { + return (google_protobuf_Struct *)upb_msg_new(&google_protobuf_Struct_msginit, arena); +} +UPB_INLINE google_protobuf_Struct *google_protobuf_Struct_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_Struct *ret = google_protobuf_Struct_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_Struct_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_Struct_serialize(const google_protobuf_Struct *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_Struct_msginit, arena, len); +} + +UPB_INLINE const google_protobuf_Struct_FieldsEntry* const* google_protobuf_Struct_fields(const google_protobuf_Struct *msg, size_t *len) { return (const google_protobuf_Struct_FieldsEntry* const*)_upb_array_accessor(msg, UPB_SIZE(0, 0), len); } + +UPB_INLINE google_protobuf_Struct_FieldsEntry** google_protobuf_Struct_mutable_fields(google_protobuf_Struct *msg, size_t *len) { + return (google_protobuf_Struct_FieldsEntry**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len); +} +UPB_INLINE google_protobuf_Struct_FieldsEntry** google_protobuf_Struct_resize_fields(google_protobuf_Struct *msg, size_t len, upb_arena *arena) { + return (google_protobuf_Struct_FieldsEntry**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_Struct_FieldsEntry* google_protobuf_Struct_add_fields(google_protobuf_Struct *msg, upb_arena *arena) { + struct google_protobuf_Struct_FieldsEntry* sub = (struct google_protobuf_Struct_FieldsEntry*)upb_msg_new(&google_protobuf_Struct_FieldsEntry_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} + + +/* google.protobuf.Struct.FieldsEntry */ + +UPB_INLINE google_protobuf_Struct_FieldsEntry *google_protobuf_Struct_FieldsEntry_new(upb_arena *arena) { + return (google_protobuf_Struct_FieldsEntry *)upb_msg_new(&google_protobuf_Struct_FieldsEntry_msginit, arena); +} +UPB_INLINE google_protobuf_Struct_FieldsEntry *google_protobuf_Struct_FieldsEntry_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_Struct_FieldsEntry *ret = google_protobuf_Struct_FieldsEntry_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_Struct_FieldsEntry_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_Struct_FieldsEntry_serialize(const google_protobuf_Struct_FieldsEntry *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_Struct_FieldsEntry_msginit, arena, len); +} + +UPB_INLINE upb_strview google_protobuf_Struct_FieldsEntry_key(const google_protobuf_Struct_FieldsEntry *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } +UPB_INLINE const google_protobuf_Value* google_protobuf_Struct_FieldsEntry_value(const google_protobuf_Struct_FieldsEntry *msg) { return UPB_FIELD_AT(msg, const google_protobuf_Value*, UPB_SIZE(8, 16)); } + +UPB_INLINE void google_protobuf_Struct_FieldsEntry_set_key(google_protobuf_Struct_FieldsEntry *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void google_protobuf_Struct_FieldsEntry_set_value(google_protobuf_Struct_FieldsEntry *msg, google_protobuf_Value* value) { + UPB_FIELD_AT(msg, google_protobuf_Value*, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE struct google_protobuf_Value* google_protobuf_Struct_FieldsEntry_mutable_value(google_protobuf_Struct_FieldsEntry *msg, upb_arena *arena) { + struct google_protobuf_Value* sub = (struct google_protobuf_Value*)google_protobuf_Struct_FieldsEntry_value(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Value*)upb_msg_new(&google_protobuf_Value_msginit, arena); + if (!sub) return NULL; + google_protobuf_Struct_FieldsEntry_set_value(msg, sub); + } + return sub; +} + + +/* google.protobuf.Value */ + +UPB_INLINE google_protobuf_Value *google_protobuf_Value_new(upb_arena *arena) { + return (google_protobuf_Value *)upb_msg_new(&google_protobuf_Value_msginit, arena); +} +UPB_INLINE google_protobuf_Value *google_protobuf_Value_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_Value *ret = google_protobuf_Value_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_Value_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_Value_serialize(const google_protobuf_Value *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_Value_msginit, arena, len); +} + +typedef enum { + google_protobuf_Value_kind_null_value = 1, + google_protobuf_Value_kind_number_value = 2, + google_protobuf_Value_kind_string_value = 3, + google_protobuf_Value_kind_bool_value = 4, + google_protobuf_Value_kind_struct_value = 5, + google_protobuf_Value_kind_list_value = 6, + google_protobuf_Value_kind_NOT_SET = 0, +} google_protobuf_Value_kind_oneofcases; +UPB_INLINE google_protobuf_Value_kind_oneofcases google_protobuf_Value_kind_case(const google_protobuf_Value* msg) { return UPB_FIELD_AT(msg, int, UPB_SIZE(8, 16)); } + +UPB_INLINE bool google_protobuf_Value_has_null_value(const google_protobuf_Value *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(8, 16), 1); } +UPB_INLINE int32_t google_protobuf_Value_null_value(const google_protobuf_Value *msg) { return UPB_READ_ONEOF(msg, int32_t, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 1, google_protobuf_NULL_VALUE); } +UPB_INLINE bool google_protobuf_Value_has_number_value(const google_protobuf_Value *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(8, 16), 2); } +UPB_INLINE double google_protobuf_Value_number_value(const google_protobuf_Value *msg) { return UPB_READ_ONEOF(msg, double, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 2, 0); } +UPB_INLINE bool google_protobuf_Value_has_string_value(const google_protobuf_Value *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(8, 16), 3); } +UPB_INLINE upb_strview google_protobuf_Value_string_value(const google_protobuf_Value *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 3, upb_strview_make("", strlen(""))); } +UPB_INLINE bool google_protobuf_Value_has_bool_value(const google_protobuf_Value *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(8, 16), 4); } +UPB_INLINE bool google_protobuf_Value_bool_value(const google_protobuf_Value *msg) { return UPB_READ_ONEOF(msg, bool, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 4, false); } +UPB_INLINE bool google_protobuf_Value_has_struct_value(const google_protobuf_Value *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(8, 16), 5); } +UPB_INLINE const google_protobuf_Struct* google_protobuf_Value_struct_value(const google_protobuf_Value *msg) { return UPB_READ_ONEOF(msg, const google_protobuf_Struct*, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 5, NULL); } +UPB_INLINE bool google_protobuf_Value_has_list_value(const google_protobuf_Value *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(8, 16), 6); } +UPB_INLINE const google_protobuf_ListValue* google_protobuf_Value_list_value(const google_protobuf_Value *msg) { return UPB_READ_ONEOF(msg, const google_protobuf_ListValue*, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 6, NULL); } + +UPB_INLINE void google_protobuf_Value_set_null_value(google_protobuf_Value *msg, int32_t value) { + UPB_WRITE_ONEOF(msg, int32_t, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), 1); +} +UPB_INLINE void google_protobuf_Value_set_number_value(google_protobuf_Value *msg, double value) { + UPB_WRITE_ONEOF(msg, double, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), 2); +} +UPB_INLINE void google_protobuf_Value_set_string_value(google_protobuf_Value *msg, upb_strview value) { + UPB_WRITE_ONEOF(msg, upb_strview, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), 3); +} +UPB_INLINE void google_protobuf_Value_set_bool_value(google_protobuf_Value *msg, bool value) { + UPB_WRITE_ONEOF(msg, bool, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), 4); +} +UPB_INLINE void google_protobuf_Value_set_struct_value(google_protobuf_Value *msg, google_protobuf_Struct* value) { + UPB_WRITE_ONEOF(msg, google_protobuf_Struct*, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), 5); +} +UPB_INLINE struct google_protobuf_Struct* google_protobuf_Value_mutable_struct_value(google_protobuf_Value *msg, upb_arena *arena) { + struct google_protobuf_Struct* sub = (struct google_protobuf_Struct*)google_protobuf_Value_struct_value(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Struct*)upb_msg_new(&google_protobuf_Struct_msginit, arena); + if (!sub) return NULL; + google_protobuf_Value_set_struct_value(msg, sub); + } + return sub; +} +UPB_INLINE void google_protobuf_Value_set_list_value(google_protobuf_Value *msg, google_protobuf_ListValue* value) { + UPB_WRITE_ONEOF(msg, google_protobuf_ListValue*, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), 6); +} +UPB_INLINE struct google_protobuf_ListValue* google_protobuf_Value_mutable_list_value(google_protobuf_Value *msg, upb_arena *arena) { + struct google_protobuf_ListValue* sub = (struct google_protobuf_ListValue*)google_protobuf_Value_list_value(msg); + if (sub == NULL) { + sub = (struct google_protobuf_ListValue*)upb_msg_new(&google_protobuf_ListValue_msginit, arena); + if (!sub) return NULL; + google_protobuf_Value_set_list_value(msg, sub); + } + return sub; +} + + +/* google.protobuf.ListValue */ + +UPB_INLINE google_protobuf_ListValue *google_protobuf_ListValue_new(upb_arena *arena) { + return (google_protobuf_ListValue *)upb_msg_new(&google_protobuf_ListValue_msginit, arena); +} +UPB_INLINE google_protobuf_ListValue *google_protobuf_ListValue_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_ListValue *ret = google_protobuf_ListValue_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_ListValue_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_ListValue_serialize(const google_protobuf_ListValue *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_ListValue_msginit, arena, len); +} + +UPB_INLINE const google_protobuf_Value* const* google_protobuf_ListValue_values(const google_protobuf_ListValue *msg, size_t *len) { return (const google_protobuf_Value* const*)_upb_array_accessor(msg, UPB_SIZE(0, 0), len); } + +UPB_INLINE google_protobuf_Value** google_protobuf_ListValue_mutable_values(google_protobuf_ListValue *msg, size_t *len) { + return (google_protobuf_Value**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len); +} +UPB_INLINE google_protobuf_Value** google_protobuf_ListValue_resize_values(google_protobuf_ListValue *msg, size_t len, upb_arena *arena) { + return (google_protobuf_Value**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_Value* google_protobuf_ListValue_add_values(google_protobuf_ListValue *msg, upb_arena *arena) { + struct google_protobuf_Value* sub = (struct google_protobuf_Value*)upb_msg_new(&google_protobuf_Value_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* GOOGLE_PROTOBUF_STRUCT_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/google/protobuf/timestamp.upb.c b/src/core/ext/upb-generated/google/protobuf/timestamp.upb.c new file mode 100644 index 00000000000..edc7af5f364 --- /dev/null +++ b/src/core/ext/upb-generated/google/protobuf/timestamp.upb.c @@ -0,0 +1,27 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * google/protobuf/timestamp.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include +#include "upb/msg.h" +#include "google/protobuf/timestamp.upb.h" + +#include "upb/port_def.inc" + +static const upb_msglayout_field google_protobuf_Timestamp__fields[2] = { + {1, UPB_SIZE(0, 0), 0, 0, 3, 1}, + {2, UPB_SIZE(8, 8), 0, 0, 5, 1}, +}; + +const upb_msglayout google_protobuf_Timestamp_msginit = { + NULL, + &google_protobuf_Timestamp__fields[0], + UPB_SIZE(16, 16), 2, false, +}; + +#include "upb/port_undef.inc" + diff --git a/src/core/ext/upb-generated/google/protobuf/timestamp.upb.h b/src/core/ext/upb-generated/google/protobuf/timestamp.upb.h new file mode 100644 index 00000000000..23d39e55f9d --- /dev/null +++ b/src/core/ext/upb-generated/google/protobuf/timestamp.upb.h @@ -0,0 +1,60 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * google/protobuf/timestamp.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef GOOGLE_PROTOBUF_TIMESTAMP_PROTO_UPB_H_ +#define GOOGLE_PROTOBUF_TIMESTAMP_PROTO_UPB_H_ + +#include "upb/generated_util.h" + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +#ifdef __cplusplus +extern "C" { +#endif + +struct google_protobuf_Timestamp; +typedef struct google_protobuf_Timestamp google_protobuf_Timestamp; +extern const upb_msglayout google_protobuf_Timestamp_msginit; + +/* Enums */ + + +/* google.protobuf.Timestamp */ + +UPB_INLINE google_protobuf_Timestamp *google_protobuf_Timestamp_new(upb_arena *arena) { + return (google_protobuf_Timestamp *)upb_msg_new(&google_protobuf_Timestamp_msginit, arena); +} +UPB_INLINE google_protobuf_Timestamp *google_protobuf_Timestamp_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_Timestamp *ret = google_protobuf_Timestamp_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_Timestamp_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_Timestamp_serialize(const google_protobuf_Timestamp *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_Timestamp_msginit, arena, len); +} + +UPB_INLINE int64_t google_protobuf_Timestamp_seconds(const google_protobuf_Timestamp *msg) { return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(0, 0)); } +UPB_INLINE int32_t google_protobuf_Timestamp_nanos(const google_protobuf_Timestamp *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); } + +UPB_INLINE void google_protobuf_Timestamp_set_seconds(google_protobuf_Timestamp *msg, int64_t value) { + UPB_FIELD_AT(msg, int64_t, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void google_protobuf_Timestamp_set_nanos(google_protobuf_Timestamp *msg, int32_t value) { + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value; +} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* GOOGLE_PROTOBUF_TIMESTAMP_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/google/protobuf/wrappers.upb.c b/src/core/ext/upb-generated/google/protobuf/wrappers.upb.c new file mode 100644 index 00000000000..1b93ef437ac --- /dev/null +++ b/src/core/ext/upb-generated/google/protobuf/wrappers.upb.c @@ -0,0 +1,106 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * google/protobuf/wrappers.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include +#include "upb/msg.h" +#include "google/protobuf/wrappers.upb.h" + +#include "upb/port_def.inc" + +static const upb_msglayout_field google_protobuf_DoubleValue__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 1, 1}, +}; + +const upb_msglayout google_protobuf_DoubleValue_msginit = { + NULL, + &google_protobuf_DoubleValue__fields[0], + UPB_SIZE(8, 8), 1, false, +}; + +static const upb_msglayout_field google_protobuf_FloatValue__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 2, 1}, +}; + +const upb_msglayout google_protobuf_FloatValue_msginit = { + NULL, + &google_protobuf_FloatValue__fields[0], + UPB_SIZE(4, 4), 1, false, +}; + +static const upb_msglayout_field google_protobuf_Int64Value__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 3, 1}, +}; + +const upb_msglayout google_protobuf_Int64Value_msginit = { + NULL, + &google_protobuf_Int64Value__fields[0], + UPB_SIZE(8, 8), 1, false, +}; + +static const upb_msglayout_field google_protobuf_UInt64Value__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 4, 1}, +}; + +const upb_msglayout google_protobuf_UInt64Value_msginit = { + NULL, + &google_protobuf_UInt64Value__fields[0], + UPB_SIZE(8, 8), 1, false, +}; + +static const upb_msglayout_field google_protobuf_Int32Value__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 5, 1}, +}; + +const upb_msglayout google_protobuf_Int32Value_msginit = { + NULL, + &google_protobuf_Int32Value__fields[0], + UPB_SIZE(4, 4), 1, false, +}; + +static const upb_msglayout_field google_protobuf_UInt32Value__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 13, 1}, +}; + +const upb_msglayout google_protobuf_UInt32Value_msginit = { + NULL, + &google_protobuf_UInt32Value__fields[0], + UPB_SIZE(4, 4), 1, false, +}; + +static const upb_msglayout_field google_protobuf_BoolValue__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 8, 1}, +}; + +const upb_msglayout google_protobuf_BoolValue_msginit = { + NULL, + &google_protobuf_BoolValue__fields[0], + UPB_SIZE(1, 1), 1, false, +}; + +static const upb_msglayout_field google_protobuf_StringValue__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, +}; + +const upb_msglayout google_protobuf_StringValue_msginit = { + NULL, + &google_protobuf_StringValue__fields[0], + UPB_SIZE(8, 16), 1, false, +}; + +static const upb_msglayout_field google_protobuf_BytesValue__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 12, 1}, +}; + +const upb_msglayout google_protobuf_BytesValue_msginit = { + NULL, + &google_protobuf_BytesValue__fields[0], + UPB_SIZE(8, 16), 1, false, +}; + +#include "upb/port_undef.inc" + diff --git a/src/core/ext/upb-generated/google/protobuf/wrappers.upb.h b/src/core/ext/upb-generated/google/protobuf/wrappers.upb.h new file mode 100644 index 00000000000..b9897ecceb2 --- /dev/null +++ b/src/core/ext/upb-generated/google/protobuf/wrappers.upb.h @@ -0,0 +1,240 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * google/protobuf/wrappers.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef GOOGLE_PROTOBUF_WRAPPERS_PROTO_UPB_H_ +#define GOOGLE_PROTOBUF_WRAPPERS_PROTO_UPB_H_ + +#include "upb/generated_util.h" + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +#ifdef __cplusplus +extern "C" { +#endif + +struct google_protobuf_DoubleValue; +struct google_protobuf_FloatValue; +struct google_protobuf_Int64Value; +struct google_protobuf_UInt64Value; +struct google_protobuf_Int32Value; +struct google_protobuf_UInt32Value; +struct google_protobuf_BoolValue; +struct google_protobuf_StringValue; +struct google_protobuf_BytesValue; +typedef struct google_protobuf_DoubleValue google_protobuf_DoubleValue; +typedef struct google_protobuf_FloatValue google_protobuf_FloatValue; +typedef struct google_protobuf_Int64Value google_protobuf_Int64Value; +typedef struct google_protobuf_UInt64Value google_protobuf_UInt64Value; +typedef struct google_protobuf_Int32Value google_protobuf_Int32Value; +typedef struct google_protobuf_UInt32Value google_protobuf_UInt32Value; +typedef struct google_protobuf_BoolValue google_protobuf_BoolValue; +typedef struct google_protobuf_StringValue google_protobuf_StringValue; +typedef struct google_protobuf_BytesValue google_protobuf_BytesValue; +extern const upb_msglayout google_protobuf_DoubleValue_msginit; +extern const upb_msglayout google_protobuf_FloatValue_msginit; +extern const upb_msglayout google_protobuf_Int64Value_msginit; +extern const upb_msglayout google_protobuf_UInt64Value_msginit; +extern const upb_msglayout google_protobuf_Int32Value_msginit; +extern const upb_msglayout google_protobuf_UInt32Value_msginit; +extern const upb_msglayout google_protobuf_BoolValue_msginit; +extern const upb_msglayout google_protobuf_StringValue_msginit; +extern const upb_msglayout google_protobuf_BytesValue_msginit; + +/* Enums */ + + +/* google.protobuf.DoubleValue */ + +UPB_INLINE google_protobuf_DoubleValue *google_protobuf_DoubleValue_new(upb_arena *arena) { + return (google_protobuf_DoubleValue *)upb_msg_new(&google_protobuf_DoubleValue_msginit, arena); +} +UPB_INLINE google_protobuf_DoubleValue *google_protobuf_DoubleValue_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_DoubleValue *ret = google_protobuf_DoubleValue_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_DoubleValue_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_DoubleValue_serialize(const google_protobuf_DoubleValue *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_DoubleValue_msginit, arena, len); +} + +UPB_INLINE double google_protobuf_DoubleValue_value(const google_protobuf_DoubleValue *msg) { return UPB_FIELD_AT(msg, double, UPB_SIZE(0, 0)); } + +UPB_INLINE void google_protobuf_DoubleValue_set_value(google_protobuf_DoubleValue *msg, double value) { + UPB_FIELD_AT(msg, double, UPB_SIZE(0, 0)) = value; +} + + +/* google.protobuf.FloatValue */ + +UPB_INLINE google_protobuf_FloatValue *google_protobuf_FloatValue_new(upb_arena *arena) { + return (google_protobuf_FloatValue *)upb_msg_new(&google_protobuf_FloatValue_msginit, arena); +} +UPB_INLINE google_protobuf_FloatValue *google_protobuf_FloatValue_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_FloatValue *ret = google_protobuf_FloatValue_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_FloatValue_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_FloatValue_serialize(const google_protobuf_FloatValue *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_FloatValue_msginit, arena, len); +} + +UPB_INLINE float google_protobuf_FloatValue_value(const google_protobuf_FloatValue *msg) { return UPB_FIELD_AT(msg, float, UPB_SIZE(0, 0)); } + +UPB_INLINE void google_protobuf_FloatValue_set_value(google_protobuf_FloatValue *msg, float value) { + UPB_FIELD_AT(msg, float, UPB_SIZE(0, 0)) = value; +} + + +/* google.protobuf.Int64Value */ + +UPB_INLINE google_protobuf_Int64Value *google_protobuf_Int64Value_new(upb_arena *arena) { + return (google_protobuf_Int64Value *)upb_msg_new(&google_protobuf_Int64Value_msginit, arena); +} +UPB_INLINE google_protobuf_Int64Value *google_protobuf_Int64Value_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_Int64Value *ret = google_protobuf_Int64Value_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_Int64Value_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_Int64Value_serialize(const google_protobuf_Int64Value *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_Int64Value_msginit, arena, len); +} + +UPB_INLINE int64_t google_protobuf_Int64Value_value(const google_protobuf_Int64Value *msg) { return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(0, 0)); } + +UPB_INLINE void google_protobuf_Int64Value_set_value(google_protobuf_Int64Value *msg, int64_t value) { + UPB_FIELD_AT(msg, int64_t, UPB_SIZE(0, 0)) = value; +} + + +/* google.protobuf.UInt64Value */ + +UPB_INLINE google_protobuf_UInt64Value *google_protobuf_UInt64Value_new(upb_arena *arena) { + return (google_protobuf_UInt64Value *)upb_msg_new(&google_protobuf_UInt64Value_msginit, arena); +} +UPB_INLINE google_protobuf_UInt64Value *google_protobuf_UInt64Value_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_UInt64Value *ret = google_protobuf_UInt64Value_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_UInt64Value_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_UInt64Value_serialize(const google_protobuf_UInt64Value *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_UInt64Value_msginit, arena, len); +} + +UPB_INLINE uint64_t google_protobuf_UInt64Value_value(const google_protobuf_UInt64Value *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(0, 0)); } + +UPB_INLINE void google_protobuf_UInt64Value_set_value(google_protobuf_UInt64Value *msg, uint64_t value) { + UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(0, 0)) = value; +} + + +/* google.protobuf.Int32Value */ + +UPB_INLINE google_protobuf_Int32Value *google_protobuf_Int32Value_new(upb_arena *arena) { + return (google_protobuf_Int32Value *)upb_msg_new(&google_protobuf_Int32Value_msginit, arena); +} +UPB_INLINE google_protobuf_Int32Value *google_protobuf_Int32Value_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_Int32Value *ret = google_protobuf_Int32Value_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_Int32Value_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_Int32Value_serialize(const google_protobuf_Int32Value *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_Int32Value_msginit, arena, len); +} + +UPB_INLINE int32_t google_protobuf_Int32Value_value(const google_protobuf_Int32Value *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(0, 0)); } + +UPB_INLINE void google_protobuf_Int32Value_set_value(google_protobuf_Int32Value *msg, int32_t value) { + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(0, 0)) = value; +} + + +/* google.protobuf.UInt32Value */ + +UPB_INLINE google_protobuf_UInt32Value *google_protobuf_UInt32Value_new(upb_arena *arena) { + return (google_protobuf_UInt32Value *)upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); +} +UPB_INLINE google_protobuf_UInt32Value *google_protobuf_UInt32Value_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_UInt32Value *ret = google_protobuf_UInt32Value_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_UInt32Value_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_UInt32Value_serialize(const google_protobuf_UInt32Value *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_UInt32Value_msginit, arena, len); +} + +UPB_INLINE uint32_t google_protobuf_UInt32Value_value(const google_protobuf_UInt32Value *msg) { return UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(0, 0)); } + +UPB_INLINE void google_protobuf_UInt32Value_set_value(google_protobuf_UInt32Value *msg, uint32_t value) { + UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(0, 0)) = value; +} + + +/* google.protobuf.BoolValue */ + +UPB_INLINE google_protobuf_BoolValue *google_protobuf_BoolValue_new(upb_arena *arena) { + return (google_protobuf_BoolValue *)upb_msg_new(&google_protobuf_BoolValue_msginit, arena); +} +UPB_INLINE google_protobuf_BoolValue *google_protobuf_BoolValue_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_BoolValue *ret = google_protobuf_BoolValue_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_BoolValue_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_BoolValue_serialize(const google_protobuf_BoolValue *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_BoolValue_msginit, arena, len); +} + +UPB_INLINE bool google_protobuf_BoolValue_value(const google_protobuf_BoolValue *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(0, 0)); } + +UPB_INLINE void google_protobuf_BoolValue_set_value(google_protobuf_BoolValue *msg, bool value) { + UPB_FIELD_AT(msg, bool, UPB_SIZE(0, 0)) = value; +} + + +/* google.protobuf.StringValue */ + +UPB_INLINE google_protobuf_StringValue *google_protobuf_StringValue_new(upb_arena *arena) { + return (google_protobuf_StringValue *)upb_msg_new(&google_protobuf_StringValue_msginit, arena); +} +UPB_INLINE google_protobuf_StringValue *google_protobuf_StringValue_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_StringValue *ret = google_protobuf_StringValue_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_StringValue_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_StringValue_serialize(const google_protobuf_StringValue *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_StringValue_msginit, arena, len); +} + +UPB_INLINE upb_strview google_protobuf_StringValue_value(const google_protobuf_StringValue *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } + +UPB_INLINE void google_protobuf_StringValue_set_value(google_protobuf_StringValue *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} + + +/* google.protobuf.BytesValue */ + +UPB_INLINE google_protobuf_BytesValue *google_protobuf_BytesValue_new(upb_arena *arena) { + return (google_protobuf_BytesValue *)upb_msg_new(&google_protobuf_BytesValue_msginit, arena); +} +UPB_INLINE google_protobuf_BytesValue *google_protobuf_BytesValue_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_BytesValue *ret = google_protobuf_BytesValue_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_BytesValue_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_BytesValue_serialize(const google_protobuf_BytesValue *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_BytesValue_msginit, arena, len); +} + +UPB_INLINE upb_strview google_protobuf_BytesValue_value(const google_protobuf_BytesValue *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } + +UPB_INLINE void google_protobuf_BytesValue_set_value(google_protobuf_BytesValue *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* GOOGLE_PROTOBUF_WRAPPERS_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/google/rpc/status.upb.c b/src/core/ext/upb-generated/google/rpc/status.upb.c new file mode 100644 index 00000000000..25ac1461741 --- /dev/null +++ b/src/core/ext/upb-generated/google/rpc/status.upb.c @@ -0,0 +1,33 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * google/rpc/status.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include +#include "upb/msg.h" +#include "google/rpc/status.upb.h" +#include "google/protobuf/any.upb.h" + +#include "upb/port_def.inc" + +static const upb_msglayout *const google_rpc_Status_submsgs[1] = { + &google_protobuf_Any_msginit, +}; + +static const upb_msglayout_field google_rpc_Status__fields[3] = { + {1, UPB_SIZE(0, 0), 0, 0, 5, 1}, + {2, UPB_SIZE(4, 8), 0, 0, 9, 1}, + {3, UPB_SIZE(12, 24), 0, 0, 11, 3}, +}; + +const upb_msglayout google_rpc_Status_msginit = { + &google_rpc_Status_submsgs[0], + &google_rpc_Status__fields[0], + UPB_SIZE(16, 32), 3, false, +}; + +#include "upb/port_undef.inc" + diff --git a/src/core/ext/upb-generated/google/rpc/status.upb.h b/src/core/ext/upb-generated/google/rpc/status.upb.h new file mode 100644 index 00000000000..ccdac652130 --- /dev/null +++ b/src/core/ext/upb-generated/google/rpc/status.upb.h @@ -0,0 +1,76 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * google/rpc/status.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef GOOGLE_RPC_STATUS_PROTO_UPB_H_ +#define GOOGLE_RPC_STATUS_PROTO_UPB_H_ + +#include "upb/generated_util.h" + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +#ifdef __cplusplus +extern "C" { +#endif + +struct google_rpc_Status; +typedef struct google_rpc_Status google_rpc_Status; +extern const upb_msglayout google_rpc_Status_msginit; +struct google_protobuf_Any; +extern const upb_msglayout google_protobuf_Any_msginit; + +/* Enums */ + + +/* google.rpc.Status */ + +UPB_INLINE google_rpc_Status *google_rpc_Status_new(upb_arena *arena) { + return (google_rpc_Status *)upb_msg_new(&google_rpc_Status_msginit, arena); +} +UPB_INLINE google_rpc_Status *google_rpc_Status_parsenew(upb_strview buf, upb_arena *arena) { + google_rpc_Status *ret = google_rpc_Status_new(arena); + return (ret && upb_decode(buf, ret, &google_rpc_Status_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_rpc_Status_serialize(const google_rpc_Status *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_rpc_Status_msginit, arena, len); +} + +UPB_INLINE int32_t google_rpc_Status_code(const google_rpc_Status *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(0, 0)); } +UPB_INLINE upb_strview google_rpc_Status_message(const google_rpc_Status *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)); } +UPB_INLINE const struct google_protobuf_Any* const* google_rpc_Status_details(const google_rpc_Status *msg, size_t *len) { return (const struct google_protobuf_Any* const*)_upb_array_accessor(msg, UPB_SIZE(12, 24), len); } + +UPB_INLINE void google_rpc_Status_set_code(google_rpc_Status *msg, int32_t value) { + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void google_rpc_Status_set_message(google_rpc_Status *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)) = value; +} +UPB_INLINE struct google_protobuf_Any** google_rpc_Status_mutable_details(google_rpc_Status *msg, size_t *len) { + return (struct google_protobuf_Any**)_upb_array_mutable_accessor(msg, UPB_SIZE(12, 24), len); +} +UPB_INLINE struct google_protobuf_Any** google_rpc_Status_resize_details(google_rpc_Status *msg, size_t len, upb_arena *arena) { + return (struct google_protobuf_Any**)_upb_array_resize_accessor(msg, UPB_SIZE(12, 24), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_Any* google_rpc_Status_add_details(google_rpc_Status *msg, upb_arena *arena) { + struct google_protobuf_Any* sub = (struct google_protobuf_Any*)upb_msg_new(&google_protobuf_Any_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(12, 24), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* GOOGLE_RPC_STATUS_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/validate/validate.upb.c b/src/core/ext/upb-generated/validate/validate.upb.c new file mode 100644 index 00000000000..6d3c6be1461 --- /dev/null +++ b/src/core/ext/upb-generated/validate/validate.upb.c @@ -0,0 +1,443 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * validate/validate.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include +#include "upb/msg.h" +#include "validate/validate.upb.h" +#include "google/protobuf/descriptor.upb.h" +#include "google/protobuf/duration.upb.h" +#include "google/protobuf/timestamp.upb.h" + +#include "upb/port_def.inc" + +static const upb_msglayout *const validate_FieldRules_submsgs[22] = { + &validate_AnyRules_msginit, + &validate_BoolRules_msginit, + &validate_BytesRules_msginit, + &validate_DoubleRules_msginit, + &validate_DurationRules_msginit, + &validate_EnumRules_msginit, + &validate_Fixed32Rules_msginit, + &validate_Fixed64Rules_msginit, + &validate_FloatRules_msginit, + &validate_Int32Rules_msginit, + &validate_Int64Rules_msginit, + &validate_MapRules_msginit, + &validate_MessageRules_msginit, + &validate_RepeatedRules_msginit, + &validate_SFixed32Rules_msginit, + &validate_SFixed64Rules_msginit, + &validate_SInt32Rules_msginit, + &validate_SInt64Rules_msginit, + &validate_StringRules_msginit, + &validate_TimestampRules_msginit, + &validate_UInt32Rules_msginit, + &validate_UInt64Rules_msginit, +}; + +static const upb_msglayout_field validate_FieldRules__fields[22] = { + {1, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 8, 11, 1}, + {2, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 3, 11, 1}, + {3, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 9, 11, 1}, + {4, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 10, 11, 1}, + {5, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 20, 11, 1}, + {6, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 21, 11, 1}, + {7, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 16, 11, 1}, + {8, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 17, 11, 1}, + {9, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 6, 11, 1}, + {10, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 7, 11, 1}, + {11, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 14, 11, 1}, + {12, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 15, 11, 1}, + {13, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 1, 11, 1}, + {14, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 18, 11, 1}, + {15, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 2, 11, 1}, + {16, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 5, 11, 1}, + {17, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 12, 11, 1}, + {18, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 13, 11, 1}, + {19, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 11, 11, 1}, + {20, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 0, 11, 1}, + {21, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 4, 11, 1}, + {22, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 19, 11, 1}, +}; + +const upb_msglayout validate_FieldRules_msginit = { + &validate_FieldRules_submsgs[0], + &validate_FieldRules__fields[0], + UPB_SIZE(8, 16), 22, false, +}; + +static const upb_msglayout_field validate_FloatRules__fields[7] = { + {1, UPB_SIZE(4, 4), 1, 0, 2, 1}, + {2, UPB_SIZE(8, 8), 2, 0, 2, 1}, + {3, UPB_SIZE(12, 12), 3, 0, 2, 1}, + {4, UPB_SIZE(16, 16), 4, 0, 2, 1}, + {5, UPB_SIZE(20, 20), 5, 0, 2, 1}, + {6, UPB_SIZE(24, 24), 0, 0, 2, 3}, + {7, UPB_SIZE(28, 32), 0, 0, 2, 3}, +}; + +const upb_msglayout validate_FloatRules_msginit = { + NULL, + &validate_FloatRules__fields[0], + UPB_SIZE(32, 40), 7, false, +}; + +static const upb_msglayout_field validate_DoubleRules__fields[7] = { + {1, UPB_SIZE(8, 8), 1, 0, 1, 1}, + {2, UPB_SIZE(16, 16), 2, 0, 1, 1}, + {3, UPB_SIZE(24, 24), 3, 0, 1, 1}, + {4, UPB_SIZE(32, 32), 4, 0, 1, 1}, + {5, UPB_SIZE(40, 40), 5, 0, 1, 1}, + {6, UPB_SIZE(48, 48), 0, 0, 1, 3}, + {7, UPB_SIZE(52, 56), 0, 0, 1, 3}, +}; + +const upb_msglayout validate_DoubleRules_msginit = { + NULL, + &validate_DoubleRules__fields[0], + UPB_SIZE(56, 64), 7, false, +}; + +static const upb_msglayout_field validate_Int32Rules__fields[7] = { + {1, UPB_SIZE(4, 4), 1, 0, 5, 1}, + {2, UPB_SIZE(8, 8), 2, 0, 5, 1}, + {3, UPB_SIZE(12, 12), 3, 0, 5, 1}, + {4, UPB_SIZE(16, 16), 4, 0, 5, 1}, + {5, UPB_SIZE(20, 20), 5, 0, 5, 1}, + {6, UPB_SIZE(24, 24), 0, 0, 5, 3}, + {7, UPB_SIZE(28, 32), 0, 0, 5, 3}, +}; + +const upb_msglayout validate_Int32Rules_msginit = { + NULL, + &validate_Int32Rules__fields[0], + UPB_SIZE(32, 40), 7, false, +}; + +static const upb_msglayout_field validate_Int64Rules__fields[7] = { + {1, UPB_SIZE(8, 8), 1, 0, 3, 1}, + {2, UPB_SIZE(16, 16), 2, 0, 3, 1}, + {3, UPB_SIZE(24, 24), 3, 0, 3, 1}, + {4, UPB_SIZE(32, 32), 4, 0, 3, 1}, + {5, UPB_SIZE(40, 40), 5, 0, 3, 1}, + {6, UPB_SIZE(48, 48), 0, 0, 3, 3}, + {7, UPB_SIZE(52, 56), 0, 0, 3, 3}, +}; + +const upb_msglayout validate_Int64Rules_msginit = { + NULL, + &validate_Int64Rules__fields[0], + UPB_SIZE(56, 64), 7, false, +}; + +static const upb_msglayout_field validate_UInt32Rules__fields[7] = { + {1, UPB_SIZE(4, 4), 1, 0, 13, 1}, + {2, UPB_SIZE(8, 8), 2, 0, 13, 1}, + {3, UPB_SIZE(12, 12), 3, 0, 13, 1}, + {4, UPB_SIZE(16, 16), 4, 0, 13, 1}, + {5, UPB_SIZE(20, 20), 5, 0, 13, 1}, + {6, UPB_SIZE(24, 24), 0, 0, 13, 3}, + {7, UPB_SIZE(28, 32), 0, 0, 13, 3}, +}; + +const upb_msglayout validate_UInt32Rules_msginit = { + NULL, + &validate_UInt32Rules__fields[0], + UPB_SIZE(32, 40), 7, false, +}; + +static const upb_msglayout_field validate_UInt64Rules__fields[7] = { + {1, UPB_SIZE(8, 8), 1, 0, 4, 1}, + {2, UPB_SIZE(16, 16), 2, 0, 4, 1}, + {3, UPB_SIZE(24, 24), 3, 0, 4, 1}, + {4, UPB_SIZE(32, 32), 4, 0, 4, 1}, + {5, UPB_SIZE(40, 40), 5, 0, 4, 1}, + {6, UPB_SIZE(48, 48), 0, 0, 4, 3}, + {7, UPB_SIZE(52, 56), 0, 0, 4, 3}, +}; + +const upb_msglayout validate_UInt64Rules_msginit = { + NULL, + &validate_UInt64Rules__fields[0], + UPB_SIZE(56, 64), 7, false, +}; + +static const upb_msglayout_field validate_SInt32Rules__fields[7] = { + {1, UPB_SIZE(4, 4), 1, 0, 17, 1}, + {2, UPB_SIZE(8, 8), 2, 0, 17, 1}, + {3, UPB_SIZE(12, 12), 3, 0, 17, 1}, + {4, UPB_SIZE(16, 16), 4, 0, 17, 1}, + {5, UPB_SIZE(20, 20), 5, 0, 17, 1}, + {6, UPB_SIZE(24, 24), 0, 0, 17, 3}, + {7, UPB_SIZE(28, 32), 0, 0, 17, 3}, +}; + +const upb_msglayout validate_SInt32Rules_msginit = { + NULL, + &validate_SInt32Rules__fields[0], + UPB_SIZE(32, 40), 7, false, +}; + +static const upb_msglayout_field validate_SInt64Rules__fields[7] = { + {1, UPB_SIZE(8, 8), 1, 0, 18, 1}, + {2, UPB_SIZE(16, 16), 2, 0, 18, 1}, + {3, UPB_SIZE(24, 24), 3, 0, 18, 1}, + {4, UPB_SIZE(32, 32), 4, 0, 18, 1}, + {5, UPB_SIZE(40, 40), 5, 0, 18, 1}, + {6, UPB_SIZE(48, 48), 0, 0, 18, 3}, + {7, UPB_SIZE(52, 56), 0, 0, 18, 3}, +}; + +const upb_msglayout validate_SInt64Rules_msginit = { + NULL, + &validate_SInt64Rules__fields[0], + UPB_SIZE(56, 64), 7, false, +}; + +static const upb_msglayout_field validate_Fixed32Rules__fields[7] = { + {1, UPB_SIZE(4, 4), 1, 0, 7, 1}, + {2, UPB_SIZE(8, 8), 2, 0, 7, 1}, + {3, UPB_SIZE(12, 12), 3, 0, 7, 1}, + {4, UPB_SIZE(16, 16), 4, 0, 7, 1}, + {5, UPB_SIZE(20, 20), 5, 0, 7, 1}, + {6, UPB_SIZE(24, 24), 0, 0, 7, 3}, + {7, UPB_SIZE(28, 32), 0, 0, 7, 3}, +}; + +const upb_msglayout validate_Fixed32Rules_msginit = { + NULL, + &validate_Fixed32Rules__fields[0], + UPB_SIZE(32, 40), 7, false, +}; + +static const upb_msglayout_field validate_Fixed64Rules__fields[7] = { + {1, UPB_SIZE(8, 8), 1, 0, 6, 1}, + {2, UPB_SIZE(16, 16), 2, 0, 6, 1}, + {3, UPB_SIZE(24, 24), 3, 0, 6, 1}, + {4, UPB_SIZE(32, 32), 4, 0, 6, 1}, + {5, UPB_SIZE(40, 40), 5, 0, 6, 1}, + {6, UPB_SIZE(48, 48), 0, 0, 6, 3}, + {7, UPB_SIZE(52, 56), 0, 0, 6, 3}, +}; + +const upb_msglayout validate_Fixed64Rules_msginit = { + NULL, + &validate_Fixed64Rules__fields[0], + UPB_SIZE(56, 64), 7, false, +}; + +static const upb_msglayout_field validate_SFixed32Rules__fields[7] = { + {1, UPB_SIZE(4, 4), 1, 0, 15, 1}, + {2, UPB_SIZE(8, 8), 2, 0, 15, 1}, + {3, UPB_SIZE(12, 12), 3, 0, 15, 1}, + {4, UPB_SIZE(16, 16), 4, 0, 15, 1}, + {5, UPB_SIZE(20, 20), 5, 0, 15, 1}, + {6, UPB_SIZE(24, 24), 0, 0, 15, 3}, + {7, UPB_SIZE(28, 32), 0, 0, 15, 3}, +}; + +const upb_msglayout validate_SFixed32Rules_msginit = { + NULL, + &validate_SFixed32Rules__fields[0], + UPB_SIZE(32, 40), 7, false, +}; + +static const upb_msglayout_field validate_SFixed64Rules__fields[7] = { + {1, UPB_SIZE(8, 8), 1, 0, 16, 1}, + {2, UPB_SIZE(16, 16), 2, 0, 16, 1}, + {3, UPB_SIZE(24, 24), 3, 0, 16, 1}, + {4, UPB_SIZE(32, 32), 4, 0, 16, 1}, + {5, UPB_SIZE(40, 40), 5, 0, 16, 1}, + {6, UPB_SIZE(48, 48), 0, 0, 16, 3}, + {7, UPB_SIZE(52, 56), 0, 0, 16, 3}, +}; + +const upb_msglayout validate_SFixed64Rules_msginit = { + NULL, + &validate_SFixed64Rules__fields[0], + UPB_SIZE(56, 64), 7, false, +}; + +static const upb_msglayout_field validate_BoolRules__fields[1] = { + {1, UPB_SIZE(1, 1), 1, 0, 8, 1}, +}; + +const upb_msglayout validate_BoolRules_msginit = { + NULL, + &validate_BoolRules__fields[0], + UPB_SIZE(2, 2), 1, false, +}; + +static const upb_msglayout_field validate_StringRules__fields[20] = { + {1, UPB_SIZE(56, 56), 7, 0, 9, 1}, + {2, UPB_SIZE(8, 8), 1, 0, 4, 1}, + {3, UPB_SIZE(16, 16), 2, 0, 4, 1}, + {4, UPB_SIZE(24, 24), 3, 0, 4, 1}, + {5, UPB_SIZE(32, 32), 4, 0, 4, 1}, + {6, UPB_SIZE(64, 72), 8, 0, 9, 1}, + {7, UPB_SIZE(72, 88), 9, 0, 9, 1}, + {8, UPB_SIZE(80, 104), 10, 0, 9, 1}, + {9, UPB_SIZE(88, 120), 11, 0, 9, 1}, + {10, UPB_SIZE(96, 136), 0, 0, 9, 3}, + {11, UPB_SIZE(100, 144), 0, 0, 9, 3}, + {12, UPB_SIZE(104, 152), UPB_SIZE(-109, -157), 0, 8, 1}, + {13, UPB_SIZE(104, 152), UPB_SIZE(-109, -157), 0, 8, 1}, + {14, UPB_SIZE(104, 152), UPB_SIZE(-109, -157), 0, 8, 1}, + {15, UPB_SIZE(104, 152), UPB_SIZE(-109, -157), 0, 8, 1}, + {16, UPB_SIZE(104, 152), UPB_SIZE(-109, -157), 0, 8, 1}, + {17, UPB_SIZE(104, 152), UPB_SIZE(-109, -157), 0, 8, 1}, + {18, UPB_SIZE(104, 152), UPB_SIZE(-109, -157), 0, 8, 1}, + {19, UPB_SIZE(40, 40), 5, 0, 4, 1}, + {20, UPB_SIZE(48, 48), 6, 0, 4, 1}, +}; + +const upb_msglayout validate_StringRules_msginit = { + NULL, + &validate_StringRules__fields[0], + UPB_SIZE(112, 160), 20, false, +}; + +static const upb_msglayout_field validate_BytesRules__fields[13] = { + {1, UPB_SIZE(32, 32), 4, 0, 12, 1}, + {2, UPB_SIZE(8, 8), 1, 0, 4, 1}, + {3, UPB_SIZE(16, 16), 2, 0, 4, 1}, + {4, UPB_SIZE(40, 48), 5, 0, 9, 1}, + {5, UPB_SIZE(48, 64), 6, 0, 12, 1}, + {6, UPB_SIZE(56, 80), 7, 0, 12, 1}, + {7, UPB_SIZE(64, 96), 8, 0, 12, 1}, + {8, UPB_SIZE(72, 112), 0, 0, 12, 3}, + {9, UPB_SIZE(76, 120), 0, 0, 12, 3}, + {10, UPB_SIZE(80, 128), UPB_SIZE(-85, -133), 0, 8, 1}, + {11, UPB_SIZE(80, 128), UPB_SIZE(-85, -133), 0, 8, 1}, + {12, UPB_SIZE(80, 128), UPB_SIZE(-85, -133), 0, 8, 1}, + {13, UPB_SIZE(24, 24), 3, 0, 4, 1}, +}; + +const upb_msglayout validate_BytesRules_msginit = { + NULL, + &validate_BytesRules__fields[0], + UPB_SIZE(88, 144), 13, false, +}; + +static const upb_msglayout_field validate_EnumRules__fields[4] = { + {1, UPB_SIZE(4, 4), 1, 0, 5, 1}, + {2, UPB_SIZE(8, 8), 2, 0, 8, 1}, + {3, UPB_SIZE(12, 16), 0, 0, 5, 3}, + {4, UPB_SIZE(16, 24), 0, 0, 5, 3}, +}; + +const upb_msglayout validate_EnumRules_msginit = { + NULL, + &validate_EnumRules__fields[0], + UPB_SIZE(20, 32), 4, false, +}; + +static const upb_msglayout_field validate_MessageRules__fields[2] = { + {1, UPB_SIZE(1, 1), 1, 0, 8, 1}, + {2, UPB_SIZE(2, 2), 2, 0, 8, 1}, +}; + +const upb_msglayout validate_MessageRules_msginit = { + NULL, + &validate_MessageRules__fields[0], + UPB_SIZE(3, 3), 2, false, +}; + +static const upb_msglayout *const validate_RepeatedRules_submsgs[1] = { + &validate_FieldRules_msginit, +}; + +static const upb_msglayout_field validate_RepeatedRules__fields[4] = { + {1, UPB_SIZE(8, 8), 1, 0, 4, 1}, + {2, UPB_SIZE(16, 16), 2, 0, 4, 1}, + {3, UPB_SIZE(24, 24), 3, 0, 8, 1}, + {4, UPB_SIZE(28, 32), 4, 0, 11, 1}, +}; + +const upb_msglayout validate_RepeatedRules_msginit = { + &validate_RepeatedRules_submsgs[0], + &validate_RepeatedRules__fields[0], + UPB_SIZE(32, 40), 4, false, +}; + +static const upb_msglayout *const validate_MapRules_submsgs[2] = { + &validate_FieldRules_msginit, +}; + +static const upb_msglayout_field validate_MapRules__fields[5] = { + {1, UPB_SIZE(8, 8), 1, 0, 4, 1}, + {2, UPB_SIZE(16, 16), 2, 0, 4, 1}, + {3, UPB_SIZE(24, 24), 3, 0, 8, 1}, + {4, UPB_SIZE(28, 32), 4, 0, 11, 1}, + {5, UPB_SIZE(32, 40), 5, 0, 11, 1}, +}; + +const upb_msglayout validate_MapRules_msginit = { + &validate_MapRules_submsgs[0], + &validate_MapRules__fields[0], + UPB_SIZE(40, 48), 5, false, +}; + +static const upb_msglayout_field validate_AnyRules__fields[3] = { + {1, UPB_SIZE(1, 1), 1, 0, 8, 1}, + {2, UPB_SIZE(4, 8), 0, 0, 9, 3}, + {3, UPB_SIZE(8, 16), 0, 0, 9, 3}, +}; + +const upb_msglayout validate_AnyRules_msginit = { + NULL, + &validate_AnyRules__fields[0], + UPB_SIZE(12, 24), 3, false, +}; + +static const upb_msglayout *const validate_DurationRules_submsgs[7] = { + &google_protobuf_Duration_msginit, +}; + +static const upb_msglayout_field validate_DurationRules__fields[8] = { + {1, UPB_SIZE(1, 1), 1, 0, 8, 1}, + {2, UPB_SIZE(4, 8), 2, 0, 11, 1}, + {3, UPB_SIZE(8, 16), 3, 0, 11, 1}, + {4, UPB_SIZE(12, 24), 4, 0, 11, 1}, + {5, UPB_SIZE(16, 32), 5, 0, 11, 1}, + {6, UPB_SIZE(20, 40), 6, 0, 11, 1}, + {7, UPB_SIZE(24, 48), 0, 0, 11, 3}, + {8, UPB_SIZE(28, 56), 0, 0, 11, 3}, +}; + +const upb_msglayout validate_DurationRules_msginit = { + &validate_DurationRules_submsgs[0], + &validate_DurationRules__fields[0], + UPB_SIZE(32, 64), 8, false, +}; + +static const upb_msglayout *const validate_TimestampRules_submsgs[6] = { + &google_protobuf_Duration_msginit, + &google_protobuf_Timestamp_msginit, +}; + +static const upb_msglayout_field validate_TimestampRules__fields[9] = { + {1, UPB_SIZE(2, 2), 1, 0, 8, 1}, + {2, UPB_SIZE(8, 8), 4, 1, 11, 1}, + {3, UPB_SIZE(12, 16), 5, 1, 11, 1}, + {4, UPB_SIZE(16, 24), 6, 1, 11, 1}, + {5, UPB_SIZE(20, 32), 7, 1, 11, 1}, + {6, UPB_SIZE(24, 40), 8, 1, 11, 1}, + {7, UPB_SIZE(3, 3), 2, 0, 8, 1}, + {8, UPB_SIZE(4, 4), 3, 0, 8, 1}, + {9, UPB_SIZE(28, 48), 9, 0, 11, 1}, +}; + +const upb_msglayout validate_TimestampRules_msginit = { + &validate_TimestampRules_submsgs[0], + &validate_TimestampRules__fields[0], + UPB_SIZE(32, 56), 9, false, +}; + +#include "upb/port_undef.inc" + diff --git a/src/core/ext/upb-generated/validate/validate.upb.h b/src/core/ext/upb-generated/validate/validate.upb.h new file mode 100644 index 00000000000..c28ac41881d --- /dev/null +++ b/src/core/ext/upb-generated/validate/validate.upb.h @@ -0,0 +1,2039 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * validate/validate.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef VALIDATE_VALIDATE_PROTO_UPB_H_ +#define VALIDATE_VALIDATE_PROTO_UPB_H_ + +#include "upb/generated_util.h" + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +#ifdef __cplusplus +extern "C" { +#endif + +struct validate_FieldRules; +struct validate_FloatRules; +struct validate_DoubleRules; +struct validate_Int32Rules; +struct validate_Int64Rules; +struct validate_UInt32Rules; +struct validate_UInt64Rules; +struct validate_SInt32Rules; +struct validate_SInt64Rules; +struct validate_Fixed32Rules; +struct validate_Fixed64Rules; +struct validate_SFixed32Rules; +struct validate_SFixed64Rules; +struct validate_BoolRules; +struct validate_StringRules; +struct validate_BytesRules; +struct validate_EnumRules; +struct validate_MessageRules; +struct validate_RepeatedRules; +struct validate_MapRules; +struct validate_AnyRules; +struct validate_DurationRules; +struct validate_TimestampRules; +typedef struct validate_FieldRules validate_FieldRules; +typedef struct validate_FloatRules validate_FloatRules; +typedef struct validate_DoubleRules validate_DoubleRules; +typedef struct validate_Int32Rules validate_Int32Rules; +typedef struct validate_Int64Rules validate_Int64Rules; +typedef struct validate_UInt32Rules validate_UInt32Rules; +typedef struct validate_UInt64Rules validate_UInt64Rules; +typedef struct validate_SInt32Rules validate_SInt32Rules; +typedef struct validate_SInt64Rules validate_SInt64Rules; +typedef struct validate_Fixed32Rules validate_Fixed32Rules; +typedef struct validate_Fixed64Rules validate_Fixed64Rules; +typedef struct validate_SFixed32Rules validate_SFixed32Rules; +typedef struct validate_SFixed64Rules validate_SFixed64Rules; +typedef struct validate_BoolRules validate_BoolRules; +typedef struct validate_StringRules validate_StringRules; +typedef struct validate_BytesRules validate_BytesRules; +typedef struct validate_EnumRules validate_EnumRules; +typedef struct validate_MessageRules validate_MessageRules; +typedef struct validate_RepeatedRules validate_RepeatedRules; +typedef struct validate_MapRules validate_MapRules; +typedef struct validate_AnyRules validate_AnyRules; +typedef struct validate_DurationRules validate_DurationRules; +typedef struct validate_TimestampRules validate_TimestampRules; +extern const upb_msglayout validate_FieldRules_msginit; +extern const upb_msglayout validate_FloatRules_msginit; +extern const upb_msglayout validate_DoubleRules_msginit; +extern const upb_msglayout validate_Int32Rules_msginit; +extern const upb_msglayout validate_Int64Rules_msginit; +extern const upb_msglayout validate_UInt32Rules_msginit; +extern const upb_msglayout validate_UInt64Rules_msginit; +extern const upb_msglayout validate_SInt32Rules_msginit; +extern const upb_msglayout validate_SInt64Rules_msginit; +extern const upb_msglayout validate_Fixed32Rules_msginit; +extern const upb_msglayout validate_Fixed64Rules_msginit; +extern const upb_msglayout validate_SFixed32Rules_msginit; +extern const upb_msglayout validate_SFixed64Rules_msginit; +extern const upb_msglayout validate_BoolRules_msginit; +extern const upb_msglayout validate_StringRules_msginit; +extern const upb_msglayout validate_BytesRules_msginit; +extern const upb_msglayout validate_EnumRules_msginit; +extern const upb_msglayout validate_MessageRules_msginit; +extern const upb_msglayout validate_RepeatedRules_msginit; +extern const upb_msglayout validate_MapRules_msginit; +extern const upb_msglayout validate_AnyRules_msginit; +extern const upb_msglayout validate_DurationRules_msginit; +extern const upb_msglayout validate_TimestampRules_msginit; +struct google_protobuf_Duration; +struct google_protobuf_Timestamp; +extern const upb_msglayout google_protobuf_Duration_msginit; +extern const upb_msglayout google_protobuf_Timestamp_msginit; + +/* Enums */ + + +/* validate.FieldRules */ + +UPB_INLINE validate_FieldRules *validate_FieldRules_new(upb_arena *arena) { + return (validate_FieldRules *)upb_msg_new(&validate_FieldRules_msginit, arena); +} +UPB_INLINE validate_FieldRules *validate_FieldRules_parsenew(upb_strview buf, upb_arena *arena) { + validate_FieldRules *ret = validate_FieldRules_new(arena); + return (ret && upb_decode(buf, ret, &validate_FieldRules_msginit)) ? ret : NULL; +} +UPB_INLINE char *validate_FieldRules_serialize(const validate_FieldRules *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &validate_FieldRules_msginit, arena, len); +} + +typedef enum { + validate_FieldRules_type_float = 1, + validate_FieldRules_type_double = 2, + validate_FieldRules_type_int32 = 3, + validate_FieldRules_type_int64 = 4, + validate_FieldRules_type_uint32 = 5, + validate_FieldRules_type_uint64 = 6, + validate_FieldRules_type_sint32 = 7, + validate_FieldRules_type_sint64 = 8, + validate_FieldRules_type_fixed32 = 9, + validate_FieldRules_type_fixed64 = 10, + validate_FieldRules_type_sfixed32 = 11, + validate_FieldRules_type_sfixed64 = 12, + validate_FieldRules_type_bool = 13, + validate_FieldRules_type_string = 14, + validate_FieldRules_type_bytes = 15, + validate_FieldRules_type_enum = 16, + validate_FieldRules_type_message = 17, + validate_FieldRules_type_repeated = 18, + validate_FieldRules_type_map = 19, + validate_FieldRules_type_any = 20, + validate_FieldRules_type_duration = 21, + validate_FieldRules_type_timestamp = 22, + validate_FieldRules_type_NOT_SET = 0, +} validate_FieldRules_type_oneofcases; +UPB_INLINE validate_FieldRules_type_oneofcases validate_FieldRules_type_case(const validate_FieldRules* msg) { return UPB_FIELD_AT(msg, int, UPB_SIZE(4, 8)); } + +UPB_INLINE bool validate_FieldRules_has_float(const validate_FieldRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 1); } +UPB_INLINE const validate_FloatRules* validate_FieldRules_float(const validate_FieldRules *msg) { return UPB_READ_ONEOF(msg, const validate_FloatRules*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 1, NULL); } +UPB_INLINE bool validate_FieldRules_has_double(const validate_FieldRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 2); } +UPB_INLINE const validate_DoubleRules* validate_FieldRules_double(const validate_FieldRules *msg) { return UPB_READ_ONEOF(msg, const validate_DoubleRules*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 2, NULL); } +UPB_INLINE bool validate_FieldRules_has_int32(const validate_FieldRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 3); } +UPB_INLINE const validate_Int32Rules* validate_FieldRules_int32(const validate_FieldRules *msg) { return UPB_READ_ONEOF(msg, const validate_Int32Rules*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 3, NULL); } +UPB_INLINE bool validate_FieldRules_has_int64(const validate_FieldRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 4); } +UPB_INLINE const validate_Int64Rules* validate_FieldRules_int64(const validate_FieldRules *msg) { return UPB_READ_ONEOF(msg, const validate_Int64Rules*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 4, NULL); } +UPB_INLINE bool validate_FieldRules_has_uint32(const validate_FieldRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 5); } +UPB_INLINE const validate_UInt32Rules* validate_FieldRules_uint32(const validate_FieldRules *msg) { return UPB_READ_ONEOF(msg, const validate_UInt32Rules*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 5, NULL); } +UPB_INLINE bool validate_FieldRules_has_uint64(const validate_FieldRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 6); } +UPB_INLINE const validate_UInt64Rules* validate_FieldRules_uint64(const validate_FieldRules *msg) { return UPB_READ_ONEOF(msg, const validate_UInt64Rules*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 6, NULL); } +UPB_INLINE bool validate_FieldRules_has_sint32(const validate_FieldRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 7); } +UPB_INLINE const validate_SInt32Rules* validate_FieldRules_sint32(const validate_FieldRules *msg) { return UPB_READ_ONEOF(msg, const validate_SInt32Rules*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 7, NULL); } +UPB_INLINE bool validate_FieldRules_has_sint64(const validate_FieldRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 8); } +UPB_INLINE const validate_SInt64Rules* validate_FieldRules_sint64(const validate_FieldRules *msg) { return UPB_READ_ONEOF(msg, const validate_SInt64Rules*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 8, NULL); } +UPB_INLINE bool validate_FieldRules_has_fixed32(const validate_FieldRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 9); } +UPB_INLINE const validate_Fixed32Rules* validate_FieldRules_fixed32(const validate_FieldRules *msg) { return UPB_READ_ONEOF(msg, const validate_Fixed32Rules*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 9, NULL); } +UPB_INLINE bool validate_FieldRules_has_fixed64(const validate_FieldRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 10); } +UPB_INLINE const validate_Fixed64Rules* validate_FieldRules_fixed64(const validate_FieldRules *msg) { return UPB_READ_ONEOF(msg, const validate_Fixed64Rules*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 10, NULL); } +UPB_INLINE bool validate_FieldRules_has_sfixed32(const validate_FieldRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 11); } +UPB_INLINE const validate_SFixed32Rules* validate_FieldRules_sfixed32(const validate_FieldRules *msg) { return UPB_READ_ONEOF(msg, const validate_SFixed32Rules*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 11, NULL); } +UPB_INLINE bool validate_FieldRules_has_sfixed64(const validate_FieldRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 12); } +UPB_INLINE const validate_SFixed64Rules* validate_FieldRules_sfixed64(const validate_FieldRules *msg) { return UPB_READ_ONEOF(msg, const validate_SFixed64Rules*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 12, NULL); } +UPB_INLINE bool validate_FieldRules_has_bool(const validate_FieldRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 13); } +UPB_INLINE const validate_BoolRules* validate_FieldRules_bool(const validate_FieldRules *msg) { return UPB_READ_ONEOF(msg, const validate_BoolRules*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 13, NULL); } +UPB_INLINE bool validate_FieldRules_has_string(const validate_FieldRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 14); } +UPB_INLINE const validate_StringRules* validate_FieldRules_string(const validate_FieldRules *msg) { return UPB_READ_ONEOF(msg, const validate_StringRules*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 14, NULL); } +UPB_INLINE bool validate_FieldRules_has_bytes(const validate_FieldRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 15); } +UPB_INLINE const validate_BytesRules* validate_FieldRules_bytes(const validate_FieldRules *msg) { return UPB_READ_ONEOF(msg, const validate_BytesRules*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 15, NULL); } +UPB_INLINE bool validate_FieldRules_has_enum(const validate_FieldRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 16); } +UPB_INLINE const validate_EnumRules* validate_FieldRules_enum(const validate_FieldRules *msg) { return UPB_READ_ONEOF(msg, const validate_EnumRules*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 16, NULL); } +UPB_INLINE bool validate_FieldRules_has_message(const validate_FieldRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 17); } +UPB_INLINE const validate_MessageRules* validate_FieldRules_message(const validate_FieldRules *msg) { return UPB_READ_ONEOF(msg, const validate_MessageRules*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 17, NULL); } +UPB_INLINE bool validate_FieldRules_has_repeated(const validate_FieldRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 18); } +UPB_INLINE const validate_RepeatedRules* validate_FieldRules_repeated(const validate_FieldRules *msg) { return UPB_READ_ONEOF(msg, const validate_RepeatedRules*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 18, NULL); } +UPB_INLINE bool validate_FieldRules_has_map(const validate_FieldRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 19); } +UPB_INLINE const validate_MapRules* validate_FieldRules_map(const validate_FieldRules *msg) { return UPB_READ_ONEOF(msg, const validate_MapRules*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 19, NULL); } +UPB_INLINE bool validate_FieldRules_has_any(const validate_FieldRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 20); } +UPB_INLINE const validate_AnyRules* validate_FieldRules_any(const validate_FieldRules *msg) { return UPB_READ_ONEOF(msg, const validate_AnyRules*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 20, NULL); } +UPB_INLINE bool validate_FieldRules_has_duration(const validate_FieldRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 21); } +UPB_INLINE const validate_DurationRules* validate_FieldRules_duration(const validate_FieldRules *msg) { return UPB_READ_ONEOF(msg, const validate_DurationRules*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 21, NULL); } +UPB_INLINE bool validate_FieldRules_has_timestamp(const validate_FieldRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 22); } +UPB_INLINE const validate_TimestampRules* validate_FieldRules_timestamp(const validate_FieldRules *msg) { return UPB_READ_ONEOF(msg, const validate_TimestampRules*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 22, NULL); } + +UPB_INLINE void validate_FieldRules_set_float(validate_FieldRules *msg, validate_FloatRules* value) { + UPB_WRITE_ONEOF(msg, validate_FloatRules*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 1); +} +UPB_INLINE struct validate_FloatRules* validate_FieldRules_mutable_float(validate_FieldRules *msg, upb_arena *arena) { + struct validate_FloatRules* sub = (struct validate_FloatRules*)validate_FieldRules_float(msg); + if (sub == NULL) { + sub = (struct validate_FloatRules*)upb_msg_new(&validate_FloatRules_msginit, arena); + if (!sub) return NULL; + validate_FieldRules_set_float(msg, sub); + } + return sub; +} +UPB_INLINE void validate_FieldRules_set_double(validate_FieldRules *msg, validate_DoubleRules* value) { + UPB_WRITE_ONEOF(msg, validate_DoubleRules*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 2); +} +UPB_INLINE struct validate_DoubleRules* validate_FieldRules_mutable_double(validate_FieldRules *msg, upb_arena *arena) { + struct validate_DoubleRules* sub = (struct validate_DoubleRules*)validate_FieldRules_double(msg); + if (sub == NULL) { + sub = (struct validate_DoubleRules*)upb_msg_new(&validate_DoubleRules_msginit, arena); + if (!sub) return NULL; + validate_FieldRules_set_double(msg, sub); + } + return sub; +} +UPB_INLINE void validate_FieldRules_set_int32(validate_FieldRules *msg, validate_Int32Rules* value) { + UPB_WRITE_ONEOF(msg, validate_Int32Rules*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 3); +} +UPB_INLINE struct validate_Int32Rules* validate_FieldRules_mutable_int32(validate_FieldRules *msg, upb_arena *arena) { + struct validate_Int32Rules* sub = (struct validate_Int32Rules*)validate_FieldRules_int32(msg); + if (sub == NULL) { + sub = (struct validate_Int32Rules*)upb_msg_new(&validate_Int32Rules_msginit, arena); + if (!sub) return NULL; + validate_FieldRules_set_int32(msg, sub); + } + return sub; +} +UPB_INLINE void validate_FieldRules_set_int64(validate_FieldRules *msg, validate_Int64Rules* value) { + UPB_WRITE_ONEOF(msg, validate_Int64Rules*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 4); +} +UPB_INLINE struct validate_Int64Rules* validate_FieldRules_mutable_int64(validate_FieldRules *msg, upb_arena *arena) { + struct validate_Int64Rules* sub = (struct validate_Int64Rules*)validate_FieldRules_int64(msg); + if (sub == NULL) { + sub = (struct validate_Int64Rules*)upb_msg_new(&validate_Int64Rules_msginit, arena); + if (!sub) return NULL; + validate_FieldRules_set_int64(msg, sub); + } + return sub; +} +UPB_INLINE void validate_FieldRules_set_uint32(validate_FieldRules *msg, validate_UInt32Rules* value) { + UPB_WRITE_ONEOF(msg, validate_UInt32Rules*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 5); +} +UPB_INLINE struct validate_UInt32Rules* validate_FieldRules_mutable_uint32(validate_FieldRules *msg, upb_arena *arena) { + struct validate_UInt32Rules* sub = (struct validate_UInt32Rules*)validate_FieldRules_uint32(msg); + if (sub == NULL) { + sub = (struct validate_UInt32Rules*)upb_msg_new(&validate_UInt32Rules_msginit, arena); + if (!sub) return NULL; + validate_FieldRules_set_uint32(msg, sub); + } + return sub; +} +UPB_INLINE void validate_FieldRules_set_uint64(validate_FieldRules *msg, validate_UInt64Rules* value) { + UPB_WRITE_ONEOF(msg, validate_UInt64Rules*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 6); +} +UPB_INLINE struct validate_UInt64Rules* validate_FieldRules_mutable_uint64(validate_FieldRules *msg, upb_arena *arena) { + struct validate_UInt64Rules* sub = (struct validate_UInt64Rules*)validate_FieldRules_uint64(msg); + if (sub == NULL) { + sub = (struct validate_UInt64Rules*)upb_msg_new(&validate_UInt64Rules_msginit, arena); + if (!sub) return NULL; + validate_FieldRules_set_uint64(msg, sub); + } + return sub; +} +UPB_INLINE void validate_FieldRules_set_sint32(validate_FieldRules *msg, validate_SInt32Rules* value) { + UPB_WRITE_ONEOF(msg, validate_SInt32Rules*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 7); +} +UPB_INLINE struct validate_SInt32Rules* validate_FieldRules_mutable_sint32(validate_FieldRules *msg, upb_arena *arena) { + struct validate_SInt32Rules* sub = (struct validate_SInt32Rules*)validate_FieldRules_sint32(msg); + if (sub == NULL) { + sub = (struct validate_SInt32Rules*)upb_msg_new(&validate_SInt32Rules_msginit, arena); + if (!sub) return NULL; + validate_FieldRules_set_sint32(msg, sub); + } + return sub; +} +UPB_INLINE void validate_FieldRules_set_sint64(validate_FieldRules *msg, validate_SInt64Rules* value) { + UPB_WRITE_ONEOF(msg, validate_SInt64Rules*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 8); +} +UPB_INLINE struct validate_SInt64Rules* validate_FieldRules_mutable_sint64(validate_FieldRules *msg, upb_arena *arena) { + struct validate_SInt64Rules* sub = (struct validate_SInt64Rules*)validate_FieldRules_sint64(msg); + if (sub == NULL) { + sub = (struct validate_SInt64Rules*)upb_msg_new(&validate_SInt64Rules_msginit, arena); + if (!sub) return NULL; + validate_FieldRules_set_sint64(msg, sub); + } + return sub; +} +UPB_INLINE void validate_FieldRules_set_fixed32(validate_FieldRules *msg, validate_Fixed32Rules* value) { + UPB_WRITE_ONEOF(msg, validate_Fixed32Rules*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 9); +} +UPB_INLINE struct validate_Fixed32Rules* validate_FieldRules_mutable_fixed32(validate_FieldRules *msg, upb_arena *arena) { + struct validate_Fixed32Rules* sub = (struct validate_Fixed32Rules*)validate_FieldRules_fixed32(msg); + if (sub == NULL) { + sub = (struct validate_Fixed32Rules*)upb_msg_new(&validate_Fixed32Rules_msginit, arena); + if (!sub) return NULL; + validate_FieldRules_set_fixed32(msg, sub); + } + return sub; +} +UPB_INLINE void validate_FieldRules_set_fixed64(validate_FieldRules *msg, validate_Fixed64Rules* value) { + UPB_WRITE_ONEOF(msg, validate_Fixed64Rules*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 10); +} +UPB_INLINE struct validate_Fixed64Rules* validate_FieldRules_mutable_fixed64(validate_FieldRules *msg, upb_arena *arena) { + struct validate_Fixed64Rules* sub = (struct validate_Fixed64Rules*)validate_FieldRules_fixed64(msg); + if (sub == NULL) { + sub = (struct validate_Fixed64Rules*)upb_msg_new(&validate_Fixed64Rules_msginit, arena); + if (!sub) return NULL; + validate_FieldRules_set_fixed64(msg, sub); + } + return sub; +} +UPB_INLINE void validate_FieldRules_set_sfixed32(validate_FieldRules *msg, validate_SFixed32Rules* value) { + UPB_WRITE_ONEOF(msg, validate_SFixed32Rules*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 11); +} +UPB_INLINE struct validate_SFixed32Rules* validate_FieldRules_mutable_sfixed32(validate_FieldRules *msg, upb_arena *arena) { + struct validate_SFixed32Rules* sub = (struct validate_SFixed32Rules*)validate_FieldRules_sfixed32(msg); + if (sub == NULL) { + sub = (struct validate_SFixed32Rules*)upb_msg_new(&validate_SFixed32Rules_msginit, arena); + if (!sub) return NULL; + validate_FieldRules_set_sfixed32(msg, sub); + } + return sub; +} +UPB_INLINE void validate_FieldRules_set_sfixed64(validate_FieldRules *msg, validate_SFixed64Rules* value) { + UPB_WRITE_ONEOF(msg, validate_SFixed64Rules*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 12); +} +UPB_INLINE struct validate_SFixed64Rules* validate_FieldRules_mutable_sfixed64(validate_FieldRules *msg, upb_arena *arena) { + struct validate_SFixed64Rules* sub = (struct validate_SFixed64Rules*)validate_FieldRules_sfixed64(msg); + if (sub == NULL) { + sub = (struct validate_SFixed64Rules*)upb_msg_new(&validate_SFixed64Rules_msginit, arena); + if (!sub) return NULL; + validate_FieldRules_set_sfixed64(msg, sub); + } + return sub; +} +UPB_INLINE void validate_FieldRules_set_bool(validate_FieldRules *msg, validate_BoolRules* value) { + UPB_WRITE_ONEOF(msg, validate_BoolRules*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 13); +} +UPB_INLINE struct validate_BoolRules* validate_FieldRules_mutable_bool(validate_FieldRules *msg, upb_arena *arena) { + struct validate_BoolRules* sub = (struct validate_BoolRules*)validate_FieldRules_bool(msg); + if (sub == NULL) { + sub = (struct validate_BoolRules*)upb_msg_new(&validate_BoolRules_msginit, arena); + if (!sub) return NULL; + validate_FieldRules_set_bool(msg, sub); + } + return sub; +} +UPB_INLINE void validate_FieldRules_set_string(validate_FieldRules *msg, validate_StringRules* value) { + UPB_WRITE_ONEOF(msg, validate_StringRules*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 14); +} +UPB_INLINE struct validate_StringRules* validate_FieldRules_mutable_string(validate_FieldRules *msg, upb_arena *arena) { + struct validate_StringRules* sub = (struct validate_StringRules*)validate_FieldRules_string(msg); + if (sub == NULL) { + sub = (struct validate_StringRules*)upb_msg_new(&validate_StringRules_msginit, arena); + if (!sub) return NULL; + validate_FieldRules_set_string(msg, sub); + } + return sub; +} +UPB_INLINE void validate_FieldRules_set_bytes(validate_FieldRules *msg, validate_BytesRules* value) { + UPB_WRITE_ONEOF(msg, validate_BytesRules*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 15); +} +UPB_INLINE struct validate_BytesRules* validate_FieldRules_mutable_bytes(validate_FieldRules *msg, upb_arena *arena) { + struct validate_BytesRules* sub = (struct validate_BytesRules*)validate_FieldRules_bytes(msg); + if (sub == NULL) { + sub = (struct validate_BytesRules*)upb_msg_new(&validate_BytesRules_msginit, arena); + if (!sub) return NULL; + validate_FieldRules_set_bytes(msg, sub); + } + return sub; +} +UPB_INLINE void validate_FieldRules_set_enum(validate_FieldRules *msg, validate_EnumRules* value) { + UPB_WRITE_ONEOF(msg, validate_EnumRules*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 16); +} +UPB_INLINE struct validate_EnumRules* validate_FieldRules_mutable_enum(validate_FieldRules *msg, upb_arena *arena) { + struct validate_EnumRules* sub = (struct validate_EnumRules*)validate_FieldRules_enum(msg); + if (sub == NULL) { + sub = (struct validate_EnumRules*)upb_msg_new(&validate_EnumRules_msginit, arena); + if (!sub) return NULL; + validate_FieldRules_set_enum(msg, sub); + } + return sub; +} +UPB_INLINE void validate_FieldRules_set_message(validate_FieldRules *msg, validate_MessageRules* value) { + UPB_WRITE_ONEOF(msg, validate_MessageRules*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 17); +} +UPB_INLINE struct validate_MessageRules* validate_FieldRules_mutable_message(validate_FieldRules *msg, upb_arena *arena) { + struct validate_MessageRules* sub = (struct validate_MessageRules*)validate_FieldRules_message(msg); + if (sub == NULL) { + sub = (struct validate_MessageRules*)upb_msg_new(&validate_MessageRules_msginit, arena); + if (!sub) return NULL; + validate_FieldRules_set_message(msg, sub); + } + return sub; +} +UPB_INLINE void validate_FieldRules_set_repeated(validate_FieldRules *msg, validate_RepeatedRules* value) { + UPB_WRITE_ONEOF(msg, validate_RepeatedRules*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 18); +} +UPB_INLINE struct validate_RepeatedRules* validate_FieldRules_mutable_repeated(validate_FieldRules *msg, upb_arena *arena) { + struct validate_RepeatedRules* sub = (struct validate_RepeatedRules*)validate_FieldRules_repeated(msg); + if (sub == NULL) { + sub = (struct validate_RepeatedRules*)upb_msg_new(&validate_RepeatedRules_msginit, arena); + if (!sub) return NULL; + validate_FieldRules_set_repeated(msg, sub); + } + return sub; +} +UPB_INLINE void validate_FieldRules_set_map(validate_FieldRules *msg, validate_MapRules* value) { + UPB_WRITE_ONEOF(msg, validate_MapRules*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 19); +} +UPB_INLINE struct validate_MapRules* validate_FieldRules_mutable_map(validate_FieldRules *msg, upb_arena *arena) { + struct validate_MapRules* sub = (struct validate_MapRules*)validate_FieldRules_map(msg); + if (sub == NULL) { + sub = (struct validate_MapRules*)upb_msg_new(&validate_MapRules_msginit, arena); + if (!sub) return NULL; + validate_FieldRules_set_map(msg, sub); + } + return sub; +} +UPB_INLINE void validate_FieldRules_set_any(validate_FieldRules *msg, validate_AnyRules* value) { + UPB_WRITE_ONEOF(msg, validate_AnyRules*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 20); +} +UPB_INLINE struct validate_AnyRules* validate_FieldRules_mutable_any(validate_FieldRules *msg, upb_arena *arena) { + struct validate_AnyRules* sub = (struct validate_AnyRules*)validate_FieldRules_any(msg); + if (sub == NULL) { + sub = (struct validate_AnyRules*)upb_msg_new(&validate_AnyRules_msginit, arena); + if (!sub) return NULL; + validate_FieldRules_set_any(msg, sub); + } + return sub; +} +UPB_INLINE void validate_FieldRules_set_duration(validate_FieldRules *msg, validate_DurationRules* value) { + UPB_WRITE_ONEOF(msg, validate_DurationRules*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 21); +} +UPB_INLINE struct validate_DurationRules* validate_FieldRules_mutable_duration(validate_FieldRules *msg, upb_arena *arena) { + struct validate_DurationRules* sub = (struct validate_DurationRules*)validate_FieldRules_duration(msg); + if (sub == NULL) { + sub = (struct validate_DurationRules*)upb_msg_new(&validate_DurationRules_msginit, arena); + if (!sub) return NULL; + validate_FieldRules_set_duration(msg, sub); + } + return sub; +} +UPB_INLINE void validate_FieldRules_set_timestamp(validate_FieldRules *msg, validate_TimestampRules* value) { + UPB_WRITE_ONEOF(msg, validate_TimestampRules*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 22); +} +UPB_INLINE struct validate_TimestampRules* validate_FieldRules_mutable_timestamp(validate_FieldRules *msg, upb_arena *arena) { + struct validate_TimestampRules* sub = (struct validate_TimestampRules*)validate_FieldRules_timestamp(msg); + if (sub == NULL) { + sub = (struct validate_TimestampRules*)upb_msg_new(&validate_TimestampRules_msginit, arena); + if (!sub) return NULL; + validate_FieldRules_set_timestamp(msg, sub); + } + return sub; +} + + +/* validate.FloatRules */ + +UPB_INLINE validate_FloatRules *validate_FloatRules_new(upb_arena *arena) { + return (validate_FloatRules *)upb_msg_new(&validate_FloatRules_msginit, arena); +} +UPB_INLINE validate_FloatRules *validate_FloatRules_parsenew(upb_strview buf, upb_arena *arena) { + validate_FloatRules *ret = validate_FloatRules_new(arena); + return (ret && upb_decode(buf, ret, &validate_FloatRules_msginit)) ? ret : NULL; +} +UPB_INLINE char *validate_FloatRules_serialize(const validate_FloatRules *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &validate_FloatRules_msginit, arena, len); +} + +UPB_INLINE bool validate_FloatRules_has_const(const validate_FloatRules *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE float validate_FloatRules_const(const validate_FloatRules *msg) { return UPB_FIELD_AT(msg, float, UPB_SIZE(4, 4)); } +UPB_INLINE bool validate_FloatRules_has_lt(const validate_FloatRules *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE float validate_FloatRules_lt(const validate_FloatRules *msg) { return UPB_FIELD_AT(msg, float, UPB_SIZE(8, 8)); } +UPB_INLINE bool validate_FloatRules_has_lte(const validate_FloatRules *msg) { return _upb_has_field(msg, 3); } +UPB_INLINE float validate_FloatRules_lte(const validate_FloatRules *msg) { return UPB_FIELD_AT(msg, float, UPB_SIZE(12, 12)); } +UPB_INLINE bool validate_FloatRules_has_gt(const validate_FloatRules *msg) { return _upb_has_field(msg, 4); } +UPB_INLINE float validate_FloatRules_gt(const validate_FloatRules *msg) { return UPB_FIELD_AT(msg, float, UPB_SIZE(16, 16)); } +UPB_INLINE bool validate_FloatRules_has_gte(const validate_FloatRules *msg) { return _upb_has_field(msg, 5); } +UPB_INLINE float validate_FloatRules_gte(const validate_FloatRules *msg) { return UPB_FIELD_AT(msg, float, UPB_SIZE(20, 20)); } +UPB_INLINE float const* validate_FloatRules_in(const validate_FloatRules *msg, size_t *len) { return (float const*)_upb_array_accessor(msg, UPB_SIZE(24, 24), len); } +UPB_INLINE float const* validate_FloatRules_not_in(const validate_FloatRules *msg, size_t *len) { return (float const*)_upb_array_accessor(msg, UPB_SIZE(28, 32), len); } + +UPB_INLINE void validate_FloatRules_set_const(validate_FloatRules *msg, float value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, float, UPB_SIZE(4, 4)) = value; +} +UPB_INLINE void validate_FloatRules_set_lt(validate_FloatRules *msg, float value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, float, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE void validate_FloatRules_set_lte(validate_FloatRules *msg, float value) { + _upb_sethas(msg, 3); + UPB_FIELD_AT(msg, float, UPB_SIZE(12, 12)) = value; +} +UPB_INLINE void validate_FloatRules_set_gt(validate_FloatRules *msg, float value) { + _upb_sethas(msg, 4); + UPB_FIELD_AT(msg, float, UPB_SIZE(16, 16)) = value; +} +UPB_INLINE void validate_FloatRules_set_gte(validate_FloatRules *msg, float value) { + _upb_sethas(msg, 5); + UPB_FIELD_AT(msg, float, UPB_SIZE(20, 20)) = value; +} +UPB_INLINE float* validate_FloatRules_mutable_in(validate_FloatRules *msg, size_t *len) { + return (float*)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 24), len); +} +UPB_INLINE float* validate_FloatRules_resize_in(validate_FloatRules *msg, size_t len, upb_arena *arena) { + return (float*)_upb_array_resize_accessor(msg, UPB_SIZE(24, 24), len, UPB_SIZE(4, 4), UPB_TYPE_FLOAT, arena); +} +UPB_INLINE bool validate_FloatRules_add_in(validate_FloatRules *msg, float val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(24, 24), UPB_SIZE(4, 4), UPB_TYPE_FLOAT, &val, arena); +} +UPB_INLINE float* validate_FloatRules_mutable_not_in(validate_FloatRules *msg, size_t *len) { + return (float*)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 32), len); +} +UPB_INLINE float* validate_FloatRules_resize_not_in(validate_FloatRules *msg, size_t len, upb_arena *arena) { + return (float*)_upb_array_resize_accessor(msg, UPB_SIZE(28, 32), len, UPB_SIZE(4, 4), UPB_TYPE_FLOAT, arena); +} +UPB_INLINE bool validate_FloatRules_add_not_in(validate_FloatRules *msg, float val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(28, 32), UPB_SIZE(4, 4), UPB_TYPE_FLOAT, &val, arena); +} + + +/* validate.DoubleRules */ + +UPB_INLINE validate_DoubleRules *validate_DoubleRules_new(upb_arena *arena) { + return (validate_DoubleRules *)upb_msg_new(&validate_DoubleRules_msginit, arena); +} +UPB_INLINE validate_DoubleRules *validate_DoubleRules_parsenew(upb_strview buf, upb_arena *arena) { + validate_DoubleRules *ret = validate_DoubleRules_new(arena); + return (ret && upb_decode(buf, ret, &validate_DoubleRules_msginit)) ? ret : NULL; +} +UPB_INLINE char *validate_DoubleRules_serialize(const validate_DoubleRules *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &validate_DoubleRules_msginit, arena, len); +} + +UPB_INLINE bool validate_DoubleRules_has_const(const validate_DoubleRules *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE double validate_DoubleRules_const(const validate_DoubleRules *msg) { return UPB_FIELD_AT(msg, double, UPB_SIZE(8, 8)); } +UPB_INLINE bool validate_DoubleRules_has_lt(const validate_DoubleRules *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE double validate_DoubleRules_lt(const validate_DoubleRules *msg) { return UPB_FIELD_AT(msg, double, UPB_SIZE(16, 16)); } +UPB_INLINE bool validate_DoubleRules_has_lte(const validate_DoubleRules *msg) { return _upb_has_field(msg, 3); } +UPB_INLINE double validate_DoubleRules_lte(const validate_DoubleRules *msg) { return UPB_FIELD_AT(msg, double, UPB_SIZE(24, 24)); } +UPB_INLINE bool validate_DoubleRules_has_gt(const validate_DoubleRules *msg) { return _upb_has_field(msg, 4); } +UPB_INLINE double validate_DoubleRules_gt(const validate_DoubleRules *msg) { return UPB_FIELD_AT(msg, double, UPB_SIZE(32, 32)); } +UPB_INLINE bool validate_DoubleRules_has_gte(const validate_DoubleRules *msg) { return _upb_has_field(msg, 5); } +UPB_INLINE double validate_DoubleRules_gte(const validate_DoubleRules *msg) { return UPB_FIELD_AT(msg, double, UPB_SIZE(40, 40)); } +UPB_INLINE double const* validate_DoubleRules_in(const validate_DoubleRules *msg, size_t *len) { return (double const*)_upb_array_accessor(msg, UPB_SIZE(48, 48), len); } +UPB_INLINE double const* validate_DoubleRules_not_in(const validate_DoubleRules *msg, size_t *len) { return (double const*)_upb_array_accessor(msg, UPB_SIZE(52, 56), len); } + +UPB_INLINE void validate_DoubleRules_set_const(validate_DoubleRules *msg, double value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, double, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE void validate_DoubleRules_set_lt(validate_DoubleRules *msg, double value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, double, UPB_SIZE(16, 16)) = value; +} +UPB_INLINE void validate_DoubleRules_set_lte(validate_DoubleRules *msg, double value) { + _upb_sethas(msg, 3); + UPB_FIELD_AT(msg, double, UPB_SIZE(24, 24)) = value; +} +UPB_INLINE void validate_DoubleRules_set_gt(validate_DoubleRules *msg, double value) { + _upb_sethas(msg, 4); + UPB_FIELD_AT(msg, double, UPB_SIZE(32, 32)) = value; +} +UPB_INLINE void validate_DoubleRules_set_gte(validate_DoubleRules *msg, double value) { + _upb_sethas(msg, 5); + UPB_FIELD_AT(msg, double, UPB_SIZE(40, 40)) = value; +} +UPB_INLINE double* validate_DoubleRules_mutable_in(validate_DoubleRules *msg, size_t *len) { + return (double*)_upb_array_mutable_accessor(msg, UPB_SIZE(48, 48), len); +} +UPB_INLINE double* validate_DoubleRules_resize_in(validate_DoubleRules *msg, size_t len, upb_arena *arena) { + return (double*)_upb_array_resize_accessor(msg, UPB_SIZE(48, 48), len, UPB_SIZE(8, 8), UPB_TYPE_DOUBLE, arena); +} +UPB_INLINE bool validate_DoubleRules_add_in(validate_DoubleRules *msg, double val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(48, 48), UPB_SIZE(8, 8), UPB_TYPE_DOUBLE, &val, arena); +} +UPB_INLINE double* validate_DoubleRules_mutable_not_in(validate_DoubleRules *msg, size_t *len) { + return (double*)_upb_array_mutable_accessor(msg, UPB_SIZE(52, 56), len); +} +UPB_INLINE double* validate_DoubleRules_resize_not_in(validate_DoubleRules *msg, size_t len, upb_arena *arena) { + return (double*)_upb_array_resize_accessor(msg, UPB_SIZE(52, 56), len, UPB_SIZE(8, 8), UPB_TYPE_DOUBLE, arena); +} +UPB_INLINE bool validate_DoubleRules_add_not_in(validate_DoubleRules *msg, double val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(52, 56), UPB_SIZE(8, 8), UPB_TYPE_DOUBLE, &val, arena); +} + + +/* validate.Int32Rules */ + +UPB_INLINE validate_Int32Rules *validate_Int32Rules_new(upb_arena *arena) { + return (validate_Int32Rules *)upb_msg_new(&validate_Int32Rules_msginit, arena); +} +UPB_INLINE validate_Int32Rules *validate_Int32Rules_parsenew(upb_strview buf, upb_arena *arena) { + validate_Int32Rules *ret = validate_Int32Rules_new(arena); + return (ret && upb_decode(buf, ret, &validate_Int32Rules_msginit)) ? ret : NULL; +} +UPB_INLINE char *validate_Int32Rules_serialize(const validate_Int32Rules *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &validate_Int32Rules_msginit, arena, len); +} + +UPB_INLINE bool validate_Int32Rules_has_const(const validate_Int32Rules *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE int32_t validate_Int32Rules_const(const validate_Int32Rules *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)); } +UPB_INLINE bool validate_Int32Rules_has_lt(const validate_Int32Rules *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE int32_t validate_Int32Rules_lt(const validate_Int32Rules *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); } +UPB_INLINE bool validate_Int32Rules_has_lte(const validate_Int32Rules *msg) { return _upb_has_field(msg, 3); } +UPB_INLINE int32_t validate_Int32Rules_lte(const validate_Int32Rules *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(12, 12)); } +UPB_INLINE bool validate_Int32Rules_has_gt(const validate_Int32Rules *msg) { return _upb_has_field(msg, 4); } +UPB_INLINE int32_t validate_Int32Rules_gt(const validate_Int32Rules *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(16, 16)); } +UPB_INLINE bool validate_Int32Rules_has_gte(const validate_Int32Rules *msg) { return _upb_has_field(msg, 5); } +UPB_INLINE int32_t validate_Int32Rules_gte(const validate_Int32Rules *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(20, 20)); } +UPB_INLINE int32_t const* validate_Int32Rules_in(const validate_Int32Rules *msg, size_t *len) { return (int32_t const*)_upb_array_accessor(msg, UPB_SIZE(24, 24), len); } +UPB_INLINE int32_t const* validate_Int32Rules_not_in(const validate_Int32Rules *msg, size_t *len) { return (int32_t const*)_upb_array_accessor(msg, UPB_SIZE(28, 32), len); } + +UPB_INLINE void validate_Int32Rules_set_const(validate_Int32Rules *msg, int32_t value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)) = value; +} +UPB_INLINE void validate_Int32Rules_set_lt(validate_Int32Rules *msg, int32_t value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE void validate_Int32Rules_set_lte(validate_Int32Rules *msg, int32_t value) { + _upb_sethas(msg, 3); + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(12, 12)) = value; +} +UPB_INLINE void validate_Int32Rules_set_gt(validate_Int32Rules *msg, int32_t value) { + _upb_sethas(msg, 4); + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(16, 16)) = value; +} +UPB_INLINE void validate_Int32Rules_set_gte(validate_Int32Rules *msg, int32_t value) { + _upb_sethas(msg, 5); + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(20, 20)) = value; +} +UPB_INLINE int32_t* validate_Int32Rules_mutable_in(validate_Int32Rules *msg, size_t *len) { + return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 24), len); +} +UPB_INLINE int32_t* validate_Int32Rules_resize_in(validate_Int32Rules *msg, size_t len, upb_arena *arena) { + return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(24, 24), len, UPB_SIZE(4, 4), UPB_TYPE_INT32, arena); +} +UPB_INLINE bool validate_Int32Rules_add_in(validate_Int32Rules *msg, int32_t val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(24, 24), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val, arena); +} +UPB_INLINE int32_t* validate_Int32Rules_mutable_not_in(validate_Int32Rules *msg, size_t *len) { + return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 32), len); +} +UPB_INLINE int32_t* validate_Int32Rules_resize_not_in(validate_Int32Rules *msg, size_t len, upb_arena *arena) { + return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(28, 32), len, UPB_SIZE(4, 4), UPB_TYPE_INT32, arena); +} +UPB_INLINE bool validate_Int32Rules_add_not_in(validate_Int32Rules *msg, int32_t val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(28, 32), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val, arena); +} + + +/* validate.Int64Rules */ + +UPB_INLINE validate_Int64Rules *validate_Int64Rules_new(upb_arena *arena) { + return (validate_Int64Rules *)upb_msg_new(&validate_Int64Rules_msginit, arena); +} +UPB_INLINE validate_Int64Rules *validate_Int64Rules_parsenew(upb_strview buf, upb_arena *arena) { + validate_Int64Rules *ret = validate_Int64Rules_new(arena); + return (ret && upb_decode(buf, ret, &validate_Int64Rules_msginit)) ? ret : NULL; +} +UPB_INLINE char *validate_Int64Rules_serialize(const validate_Int64Rules *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &validate_Int64Rules_msginit, arena, len); +} + +UPB_INLINE bool validate_Int64Rules_has_const(const validate_Int64Rules *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE int64_t validate_Int64Rules_const(const validate_Int64Rules *msg) { return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(8, 8)); } +UPB_INLINE bool validate_Int64Rules_has_lt(const validate_Int64Rules *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE int64_t validate_Int64Rules_lt(const validate_Int64Rules *msg) { return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(16, 16)); } +UPB_INLINE bool validate_Int64Rules_has_lte(const validate_Int64Rules *msg) { return _upb_has_field(msg, 3); } +UPB_INLINE int64_t validate_Int64Rules_lte(const validate_Int64Rules *msg) { return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(24, 24)); } +UPB_INLINE bool validate_Int64Rules_has_gt(const validate_Int64Rules *msg) { return _upb_has_field(msg, 4); } +UPB_INLINE int64_t validate_Int64Rules_gt(const validate_Int64Rules *msg) { return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(32, 32)); } +UPB_INLINE bool validate_Int64Rules_has_gte(const validate_Int64Rules *msg) { return _upb_has_field(msg, 5); } +UPB_INLINE int64_t validate_Int64Rules_gte(const validate_Int64Rules *msg) { return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(40, 40)); } +UPB_INLINE int64_t const* validate_Int64Rules_in(const validate_Int64Rules *msg, size_t *len) { return (int64_t const*)_upb_array_accessor(msg, UPB_SIZE(48, 48), len); } +UPB_INLINE int64_t const* validate_Int64Rules_not_in(const validate_Int64Rules *msg, size_t *len) { return (int64_t const*)_upb_array_accessor(msg, UPB_SIZE(52, 56), len); } + +UPB_INLINE void validate_Int64Rules_set_const(validate_Int64Rules *msg, int64_t value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, int64_t, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE void validate_Int64Rules_set_lt(validate_Int64Rules *msg, int64_t value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, int64_t, UPB_SIZE(16, 16)) = value; +} +UPB_INLINE void validate_Int64Rules_set_lte(validate_Int64Rules *msg, int64_t value) { + _upb_sethas(msg, 3); + UPB_FIELD_AT(msg, int64_t, UPB_SIZE(24, 24)) = value; +} +UPB_INLINE void validate_Int64Rules_set_gt(validate_Int64Rules *msg, int64_t value) { + _upb_sethas(msg, 4); + UPB_FIELD_AT(msg, int64_t, UPB_SIZE(32, 32)) = value; +} +UPB_INLINE void validate_Int64Rules_set_gte(validate_Int64Rules *msg, int64_t value) { + _upb_sethas(msg, 5); + UPB_FIELD_AT(msg, int64_t, UPB_SIZE(40, 40)) = value; +} +UPB_INLINE int64_t* validate_Int64Rules_mutable_in(validate_Int64Rules *msg, size_t *len) { + return (int64_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(48, 48), len); +} +UPB_INLINE int64_t* validate_Int64Rules_resize_in(validate_Int64Rules *msg, size_t len, upb_arena *arena) { + return (int64_t*)_upb_array_resize_accessor(msg, UPB_SIZE(48, 48), len, UPB_SIZE(8, 8), UPB_TYPE_INT64, arena); +} +UPB_INLINE bool validate_Int64Rules_add_in(validate_Int64Rules *msg, int64_t val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(48, 48), UPB_SIZE(8, 8), UPB_TYPE_INT64, &val, arena); +} +UPB_INLINE int64_t* validate_Int64Rules_mutable_not_in(validate_Int64Rules *msg, size_t *len) { + return (int64_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(52, 56), len); +} +UPB_INLINE int64_t* validate_Int64Rules_resize_not_in(validate_Int64Rules *msg, size_t len, upb_arena *arena) { + return (int64_t*)_upb_array_resize_accessor(msg, UPB_SIZE(52, 56), len, UPB_SIZE(8, 8), UPB_TYPE_INT64, arena); +} +UPB_INLINE bool validate_Int64Rules_add_not_in(validate_Int64Rules *msg, int64_t val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(52, 56), UPB_SIZE(8, 8), UPB_TYPE_INT64, &val, arena); +} + + +/* validate.UInt32Rules */ + +UPB_INLINE validate_UInt32Rules *validate_UInt32Rules_new(upb_arena *arena) { + return (validate_UInt32Rules *)upb_msg_new(&validate_UInt32Rules_msginit, arena); +} +UPB_INLINE validate_UInt32Rules *validate_UInt32Rules_parsenew(upb_strview buf, upb_arena *arena) { + validate_UInt32Rules *ret = validate_UInt32Rules_new(arena); + return (ret && upb_decode(buf, ret, &validate_UInt32Rules_msginit)) ? ret : NULL; +} +UPB_INLINE char *validate_UInt32Rules_serialize(const validate_UInt32Rules *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &validate_UInt32Rules_msginit, arena, len); +} + +UPB_INLINE bool validate_UInt32Rules_has_const(const validate_UInt32Rules *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE uint32_t validate_UInt32Rules_const(const validate_UInt32Rules *msg) { return UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(4, 4)); } +UPB_INLINE bool validate_UInt32Rules_has_lt(const validate_UInt32Rules *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE uint32_t validate_UInt32Rules_lt(const validate_UInt32Rules *msg) { return UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(8, 8)); } +UPB_INLINE bool validate_UInt32Rules_has_lte(const validate_UInt32Rules *msg) { return _upb_has_field(msg, 3); } +UPB_INLINE uint32_t validate_UInt32Rules_lte(const validate_UInt32Rules *msg) { return UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(12, 12)); } +UPB_INLINE bool validate_UInt32Rules_has_gt(const validate_UInt32Rules *msg) { return _upb_has_field(msg, 4); } +UPB_INLINE uint32_t validate_UInt32Rules_gt(const validate_UInt32Rules *msg) { return UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(16, 16)); } +UPB_INLINE bool validate_UInt32Rules_has_gte(const validate_UInt32Rules *msg) { return _upb_has_field(msg, 5); } +UPB_INLINE uint32_t validate_UInt32Rules_gte(const validate_UInt32Rules *msg) { return UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(20, 20)); } +UPB_INLINE uint32_t const* validate_UInt32Rules_in(const validate_UInt32Rules *msg, size_t *len) { return (uint32_t const*)_upb_array_accessor(msg, UPB_SIZE(24, 24), len); } +UPB_INLINE uint32_t const* validate_UInt32Rules_not_in(const validate_UInt32Rules *msg, size_t *len) { return (uint32_t const*)_upb_array_accessor(msg, UPB_SIZE(28, 32), len); } + +UPB_INLINE void validate_UInt32Rules_set_const(validate_UInt32Rules *msg, uint32_t value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(4, 4)) = value; +} +UPB_INLINE void validate_UInt32Rules_set_lt(validate_UInt32Rules *msg, uint32_t value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE void validate_UInt32Rules_set_lte(validate_UInt32Rules *msg, uint32_t value) { + _upb_sethas(msg, 3); + UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(12, 12)) = value; +} +UPB_INLINE void validate_UInt32Rules_set_gt(validate_UInt32Rules *msg, uint32_t value) { + _upb_sethas(msg, 4); + UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(16, 16)) = value; +} +UPB_INLINE void validate_UInt32Rules_set_gte(validate_UInt32Rules *msg, uint32_t value) { + _upb_sethas(msg, 5); + UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(20, 20)) = value; +} +UPB_INLINE uint32_t* validate_UInt32Rules_mutable_in(validate_UInt32Rules *msg, size_t *len) { + return (uint32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 24), len); +} +UPB_INLINE uint32_t* validate_UInt32Rules_resize_in(validate_UInt32Rules *msg, size_t len, upb_arena *arena) { + return (uint32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(24, 24), len, UPB_SIZE(4, 4), UPB_TYPE_UINT32, arena); +} +UPB_INLINE bool validate_UInt32Rules_add_in(validate_UInt32Rules *msg, uint32_t val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(24, 24), UPB_SIZE(4, 4), UPB_TYPE_UINT32, &val, arena); +} +UPB_INLINE uint32_t* validate_UInt32Rules_mutable_not_in(validate_UInt32Rules *msg, size_t *len) { + return (uint32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 32), len); +} +UPB_INLINE uint32_t* validate_UInt32Rules_resize_not_in(validate_UInt32Rules *msg, size_t len, upb_arena *arena) { + return (uint32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(28, 32), len, UPB_SIZE(4, 4), UPB_TYPE_UINT32, arena); +} +UPB_INLINE bool validate_UInt32Rules_add_not_in(validate_UInt32Rules *msg, uint32_t val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(28, 32), UPB_SIZE(4, 4), UPB_TYPE_UINT32, &val, arena); +} + + +/* validate.UInt64Rules */ + +UPB_INLINE validate_UInt64Rules *validate_UInt64Rules_new(upb_arena *arena) { + return (validate_UInt64Rules *)upb_msg_new(&validate_UInt64Rules_msginit, arena); +} +UPB_INLINE validate_UInt64Rules *validate_UInt64Rules_parsenew(upb_strview buf, upb_arena *arena) { + validate_UInt64Rules *ret = validate_UInt64Rules_new(arena); + return (ret && upb_decode(buf, ret, &validate_UInt64Rules_msginit)) ? ret : NULL; +} +UPB_INLINE char *validate_UInt64Rules_serialize(const validate_UInt64Rules *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &validate_UInt64Rules_msginit, arena, len); +} + +UPB_INLINE bool validate_UInt64Rules_has_const(const validate_UInt64Rules *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE uint64_t validate_UInt64Rules_const(const validate_UInt64Rules *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(8, 8)); } +UPB_INLINE bool validate_UInt64Rules_has_lt(const validate_UInt64Rules *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE uint64_t validate_UInt64Rules_lt(const validate_UInt64Rules *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(16, 16)); } +UPB_INLINE bool validate_UInt64Rules_has_lte(const validate_UInt64Rules *msg) { return _upb_has_field(msg, 3); } +UPB_INLINE uint64_t validate_UInt64Rules_lte(const validate_UInt64Rules *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(24, 24)); } +UPB_INLINE bool validate_UInt64Rules_has_gt(const validate_UInt64Rules *msg) { return _upb_has_field(msg, 4); } +UPB_INLINE uint64_t validate_UInt64Rules_gt(const validate_UInt64Rules *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(32, 32)); } +UPB_INLINE bool validate_UInt64Rules_has_gte(const validate_UInt64Rules *msg) { return _upb_has_field(msg, 5); } +UPB_INLINE uint64_t validate_UInt64Rules_gte(const validate_UInt64Rules *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(40, 40)); } +UPB_INLINE uint64_t const* validate_UInt64Rules_in(const validate_UInt64Rules *msg, size_t *len) { return (uint64_t const*)_upb_array_accessor(msg, UPB_SIZE(48, 48), len); } +UPB_INLINE uint64_t const* validate_UInt64Rules_not_in(const validate_UInt64Rules *msg, size_t *len) { return (uint64_t const*)_upb_array_accessor(msg, UPB_SIZE(52, 56), len); } + +UPB_INLINE void validate_UInt64Rules_set_const(validate_UInt64Rules *msg, uint64_t value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE void validate_UInt64Rules_set_lt(validate_UInt64Rules *msg, uint64_t value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(16, 16)) = value; +} +UPB_INLINE void validate_UInt64Rules_set_lte(validate_UInt64Rules *msg, uint64_t value) { + _upb_sethas(msg, 3); + UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(24, 24)) = value; +} +UPB_INLINE void validate_UInt64Rules_set_gt(validate_UInt64Rules *msg, uint64_t value) { + _upb_sethas(msg, 4); + UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(32, 32)) = value; +} +UPB_INLINE void validate_UInt64Rules_set_gte(validate_UInt64Rules *msg, uint64_t value) { + _upb_sethas(msg, 5); + UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(40, 40)) = value; +} +UPB_INLINE uint64_t* validate_UInt64Rules_mutable_in(validate_UInt64Rules *msg, size_t *len) { + return (uint64_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(48, 48), len); +} +UPB_INLINE uint64_t* validate_UInt64Rules_resize_in(validate_UInt64Rules *msg, size_t len, upb_arena *arena) { + return (uint64_t*)_upb_array_resize_accessor(msg, UPB_SIZE(48, 48), len, UPB_SIZE(8, 8), UPB_TYPE_UINT64, arena); +} +UPB_INLINE bool validate_UInt64Rules_add_in(validate_UInt64Rules *msg, uint64_t val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(48, 48), UPB_SIZE(8, 8), UPB_TYPE_UINT64, &val, arena); +} +UPB_INLINE uint64_t* validate_UInt64Rules_mutable_not_in(validate_UInt64Rules *msg, size_t *len) { + return (uint64_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(52, 56), len); +} +UPB_INLINE uint64_t* validate_UInt64Rules_resize_not_in(validate_UInt64Rules *msg, size_t len, upb_arena *arena) { + return (uint64_t*)_upb_array_resize_accessor(msg, UPB_SIZE(52, 56), len, UPB_SIZE(8, 8), UPB_TYPE_UINT64, arena); +} +UPB_INLINE bool validate_UInt64Rules_add_not_in(validate_UInt64Rules *msg, uint64_t val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(52, 56), UPB_SIZE(8, 8), UPB_TYPE_UINT64, &val, arena); +} + + +/* validate.SInt32Rules */ + +UPB_INLINE validate_SInt32Rules *validate_SInt32Rules_new(upb_arena *arena) { + return (validate_SInt32Rules *)upb_msg_new(&validate_SInt32Rules_msginit, arena); +} +UPB_INLINE validate_SInt32Rules *validate_SInt32Rules_parsenew(upb_strview buf, upb_arena *arena) { + validate_SInt32Rules *ret = validate_SInt32Rules_new(arena); + return (ret && upb_decode(buf, ret, &validate_SInt32Rules_msginit)) ? ret : NULL; +} +UPB_INLINE char *validate_SInt32Rules_serialize(const validate_SInt32Rules *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &validate_SInt32Rules_msginit, arena, len); +} + +UPB_INLINE bool validate_SInt32Rules_has_const(const validate_SInt32Rules *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE int32_t validate_SInt32Rules_const(const validate_SInt32Rules *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)); } +UPB_INLINE bool validate_SInt32Rules_has_lt(const validate_SInt32Rules *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE int32_t validate_SInt32Rules_lt(const validate_SInt32Rules *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); } +UPB_INLINE bool validate_SInt32Rules_has_lte(const validate_SInt32Rules *msg) { return _upb_has_field(msg, 3); } +UPB_INLINE int32_t validate_SInt32Rules_lte(const validate_SInt32Rules *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(12, 12)); } +UPB_INLINE bool validate_SInt32Rules_has_gt(const validate_SInt32Rules *msg) { return _upb_has_field(msg, 4); } +UPB_INLINE int32_t validate_SInt32Rules_gt(const validate_SInt32Rules *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(16, 16)); } +UPB_INLINE bool validate_SInt32Rules_has_gte(const validate_SInt32Rules *msg) { return _upb_has_field(msg, 5); } +UPB_INLINE int32_t validate_SInt32Rules_gte(const validate_SInt32Rules *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(20, 20)); } +UPB_INLINE int32_t const* validate_SInt32Rules_in(const validate_SInt32Rules *msg, size_t *len) { return (int32_t const*)_upb_array_accessor(msg, UPB_SIZE(24, 24), len); } +UPB_INLINE int32_t const* validate_SInt32Rules_not_in(const validate_SInt32Rules *msg, size_t *len) { return (int32_t const*)_upb_array_accessor(msg, UPB_SIZE(28, 32), len); } + +UPB_INLINE void validate_SInt32Rules_set_const(validate_SInt32Rules *msg, int32_t value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)) = value; +} +UPB_INLINE void validate_SInt32Rules_set_lt(validate_SInt32Rules *msg, int32_t value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE void validate_SInt32Rules_set_lte(validate_SInt32Rules *msg, int32_t value) { + _upb_sethas(msg, 3); + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(12, 12)) = value; +} +UPB_INLINE void validate_SInt32Rules_set_gt(validate_SInt32Rules *msg, int32_t value) { + _upb_sethas(msg, 4); + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(16, 16)) = value; +} +UPB_INLINE void validate_SInt32Rules_set_gte(validate_SInt32Rules *msg, int32_t value) { + _upb_sethas(msg, 5); + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(20, 20)) = value; +} +UPB_INLINE int32_t* validate_SInt32Rules_mutable_in(validate_SInt32Rules *msg, size_t *len) { + return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 24), len); +} +UPB_INLINE int32_t* validate_SInt32Rules_resize_in(validate_SInt32Rules *msg, size_t len, upb_arena *arena) { + return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(24, 24), len, UPB_SIZE(4, 4), UPB_TYPE_INT32, arena); +} +UPB_INLINE bool validate_SInt32Rules_add_in(validate_SInt32Rules *msg, int32_t val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(24, 24), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val, arena); +} +UPB_INLINE int32_t* validate_SInt32Rules_mutable_not_in(validate_SInt32Rules *msg, size_t *len) { + return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 32), len); +} +UPB_INLINE int32_t* validate_SInt32Rules_resize_not_in(validate_SInt32Rules *msg, size_t len, upb_arena *arena) { + return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(28, 32), len, UPB_SIZE(4, 4), UPB_TYPE_INT32, arena); +} +UPB_INLINE bool validate_SInt32Rules_add_not_in(validate_SInt32Rules *msg, int32_t val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(28, 32), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val, arena); +} + + +/* validate.SInt64Rules */ + +UPB_INLINE validate_SInt64Rules *validate_SInt64Rules_new(upb_arena *arena) { + return (validate_SInt64Rules *)upb_msg_new(&validate_SInt64Rules_msginit, arena); +} +UPB_INLINE validate_SInt64Rules *validate_SInt64Rules_parsenew(upb_strview buf, upb_arena *arena) { + validate_SInt64Rules *ret = validate_SInt64Rules_new(arena); + return (ret && upb_decode(buf, ret, &validate_SInt64Rules_msginit)) ? ret : NULL; +} +UPB_INLINE char *validate_SInt64Rules_serialize(const validate_SInt64Rules *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &validate_SInt64Rules_msginit, arena, len); +} + +UPB_INLINE bool validate_SInt64Rules_has_const(const validate_SInt64Rules *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE int64_t validate_SInt64Rules_const(const validate_SInt64Rules *msg) { return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(8, 8)); } +UPB_INLINE bool validate_SInt64Rules_has_lt(const validate_SInt64Rules *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE int64_t validate_SInt64Rules_lt(const validate_SInt64Rules *msg) { return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(16, 16)); } +UPB_INLINE bool validate_SInt64Rules_has_lte(const validate_SInt64Rules *msg) { return _upb_has_field(msg, 3); } +UPB_INLINE int64_t validate_SInt64Rules_lte(const validate_SInt64Rules *msg) { return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(24, 24)); } +UPB_INLINE bool validate_SInt64Rules_has_gt(const validate_SInt64Rules *msg) { return _upb_has_field(msg, 4); } +UPB_INLINE int64_t validate_SInt64Rules_gt(const validate_SInt64Rules *msg) { return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(32, 32)); } +UPB_INLINE bool validate_SInt64Rules_has_gte(const validate_SInt64Rules *msg) { return _upb_has_field(msg, 5); } +UPB_INLINE int64_t validate_SInt64Rules_gte(const validate_SInt64Rules *msg) { return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(40, 40)); } +UPB_INLINE int64_t const* validate_SInt64Rules_in(const validate_SInt64Rules *msg, size_t *len) { return (int64_t const*)_upb_array_accessor(msg, UPB_SIZE(48, 48), len); } +UPB_INLINE int64_t const* validate_SInt64Rules_not_in(const validate_SInt64Rules *msg, size_t *len) { return (int64_t const*)_upb_array_accessor(msg, UPB_SIZE(52, 56), len); } + +UPB_INLINE void validate_SInt64Rules_set_const(validate_SInt64Rules *msg, int64_t value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, int64_t, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE void validate_SInt64Rules_set_lt(validate_SInt64Rules *msg, int64_t value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, int64_t, UPB_SIZE(16, 16)) = value; +} +UPB_INLINE void validate_SInt64Rules_set_lte(validate_SInt64Rules *msg, int64_t value) { + _upb_sethas(msg, 3); + UPB_FIELD_AT(msg, int64_t, UPB_SIZE(24, 24)) = value; +} +UPB_INLINE void validate_SInt64Rules_set_gt(validate_SInt64Rules *msg, int64_t value) { + _upb_sethas(msg, 4); + UPB_FIELD_AT(msg, int64_t, UPB_SIZE(32, 32)) = value; +} +UPB_INLINE void validate_SInt64Rules_set_gte(validate_SInt64Rules *msg, int64_t value) { + _upb_sethas(msg, 5); + UPB_FIELD_AT(msg, int64_t, UPB_SIZE(40, 40)) = value; +} +UPB_INLINE int64_t* validate_SInt64Rules_mutable_in(validate_SInt64Rules *msg, size_t *len) { + return (int64_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(48, 48), len); +} +UPB_INLINE int64_t* validate_SInt64Rules_resize_in(validate_SInt64Rules *msg, size_t len, upb_arena *arena) { + return (int64_t*)_upb_array_resize_accessor(msg, UPB_SIZE(48, 48), len, UPB_SIZE(8, 8), UPB_TYPE_INT64, arena); +} +UPB_INLINE bool validate_SInt64Rules_add_in(validate_SInt64Rules *msg, int64_t val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(48, 48), UPB_SIZE(8, 8), UPB_TYPE_INT64, &val, arena); +} +UPB_INLINE int64_t* validate_SInt64Rules_mutable_not_in(validate_SInt64Rules *msg, size_t *len) { + return (int64_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(52, 56), len); +} +UPB_INLINE int64_t* validate_SInt64Rules_resize_not_in(validate_SInt64Rules *msg, size_t len, upb_arena *arena) { + return (int64_t*)_upb_array_resize_accessor(msg, UPB_SIZE(52, 56), len, UPB_SIZE(8, 8), UPB_TYPE_INT64, arena); +} +UPB_INLINE bool validate_SInt64Rules_add_not_in(validate_SInt64Rules *msg, int64_t val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(52, 56), UPB_SIZE(8, 8), UPB_TYPE_INT64, &val, arena); +} + + +/* validate.Fixed32Rules */ + +UPB_INLINE validate_Fixed32Rules *validate_Fixed32Rules_new(upb_arena *arena) { + return (validate_Fixed32Rules *)upb_msg_new(&validate_Fixed32Rules_msginit, arena); +} +UPB_INLINE validate_Fixed32Rules *validate_Fixed32Rules_parsenew(upb_strview buf, upb_arena *arena) { + validate_Fixed32Rules *ret = validate_Fixed32Rules_new(arena); + return (ret && upb_decode(buf, ret, &validate_Fixed32Rules_msginit)) ? ret : NULL; +} +UPB_INLINE char *validate_Fixed32Rules_serialize(const validate_Fixed32Rules *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &validate_Fixed32Rules_msginit, arena, len); +} + +UPB_INLINE bool validate_Fixed32Rules_has_const(const validate_Fixed32Rules *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE uint32_t validate_Fixed32Rules_const(const validate_Fixed32Rules *msg) { return UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(4, 4)); } +UPB_INLINE bool validate_Fixed32Rules_has_lt(const validate_Fixed32Rules *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE uint32_t validate_Fixed32Rules_lt(const validate_Fixed32Rules *msg) { return UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(8, 8)); } +UPB_INLINE bool validate_Fixed32Rules_has_lte(const validate_Fixed32Rules *msg) { return _upb_has_field(msg, 3); } +UPB_INLINE uint32_t validate_Fixed32Rules_lte(const validate_Fixed32Rules *msg) { return UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(12, 12)); } +UPB_INLINE bool validate_Fixed32Rules_has_gt(const validate_Fixed32Rules *msg) { return _upb_has_field(msg, 4); } +UPB_INLINE uint32_t validate_Fixed32Rules_gt(const validate_Fixed32Rules *msg) { return UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(16, 16)); } +UPB_INLINE bool validate_Fixed32Rules_has_gte(const validate_Fixed32Rules *msg) { return _upb_has_field(msg, 5); } +UPB_INLINE uint32_t validate_Fixed32Rules_gte(const validate_Fixed32Rules *msg) { return UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(20, 20)); } +UPB_INLINE uint32_t const* validate_Fixed32Rules_in(const validate_Fixed32Rules *msg, size_t *len) { return (uint32_t const*)_upb_array_accessor(msg, UPB_SIZE(24, 24), len); } +UPB_INLINE uint32_t const* validate_Fixed32Rules_not_in(const validate_Fixed32Rules *msg, size_t *len) { return (uint32_t const*)_upb_array_accessor(msg, UPB_SIZE(28, 32), len); } + +UPB_INLINE void validate_Fixed32Rules_set_const(validate_Fixed32Rules *msg, uint32_t value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(4, 4)) = value; +} +UPB_INLINE void validate_Fixed32Rules_set_lt(validate_Fixed32Rules *msg, uint32_t value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE void validate_Fixed32Rules_set_lte(validate_Fixed32Rules *msg, uint32_t value) { + _upb_sethas(msg, 3); + UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(12, 12)) = value; +} +UPB_INLINE void validate_Fixed32Rules_set_gt(validate_Fixed32Rules *msg, uint32_t value) { + _upb_sethas(msg, 4); + UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(16, 16)) = value; +} +UPB_INLINE void validate_Fixed32Rules_set_gte(validate_Fixed32Rules *msg, uint32_t value) { + _upb_sethas(msg, 5); + UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(20, 20)) = value; +} +UPB_INLINE uint32_t* validate_Fixed32Rules_mutable_in(validate_Fixed32Rules *msg, size_t *len) { + return (uint32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 24), len); +} +UPB_INLINE uint32_t* validate_Fixed32Rules_resize_in(validate_Fixed32Rules *msg, size_t len, upb_arena *arena) { + return (uint32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(24, 24), len, UPB_SIZE(4, 4), UPB_TYPE_UINT32, arena); +} +UPB_INLINE bool validate_Fixed32Rules_add_in(validate_Fixed32Rules *msg, uint32_t val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(24, 24), UPB_SIZE(4, 4), UPB_TYPE_UINT32, &val, arena); +} +UPB_INLINE uint32_t* validate_Fixed32Rules_mutable_not_in(validate_Fixed32Rules *msg, size_t *len) { + return (uint32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 32), len); +} +UPB_INLINE uint32_t* validate_Fixed32Rules_resize_not_in(validate_Fixed32Rules *msg, size_t len, upb_arena *arena) { + return (uint32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(28, 32), len, UPB_SIZE(4, 4), UPB_TYPE_UINT32, arena); +} +UPB_INLINE bool validate_Fixed32Rules_add_not_in(validate_Fixed32Rules *msg, uint32_t val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(28, 32), UPB_SIZE(4, 4), UPB_TYPE_UINT32, &val, arena); +} + + +/* validate.Fixed64Rules */ + +UPB_INLINE validate_Fixed64Rules *validate_Fixed64Rules_new(upb_arena *arena) { + return (validate_Fixed64Rules *)upb_msg_new(&validate_Fixed64Rules_msginit, arena); +} +UPB_INLINE validate_Fixed64Rules *validate_Fixed64Rules_parsenew(upb_strview buf, upb_arena *arena) { + validate_Fixed64Rules *ret = validate_Fixed64Rules_new(arena); + return (ret && upb_decode(buf, ret, &validate_Fixed64Rules_msginit)) ? ret : NULL; +} +UPB_INLINE char *validate_Fixed64Rules_serialize(const validate_Fixed64Rules *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &validate_Fixed64Rules_msginit, arena, len); +} + +UPB_INLINE bool validate_Fixed64Rules_has_const(const validate_Fixed64Rules *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE uint64_t validate_Fixed64Rules_const(const validate_Fixed64Rules *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(8, 8)); } +UPB_INLINE bool validate_Fixed64Rules_has_lt(const validate_Fixed64Rules *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE uint64_t validate_Fixed64Rules_lt(const validate_Fixed64Rules *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(16, 16)); } +UPB_INLINE bool validate_Fixed64Rules_has_lte(const validate_Fixed64Rules *msg) { return _upb_has_field(msg, 3); } +UPB_INLINE uint64_t validate_Fixed64Rules_lte(const validate_Fixed64Rules *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(24, 24)); } +UPB_INLINE bool validate_Fixed64Rules_has_gt(const validate_Fixed64Rules *msg) { return _upb_has_field(msg, 4); } +UPB_INLINE uint64_t validate_Fixed64Rules_gt(const validate_Fixed64Rules *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(32, 32)); } +UPB_INLINE bool validate_Fixed64Rules_has_gte(const validate_Fixed64Rules *msg) { return _upb_has_field(msg, 5); } +UPB_INLINE uint64_t validate_Fixed64Rules_gte(const validate_Fixed64Rules *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(40, 40)); } +UPB_INLINE uint64_t const* validate_Fixed64Rules_in(const validate_Fixed64Rules *msg, size_t *len) { return (uint64_t const*)_upb_array_accessor(msg, UPB_SIZE(48, 48), len); } +UPB_INLINE uint64_t const* validate_Fixed64Rules_not_in(const validate_Fixed64Rules *msg, size_t *len) { return (uint64_t const*)_upb_array_accessor(msg, UPB_SIZE(52, 56), len); } + +UPB_INLINE void validate_Fixed64Rules_set_const(validate_Fixed64Rules *msg, uint64_t value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE void validate_Fixed64Rules_set_lt(validate_Fixed64Rules *msg, uint64_t value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(16, 16)) = value; +} +UPB_INLINE void validate_Fixed64Rules_set_lte(validate_Fixed64Rules *msg, uint64_t value) { + _upb_sethas(msg, 3); + UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(24, 24)) = value; +} +UPB_INLINE void validate_Fixed64Rules_set_gt(validate_Fixed64Rules *msg, uint64_t value) { + _upb_sethas(msg, 4); + UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(32, 32)) = value; +} +UPB_INLINE void validate_Fixed64Rules_set_gte(validate_Fixed64Rules *msg, uint64_t value) { + _upb_sethas(msg, 5); + UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(40, 40)) = value; +} +UPB_INLINE uint64_t* validate_Fixed64Rules_mutable_in(validate_Fixed64Rules *msg, size_t *len) { + return (uint64_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(48, 48), len); +} +UPB_INLINE uint64_t* validate_Fixed64Rules_resize_in(validate_Fixed64Rules *msg, size_t len, upb_arena *arena) { + return (uint64_t*)_upb_array_resize_accessor(msg, UPB_SIZE(48, 48), len, UPB_SIZE(8, 8), UPB_TYPE_UINT64, arena); +} +UPB_INLINE bool validate_Fixed64Rules_add_in(validate_Fixed64Rules *msg, uint64_t val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(48, 48), UPB_SIZE(8, 8), UPB_TYPE_UINT64, &val, arena); +} +UPB_INLINE uint64_t* validate_Fixed64Rules_mutable_not_in(validate_Fixed64Rules *msg, size_t *len) { + return (uint64_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(52, 56), len); +} +UPB_INLINE uint64_t* validate_Fixed64Rules_resize_not_in(validate_Fixed64Rules *msg, size_t len, upb_arena *arena) { + return (uint64_t*)_upb_array_resize_accessor(msg, UPB_SIZE(52, 56), len, UPB_SIZE(8, 8), UPB_TYPE_UINT64, arena); +} +UPB_INLINE bool validate_Fixed64Rules_add_not_in(validate_Fixed64Rules *msg, uint64_t val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(52, 56), UPB_SIZE(8, 8), UPB_TYPE_UINT64, &val, arena); +} + + +/* validate.SFixed32Rules */ + +UPB_INLINE validate_SFixed32Rules *validate_SFixed32Rules_new(upb_arena *arena) { + return (validate_SFixed32Rules *)upb_msg_new(&validate_SFixed32Rules_msginit, arena); +} +UPB_INLINE validate_SFixed32Rules *validate_SFixed32Rules_parsenew(upb_strview buf, upb_arena *arena) { + validate_SFixed32Rules *ret = validate_SFixed32Rules_new(arena); + return (ret && upb_decode(buf, ret, &validate_SFixed32Rules_msginit)) ? ret : NULL; +} +UPB_INLINE char *validate_SFixed32Rules_serialize(const validate_SFixed32Rules *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &validate_SFixed32Rules_msginit, arena, len); +} + +UPB_INLINE bool validate_SFixed32Rules_has_const(const validate_SFixed32Rules *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE int32_t validate_SFixed32Rules_const(const validate_SFixed32Rules *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)); } +UPB_INLINE bool validate_SFixed32Rules_has_lt(const validate_SFixed32Rules *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE int32_t validate_SFixed32Rules_lt(const validate_SFixed32Rules *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); } +UPB_INLINE bool validate_SFixed32Rules_has_lte(const validate_SFixed32Rules *msg) { return _upb_has_field(msg, 3); } +UPB_INLINE int32_t validate_SFixed32Rules_lte(const validate_SFixed32Rules *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(12, 12)); } +UPB_INLINE bool validate_SFixed32Rules_has_gt(const validate_SFixed32Rules *msg) { return _upb_has_field(msg, 4); } +UPB_INLINE int32_t validate_SFixed32Rules_gt(const validate_SFixed32Rules *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(16, 16)); } +UPB_INLINE bool validate_SFixed32Rules_has_gte(const validate_SFixed32Rules *msg) { return _upb_has_field(msg, 5); } +UPB_INLINE int32_t validate_SFixed32Rules_gte(const validate_SFixed32Rules *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(20, 20)); } +UPB_INLINE int32_t const* validate_SFixed32Rules_in(const validate_SFixed32Rules *msg, size_t *len) { return (int32_t const*)_upb_array_accessor(msg, UPB_SIZE(24, 24), len); } +UPB_INLINE int32_t const* validate_SFixed32Rules_not_in(const validate_SFixed32Rules *msg, size_t *len) { return (int32_t const*)_upb_array_accessor(msg, UPB_SIZE(28, 32), len); } + +UPB_INLINE void validate_SFixed32Rules_set_const(validate_SFixed32Rules *msg, int32_t value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)) = value; +} +UPB_INLINE void validate_SFixed32Rules_set_lt(validate_SFixed32Rules *msg, int32_t value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE void validate_SFixed32Rules_set_lte(validate_SFixed32Rules *msg, int32_t value) { + _upb_sethas(msg, 3); + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(12, 12)) = value; +} +UPB_INLINE void validate_SFixed32Rules_set_gt(validate_SFixed32Rules *msg, int32_t value) { + _upb_sethas(msg, 4); + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(16, 16)) = value; +} +UPB_INLINE void validate_SFixed32Rules_set_gte(validate_SFixed32Rules *msg, int32_t value) { + _upb_sethas(msg, 5); + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(20, 20)) = value; +} +UPB_INLINE int32_t* validate_SFixed32Rules_mutable_in(validate_SFixed32Rules *msg, size_t *len) { + return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 24), len); +} +UPB_INLINE int32_t* validate_SFixed32Rules_resize_in(validate_SFixed32Rules *msg, size_t len, upb_arena *arena) { + return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(24, 24), len, UPB_SIZE(4, 4), UPB_TYPE_INT32, arena); +} +UPB_INLINE bool validate_SFixed32Rules_add_in(validate_SFixed32Rules *msg, int32_t val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(24, 24), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val, arena); +} +UPB_INLINE int32_t* validate_SFixed32Rules_mutable_not_in(validate_SFixed32Rules *msg, size_t *len) { + return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 32), len); +} +UPB_INLINE int32_t* validate_SFixed32Rules_resize_not_in(validate_SFixed32Rules *msg, size_t len, upb_arena *arena) { + return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(28, 32), len, UPB_SIZE(4, 4), UPB_TYPE_INT32, arena); +} +UPB_INLINE bool validate_SFixed32Rules_add_not_in(validate_SFixed32Rules *msg, int32_t val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(28, 32), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val, arena); +} + + +/* validate.SFixed64Rules */ + +UPB_INLINE validate_SFixed64Rules *validate_SFixed64Rules_new(upb_arena *arena) { + return (validate_SFixed64Rules *)upb_msg_new(&validate_SFixed64Rules_msginit, arena); +} +UPB_INLINE validate_SFixed64Rules *validate_SFixed64Rules_parsenew(upb_strview buf, upb_arena *arena) { + validate_SFixed64Rules *ret = validate_SFixed64Rules_new(arena); + return (ret && upb_decode(buf, ret, &validate_SFixed64Rules_msginit)) ? ret : NULL; +} +UPB_INLINE char *validate_SFixed64Rules_serialize(const validate_SFixed64Rules *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &validate_SFixed64Rules_msginit, arena, len); +} + +UPB_INLINE bool validate_SFixed64Rules_has_const(const validate_SFixed64Rules *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE int64_t validate_SFixed64Rules_const(const validate_SFixed64Rules *msg) { return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(8, 8)); } +UPB_INLINE bool validate_SFixed64Rules_has_lt(const validate_SFixed64Rules *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE int64_t validate_SFixed64Rules_lt(const validate_SFixed64Rules *msg) { return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(16, 16)); } +UPB_INLINE bool validate_SFixed64Rules_has_lte(const validate_SFixed64Rules *msg) { return _upb_has_field(msg, 3); } +UPB_INLINE int64_t validate_SFixed64Rules_lte(const validate_SFixed64Rules *msg) { return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(24, 24)); } +UPB_INLINE bool validate_SFixed64Rules_has_gt(const validate_SFixed64Rules *msg) { return _upb_has_field(msg, 4); } +UPB_INLINE int64_t validate_SFixed64Rules_gt(const validate_SFixed64Rules *msg) { return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(32, 32)); } +UPB_INLINE bool validate_SFixed64Rules_has_gte(const validate_SFixed64Rules *msg) { return _upb_has_field(msg, 5); } +UPB_INLINE int64_t validate_SFixed64Rules_gte(const validate_SFixed64Rules *msg) { return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(40, 40)); } +UPB_INLINE int64_t const* validate_SFixed64Rules_in(const validate_SFixed64Rules *msg, size_t *len) { return (int64_t const*)_upb_array_accessor(msg, UPB_SIZE(48, 48), len); } +UPB_INLINE int64_t const* validate_SFixed64Rules_not_in(const validate_SFixed64Rules *msg, size_t *len) { return (int64_t const*)_upb_array_accessor(msg, UPB_SIZE(52, 56), len); } + +UPB_INLINE void validate_SFixed64Rules_set_const(validate_SFixed64Rules *msg, int64_t value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, int64_t, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE void validate_SFixed64Rules_set_lt(validate_SFixed64Rules *msg, int64_t value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, int64_t, UPB_SIZE(16, 16)) = value; +} +UPB_INLINE void validate_SFixed64Rules_set_lte(validate_SFixed64Rules *msg, int64_t value) { + _upb_sethas(msg, 3); + UPB_FIELD_AT(msg, int64_t, UPB_SIZE(24, 24)) = value; +} +UPB_INLINE void validate_SFixed64Rules_set_gt(validate_SFixed64Rules *msg, int64_t value) { + _upb_sethas(msg, 4); + UPB_FIELD_AT(msg, int64_t, UPB_SIZE(32, 32)) = value; +} +UPB_INLINE void validate_SFixed64Rules_set_gte(validate_SFixed64Rules *msg, int64_t value) { + _upb_sethas(msg, 5); + UPB_FIELD_AT(msg, int64_t, UPB_SIZE(40, 40)) = value; +} +UPB_INLINE int64_t* validate_SFixed64Rules_mutable_in(validate_SFixed64Rules *msg, size_t *len) { + return (int64_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(48, 48), len); +} +UPB_INLINE int64_t* validate_SFixed64Rules_resize_in(validate_SFixed64Rules *msg, size_t len, upb_arena *arena) { + return (int64_t*)_upb_array_resize_accessor(msg, UPB_SIZE(48, 48), len, UPB_SIZE(8, 8), UPB_TYPE_INT64, arena); +} +UPB_INLINE bool validate_SFixed64Rules_add_in(validate_SFixed64Rules *msg, int64_t val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(48, 48), UPB_SIZE(8, 8), UPB_TYPE_INT64, &val, arena); +} +UPB_INLINE int64_t* validate_SFixed64Rules_mutable_not_in(validate_SFixed64Rules *msg, size_t *len) { + return (int64_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(52, 56), len); +} +UPB_INLINE int64_t* validate_SFixed64Rules_resize_not_in(validate_SFixed64Rules *msg, size_t len, upb_arena *arena) { + return (int64_t*)_upb_array_resize_accessor(msg, UPB_SIZE(52, 56), len, UPB_SIZE(8, 8), UPB_TYPE_INT64, arena); +} +UPB_INLINE bool validate_SFixed64Rules_add_not_in(validate_SFixed64Rules *msg, int64_t val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(52, 56), UPB_SIZE(8, 8), UPB_TYPE_INT64, &val, arena); +} + + +/* validate.BoolRules */ + +UPB_INLINE validate_BoolRules *validate_BoolRules_new(upb_arena *arena) { + return (validate_BoolRules *)upb_msg_new(&validate_BoolRules_msginit, arena); +} +UPB_INLINE validate_BoolRules *validate_BoolRules_parsenew(upb_strview buf, upb_arena *arena) { + validate_BoolRules *ret = validate_BoolRules_new(arena); + return (ret && upb_decode(buf, ret, &validate_BoolRules_msginit)) ? ret : NULL; +} +UPB_INLINE char *validate_BoolRules_serialize(const validate_BoolRules *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &validate_BoolRules_msginit, arena, len); +} + +UPB_INLINE bool validate_BoolRules_has_const(const validate_BoolRules *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE bool validate_BoolRules_const(const validate_BoolRules *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)); } + +UPB_INLINE void validate_BoolRules_set_const(validate_BoolRules *msg, bool value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)) = value; +} + + +/* validate.StringRules */ + +UPB_INLINE validate_StringRules *validate_StringRules_new(upb_arena *arena) { + return (validate_StringRules *)upb_msg_new(&validate_StringRules_msginit, arena); +} +UPB_INLINE validate_StringRules *validate_StringRules_parsenew(upb_strview buf, upb_arena *arena) { + validate_StringRules *ret = validate_StringRules_new(arena); + return (ret && upb_decode(buf, ret, &validate_StringRules_msginit)) ? ret : NULL; +} +UPB_INLINE char *validate_StringRules_serialize(const validate_StringRules *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &validate_StringRules_msginit, arena, len); +} + +typedef enum { + validate_StringRules_well_known_email = 12, + validate_StringRules_well_known_hostname = 13, + validate_StringRules_well_known_ip = 14, + validate_StringRules_well_known_ipv4 = 15, + validate_StringRules_well_known_ipv6 = 16, + validate_StringRules_well_known_uri = 17, + validate_StringRules_well_known_uri_ref = 18, + validate_StringRules_well_known_NOT_SET = 0, +} validate_StringRules_well_known_oneofcases; +UPB_INLINE validate_StringRules_well_known_oneofcases validate_StringRules_well_known_case(const validate_StringRules* msg) { return UPB_FIELD_AT(msg, int, UPB_SIZE(108, 156)); } + +UPB_INLINE bool validate_StringRules_has_const(const validate_StringRules *msg) { return _upb_has_field(msg, 7); } +UPB_INLINE upb_strview validate_StringRules_const(const validate_StringRules *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(56, 56)); } +UPB_INLINE bool validate_StringRules_has_min_len(const validate_StringRules *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE uint64_t validate_StringRules_min_len(const validate_StringRules *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(8, 8)); } +UPB_INLINE bool validate_StringRules_has_max_len(const validate_StringRules *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE uint64_t validate_StringRules_max_len(const validate_StringRules *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(16, 16)); } +UPB_INLINE bool validate_StringRules_has_min_bytes(const validate_StringRules *msg) { return _upb_has_field(msg, 3); } +UPB_INLINE uint64_t validate_StringRules_min_bytes(const validate_StringRules *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(24, 24)); } +UPB_INLINE bool validate_StringRules_has_max_bytes(const validate_StringRules *msg) { return _upb_has_field(msg, 4); } +UPB_INLINE uint64_t validate_StringRules_max_bytes(const validate_StringRules *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(32, 32)); } +UPB_INLINE bool validate_StringRules_has_pattern(const validate_StringRules *msg) { return _upb_has_field(msg, 8); } +UPB_INLINE upb_strview validate_StringRules_pattern(const validate_StringRules *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(64, 72)); } +UPB_INLINE bool validate_StringRules_has_prefix(const validate_StringRules *msg) { return _upb_has_field(msg, 9); } +UPB_INLINE upb_strview validate_StringRules_prefix(const validate_StringRules *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(72, 88)); } +UPB_INLINE bool validate_StringRules_has_suffix(const validate_StringRules *msg) { return _upb_has_field(msg, 10); } +UPB_INLINE upb_strview validate_StringRules_suffix(const validate_StringRules *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(80, 104)); } +UPB_INLINE bool validate_StringRules_has_contains(const validate_StringRules *msg) { return _upb_has_field(msg, 11); } +UPB_INLINE upb_strview validate_StringRules_contains(const validate_StringRules *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(88, 120)); } +UPB_INLINE upb_strview const* validate_StringRules_in(const validate_StringRules *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(96, 136), len); } +UPB_INLINE upb_strview const* validate_StringRules_not_in(const validate_StringRules *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(100, 144), len); } +UPB_INLINE bool validate_StringRules_has_email(const validate_StringRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(108, 156), 12); } +UPB_INLINE bool validate_StringRules_email(const validate_StringRules *msg) { return UPB_READ_ONEOF(msg, bool, UPB_SIZE(104, 152), UPB_SIZE(108, 156), 12, false); } +UPB_INLINE bool validate_StringRules_has_hostname(const validate_StringRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(108, 156), 13); } +UPB_INLINE bool validate_StringRules_hostname(const validate_StringRules *msg) { return UPB_READ_ONEOF(msg, bool, UPB_SIZE(104, 152), UPB_SIZE(108, 156), 13, false); } +UPB_INLINE bool validate_StringRules_has_ip(const validate_StringRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(108, 156), 14); } +UPB_INLINE bool validate_StringRules_ip(const validate_StringRules *msg) { return UPB_READ_ONEOF(msg, bool, UPB_SIZE(104, 152), UPB_SIZE(108, 156), 14, false); } +UPB_INLINE bool validate_StringRules_has_ipv4(const validate_StringRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(108, 156), 15); } +UPB_INLINE bool validate_StringRules_ipv4(const validate_StringRules *msg) { return UPB_READ_ONEOF(msg, bool, UPB_SIZE(104, 152), UPB_SIZE(108, 156), 15, false); } +UPB_INLINE bool validate_StringRules_has_ipv6(const validate_StringRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(108, 156), 16); } +UPB_INLINE bool validate_StringRules_ipv6(const validate_StringRules *msg) { return UPB_READ_ONEOF(msg, bool, UPB_SIZE(104, 152), UPB_SIZE(108, 156), 16, false); } +UPB_INLINE bool validate_StringRules_has_uri(const validate_StringRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(108, 156), 17); } +UPB_INLINE bool validate_StringRules_uri(const validate_StringRules *msg) { return UPB_READ_ONEOF(msg, bool, UPB_SIZE(104, 152), UPB_SIZE(108, 156), 17, false); } +UPB_INLINE bool validate_StringRules_has_uri_ref(const validate_StringRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(108, 156), 18); } +UPB_INLINE bool validate_StringRules_uri_ref(const validate_StringRules *msg) { return UPB_READ_ONEOF(msg, bool, UPB_SIZE(104, 152), UPB_SIZE(108, 156), 18, false); } +UPB_INLINE bool validate_StringRules_has_len(const validate_StringRules *msg) { return _upb_has_field(msg, 5); } +UPB_INLINE uint64_t validate_StringRules_len(const validate_StringRules *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(40, 40)); } +UPB_INLINE bool validate_StringRules_has_len_bytes(const validate_StringRules *msg) { return _upb_has_field(msg, 6); } +UPB_INLINE uint64_t validate_StringRules_len_bytes(const validate_StringRules *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(48, 48)); } + +UPB_INLINE void validate_StringRules_set_const(validate_StringRules *msg, upb_strview value) { + _upb_sethas(msg, 7); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(56, 56)) = value; +} +UPB_INLINE void validate_StringRules_set_min_len(validate_StringRules *msg, uint64_t value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE void validate_StringRules_set_max_len(validate_StringRules *msg, uint64_t value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(16, 16)) = value; +} +UPB_INLINE void validate_StringRules_set_min_bytes(validate_StringRules *msg, uint64_t value) { + _upb_sethas(msg, 3); + UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(24, 24)) = value; +} +UPB_INLINE void validate_StringRules_set_max_bytes(validate_StringRules *msg, uint64_t value) { + _upb_sethas(msg, 4); + UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(32, 32)) = value; +} +UPB_INLINE void validate_StringRules_set_pattern(validate_StringRules *msg, upb_strview value) { + _upb_sethas(msg, 8); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(64, 72)) = value; +} +UPB_INLINE void validate_StringRules_set_prefix(validate_StringRules *msg, upb_strview value) { + _upb_sethas(msg, 9); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(72, 88)) = value; +} +UPB_INLINE void validate_StringRules_set_suffix(validate_StringRules *msg, upb_strview value) { + _upb_sethas(msg, 10); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(80, 104)) = value; +} +UPB_INLINE void validate_StringRules_set_contains(validate_StringRules *msg, upb_strview value) { + _upb_sethas(msg, 11); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(88, 120)) = value; +} +UPB_INLINE upb_strview* validate_StringRules_mutable_in(validate_StringRules *msg, size_t *len) { + return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(96, 136), len); +} +UPB_INLINE upb_strview* validate_StringRules_resize_in(validate_StringRules *msg, size_t len, upb_arena *arena) { + return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(96, 136), len, UPB_SIZE(8, 16), UPB_TYPE_STRING, arena); +} +UPB_INLINE bool validate_StringRules_add_in(validate_StringRules *msg, upb_strview val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(96, 136), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, arena); +} +UPB_INLINE upb_strview* validate_StringRules_mutable_not_in(validate_StringRules *msg, size_t *len) { + return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(100, 144), len); +} +UPB_INLINE upb_strview* validate_StringRules_resize_not_in(validate_StringRules *msg, size_t len, upb_arena *arena) { + return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(100, 144), len, UPB_SIZE(8, 16), UPB_TYPE_STRING, arena); +} +UPB_INLINE bool validate_StringRules_add_not_in(validate_StringRules *msg, upb_strview val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(100, 144), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, arena); +} +UPB_INLINE void validate_StringRules_set_email(validate_StringRules *msg, bool value) { + UPB_WRITE_ONEOF(msg, bool, UPB_SIZE(104, 152), value, UPB_SIZE(108, 156), 12); +} +UPB_INLINE void validate_StringRules_set_hostname(validate_StringRules *msg, bool value) { + UPB_WRITE_ONEOF(msg, bool, UPB_SIZE(104, 152), value, UPB_SIZE(108, 156), 13); +} +UPB_INLINE void validate_StringRules_set_ip(validate_StringRules *msg, bool value) { + UPB_WRITE_ONEOF(msg, bool, UPB_SIZE(104, 152), value, UPB_SIZE(108, 156), 14); +} +UPB_INLINE void validate_StringRules_set_ipv4(validate_StringRules *msg, bool value) { + UPB_WRITE_ONEOF(msg, bool, UPB_SIZE(104, 152), value, UPB_SIZE(108, 156), 15); +} +UPB_INLINE void validate_StringRules_set_ipv6(validate_StringRules *msg, bool value) { + UPB_WRITE_ONEOF(msg, bool, UPB_SIZE(104, 152), value, UPB_SIZE(108, 156), 16); +} +UPB_INLINE void validate_StringRules_set_uri(validate_StringRules *msg, bool value) { + UPB_WRITE_ONEOF(msg, bool, UPB_SIZE(104, 152), value, UPB_SIZE(108, 156), 17); +} +UPB_INLINE void validate_StringRules_set_uri_ref(validate_StringRules *msg, bool value) { + UPB_WRITE_ONEOF(msg, bool, UPB_SIZE(104, 152), value, UPB_SIZE(108, 156), 18); +} +UPB_INLINE void validate_StringRules_set_len(validate_StringRules *msg, uint64_t value) { + _upb_sethas(msg, 5); + UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(40, 40)) = value; +} +UPB_INLINE void validate_StringRules_set_len_bytes(validate_StringRules *msg, uint64_t value) { + _upb_sethas(msg, 6); + UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(48, 48)) = value; +} + + +/* validate.BytesRules */ + +UPB_INLINE validate_BytesRules *validate_BytesRules_new(upb_arena *arena) { + return (validate_BytesRules *)upb_msg_new(&validate_BytesRules_msginit, arena); +} +UPB_INLINE validate_BytesRules *validate_BytesRules_parsenew(upb_strview buf, upb_arena *arena) { + validate_BytesRules *ret = validate_BytesRules_new(arena); + return (ret && upb_decode(buf, ret, &validate_BytesRules_msginit)) ? ret : NULL; +} +UPB_INLINE char *validate_BytesRules_serialize(const validate_BytesRules *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &validate_BytesRules_msginit, arena, len); +} + +typedef enum { + validate_BytesRules_well_known_ip = 10, + validate_BytesRules_well_known_ipv4 = 11, + validate_BytesRules_well_known_ipv6 = 12, + validate_BytesRules_well_known_NOT_SET = 0, +} validate_BytesRules_well_known_oneofcases; +UPB_INLINE validate_BytesRules_well_known_oneofcases validate_BytesRules_well_known_case(const validate_BytesRules* msg) { return UPB_FIELD_AT(msg, int, UPB_SIZE(84, 132)); } + +UPB_INLINE bool validate_BytesRules_has_const(const validate_BytesRules *msg) { return _upb_has_field(msg, 4); } +UPB_INLINE upb_strview validate_BytesRules_const(const validate_BytesRules *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(32, 32)); } +UPB_INLINE bool validate_BytesRules_has_min_len(const validate_BytesRules *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE uint64_t validate_BytesRules_min_len(const validate_BytesRules *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(8, 8)); } +UPB_INLINE bool validate_BytesRules_has_max_len(const validate_BytesRules *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE uint64_t validate_BytesRules_max_len(const validate_BytesRules *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(16, 16)); } +UPB_INLINE bool validate_BytesRules_has_pattern(const validate_BytesRules *msg) { return _upb_has_field(msg, 5); } +UPB_INLINE upb_strview validate_BytesRules_pattern(const validate_BytesRules *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(40, 48)); } +UPB_INLINE bool validate_BytesRules_has_prefix(const validate_BytesRules *msg) { return _upb_has_field(msg, 6); } +UPB_INLINE upb_strview validate_BytesRules_prefix(const validate_BytesRules *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(48, 64)); } +UPB_INLINE bool validate_BytesRules_has_suffix(const validate_BytesRules *msg) { return _upb_has_field(msg, 7); } +UPB_INLINE upb_strview validate_BytesRules_suffix(const validate_BytesRules *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(56, 80)); } +UPB_INLINE bool validate_BytesRules_has_contains(const validate_BytesRules *msg) { return _upb_has_field(msg, 8); } +UPB_INLINE upb_strview validate_BytesRules_contains(const validate_BytesRules *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(64, 96)); } +UPB_INLINE upb_strview const* validate_BytesRules_in(const validate_BytesRules *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(72, 112), len); } +UPB_INLINE upb_strview const* validate_BytesRules_not_in(const validate_BytesRules *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(76, 120), len); } +UPB_INLINE bool validate_BytesRules_has_ip(const validate_BytesRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(84, 132), 10); } +UPB_INLINE bool validate_BytesRules_ip(const validate_BytesRules *msg) { return UPB_READ_ONEOF(msg, bool, UPB_SIZE(80, 128), UPB_SIZE(84, 132), 10, false); } +UPB_INLINE bool validate_BytesRules_has_ipv4(const validate_BytesRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(84, 132), 11); } +UPB_INLINE bool validate_BytesRules_ipv4(const validate_BytesRules *msg) { return UPB_READ_ONEOF(msg, bool, UPB_SIZE(80, 128), UPB_SIZE(84, 132), 11, false); } +UPB_INLINE bool validate_BytesRules_has_ipv6(const validate_BytesRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(84, 132), 12); } +UPB_INLINE bool validate_BytesRules_ipv6(const validate_BytesRules *msg) { return UPB_READ_ONEOF(msg, bool, UPB_SIZE(80, 128), UPB_SIZE(84, 132), 12, false); } +UPB_INLINE bool validate_BytesRules_has_len(const validate_BytesRules *msg) { return _upb_has_field(msg, 3); } +UPB_INLINE uint64_t validate_BytesRules_len(const validate_BytesRules *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(24, 24)); } + +UPB_INLINE void validate_BytesRules_set_const(validate_BytesRules *msg, upb_strview value) { + _upb_sethas(msg, 4); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(32, 32)) = value; +} +UPB_INLINE void validate_BytesRules_set_min_len(validate_BytesRules *msg, uint64_t value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE void validate_BytesRules_set_max_len(validate_BytesRules *msg, uint64_t value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(16, 16)) = value; +} +UPB_INLINE void validate_BytesRules_set_pattern(validate_BytesRules *msg, upb_strview value) { + _upb_sethas(msg, 5); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(40, 48)) = value; +} +UPB_INLINE void validate_BytesRules_set_prefix(validate_BytesRules *msg, upb_strview value) { + _upb_sethas(msg, 6); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(48, 64)) = value; +} +UPB_INLINE void validate_BytesRules_set_suffix(validate_BytesRules *msg, upb_strview value) { + _upb_sethas(msg, 7); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(56, 80)) = value; +} +UPB_INLINE void validate_BytesRules_set_contains(validate_BytesRules *msg, upb_strview value) { + _upb_sethas(msg, 8); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(64, 96)) = value; +} +UPB_INLINE upb_strview* validate_BytesRules_mutable_in(validate_BytesRules *msg, size_t *len) { + return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(72, 112), len); +} +UPB_INLINE upb_strview* validate_BytesRules_resize_in(validate_BytesRules *msg, size_t len, upb_arena *arena) { + return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(72, 112), len, UPB_SIZE(8, 16), UPB_TYPE_STRING, arena); +} +UPB_INLINE bool validate_BytesRules_add_in(validate_BytesRules *msg, upb_strview val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(72, 112), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, arena); +} +UPB_INLINE upb_strview* validate_BytesRules_mutable_not_in(validate_BytesRules *msg, size_t *len) { + return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(76, 120), len); +} +UPB_INLINE upb_strview* validate_BytesRules_resize_not_in(validate_BytesRules *msg, size_t len, upb_arena *arena) { + return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(76, 120), len, UPB_SIZE(8, 16), UPB_TYPE_STRING, arena); +} +UPB_INLINE bool validate_BytesRules_add_not_in(validate_BytesRules *msg, upb_strview val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(76, 120), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, arena); +} +UPB_INLINE void validate_BytesRules_set_ip(validate_BytesRules *msg, bool value) { + UPB_WRITE_ONEOF(msg, bool, UPB_SIZE(80, 128), value, UPB_SIZE(84, 132), 10); +} +UPB_INLINE void validate_BytesRules_set_ipv4(validate_BytesRules *msg, bool value) { + UPB_WRITE_ONEOF(msg, bool, UPB_SIZE(80, 128), value, UPB_SIZE(84, 132), 11); +} +UPB_INLINE void validate_BytesRules_set_ipv6(validate_BytesRules *msg, bool value) { + UPB_WRITE_ONEOF(msg, bool, UPB_SIZE(80, 128), value, UPB_SIZE(84, 132), 12); +} +UPB_INLINE void validate_BytesRules_set_len(validate_BytesRules *msg, uint64_t value) { + _upb_sethas(msg, 3); + UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(24, 24)) = value; +} + + +/* validate.EnumRules */ + +UPB_INLINE validate_EnumRules *validate_EnumRules_new(upb_arena *arena) { + return (validate_EnumRules *)upb_msg_new(&validate_EnumRules_msginit, arena); +} +UPB_INLINE validate_EnumRules *validate_EnumRules_parsenew(upb_strview buf, upb_arena *arena) { + validate_EnumRules *ret = validate_EnumRules_new(arena); + return (ret && upb_decode(buf, ret, &validate_EnumRules_msginit)) ? ret : NULL; +} +UPB_INLINE char *validate_EnumRules_serialize(const validate_EnumRules *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &validate_EnumRules_msginit, arena, len); +} + +UPB_INLINE bool validate_EnumRules_has_const(const validate_EnumRules *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE int32_t validate_EnumRules_const(const validate_EnumRules *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)); } +UPB_INLINE bool validate_EnumRules_has_defined_only(const validate_EnumRules *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE bool validate_EnumRules_defined_only(const validate_EnumRules *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(8, 8)); } +UPB_INLINE int32_t const* validate_EnumRules_in(const validate_EnumRules *msg, size_t *len) { return (int32_t const*)_upb_array_accessor(msg, UPB_SIZE(12, 16), len); } +UPB_INLINE int32_t const* validate_EnumRules_not_in(const validate_EnumRules *msg, size_t *len) { return (int32_t const*)_upb_array_accessor(msg, UPB_SIZE(16, 24), len); } + +UPB_INLINE void validate_EnumRules_set_const(validate_EnumRules *msg, int32_t value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)) = value; +} +UPB_INLINE void validate_EnumRules_set_defined_only(validate_EnumRules *msg, bool value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, bool, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE int32_t* validate_EnumRules_mutable_in(validate_EnumRules *msg, size_t *len) { + return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(12, 16), len); +} +UPB_INLINE int32_t* validate_EnumRules_resize_in(validate_EnumRules *msg, size_t len, upb_arena *arena) { + return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(12, 16), len, UPB_SIZE(4, 4), UPB_TYPE_INT32, arena); +} +UPB_INLINE bool validate_EnumRules_add_in(validate_EnumRules *msg, int32_t val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(12, 16), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val, arena); +} +UPB_INLINE int32_t* validate_EnumRules_mutable_not_in(validate_EnumRules *msg, size_t *len) { + return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(16, 24), len); +} +UPB_INLINE int32_t* validate_EnumRules_resize_not_in(validate_EnumRules *msg, size_t len, upb_arena *arena) { + return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(16, 24), len, UPB_SIZE(4, 4), UPB_TYPE_INT32, arena); +} +UPB_INLINE bool validate_EnumRules_add_not_in(validate_EnumRules *msg, int32_t val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(16, 24), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val, arena); +} + + +/* validate.MessageRules */ + +UPB_INLINE validate_MessageRules *validate_MessageRules_new(upb_arena *arena) { + return (validate_MessageRules *)upb_msg_new(&validate_MessageRules_msginit, arena); +} +UPB_INLINE validate_MessageRules *validate_MessageRules_parsenew(upb_strview buf, upb_arena *arena) { + validate_MessageRules *ret = validate_MessageRules_new(arena); + return (ret && upb_decode(buf, ret, &validate_MessageRules_msginit)) ? ret : NULL; +} +UPB_INLINE char *validate_MessageRules_serialize(const validate_MessageRules *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &validate_MessageRules_msginit, arena, len); +} + +UPB_INLINE bool validate_MessageRules_has_skip(const validate_MessageRules *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE bool validate_MessageRules_skip(const validate_MessageRules *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)); } +UPB_INLINE bool validate_MessageRules_has_required(const validate_MessageRules *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE bool validate_MessageRules_required(const validate_MessageRules *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(2, 2)); } + +UPB_INLINE void validate_MessageRules_set_skip(validate_MessageRules *msg, bool value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)) = value; +} +UPB_INLINE void validate_MessageRules_set_required(validate_MessageRules *msg, bool value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, bool, UPB_SIZE(2, 2)) = value; +} + + +/* validate.RepeatedRules */ + +UPB_INLINE validate_RepeatedRules *validate_RepeatedRules_new(upb_arena *arena) { + return (validate_RepeatedRules *)upb_msg_new(&validate_RepeatedRules_msginit, arena); +} +UPB_INLINE validate_RepeatedRules *validate_RepeatedRules_parsenew(upb_strview buf, upb_arena *arena) { + validate_RepeatedRules *ret = validate_RepeatedRules_new(arena); + return (ret && upb_decode(buf, ret, &validate_RepeatedRules_msginit)) ? ret : NULL; +} +UPB_INLINE char *validate_RepeatedRules_serialize(const validate_RepeatedRules *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &validate_RepeatedRules_msginit, arena, len); +} + +UPB_INLINE bool validate_RepeatedRules_has_min_items(const validate_RepeatedRules *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE uint64_t validate_RepeatedRules_min_items(const validate_RepeatedRules *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(8, 8)); } +UPB_INLINE bool validate_RepeatedRules_has_max_items(const validate_RepeatedRules *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE uint64_t validate_RepeatedRules_max_items(const validate_RepeatedRules *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(16, 16)); } +UPB_INLINE bool validate_RepeatedRules_has_unique(const validate_RepeatedRules *msg) { return _upb_has_field(msg, 3); } +UPB_INLINE bool validate_RepeatedRules_unique(const validate_RepeatedRules *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(24, 24)); } +UPB_INLINE bool validate_RepeatedRules_has_items(const validate_RepeatedRules *msg) { return _upb_has_field(msg, 4); } +UPB_INLINE const validate_FieldRules* validate_RepeatedRules_items(const validate_RepeatedRules *msg) { return UPB_FIELD_AT(msg, const validate_FieldRules*, UPB_SIZE(28, 32)); } + +UPB_INLINE void validate_RepeatedRules_set_min_items(validate_RepeatedRules *msg, uint64_t value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE void validate_RepeatedRules_set_max_items(validate_RepeatedRules *msg, uint64_t value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(16, 16)) = value; +} +UPB_INLINE void validate_RepeatedRules_set_unique(validate_RepeatedRules *msg, bool value) { + _upb_sethas(msg, 3); + UPB_FIELD_AT(msg, bool, UPB_SIZE(24, 24)) = value; +} +UPB_INLINE void validate_RepeatedRules_set_items(validate_RepeatedRules *msg, validate_FieldRules* value) { + _upb_sethas(msg, 4); + UPB_FIELD_AT(msg, validate_FieldRules*, UPB_SIZE(28, 32)) = value; +} +UPB_INLINE struct validate_FieldRules* validate_RepeatedRules_mutable_items(validate_RepeatedRules *msg, upb_arena *arena) { + struct validate_FieldRules* sub = (struct validate_FieldRules*)validate_RepeatedRules_items(msg); + if (sub == NULL) { + sub = (struct validate_FieldRules*)upb_msg_new(&validate_FieldRules_msginit, arena); + if (!sub) return NULL; + validate_RepeatedRules_set_items(msg, sub); + } + return sub; +} + + +/* validate.MapRules */ + +UPB_INLINE validate_MapRules *validate_MapRules_new(upb_arena *arena) { + return (validate_MapRules *)upb_msg_new(&validate_MapRules_msginit, arena); +} +UPB_INLINE validate_MapRules *validate_MapRules_parsenew(upb_strview buf, upb_arena *arena) { + validate_MapRules *ret = validate_MapRules_new(arena); + return (ret && upb_decode(buf, ret, &validate_MapRules_msginit)) ? ret : NULL; +} +UPB_INLINE char *validate_MapRules_serialize(const validate_MapRules *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &validate_MapRules_msginit, arena, len); +} + +UPB_INLINE bool validate_MapRules_has_min_pairs(const validate_MapRules *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE uint64_t validate_MapRules_min_pairs(const validate_MapRules *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(8, 8)); } +UPB_INLINE bool validate_MapRules_has_max_pairs(const validate_MapRules *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE uint64_t validate_MapRules_max_pairs(const validate_MapRules *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(16, 16)); } +UPB_INLINE bool validate_MapRules_has_no_sparse(const validate_MapRules *msg) { return _upb_has_field(msg, 3); } +UPB_INLINE bool validate_MapRules_no_sparse(const validate_MapRules *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(24, 24)); } +UPB_INLINE bool validate_MapRules_has_keys(const validate_MapRules *msg) { return _upb_has_field(msg, 4); } +UPB_INLINE const validate_FieldRules* validate_MapRules_keys(const validate_MapRules *msg) { return UPB_FIELD_AT(msg, const validate_FieldRules*, UPB_SIZE(28, 32)); } +UPB_INLINE bool validate_MapRules_has_values(const validate_MapRules *msg) { return _upb_has_field(msg, 5); } +UPB_INLINE const validate_FieldRules* validate_MapRules_values(const validate_MapRules *msg) { return UPB_FIELD_AT(msg, const validate_FieldRules*, UPB_SIZE(32, 40)); } + +UPB_INLINE void validate_MapRules_set_min_pairs(validate_MapRules *msg, uint64_t value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE void validate_MapRules_set_max_pairs(validate_MapRules *msg, uint64_t value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(16, 16)) = value; +} +UPB_INLINE void validate_MapRules_set_no_sparse(validate_MapRules *msg, bool value) { + _upb_sethas(msg, 3); + UPB_FIELD_AT(msg, bool, UPB_SIZE(24, 24)) = value; +} +UPB_INLINE void validate_MapRules_set_keys(validate_MapRules *msg, validate_FieldRules* value) { + _upb_sethas(msg, 4); + UPB_FIELD_AT(msg, validate_FieldRules*, UPB_SIZE(28, 32)) = value; +} +UPB_INLINE struct validate_FieldRules* validate_MapRules_mutable_keys(validate_MapRules *msg, upb_arena *arena) { + struct validate_FieldRules* sub = (struct validate_FieldRules*)validate_MapRules_keys(msg); + if (sub == NULL) { + sub = (struct validate_FieldRules*)upb_msg_new(&validate_FieldRules_msginit, arena); + if (!sub) return NULL; + validate_MapRules_set_keys(msg, sub); + } + return sub; +} +UPB_INLINE void validate_MapRules_set_values(validate_MapRules *msg, validate_FieldRules* value) { + _upb_sethas(msg, 5); + UPB_FIELD_AT(msg, validate_FieldRules*, UPB_SIZE(32, 40)) = value; +} +UPB_INLINE struct validate_FieldRules* validate_MapRules_mutable_values(validate_MapRules *msg, upb_arena *arena) { + struct validate_FieldRules* sub = (struct validate_FieldRules*)validate_MapRules_values(msg); + if (sub == NULL) { + sub = (struct validate_FieldRules*)upb_msg_new(&validate_FieldRules_msginit, arena); + if (!sub) return NULL; + validate_MapRules_set_values(msg, sub); + } + return sub; +} + + +/* validate.AnyRules */ + +UPB_INLINE validate_AnyRules *validate_AnyRules_new(upb_arena *arena) { + return (validate_AnyRules *)upb_msg_new(&validate_AnyRules_msginit, arena); +} +UPB_INLINE validate_AnyRules *validate_AnyRules_parsenew(upb_strview buf, upb_arena *arena) { + validate_AnyRules *ret = validate_AnyRules_new(arena); + return (ret && upb_decode(buf, ret, &validate_AnyRules_msginit)) ? ret : NULL; +} +UPB_INLINE char *validate_AnyRules_serialize(const validate_AnyRules *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &validate_AnyRules_msginit, arena, len); +} + +UPB_INLINE bool validate_AnyRules_has_required(const validate_AnyRules *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE bool validate_AnyRules_required(const validate_AnyRules *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)); } +UPB_INLINE upb_strview const* validate_AnyRules_in(const validate_AnyRules *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(4, 8), len); } +UPB_INLINE upb_strview const* validate_AnyRules_not_in(const validate_AnyRules *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(8, 16), len); } + +UPB_INLINE void validate_AnyRules_set_required(validate_AnyRules *msg, bool value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)) = value; +} +UPB_INLINE upb_strview* validate_AnyRules_mutable_in(validate_AnyRules *msg, size_t *len) { + return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(4, 8), len); +} +UPB_INLINE upb_strview* validate_AnyRules_resize_in(validate_AnyRules *msg, size_t len, upb_arena *arena) { + return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(4, 8), len, UPB_SIZE(8, 16), UPB_TYPE_STRING, arena); +} +UPB_INLINE bool validate_AnyRules_add_in(validate_AnyRules *msg, upb_strview val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(4, 8), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, arena); +} +UPB_INLINE upb_strview* validate_AnyRules_mutable_not_in(validate_AnyRules *msg, size_t *len) { + return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(8, 16), len); +} +UPB_INLINE upb_strview* validate_AnyRules_resize_not_in(validate_AnyRules *msg, size_t len, upb_arena *arena) { + return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(8, 16), len, UPB_SIZE(8, 16), UPB_TYPE_STRING, arena); +} +UPB_INLINE bool validate_AnyRules_add_not_in(validate_AnyRules *msg, upb_strview val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(8, 16), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, arena); +} + + +/* validate.DurationRules */ + +UPB_INLINE validate_DurationRules *validate_DurationRules_new(upb_arena *arena) { + return (validate_DurationRules *)upb_msg_new(&validate_DurationRules_msginit, arena); +} +UPB_INLINE validate_DurationRules *validate_DurationRules_parsenew(upb_strview buf, upb_arena *arena) { + validate_DurationRules *ret = validate_DurationRules_new(arena); + return (ret && upb_decode(buf, ret, &validate_DurationRules_msginit)) ? ret : NULL; +} +UPB_INLINE char *validate_DurationRules_serialize(const validate_DurationRules *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &validate_DurationRules_msginit, arena, len); +} + +UPB_INLINE bool validate_DurationRules_has_required(const validate_DurationRules *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE bool validate_DurationRules_required(const validate_DurationRules *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)); } +UPB_INLINE bool validate_DurationRules_has_const(const validate_DurationRules *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE const struct google_protobuf_Duration* validate_DurationRules_const(const validate_DurationRules *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Duration*, UPB_SIZE(4, 8)); } +UPB_INLINE bool validate_DurationRules_has_lt(const validate_DurationRules *msg) { return _upb_has_field(msg, 3); } +UPB_INLINE const struct google_protobuf_Duration* validate_DurationRules_lt(const validate_DurationRules *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Duration*, UPB_SIZE(8, 16)); } +UPB_INLINE bool validate_DurationRules_has_lte(const validate_DurationRules *msg) { return _upb_has_field(msg, 4); } +UPB_INLINE const struct google_protobuf_Duration* validate_DurationRules_lte(const validate_DurationRules *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Duration*, UPB_SIZE(12, 24)); } +UPB_INLINE bool validate_DurationRules_has_gt(const validate_DurationRules *msg) { return _upb_has_field(msg, 5); } +UPB_INLINE const struct google_protobuf_Duration* validate_DurationRules_gt(const validate_DurationRules *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Duration*, UPB_SIZE(16, 32)); } +UPB_INLINE bool validate_DurationRules_has_gte(const validate_DurationRules *msg) { return _upb_has_field(msg, 6); } +UPB_INLINE const struct google_protobuf_Duration* validate_DurationRules_gte(const validate_DurationRules *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Duration*, UPB_SIZE(20, 40)); } +UPB_INLINE const struct google_protobuf_Duration* const* validate_DurationRules_in(const validate_DurationRules *msg, size_t *len) { return (const struct google_protobuf_Duration* const*)_upb_array_accessor(msg, UPB_SIZE(24, 48), len); } +UPB_INLINE const struct google_protobuf_Duration* const* validate_DurationRules_not_in(const validate_DurationRules *msg, size_t *len) { return (const struct google_protobuf_Duration* const*)_upb_array_accessor(msg, UPB_SIZE(28, 56), len); } + +UPB_INLINE void validate_DurationRules_set_required(validate_DurationRules *msg, bool value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)) = value; +} +UPB_INLINE void validate_DurationRules_set_const(validate_DurationRules *msg, struct google_protobuf_Duration* value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, struct google_protobuf_Duration*, UPB_SIZE(4, 8)) = value; +} +UPB_INLINE struct google_protobuf_Duration* validate_DurationRules_mutable_const(validate_DurationRules *msg, upb_arena *arena) { + struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)validate_DurationRules_const(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Duration*)upb_msg_new(&google_protobuf_Duration_msginit, arena); + if (!sub) return NULL; + validate_DurationRules_set_const(msg, sub); + } + return sub; +} +UPB_INLINE void validate_DurationRules_set_lt(validate_DurationRules *msg, struct google_protobuf_Duration* value) { + _upb_sethas(msg, 3); + UPB_FIELD_AT(msg, struct google_protobuf_Duration*, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE struct google_protobuf_Duration* validate_DurationRules_mutable_lt(validate_DurationRules *msg, upb_arena *arena) { + struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)validate_DurationRules_lt(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Duration*)upb_msg_new(&google_protobuf_Duration_msginit, arena); + if (!sub) return NULL; + validate_DurationRules_set_lt(msg, sub); + } + return sub; +} +UPB_INLINE void validate_DurationRules_set_lte(validate_DurationRules *msg, struct google_protobuf_Duration* value) { + _upb_sethas(msg, 4); + UPB_FIELD_AT(msg, struct google_protobuf_Duration*, UPB_SIZE(12, 24)) = value; +} +UPB_INLINE struct google_protobuf_Duration* validate_DurationRules_mutable_lte(validate_DurationRules *msg, upb_arena *arena) { + struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)validate_DurationRules_lte(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Duration*)upb_msg_new(&google_protobuf_Duration_msginit, arena); + if (!sub) return NULL; + validate_DurationRules_set_lte(msg, sub); + } + return sub; +} +UPB_INLINE void validate_DurationRules_set_gt(validate_DurationRules *msg, struct google_protobuf_Duration* value) { + _upb_sethas(msg, 5); + UPB_FIELD_AT(msg, struct google_protobuf_Duration*, UPB_SIZE(16, 32)) = value; +} +UPB_INLINE struct google_protobuf_Duration* validate_DurationRules_mutable_gt(validate_DurationRules *msg, upb_arena *arena) { + struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)validate_DurationRules_gt(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Duration*)upb_msg_new(&google_protobuf_Duration_msginit, arena); + if (!sub) return NULL; + validate_DurationRules_set_gt(msg, sub); + } + return sub; +} +UPB_INLINE void validate_DurationRules_set_gte(validate_DurationRules *msg, struct google_protobuf_Duration* value) { + _upb_sethas(msg, 6); + UPB_FIELD_AT(msg, struct google_protobuf_Duration*, UPB_SIZE(20, 40)) = value; +} +UPB_INLINE struct google_protobuf_Duration* validate_DurationRules_mutable_gte(validate_DurationRules *msg, upb_arena *arena) { + struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)validate_DurationRules_gte(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Duration*)upb_msg_new(&google_protobuf_Duration_msginit, arena); + if (!sub) return NULL; + validate_DurationRules_set_gte(msg, sub); + } + return sub; +} +UPB_INLINE struct google_protobuf_Duration** validate_DurationRules_mutable_in(validate_DurationRules *msg, size_t *len) { + return (struct google_protobuf_Duration**)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 48), len); +} +UPB_INLINE struct google_protobuf_Duration** validate_DurationRules_resize_in(validate_DurationRules *msg, size_t len, upb_arena *arena) { + return (struct google_protobuf_Duration**)_upb_array_resize_accessor(msg, UPB_SIZE(24, 48), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_Duration* validate_DurationRules_add_in(validate_DurationRules *msg, upb_arena *arena) { + struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)upb_msg_new(&google_protobuf_Duration_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(24, 48), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE struct google_protobuf_Duration** validate_DurationRules_mutable_not_in(validate_DurationRules *msg, size_t *len) { + return (struct google_protobuf_Duration**)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 56), len); +} +UPB_INLINE struct google_protobuf_Duration** validate_DurationRules_resize_not_in(validate_DurationRules *msg, size_t len, upb_arena *arena) { + return (struct google_protobuf_Duration**)_upb_array_resize_accessor(msg, UPB_SIZE(28, 56), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_Duration* validate_DurationRules_add_not_in(validate_DurationRules *msg, upb_arena *arena) { + struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)upb_msg_new(&google_protobuf_Duration_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(28, 56), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} + + +/* validate.TimestampRules */ + +UPB_INLINE validate_TimestampRules *validate_TimestampRules_new(upb_arena *arena) { + return (validate_TimestampRules *)upb_msg_new(&validate_TimestampRules_msginit, arena); +} +UPB_INLINE validate_TimestampRules *validate_TimestampRules_parsenew(upb_strview buf, upb_arena *arena) { + validate_TimestampRules *ret = validate_TimestampRules_new(arena); + return (ret && upb_decode(buf, ret, &validate_TimestampRules_msginit)) ? ret : NULL; +} +UPB_INLINE char *validate_TimestampRules_serialize(const validate_TimestampRules *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &validate_TimestampRules_msginit, arena, len); +} + +UPB_INLINE bool validate_TimestampRules_has_required(const validate_TimestampRules *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE bool validate_TimestampRules_required(const validate_TimestampRules *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(2, 2)); } +UPB_INLINE bool validate_TimestampRules_has_const(const validate_TimestampRules *msg) { return _upb_has_field(msg, 4); } +UPB_INLINE const struct google_protobuf_Timestamp* validate_TimestampRules_const(const validate_TimestampRules *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Timestamp*, UPB_SIZE(8, 8)); } +UPB_INLINE bool validate_TimestampRules_has_lt(const validate_TimestampRules *msg) { return _upb_has_field(msg, 5); } +UPB_INLINE const struct google_protobuf_Timestamp* validate_TimestampRules_lt(const validate_TimestampRules *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Timestamp*, UPB_SIZE(12, 16)); } +UPB_INLINE bool validate_TimestampRules_has_lte(const validate_TimestampRules *msg) { return _upb_has_field(msg, 6); } +UPB_INLINE const struct google_protobuf_Timestamp* validate_TimestampRules_lte(const validate_TimestampRules *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Timestamp*, UPB_SIZE(16, 24)); } +UPB_INLINE bool validate_TimestampRules_has_gt(const validate_TimestampRules *msg) { return _upb_has_field(msg, 7); } +UPB_INLINE const struct google_protobuf_Timestamp* validate_TimestampRules_gt(const validate_TimestampRules *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Timestamp*, UPB_SIZE(20, 32)); } +UPB_INLINE bool validate_TimestampRules_has_gte(const validate_TimestampRules *msg) { return _upb_has_field(msg, 8); } +UPB_INLINE const struct google_protobuf_Timestamp* validate_TimestampRules_gte(const validate_TimestampRules *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Timestamp*, UPB_SIZE(24, 40)); } +UPB_INLINE bool validate_TimestampRules_has_lt_now(const validate_TimestampRules *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE bool validate_TimestampRules_lt_now(const validate_TimestampRules *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(3, 3)); } +UPB_INLINE bool validate_TimestampRules_has_gt_now(const validate_TimestampRules *msg) { return _upb_has_field(msg, 3); } +UPB_INLINE bool validate_TimestampRules_gt_now(const validate_TimestampRules *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(4, 4)); } +UPB_INLINE bool validate_TimestampRules_has_within(const validate_TimestampRules *msg) { return _upb_has_field(msg, 9); } +UPB_INLINE const struct google_protobuf_Duration* validate_TimestampRules_within(const validate_TimestampRules *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Duration*, UPB_SIZE(28, 48)); } + +UPB_INLINE void validate_TimestampRules_set_required(validate_TimestampRules *msg, bool value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, bool, UPB_SIZE(2, 2)) = value; +} +UPB_INLINE void validate_TimestampRules_set_const(validate_TimestampRules *msg, struct google_protobuf_Timestamp* value) { + _upb_sethas(msg, 4); + UPB_FIELD_AT(msg, struct google_protobuf_Timestamp*, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE struct google_protobuf_Timestamp* validate_TimestampRules_mutable_const(validate_TimestampRules *msg, upb_arena *arena) { + struct google_protobuf_Timestamp* sub = (struct google_protobuf_Timestamp*)validate_TimestampRules_const(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Timestamp*)upb_msg_new(&google_protobuf_Timestamp_msginit, arena); + if (!sub) return NULL; + validate_TimestampRules_set_const(msg, sub); + } + return sub; +} +UPB_INLINE void validate_TimestampRules_set_lt(validate_TimestampRules *msg, struct google_protobuf_Timestamp* value) { + _upb_sethas(msg, 5); + UPB_FIELD_AT(msg, struct google_protobuf_Timestamp*, UPB_SIZE(12, 16)) = value; +} +UPB_INLINE struct google_protobuf_Timestamp* validate_TimestampRules_mutable_lt(validate_TimestampRules *msg, upb_arena *arena) { + struct google_protobuf_Timestamp* sub = (struct google_protobuf_Timestamp*)validate_TimestampRules_lt(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Timestamp*)upb_msg_new(&google_protobuf_Timestamp_msginit, arena); + if (!sub) return NULL; + validate_TimestampRules_set_lt(msg, sub); + } + return sub; +} +UPB_INLINE void validate_TimestampRules_set_lte(validate_TimestampRules *msg, struct google_protobuf_Timestamp* value) { + _upb_sethas(msg, 6); + UPB_FIELD_AT(msg, struct google_protobuf_Timestamp*, UPB_SIZE(16, 24)) = value; +} +UPB_INLINE struct google_protobuf_Timestamp* validate_TimestampRules_mutable_lte(validate_TimestampRules *msg, upb_arena *arena) { + struct google_protobuf_Timestamp* sub = (struct google_protobuf_Timestamp*)validate_TimestampRules_lte(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Timestamp*)upb_msg_new(&google_protobuf_Timestamp_msginit, arena); + if (!sub) return NULL; + validate_TimestampRules_set_lte(msg, sub); + } + return sub; +} +UPB_INLINE void validate_TimestampRules_set_gt(validate_TimestampRules *msg, struct google_protobuf_Timestamp* value) { + _upb_sethas(msg, 7); + UPB_FIELD_AT(msg, struct google_protobuf_Timestamp*, UPB_SIZE(20, 32)) = value; +} +UPB_INLINE struct google_protobuf_Timestamp* validate_TimestampRules_mutable_gt(validate_TimestampRules *msg, upb_arena *arena) { + struct google_protobuf_Timestamp* sub = (struct google_protobuf_Timestamp*)validate_TimestampRules_gt(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Timestamp*)upb_msg_new(&google_protobuf_Timestamp_msginit, arena); + if (!sub) return NULL; + validate_TimestampRules_set_gt(msg, sub); + } + return sub; +} +UPB_INLINE void validate_TimestampRules_set_gte(validate_TimestampRules *msg, struct google_protobuf_Timestamp* value) { + _upb_sethas(msg, 8); + UPB_FIELD_AT(msg, struct google_protobuf_Timestamp*, UPB_SIZE(24, 40)) = value; +} +UPB_INLINE struct google_protobuf_Timestamp* validate_TimestampRules_mutable_gte(validate_TimestampRules *msg, upb_arena *arena) { + struct google_protobuf_Timestamp* sub = (struct google_protobuf_Timestamp*)validate_TimestampRules_gte(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Timestamp*)upb_msg_new(&google_protobuf_Timestamp_msginit, arena); + if (!sub) return NULL; + validate_TimestampRules_set_gte(msg, sub); + } + return sub; +} +UPB_INLINE void validate_TimestampRules_set_lt_now(validate_TimestampRules *msg, bool value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, bool, UPB_SIZE(3, 3)) = value; +} +UPB_INLINE void validate_TimestampRules_set_gt_now(validate_TimestampRules *msg, bool value) { + _upb_sethas(msg, 3); + UPB_FIELD_AT(msg, bool, UPB_SIZE(4, 4)) = value; +} +UPB_INLINE void validate_TimestampRules_set_within(validate_TimestampRules *msg, struct google_protobuf_Duration* value) { + _upb_sethas(msg, 9); + UPB_FIELD_AT(msg, struct google_protobuf_Duration*, UPB_SIZE(28, 48)) = value; +} +UPB_INLINE struct google_protobuf_Duration* validate_TimestampRules_mutable_within(validate_TimestampRules *msg, upb_arena *arena) { + struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)validate_TimestampRules_within(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Duration*)upb_msg_new(&google_protobuf_Duration_msginit, arena); + if (!sub) return NULL; + validate_TimestampRules_set_within(msg, sub); + } + return sub; +} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* VALIDATE_VALIDATE_PROTO_UPB_H_ */ diff --git a/src/core/lib/channel/channel_args.cc b/src/core/lib/channel/channel_args.cc index e49d532e11d..a35db186a30 100644 --- a/src/core/lib/channel/channel_args.cc +++ b/src/core/lib/channel/channel_args.cc @@ -21,7 +21,6 @@ #include #include -#include #include #include #include @@ -118,6 +117,8 @@ grpc_channel_args* grpc_channel_args_copy(const grpc_channel_args* src) { grpc_channel_args* grpc_channel_args_union(const grpc_channel_args* a, const grpc_channel_args* b) { + if (a == nullptr) return grpc_channel_args_copy(b); + if (b == nullptr) return grpc_channel_args_copy(a); const size_t max_out = (a->num_args + b->num_args); grpc_arg* uniques = static_cast(gpr_malloc(sizeof(*uniques) * max_out)); @@ -211,106 +212,6 @@ void grpc_channel_args_destroy(grpc_channel_args* a) { gpr_free(a); } -grpc_compression_algorithm grpc_channel_args_get_compression_algorithm( - const grpc_channel_args* a) { - size_t i; - if (a == nullptr) return GRPC_COMPRESS_NONE; - for (i = 0; i < a->num_args; ++i) { - if (a->args[i].type == GRPC_ARG_INTEGER && - !strcmp(GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM, a->args[i].key)) { - return static_cast(a->args[i].value.integer); - break; - } - } - return GRPC_COMPRESS_NONE; -} - -grpc_channel_args* grpc_channel_args_set_compression_algorithm( - grpc_channel_args* a, grpc_compression_algorithm algorithm) { - GPR_ASSERT(algorithm < GRPC_COMPRESS_ALGORITHMS_COUNT); - grpc_arg tmp; - tmp.type = GRPC_ARG_INTEGER; - tmp.key = (char*)GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM; - tmp.value.integer = algorithm; - return grpc_channel_args_copy_and_add(a, &tmp, 1); -} - -/** Returns 1 if the argument for compression algorithm's enabled states bitset - * was found in \a a, returning the arg's value in \a states. Otherwise, returns - * 0. */ -static int find_compression_algorithm_states_bitset(const grpc_channel_args* a, - int** states_arg) { - if (a != nullptr) { - size_t i; - for (i = 0; i < a->num_args; ++i) { - if (a->args[i].type == GRPC_ARG_INTEGER && - !strcmp(GRPC_COMPRESSION_CHANNEL_ENABLED_ALGORITHMS_BITSET, - a->args[i].key)) { - *states_arg = &a->args[i].value.integer; - **states_arg |= 0x1; /* forcefully enable support for no compression */ - return 1; - } - } - } - return 0; /* GPR_FALSE */ -} - -grpc_channel_args* grpc_channel_args_compression_algorithm_set_state( - grpc_channel_args** a, grpc_compression_algorithm algorithm, int state) { - int* states_arg = nullptr; - grpc_channel_args* result = *a; - const int states_arg_found = - find_compression_algorithm_states_bitset(*a, &states_arg); - - if (grpc_channel_args_get_compression_algorithm(*a) == algorithm && - state == 0) { - const char* algo_name = nullptr; - GPR_ASSERT(grpc_compression_algorithm_name(algorithm, &algo_name) != 0); - gpr_log(GPR_ERROR, - "Tried to disable default compression algorithm '%s'. The " - "operation has been ignored.", - algo_name); - } else if (states_arg_found) { - if (state != 0) { - GPR_BITSET((unsigned*)states_arg, algorithm); - } else if (algorithm != GRPC_COMPRESS_NONE) { - GPR_BITCLEAR((unsigned*)states_arg, algorithm); - } - } else { - /* create a new arg */ - grpc_arg tmp; - tmp.type = GRPC_ARG_INTEGER; - tmp.key = (char*)GRPC_COMPRESSION_CHANNEL_ENABLED_ALGORITHMS_BITSET; - /* all enabled by default */ - tmp.value.integer = (1u << GRPC_COMPRESS_ALGORITHMS_COUNT) - 1; - if (state != 0) { - GPR_BITSET((unsigned*)&tmp.value.integer, algorithm); - } else if (algorithm != GRPC_COMPRESS_NONE) { - GPR_BITCLEAR((unsigned*)&tmp.value.integer, algorithm); - } - result = grpc_channel_args_copy_and_add(*a, &tmp, 1); - grpc_channel_args_destroy(*a); - *a = result; - } - return result; -} - -uint32_t grpc_channel_args_compression_algorithm_get_states( - const grpc_channel_args* a) { - int* states_arg; - if (find_compression_algorithm_states_bitset(a, &states_arg)) { - return static_cast(*states_arg); - } else { - return (1u << GRPC_COMPRESS_ALGORITHMS_COUNT) - 1; /* All algs. enabled */ - } -} - -grpc_channel_args* grpc_channel_args_set_socket_mutator( - grpc_channel_args* a, grpc_socket_mutator* mutator) { - grpc_arg tmp = grpc_socket_mutator_to_arg(mutator); - return grpc_channel_args_copy_and_add(a, &tmp, 1); -} - int grpc_channel_args_compare(const grpc_channel_args* a, const grpc_channel_args* b) { int c = GPR_ICMP(a->num_args, b->num_args); diff --git a/src/core/lib/channel/channel_args.h b/src/core/lib/channel/channel_args.h index 5ff303a9dc6..2b698a66cfb 100644 --- a/src/core/lib/channel/channel_args.h +++ b/src/core/lib/channel/channel_args.h @@ -21,9 +21,7 @@ #include -#include #include -#include "src/core/lib/iomgr/socket_mutator.h" // Channel args are intentionally immutable, to avoid the need for locking. @@ -56,45 +54,13 @@ grpc_channel_args* grpc_channel_args_union(const grpc_channel_args* a, /** Destroy arguments created by \a grpc_channel_args_copy */ void grpc_channel_args_destroy(grpc_channel_args* a); - -/** Returns the compression algorithm set in \a a. */ -grpc_compression_algorithm grpc_channel_args_get_compression_algorithm( - const grpc_channel_args* a); - -/** Returns a channel arg instance with compression enabled. If \a a is - * non-NULL, its args are copied. N.B. GRPC_COMPRESS_NONE disables compression - * for the channel. */ -grpc_channel_args* grpc_channel_args_set_compression_algorithm( - grpc_channel_args* a, grpc_compression_algorithm algorithm); - -/** Sets the support for the given compression algorithm. By default, all - * compression algorithms are enabled. It's an error to disable an algorithm set - * by grpc_channel_args_set_compression_algorithm. - * - * Returns an instance with the updated algorithm states. The \a a pointer is - * modified to point to the returned instance (which may be different from the - * input value of \a a). */ -grpc_channel_args* grpc_channel_args_compression_algorithm_set_state( - grpc_channel_args** a, grpc_compression_algorithm algorithm, int enabled); - -/** Returns the bitset representing the support state (true for enabled, false - * for disabled) for compression algorithms. - * - * The i-th bit of the returned bitset corresponds to the i-th entry in the - * grpc_compression_algorithm enum. */ -uint32_t grpc_channel_args_compression_algorithm_get_states( - const grpc_channel_args* a); +inline void grpc_channel_args_destroy(const grpc_channel_args* a) { + grpc_channel_args_destroy(const_cast(a)); +} int grpc_channel_args_compare(const grpc_channel_args* a, const grpc_channel_args* b); -/** Returns a channel arg instance with socket mutator added. The socket mutator - * will perform its mutate_fd method on all file descriptors used by the - * channel. - * If \a a is non-MULL, its args are copied. */ -grpc_channel_args* grpc_channel_args_set_socket_mutator( - grpc_channel_args* a, grpc_socket_mutator* mutator); - /** Returns the value of argument \a name from \a args, or NULL if not found. */ const grpc_arg* grpc_channel_args_find(const grpc_channel_args* args, const char* name); diff --git a/src/core/lib/channel/channel_stack.h b/src/core/lib/channel/channel_stack.h index 0de8c670790..a7c28d059f3 100644 --- a/src/core/lib/channel/channel_stack.h +++ b/src/core/lib/channel/channel_stack.h @@ -42,7 +42,7 @@ #include #include "src/core/lib/debug/trace.h" -#include "src/core/lib/gpr/arena.h" +#include "src/core/lib/gprpp/arena.h" #include "src/core/lib/iomgr/call_combiner.h" #include "src/core/lib/iomgr/polling_entity.h" #include "src/core/lib/transport/transport.h" @@ -66,11 +66,11 @@ typedef struct { grpc_call_stack* call_stack; const void* server_transport_data; grpc_call_context_element* context; - grpc_slice path; + const grpc_slice& path; gpr_timespec start_time; grpc_millis deadline; - gpr_arena* arena; - grpc_call_combiner* call_combiner; + grpc_core::Arena* arena; + grpc_core::CallCombiner* call_combiner; } grpc_call_element_args; typedef struct { @@ -274,7 +274,11 @@ void grpc_call_log_op(const char* file, int line, gpr_log_severity severity, extern grpc_core::TraceFlag grpc_trace_channel; -#define GRPC_CALL_LOG_OP(sev, elem, op) \ - if (grpc_trace_channel.enabled()) grpc_call_log_op(sev, elem, op) +#define GRPC_CALL_LOG_OP(sev, elem, op) \ + do { \ + if (GRPC_TRACE_FLAG_ENABLED(grpc_trace_channel)) { \ + grpc_call_log_op(sev, elem, op); \ + } \ + } while (0) #endif /* GRPC_CORE_LIB_CHANNEL_CHANNEL_STACK_H */ diff --git a/src/core/lib/channel/channel_trace.cc b/src/core/lib/channel/channel_trace.cc index f0d21db32a8..d329ccc98de 100644 --- a/src/core/lib/channel/channel_trace.cc +++ b/src/core/lib/channel/channel_trace.cc @@ -41,7 +41,7 @@ namespace grpc_core { namespace channelz { -ChannelTrace::TraceEvent::TraceEvent(Severity severity, grpc_slice data, +ChannelTrace::TraceEvent::TraceEvent(Severity severity, const grpc_slice& data, RefCountedPtr referenced_entity) : severity_(severity), data_(data), @@ -51,7 +51,7 @@ ChannelTrace::TraceEvent::TraceEvent(Severity severity, grpc_slice data, referenced_entity_(std::move(referenced_entity)), memory_usage_(sizeof(TraceEvent) + grpc_slice_memory_usage(data)) {} -ChannelTrace::TraceEvent::TraceEvent(Severity severity, grpc_slice data) +ChannelTrace::TraceEvent::TraceEvent(Severity severity, const grpc_slice& data) : severity_(severity), data_(data), timestamp_(grpc_millis_to_timespec(grpc_core::ExecCtx::Get()->Now(), @@ -107,7 +107,7 @@ void ChannelTrace::AddTraceEventHelper(TraceEvent* new_trace_event) { } } -void ChannelTrace::AddTraceEvent(Severity severity, grpc_slice data) { +void ChannelTrace::AddTraceEvent(Severity severity, const grpc_slice& data) { if (max_event_memory_ == 0) { grpc_slice_unref_internal(data); return; // tracing is disabled if max_event_memory_ == 0 @@ -116,7 +116,7 @@ void ChannelTrace::AddTraceEvent(Severity severity, grpc_slice data) { } void ChannelTrace::AddTraceEventWithReference( - Severity severity, grpc_slice data, + Severity severity, const grpc_slice& data, RefCountedPtr referenced_entity) { if (max_event_memory_ == 0) { grpc_slice_unref_internal(data); diff --git a/src/core/lib/channel/channel_trace.h b/src/core/lib/channel/channel_trace.h index 8ff91ee8c81..f088185a423 100644 --- a/src/core/lib/channel/channel_trace.h +++ b/src/core/lib/channel/channel_trace.h @@ -62,7 +62,7 @@ class ChannelTrace { // TODO(ncteisen): as this call is used more and more throughout the gRPC // stack, determine if it makes more sense to accept a char* instead of a // slice. - void AddTraceEvent(Severity severity, grpc_slice data); + void AddTraceEvent(Severity severity, const grpc_slice& data); // Adds a new trace event to the tracing object. This trace event refers to a // an event that concerns a different channelz entity. For example, if this @@ -72,7 +72,7 @@ class ChannelTrace { // NOTE: see the note in the method above. // // TODO(ncteisen): see the todo in the method above. - void AddTraceEventWithReference(Severity severity, grpc_slice data, + void AddTraceEventWithReference(Severity severity, const grpc_slice& data, RefCountedPtr referenced_entity); // Creates and returns the raw grpc_json object, so a parent channelz @@ -87,12 +87,12 @@ class ChannelTrace { class TraceEvent { public: // Constructor for a TraceEvent that references a channel. - TraceEvent(Severity severity, grpc_slice data, + TraceEvent(Severity severity, const grpc_slice& data, RefCountedPtr referenced_entity_); // Constructor for a TraceEvent that does not reverence a different // channel. - TraceEvent(Severity severity, grpc_slice data); + TraceEvent(Severity severity, const grpc_slice& data); ~TraceEvent(); diff --git a/src/core/lib/channel/channelz.cc b/src/core/lib/channel/channelz.cc index 8d589f5983e..0eed9a59fef 100644 --- a/src/core/lib/channel/channelz.cc +++ b/src/core/lib/channel/channelz.cc @@ -203,33 +203,34 @@ ServerNode::ServerNode(grpc_server* server, size_t channel_tracer_max_nodes) ServerNode::~ServerNode() {} -char* ServerNode::RenderServerSockets(intptr_t start_socket_id) { +char* ServerNode::RenderServerSockets(intptr_t start_socket_id, + intptr_t max_results) { + // if user does not set max_results, we choose 500. + size_t pagination_limit = max_results == 0 ? 500 : max_results; grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT); grpc_json* json = top_level_json; grpc_json* json_iterator = nullptr; - ChildRefsList socket_refs; - // uuids index into entities one-off (idx 0 is really uuid 1, since 0 is - // reserved). However, we want to support requests coming in with - // start_server_id=0, which signifies "give me everything." - size_t start_idx = start_socket_id == 0 ? 0 : start_socket_id - 1; - grpc_server_populate_server_sockets(server_, &socket_refs, start_idx); + ChildSocketsList socket_refs; + grpc_server_populate_server_sockets(server_, &socket_refs, start_socket_id); + // declared early so it can be used outside of the loop. + size_t i = 0; if (!socket_refs.empty()) { // create list of socket refs grpc_json* array_parent = grpc_json_create_child( nullptr, json, "socketRef", nullptr, GRPC_JSON_ARRAY, false); - for (size_t i = 0; i < socket_refs.size(); ++i) { - json_iterator = - grpc_json_create_child(json_iterator, array_parent, nullptr, nullptr, - GRPC_JSON_OBJECT, false); - grpc_json_add_number_string_child(json_iterator, nullptr, "socketId", - socket_refs[i]); + for (i = 0; i < GPR_MIN(socket_refs.size(), pagination_limit); ++i) { + grpc_json* socket_ref_json = grpc_json_create_child( + nullptr, array_parent, nullptr, nullptr, GRPC_JSON_OBJECT, false); + json_iterator = grpc_json_add_number_string_child( + socket_ref_json, nullptr, "socketId", socket_refs[i]->uuid()); + grpc_json_create_child(json_iterator, socket_ref_json, "name", + socket_refs[i]->remote(), GRPC_JSON_STRING, false); } } - // For now we do not have any pagination rules. In the future we could - // pick a constant for max_channels_sent for a GetServers request. - // Tracking: https://github.com/grpc/grpc/issues/16019. - json_iterator = grpc_json_create_child(nullptr, json, "end", nullptr, - GRPC_JSON_TRUE, false); + if (i == socket_refs.size()) { + json_iterator = grpc_json_create_child(nullptr, json, "end", nullptr, + GRPC_JSON_TRUE, false); + } char* json_str = grpc_json_dump_to_string(top_level_json, 0); grpc_json_destroy(top_level_json); return json_str; @@ -384,52 +385,65 @@ grpc_json* SocketNode::RenderJson() { json = data; json_iterator = nullptr; gpr_timespec ts; - if (streams_started_ != 0) { + gpr_atm streams_started = gpr_atm_no_barrier_load(&streams_started_); + if (streams_started != 0) { json_iterator = grpc_json_add_number_string_child( - json, json_iterator, "streamsStarted", streams_started_); - if (last_local_stream_created_millis_ != 0) { - ts = grpc_millis_to_timespec(last_local_stream_created_millis_, + json, json_iterator, "streamsStarted", streams_started); + gpr_atm last_local_stream_created_millis = + gpr_atm_no_barrier_load(&last_local_stream_created_millis_); + if (last_local_stream_created_millis != 0) { + ts = grpc_millis_to_timespec(last_local_stream_created_millis, GPR_CLOCK_REALTIME); json_iterator = grpc_json_create_child( json_iterator, json, "lastLocalStreamCreatedTimestamp", gpr_format_timespec(ts), GRPC_JSON_STRING, true); } - if (last_remote_stream_created_millis_ != 0) { - ts = grpc_millis_to_timespec(last_remote_stream_created_millis_, + gpr_atm last_remote_stream_created_millis = + gpr_atm_no_barrier_load(&last_remote_stream_created_millis_); + if (last_remote_stream_created_millis != 0) { + ts = grpc_millis_to_timespec(last_remote_stream_created_millis, GPR_CLOCK_REALTIME); json_iterator = grpc_json_create_child( json_iterator, json, "lastRemoteStreamCreatedTimestamp", gpr_format_timespec(ts), GRPC_JSON_STRING, true); } } - if (streams_succeeded_ != 0) { + gpr_atm streams_succeeded = gpr_atm_no_barrier_load(&streams_succeeded_); + if (streams_succeeded != 0) { json_iterator = grpc_json_add_number_string_child( - json, json_iterator, "streamsSucceeded", streams_succeeded_); + json, json_iterator, "streamsSucceeded", streams_succeeded); } - if (streams_failed_) { + gpr_atm streams_failed = gpr_atm_no_barrier_load(&streams_failed_); + if (streams_failed) { json_iterator = grpc_json_add_number_string_child( - json, json_iterator, "streamsFailed", streams_failed_); + json, json_iterator, "streamsFailed", streams_failed); } - if (messages_sent_ != 0) { + gpr_atm messages_sent = gpr_atm_no_barrier_load(&messages_sent_); + if (messages_sent != 0) { json_iterator = grpc_json_add_number_string_child( - json, json_iterator, "messagesSent", messages_sent_); - ts = grpc_millis_to_timespec(last_message_sent_millis_, GPR_CLOCK_REALTIME); + json, json_iterator, "messagesSent", messages_sent); + ts = grpc_millis_to_timespec( + gpr_atm_no_barrier_load(&last_message_sent_millis_), + GPR_CLOCK_REALTIME); json_iterator = grpc_json_create_child(json_iterator, json, "lastMessageSentTimestamp", gpr_format_timespec(ts), GRPC_JSON_STRING, true); } - if (messages_received_ != 0) { + gpr_atm messages_received = gpr_atm_no_barrier_load(&messages_received_); + if (messages_received != 0) { json_iterator = grpc_json_add_number_string_child( - json, json_iterator, "messagesReceived", messages_received_); - ts = grpc_millis_to_timespec(last_message_received_millis_, - GPR_CLOCK_REALTIME); + json, json_iterator, "messagesReceived", messages_received); + ts = grpc_millis_to_timespec( + gpr_atm_no_barrier_load(&last_message_received_millis_), + GPR_CLOCK_REALTIME); json_iterator = grpc_json_create_child( json_iterator, json, "lastMessageReceivedTimestamp", gpr_format_timespec(ts), GRPC_JSON_STRING, true); } - if (keepalives_sent_ != 0) { + gpr_atm keepalives_sent = gpr_atm_no_barrier_load(&keepalives_sent_); + if (keepalives_sent != 0) { json_iterator = grpc_json_add_number_string_child( - json, json_iterator, "keepAlivesSent", keepalives_sent_); + json, json_iterator, "keepAlivesSent", keepalives_sent); } return top_level_json; } diff --git a/src/core/lib/channel/channelz.h b/src/core/lib/channel/channelz.h index 64ab5cb3a65..e543cda1c2b 100644 --- a/src/core/lib/channel/channelz.h +++ b/src/core/lib/channel/channelz.h @@ -59,6 +59,9 @@ namespace channelz { // add human readable names as in the channelz.proto typedef InlinedVector ChildRefsList; +class SocketNode; +typedef InlinedVector ChildSocketsList; + namespace testing { class CallCountingHelperPeer; class ChannelNodePeer; @@ -177,11 +180,11 @@ class ChannelNode : public BaseNode { bool ChannelIsDestroyed() { return channel_ == nullptr; } // proxy methods to composed classes. - void AddTraceEvent(ChannelTrace::Severity severity, grpc_slice data) { + void AddTraceEvent(ChannelTrace::Severity severity, const grpc_slice& data) { trace_.AddTraceEvent(severity, data); } void AddTraceEventWithReference(ChannelTrace::Severity severity, - grpc_slice data, + const grpc_slice& data, RefCountedPtr referenced_channel) { trace_.AddTraceEventWithReference(severity, data, std::move(referenced_channel)); @@ -207,14 +210,15 @@ class ServerNode : public BaseNode { grpc_json* RenderJson() override; - char* RenderServerSockets(intptr_t start_socket_id); + char* RenderServerSockets(intptr_t start_socket_id, + intptr_t pagination_limit); // proxy methods to composed classes. - void AddTraceEvent(ChannelTrace::Severity severity, grpc_slice data) { + void AddTraceEvent(ChannelTrace::Severity severity, const grpc_slice& data) { trace_.AddTraceEvent(severity, data); } void AddTraceEventWithReference(ChannelTrace::Severity severity, - grpc_slice data, + const grpc_slice& data, RefCountedPtr referenced_channel) { trace_.AddTraceEventWithReference(severity, data, std::move(referenced_channel)); @@ -251,6 +255,8 @@ class SocketNode : public BaseNode { gpr_atm_no_barrier_fetch_add(&keepalives_sent_, static_cast(1)); } + const char* remote() { return remote_.get(); } + private: gpr_atm streams_started_ = 0; gpr_atm streams_succeeded_ = 0; diff --git a/src/core/lib/channel/channelz_registry.cc b/src/core/lib/channel/channelz_registry.cc index bc23b90a661..b6a660b18fd 100644 --- a/src/core/lib/channel/channelz_registry.cc +++ b/src/core/lib/channel/channelz_registry.cc @@ -23,7 +23,7 @@ #include "src/core/lib/channel/channelz_registry.h" #include "src/core/lib/gpr/useful.h" #include "src/core/lib/gprpp/memory.h" -#include "src/core/lib/gprpp/mutex_lock.h" +#include "src/core/lib/gprpp/sync.h" #include #include @@ -62,7 +62,7 @@ void ChannelzRegistry::InternalRegister(BaseNode* node) { } void ChannelzRegistry::MaybePerformCompactionLocked() { - constexpr double kEmptinessTheshold = 1 / 3; + constexpr double kEmptinessTheshold = 1. / 3; double emptiness_ratio = double(num_empty_slots_) / double(entities_.capacity()); if (emptiness_ratio > kEmptinessTheshold) { @@ -252,7 +252,8 @@ char* grpc_channelz_get_server(intptr_t server_id) { } char* grpc_channelz_get_server_sockets(intptr_t server_id, - intptr_t start_socket_id) { + intptr_t start_socket_id, + intptr_t max_results) { grpc_core::channelz::BaseNode* base_node = grpc_core::channelz::ChannelzRegistry::Get(server_id); if (base_node == nullptr || @@ -263,7 +264,7 @@ char* grpc_channelz_get_server_sockets(intptr_t server_id, // actually a server node grpc_core::channelz::ServerNode* server_node = static_cast(base_node); - return server_node->RenderServerSockets(start_socket_id); + return server_node->RenderServerSockets(start_socket_id, max_results); } char* grpc_channelz_get_channel(intptr_t channel_id) { diff --git a/src/core/lib/channel/connected_channel.cc b/src/core/lib/channel/connected_channel.cc index e2ea334dedf..bd30c3663a2 100644 --- a/src/core/lib/channel/connected_channel.cc +++ b/src/core/lib/channel/connected_channel.cc @@ -41,12 +41,12 @@ typedef struct connected_channel_channel_data { typedef struct { grpc_closure closure; grpc_closure* original_closure; - grpc_call_combiner* call_combiner; + grpc_core::CallCombiner* call_combiner; const char* reason; } callback_state; typedef struct connected_channel_call_data { - grpc_call_combiner* call_combiner; + grpc_core::CallCombiner* call_combiner; // Closures used for returning results on the call combiner. callback_state on_complete[6]; // Max number of pending batches. callback_state recv_initial_metadata_ready; diff --git a/src/core/lib/channel/context.h b/src/core/lib/channel/context.h index 763e4ffc9fe..fd9d0ce711a 100644 --- a/src/core/lib/channel/context.h +++ b/src/core/lib/channel/context.h @@ -35,8 +35,8 @@ typedef enum { /// Reserved for traffic_class_context. GRPC_CONTEXT_TRAFFIC, - /// Value is a \a grpc_grpclb_client_stats. - GRPC_GRPCLB_CLIENT_STATS, + /// Holds a pointer to ServiceConfig::CallData associated with this call. + GRPC_SERVICE_CONFIG_CALL_DATA, GRPC_CONTEXT_COUNT } grpc_context_index; diff --git a/src/core/lib/channel/handshaker.cc b/src/core/lib/channel/handshaker.cc index e516b56b743..27ff25084cb 100644 --- a/src/core/lib/channel/handshaker.cc +++ b/src/core/lib/channel/handshaker.cc @@ -30,164 +30,13 @@ #include "src/core/lib/iomgr/timer.h" #include "src/core/lib/slice/slice_internal.h" -grpc_core::TraceFlag grpc_handshaker_trace(false, "handshaker"); +namespace grpc_core { -// -// grpc_handshaker -// +TraceFlag grpc_handshaker_trace(false, "handshaker"); -void grpc_handshaker_init(const grpc_handshaker_vtable* vtable, - grpc_handshaker* handshaker) { - handshaker->vtable = vtable; -} +namespace { -void grpc_handshaker_destroy(grpc_handshaker* handshaker) { - handshaker->vtable->destroy(handshaker); -} - -void grpc_handshaker_shutdown(grpc_handshaker* handshaker, grpc_error* why) { - handshaker->vtable->shutdown(handshaker, why); -} - -void grpc_handshaker_do_handshake(grpc_handshaker* handshaker, - grpc_tcp_server_acceptor* acceptor, - grpc_closure* on_handshake_done, - grpc_handshaker_args* args) { - handshaker->vtable->do_handshake(handshaker, acceptor, on_handshake_done, - args); -} - -const char* grpc_handshaker_name(grpc_handshaker* handshaker) { - return handshaker->vtable->name; -} - -// -// grpc_handshake_manager -// - -struct grpc_handshake_manager { - gpr_mu mu; - gpr_refcount refs; - bool shutdown; - // An array of handshakers added via grpc_handshake_manager_add(). - size_t count; - grpc_handshaker** handshakers; - // The index of the handshaker to invoke next and closure to invoke it. - size_t index; - grpc_closure call_next_handshaker; - // The acceptor to call the handshakers with. - grpc_tcp_server_acceptor* acceptor; - // Deadline timer across all handshakers. - grpc_timer deadline_timer; - grpc_closure on_timeout; - // The final callback and user_data to invoke after the last handshaker. - grpc_closure on_handshake_done; - void* user_data; - // Handshaker args. - grpc_handshaker_args args; - // Links to the previous and next managers in a list of all pending handshakes - // Used at server side only. - grpc_handshake_manager* prev; - grpc_handshake_manager* next; -}; - -grpc_handshake_manager* grpc_handshake_manager_create() { - grpc_handshake_manager* mgr = static_cast( - gpr_zalloc(sizeof(grpc_handshake_manager))); - gpr_mu_init(&mgr->mu); - gpr_ref_init(&mgr->refs, 1); - return mgr; -} - -void grpc_handshake_manager_pending_list_add(grpc_handshake_manager** head, - grpc_handshake_manager* mgr) { - GPR_ASSERT(mgr->prev == nullptr); - GPR_ASSERT(mgr->next == nullptr); - mgr->next = *head; - if (*head) { - (*head)->prev = mgr; - } - *head = mgr; -} - -void grpc_handshake_manager_pending_list_remove(grpc_handshake_manager** head, - grpc_handshake_manager* mgr) { - if (mgr->next != nullptr) { - mgr->next->prev = mgr->prev; - } - if (mgr->prev != nullptr) { - mgr->prev->next = mgr->next; - } else { - GPR_ASSERT(*head == mgr); - *head = mgr->next; - } -} - -void grpc_handshake_manager_pending_list_shutdown_all( - grpc_handshake_manager* head, grpc_error* why) { - while (head != nullptr) { - grpc_handshake_manager_shutdown(head, GRPC_ERROR_REF(why)); - head = head->next; - } - GRPC_ERROR_UNREF(why); -} - -static bool is_power_of_2(size_t n) { return (n & (n - 1)) == 0; } - -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. - size_t realloc_count = 0; - if (mgr->count == 0) { - realloc_count = 2; - } else if (mgr->count >= 2 && is_power_of_2(mgr->count)) { - realloc_count = mgr->count * 2; - } - if (realloc_count > 0) { - mgr->handshakers = static_cast(gpr_realloc( - mgr->handshakers, realloc_count * sizeof(grpc_handshaker*))); - } - mgr->handshakers[mgr->count++] = handshaker; - gpr_mu_unlock(&mgr->mu); -} - -static void grpc_handshake_manager_unref(grpc_handshake_manager* mgr) { - if (gpr_unref(&mgr->refs)) { - for (size_t i = 0; i < mgr->count; ++i) { - grpc_handshaker_destroy(mgr->handshakers[i]); - } - gpr_free(mgr->handshakers); - gpr_mu_destroy(&mgr->mu); - gpr_free(mgr); - } -} - -void grpc_handshake_manager_destroy(grpc_handshake_manager* mgr) { - grpc_handshake_manager_unref(mgr); -} - -void grpc_handshake_manager_shutdown(grpc_handshake_manager* mgr, - grpc_error* why) { - gpr_mu_lock(&mgr->mu); - // Shutdown the handshaker that's currently in progress, if any. - if (!mgr->shutdown && mgr->index > 0) { - mgr->shutdown = true; - grpc_handshaker_shutdown(mgr->handshakers[mgr->index - 1], - GRPC_ERROR_REF(why)); - } - gpr_mu_unlock(&mgr->mu); - GRPC_ERROR_UNREF(why); -} - -static char* handshaker_args_string(grpc_handshaker_args* args) { +char* HandshakerArgsString(HandshakerArgs* 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 = @@ -202,130 +51,208 @@ static char* handshaker_args_string(grpc_handshaker_args* args) { return str; } +} // namespace + +HandshakeManager::HandshakeManager() { gpr_mu_init(&mu_); } + +/// Add \a mgr to the server side list of all pending handshake managers, the +/// list starts with \a *head. +// Not thread-safe. Caller needs to synchronize. +void HandshakeManager::AddToPendingMgrList(HandshakeManager** head) { + GPR_ASSERT(prev_ == nullptr); + GPR_ASSERT(next_ == nullptr); + next_ = *head; + if (*head) { + (*head)->prev_ = this; + } + *head = this; +} + +/// Remove \a mgr from the server side list of all pending handshake managers. +// Not thread-safe. Caller needs to synchronize. +void HandshakeManager::RemoveFromPendingMgrList(HandshakeManager** head) { + if (next_ != nullptr) { + next_->prev_ = prev_; + } + if (prev_ != nullptr) { + prev_->next_ = next_; + } else { + GPR_ASSERT(*head == this); + *head = next_; + } +} + +/// Shutdown all pending handshake managers starting at head on the server +/// side. Not thread-safe. Caller needs to synchronize. +void HandshakeManager::ShutdownAllPending(grpc_error* why) { + auto* head = this; + while (head != nullptr) { + head->Shutdown(GRPC_ERROR_REF(why)); + head = head->next_; + } + GRPC_ERROR_UNREF(why); +} + +void HandshakeManager::Add(RefCountedPtr handshaker) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_handshaker_trace)) { + gpr_log( + GPR_INFO, + "handshake_manager %p: adding handshaker %s [%p] at index %" PRIuPTR, + this, handshaker->name(), handshaker.get(), handshakers_.size()); + } + MutexLock lock(&mu_); + handshakers_.push_back(std::move(handshaker)); +} + +HandshakeManager::~HandshakeManager() { + handshakers_.clear(); + gpr_mu_destroy(&mu_); +} + +void HandshakeManager::Shutdown(grpc_error* why) { + { + MutexLock lock(&mu_); + // Shutdown the handshaker that's currently in progress, if any. + if (!is_shutdown_ && index_ > 0) { + is_shutdown_ = true; + handshakers_[index_ - 1]->Shutdown(GRPC_ERROR_REF(why)); + } + } + GRPC_ERROR_UNREF(why); +} + // 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); +bool HandshakeManager::CallNextHandshakerLocked(grpc_error* error) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_handshaker_trace)) { + char* args_str = HandshakerArgsString(&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); + this, grpc_error_string(error), is_shutdown_, index_, args_str); gpr_free(args_str); } - GPR_ASSERT(mgr->index <= mgr->count); + GPR_ASSERT(index_ <= handshakers_.size()); // 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 (error == GRPC_ERROR_NONE && mgr->shutdown) { + if (error != GRPC_ERROR_NONE || is_shutdown_ || args_.exit_early || + index_ == handshakers_.size()) { + if (error == GRPC_ERROR_NONE && is_shutdown_) { error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("handshaker shutdown"); // It is possible that the endpoint has already been destroyed by // a shutdown call while this callback was sitting on the ExecCtx // with no error. - if (mgr->args.endpoint != nullptr) { + if (args_.endpoint != nullptr) { // TODO(roth): It is currently necessary to shutdown endpoints // before destroying then, even when we know that there are no // pending read/write callbacks. This should be fixed, at which // point this can be removed. - grpc_endpoint_shutdown(mgr->args.endpoint, GRPC_ERROR_REF(error)); - grpc_endpoint_destroy(mgr->args.endpoint); - mgr->args.endpoint = nullptr; - grpc_channel_args_destroy(mgr->args.args); - mgr->args.args = nullptr; - grpc_slice_buffer_destroy_internal(mgr->args.read_buffer); - gpr_free(mgr->args.read_buffer); - mgr->args.read_buffer = nullptr; + grpc_endpoint_shutdown(args_.endpoint, GRPC_ERROR_REF(error)); + grpc_endpoint_destroy(args_.endpoint); + args_.endpoint = nullptr; + grpc_channel_args_destroy(args_.args); + args_.args = nullptr; + grpc_slice_buffer_destroy_internal(args_.read_buffer); + gpr_free(args_.read_buffer); + args_.read_buffer = nullptr; } } - if (grpc_handshaker_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_handshaker_trace)) { gpr_log(GPR_INFO, "handshake_manager %p: handshaking complete -- scheduling " "on_handshake_done with error=%s", - mgr, grpc_error_string(error)); + this, grpc_error_string(error)); } // 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; + grpc_timer_cancel(&deadline_timer_); + GRPC_CLOSURE_SCHED(&on_handshake_done_, error); + is_shutdown_ = true; } else { - if (grpc_handshaker_trace.enabled()) { + auto handshaker = handshakers_[index_]; + if (GRPC_TRACE_FLAG_ENABLED(grpc_handshaker_trace)) { 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); + this, handshaker->name(), handshaker.get(), index_); } - grpc_handshaker_do_handshake(mgr->handshakers[mgr->index], mgr->acceptor, - &mgr->call_next_handshaker, &mgr->args); + handshaker->DoHandshake(acceptor_, &call_next_handshaker_, &args_); } - ++mgr->index; - return mgr->shutdown; + ++index_; + return is_shutdown_; } -// A function used as the handshaker-done callback when chaining -// handshakers together. -static void call_next_handshaker(void* arg, grpc_error* error) { - grpc_handshake_manager* mgr = static_cast(arg); - gpr_mu_lock(&mgr->mu); - bool done = call_next_handshaker_locked(mgr, GRPC_ERROR_REF(error)); - gpr_mu_unlock(&mgr->mu); +void HandshakeManager::CallNextHandshakerFn(void* arg, grpc_error* error) { + auto* mgr = static_cast(arg); + bool done; + { + MutexLock lock(&mgr->mu_); + done = mgr->CallNextHandshakerLocked(GRPC_ERROR_REF(error)); + } // If we're invoked the final callback, we won't be coming back // to this function, so we can release our reference to the // handshake manager. if (done) { - grpc_handshake_manager_unref(mgr); + mgr->Unref(); } } -// Callback invoked when deadline is exceeded. -static void on_timeout(void* arg, grpc_error* error) { - grpc_handshake_manager* mgr = static_cast(arg); - if (error == GRPC_ERROR_NONE) { // Timer fired, rather than being cancelled. - grpc_handshake_manager_shutdown( - mgr, GRPC_ERROR_CREATE_FROM_STATIC_STRING("Handshake timed out")); +void HandshakeManager::OnTimeoutFn(void* arg, grpc_error* error) { + auto* mgr = static_cast(arg); + if (error == GRPC_ERROR_NONE) { // Timer fired, rather than being cancelled + mgr->Shutdown(GRPC_ERROR_CREATE_FROM_STATIC_STRING("Handshake timed out")); } - grpc_handshake_manager_unref(mgr); + mgr->Unref(); } -void grpc_handshake_manager_do_handshake(grpc_handshake_manager* mgr, - grpc_endpoint* endpoint, - const grpc_channel_args* channel_args, - grpc_millis deadline, - grpc_tcp_server_acceptor* acceptor, - grpc_iomgr_cb_func on_handshake_done, - void* user_data) { - gpr_mu_lock(&mgr->mu); - GPR_ASSERT(mgr->index == 0); - GPR_ASSERT(!mgr->shutdown); - // Construct handshaker args. These will be passed through all - // handshakers and eventually be freed by the on_handshake_done callback. - mgr->args.endpoint = endpoint; - mgr->args.args = grpc_channel_args_copy(channel_args); - mgr->args.user_data = user_data; - mgr->args.read_buffer = static_cast( - gpr_malloc(sizeof(*mgr->args.read_buffer))); - grpc_slice_buffer_init(mgr->args.read_buffer); - // Initialize state needed for calling handshakers. - mgr->acceptor = acceptor; - GRPC_CLOSURE_INIT(&mgr->call_next_handshaker, call_next_handshaker, mgr, - grpc_schedule_on_exec_ctx); - GRPC_CLOSURE_INIT(&mgr->on_handshake_done, on_handshake_done, &mgr->args, - grpc_schedule_on_exec_ctx); - // Start deadline timer, which owns a ref. - gpr_ref(&mgr->refs); - GRPC_CLOSURE_INIT(&mgr->on_timeout, on_timeout, mgr, - grpc_schedule_on_exec_ctx); - grpc_timer_init(&mgr->deadline_timer, deadline, &mgr->on_timeout); - // Start first handshaker, which also owns a ref. - gpr_ref(&mgr->refs); - bool done = call_next_handshaker_locked(mgr, GRPC_ERROR_NONE); - gpr_mu_unlock(&mgr->mu); +void HandshakeManager::DoHandshake(grpc_endpoint* endpoint, + const grpc_channel_args* channel_args, + grpc_millis deadline, + grpc_tcp_server_acceptor* acceptor, + grpc_iomgr_cb_func on_handshake_done, + void* user_data) { + bool done; + { + MutexLock lock(&mu_); + GPR_ASSERT(index_ == 0); + GPR_ASSERT(!is_shutdown_); + // Construct handshaker args. These will be passed through all + // handshakers and eventually be freed by the on_handshake_done callback. + args_.endpoint = endpoint; + args_.args = grpc_channel_args_copy(channel_args); + args_.user_data = user_data; + args_.read_buffer = + static_cast(gpr_malloc(sizeof(*args_.read_buffer))); + grpc_slice_buffer_init(args_.read_buffer); + // Initialize state needed for calling handshakers. + acceptor_ = acceptor; + GRPC_CLOSURE_INIT(&call_next_handshaker_, + &HandshakeManager::CallNextHandshakerFn, this, + grpc_schedule_on_exec_ctx); + GRPC_CLOSURE_INIT(&on_handshake_done_, on_handshake_done, &args_, + grpc_schedule_on_exec_ctx); + // Start deadline timer, which owns a ref. + Ref().release(); + GRPC_CLOSURE_INIT(&on_timeout_, &HandshakeManager::OnTimeoutFn, this, + grpc_schedule_on_exec_ctx); + grpc_timer_init(&deadline_timer_, deadline, &on_timeout_); + // Start first handshaker, which also owns a ref. + Ref().release(); + done = CallNextHandshakerLocked(GRPC_ERROR_NONE); + } if (done) { - grpc_handshake_manager_unref(mgr); + Unref(); } } + +} // namespace grpc_core + +void grpc_handshake_manager_add(grpc_handshake_manager* mgr, + grpc_handshaker* handshaker) { + // This is a transition method to aid the API change for handshakers. + using namespace grpc_core; + RefCountedPtr refd_hs(static_cast(handshaker)); + mgr->Add(refd_hs); +} diff --git a/src/core/lib/channel/handshaker.h b/src/core/lib/channel/handshaker.h index a65990fceb4..b68799b6e0e 100644 --- a/src/core/lib/channel/handshaker.h +++ b/src/core/lib/channel/handshaker.h @@ -21,12 +21,21 @@ #include +#include + #include +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gprpp/inlined_vector.h" +#include "src/core/lib/gprpp/ref_counted.h" +#include "src/core/lib/gprpp/sync.h" #include "src/core/lib/iomgr/closure.h" #include "src/core/lib/iomgr/endpoint.h" #include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/iomgr/tcp_server.h" +#include "src/core/lib/iomgr/timer.h" + +namespace grpc_core { /// Handshakers are used to perform initial handshakes on a connection /// before the client sends the initial request. Some examples of what @@ -35,12 +44,6 @@ /// /// In general, handshakers should be used via a handshake manager. -/// -/// grpc_handshaker -/// - -typedef struct grpc_handshaker grpc_handshaker; - /// Arguments passed through handshakers and to the on_handshake_done callback. /// /// For handshakers, all members are input/output parameters; for @@ -55,115 +58,121 @@ typedef struct grpc_handshaker grpc_handshaker; /// /// For the on_handshake_done callback, all members are input arguments, /// which the callback takes ownership of. -typedef struct { - grpc_endpoint* endpoint; - grpc_channel_args* args; - grpc_slice_buffer* read_buffer; +struct HandshakerArgs { + grpc_endpoint* endpoint = nullptr; + grpc_channel_args* args = nullptr; + grpc_slice_buffer* read_buffer = nullptr; // A handshaker may set this to true before invoking on_handshake_done // to indicate that subsequent handshakers should be skipped. - bool exit_early; + bool exit_early = false; // User data passed through the handshake manager. Not used by // individual handshakers. - void* user_data; -} grpc_handshaker_args; - -typedef struct { - /// Destroys the handshaker. - void (*destroy)(grpc_handshaker* handshaker); - - /// Shuts down the handshaker (e.g., to clean up when the operation is - /// aborted in the middle). - void (*shutdown)(grpc_handshaker* handshaker, grpc_error* why); - - /// Performs handshaking, modifying \a args as needed (e.g., to - /// replace \a endpoint with a wrapped endpoint). - /// When finished, invokes \a on_handshake_done. - /// \a acceptor will be NULL for client-side handshakers. - void (*do_handshake)(grpc_handshaker* handshaker, - 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 -/// implementation struct. -struct grpc_handshaker { - const grpc_handshaker_vtable* vtable; + void* user_data = nullptr; }; -/// Called by concrete implementations to initialize the base struct. -void grpc_handshaker_init(const grpc_handshaker_vtable* vtable, - grpc_handshaker* handshaker); - -void grpc_handshaker_destroy(grpc_handshaker* handshaker); -void grpc_handshaker_shutdown(grpc_handshaker* handshaker, grpc_error* why); -void grpc_handshaker_do_handshake(grpc_handshaker* handshaker, - 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 +/// Handshaker /// -typedef struct grpc_handshake_manager grpc_handshake_manager; +class Handshaker : public RefCounted { + public: + virtual ~Handshaker() = default; + virtual void Shutdown(grpc_error* why) GRPC_ABSTRACT; + virtual void DoHandshake(grpc_tcp_server_acceptor* acceptor, + grpc_closure* on_handshake_done, + HandshakerArgs* args) GRPC_ABSTRACT; + virtual const char* name() const GRPC_ABSTRACT; + GRPC_ABSTRACT_BASE_CLASS +}; -/// Creates a new handshake manager. Caller takes ownership. -grpc_handshake_manager* grpc_handshake_manager_create(); +// +// HandshakeManager +// -/// Adds a handshaker to the handshake manager. -/// Takes ownership of \a handshaker. +class HandshakeManager : public RefCounted { + public: + HandshakeManager(); + ~HandshakeManager(); + + /// Add \a mgr to the server side list of all pending handshake managers, the + /// list starts with \a *head. + // Not thread-safe. Caller needs to synchronize. + void AddToPendingMgrList(HandshakeManager** head); + + /// Remove \a mgr from the server side list of all pending handshake managers. + // Not thread-safe. Caller needs to synchronize. + void RemoveFromPendingMgrList(HandshakeManager** head); + + /// Shutdown all pending handshake managers starting at head on the server + /// side. Not thread-safe. Caller needs to synchronize. + void ShutdownAllPending(grpc_error* why); + + /// Adds a handshaker to the handshake manager. + /// Takes ownership of \a handshaker. + void Add(RefCountedPtr handshaker); + + /// Shuts down the handshake manager (e.g., to clean up when the operation is + /// aborted in the middle). + void Shutdown(grpc_error* why); + + /// Invokes handshakers in the order they were added. + /// Takes ownership of \a endpoint, and then passes that ownership to + /// the \a on_handshake_done callback. + /// Does NOT take ownership of \a channel_args. Instead, makes a copy before + /// invoking the first handshaker. + /// \a acceptor will be nullptr for client-side handshakers. + /// + /// When done, invokes \a on_handshake_done with a HandshakerArgs + /// object as its argument. If the callback is invoked with error != + /// GRPC_ERROR_NONE, then handshaking failed and the handshaker has done + /// the necessary clean-up. Otherwise, the callback takes ownership of + /// the arguments. + void DoHandshake(grpc_endpoint* endpoint, + const grpc_channel_args* channel_args, grpc_millis deadline, + grpc_tcp_server_acceptor* acceptor, + grpc_iomgr_cb_func on_handshake_done, void* user_data); + + private: + bool CallNextHandshakerLocked(grpc_error* error); + + // A function used as the handshaker-done callback when chaining + // handshakers together. + static void CallNextHandshakerFn(void* arg, grpc_error* error); + + // Callback invoked when deadline is exceeded. + static void OnTimeoutFn(void* arg, grpc_error* error); + + static const size_t HANDSHAKERS_INIT_SIZE = 2; + + gpr_mu mu_; + bool is_shutdown_ = false; + // An array of handshakers added via grpc_handshake_manager_add(). + InlinedVector, HANDSHAKERS_INIT_SIZE> handshakers_; + // The index of the handshaker to invoke next and closure to invoke it. + size_t index_ = 0; + grpc_closure call_next_handshaker_; + // The acceptor to call the handshakers with. + grpc_tcp_server_acceptor* acceptor_; + // Deadline timer across all handshakers. + grpc_timer deadline_timer_; + grpc_closure on_timeout_; + // The final callback and user_data to invoke after the last handshaker. + grpc_closure on_handshake_done_; + // Handshaker args. + HandshakerArgs args_; + // Links to the previous and next managers in a list of all pending handshakes + // Used at server side only. + HandshakeManager* prev_ = nullptr; + HandshakeManager* next_ = nullptr; +}; + +} // namespace grpc_core + +// TODO(arjunroy): These are transitional to account for the new handshaker API +// and will eventually be removed entirely. +typedef grpc_core::HandshakeManager grpc_handshake_manager; +typedef grpc_core::Handshaker grpc_handshaker; void grpc_handshake_manager_add(grpc_handshake_manager* mgr, grpc_handshaker* handshaker); -/// Destroys the handshake manager. -void grpc_handshake_manager_destroy(grpc_handshake_manager* mgr); - -/// Shuts down the handshake manager (e.g., to clean up when the operation is -/// aborted in the middle). -/// The caller must still call grpc_handshake_manager_destroy() after -/// calling this function. -void grpc_handshake_manager_shutdown(grpc_handshake_manager* mgr, - grpc_error* why); - -/// Invokes handshakers in the order they were added. -/// Takes ownership of \a endpoint, and then passes that ownership to -/// the \a on_handshake_done callback. -/// Does NOT take ownership of \a channel_args. Instead, makes a copy before -/// invoking the first handshaker. -/// \a acceptor will be nullptr for client-side handshakers. -/// -/// When done, invokes \a on_handshake_done with a grpc_handshaker_args -/// object as its argument. If the callback is invoked with error != -/// GRPC_ERROR_NONE, then handshaking failed and the handshaker has done -/// the necessary clean-up. Otherwise, the callback takes ownership of -/// the arguments. -void grpc_handshake_manager_do_handshake(grpc_handshake_manager* mgr, - grpc_endpoint* endpoint, - const grpc_channel_args* channel_args, - grpc_millis deadline, - grpc_tcp_server_acceptor* acceptor, - grpc_iomgr_cb_func on_handshake_done, - void* user_data); - -/// Add \a mgr to the server side list of all pending handshake managers, the -/// list starts with \a *head. -// Not thread-safe. Caller needs to synchronize. -void grpc_handshake_manager_pending_list_add(grpc_handshake_manager** head, - grpc_handshake_manager* mgr); - -/// Remove \a mgr from the server side list of all pending handshake managers. -// Not thread-safe. Caller needs to synchronize. -void grpc_handshake_manager_pending_list_remove(grpc_handshake_manager** head, - grpc_handshake_manager* mgr); - -/// Shutdown all pending handshake managers on the server side. -// Not thread-safe. Caller needs to synchronize. -void grpc_handshake_manager_pending_list_shutdown_all( - grpc_handshake_manager* head, grpc_error* why); - #endif /* GRPC_CORE_LIB_CHANNEL_HANDSHAKER_H */ diff --git a/src/core/lib/channel/handshaker_factory.cc b/src/core/lib/channel/handshaker_factory.cc deleted file mode 100644 index 8ade8fe4e23..00000000000 --- a/src/core/lib/channel/handshaker_factory.cc +++ /dev/null @@ -1,42 +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. - * - */ - -#include - -#include "src/core/lib/channel/handshaker_factory.h" - -#include - -void grpc_handshaker_factory_add_handshakers( - grpc_handshaker_factory* handshaker_factory, const grpc_channel_args* args, - grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr) { - if (handshaker_factory != nullptr) { - GPR_ASSERT(handshaker_factory->vtable != nullptr); - handshaker_factory->vtable->add_handshakers( - handshaker_factory, args, interested_parties, handshake_mgr); - } -} - -void grpc_handshaker_factory_destroy( - grpc_handshaker_factory* handshaker_factory) { - if (handshaker_factory != nullptr) { - GPR_ASSERT(handshaker_factory->vtable != nullptr); - handshaker_factory->vtable->destroy(handshaker_factory); - } -} diff --git a/src/core/lib/channel/handshaker_factory.h b/src/core/lib/channel/handshaker_factory.h index e17a6781798..3972af1f439 100644 --- a/src/core/lib/channel/handshaker_factory.h +++ b/src/core/lib/channel/handshaker_factory.h @@ -27,26 +27,18 @@ // A handshaker factory is used to create handshakers. -typedef struct grpc_handshaker_factory grpc_handshaker_factory; +namespace grpc_core { -typedef struct { - void (*add_handshakers)(grpc_handshaker_factory* handshaker_factory, - const grpc_channel_args* args, - grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr); - void (*destroy)(grpc_handshaker_factory* handshaker_factory); -} grpc_handshaker_factory_vtable; +class HandshakerFactory { + public: + virtual void AddHandshakers(const grpc_channel_args* args, + grpc_pollset_set* interested_parties, + HandshakeManager* handshake_mgr) GRPC_ABSTRACT; + virtual ~HandshakerFactory() = default; -struct grpc_handshaker_factory { - const grpc_handshaker_factory_vtable* vtable; + GRPC_ABSTRACT_BASE_CLASS }; -void grpc_handshaker_factory_add_handshakers( - grpc_handshaker_factory* handshaker_factory, const grpc_channel_args* args, - grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr); - -void grpc_handshaker_factory_destroy( - grpc_handshaker_factory* handshaker_factory); +} // namespace grpc_core #endif /* GRPC_CORE_LIB_CHANNEL_HANDSHAKER_FACTORY_H */ diff --git a/src/core/lib/channel/handshaker_registry.cc b/src/core/lib/channel/handshaker_registry.cc index fbafc43e795..199cb877497 100644 --- a/src/core/lib/channel/handshaker_registry.cc +++ b/src/core/lib/channel/handshaker_registry.cc @@ -19,8 +19,12 @@ #include #include "src/core/lib/channel/handshaker_registry.h" +#include "src/core/lib/gpr/alloc.h" +#include "src/core/lib/gprpp/inlined_vector.h" +#include "src/core/lib/gprpp/memory.h" #include +#include #include @@ -28,74 +32,86 @@ // grpc_handshaker_factory_list // -typedef struct { - grpc_handshaker_factory** list; - size_t num_factories; -} grpc_handshaker_factory_list; +namespace grpc_core { -static void grpc_handshaker_factory_list_register( - grpc_handshaker_factory_list* list, bool at_start, - grpc_handshaker_factory* factory) { - list->list = static_cast(gpr_realloc( - list->list, - (list->num_factories + 1) * sizeof(grpc_handshaker_factory*))); +namespace { + +class HandshakerFactoryList { + public: + void Register(bool at_start, UniquePtr factory); + void AddHandshakers(const grpc_channel_args* args, + grpc_pollset_set* interested_parties, + HandshakeManager* handshake_mgr); + + private: + InlinedVector, 2> factories_; +}; + +HandshakerFactoryList* g_handshaker_factory_lists = nullptr; + +} // namespace + +void HandshakerFactoryList::Register(bool at_start, + UniquePtr factory) { + factories_.push_back(std::move(factory)); if (at_start) { - memmove(list->list + 1, list->list, - sizeof(grpc_handshaker_factory*) * list->num_factories); - list->list[0] = factory; - } else { - list->list[list->num_factories] = factory; - } - ++list->num_factories; -} - -static void grpc_handshaker_factory_list_add_handshakers( - grpc_handshaker_factory_list* list, const grpc_channel_args* args, - grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr) { - for (size_t i = 0; i < list->num_factories; ++i) { - grpc_handshaker_factory_add_handshakers(list->list[i], args, - interested_parties, handshake_mgr); + auto* end = &factories_[factories_.size() - 1]; + std::rotate(&factories_[0], end, end + 1); } } -static void grpc_handshaker_factory_list_destroy( - grpc_handshaker_factory_list* list) { - for (size_t i = 0; i < list->num_factories; ++i) { - grpc_handshaker_factory_destroy(list->list[i]); +void HandshakerFactoryList::AddHandshakers(const grpc_channel_args* args, + grpc_pollset_set* interested_parties, + HandshakeManager* handshake_mgr) { + for (size_t idx = 0; idx < factories_.size(); ++idx) { + auto& handshaker_factory = factories_[idx]; + handshaker_factory->AddHandshakers(args, interested_parties, handshake_mgr); } - gpr_free(list->list); } // // plugin // -static grpc_handshaker_factory_list - g_handshaker_factory_lists[NUM_HANDSHAKER_TYPES]; +void HandshakerRegistry::Init() { + GPR_ASSERT(g_handshaker_factory_lists == nullptr); + g_handshaker_factory_lists = + static_cast(gpr_malloc_aligned( + sizeof(*g_handshaker_factory_lists) * NUM_HANDSHAKER_TYPES, + GPR_MAX_ALIGNMENT)); -void grpc_handshaker_factory_registry_init() { - memset(g_handshaker_factory_lists, 0, sizeof(g_handshaker_factory_lists)); -} - -void grpc_handshaker_factory_registry_shutdown() { - for (size_t i = 0; i < NUM_HANDSHAKER_TYPES; ++i) { - grpc_handshaker_factory_list_destroy(&g_handshaker_factory_lists[i]); + GPR_ASSERT(g_handshaker_factory_lists != nullptr); + for (auto idx = 0; idx < NUM_HANDSHAKER_TYPES; ++idx) { + auto factory_list = g_handshaker_factory_lists + idx; + new (factory_list) HandshakerFactoryList(); } } -void grpc_handshaker_factory_register(bool at_start, - grpc_handshaker_type handshaker_type, - grpc_handshaker_factory* factory) { - grpc_handshaker_factory_list_register( - &g_handshaker_factory_lists[handshaker_type], at_start, factory); +void HandshakerRegistry::Shutdown() { + GPR_ASSERT(g_handshaker_factory_lists != nullptr); + for (auto idx = 0; idx < NUM_HANDSHAKER_TYPES; ++idx) { + auto factory_list = g_handshaker_factory_lists + idx; + factory_list->~HandshakerFactoryList(); + } + gpr_free_aligned(g_handshaker_factory_lists); + g_handshaker_factory_lists = nullptr; } -void grpc_handshakers_add(grpc_handshaker_type handshaker_type, - const grpc_channel_args* args, - grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr) { - grpc_handshaker_factory_list_add_handshakers( - &g_handshaker_factory_lists[handshaker_type], args, interested_parties, - handshake_mgr); +void HandshakerRegistry::RegisterHandshakerFactory( + bool at_start, HandshakerType handshaker_type, + UniquePtr factory) { + GPR_ASSERT(g_handshaker_factory_lists != nullptr); + auto& factory_list = g_handshaker_factory_lists[handshaker_type]; + factory_list.Register(at_start, std::move(factory)); } + +void HandshakerRegistry::AddHandshakers(HandshakerType handshaker_type, + const grpc_channel_args* args, + grpc_pollset_set* interested_parties, + HandshakeManager* handshake_mgr) { + GPR_ASSERT(g_handshaker_factory_lists != nullptr); + auto& factory_list = g_handshaker_factory_lists[handshaker_type]; + factory_list.AddHandshakers(args, interested_parties, handshake_mgr); +} + +} // namespace grpc_core diff --git a/src/core/lib/channel/handshaker_registry.h b/src/core/lib/channel/handshaker_registry.h index 3dd4316de67..1b93a8dd47e 100644 --- a/src/core/lib/channel/handshaker_registry.h +++ b/src/core/lib/channel/handshaker_registry.h @@ -25,25 +25,30 @@ #include "src/core/lib/channel/handshaker_factory.h" +namespace grpc_core { + typedef enum { HANDSHAKER_CLIENT = 0, HANDSHAKER_SERVER, NUM_HANDSHAKER_TYPES, // Must be last. -} grpc_handshaker_type; +} HandshakerType; -void grpc_handshaker_factory_registry_init(); -void grpc_handshaker_factory_registry_shutdown(); +class HandshakerRegistry { + public: + /// Registers a new handshaker factory. Takes ownership. + /// If \a at_start is true, the new handshaker will be at the beginning of + /// the list. Otherwise, it will be added to the end. + static void RegisterHandshakerFactory(bool at_start, + HandshakerType handshaker_type, + UniquePtr factory); + static void AddHandshakers(HandshakerType handshaker_type, + const grpc_channel_args* args, + grpc_pollset_set* interested_parties, + HandshakeManager* handshake_mgr); + static void Init(); + static void Shutdown(); +}; -/// Registers a new handshaker factory. Takes ownership. -/// If \a at_start is true, the new handshaker will be at the beginning of -/// the list. Otherwise, it will be added to the end. -void grpc_handshaker_factory_register(bool at_start, - grpc_handshaker_type handshaker_type, - grpc_handshaker_factory* factory); - -void grpc_handshakers_add(grpc_handshaker_type handshaker_type, - const grpc_channel_args* args, - grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr); +} // namespace grpc_core #endif /* GRPC_CORE_LIB_CHANNEL_HANDSHAKER_REGISTRY_H */ diff --git a/src/core/lib/compression/algorithm_metadata.h b/src/core/lib/compression/algorithm_metadata.h index 1be79e59c00..d58d2f541a0 100644 --- a/src/core/lib/compression/algorithm_metadata.h +++ b/src/core/lib/compression/algorithm_metadata.h @@ -32,7 +32,7 @@ grpc_slice grpc_compression_algorithm_slice( /** Find compression algorithm based on passed in mdstr - returns * GRPC_COMPRESS_ALGORITHM_COUNT on failure */ grpc_compression_algorithm grpc_compression_algorithm_from_slice( - grpc_slice str); + const grpc_slice& str); /** Return compression algorithm based metadata element */ grpc_mdelem grpc_compression_encoding_mdelem( @@ -51,11 +51,11 @@ grpc_mdelem grpc_stream_compression_encoding_mdelem( /** Find compression algorithm based on passed in mdstr - returns * GRPC_COMPRESS_ALGORITHM_COUNT on failure */ grpc_message_compression_algorithm -grpc_message_compression_algorithm_from_slice(grpc_slice str); +grpc_message_compression_algorithm_from_slice(const grpc_slice& str); /** Find stream compression algorithm based on passed in mdstr - returns * GRPC_STREAM_COMPRESS_ALGORITHM_COUNT on failure */ grpc_stream_compression_algorithm grpc_stream_compression_algorithm_from_slice( - grpc_slice str); + const grpc_slice& str); #endif /* GRPC_CORE_LIB_COMPRESSION_ALGORITHM_METADATA_H */ diff --git a/src/core/lib/compression/compression.cc b/src/core/lib/compression/compression.cc index 48717541a76..a3a069d9266 100644 --- a/src/core/lib/compression/compression.cc +++ b/src/core/lib/compression/compression.cc @@ -26,6 +26,7 @@ #include "src/core/lib/compression/algorithm_metadata.h" #include "src/core/lib/compression/compression_internal.h" #include "src/core/lib/gpr/useful.h" +#include "src/core/lib/slice/slice_utils.h" #include "src/core/lib/surface/api_trace.h" #include "src/core/lib/transport/static_metadata.h" @@ -42,16 +43,17 @@ int grpc_compression_algorithm_is_stream(grpc_compression_algorithm algorithm) { int grpc_compression_algorithm_parse(grpc_slice name, grpc_compression_algorithm* algorithm) { - if (grpc_slice_eq(name, GRPC_MDSTR_IDENTITY)) { + if (grpc_slice_eq_static_interned(name, GRPC_MDSTR_IDENTITY)) { *algorithm = GRPC_COMPRESS_NONE; return 1; - } else if (grpc_slice_eq(name, GRPC_MDSTR_DEFLATE)) { + } else if (grpc_slice_eq_static_interned(name, GRPC_MDSTR_DEFLATE)) { *algorithm = GRPC_COMPRESS_DEFLATE; return 1; - } else if (grpc_slice_eq(name, GRPC_MDSTR_GZIP)) { + } else if (grpc_slice_eq_static_interned(name, GRPC_MDSTR_GZIP)) { *algorithm = GRPC_COMPRESS_GZIP; return 1; - } else if (grpc_slice_eq(name, GRPC_MDSTR_STREAM_SLASH_GZIP)) { + } else if (grpc_slice_eq_static_interned(name, + GRPC_MDSTR_STREAM_SLASH_GZIP)) { *algorithm = GRPC_COMPRESS_STREAM_GZIP; return 1; } else { @@ -147,11 +149,14 @@ grpc_slice grpc_compression_algorithm_slice( } grpc_compression_algorithm grpc_compression_algorithm_from_slice( - grpc_slice str) { - if (grpc_slice_eq(str, GRPC_MDSTR_IDENTITY)) return GRPC_COMPRESS_NONE; - if (grpc_slice_eq(str, GRPC_MDSTR_DEFLATE)) return GRPC_COMPRESS_DEFLATE; - if (grpc_slice_eq(str, GRPC_MDSTR_GZIP)) return GRPC_COMPRESS_GZIP; - if (grpc_slice_eq(str, GRPC_MDSTR_STREAM_SLASH_GZIP)) + const grpc_slice& str) { + if (grpc_slice_eq_static_interned(str, GRPC_MDSTR_IDENTITY)) + return GRPC_COMPRESS_NONE; + if (grpc_slice_eq_static_interned(str, GRPC_MDSTR_DEFLATE)) + return GRPC_COMPRESS_DEFLATE; + if (grpc_slice_eq_static_interned(str, GRPC_MDSTR_GZIP)) + return GRPC_COMPRESS_GZIP; + if (grpc_slice_eq_static_interned(str, GRPC_MDSTR_STREAM_SLASH_GZIP)) return GRPC_COMPRESS_STREAM_GZIP; return GRPC_COMPRESS_ALGORITHMS_COUNT; } diff --git a/src/core/lib/compression/compression_args.cc b/src/core/lib/compression/compression_args.cc new file mode 100644 index 00000000000..6a8232dc033 --- /dev/null +++ b/src/core/lib/compression/compression_args.cc @@ -0,0 +1,127 @@ +/* + * + * 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 + +#include +#include + +#include +#include +#include +#include +#include + +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/compression/compression_args.h" +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/gpr/useful.h" + +grpc_compression_algorithm grpc_channel_args_get_compression_algorithm( + const grpc_channel_args* a) { + size_t i; + if (a == nullptr) return GRPC_COMPRESS_NONE; + for (i = 0; i < a->num_args; ++i) { + if (a->args[i].type == GRPC_ARG_INTEGER && + !strcmp(GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM, a->args[i].key)) { + return static_cast(a->args[i].value.integer); + break; + } + } + return GRPC_COMPRESS_NONE; +} + +grpc_channel_args* grpc_channel_args_set_compression_algorithm( + grpc_channel_args* a, grpc_compression_algorithm algorithm) { + GPR_ASSERT(algorithm < GRPC_COMPRESS_ALGORITHMS_COUNT); + grpc_arg tmp; + tmp.type = GRPC_ARG_INTEGER; + tmp.key = (char*)GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM; + tmp.value.integer = algorithm; + return grpc_channel_args_copy_and_add(a, &tmp, 1); +} + +/** Returns 1 if the argument for compression algorithm's enabled states bitset + * was found in \a a, returning the arg's value in \a states. Otherwise, returns + * 0. */ +static int find_compression_algorithm_states_bitset(const grpc_channel_args* a, + int** states_arg) { + if (a != nullptr) { + size_t i; + for (i = 0; i < a->num_args; ++i) { + if (a->args[i].type == GRPC_ARG_INTEGER && + !strcmp(GRPC_COMPRESSION_CHANNEL_ENABLED_ALGORITHMS_BITSET, + a->args[i].key)) { + *states_arg = &a->args[i].value.integer; + **states_arg |= 0x1; /* forcefully enable support for no compression */ + return 1; + } + } + } + return 0; /* GPR_FALSE */ +} + +grpc_channel_args* grpc_channel_args_compression_algorithm_set_state( + grpc_channel_args** a, grpc_compression_algorithm algorithm, int state) { + int* states_arg = nullptr; + grpc_channel_args* result = *a; + const int states_arg_found = + find_compression_algorithm_states_bitset(*a, &states_arg); + + if (grpc_channel_args_get_compression_algorithm(*a) == algorithm && + state == 0) { + const char* algo_name = nullptr; + GPR_ASSERT(grpc_compression_algorithm_name(algorithm, &algo_name) != 0); + gpr_log(GPR_ERROR, + "Tried to disable default compression algorithm '%s'. The " + "operation has been ignored.", + algo_name); + } else if (states_arg_found) { + if (state != 0) { + GPR_BITSET((unsigned*)states_arg, algorithm); + } else if (algorithm != GRPC_COMPRESS_NONE) { + GPR_BITCLEAR((unsigned*)states_arg, algorithm); + } + } else { + /* create a new arg */ + grpc_arg tmp; + tmp.type = GRPC_ARG_INTEGER; + tmp.key = (char*)GRPC_COMPRESSION_CHANNEL_ENABLED_ALGORITHMS_BITSET; + /* all enabled by default */ + tmp.value.integer = (1u << GRPC_COMPRESS_ALGORITHMS_COUNT) - 1; + if (state != 0) { + GPR_BITSET((unsigned*)&tmp.value.integer, algorithm); + } else if (algorithm != GRPC_COMPRESS_NONE) { + GPR_BITCLEAR((unsigned*)&tmp.value.integer, algorithm); + } + result = grpc_channel_args_copy_and_add(*a, &tmp, 1); + grpc_channel_args_destroy(*a); + *a = result; + } + return result; +} + +uint32_t grpc_channel_args_compression_algorithm_get_states( + const grpc_channel_args* a) { + int* states_arg; + if (find_compression_algorithm_states_bitset(a, &states_arg)) { + return static_cast(*states_arg); + } else { + return (1u << GRPC_COMPRESS_ALGORITHMS_COUNT) - 1; /* All algs. enabled */ + } +} diff --git a/src/core/lib/compression/compression_args.h b/src/core/lib/compression/compression_args.h new file mode 100644 index 00000000000..407d6e2b8ca --- /dev/null +++ b/src/core/lib/compression/compression_args.h @@ -0,0 +1,55 @@ +/* + * + * 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 GRPC_CORE_LIB_COMPRESSION_COMPRESSION_ARGS_H +#define GRPC_CORE_LIB_COMPRESSION_COMPRESSION_ARGS_H + +#include + +#include +#include + +/** Returns the compression algorithm set in \a a. */ +grpc_compression_algorithm grpc_channel_args_get_compression_algorithm( + const grpc_channel_args* a); + +/** Returns a channel arg instance with compression enabled. If \a a is + * non-NULL, its args are copied. N.B. GRPC_COMPRESS_NONE disables compression + * for the channel. */ +grpc_channel_args* grpc_channel_args_set_compression_algorithm( + grpc_channel_args* a, grpc_compression_algorithm algorithm); + +/** Sets the support for the given compression algorithm. By default, all + * compression algorithms are enabled. It's an error to disable an algorithm set + * by grpc_channel_args_set_compression_algorithm. + * + * Returns an instance with the updated algorithm states. The \a a pointer is + * modified to point to the returned instance (which may be different from the + * input value of \a a). */ +grpc_channel_args* grpc_channel_args_compression_algorithm_set_state( + grpc_channel_args** a, grpc_compression_algorithm algorithm, int state); + +/** Returns the bitset representing the support state (true for enabled, false + * for disabled) for compression algorithms. + * + * The i-th bit of the returned bitset corresponds to the i-th entry in the + * grpc_compression_algorithm enum. */ +uint32_t grpc_channel_args_compression_algorithm_get_states( + const grpc_channel_args* a); + +#endif /* GRPC_CORE_LIB_COMPRESSION_COMPRESSION_ARGS_H */ diff --git a/src/core/lib/compression/compression_internal.cc b/src/core/lib/compression/compression_internal.cc index 538514caf37..e0d73ef6d83 100644 --- a/src/core/lib/compression/compression_internal.cc +++ b/src/core/lib/compression/compression_internal.cc @@ -26,25 +26,29 @@ #include "src/core/lib/compression/algorithm_metadata.h" #include "src/core/lib/compression/compression_internal.h" #include "src/core/lib/gpr/useful.h" +#include "src/core/lib/slice/slice_utils.h" #include "src/core/lib/surface/api_trace.h" #include "src/core/lib/transport/static_metadata.h" /* Interfaces related to MD */ grpc_message_compression_algorithm -grpc_message_compression_algorithm_from_slice(grpc_slice str) { - if (grpc_slice_eq(str, GRPC_MDSTR_IDENTITY)) +grpc_message_compression_algorithm_from_slice(const grpc_slice& str) { + if (grpc_slice_eq_static_interned(str, GRPC_MDSTR_IDENTITY)) return GRPC_MESSAGE_COMPRESS_NONE; - if (grpc_slice_eq(str, GRPC_MDSTR_DEFLATE)) + if (grpc_slice_eq_static_interned(str, GRPC_MDSTR_DEFLATE)) return GRPC_MESSAGE_COMPRESS_DEFLATE; - if (grpc_slice_eq(str, GRPC_MDSTR_GZIP)) return GRPC_MESSAGE_COMPRESS_GZIP; + if (grpc_slice_eq_static_interned(str, GRPC_MDSTR_GZIP)) + return GRPC_MESSAGE_COMPRESS_GZIP; return GRPC_MESSAGE_COMPRESS_ALGORITHMS_COUNT; } grpc_stream_compression_algorithm grpc_stream_compression_algorithm_from_slice( - grpc_slice str) { - if (grpc_slice_eq(str, GRPC_MDSTR_IDENTITY)) return GRPC_STREAM_COMPRESS_NONE; - if (grpc_slice_eq(str, GRPC_MDSTR_GZIP)) return GRPC_STREAM_COMPRESS_GZIP; + const grpc_slice& str) { + if (grpc_slice_eq_static_interned(str, GRPC_MDSTR_IDENTITY)) + return GRPC_STREAM_COMPRESS_NONE; + if (grpc_slice_eq_static_interned(str, GRPC_MDSTR_GZIP)) + return GRPC_STREAM_COMPRESS_GZIP; return GRPC_STREAM_COMPRESS_ALGORITHMS_COUNT; } @@ -244,13 +248,13 @@ grpc_message_compression_algorithm grpc_message_compression_algorithm_for_level( int grpc_message_compression_algorithm_parse( grpc_slice value, grpc_message_compression_algorithm* algorithm) { - if (grpc_slice_eq(value, GRPC_MDSTR_IDENTITY)) { + if (grpc_slice_eq_static_interned(value, GRPC_MDSTR_IDENTITY)) { *algorithm = GRPC_MESSAGE_COMPRESS_NONE; return 1; - } else if (grpc_slice_eq(value, GRPC_MDSTR_DEFLATE)) { + } else if (grpc_slice_eq_static_interned(value, GRPC_MDSTR_DEFLATE)) { *algorithm = GRPC_MESSAGE_COMPRESS_DEFLATE; return 1; - } else if (grpc_slice_eq(value, GRPC_MDSTR_GZIP)) { + } else if (grpc_slice_eq_static_interned(value, GRPC_MDSTR_GZIP)) { *algorithm = GRPC_MESSAGE_COMPRESS_GZIP; return 1; } else { @@ -263,10 +267,10 @@ int grpc_message_compression_algorithm_parse( int grpc_stream_compression_algorithm_parse( grpc_slice value, grpc_stream_compression_algorithm* algorithm) { - if (grpc_slice_eq(value, GRPC_MDSTR_IDENTITY)) { + if (grpc_slice_eq_static_interned(value, GRPC_MDSTR_IDENTITY)) { *algorithm = GRPC_STREAM_COMPRESS_NONE; return 1; - } else if (grpc_slice_eq(value, GRPC_MDSTR_GZIP)) { + } else if (grpc_slice_eq_static_interned(value, GRPC_MDSTR_GZIP)) { *algorithm = GRPC_STREAM_COMPRESS_GZIP; return 1; } else { diff --git a/src/core/lib/compression/compression_internal.h b/src/core/lib/compression/compression_internal.h index da007368b01..73947a2c34d 100644 --- a/src/core/lib/compression/compression_internal.h +++ b/src/core/lib/compression/compression_internal.h @@ -35,7 +35,7 @@ typedef enum { GRPC_MESSAGE_COMPRESS_ALGORITHMS_COUNT } grpc_message_compression_algorithm; -/** Stream compresssion algorithms supported by gRPC */ +/** Stream compression algorithms supported by gRPC */ typedef enum { GRPC_STREAM_COMPRESS_NONE = 0, GRPC_STREAM_COMPRESS_GZIP, diff --git a/src/core/lib/compression/stream_compression.cc b/src/core/lib/compression/stream_compression.cc index 46cb3daf4cc..e0857988643 100644 --- a/src/core/lib/compression/stream_compression.cc +++ b/src/core/lib/compression/stream_compression.cc @@ -22,6 +22,7 @@ #include "src/core/lib/compression/stream_compression.h" #include "src/core/lib/compression/stream_compression_gzip.h" +#include "src/core/lib/slice/slice_utils.h" extern const grpc_stream_compression_vtable grpc_stream_compression_identity_vtable; @@ -65,11 +66,11 @@ void grpc_stream_compression_context_destroy( int grpc_stream_compression_method_parse( grpc_slice value, bool is_compress, grpc_stream_compression_method* method) { - if (grpc_slice_eq(value, GRPC_MDSTR_IDENTITY)) { + if (grpc_slice_eq_static_interned(value, GRPC_MDSTR_IDENTITY)) { *method = is_compress ? GRPC_STREAM_COMPRESSION_IDENTITY_COMPRESS : GRPC_STREAM_COMPRESSION_IDENTITY_DECOMPRESS; return 1; - } else if (grpc_slice_eq(value, GRPC_MDSTR_GZIP)) { + } else if (grpc_slice_eq_static_interned(value, GRPC_MDSTR_GZIP)) { *method = is_compress ? GRPC_STREAM_COMPRESSION_GZIP_COMPRESS : GRPC_STREAM_COMPRESSION_GZIP_DECOMPRESS; return 1; diff --git a/src/core/lib/compression/stream_compression.h b/src/core/lib/compression/stream_compression.h index c80f2f8692b..7328c3ec0f2 100644 --- a/src/core/lib/compression/stream_compression.h +++ b/src/core/lib/compression/stream_compression.h @@ -68,7 +68,7 @@ struct grpc_stream_compression_vtable { * at the end of compression. Emits at most \a max_output_size compressed bytes * into \a out. If all the bytes in input buffer \a in are depleted and \a flush * is not GRPC_STREAM_COMPRESSION_FLUSH_NONE, the corresponding flush method is - * executed. The total number of bytes emitted is outputed in \a output_size. + * executed. The total number of bytes emitted is outputted in \a output_size. * * A SYNC flush indicates that the entire messages in \a in can be decompressed * from \a out. A FINISH flush implies a SYNC flush, and that any further @@ -85,7 +85,7 @@ bool grpc_stream_compress(grpc_stream_compression_context* ctx, * Decompress bytes provided in \a in with a given context. Emits at most \a * max_output_size decompressed bytes into \a out. If decompression process * reached the end of a gzip stream, \a end_of_context is set to true; otherwise - * it is set to false. The total number of bytes emitted is outputed in \a + * it is set to false. The total number of bytes emitted is outputted in \a * output_size. */ bool grpc_stream_decompress(grpc_stream_compression_context* ctx, diff --git a/src/core/lib/compression/stream_compression_gzip.cc b/src/core/lib/compression/stream_compression_gzip.cc index 682f712843a..452b22b7628 100644 --- a/src/core/lib/compression/stream_compression_gzip.cc +++ b/src/core/lib/compression/stream_compression_gzip.cc @@ -53,25 +53,25 @@ static bool gzip_flate(grpc_stream_compression_context_gzip* ctx, ctx->zs.avail_out = static_cast(slice_size); ctx->zs.next_out = GRPC_SLICE_START_PTR(slice_out); while (ctx->zs.avail_out > 0 && in->length > 0 && !eoc) { - grpc_slice slice = grpc_slice_buffer_take_first(in); - ctx->zs.avail_in = static_cast GRPC_SLICE_LENGTH(slice); - ctx->zs.next_in = GRPC_SLICE_START_PTR(slice); + grpc_slice* slice = grpc_slice_buffer_peek_first(in); + ctx->zs.avail_in = static_cast GRPC_SLICE_LENGTH(*slice); + ctx->zs.next_in = GRPC_SLICE_START_PTR(*slice); r = ctx->flate(&ctx->zs, Z_NO_FLUSH); if (r < 0 && r != Z_BUF_ERROR) { gpr_log(GPR_ERROR, "zlib error (%d)", r); grpc_slice_unref_internal(slice_out); - + grpc_slice_buffer_remove_first(in); return false; } else if (r == Z_STREAM_END && ctx->flate == inflate) { eoc = true; } if (ctx->zs.avail_in > 0) { - grpc_slice_buffer_undo_take_first( - in, - grpc_slice_sub(slice, GRPC_SLICE_LENGTH(slice) - ctx->zs.avail_in, - GRPC_SLICE_LENGTH(slice))); + grpc_slice_buffer_sub_first( + in, GRPC_SLICE_LENGTH(*slice) - ctx->zs.avail_in, + GRPC_SLICE_LENGTH(*slice)); + } else { + grpc_slice_buffer_remove_first(in); } - grpc_slice_unref_internal(slice); } if (flush != 0 && ctx->zs.avail_out > 0 && !eoc) { GPR_ASSERT(in->length == 0); diff --git a/src/core/lib/debug/trace.cc b/src/core/lib/debug/trace.cc index 01c1e867d9d..cafdb15c699 100644 --- a/src/core/lib/debug/trace.cc +++ b/src/core/lib/debug/trace.cc @@ -21,6 +21,7 @@ #include "src/core/lib/debug/trace.h" #include +#include #include #include @@ -79,6 +80,8 @@ void TraceFlagList::LogAllTracers() { // Flags register themselves on the list during construction TraceFlag::TraceFlag(bool default_enabled, const char* name) : name_(name) { + static_assert(std::is_trivially_destructible::value, + "TraceFlag needs to be trivially destructible."); set_enabled(default_enabled); TraceFlagList::Add(this); } diff --git a/src/core/lib/debug/trace.h b/src/core/lib/debug/trace.h index fe6301a3fcd..72e1a4eded7 100644 --- a/src/core/lib/debug/trace.h +++ b/src/core/lib/debug/trace.h @@ -53,7 +53,9 @@ void grpc_tracer_enable_flag(grpc_core::TraceFlag* flag); class TraceFlag { public: TraceFlag(bool default_enabled, const char* name); - ~TraceFlag() {} + // TraceFlag needs to be trivially destructible since it is used as global + // variable. + ~TraceFlag() = default; const char* name() const { return name_; } @@ -63,6 +65,8 @@ class TraceFlag { // wrapped language (wr don't want to force recompilation to get tracing). // Internally, however, for performance reasons, we compile them out by // default, since internal build systems make recompiling trivial. +// +// Prefer GRPC_TRACE_FLAG_ENABLED() macro instead of using enabled() directly. #define GRPC_USE_TRACERS // tracers on by default in OSS #if defined(GRPC_USE_TRACERS) || !defined(NDEBUG) bool enabled() { @@ -97,13 +101,16 @@ class TraceFlag { #endif }; +#define GRPC_TRACE_FLAG_ENABLED(f) GPR_UNLIKELY((f).enabled()) + #ifndef NDEBUG typedef TraceFlag DebugOnlyTraceFlag; #else class DebugOnlyTraceFlag { public: - DebugOnlyTraceFlag(bool default_enabled, const char* name) {} - bool enabled() { return false; } + constexpr DebugOnlyTraceFlag(bool default_enabled, const char* name) {} + constexpr bool enabled() const { return false; } + constexpr const char* name() const { return "DebugOnlyTraceFlag"; } private: void set_enabled(bool enabled) {} diff --git a/src/core/lib/gpr/arena.cc b/src/core/lib/gpr/arena.cc deleted file mode 100644 index 836a7ca793d..00000000000 --- a/src/core/lib/gpr/arena.cc +++ /dev/null @@ -1,192 +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 - -#include "src/core/lib/gpr/arena.h" - -#include -#include - -#include -#include -#include -#include - -#include "src/core/lib/gpr/alloc.h" -#include "src/core/lib/gpr/env.h" -#include "src/core/lib/gprpp/memory.h" - -namespace { -enum init_strategy { - NO_INIT, // Do not initialize the arena blocks. - ZERO_INIT, // Initialize arena blocks with 0. - NON_ZERO_INIT, // Initialize arena blocks with a non-zero value. -}; - -gpr_once g_init_strategy_once = GPR_ONCE_INIT; -init_strategy g_init_strategy = NO_INIT; -} // namespace - -static void set_strategy_from_env() { - char* str = gpr_getenv("GRPC_ARENA_INIT_STRATEGY"); - if (str == nullptr) { - g_init_strategy = NO_INIT; - } else if (strcmp(str, "zero_init") == 0) { - g_init_strategy = ZERO_INIT; - } else if (strcmp(str, "non_zero_init") == 0) { - g_init_strategy = NON_ZERO_INIT; - } else { - g_init_strategy = NO_INIT; - } - gpr_free(str); -} - -static void* gpr_arena_alloc_maybe_init(size_t size) { - void* mem = gpr_malloc_aligned(size, GPR_MAX_ALIGNMENT); - gpr_once_init(&g_init_strategy_once, set_strategy_from_env); - if (GPR_UNLIKELY(g_init_strategy != NO_INIT)) { - if (g_init_strategy == ZERO_INIT) { - memset(mem, 0, size); - } else { // NON_ZERO_INIT. - memset(mem, 0xFE, size); - } - } - return mem; -} - -void gpr_arena_init() { - gpr_once_init(&g_init_strategy_once, set_strategy_from_env); -} - -// Uncomment this to use a simple arena that simply allocates the -// requested amount of memory for each call to gpr_arena_alloc(). This -// effectively eliminates the efficiency gain of using an arena, but it -// may be useful for debugging purposes. -//#define SIMPLE_ARENA_FOR_DEBUGGING -#ifdef SIMPLE_ARENA_FOR_DEBUGGING - -struct gpr_arena { - gpr_arena() { gpr_mu_init(&mu); } - ~gpr_arena() { - gpr_mu_destroy(&mu); - for (size_t i = 0; i < num_ptrs; ++i) { - gpr_free_aligned(ptrs[i]); - } - gpr_free(ptrs); - } - - gpr_mu mu; - void** ptrs = nullptr; - size_t num_ptrs = 0; -}; - -gpr_arena* gpr_arena_create(size_t ignored_initial_size) { - return grpc_core::New(); -} - -size_t gpr_arena_destroy(gpr_arena* arena) { - grpc_core::Delete(arena); - return 1; // Value doesn't matter, since it won't be used. -} - -void* gpr_arena_alloc(gpr_arena* arena, size_t size) { - gpr_mu_lock(&arena->mu); - arena->ptrs = - (void**)gpr_realloc(arena->ptrs, sizeof(void*) * (arena->num_ptrs + 1)); - void* retval = arena->ptrs[arena->num_ptrs++] = - gpr_arena_alloc_maybe_init(size); - gpr_mu_unlock(&arena->mu); - return retval; -} - -#else // SIMPLE_ARENA_FOR_DEBUGGING - -// TODO(roth): We currently assume that all callers need alignment of 16 -// bytes, which may be wrong in some cases. As part of converting the -// arena API to C++, we should consider replacing gpr_arena_alloc() with a -// template that takes the type of the value being allocated, which -// would allow us to use the alignment actually needed by the caller. - -typedef struct zone { - zone* next = nullptr; -} zone; - -struct gpr_arena { - gpr_arena(size_t initial_size) - : initial_zone_size(initial_size), last_zone(&initial_zone) { - gpr_mu_init(&arena_growth_mutex); - } - ~gpr_arena() { - gpr_mu_destroy(&arena_growth_mutex); - zone* z = initial_zone.next; - while (z) { - zone* next_z = z->next; - z->~zone(); - gpr_free_aligned(z); - z = next_z; - } - } - - // Keep track of the total used size. We use this in our call sizing - // historesis. - gpr_atm total_used = 0; - size_t initial_zone_size; - zone initial_zone; - zone* last_zone; - gpr_mu arena_growth_mutex; -}; - -gpr_arena* gpr_arena_create(size_t initial_size) { - initial_size = GPR_ROUND_UP_TO_ALIGNMENT_SIZE(initial_size); - return new (gpr_arena_alloc_maybe_init( - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(gpr_arena)) + initial_size)) - gpr_arena(initial_size); -} - -size_t gpr_arena_destroy(gpr_arena* arena) { - const gpr_atm size = gpr_atm_no_barrier_load(&arena->total_used); - arena->~gpr_arena(); - gpr_free_aligned(arena); - return static_cast(size); -} - -void* gpr_arena_alloc(gpr_arena* arena, size_t size) { - size = GPR_ROUND_UP_TO_ALIGNMENT_SIZE(size); - size_t begin = gpr_atm_no_barrier_fetch_add(&arena->total_used, size); - if (begin + size <= arena->initial_zone_size) { - return reinterpret_cast(arena) + - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(gpr_arena)) + begin; - } else { - // If the allocation isn't able to end in the initial zone, create a new - // zone for this allocation, and any unused space in the initial zone is - // wasted. This overflowing and wasting is uncommon because of our arena - // sizing historesis (that is, most calls should have a large enough initial - // zone and will not need to grow the arena). - gpr_mu_lock(&arena->arena_growth_mutex); - zone* z = new (gpr_arena_alloc_maybe_init( - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(zone)) + size)) zone(); - arena->last_zone->next = z; - arena->last_zone = z; - gpr_mu_unlock(&arena->arena_growth_mutex); - return reinterpret_cast(z) + - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(zone)); - } -} - -#endif // SIMPLE_ARENA_FOR_DEBUGGING diff --git a/src/core/lib/gpr/arena.h b/src/core/lib/gpr/arena.h index 069892b2282..4d70695149c 100644 --- a/src/core/lib/gpr/arena.h +++ b/src/core/lib/gpr/arena.h @@ -21,23 +21,27 @@ // the arena as a whole is freed // Tracks the total memory allocated against it, so that future arenas can // pre-allocate the right amount of memory +// This transitional API is deprecated and will be removed soon in favour of +// src/core/lib/gprpp/arena.h . #ifndef GRPC_CORE_LIB_GPR_ARENA_H #define GRPC_CORE_LIB_GPR_ARENA_H #include -#include - -typedef struct gpr_arena gpr_arena; +#include "src/core/lib/gprpp/arena.h" +// TODO(arjunroy) : Remove deprecated gpr_arena API once all callers are gone. +typedef class grpc_core::Arena gpr_arena; // Create an arena, with \a initial_size bytes in the first allocated buffer -gpr_arena* gpr_arena_create(size_t initial_size); -// Allocate \a size bytes from the arena -void* gpr_arena_alloc(gpr_arena* arena, size_t size); +inline gpr_arena* gpr_arena_create(size_t initial_size) { + return grpc_core::Arena::Create(initial_size); +} // Destroy an arena, returning the total number of bytes allocated -size_t gpr_arena_destroy(gpr_arena* arena); -// Initializes the Arena component. -void gpr_arena_init(); +inline size_t gpr_arena_destroy(gpr_arena* arena) { return arena->Destroy(); } +// Allocate \a size bytes from the arena +inline void* gpr_arena_alloc(gpr_arena* arena, size_t size) { + return arena->Alloc(size); +} #endif /* GRPC_CORE_LIB_GPR_ARENA_H */ diff --git a/src/core/lib/gpr/cpu_posix.cc b/src/core/lib/gpr/cpu_posix.cc index 915fd4976c2..982ccbd6ffe 100644 --- a/src/core/lib/gpr/cpu_posix.cc +++ b/src/core/lib/gpr/cpu_posix.cc @@ -25,7 +25,6 @@ #include #include -#include #include #include #include @@ -52,7 +51,7 @@ unsigned gpr_cpu_num_cores(void) { static void delete_thread_id(void* value) { if (value) { - gpr_free(value); + free(value); } } @@ -71,7 +70,10 @@ unsigned gpr_cpu_current_cpu(void) { unsigned int* thread_id = static_cast(pthread_getspecific(thread_id_key)); if (thread_id == nullptr) { - thread_id = static_cast(gpr_malloc(sizeof(unsigned int))); + // Note we cannot use gpr_malloc here because this allocation can happen in + // a main thread and will only be free'd when the main thread exits, which + // will cause our internal memory counters to believe it is a leak. + thread_id = static_cast(malloc(sizeof(unsigned int))); pthread_setspecific(thread_id_key, thread_id); } diff --git a/src/core/lib/gpr/env.h b/src/core/lib/gpr/env.h index aec8a3166b1..fb9e0636d10 100644 --- a/src/core/lib/gpr/env.h +++ b/src/core/lib/gpr/env.h @@ -26,7 +26,7 @@ /* Env utility functions */ /* Gets the environment variable value with the specified name. - Returns a newly allocated string. It is the responsability of the caller to + Returns a newly allocated string. It is the responsibility of the caller to gpr_free the return value if not NULL (which means that the environment variable exists). */ char* gpr_getenv(const char* name); @@ -40,4 +40,7 @@ void gpr_setenv(const char* name, const char* value); level of logging. So DO NOT USE THIS. */ const char* gpr_getenv_silent(const char* name, char** dst); +/* Deletes the variable name from the environment. */ +void gpr_unsetenv(const char* name); + #endif /* GRPC_CORE_LIB_GPR_ENV_H */ diff --git a/src/core/lib/gpr/env_linux.cc b/src/core/lib/gpr/env_linux.cc index fadc42f22f1..e84a9f6064c 100644 --- a/src/core/lib/gpr/env_linux.cc +++ b/src/core/lib/gpr/env_linux.cc @@ -79,4 +79,9 @@ void gpr_setenv(const char* name, const char* value) { GPR_ASSERT(res == 0); } +void gpr_unsetenv(const char* name) { + int res = unsetenv(name); + GPR_ASSERT(res == 0); +} + #endif /* GPR_LINUX_ENV */ diff --git a/src/core/lib/gpr/env_posix.cc b/src/core/lib/gpr/env_posix.cc index 599f85aa72b..30ddc50f682 100644 --- a/src/core/lib/gpr/env_posix.cc +++ b/src/core/lib/gpr/env_posix.cc @@ -44,4 +44,9 @@ void gpr_setenv(const char* name, const char* value) { GPR_ASSERT(res == 0); } +void gpr_unsetenv(const char* name) { + int res = unsetenv(name); + GPR_ASSERT(res == 0); +} + #endif /* GPR_POSIX_ENV */ diff --git a/src/core/lib/gpr/env_windows.cc b/src/core/lib/gpr/env_windows.cc index cf8ed60d8f6..72850a9587d 100644 --- a/src/core/lib/gpr/env_windows.cc +++ b/src/core/lib/gpr/env_windows.cc @@ -69,4 +69,11 @@ void gpr_setenv(const char* name, const char* value) { GPR_ASSERT(res); } +void gpr_unsetenv(const char* name) { + LPTSTR tname = gpr_char_to_tchar(name); + BOOL res = SetEnvironmentVariable(tname, NULL); + gpr_free(tname); + GPR_ASSERT(res); +} + #endif /* GPR_WINDOWS_ENV */ diff --git a/src/core/lib/gpr/log_posix.cc b/src/core/lib/gpr/log_posix.cc index 0acb2255724..b6edc14ab6b 100644 --- a/src/core/lib/gpr/log_posix.cc +++ b/src/core/lib/gpr/log_posix.cc @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -83,7 +84,7 @@ void gpr_default_log(gpr_log_func_args* args) { } char* prefix; - gpr_asprintf(&prefix, "%s%s.%09d %7tu %s:%d]", + gpr_asprintf(&prefix, "%s%s.%09d %7" PRIdPTR " %s:%d]", gpr_log_severity_string(args->severity), time_buffer, (int)(now.tv_nsec), gettid(), display_file, args->line); diff --git a/src/core/lib/gpr/string.cc b/src/core/lib/gpr/string.cc index 0a76fc1f54a..31d5fdee5be 100644 --- a/src/core/lib/gpr/string.cc +++ b/src/core/lib/gpr/string.cc @@ -332,16 +332,22 @@ void* gpr_memrchr(const void* s, int c, size_t n) { return nullptr; } -bool gpr_is_true(const char* s) { - size_t i; +bool gpr_parse_bool_value(const char* s, bool* dst) { + const char* kTrue[] = {"1", "t", "true", "y", "yes"}; + const char* kFalse[] = {"0", "f", "false", "n", "no"}; + static_assert(sizeof(kTrue) == sizeof(kFalse), "true_false_equal"); + if (s == nullptr) { return false; } - static const char* truthy[] = {"yes", "true", "1"}; - for (i = 0; i < GPR_ARRAY_SIZE(truthy); i++) { - if (0 == gpr_stricmp(s, truthy[i])) { + for (size_t i = 0; i < GPR_ARRAY_SIZE(kTrue); ++i) { + if (gpr_stricmp(s, kTrue[i]) == 0) { + *dst = true; + return true; + } else if (gpr_stricmp(s, kFalse[i]) == 0) { + *dst = false; return true; } } - return false; + return false; // didn't match a legal input } diff --git a/src/core/lib/gpr/string.h b/src/core/lib/gpr/string.h index ce51fe46321..c5efcec3bb1 100644 --- a/src/core/lib/gpr/string.h +++ b/src/core/lib/gpr/string.h @@ -113,7 +113,9 @@ int gpr_stricmp(const char* a, const char* b); void* gpr_memrchr(const void* s, int c, size_t n); -/** Return true if lower(s) equals "true", "yes" or "1", otherwise false. */ -bool gpr_is_true(const char* s); +/* Try to parse given string into a boolean value. + When parsed successfully, dst will have the value and returns true. + Otherwise, it returns false. */ +bool gpr_parse_bool_value(const char* value, bool* dst); #endif /* GRPC_CORE_LIB_GPR_STRING_H */ diff --git a/src/core/lib/gpr/sync_posix.cc b/src/core/lib/gpr/sync_posix.cc index 69bd6094850..a30e36c11ac 100644 --- a/src/core/lib/gpr/sync_posix.cc +++ b/src/core/lib/gpr/sync_posix.cc @@ -18,6 +18,8 @@ #include +#include + #ifdef GPR_POSIX_SYNC #include @@ -30,11 +32,18 @@ // For debug of the timer manager crash only. // TODO (mxyan): remove after bug is fixed. #ifdef GRPC_DEBUG_TIMER_MANAGER +#include void (*g_grpc_debug_timer_manager_stats)( int64_t timer_manager_init_count, int64_t timer_manager_shutdown_count, int64_t fork_count, int64_t timer_wait_err, int64_t timer_cv_value, int64_t timer_mu_value, int64_t abstime_sec_value, - int64_t abstime_nsec_value) = nullptr; + int64_t abstime_nsec_value, int64_t abs_deadline_sec_value, + int64_t abs_deadline_nsec_value, int64_t now1_sec_value, + int64_t now1_nsec_value, int64_t now2_sec_value, int64_t now2_nsec_value, + int64_t add_result_sec_value, int64_t add_result_nsec_value, + int64_t sub_result_sec_value, int64_t sub_result_nsec_value, + int64_t next_value, int64_t start_time_sec, + int64_t start_time_nsec) = nullptr; int64_t g_timer_manager_init_count = 0; int64_t g_timer_manager_shutdown_count = 0; int64_t g_fork_count = 0; @@ -43,6 +52,19 @@ int64_t g_timer_cv_value = 0; int64_t g_timer_mu_value = 0; int64_t g_abstime_sec_value = -1; int64_t g_abstime_nsec_value = -1; +int64_t g_abs_deadline_sec_value = -1; +int64_t g_abs_deadline_nsec_value = -1; +int64_t g_now1_sec_value = -1; +int64_t g_now1_nsec_value = -1; +int64_t g_now2_sec_value = -1; +int64_t g_now2_nsec_value = -1; +int64_t g_add_result_sec_value = -1; +int64_t g_add_result_nsec_value = -1; +int64_t g_sub_result_sec_value = -1; +int64_t g_sub_result_nsec_value = -1; +int64_t g_next_value = -1; +int64_t g_start_time_sec = -1; +int64_t g_start_time_nsec = -1; #endif // GRPC_DEBUG_TIMER_MANAGER #ifdef GPR_LOW_LEVEL_COUNTERS @@ -52,27 +74,53 @@ gpr_atm gpr_counter_atm_add = 0; #endif void gpr_mu_init(gpr_mu* mu) { +#ifdef GRPC_ASAN_ENABLED + GPR_ASSERT(pthread_mutex_init(&mu->mutex, nullptr) == 0); + mu->leak_checker = static_cast(malloc(sizeof(*mu->leak_checker))); + GPR_ASSERT(mu->leak_checker != nullptr); +#else GPR_ASSERT(pthread_mutex_init(mu, nullptr) == 0); +#endif } -void gpr_mu_destroy(gpr_mu* mu) { GPR_ASSERT(pthread_mutex_destroy(mu) == 0); } +void gpr_mu_destroy(gpr_mu* mu) { +#ifdef GRPC_ASAN_ENABLED + GPR_ASSERT(pthread_mutex_destroy(&mu->mutex) == 0); + free(mu->leak_checker); +#else + GPR_ASSERT(pthread_mutex_destroy(mu) == 0); +#endif +} void gpr_mu_lock(gpr_mu* mu) { #ifdef GPR_LOW_LEVEL_COUNTERS GPR_ATM_INC_COUNTER(gpr_mu_locks); #endif GPR_TIMER_SCOPE("gpr_mu_lock", 0); +#ifdef GRPC_ASAN_ENABLED + GPR_ASSERT(pthread_mutex_lock(&mu->mutex) == 0); +#else GPR_ASSERT(pthread_mutex_lock(mu) == 0); +#endif } void gpr_mu_unlock(gpr_mu* mu) { GPR_TIMER_SCOPE("gpr_mu_unlock", 0); +#ifdef GRPC_ASAN_ENABLED + GPR_ASSERT(pthread_mutex_unlock(&mu->mutex) == 0); +#else GPR_ASSERT(pthread_mutex_unlock(mu) == 0); +#endif } int gpr_mu_trylock(gpr_mu* mu) { GPR_TIMER_SCOPE("gpr_mu_trylock", 0); - int err = pthread_mutex_trylock(mu); + int err = 0; +#ifdef GRPC_ASAN_ENABLED + err = pthread_mutex_trylock(&mu->mutex); +#else + err = pthread_mutex_trylock(mu); +#endif GPR_ASSERT(err == 0 || err == EBUSY); return err == 0; } @@ -85,26 +133,106 @@ void gpr_cv_init(gpr_cv* cv) { #if GPR_LINUX GPR_ASSERT(pthread_condattr_setclock(&attr, CLOCK_MONOTONIC) == 0); #endif // GPR_LINUX + +#ifdef GRPC_ASAN_ENABLED + GPR_ASSERT(pthread_cond_init(&cv->cond_var, &attr) == 0); + cv->leak_checker = static_cast(malloc(sizeof(*cv->leak_checker))); + GPR_ASSERT(cv->leak_checker != nullptr); +#else GPR_ASSERT(pthread_cond_init(cv, &attr) == 0); +#endif } -void gpr_cv_destroy(gpr_cv* cv) { GPR_ASSERT(pthread_cond_destroy(cv) == 0); } +void gpr_cv_destroy(gpr_cv* cv) { +#ifdef GRPC_ASAN_ENABLED + GPR_ASSERT(pthread_cond_destroy(&cv->cond_var) == 0); + free(cv->leak_checker); +#else + GPR_ASSERT(pthread_cond_destroy(cv) == 0); +#endif +} + +// For debug of the timer manager crash only. +// TODO (mxyan): remove after bug is fixed. +#ifdef GRPC_DEBUG_TIMER_MANAGER +static gpr_timespec gpr_convert_clock_type_debug_timespec( + gpr_timespec t, gpr_clock_type clock_type, gpr_timespec& now1, + gpr_timespec& now2, gpr_timespec& add_result, gpr_timespec& sub_result) { + if (t.clock_type == clock_type) { + return t; + } + + if (t.tv_sec == INT64_MAX || t.tv_sec == INT64_MIN) { + t.clock_type = clock_type; + return t; + } + + if (clock_type == GPR_TIMESPAN) { + return gpr_time_sub(t, gpr_now(t.clock_type)); + } + + if (t.clock_type == GPR_TIMESPAN) { + return gpr_time_add(gpr_now(clock_type), t); + } + + now1 = gpr_now(t.clock_type); + sub_result = gpr_time_sub(t, now1); + now2 = gpr_now(clock_type); + add_result = gpr_time_add(now2, sub_result); + return add_result; +} + +#define gpr_convert_clock_type_debug(t, clock_type, now1, now2, add_result, \ + sub_result) \ + gpr_convert_clock_type_debug_timespec((t), (clock_type), (now1), (now2), \ + (add_result), (sub_result)) +#else +#define gpr_convert_clock_type_debug(t, clock_type, now1, now2, add_result, \ + sub_result) \ + gpr_convert_clock_type((t), (clock_type)) +#endif int gpr_cv_wait(gpr_cv* cv, gpr_mu* mu, gpr_timespec abs_deadline) { int err = 0; +#ifdef GRPC_DEBUG_TIMER_MANAGER + // For debug of the timer manager crash only. + // TODO (mxyan): remove after bug is fixed. + gpr_timespec abs_deadline_copy; + abs_deadline_copy.tv_sec = abs_deadline.tv_sec; + abs_deadline_copy.tv_nsec = abs_deadline.tv_nsec; + gpr_timespec now1; + gpr_timespec now2; + gpr_timespec add_result; + gpr_timespec sub_result; + memset(&now1, 0, sizeof(now1)); + memset(&now2, 0, sizeof(now2)); + memset(&add_result, 0, sizeof(add_result)); + memset(&sub_result, 0, sizeof(sub_result)); +#endif if (gpr_time_cmp(abs_deadline, gpr_inf_future(abs_deadline.clock_type)) == 0) { +#ifdef GRPC_ASAN_ENABLED + err = pthread_cond_wait(&cv->cond_var, &mu->mutex); +#else err = pthread_cond_wait(cv, mu); +#endif } else { struct timespec abs_deadline_ts; #if GPR_LINUX - abs_deadline = gpr_convert_clock_type(abs_deadline, GPR_CLOCK_MONOTONIC); + abs_deadline = gpr_convert_clock_type_debug( + abs_deadline, GPR_CLOCK_MONOTONIC, now1, now2, add_result, sub_result); #else - abs_deadline = gpr_convert_clock_type(abs_deadline, GPR_CLOCK_REALTIME); + abs_deadline = gpr_convert_clock_type_debug( + abs_deadline, GPR_CLOCK_REALTIME, now1, now2, add_result, sub_result); #endif // GPR_LINUX abs_deadline_ts.tv_sec = static_cast(abs_deadline.tv_sec); abs_deadline_ts.tv_nsec = abs_deadline.tv_nsec; +#ifdef GRPC_ASAN_ENABLED + err = pthread_cond_timedwait(&cv->cond_var, &mu->mutex, &abs_deadline_ts); +#else err = pthread_cond_timedwait(cv, mu, &abs_deadline_ts); +#endif + #ifdef GRPC_DEBUG_TIMER_MANAGER // For debug of the timer manager crash only. // TODO (mxyan): remove after bug is fixed. @@ -123,10 +251,25 @@ int gpr_cv_wait(gpr_cv* cv, gpr_mu* mu, gpr_timespec abs_deadline) { g_timer_wait_err = err; g_timer_cv_value = (int64_t)cv; g_timer_mu_value = (int64_t)mu; + g_abs_deadline_sec_value = abs_deadline_copy.tv_sec; + g_abs_deadline_nsec_value = abs_deadline_copy.tv_nsec; + g_now1_sec_value = now1.tv_sec; + g_now1_nsec_value = now1.tv_nsec; + g_now2_sec_value = now2.tv_sec; + g_now2_nsec_value = now2.tv_nsec; + g_add_result_sec_value = add_result.tv_sec; + g_add_result_nsec_value = add_result.tv_nsec; + g_sub_result_sec_value = sub_result.tv_sec; + g_sub_result_nsec_value = sub_result.tv_nsec; g_grpc_debug_timer_manager_stats( g_timer_manager_init_count, g_timer_manager_shutdown_count, g_fork_count, g_timer_wait_err, g_timer_cv_value, g_timer_mu_value, - g_abstime_sec_value, g_abstime_nsec_value); + g_abstime_sec_value, g_abstime_nsec_value, g_abs_deadline_sec_value, + g_abs_deadline_nsec_value, g_now1_sec_value, g_now1_nsec_value, + g_now2_sec_value, g_now2_nsec_value, g_add_result_sec_value, + g_add_result_nsec_value, g_sub_result_sec_value, + g_sub_result_nsec_value, g_next_value, g_start_time_sec, + g_start_time_nsec); } } #endif @@ -134,10 +277,20 @@ int gpr_cv_wait(gpr_cv* cv, gpr_mu* mu, gpr_timespec abs_deadline) { return err == ETIMEDOUT; } -void gpr_cv_signal(gpr_cv* cv) { GPR_ASSERT(pthread_cond_signal(cv) == 0); } +void gpr_cv_signal(gpr_cv* cv) { +#ifdef GRPC_ASAN_ENABLED + GPR_ASSERT(pthread_cond_signal(&cv->cond_var) == 0); +#else + GPR_ASSERT(pthread_cond_signal(cv) == 0); +#endif +} void gpr_cv_broadcast(gpr_cv* cv) { +#ifdef GRPC_ASAN_ENABLED + GPR_ASSERT(pthread_cond_broadcast(&cv->cond_var) == 0); +#else GPR_ASSERT(pthread_cond_broadcast(cv) == 0); +#endif } /*----------------------------------------*/ diff --git a/src/core/lib/gpr/time.cc b/src/core/lib/gpr/time.cc index 64c1c98f560..8927dab5a30 100644 --- a/src/core/lib/gpr/time.cc +++ b/src/core/lib/gpr/time.cc @@ -135,6 +135,10 @@ gpr_timespec gpr_time_add(gpr_timespec a, gpr_timespec b) { gpr_timespec sum; int64_t inc = 0; GPR_ASSERT(b.clock_type == GPR_TIMESPAN); + // tv_nsec in a timespan is always +ve. -ve timespan is represented as (-ve + // tv_sec, +ve tv_nsec). For example, timespan = -2.5 seconds is represented + // as {-3, 5e8, GPR_TIMESPAN} + GPR_ASSERT(b.tv_nsec >= 0); sum.clock_type = a.clock_type; sum.tv_nsec = a.tv_nsec + b.tv_nsec; if (sum.tv_nsec >= GPR_NS_PER_SEC) { @@ -165,6 +169,10 @@ gpr_timespec gpr_time_sub(gpr_timespec a, gpr_timespec b) { int64_t dec = 0; if (b.clock_type == GPR_TIMESPAN) { diff.clock_type = a.clock_type; + // tv_nsec in a timespan is always +ve. -ve timespan is represented as (-ve + // tv_sec, +ve tv_nsec). For example, timespan = -2.5 seconds is represented + // as {-3, 5e8, GPR_TIMESPAN} + GPR_ASSERT(b.tv_nsec >= 0); } else { GPR_ASSERT(a.clock_type == b.clock_type); diff.clock_type = GPR_TIMESPAN; diff --git a/src/core/lib/gpr/time_posix.cc b/src/core/lib/gpr/time_posix.cc index 28836bfa54e..b5a47673676 100644 --- a/src/core/lib/gpr/time_posix.cc +++ b/src/core/lib/gpr/time_posix.cc @@ -108,6 +108,9 @@ static gpr_timespec now_impl(gpr_clock_type clock) { now.clock_type = clock; switch (clock) { case GPR_CLOCK_REALTIME: + // gettimeofday(...) function may return with a value whose tv_usec is + // greater than 1e6 on iOS The case is resolved with the guard at end of + // this function. gettimeofday(&now_tv, nullptr); now.tv_sec = now_tv.tv_sec; now.tv_nsec = now_tv.tv_usec * 1000; @@ -124,6 +127,16 @@ static gpr_timespec now_impl(gpr_clock_type clock) { abort(); } + // Guard the tv_nsec field in valid range for all clock types + while (GPR_UNLIKELY(now.tv_nsec >= 1e9)) { + now.tv_sec++; + now.tv_nsec -= 1e9; + } + while (GPR_UNLIKELY(now.tv_nsec < 0)) { + now.tv_sec--; + now.tv_nsec += 1e9; + } + return now; } #endif @@ -133,12 +146,18 @@ gpr_timespec (*gpr_now_impl)(gpr_clock_type clock_type) = now_impl; #ifdef GPR_LOW_LEVEL_COUNTERS gpr_atm gpr_now_call_count; #endif - gpr_timespec gpr_now(gpr_clock_type clock_type) { #ifdef GPR_LOW_LEVEL_COUNTERS __atomic_fetch_add(&gpr_now_call_count, 1, __ATOMIC_RELAXED); #endif - return gpr_now_impl(clock_type); + // validate clock type + GPR_ASSERT(clock_type == GPR_CLOCK_MONOTONIC || + clock_type == GPR_CLOCK_REALTIME || + clock_type == GPR_CLOCK_PRECISE); + gpr_timespec ts = gpr_now_impl(clock_type); + // tv_nsecs must be in the range [0, 1e9). + GPR_ASSERT(ts.tv_nsec >= 0 && ts.tv_nsec < 1e9); + return ts; } void gpr_sleep_until(gpr_timespec until) { diff --git a/src/core/lib/gprpp/arena.cc b/src/core/lib/gprpp/arena.cc new file mode 100644 index 00000000000..5c344db4e35 --- /dev/null +++ b/src/core/lib/gprpp/arena.cc @@ -0,0 +1,103 @@ +/* + * + * 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 + +#include "src/core/lib/gprpp/arena.h" + +#include +#include + +#include +#include +#include +#include + +#include "src/core/lib/gpr/alloc.h" +#include "src/core/lib/gprpp/memory.h" + +namespace { + +void* ArenaStorage(size_t initial_size) { + static constexpr size_t base_size = + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_core::Arena)); + initial_size = GPR_ROUND_UP_TO_ALIGNMENT_SIZE(initial_size); + size_t alloc_size = base_size + initial_size; + static constexpr size_t alignment = + (GPR_CACHELINE_SIZE > GPR_MAX_ALIGNMENT && + GPR_CACHELINE_SIZE % GPR_MAX_ALIGNMENT == 0) + ? GPR_CACHELINE_SIZE + : GPR_MAX_ALIGNMENT; + return gpr_malloc_aligned(alloc_size, alignment); +} + +} // namespace + +namespace grpc_core { + +Arena::~Arena() { + Zone* z = last_zone_; + while (z) { + Zone* prev_z = z->prev; + z->~Zone(); + gpr_free_aligned(z); + z = prev_z; + } +} + +Arena* Arena::Create(size_t initial_size) { + return new (ArenaStorage(initial_size)) Arena(initial_size); +} + +Pair Arena::CreateWithAlloc(size_t initial_size, + size_t alloc_size) { + static constexpr size_t base_size = + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(Arena)); + auto* new_arena = + new (ArenaStorage(initial_size)) Arena(initial_size, alloc_size); + void* first_alloc = reinterpret_cast(new_arena) + base_size; + return MakePair(new_arena, first_alloc); +} + +size_t Arena::Destroy() { + size_t size = total_used_.Load(MemoryOrder::RELAXED); + this->~Arena(); + gpr_free_aligned(this); + return size; +} + +void* Arena::AllocZone(size_t size) { + // If the allocation isn't able to end in the initial zone, create a new + // zone for this allocation, and any unused space in the initial zone is + // wasted. This overflowing and wasting is uncommon because of our arena + // sizing hysteresis (that is, most calls should have a large enough initial + // zone and will not need to grow the arena). + static constexpr size_t zone_base_size = + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(Zone)); + size_t alloc_size = zone_base_size + size; + Zone* z = new (gpr_malloc_aligned(alloc_size, GPR_MAX_ALIGNMENT)) Zone(); + { + gpr_spinlock_lock(&arena_growth_spinlock_); + z->prev = last_zone_; + last_zone_ = z; + gpr_spinlock_unlock(&arena_growth_spinlock_); + } + return reinterpret_cast(z) + zone_base_size; +} + +} // namespace grpc_core diff --git a/src/core/lib/gprpp/arena.h b/src/core/lib/gprpp/arena.h new file mode 100644 index 00000000000..b1b0c4a85cb --- /dev/null +++ b/src/core/lib/gprpp/arena.h @@ -0,0 +1,121 @@ +/* + * + * 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. + * + */ + +// \file Arena based allocator +// Allows very fast allocation of memory, but that memory cannot be freed until +// the arena as a whole is freed +// Tracks the total memory allocated against it, so that future arenas can +// pre-allocate the right amount of memory + +#ifndef GRPC_CORE_LIB_GPRPP_ARENA_H +#define GRPC_CORE_LIB_GPRPP_ARENA_H + +#include + +#include +#include + +#include +#include + +#include "src/core/lib/gpr/alloc.h" +#include "src/core/lib/gpr/spinlock.h" +#include "src/core/lib/gprpp/atomic.h" +#include "src/core/lib/gprpp/pair.h" + +#include + +namespace grpc_core { + +class Arena { + public: + // Create an arena, with \a initial_size bytes in the first allocated buffer. + static Arena* Create(size_t initial_size); + + // Create an arena, with \a initial_size bytes in the first allocated buffer, + // and return both a void pointer to the returned arena and a void* with the + // first allocation. + static Pair CreateWithAlloc(size_t initial_size, + size_t alloc_size); + + // Destroy an arena, returning the total number of bytes allocated. + size_t Destroy(); + // Allocate \a size bytes from the arena. + void* Alloc(size_t size) { + static constexpr size_t base_size = + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(Arena)); + size = GPR_ROUND_UP_TO_ALIGNMENT_SIZE(size); + size_t begin = total_used_.FetchAdd(size, MemoryOrder::RELAXED); + if (begin + size <= initial_zone_size_) { + return reinterpret_cast(this) + base_size + begin; + } else { + return AllocZone(size); + } + } + + // TODO(roth): We currently assume that all callers need alignment of 16 + // bytes, which may be wrong in some cases. When we have time, we should + // change this to instead use the alignment of the type being allocated by + // this method. + template + T* New(Args&&... args) { + T* t = static_cast(Alloc(sizeof(T))); + new (t) T(std::forward(args)...); + return t; + } + + private: + struct Zone { + Zone* prev; + }; + + // Initialize an arena. + // Parameters: + // initial_size: The initial size of the whole arena in bytes. These bytes + // are contained within 'zone 0'. If the arena user ends up requiring more + // memory than the arena contains in zone 0, subsequent zones are allocated + // on demand and maintained in a tail-linked list. + // + // initial_alloc: Optionally, construct the arena as though a call to + // Alloc() had already been made for initial_alloc bytes. This provides a + // quick optimization (avoiding an atomic fetch-add) for the common case + // where we wish to create an arena and then perform an immediate + // allocation. + explicit Arena(size_t initial_size, size_t initial_alloc = 0) + : total_used_(initial_alloc), initial_zone_size_(initial_size) {} + + ~Arena(); + + void* AllocZone(size_t size); + + // Keep track of the total used size. We use this in our call sizing + // hysteresis. + Atomic total_used_; + size_t initial_zone_size_; + gpr_spinlock arena_growth_spinlock_ = GPR_SPINLOCK_STATIC_INITIALIZER; + // If the initial arena allocation wasn't enough, we allocate additional zones + // in a reverse linked list. Each additional zone consists of (1) a pointer to + // the zone added before this zone (null if this is the first additional zone) + // and (2) the allocated memory. The arena itself maintains a pointer to the + // last zone; the zone list is reverse-walked during arena destruction only. + Zone* last_zone_ = nullptr; +}; + +} // namespace grpc_core + +#endif /* GRPC_CORE_LIB_GPRPP_ARENA_H */ diff --git a/src/core/lib/gprpp/atomic.h b/src/core/lib/gprpp/atomic.h index 8b08fc4e9c4..80412ef9583 100644 --- a/src/core/lib/gprpp/atomic.h +++ b/src/core/lib/gprpp/atomic.h @@ -21,10 +21,80 @@ #include -#ifdef GPR_HAS_CXX11_ATOMIC -#include "src/core/lib/gprpp/atomic_with_std.h" -#else -#include "src/core/lib/gprpp/atomic_with_atm.h" -#endif +#include + +#include + +namespace grpc_core { + +enum class MemoryOrder { + RELAXED = std::memory_order_relaxed, + CONSUME = std::memory_order_consume, + ACQUIRE = std::memory_order_acquire, + RELEASE = std::memory_order_release, + ACQ_REL = std::memory_order_acq_rel, + SEQ_CST = std::memory_order_seq_cst +}; + +template +class Atomic { + public: + explicit Atomic(T val = T()) : storage_(val) {} + + T Load(MemoryOrder order) const { + return storage_.load(static_cast(order)); + } + + void Store(T val, MemoryOrder order) { + storage_.store(val, static_cast(order)); + } + + bool CompareExchangeWeak(T* expected, T desired, MemoryOrder success, + MemoryOrder failure) { + return GPR_ATM_INC_CAS_THEN(storage_.compare_exchange_weak( + *expected, desired, static_cast(success), + static_cast(failure))); + } + + bool CompareExchangeStrong(T* expected, T desired, MemoryOrder success, + MemoryOrder failure) { + return GPR_ATM_INC_CAS_THEN(storage_.compare_exchange_strong( + *expected, desired, static_cast(success), + static_cast(failure))); + } + + template + T FetchAdd(Arg arg, MemoryOrder order = MemoryOrder::SEQ_CST) { + return GPR_ATM_INC_ADD_THEN(storage_.fetch_add( + static_cast(arg), static_cast(order))); + } + + template + T FetchSub(Arg arg, MemoryOrder order = MemoryOrder::SEQ_CST) { + return GPR_ATM_INC_ADD_THEN(storage_.fetch_sub( + static_cast(arg), static_cast(order))); + } + + // Atomically increment a counter only if the counter value is not zero. + // Returns true if increment took place; false if counter is zero. + bool IncrementIfNonzero(MemoryOrder load_order = MemoryOrder::ACQUIRE) { + T count = storage_.load(static_cast(load_order)); + do { + // If zero, we are done (without an increment). If not, we must do a CAS + // to maintain the contract: do not increment the counter if it is already + // zero + if (count == 0) { + return false; + } + } while (!CompareExchangeWeak(&count, count + 1, MemoryOrder::ACQ_REL, + load_order)); + return true; + } + + private: + std::atomic storage_; +}; + +} // namespace grpc_core #endif /* GRPC_CORE_LIB_GPRPP_ATOMIC_H */ diff --git a/src/core/lib/gprpp/atomic_with_atm.h b/src/core/lib/gprpp/atomic_with_atm.h deleted file mode 100644 index 3d0021bb1ce..00000000000 --- a/src/core/lib/gprpp/atomic_with_atm.h +++ /dev/null @@ -1,57 +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_LIB_GPRPP_ATOMIC_WITH_ATM_H -#define GRPC_CORE_LIB_GPRPP_ATOMIC_WITH_ATM_H - -#include - -#include - -namespace grpc_core { - -enum MemoryOrderRelaxed { memory_order_relaxed }; - -template -class atomic; - -template <> -class atomic { - public: - atomic() { gpr_atm_no_barrier_store(&x_, static_cast(false)); } - explicit atomic(bool x) { - gpr_atm_no_barrier_store(&x_, static_cast(x)); - } - - bool compare_exchange_strong(bool& expected, bool update, MemoryOrderRelaxed, - MemoryOrderRelaxed) { - if (!gpr_atm_no_barrier_cas(&x_, static_cast(expected), - static_cast(update))) { - expected = gpr_atm_no_barrier_load(&x_) != 0; - return false; - } - return true; - } - - private: - gpr_atm x_; -}; - -} // namespace grpc_core - -#endif /* GRPC_CORE_LIB_GPRPP_ATOMIC_WITH_ATM_H */ diff --git a/src/core/lib/gprpp/fork.cc b/src/core/lib/gprpp/fork.cc index 3b9c16510a7..fdc7c5354bd 100644 --- a/src/core/lib/gprpp/fork.cc +++ b/src/core/lib/gprpp/fork.cc @@ -160,8 +160,6 @@ void Fork::GlobalInit() { if (!override_enabled_) { #ifdef GRPC_ENABLE_FORK_SUPPORT support_enabled_ = true; -#else - support_enabled_ = false; #endif bool env_var_set = false; char* env = gpr_getenv("GRPC_ENABLE_FORK_SUPPORT"); @@ -262,7 +260,7 @@ void Fork::AwaitThreads() { internal::ExecCtxState* Fork::exec_ctx_state_ = nullptr; internal::ThreadState* Fork::thread_state_ = nullptr; -bool Fork::support_enabled_ = false; +std::atomic Fork::support_enabled_; bool Fork::override_enabled_ = false; Fork::child_postfork_func Fork::reset_child_polling_engine_ = nullptr; } // namespace grpc_core diff --git a/src/core/lib/gprpp/fork.h b/src/core/lib/gprpp/fork.h index 5a7404f0d91..73f2fa56aa7 100644 --- a/src/core/lib/gprpp/fork.h +++ b/src/core/lib/gprpp/fork.h @@ -19,6 +19,10 @@ #ifndef GRPC_CORE_LIB_GPRPP_FORK_H #define GRPC_CORE_LIB_GPRPP_FORK_H +#include + +#include + /* * NOTE: FORKING IS NOT GENERALLY SUPPORTED, THIS IS ONLY INTENDED TO WORK * AROUND VERY SPECIFIC USE CASES. @@ -78,7 +82,7 @@ class Fork { private: static internal::ExecCtxState* exec_ctx_state_; static internal::ThreadState* thread_state_; - static bool support_enabled_; + static std::atomic support_enabled_; static bool override_enabled_; static child_postfork_func reset_child_polling_engine_; }; diff --git a/src/core/lib/gprpp/global_config.h b/src/core/lib/gprpp/global_config.h new file mode 100644 index 00000000000..a1bbf07564c --- /dev/null +++ b/src/core/lib/gprpp/global_config.h @@ -0,0 +1,87 @@ +/* + * + * Copyright 2019 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_GPRPP_GLOBAL_CONFIG_H +#define GRPC_CORE_LIB_GPRPP_GLOBAL_CONFIG_H + +#include + +#include + +// -------------------------------------------------------------------- +// How to use global configuration variables: +// +// Defining config variables of a specified type: +// GPR_GLOBAL_CONFIG_DEFINE_*TYPE*(name, default_value, help); +// +// Supported TYPEs: BOOL, INT32, STRING +// +// It's recommended to use lowercase letters for 'name' like +// regular variables. The builtin configuration system uses +// environment variable and the name is converted to uppercase +// when looking up the value. For example, +// GPR_GLOBAL_CONFIG_DEFINE(grpc_latency) looks up the value with the +// name, "GRPC_LATENCY". +// +// The variable initially has the specified 'default_value' +// which must be an expression convertible to 'Type'. +// 'default_value' may be evaluated 0 or more times, +// and at an unspecified time; keep it +// simple and usually free of side-effects. +// +// GPR_GLOBAL_CONFIG_DEFINE_*TYPE* should not be called in a C++ header. +// It should be called at the top-level (outside any namespaces) +// in a .cc file. +// +// Getting the variables: +// GPR_GLOBAL_CONFIG_GET(name) +// +// If error happens during getting variables, error messages will +// be logged and default value will be returned. +// +// Setting the variables with new value: +// GPR_GLOBAL_CONFIG_SET(name, new_value) +// +// Declaring config variables for other modules to access: +// GPR_GLOBAL_CONFIG_DECLARE_*TYPE*(name) + +// -------------------------------------------------------------------- +// How to customize the global configuration system: +// +// How to read and write configuration value can be customized. +// Builtin system uses environment variables but it can be extended to +// support command-line flag, file, etc. +// +// To customize it, following macros should be redefined. +// +// GPR_GLOBAL_CONFIG_DEFINE_BOOL +// GPR_GLOBAL_CONFIG_DEFINE_INT32 +// GPR_GLOBAL_CONFIG_DEFINE_STRING +// +// These macros should define functions for getting and setting variable. +// For example, GPR_GLOBAL_CONFIG_DEFINE_BOOL(test, ...) would define two +// functions. +// +// bool gpr_global_config_get_test(); +// void gpr_global_config_set_test(bool value); + +#include "src/core/lib/gprpp/global_config_env.h" + +#include "src/core/lib/gprpp/global_config_custom.h" + +#endif /* GRPC_CORE_LIB_GPRPP_GLOBAL_CONFIG_H */ diff --git a/src/core/lib/gprpp/global_config_custom.h b/src/core/lib/gprpp/global_config_custom.h new file mode 100644 index 00000000000..175677e07c7 --- /dev/null +++ b/src/core/lib/gprpp/global_config_custom.h @@ -0,0 +1,29 @@ +/* + * + * Copyright 2019 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_GPRPP_GLOBAL_CONFIG_CUSTOM_H +#define GRPC_CORE_LIB_GPRPP_GLOBAL_CONFIG_CUSTOM_H + +// This is a placeholder for custom global configuration implementation. +// To use the custom one, please define following macros here. +// +// GPR_GLOBAL_CONFIG_DEFINE_BOOL +// GPR_GLOBAL_CONFIG_DEFINE_INT32 +// GPR_GLOBAL_CONFIG_DEFINE_STRING + +#endif /* GRPC_CORE_LIB_GPRPP_GLOBAL_CONFIG_CUSTOM_H */ diff --git a/src/core/lib/gprpp/global_config_env.cc b/src/core/lib/gprpp/global_config_env.cc new file mode 100644 index 00000000000..fb14805d01b --- /dev/null +++ b/src/core/lib/gprpp/global_config_env.cc @@ -0,0 +1,135 @@ +/* + * + * Copyright 2019 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 + +#include "src/core/lib/gprpp/global_config_env.h" + +#include +#include +#include + +#include "src/core/lib/gpr/env.h" +#include "src/core/lib/gpr/string.h" + +#include +#include + +namespace grpc_core { + +namespace { + +void DefaultGlobalConfigEnvErrorFunction(const char* error_message) { + gpr_log(GPR_ERROR, "%s", error_message); +} + +GlobalConfigEnvErrorFunctionType g_global_config_env_error_func = + DefaultGlobalConfigEnvErrorFunction; + +void LogParsingError(const char* name, const char* value) { + char* error_message; + gpr_asprintf(&error_message, + "Illegal value '%s' specified for environment variable '%s'", + value, name); + (*g_global_config_env_error_func)(error_message); + gpr_free(error_message); +} + +} // namespace + +void SetGlobalConfigEnvErrorFunction(GlobalConfigEnvErrorFunctionType func) { + g_global_config_env_error_func = func; +} + +UniquePtr GlobalConfigEnv::GetValue() { + return UniquePtr(gpr_getenv(GetName())); +} + +void GlobalConfigEnv::SetValue(const char* value) { + gpr_setenv(GetName(), value); +} + +void GlobalConfigEnv::Unset() { gpr_unsetenv(GetName()); } + +char* GlobalConfigEnv::GetName() { + // This makes sure that name_ is in a canonical form having uppercase + // letters. This is okay to be called serveral times. + for (char* c = name_; *c != 0; ++c) { + *c = toupper(*c); + } + return name_; +} +static_assert(std::is_trivially_destructible::value, + "GlobalConfigEnvBool needs to be trivially destructible."); + +bool GlobalConfigEnvBool::Get() { + UniquePtr str = GetValue(); + if (str == nullptr) { + return default_value_; + } + // parsing given value string. + bool result = false; + if (!gpr_parse_bool_value(str.get(), &result)) { + LogParsingError(GetName(), str.get()); + result = default_value_; + } + return result; +} + +void GlobalConfigEnvBool::Set(bool value) { + SetValue(value ? "true" : "false"); +} + +static_assert(std::is_trivially_destructible::value, + "GlobalConfigEnvInt32 needs to be trivially destructible."); + +int32_t GlobalConfigEnvInt32::Get() { + UniquePtr str = GetValue(); + if (str == nullptr) { + return default_value_; + } + // parsing given value string. + char* end = str.get(); + long result = strtol(str.get(), &end, 10); + if (*end != 0) { + LogParsingError(GetName(), str.get()); + result = default_value_; + } + return static_cast(result); +} + +void GlobalConfigEnvInt32::Set(int32_t value) { + char buffer[GPR_LTOA_MIN_BUFSIZE]; + gpr_ltoa(value, buffer); + SetValue(buffer); +} + +static_assert(std::is_trivially_destructible::value, + "GlobalConfigEnvString needs to be trivially destructible."); + +UniquePtr GlobalConfigEnvString::Get() { + UniquePtr str = GetValue(); + if (str == nullptr) { + return UniquePtr(gpr_strdup(default_value_)); + } + return str; +} + +void GlobalConfigEnvString::Set(const char* value) { SetValue(value); } + +} // namespace grpc_core diff --git a/src/core/lib/gprpp/global_config_env.h b/src/core/lib/gprpp/global_config_env.h new file mode 100644 index 00000000000..3d3038895d3 --- /dev/null +++ b/src/core/lib/gprpp/global_config_env.h @@ -0,0 +1,131 @@ +/* + * + * Copyright 2019 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_GPRPP_GLOBAL_CONFIG_ENV_H +#define GRPC_CORE_LIB_GPRPP_GLOBAL_CONFIG_ENV_H + +#include + +#include "src/core/lib/gprpp/global_config_generic.h" +#include "src/core/lib/gprpp/memory.h" + +namespace grpc_core { + +typedef void (*GlobalConfigEnvErrorFunctionType)(const char* error_message); + +/* + * Set global_config_env_error_function which is called when config system + * encounters errors such as parsing error. What the default function does + * is logging error message. + */ +void SetGlobalConfigEnvErrorFunction(GlobalConfigEnvErrorFunctionType func); + +// Base class for all classes to access environment variables. +class GlobalConfigEnv { + protected: + // `name` should be writable and alive after constructor is called. + constexpr explicit GlobalConfigEnv(char* name) : name_(name) {} + + public: + // Returns the value of `name` variable. + UniquePtr GetValue(); + + // Sets the value of `name` variable. + void SetValue(const char* value); + + // Unsets `name` variable. + void Unset(); + + protected: + char* GetName(); + + private: + char* name_; +}; + +class GlobalConfigEnvBool : public GlobalConfigEnv { + public: + constexpr GlobalConfigEnvBool(char* name, bool default_value) + : GlobalConfigEnv(name), default_value_(default_value) {} + + bool Get(); + void Set(bool value); + + private: + bool default_value_; +}; + +class GlobalConfigEnvInt32 : public GlobalConfigEnv { + public: + constexpr GlobalConfigEnvInt32(char* name, int32_t default_value) + : GlobalConfigEnv(name), default_value_(default_value) {} + + int32_t Get(); + void Set(int32_t value); + + private: + int32_t default_value_; +}; + +class GlobalConfigEnvString : public GlobalConfigEnv { + public: + constexpr GlobalConfigEnvString(char* name, const char* default_value) + : GlobalConfigEnv(name), default_value_(default_value) {} + + UniquePtr Get(); + void Set(const char* value); + + private: + const char* default_value_; +}; + +} // namespace grpc_core + +// Macros for defining global config instances using environment variables. +// This defines a GlobalConfig*Type* instance with arguments for +// mutable variable name and default value. +// Mutable name (g_env_str_##name) is here for having an array +// for the canonical name without dynamic allocation. +// `help` argument is ignored for this implementation. + +#define GPR_GLOBAL_CONFIG_DEFINE_BOOL(name, default_value, help) \ + static char g_env_str_##name[] = #name; \ + static ::grpc_core::GlobalConfigEnvBool g_env_##name(g_env_str_##name, \ + default_value); \ + bool gpr_global_config_get_##name() { return g_env_##name.Get(); } \ + void gpr_global_config_set_##name(bool value) { g_env_##name.Set(value); } + +#define GPR_GLOBAL_CONFIG_DEFINE_INT32(name, default_value, help) \ + static char g_env_str_##name[] = #name; \ + static ::grpc_core::GlobalConfigEnvInt32 g_env_##name(g_env_str_##name, \ + default_value); \ + int32_t gpr_global_config_get_##name() { return g_env_##name.Get(); } \ + void gpr_global_config_set_##name(int32_t value) { g_env_##name.Set(value); } + +#define GPR_GLOBAL_CONFIG_DEFINE_STRING(name, default_value, help) \ + static char g_env_str_##name[] = #name; \ + static ::grpc_core::GlobalConfigEnvString g_env_##name(g_env_str_##name, \ + default_value); \ + ::grpc_core::UniquePtr gpr_global_config_get_##name() { \ + return g_env_##name.Get(); \ + } \ + void gpr_global_config_set_##name(const char* value) { \ + g_env_##name.Set(value); \ + } + +#endif /* GRPC_CORE_LIB_GPRPP_GLOBAL_CONFIG_ENV_H */ diff --git a/src/core/lib/gprpp/global_config_generic.h b/src/core/lib/gprpp/global_config_generic.h new file mode 100644 index 00000000000..d3e3e2a2dbe --- /dev/null +++ b/src/core/lib/gprpp/global_config_generic.h @@ -0,0 +1,44 @@ +/* + * + * Copyright 2019 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_GPRPP_GLOBAL_CONFIG_GENERIC_H +#define GRPC_CORE_LIB_GPRPP_GLOBAL_CONFIG_GENERIC_H + +#include + +#include "src/core/lib/gprpp/memory.h" + +#include + +#define GPR_GLOBAL_CONFIG_GET(name) gpr_global_config_get_##name() + +#define GPR_GLOBAL_CONFIG_SET(name, value) gpr_global_config_set_##name(value) + +#define GPR_GLOBAL_CONFIG_DECLARE_BOOL(name) \ + extern bool gpr_global_config_get_##name(); \ + extern void gpr_global_config_set_##name(bool value) + +#define GPR_GLOBAL_CONFIG_DECLARE_INT32(name) \ + extern int32_t gpr_global_config_get_##name(); \ + extern void gpr_global_config_set_##name(int32_t value) + +#define GPR_GLOBAL_CONFIG_DECLARE_STRING(name) \ + extern grpc_core::UniquePtr gpr_global_config_get_##name(); \ + extern void gpr_global_config_set_##name(const char* value) + +#endif /* GRPC_CORE_LIB_GPRPP_GLOBAL_CONFIG_GENERIC_H */ diff --git a/src/core/lib/gprpp/inlined_vector.h b/src/core/lib/gprpp/inlined_vector.h index 65c2b9634f2..66dc751a567 100644 --- a/src/core/lib/gprpp/inlined_vector.h +++ b/src/core/lib/gprpp/inlined_vector.h @@ -100,10 +100,7 @@ class InlinedVector { void reserve(size_t capacity) { if (capacity > capacity_) { T* new_dynamic = static_cast(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(); - } + move_elements(data(), new_dynamic, size_); gpr_free(dynamic_); dynamic_ = new_dynamic; capacity_ = capacity; @@ -131,33 +128,6 @@ class InlinedVector { size_--; } - void copy_from(const InlinedVector& v) { - // if v is allocated, copy over the buffer. - if (v.dynamic_ != nullptr) { - reserve(v.capacity_); - memcpy(dynamic_, v.dynamic_, v.size_ * sizeof(T)); - } else { - memcpy(inline_, v.inline_, v.size_ * sizeof(T)); - } - // copy over metadata - size_ = v.size_; - capacity_ = v.capacity_; - } - - void move_from(InlinedVector& v) { - // if v is allocated, then we steal its buffer, else we copy it. - if (v.dynamic_ != nullptr) { - dynamic_ = v.dynamic_; - } else { - memcpy(inline_, v.inline_, v.size_ * sizeof(T)); - } - // copy over metadata - size_ = v.size_; - capacity_ = v.capacity_; - // null out the original - v.init_data(); - } - size_t size() const { return size_; } bool empty() const { return size_ == 0; } @@ -169,6 +139,42 @@ class InlinedVector { } private: + void copy_from(const InlinedVector& v) { + // if v is allocated, make sure we have enough capacity. + if (v.dynamic_ != nullptr) { + reserve(v.capacity_); + } + // copy over elements + for (size_t i = 0; i < v.size_; ++i) { + new (&(data()[i])) T(v[i]); + } + // copy over metadata + size_ = v.size_; + capacity_ = v.capacity_; + } + + void move_from(InlinedVector& v) { + // if v is allocated, then we steal its dynamic array; otherwise, we + // move the elements individually. + if (v.dynamic_ != nullptr) { + dynamic_ = v.dynamic_; + } else { + move_elements(v.data(), data(), v.size_); + } + // copy over metadata + size_ = v.size_; + capacity_ = v.capacity_; + // null out the original + v.init_data(); + } + + static void move_elements(T* src, T* dst, size_t num_elements) { + for (size_t i = 0; i < num_elements; ++i) { + new (&dst[i]) T(std::move(src[i])); + src[i].~T(); + } + } + void init_data() { dynamic_ = nullptr; size_ = 0; diff --git a/src/core/lib/gprpp/map.h b/src/core/lib/gprpp/map.h new file mode 100644 index 00000000000..b210c26cbff --- /dev/null +++ b/src/core/lib/gprpp/map.h @@ -0,0 +1,419 @@ +/* + * + * Copyright 2017 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPC_CORE_LIB_GPRPP_MAP_H +#define GRPC_CORE_LIB_GPRPP_MAP_H + +#include + +#include +#include +#include +#include "src/core/lib/gpr/useful.h" +#include "src/core/lib/gprpp/memory.h" +#include "src/core/lib/gprpp/pair.h" + +namespace grpc_core { +struct StringLess { + bool operator()(const char* a, const char* b) const { + return strcmp(a, b) < 0; + } + bool operator()(const UniquePtr& k1, const UniquePtr& k2) { + return strcmp(k1.get(), k2.get()) < 0; + } +}; + +namespace testing { +class MapTest; +} + +// Alternative map implementation for grpc_core +template > +class Map { + public: + typedef Key key_type; + typedef T mapped_type; + typedef Pair value_type; + typedef Compare key_compare; + class iterator; + + ~Map() { clear(); } + + T& operator[](key_type&& key); + T& operator[](const key_type& key); + iterator find(const key_type& k); + size_t erase(const key_type& key); + // Removes the current entry and points to the next one + iterator erase(iterator iter); + + size_t size() { return size_; } + + template + Pair emplace(Args&&... args); + + Pair insert(value_type&& pair) { + return emplace(std::move(pair)); + } + + Pair insert(const value_type& pair) { return emplace(pair); } + + bool empty() const { return root_ == nullptr; } + + void clear() { + auto iter = begin(); + while (!empty()) { + iter = erase(iter); + } + } + + iterator begin() { + Entry* curr = GetMinEntry(root_); + return iterator(this, curr); + } + + iterator end() { return iterator(this, nullptr); } + + private: + friend class testing::MapTest; + struct Entry { + explicit Entry(value_type&& pair) : pair(std::move(pair)) {} + value_type pair; + Entry* left = nullptr; + Entry* right = nullptr; + int32_t height = 1; + }; + + static int32_t EntryHeight(const Entry* e) { + return e == nullptr ? 0 : e->height; + } + + static Entry* GetMinEntry(Entry* e); + Entry* InOrderSuccessor(const Entry* e) const; + static Entry* RotateLeft(Entry* e); + static Entry* RotateRight(Entry* e); + static Entry* RebalanceTreeAfterInsertion(Entry* root, const key_type& k); + static Entry* RebalanceTreeAfterDeletion(Entry* root); + // Returns a pair with the first value being an iterator pointing to the + // inserted entry and the second value being the new root of the subtree + // after a rebalance + Pair InsertRecursive(Entry* root, value_type&& p); + static Entry* RemoveRecursive(Entry* root, const key_type& k); + // Return 0 if lhs = rhs + // 1 if lhs > rhs + // -1 if lhs < rhs + static int CompareKeys(const Key& lhs, const Key& rhs); + + Entry* root_ = nullptr; + size_t size_ = 0; +}; + +template +class Map::iterator + : public std::iterator, int32_t, + Pair*, Pair&> { + public: + iterator(const iterator& iter) : curr_(iter.curr_), map_(iter.map_) {} + bool operator==(const iterator& rhs) const { return (curr_ == rhs.curr_); } + bool operator!=(const iterator& rhs) const { return (curr_ != rhs.curr_); } + + iterator& operator++() { + curr_ = map_->InOrderSuccessor(curr_); + return *this; + } + + iterator operator++(int) { + Entry* prev = curr_; + curr_ = map_->InOrderSuccessor(curr_); + return iterator(map_, prev); + } + + iterator& operator=(const iterator& other) { + if (this != &other) { + this->curr_ = other.curr_; + this->map_ = other.map_; + } + return *this; + } + + // operator*() + value_type& operator*() { return curr_->pair; } + const value_type& operator*() const { return curr_->pair; } + + // operator->() + value_type* operator->() { return &curr_->pair; } + value_type const* operator->() const { return &curr_->pair; } + + private: + friend class Map; + using GrpcMap = typename ::grpc_core::Map; + iterator(GrpcMap* map, Entry* curr) : curr_(curr), map_(map) {} + Entry* curr_; + GrpcMap* map_; +}; + +template +T& Map::operator[](key_type&& key) { + auto iter = find(key); + if (iter == end()) { + return emplace(std::move(key), T()).first->second; + } + return iter->second; +} + +template +T& Map::operator[](const key_type& key) { + auto iter = find(key); + if (iter == end()) { + return emplace(key, T()).first->second; + } + return iter->second; +} + +template +typename Map::iterator Map::find( + const key_type& k) { + Entry* iter = root_; + while (iter != nullptr) { + int comp = CompareKeys(iter->pair.first, k); + if (comp == 0) { + return iterator(this, iter); + } else if (comp < 0) { + iter = iter->right; + } else { + iter = iter->left; + } + } + return end(); +} + +template +template +typename ::grpc_core::Pair::iterator, bool> +Map::emplace(Args&&... args) { + Pair pair(std::forward(args)...); + iterator ret = find(pair.first); + bool insertion = false; + if (ret == end()) { + Pair p = InsertRecursive(root_, std::move(pair)); + root_ = p.second; + ret = p.first; + insertion = true; + size_++; + } + return MakePair(ret, insertion); +} + +template +size_t Map::erase(const key_type& key) { + iterator it = find(key); + if (it == end()) return 0; + erase(it); + return 1; +} + +// TODO(mhaidry): Modify erase to use the iterator location +// to create an efficient erase method +template +typename Map::iterator Map::erase( + iterator iter) { + if (iter == end()) return iter; + key_type& del_key = iter->first; + iter++; + root_ = RemoveRecursive(root_, del_key); + size_--; + return iter; +} + +template +typename Map::Entry* Map::InOrderSuccessor( + const Entry* e) const { + if (e->right != nullptr) { + return GetMinEntry(e->right); + } + Entry* successor = nullptr; + Entry* iter = root_; + while (iter != nullptr) { + int comp = CompareKeys(iter->pair.first, e->pair.first); + if (comp > 0) { + successor = iter; + iter = iter->left; + } else if (comp < 0) { + iter = iter->right; + } else + break; + } + return successor; +} + +// Returns a pair with the first value being an iterator pointing to the +// inserted entry and the second value being the new root of the subtree +// after a rebalance +template +typename ::grpc_core::Pair::iterator, + typename Map::Entry*> +Map::InsertRecursive(Entry* root, value_type&& p) { + if (root == nullptr) { + Entry* e = New(std::move(p)); + return MakePair(iterator(this, e), e); + } + int comp = CompareKeys(root->pair.first, p.first); + if (comp > 0) { + Pair ret = InsertRecursive(root->left, std::move(p)); + root->left = ret.second; + ret.second = RebalanceTreeAfterInsertion(root, ret.first->first); + return ret; + } else if (comp < 0) { + Pair ret = InsertRecursive(root->right, std::move(p)); + root->right = ret.second; + ret.second = RebalanceTreeAfterInsertion(root, ret.first->first); + return ret; + } else { + root->pair = std::move(p); + return MakePair(iterator(this, root), root); + } +} + +template +typename Map::Entry* Map::GetMinEntry( + Entry* e) { + if (e != nullptr) { + while (e->left != nullptr) { + e = e->left; + } + } + return e; +} + +template +typename Map::Entry* Map::RotateLeft( + Entry* e) { + Entry* rightChild = e->right; + Entry* rightLeftChild = rightChild->left; + rightChild->left = e; + e->right = rightLeftChild; + e->height = 1 + GPR_MAX(EntryHeight(e->left), EntryHeight(e->right)); + rightChild->height = 1 + GPR_MAX(EntryHeight(rightChild->left), + EntryHeight(rightChild->right)); + return rightChild; +} + +template +typename Map::Entry* Map::RotateRight( + Entry* e) { + Entry* leftChild = e->left; + Entry* leftRightChild = leftChild->right; + leftChild->right = e; + e->left = leftRightChild; + e->height = 1 + GPR_MAX(EntryHeight(e->left), EntryHeight(e->right)); + leftChild->height = + 1 + GPR_MAX(EntryHeight(leftChild->left), EntryHeight(leftChild->right)); + return leftChild; +} + +template +typename Map::Entry* +Map::RebalanceTreeAfterInsertion(Entry* root, + const key_type& k) { + root->height = 1 + GPR_MAX(EntryHeight(root->left), EntryHeight(root->right)); + int32_t heightDifference = EntryHeight(root->left) - EntryHeight(root->right); + if (heightDifference > 1 && CompareKeys(root->left->pair.first, k) > 0) { + return RotateRight(root); + } + if (heightDifference < -1 && CompareKeys(root->right->pair.first, k) < 0) { + return RotateLeft(root); + } + if (heightDifference > 1 && CompareKeys(root->left->pair.first, k) < 0) { + root->left = RotateLeft(root->left); + return RotateRight(root); + } + if (heightDifference < -1 && CompareKeys(root->right->pair.first, k) > 0) { + root->right = RotateRight(root->right); + return RotateLeft(root); + } + return root; +} + +template +typename Map::Entry* +Map::RebalanceTreeAfterDeletion(Entry* root) { + root->height = 1 + GPR_MAX(EntryHeight(root->left), EntryHeight(root->right)); + int32_t heightDifference = EntryHeight(root->left) - EntryHeight(root->right); + if (heightDifference > 1) { + int leftHeightDifference = + EntryHeight(root->left->left) - EntryHeight(root->left->right); + if (leftHeightDifference < 0) { + root->left = RotateLeft(root->left); + } + return RotateRight(root); + } + if (heightDifference < -1) { + int rightHeightDifference = + EntryHeight(root->right->left) - EntryHeight(root->right->right); + if (rightHeightDifference > 0) { + root->right = RotateRight(root->right); + } + return RotateLeft(root); + } + return root; +} + +template +typename Map::Entry* Map::RemoveRecursive( + Entry* root, const key_type& k) { + if (root == nullptr) return root; + int comp = CompareKeys(root->pair.first, k); + if (comp > 0) { + root->left = RemoveRecursive(root->left, k); + } else if (comp < 0) { + root->right = RemoveRecursive(root->right, k); + } else { + Entry* ret; + if (root->left == nullptr) { + ret = root->right; + Delete(root); + return ret; + } else if (root->right == nullptr) { + ret = root->left; + Delete(root); + return ret; + } else { + ret = root->right; + while (ret->left != nullptr) { + ret = ret->left; + } + root->pair.swap(ret->pair); + root->right = RemoveRecursive(root->right, ret->pair.first); + } + } + return RebalanceTreeAfterDeletion(root); +} + +template +int Map::CompareKeys(const key_type& lhs, + const key_type& rhs) { + key_compare compare; + bool left_comparison = compare(lhs, rhs); + bool right_comparison = compare(rhs, lhs); + // Both values are equal + if (!left_comparison && !right_comparison) { + return 0; + } + return left_comparison ? -1 : 1; +} +} // namespace grpc_core +#endif /* GRPC_CORE_LIB_GPRPP_MAP_H */ diff --git a/src/core/lib/gprpp/memory.h b/src/core/lib/gprpp/memory.h index e90bedcd9b4..b4b63ae771a 100644 --- a/src/core/lib/gprpp/memory.h +++ b/src/core/lib/gprpp/memory.h @@ -40,15 +40,10 @@ namespace grpc_core { -// The alignment of memory returned by gpr_malloc(). -constexpr size_t kAlignmentForDefaultAllocationInBytes = 8; - // Alternative to new, since we cannot use it (for fear of libstdc++) template inline T* New(Args&&... args) { - void* p = alignof(T) > kAlignmentForDefaultAllocationInBytes - ? gpr_malloc_aligned(sizeof(T), alignof(T)) - : gpr_malloc(sizeof(T)); + void* p = gpr_malloc(sizeof(T)); return new (p) T(std::forward(args)...); } @@ -57,11 +52,7 @@ template inline void Delete(T* p) { if (p == nullptr) return; p->~T(); - if (alignof(T) > kAlignmentForDefaultAllocationInBytes) { - gpr_free_aligned(p); - } else { - gpr_free(p); - } + gpr_free(p); } template diff --git a/src/core/lib/gprpp/optional.h b/src/core/lib/gprpp/optional.h new file mode 100644 index 00000000000..ab5f86393b6 --- /dev/null +++ b/src/core/lib/gprpp/optional.h @@ -0,0 +1,48 @@ +/* + * + * Copyright 2019 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_GPRPP_OPTIONAL_H +#define GRPC_CORE_LIB_GPRPP_OPTIONAL_H + +namespace grpc_core { + +/* A make-shift alternative for absl::Optional. This can be removed in favor of + * that once absl dependencies can be introduced. */ +template +class Optional { + public: + Optional() : value_() {} + void set(const T& val) { + value_ = val; + set_ = true; + } + + bool has_value() const { return set_; } + + void reset() { set_ = false; } + + T value() const { return value_; } + + private: + T value_; + bool set_ = false; +}; + +} /* namespace grpc_core */ + +#endif /* GRPC_CORE_LIB_GPRPP_OPTIONAL_H */ diff --git a/src/core/lib/gprpp/orphanable.h b/src/core/lib/gprpp/orphanable.h index 3123e3f5a39..2e467e49060 100644 --- a/src/core/lib/gprpp/orphanable.h +++ b/src/core/lib/gprpp/orphanable.h @@ -31,6 +31,7 @@ #include "src/core/lib/gprpp/abstract.h" #include "src/core/lib/gprpp/debug_location.h" #include "src/core/lib/gprpp/memory.h" +#include "src/core/lib/gprpp/ref_counted.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" namespace grpc_core { @@ -89,107 +90,43 @@ class InternallyRefCounted : public Orphanable { template friend class RefCountedPtr; - InternallyRefCounted() { gpr_ref_init(&refs_, 1); } - virtual ~InternallyRefCounted() {} + // TraceFlagT is defined to accept both DebugOnlyTraceFlag and TraceFlag. + // Note: RefCount tracing is only enabled on debug builds, even when a + // TraceFlag is used. + template + explicit InternallyRefCounted(TraceFlagT* trace_flag = nullptr, + intptr_t initial_refcount = 1) + : refs_(initial_refcount, trace_flag) {} + virtual ~InternallyRefCounted() = default; RefCountedPtr Ref() GRPC_MUST_USE_RESULT { IncrementRefCount(); return RefCountedPtr(static_cast(this)); } - - void Unref() { - if (gpr_unref(&refs_)) { - Delete(static_cast(this)); - } - } - - private: - void IncrementRefCount() { gpr_ref(&refs_); } - - gpr_refcount refs_; -}; - -// An alternative version of the InternallyRefCounted base class that -// supports tracing. This is intended to be used in cases where the -// object will be handled both by idiomatic C++ code using smart -// pointers and legacy code that is manually calling Ref() and Unref(). -// Once all of our code is converted to idiomatic C++, we may be able to -// eliminate this class. -template -class InternallyRefCountedWithTracing : public Orphanable { - public: - // Not copyable nor movable. - InternallyRefCountedWithTracing(const InternallyRefCountedWithTracing&) = - delete; - InternallyRefCountedWithTracing& operator=( - const InternallyRefCountedWithTracing&) = delete; - - GRPC_ABSTRACT_BASE_CLASS - - protected: - GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE - - // Allow RefCountedPtr<> to access Unref() and IncrementRefCount(). - template - friend class RefCountedPtr; - - InternallyRefCountedWithTracing() - : InternallyRefCountedWithTracing(static_cast(nullptr)) {} - - explicit InternallyRefCountedWithTracing(TraceFlag* trace_flag) - : trace_flag_(trace_flag) { - gpr_ref_init(&refs_, 1); - } - -#ifdef NDEBUG - explicit InternallyRefCountedWithTracing(DebugOnlyTraceFlag* trace_flag) - : InternallyRefCountedWithTracing() {} -#endif - - virtual ~InternallyRefCountedWithTracing() {} - - RefCountedPtr Ref() GRPC_MUST_USE_RESULT { - IncrementRefCount(); - return RefCountedPtr(static_cast(this)); - } - RefCountedPtr Ref(const DebugLocation& location, 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_INFO, "%s:%p %s:%d ref %" PRIdPTR " -> %" PRIdPTR " %s", - trace_flag_->name(), this, location.file(), location.line(), - old_refs, old_refs + 1, reason); - } - return Ref(); + IncrementRefCount(location, reason); + return RefCountedPtr(static_cast(this)); } - // TODO(roth): Once all of our code is converted to C++ and can use - // RefCountedPtr<> instead of manual ref-counting, make the Unref() methods - // private, since they will only be used by RefCountedPtr<>, which is a - // friend of this class. - void Unref() { - if (gpr_unref(&refs_)) { + if (GPR_UNLIKELY(refs_.Unref())) { + Delete(static_cast(this)); + } + } + void Unref(const DebugLocation& location, const char* reason) { + if (GPR_UNLIKELY(refs_.Unref(location, reason))) { Delete(static_cast(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_INFO, "%s:%p %s:%d unref %" PRIdPTR " -> %" PRIdPTR " %s", - trace_flag_->name(), this, location.file(), location.line(), - old_refs, old_refs - 1, reason); - } - Unref(); + private: + void IncrementRefCount() { refs_.Ref(); } + void IncrementRefCount(const DebugLocation& location, const char* reason) { + refs_.Ref(location, reason); } - private: - void IncrementRefCount() { gpr_ref(&refs_); } - - TraceFlag* trace_flag_ = nullptr; - gpr_refcount refs_; + grpc_core::RefCount refs_; }; } // namespace grpc_core diff --git a/src/core/lib/iomgr/network_status_tracker.cc b/src/core/lib/gprpp/pair.h similarity index 52% rename from src/core/lib/iomgr/network_status_tracker.cc rename to src/core/lib/gprpp/pair.h index d4b7f4a57d1..ca8294cc7bb 100644 --- a/src/core/lib/iomgr/network_status_tracker.cc +++ b/src/core/lib/gprpp/pair.h @@ -1,6 +1,6 @@ /* * - * Copyright 2015 gRPC authors. + * Copyright 2017 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,21 +16,23 @@ * */ +#ifndef GRPC_CORE_LIB_GPRPP_PAIR_H +#define GRPC_CORE_LIB_GPRPP_PAIR_H + #include -#include "src/core/lib/iomgr/endpoint.h" -#include "src/core/lib/iomgr/network_status_tracker.h" +#include -void grpc_network_status_shutdown(void) {} +namespace grpc_core { +template +using Pair = std::pair; -void grpc_network_status_init(void) { - // TODO(makarandd): Install callback with OS to monitor network status. +template +inline Pair::type, typename std::decay::type> +MakePair(T1&& u, T2&& v) { + typedef typename std::decay::type V1; + typedef typename std::decay::type V2; + return Pair(std::forward(u), std::forward(v)); } - -void grpc_destroy_network_status_monitor() {} - -void grpc_network_status_register_endpoint(grpc_endpoint* ep) { (void)ep; } - -void grpc_network_status_unregister_endpoint(grpc_endpoint* ep) { (void)ep; } - -void grpc_network_status_shutdown_all_endpoints() {} +} // namespace grpc_core +#endif /* GRPC_CORE_LIB_GPRPP_PAIR_H */ diff --git a/src/core/lib/gprpp/ref_counted.h b/src/core/lib/gprpp/ref_counted.h index e366445bff4..4de50985dcf 100644 --- a/src/core/lib/gprpp/ref_counted.h +++ b/src/core/lib/gprpp/ref_counted.h @@ -21,6 +21,7 @@ #include +#include #include #include @@ -30,6 +31,7 @@ #include "src/core/lib/debug/trace.h" #include "src/core/lib/gprpp/abstract.h" +#include "src/core/lib/gprpp/atomic.h" #include "src/core/lib/gprpp/debug_location.h" #include "src/core/lib/gprpp/memory.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" @@ -73,32 +75,95 @@ class RefCount { using Value = intptr_t; // `init` is the initial refcount stored in this object. - constexpr explicit RefCount(Value init = 1) : value_(init) {} + // + // TraceFlagT is defined to accept both DebugOnlyTraceFlag and TraceFlag. + // Note: RefCount tracing is only enabled on debug builds, even when a + // TraceFlag is used. + template + constexpr explicit RefCount(Value init = 1, TraceFlagT* trace_flag = nullptr) + : +#ifndef NDEBUG + trace_flag_(trace_flag), +#endif + value_(init) { + } // Increases the ref-count by `n`. - void Ref(Value n = 1) { value_.fetch_add(n, std::memory_order_relaxed); } + void Ref(Value n = 1) { value_.FetchAdd(n, MemoryOrder::RELAXED); } + void Ref(const DebugLocation& location, const char* reason, Value n = 1) { +#ifndef NDEBUG + if (location.Log() && trace_flag_ != nullptr && trace_flag_->enabled()) { + const RefCount::Value old_refs = get(); + gpr_log(GPR_INFO, "%s:%p %s:%d ref %" PRIdPTR " -> %" PRIdPTR " %s", + trace_flag_->name(), this, location.file(), location.line(), + old_refs, old_refs + n, reason); + } +#endif + Ref(n); + } // Similar to Ref() with an assert on the ref-count being non-zero. void RefNonZero() { #ifndef NDEBUG - const Value prior = value_.fetch_add(1, std::memory_order_relaxed); + const Value prior = value_.FetchAdd(1, MemoryOrder::RELAXED); assert(prior > 0); #else Ref(); #endif } + void RefNonZero(const DebugLocation& location, const char* reason) { +#ifndef NDEBUG + if (location.Log() && trace_flag_ != nullptr && trace_flag_->enabled()) { + const RefCount::Value old_refs = get(); + 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); + } +#endif + RefNonZero(); + } + + bool RefIfNonZero() { return value_.IncrementIfNonzero(); } + + bool RefIfNonZero(const DebugLocation& location, const char* reason) { +#ifndef NDEBUG + if (location.Log() && trace_flag_ != nullptr && trace_flag_->enabled()) { + const RefCount::Value old_refs = get(); + gpr_log(GPR_INFO, + "%s:%p %s:%d ref_if_non_zero " + "%" PRIdPTR " -> %" PRIdPTR " %s", + trace_flag_->name(), this, location.file(), location.line(), + old_refs, old_refs + 1, reason); + } +#endif + return RefIfNonZero(); + } // Decrements the ref-count and returns true if the ref-count reaches 0. bool Unref() { - const Value prior = value_.fetch_sub(1, std::memory_order_acq_rel); + const Value prior = value_.FetchSub(1, MemoryOrder::ACQ_REL); GPR_DEBUG_ASSERT(prior > 0); return prior == 1; } - - Value get() const { return value_.load(std::memory_order_relaxed); } + bool Unref(const DebugLocation& location, const char* reason) { +#ifndef NDEBUG + if (location.Log() && trace_flag_ != nullptr && trace_flag_->enabled()) { + const RefCount::Value old_refs = get(); + 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); + } +#endif + return Unref(); + } private: - std::atomic value_; + Value get() const { return value_.Load(MemoryOrder::RELAXED); } + +#ifndef NDEBUG + TraceFlag* trace_flag_; +#endif + Atomic value_; }; // A base class for reference-counted objects. @@ -115,7 +180,7 @@ class RefCount { // So, use NonPolymorphicRefCount only when both of the following conditions // are guaranteed to hold: // (a) Child is a concrete leaf class in RefCounted, and -// (b) you are gauranteed to call Unref only on concrete leaf classes and not +// (b) you are guaranteed to call Unref only on concrete leaf classes and not // their parents. // // The following example is illegal, because calling Unref() will not call @@ -135,12 +200,23 @@ class RefCounted : public Impl { return RefCountedPtr(static_cast(this)); } + RefCountedPtr Ref(const DebugLocation& location, + const char* reason) GRPC_MUST_USE_RESULT { + IncrementRefCount(location, reason); + return RefCountedPtr(static_cast(this)); + } + // TODO(roth): Once all of our code is converted to C++ and can use // RefCountedPtr<> instead of manual ref-counting, make this method // private, since it will only be used by RefCountedPtr<>, which is a // friend of this class. void Unref() { - if (refs_.Unref()) { + if (GPR_UNLIKELY(refs_.Unref())) { + Delete(static_cast(this)); + } + } + void Unref(const DebugLocation& location, const char* reason) { + if (GPR_UNLIKELY(refs_.Unref(location, reason))) { Delete(static_cast(this)); } } @@ -154,7 +230,13 @@ class RefCounted : public Impl { protected: GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE - RefCounted() = default; + // TraceFlagT is defined to accept both DebugOnlyTraceFlag and TraceFlag. + // Note: RefCount tracing is only enabled on debug builds, even when a + // TraceFlag is used. + template + explicit RefCounted(TraceFlagT* trace_flag = nullptr, + intptr_t initial_refcount = 1) + : refs_(initial_refcount, trace_flag) {} // Note: Depending on the Impl used, this dtor can be implicitly virtual. ~RefCounted() = default; @@ -165,87 +247,10 @@ class RefCounted : public Impl { friend class RefCountedPtr; void IncrementRefCount() { refs_.Ref(); } - - RefCount refs_; -}; - -// An alternative version of the RefCounted base class that -// supports tracing. This is intended to be used in cases where the -// object will be handled both by idiomatic C++ code using smart -// pointers and legacy code that is manually calling Ref() and Unref(). -// Once all of our code is converted to idiomatic C++, we may be able to -// eliminate this class. -template -class RefCountedWithTracing : public Impl { - public: - RefCountedPtr Ref() GRPC_MUST_USE_RESULT { - IncrementRefCount(); - return RefCountedPtr(static_cast(this)); + void IncrementRefCount(const DebugLocation& location, const char* reason) { + refs_.Ref(location, reason); } - RefCountedPtr Ref(const DebugLocation& location, - const char* reason) GRPC_MUST_USE_RESULT { - if (location.Log() && trace_flag_ != nullptr && trace_flag_->enabled()) { - const RefCount::Value old_refs = refs_.get(); - 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); - } - return Ref(); - } - - // TODO(roth): Once all of our code is converted to C++ and can use - // RefCountedPtr<> instead of manual ref-counting, make the Unref() methods - // private, since they will only be used by RefCountedPtr<>, which is a - // friend of this class. - - void Unref() { - if (refs_.Unref()) { - Delete(static_cast(this)); - } - } - - void Unref(const DebugLocation& location, const char* reason) { - if (location.Log() && trace_flag_ != nullptr && trace_flag_->enabled()) { - const RefCount::Value old_refs = refs_.get(); - 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); - } - Unref(); - } - - // Not copyable nor movable. - RefCountedWithTracing(const RefCountedWithTracing&) = delete; - RefCountedWithTracing& operator=(const RefCountedWithTracing&) = delete; - - GRPC_ABSTRACT_BASE_CLASS - - protected: - GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE - - RefCountedWithTracing() - : RefCountedWithTracing(static_cast(nullptr)) {} - - explicit RefCountedWithTracing(TraceFlag* trace_flag) - : trace_flag_(trace_flag) {} - -#ifdef NDEBUG - explicit RefCountedWithTracing(DebugOnlyTraceFlag* trace_flag) - : RefCountedWithTracing() {} -#endif - - // Note: Depending on the Impl used, this dtor can be implicitly virtual. - ~RefCountedWithTracing() = default; - - private: - // Allow RefCountedPtr<> to access IncrementRefCount(). - template - friend class RefCountedPtr; - - void IncrementRefCount() { refs_.Ref(); } - - TraceFlag* trace_flag_ = nullptr; RefCount refs_; }; diff --git a/src/core/lib/gprpp/ref_counted_ptr.h b/src/core/lib/gprpp/ref_counted_ptr.h index facd7c6dce6..19f38d7f013 100644 --- a/src/core/lib/gprpp/ref_counted_ptr.h +++ b/src/core/lib/gprpp/ref_counted_ptr.h @@ -24,6 +24,7 @@ #include #include +#include "src/core/lib/gprpp/debug_location.h" #include "src/core/lib/gprpp/memory.h" namespace grpc_core { @@ -49,21 +50,19 @@ class RefCountedPtr { } template RefCountedPtr(RefCountedPtr&& other) { - value_ = other.value_; + value_ = static_cast(other.value_); other.value_ = nullptr; } // Move assignment. RefCountedPtr& operator=(RefCountedPtr&& other) { - if (value_ != nullptr) value_->Unref(); - value_ = other.value_; + reset(other.value_); other.value_ = nullptr; return *this; } template RefCountedPtr& operator=(RefCountedPtr&& other) { - if (value_ != nullptr) value_->Unref(); - value_ = other.value_; + reset(other.value_); other.value_ = nullptr; return *this; } @@ -78,7 +77,7 @@ class RefCountedPtr { static_assert(std::has_virtual_destructor::value, "T does not have a virtual dtor"); if (other.value_ != nullptr) other.value_->IncrementRefCount(); - value_ = other.value_; + value_ = static_cast(other.value_); } // Copy assignment. @@ -86,8 +85,7 @@ class RefCountedPtr { // Note: Order of reffing and unreffing is important here in case value_ // and other.value_ are the same object. if (other.value_ != nullptr) other.value_->IncrementRefCount(); - if (value_ != nullptr) value_->Unref(); - value_ = other.value_; + reset(other.value_); return *this; } template @@ -97,8 +95,7 @@ class RefCountedPtr { // Note: Order of reffing and unreffing is important here in case value_ // and other.value_ are the same object. if (other.value_ != nullptr) other.value_->IncrementRefCount(); - if (value_ != nullptr) value_->Unref(); - value_ = other.value_; + reset(other.value_); return *this; } @@ -107,21 +104,29 @@ class RefCountedPtr { } // If value is non-null, we take ownership of a ref to it. - void reset(T* value) { + void reset(T* value = nullptr) { if (value_ != nullptr) value_->Unref(); value_ = value; } + void reset(const DebugLocation& location, const char* reason, + T* value = nullptr) { + if (value_ != nullptr) value_->Unref(location, reason); + value_ = value; + } template - void reset(Y* value) { + void reset(Y* value = nullptr) { static_assert(std::has_virtual_destructor::value, "T does not have a virtual dtor"); if (value_ != nullptr) value_->Unref(); - value_ = value; + value_ = static_cast(value); } - - void reset() { - if (value_ != nullptr) value_->Unref(); - value_ = nullptr; + template + void reset(const DebugLocation& location, const char* reason, + Y* value = nullptr) { + static_assert(std::has_virtual_destructor::value, + "T does not have a virtual dtor"); + if (value_ != nullptr) value_->Unref(location, reason); + value_ = static_cast(value); } // TODO(roth): This method exists solely as a transition mechanism to allow diff --git a/src/core/lib/gprpp/sync.h b/src/core/lib/gprpp/sync.h new file mode 100644 index 00000000000..895ca60fec0 --- /dev/null +++ b/src/core/lib/gprpp/sync.h @@ -0,0 +1,126 @@ +/* + * + * Copyright 2019 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_GPRPP_SYNC_H +#define GRPC_CORE_LIB_GPRPP_SYNC_H + +#include + +#include +#include +#include +#include + +// The core library is not accessible in C++ codegen headers, and vice versa. +// Thus, we need to have duplicate headers with similar functionality. +// Make sure any change to this file is also reflected in +// include/grpcpp/impl/codegen/sync.h. +// +// Whenever possible, prefer using this file over +// since this file doesn't rely on g_core_codegen_interface and hence does not +// pay the costs of virtual function calls. + +namespace grpc_core { + +class Mutex { + public: + Mutex() { gpr_mu_init(&mu_); } + ~Mutex() { gpr_mu_destroy(&mu_); } + + Mutex(const Mutex&) = delete; + Mutex& operator=(const Mutex&) = delete; + + gpr_mu* get() { return &mu_; } + const gpr_mu* get() const { return &mu_; } + + private: + gpr_mu mu_; +}; + +// MutexLock is a std:: +class MutexLock { + public: + explicit MutexLock(Mutex* mu) : mu_(mu->get()) { gpr_mu_lock(mu_); } + explicit MutexLock(gpr_mu* mu) : mu_(mu) { gpr_mu_lock(mu_); } + ~MutexLock() { gpr_mu_unlock(mu_); } + + MutexLock(const MutexLock&) = delete; + MutexLock& operator=(const MutexLock&) = delete; + + private: + gpr_mu* const mu_; +}; + +class ReleasableMutexLock { + public: + explicit ReleasableMutexLock(Mutex* mu) : mu_(mu->get()) { gpr_mu_lock(mu_); } + explicit ReleasableMutexLock(gpr_mu* mu) : mu_(mu) { gpr_mu_lock(mu_); } + ~ReleasableMutexLock() { + if (!released_) gpr_mu_unlock(mu_); + } + + ReleasableMutexLock(const ReleasableMutexLock&) = delete; + ReleasableMutexLock& operator=(const ReleasableMutexLock&) = delete; + + void Lock() { + GPR_DEBUG_ASSERT(released_); + gpr_mu_lock(mu_); + released_ = false; + } + + void Unlock() { + GPR_DEBUG_ASSERT(!released_); + released_ = true; + gpr_mu_unlock(mu_); + } + + private: + gpr_mu* const mu_; + bool released_ = false; +}; + +class CondVar { + public: + CondVar() { gpr_cv_init(&cv_); } + ~CondVar() { gpr_cv_destroy(&cv_); } + + CondVar(const CondVar&) = delete; + CondVar& operator=(const CondVar&) = delete; + + void Signal() { gpr_cv_signal(&cv_); } + void Broadcast() { gpr_cv_broadcast(&cv_); } + + int Wait(Mutex* mu) { return Wait(mu, gpr_inf_future(GPR_CLOCK_REALTIME)); } + int Wait(Mutex* mu, const gpr_timespec& deadline) { + return gpr_cv_wait(&cv_, mu->get(), deadline); + } + + template + void WaitUntil(Mutex* mu, Predicate pred) { + while (!pred()) { + Wait(mu, gpr_inf_future(GPR_CLOCK_REALTIME)); + } + } + + private: + gpr_cv cv_; +}; + +} // namespace grpc_core + +#endif /* GRPC_CORE_LIB_GPRPP_SYNC_H */ diff --git a/src/core/lib/gprpp/thd.h b/src/core/lib/gprpp/thd.h index caf0652c1a7..cae707061e0 100644 --- a/src/core/lib/gprpp/thd.h +++ b/src/core/lib/gprpp/thd.h @@ -47,6 +47,27 @@ class ThreadInternalsInterface { class Thread { public: + class Options { + public: + Options() : joinable_(true), tracked_(true) {} + /// Set whether the thread is joinable or detached. + Options& set_joinable(bool joinable) { + joinable_ = joinable; + return *this; + } + bool joinable() const { return joinable_; } + + /// Set whether the thread is tracked for fork support. + Options& set_tracked(bool tracked) { + tracked_ = tracked; + return *this; + } + bool tracked() const { return tracked_; } + + private: + bool joinable_; + bool tracked_; + }; /// Default constructor only to allow use in structs that lack constructors /// Does not produce a validly-constructed thread; must later /// use placement new to construct a real thread. Does not init mu_ and cv_ @@ -57,14 +78,17 @@ class Thread { /// with argument \a arg once it is started. /// The optional \a success argument indicates whether the thread /// is successfully created. + /// The optional \a options can be used to set the thread detachable. Thread(const char* thd_name, void (*thd_body)(void* arg), void* arg, - bool* success = nullptr); + bool* success = nullptr, const Options& options = Options()); /// Move constructor for thread. After this is called, the other thread /// no longer represents a living thread object - Thread(Thread&& other) : state_(other.state_), impl_(other.impl_) { + Thread(Thread&& other) + : state_(other.state_), impl_(other.impl_), options_(other.options_) { other.state_ = MOVED; other.impl_ = nullptr; + other.options_ = Options(); } /// Move assignment operator for thread. After this is called, the other @@ -79,27 +103,37 @@ class Thread { // assert it for the time being. state_ = other.state_; impl_ = other.impl_; + options_ = other.options_; other.state_ = MOVED; other.impl_ = nullptr; + other.options_ = Options(); } return *this; } /// The destructor is strictly optional; either the thread never came to life - /// and the constructor itself killed it or it has already been joined and - /// the Join function kills it. The destructor shouldn't have to do anything. - ~Thread() { GPR_ASSERT(impl_ == nullptr); } + /// and the constructor itself killed it, or it has already been joined and + /// the Join function kills it, or it was detached (non-joinable) and it has + /// run to completion and is now killing itself. The destructor shouldn't have + /// to do anything. + ~Thread() { GPR_ASSERT(!options_.joinable() || impl_ == nullptr); } void Start() { if (impl_ != nullptr) { GPR_ASSERT(state_ == ALIVE); state_ = STARTED; impl_->Start(); + // If the Thread is not joinable, then the impl_ will cause the deletion + // of this Thread object when the thread function completes. Since no + // other operation is allowed to a detached thread after Start, there is + // no need to change the value of the impl_ or state_ . The next operation + // on this object will be the deletion, which will trigger the destructor. } else { GPR_ASSERT(state_ == FAILED); } - }; + } + // It is only legal to call Join if the Thread is created as joinable. void Join() { if (impl_ != nullptr) { impl_->Join(); @@ -109,7 +143,7 @@ class Thread { } else { GPR_ASSERT(state_ == FAILED); } - }; + } private: Thread(const Thread&) = delete; @@ -125,6 +159,7 @@ class Thread { enum ThreadState { FAKE, ALIVE, STARTED, DONE, FAILED, MOVED }; ThreadState state_; internal::ThreadInternalsInterface* impl_; + Options options_; }; } // namespace grpc_core diff --git a/src/core/lib/gprpp/thd_posix.cc b/src/core/lib/gprpp/thd_posix.cc index 2751b221a8f..28932081538 100644 --- a/src/core/lib/gprpp/thd_posix.cc +++ b/src/core/lib/gprpp/thd_posix.cc @@ -44,13 +44,14 @@ struct thd_arg { void (*body)(void* arg); /* body of a thread */ void* arg; /* argument to a thread */ const char* name; /* name of thread. Can be nullptr. */ + bool joinable; + bool tracked; }; -class ThreadInternalsPosix - : public grpc_core::internal::ThreadInternalsInterface { +class ThreadInternalsPosix : public internal::ThreadInternalsInterface { public: ThreadInternalsPosix(const char* thd_name, void (*thd_body)(void* arg), - void* arg, bool* success) + void* arg, bool* success, const Thread::Options& options) : started_(false) { gpr_mu_init(&mu_); gpr_cv_init(&ready_); @@ -63,11 +64,20 @@ class ThreadInternalsPosix info->body = thd_body; info->arg = arg; info->name = thd_name; - grpc_core::Fork::IncThreadCount(); + info->joinable = options.joinable(); + info->tracked = options.tracked(); + if (options.tracked()) { + Fork::IncThreadCount(); + } GPR_ASSERT(pthread_attr_init(&attr) == 0); - GPR_ASSERT(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE) == - 0); + if (options.joinable()) { + GPR_ASSERT(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE) == + 0); + } else { + GPR_ASSERT(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) == + 0); + } *success = (pthread_create(&pthread_id_, &attr, @@ -97,8 +107,14 @@ class ThreadInternalsPosix } gpr_mu_unlock(&arg.thread->mu_); + if (!arg.joinable) { + Delete(arg.thread); + } + (*arg.body)(arg.arg); - grpc_core::Fork::DecThreadCount(); + if (arg.tracked) { + Fork::DecThreadCount(); + } return nullptr; }, info) == 0); @@ -108,9 +124,11 @@ class ThreadInternalsPosix if (!(*success)) { /* don't use gpr_free, as this was allocated using malloc (see above) */ free(info); - grpc_core::Fork::DecThreadCount(); + if (options.tracked()) { + Fork::DecThreadCount(); + } } - }; + } ~ThreadInternalsPosix() override { gpr_mu_destroy(&mu_); @@ -136,15 +154,15 @@ class ThreadInternalsPosix } // namespace Thread::Thread(const char* thd_name, void (*thd_body)(void* arg), void* arg, - bool* success) { + bool* success, const Options& options) + : options_(options) { bool outcome = false; - impl_ = - grpc_core::New(thd_name, thd_body, arg, &outcome); + impl_ = New(thd_name, thd_body, arg, &outcome, options); if (outcome) { state_ = ALIVE; } else { state_ = FAILED; - grpc_core::Delete(impl_); + Delete(impl_); impl_ = nullptr; } diff --git a/src/core/lib/gprpp/thd_windows.cc b/src/core/lib/gprpp/thd_windows.cc index 71584fd358e..bbb48a58cd6 100644 --- a/src/core/lib/gprpp/thd_windows.cc +++ b/src/core/lib/gprpp/thd_windows.cc @@ -33,10 +33,8 @@ #if defined(_MSC_VER) #define thread_local __declspec(thread) -#define WIN_LAMBDA #elif defined(__GNUC__) #define thread_local __thread -#define WIN_LAMBDA WINAPI #else #error "Unknown compiler - please file a bug report" #endif @@ -48,6 +46,7 @@ struct thd_info { void (*body)(void* arg); /* body of a thread */ void* arg; /* argument to a thread */ HANDLE join_event; /* the join event */ + bool joinable; /* whether it is joinable */ }; thread_local struct thd_info* g_thd_info; @@ -55,7 +54,8 @@ thread_local struct thd_info* g_thd_info; class ThreadInternalsWindows : public grpc_core::internal::ThreadInternalsInterface { public: - ThreadInternalsWindows(void (*thd_body)(void* arg), void* arg, bool* success) + ThreadInternalsWindows(void (*thd_body)(void* arg), void* arg, bool* success, + const grpc_core::Thread::Options& options) : started_(false) { gpr_mu_init(&mu_); gpr_cv_init(&ready_); @@ -65,35 +65,23 @@ class ThreadInternalsWindows info_->thread = this; info_->body = thd_body; info_->arg = arg; - - info_->join_event = CreateEvent(nullptr, FALSE, FALSE, nullptr); - if (info_->join_event == nullptr) { - gpr_free(info_); + info_->join_event = nullptr; + info_->joinable = options.joinable(); + if (info_->joinable) { + info_->join_event = CreateEvent(nullptr, FALSE, FALSE, nullptr); + if (info_->join_event == nullptr) { + gpr_free(info_); + *success = false; + return; + } + } + handle = CreateThread(nullptr, 64 * 1024, thread_body, info_, 0, nullptr); + if (handle == nullptr) { + destroy_thread(); *success = false; } else { - handle = CreateThread( - nullptr, 64 * 1024, - [](void* v) WIN_LAMBDA -> DWORD { - g_thd_info = static_cast(v); - gpr_mu_lock(&g_thd_info->thread->mu_); - while (!g_thd_info->thread->started_) { - gpr_cv_wait(&g_thd_info->thread->ready_, &g_thd_info->thread->mu_, - gpr_inf_future(GPR_CLOCK_MONOTONIC)); - } - gpr_mu_unlock(&g_thd_info->thread->mu_); - g_thd_info->body(g_thd_info->arg); - BOOL ret = SetEvent(g_thd_info->join_event); - GPR_ASSERT(ret); - return 0; - }, - info_, 0, nullptr); - if (handle == nullptr) { - destroy_thread(); - *success = false; - } else { - CloseHandle(handle); - *success = true; - } + CloseHandle(handle); + *success = true; } } @@ -116,8 +104,32 @@ class ThreadInternalsWindows } private: + static DWORD WINAPI thread_body(void* v) { + g_thd_info = static_cast(v); + gpr_mu_lock(&g_thd_info->thread->mu_); + while (!g_thd_info->thread->started_) { + gpr_cv_wait(&g_thd_info->thread->ready_, &g_thd_info->thread->mu_, + gpr_inf_future(GPR_CLOCK_MONOTONIC)); + } + gpr_mu_unlock(&g_thd_info->thread->mu_); + if (!g_thd_info->joinable) { + grpc_core::Delete(g_thd_info->thread); + g_thd_info->thread = nullptr; + } + g_thd_info->body(g_thd_info->arg); + if (g_thd_info->joinable) { + BOOL ret = SetEvent(g_thd_info->join_event); + GPR_ASSERT(ret); + } else { + gpr_free(g_thd_info); + } + return 0; + } + void destroy_thread() { - CloseHandle(info_->join_event); + if (info_ != nullptr && info_->joinable) { + CloseHandle(info_->join_event); + } gpr_free(info_); } @@ -132,14 +144,15 @@ class ThreadInternalsWindows namespace grpc_core { Thread::Thread(const char* thd_name, void (*thd_body)(void* arg), void* arg, - bool* success) { + bool* success, const Options& options) + : options_(options) { bool outcome = false; - impl_ = grpc_core::New(thd_body, arg, &outcome); + impl_ = New(thd_body, arg, &outcome, options); if (outcome) { state_ = ALIVE; } else { state_ = FAILED; - grpc_core::Delete(impl_); + Delete(impl_); impl_ = nullptr; } diff --git a/src/core/lib/http/httpcli.cc b/src/core/lib/http/httpcli.cc index 3bd7a2ce590..8a8da8b1604 100644 --- a/src/core/lib/http/httpcli.cc +++ b/src/core/lib/http/httpcli.cc @@ -121,7 +121,7 @@ static void append_error(internal_request* req, grpc_error* error) { } static void do_read(internal_request* req) { - grpc_endpoint_read(req->ep, &req->incoming, &req->on_read); + grpc_endpoint_read(req->ep, &req->incoming, &req->on_read, /*urgent=*/true); } static void on_read(void* user_data, grpc_error* error) { @@ -229,7 +229,8 @@ static void internal_request_begin(grpc_httpcli_context* context, const grpc_httpcli_request* request, grpc_millis deadline, grpc_closure* on_done, grpc_httpcli_response* response, - const char* name, grpc_slice request_text) { + const char* name, + const grpc_slice& request_text) { internal_request* req = static_cast(gpr_malloc(sizeof(internal_request))); memset(req, 0, sizeof(*req)); diff --git a/src/core/lib/http/httpcli_security_connector.cc b/src/core/lib/http/httpcli_security_connector.cc index 1c798d368b0..762cbe41bcf 100644 --- a/src/core/lib/http/httpcli_security_connector.cc +++ b/src/core/lib/http/httpcli_security_connector.cc @@ -29,119 +29,123 @@ #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/handshaker_registry.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/pollset.h" +#include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/security/security_connector/ssl_utils.h" #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" -typedef struct { - grpc_channel_security_connector base; - tsi_ssl_client_handshaker_factory* handshaker_factory; - char* secure_peer_name; -} grpc_httpcli_ssl_channel_security_connector; +class grpc_httpcli_ssl_channel_security_connector final + : public grpc_channel_security_connector { + public: + explicit grpc_httpcli_ssl_channel_security_connector(char* secure_peer_name) + : grpc_channel_security_connector( + /*url_scheme=*/nullptr, + /*channel_creds=*/nullptr, + /*request_metadata_creds=*/nullptr), + secure_peer_name_(secure_peer_name) {} -static void httpcli_ssl_destroy(grpc_security_connector* sc) { - grpc_httpcli_ssl_channel_security_connector* c = - reinterpret_cast(sc); - if (c->handshaker_factory != nullptr) { - tsi_ssl_client_handshaker_factory_unref(c->handshaker_factory); - c->handshaker_factory = nullptr; - } - if (c->secure_peer_name != nullptr) gpr_free(c->secure_peer_name); - gpr_free(sc); -} - -static void httpcli_ssl_add_handshakers(grpc_channel_security_connector* sc, - grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr) { - grpc_httpcli_ssl_channel_security_connector* c = - reinterpret_cast(sc); - tsi_handshaker* handshaker = nullptr; - if (c->handshaker_factory != nullptr) { - tsi_result result = tsi_ssl_client_handshaker_factory_create_handshaker( - c->handshaker_factory, c->secure_peer_name, &handshaker); - if (result != TSI_OK) { - gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.", - tsi_result_to_string(result)); + ~grpc_httpcli_ssl_channel_security_connector() override { + if (handshaker_factory_ != nullptr) { + tsi_ssl_client_handshaker_factory_unref(handshaker_factory_); + } + if (secure_peer_name_ != nullptr) { + gpr_free(secure_peer_name_); } } - grpc_handshake_manager_add( - handshake_mgr, grpc_security_handshaker_create(handshaker, &sc->base)); -} -static void httpcli_ssl_check_peer(grpc_security_connector* sc, tsi_peer peer, - grpc_auth_context** auth_context, - grpc_closure* on_peer_checked) { - grpc_httpcli_ssl_channel_security_connector* c = - reinterpret_cast(sc); - grpc_error* error = GRPC_ERROR_NONE; - - /* Check the peer name. */ - if (c->secure_peer_name != nullptr && - !tsi_ssl_peer_matches_name(&peer, c->secure_peer_name)) { - char* msg; - gpr_asprintf(&msg, "Peer name %s is not in peer certificate", - c->secure_peer_name); - error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); - gpr_free(msg); + tsi_result InitHandshakerFactory(const char* pem_root_certs, + const tsi_ssl_root_certs_store* root_store) { + tsi_ssl_client_handshaker_options options; + options.pem_root_certs = pem_root_certs; + options.root_store = root_store; + return tsi_create_ssl_client_handshaker_factory_with_options( + &options, &handshaker_factory_); } - GRPC_CLOSURE_SCHED(on_peer_checked, error); - tsi_peer_destruct(&peer); -} -static int httpcli_ssl_cmp(grpc_security_connector* sc1, - grpc_security_connector* sc2) { - grpc_httpcli_ssl_channel_security_connector* c1 = - reinterpret_cast(sc1); - grpc_httpcli_ssl_channel_security_connector* c2 = - reinterpret_cast(sc2); - return strcmp(c1->secure_peer_name, c2->secure_peer_name); -} + void add_handshakers(grpc_pollset_set* interested_parties, + grpc_core::HandshakeManager* handshake_mgr) override { + tsi_handshaker* handshaker = nullptr; + if (handshaker_factory_ != nullptr) { + tsi_result result = tsi_ssl_client_handshaker_factory_create_handshaker( + handshaker_factory_, secure_peer_name_, &handshaker); + if (result != TSI_OK) { + gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.", + tsi_result_to_string(result)); + } + } + handshake_mgr->Add(grpc_core::SecurityHandshakerCreate(handshaker, this)); + } -static grpc_security_connector_vtable httpcli_ssl_vtable = { - httpcli_ssl_destroy, httpcli_ssl_check_peer, httpcli_ssl_cmp}; + tsi_ssl_client_handshaker_factory* handshaker_factory() const { + return handshaker_factory_; + } -static grpc_security_status httpcli_ssl_channel_security_connector_create( + void check_peer(tsi_peer peer, grpc_endpoint* ep, + grpc_core::RefCountedPtr* /*auth_context*/, + grpc_closure* on_peer_checked) override { + grpc_error* error = GRPC_ERROR_NONE; + + /* Check the peer name. */ + if (secure_peer_name_ != nullptr && + !tsi_ssl_peer_matches_name(&peer, secure_peer_name_)) { + char* msg; + gpr_asprintf(&msg, "Peer name %s is not in peer certificate", + secure_peer_name_); + error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); + gpr_free(msg); + } + GRPC_CLOSURE_SCHED(on_peer_checked, error); + tsi_peer_destruct(&peer); + } + + int cmp(const grpc_security_connector* other_sc) const override { + auto* other = + reinterpret_cast( + other_sc); + return strcmp(secure_peer_name_, other->secure_peer_name_); + } + + bool check_call_host(const char* host, grpc_auth_context* auth_context, + grpc_closure* on_call_host_checked, + grpc_error** error) override { + *error = GRPC_ERROR_NONE; + return true; + } + + void cancel_check_call_host(grpc_closure* on_call_host_checked, + grpc_error* error) override { + GRPC_ERROR_UNREF(error); + } + + const char* secure_peer_name() const { return secure_peer_name_; } + + private: + tsi_ssl_client_handshaker_factory* handshaker_factory_ = nullptr; + char* secure_peer_name_; +}; + +static grpc_core::RefCountedPtr +httpcli_ssl_channel_security_connector_create( const char* pem_root_certs, const tsi_ssl_root_certs_store* root_store, - const char* secure_peer_name, grpc_channel_security_connector** sc) { - tsi_result result = TSI_OK; - grpc_httpcli_ssl_channel_security_connector* c; - + const char* secure_peer_name) { if (secure_peer_name != nullptr && pem_root_certs == nullptr) { gpr_log(GPR_ERROR, "Cannot assert a secure peer name without a trust root."); - return GRPC_SECURITY_ERROR; + return nullptr; } - - c = static_cast( - gpr_zalloc(sizeof(grpc_httpcli_ssl_channel_security_connector))); - - gpr_ref_init(&c->base.base.refcount, 1); - c->base.base.vtable = &httpcli_ssl_vtable; - if (secure_peer_name != nullptr) { - c->secure_peer_name = gpr_strdup(secure_peer_name); - } - tsi_ssl_client_handshaker_options options; - memset(&options, 0, sizeof(options)); - options.pem_root_certs = pem_root_certs; - options.root_store = root_store; - result = tsi_create_ssl_client_handshaker_factory_with_options( - &options, &c->handshaker_factory); + grpc_core::RefCountedPtr c = + grpc_core::MakeRefCounted( + secure_peer_name == nullptr ? nullptr : gpr_strdup(secure_peer_name)); + tsi_result result = c->InitHandshakerFactory(pem_root_certs, root_store); if (result != TSI_OK) { gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.", tsi_result_to_string(result)); - httpcli_ssl_destroy(&c->base.base); - *sc = nullptr; - return GRPC_SECURITY_ERROR; + return nullptr; } - // We don't actually need a channel credentials object in this case, - // but we set it to a non-nullptr address so that we don't trigger - // assertions in grpc_channel_security_connector_cmp(). - c->base.channel_creds = (grpc_channel_credentials*)1; - c->base.add_handshakers = httpcli_ssl_add_handshakers; - *sc = &c->base; - return GRPC_SECURITY_OK; + return c; } /* handshaker */ @@ -149,11 +153,11 @@ static grpc_security_status httpcli_ssl_channel_security_connector_create( typedef struct { void (*func)(void* arg, grpc_endpoint* endpoint); void* arg; - grpc_handshake_manager* handshake_mgr; + grpc_core::RefCountedPtr handshake_mgr; } on_done_closure; static void on_handshake_done(void* arg, grpc_error* error) { - grpc_handshaker_args* args = static_cast(arg); + auto* args = static_cast(arg); on_done_closure* c = static_cast(args->user_data); if (error != GRPC_ERROR_NONE) { const char* msg = grpc_error_string(error); @@ -166,14 +170,13 @@ static void on_handshake_done(void* arg, grpc_error* error) { gpr_free(args->read_buffer); c->func(c->arg, args->endpoint); } - grpc_handshake_manager_destroy(c->handshake_mgr); - gpr_free(c); + grpc_core::Delete(c); } static void ssl_handshake(void* arg, grpc_endpoint* tcp, const char* host, grpc_millis deadline, void (*on_done)(void* arg, grpc_endpoint* endpoint)) { - on_done_closure* c = static_cast(gpr_malloc(sizeof(*c))); + auto* c = grpc_core::New(); const char* pem_root_certs = grpc_core::DefaultSslRootStore::GetPemRootCerts(); const tsi_ssl_root_certs_store* root_store = @@ -186,18 +189,20 @@ static void ssl_handshake(void* arg, grpc_endpoint* tcp, const char* host, } c->func = on_done; c->arg = arg; - grpc_channel_security_connector* sc = nullptr; - GPR_ASSERT(httpcli_ssl_channel_security_connector_create( - pem_root_certs, root_store, host, &sc) == GRPC_SECURITY_OK); - grpc_arg channel_arg = grpc_security_connector_to_arg(&sc->base); + grpc_core::RefCountedPtr sc = + httpcli_ssl_channel_security_connector_create(pem_root_certs, root_store, + host); + GPR_ASSERT(sc != nullptr); + grpc_arg channel_arg = grpc_security_connector_to_arg(sc.get()); grpc_channel_args args = {1, &channel_arg}; - c->handshake_mgr = grpc_handshake_manager_create(); - grpc_handshakers_add(HANDSHAKER_CLIENT, &args, - nullptr /* interested_parties */, c->handshake_mgr); - grpc_handshake_manager_do_handshake( - c->handshake_mgr, tcp, nullptr /* channel_args */, deadline, - nullptr /* acceptor */, on_handshake_done, c /* user_data */); - GRPC_SECURITY_CONNECTOR_UNREF(&sc->base, "httpcli"); + c->handshake_mgr = grpc_core::MakeRefCounted(); + grpc_core::HandshakerRegistry::AddHandshakers( + grpc_core::HANDSHAKER_CLIENT, &args, /*interested_parties=*/nullptr, + c->handshake_mgr.get()); + c->handshake_mgr->DoHandshake(tcp, /*channel_args=*/nullptr, deadline, + /*acceptor=*/nullptr, on_handshake_done, + /*user_data=*/c); + sc.reset(DEBUG_LOCATION, "httpcli"); } const grpc_httpcli_handshaker grpc_httpcli_ssl = {"https", ssl_handshake}; diff --git a/src/core/lib/http/parser.cc b/src/core/lib/http/parser.cc index a37fdda8ea7..58608da982c 100644 --- a/src/core/lib/http/parser.cc +++ b/src/core/lib/http/parser.cc @@ -300,7 +300,7 @@ static grpc_error* addbyte(grpc_http_parser* parser, uint8_t byte, case GRPC_HTTP_FIRST_LINE: case GRPC_HTTP_HEADERS: if (parser->cur_line_length >= GRPC_HTTP_PARSER_MAX_HEADER_LENGTH) { - if (grpc_http1_trace.enabled()) + if (GRPC_TRACE_FLAG_ENABLED(grpc_http1_trace)) gpr_log(GPR_ERROR, "HTTP header max line length (%d) exceeded", GRPC_HTTP_PARSER_MAX_HEADER_LENGTH); return GRPC_ERROR_CREATE_FROM_STATIC_STRING( @@ -351,7 +351,8 @@ void grpc_http_response_destroy(grpc_http_response* response) { gpr_free(response->hdrs); } -grpc_error* grpc_http_parser_parse(grpc_http_parser* parser, grpc_slice slice, +grpc_error* grpc_http_parser_parse(grpc_http_parser* parser, + const grpc_slice& slice, size_t* start_of_body) { for (size_t i = 0; i < GRPC_SLICE_LENGTH(slice); i++) { bool found_body_start = false; diff --git a/src/core/lib/http/parser.h b/src/core/lib/http/parser.h index 1d2e13e8317..b51fd5af09f 100644 --- a/src/core/lib/http/parser.h +++ b/src/core/lib/http/parser.h @@ -70,13 +70,13 @@ typedef struct grpc_http_request { /* A response */ typedef struct grpc_http_response { /* HTTP status code */ - int status; + int status = 0; /* Headers: count and key/values */ - size_t hdr_count; - grpc_http_header* hdrs; + size_t hdr_count = 0; + grpc_http_header* hdrs = nullptr; /* Body: length and contents; contents are NOT null-terminated */ - size_t body_length; - char* body; + size_t body_length = 0; + char* body = nullptr; } grpc_http_response; typedef struct { @@ -101,7 +101,8 @@ void grpc_http_parser_init(grpc_http_parser* parser, grpc_http_type type, void grpc_http_parser_destroy(grpc_http_parser* parser); /* Sets \a start_of_body to the offset in \a slice of the start of the body. */ -grpc_error* grpc_http_parser_parse(grpc_http_parser* parser, grpc_slice slice, +grpc_error* grpc_http_parser_parse(grpc_http_parser* parser, + const grpc_slice& slice, size_t* start_of_body); grpc_error* grpc_http_parser_eof(grpc_http_parser* parser); diff --git a/src/core/lib/iomgr/buffer_list.cc b/src/core/lib/iomgr/buffer_list.cc index 6ada23db1c2..73915933eee 100644 --- a/src/core/lib/iomgr/buffer_list.cc +++ b/src/core/lib/iomgr/buffer_list.cc @@ -24,17 +24,190 @@ #include #ifdef GRPC_LINUX_ERRQUEUE +#include +#include #include #include "src/core/lib/gprpp/memory.h" namespace grpc_core { -void TracedBuffer::AddNewEntry(TracedBuffer** head, uint32_t seq_no, +namespace { +/** Fills gpr_timespec gts based on values from timespec ts */ +void fill_gpr_from_timestamp(gpr_timespec* gts, const struct timespec* ts) { + gts->tv_sec = ts->tv_sec; + gts->tv_nsec = static_cast(ts->tv_nsec); + gts->clock_type = GPR_CLOCK_REALTIME; +} + +void default_timestamps_callback(void* arg, grpc_core::Timestamps* ts, + grpc_error* shudown_err) { + gpr_log(GPR_DEBUG, "Timestamps callback has not been registered"); +} + +/** The saved callback function that will be invoked when we get all the + * timestamps that we are going to get for a TracedBuffer. */ +void (*timestamps_callback)(void*, grpc_core::Timestamps*, + grpc_error* shutdown_err) = + default_timestamps_callback; + +/* Used to extract individual opt stats from cmsg, so as to avoid troubles with + * unaligned reads */ +template +T read_unaligned(const void* ptr) { + T val; + memcpy(&val, ptr, sizeof(val)); + return val; +} + +/* Extracts opt stats from the tcp_info struct \a info to \a metrics */ +void extract_opt_stats_from_tcp_info(ConnectionMetrics* metrics, + const grpc_core::tcp_info* info) { + if (info == nullptr) { + return; + } + if (info->length > offsetof(grpc_core::tcp_info, tcpi_sndbuf_limited)) { + metrics->recurring_retrans.set(info->tcpi_retransmits); + metrics->is_delivery_rate_app_limited.set( + info->tcpi_delivery_rate_app_limited); + metrics->congestion_window.set(info->tcpi_snd_cwnd); + metrics->reordering.set(info->tcpi_reordering); + metrics->packet_retx.set(info->tcpi_total_retrans); + metrics->pacing_rate.set(info->tcpi_pacing_rate); + metrics->data_notsent.set(info->tcpi_notsent_bytes); + if (info->tcpi_min_rtt != UINT32_MAX) { + metrics->min_rtt.set(info->tcpi_min_rtt); + } + metrics->packet_sent.set(info->tcpi_data_segs_out); + metrics->delivery_rate.set(info->tcpi_delivery_rate); + metrics->busy_usec.set(info->tcpi_busy_time); + metrics->rwnd_limited_usec.set(info->tcpi_rwnd_limited); + metrics->sndbuf_limited_usec.set(info->tcpi_sndbuf_limited); + } + if (info->length > offsetof(grpc_core::tcp_info, tcpi_dsack_dups)) { + metrics->data_sent.set(info->tcpi_bytes_sent); + metrics->data_retx.set(info->tcpi_bytes_retrans); + metrics->packet_spurious_retx.set(info->tcpi_dsack_dups); + } +} + +/** Extracts opt stats from the given control message \a opt_stats to the + * connection metrics \a metrics */ +void extract_opt_stats_from_cmsg(ConnectionMetrics* metrics, + const cmsghdr* opt_stats) { + if (opt_stats == nullptr) { + return; + } + const auto* data = CMSG_DATA(opt_stats); + constexpr int64_t cmsg_hdr_len = CMSG_ALIGN(sizeof(struct cmsghdr)); + const int64_t len = opt_stats->cmsg_len - cmsg_hdr_len; + int64_t offset = 0; + + while (offset < len) { + const auto* attr = reinterpret_cast(data + offset); + const void* val = data + offset + NLA_HDRLEN; + switch (attr->nla_type) { + case TCP_NLA_BUSY: { + metrics->busy_usec.set(read_unaligned(val)); + break; + } + case TCP_NLA_RWND_LIMITED: { + metrics->rwnd_limited_usec.set(read_unaligned(val)); + break; + } + case TCP_NLA_SNDBUF_LIMITED: { + metrics->sndbuf_limited_usec.set(read_unaligned(val)); + break; + } + case TCP_NLA_PACING_RATE: { + metrics->pacing_rate.set(read_unaligned(val)); + break; + } + case TCP_NLA_DELIVERY_RATE: { + metrics->delivery_rate.set(read_unaligned(val)); + break; + } + case TCP_NLA_DELIVERY_RATE_APP_LMT: { + metrics->is_delivery_rate_app_limited.set(read_unaligned(val)); + break; + } + case TCP_NLA_SND_CWND: { + metrics->congestion_window.set(read_unaligned(val)); + break; + } + case TCP_NLA_MIN_RTT: { + metrics->min_rtt.set(read_unaligned(val)); + break; + } + case TCP_NLA_SRTT: { + metrics->srtt.set(read_unaligned(val)); + break; + } + case TCP_NLA_RECUR_RETRANS: { + metrics->recurring_retrans.set(read_unaligned(val)); + break; + } + case TCP_NLA_BYTES_SENT: { + metrics->data_sent.set(read_unaligned(val)); + break; + } + case TCP_NLA_DATA_SEGS_OUT: { + metrics->packet_sent.set(read_unaligned(val)); + break; + } + case TCP_NLA_TOTAL_RETRANS: { + metrics->packet_retx.set(read_unaligned(val)); + break; + } + case TCP_NLA_DELIVERED: { + metrics->packet_delivered.set(read_unaligned(val)); + break; + } + case TCP_NLA_DELIVERED_CE: { + metrics->packet_delivered_ce.set(read_unaligned(val)); + break; + } + case TCP_NLA_BYTES_RETRANS: { + metrics->data_retx.set(read_unaligned(val)); + break; + } + case TCP_NLA_DSACK_DUPS: { + metrics->packet_spurious_retx.set(read_unaligned(val)); + break; + } + case TCP_NLA_REORDERING: { + metrics->reordering.set(read_unaligned(val)); + break; + } + case TCP_NLA_SND_SSTHRESH: { + metrics->snd_ssthresh.set(read_unaligned(val)); + break; + } + } + offset += NLA_ALIGN(attr->nla_len); + } +} + +static int get_socket_tcp_info(grpc_core::tcp_info* info, int fd) { + memset(info, 0, sizeof(*info)); + info->length = sizeof(*info) - sizeof(socklen_t); + return getsockopt(fd, IPPROTO_TCP, TCP_INFO, info, &(info->length)); +} +} /* namespace */ + +void TracedBuffer::AddNewEntry(TracedBuffer** head, uint32_t seq_no, int fd, void* arg) { GPR_DEBUG_ASSERT(head != nullptr); TracedBuffer* new_elem = New(seq_no, arg); /* Store the current time as the sendmsg time. */ - new_elem->ts_.sendmsg_time = gpr_now(GPR_CLOCK_REALTIME); + new_elem->ts_.sendmsg_time.time = gpr_now(GPR_CLOCK_REALTIME); + new_elem->ts_.scheduled_time.time = gpr_inf_past(GPR_CLOCK_REALTIME); + new_elem->ts_.sent_time.time = gpr_inf_past(GPR_CLOCK_REALTIME); + new_elem->ts_.acked_time.time = gpr_inf_past(GPR_CLOCK_REALTIME); + + if (get_socket_tcp_info(&new_elem->ts_.info, fd) == 0) { + extract_opt_stats_from_tcp_info(&new_elem->ts_.sendmsg_time.metrics, + &new_elem->ts_.info); + } if (*head == nullptr) { *head = new_elem; return; @@ -47,22 +220,9 @@ void TracedBuffer::AddNewEntry(TracedBuffer** head, uint32_t seq_no, ptr->next_ = new_elem; } -namespace { -/** Fills gpr_timespec gts based on values from timespec ts */ -void fill_gpr_from_timestamp(gpr_timespec* gts, const struct timespec* ts) { - gts->tv_sec = ts->tv_sec; - gts->tv_nsec = static_cast(ts->tv_nsec); - gts->clock_type = GPR_CLOCK_REALTIME; -} - -/** The saved callback function that will be invoked when we get all the - * timestamps that we are going to get for a TracedBuffer. */ -void (*timestamps_callback)(void*, grpc_core::Timestamps*, - grpc_error* shutdown_err); -} /* namespace */ - void TracedBuffer::ProcessTimestamp(TracedBuffer** head, struct sock_extended_err* serr, + struct cmsghdr* opt_stats, struct scm_timestamping* tss) { GPR_DEBUG_ASSERT(head != nullptr); TracedBuffer* elem = *head; @@ -73,15 +233,22 @@ void TracedBuffer::ProcessTimestamp(TracedBuffer** head, if (serr->ee_data >= elem->seq_no_) { switch (serr->ee_info) { case SCM_TSTAMP_SCHED: - fill_gpr_from_timestamp(&(elem->ts_.scheduled_time), &(tss->ts[0])); + fill_gpr_from_timestamp(&(elem->ts_.scheduled_time.time), + &(tss->ts[0])); + extract_opt_stats_from_cmsg(&(elem->ts_.scheduled_time.metrics), + opt_stats); elem = elem->next_; break; case SCM_TSTAMP_SND: - fill_gpr_from_timestamp(&(elem->ts_.sent_time), &(tss->ts[0])); + fill_gpr_from_timestamp(&(elem->ts_.sent_time.time), &(tss->ts[0])); + extract_opt_stats_from_cmsg(&(elem->ts_.sent_time.metrics), + opt_stats); elem = elem->next_; break; case SCM_TSTAMP_ACK: - fill_gpr_from_timestamp(&(elem->ts_.acked_time), &(tss->ts[0])); + fill_gpr_from_timestamp(&(elem->ts_.acked_time.time), &(tss->ts[0])); + extract_opt_stats_from_cmsg(&(elem->ts_.acked_time.metrics), + opt_stats); /* Got all timestamps. Do the callback and free this TracedBuffer. * The thing below can be passed by value if we don't want the * restriction on the lifetime. */ @@ -99,18 +266,20 @@ void TracedBuffer::ProcessTimestamp(TracedBuffer** head, } } -void TracedBuffer::Shutdown(TracedBuffer** head, grpc_error* shutdown_err) { +void TracedBuffer::Shutdown(TracedBuffer** head, void* remaining, + grpc_error* shutdown_err) { GPR_DEBUG_ASSERT(head != nullptr); TracedBuffer* elem = *head; while (elem != nullptr) { - if (timestamps_callback) { - timestamps_callback(elem->arg_, &(elem->ts_), shutdown_err); - } + timestamps_callback(elem->arg_, &(elem->ts_), shutdown_err); auto* next = elem->next_; Delete(elem); elem = next; } *head = nullptr; + if (remaining != nullptr) { + timestamps_callback(remaining, nullptr, shutdown_err); + } GRPC_ERROR_UNREF(shutdown_err); } diff --git a/src/core/lib/iomgr/buffer_list.h b/src/core/lib/iomgr/buffer_list.h index cbbf50a6575..8bb271867c2 100644 --- a/src/core/lib/iomgr/buffer_list.h +++ b/src/core/lib/iomgr/buffer_list.h @@ -26,17 +26,78 @@ #include #include "src/core/lib/gprpp/memory.h" +#include "src/core/lib/gprpp/optional.h" #include "src/core/lib/iomgr/error.h" #include "src/core/lib/iomgr/internal_errqueue.h" namespace grpc_core { + +struct ConnectionMetrics { + /* Delivery rate in Bytes/s. */ + Optional delivery_rate; + /* If the delivery rate is limited by the application, this is set to true. */ + Optional is_delivery_rate_app_limited; + /* Total packets retransmitted. */ + Optional packet_retx; + /* Total packets retransmitted spuriously. This metric is smaller than or + equal to packet_retx. */ + Optional packet_spurious_retx; + /* Total packets sent. */ + Optional packet_sent; + /* Total packets delivered. */ + Optional packet_delivered; + /* Total packets delivered with ECE marked. This metric is smaller than or + equal to packet_delivered. */ + Optional packet_delivered_ce; + /* Total bytes lost so far. */ + Optional data_retx; + /* Total bytes sent so far. */ + Optional data_sent; + /* Total bytes in write queue but not sent. */ + Optional data_notsent; + /* Pacing rate of the connection in Bps */ + Optional pacing_rate; + /* Minimum RTT observed in usec. */ + Optional min_rtt; + /* Smoothed RTT in usec */ + Optional srtt; + /* Send congestion window. */ + Optional congestion_window; + /* Slow start threshold in packets. */ + Optional snd_ssthresh; + /* Maximum degree of reordering (i.e., maximum number of packets reodered) + on the connection. */ + Optional reordering; + /* Represents the number of recurring retransmissions of the first sequence + that is not acknowledged yet. */ + Optional recurring_retrans; + /* The cumulative time (in usec) that the transport protocol was busy + sending data. */ + Optional busy_usec; + /* The cumulative time (in usec) that the transport protocol was limited by + the receive window size. */ + Optional rwnd_limited_usec; + /* The cumulative time (in usec) that the transport protocol was limited by + the send buffer size. */ + Optional sndbuf_limited_usec; +}; + +struct Timestamp { + gpr_timespec time; + ConnectionMetrics metrics; /* Metrics collected with this timestamp */ +}; + struct Timestamps { - /* TODO(yashykt): This would also need to store OPTSTAT once support is added - */ - gpr_timespec sendmsg_time; - gpr_timespec scheduled_time; - gpr_timespec sent_time; - gpr_timespec acked_time; + Timestamp sendmsg_time; + Timestamp scheduled_time; + Timestamp sent_time; + Timestamp acked_time; + + uint32_t byte_offset; /* byte offset relative to the start of the RPC */ + +#ifdef GRPC_LINUX_ERRQUEUE + grpc_core::tcp_info info; /* tcp_info collected on sendmsg */ +#endif /* GRPC_LINUX_ERRQUEUE */ }; /** TracedBuffer is a class to keep track of timestamps for a specific buffer in @@ -56,24 +117,25 @@ class TracedBuffer { /** Add a new entry in the TracedBuffer list pointed to by head. Also saves * sendmsg_time with the current timestamp. */ static void AddNewEntry(grpc_core::TracedBuffer** head, uint32_t seq_no, - void* arg); + int fd, void* arg); /** Processes a received timestamp based on sock_extended_err and * scm_timestamping structures. It will invoke the timestamps callback if the * timestamp type is SCM_TSTAMP_ACK. */ static void ProcessTimestamp(grpc_core::TracedBuffer** head, struct sock_extended_err* serr, + struct cmsghdr* opt_stats, struct scm_timestamping* tss); /** Cleans the list by calling the callback for each traced buffer in the list * with timestamps that it has. */ - static void Shutdown(grpc_core::TracedBuffer** head, + static void Shutdown(grpc_core::TracedBuffer** head, void* remaining, grpc_error* shutdown_err); private: GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW - TracedBuffer(int seq_no, void* arg) + TracedBuffer(uint32_t seq_no, void* arg) : seq_no_(seq_no), arg_(arg), next_(nullptr) {} uint32_t seq_no_; /* The sequence number for the last byte in the buffer */ @@ -82,7 +144,14 @@ class TracedBuffer { grpc_core::TracedBuffer* next_; /* The next TracedBuffer in the list */ }; #else /* GRPC_LINUX_ERRQUEUE */ -class TracedBuffer {}; +class TracedBuffer { + public: + /* Dummy shutdown function */ + static void Shutdown(grpc_core::TracedBuffer** head, void* remaining, + grpc_error* shutdown_err) { + GRPC_ERROR_UNREF(shutdown_err); + } +}; #endif /* GRPC_LINUX_ERRQUEUE */ /** Sets the callback function to call when timestamps for a write are @@ -91,6 +160,6 @@ void grpc_tcp_set_write_timestamps_callback(void (*fn)(void*, grpc_core::Timestamps*, grpc_error* error)); -}; /* namespace grpc_core */ +} /* namespace grpc_core */ #endif /* GRPC_CORE_LIB_IOMGR_BUFFER_LIST_H */ diff --git a/src/core/lib/iomgr/call_combiner.cc b/src/core/lib/iomgr/call_combiner.cc index 90dda45ba37..6a4e85de4df 100644 --- a/src/core/lib/iomgr/call_combiner.cc +++ b/src/core/lib/iomgr/call_combiner.cc @@ -26,32 +26,82 @@ #include "src/core/lib/debug/stats.h" #include "src/core/lib/profiling/timers.h" -grpc_core::TraceFlag grpc_call_combiner_trace(false, "call_combiner"); +namespace grpc_core { -static grpc_error* decode_cancel_state_error(gpr_atm cancel_state) { +TraceFlag grpc_call_combiner_trace(false, "call_combiner"); + +namespace { + +grpc_error* DecodeCancelStateError(gpr_atm cancel_state) { if (cancel_state & 1) { return (grpc_error*)(cancel_state & ~static_cast(1)); } return GRPC_ERROR_NONE; } -static gpr_atm encode_cancel_state_error(grpc_error* error) { +gpr_atm EncodeCancelStateError(grpc_error* error) { return static_cast(1) | (gpr_atm)error; } -void grpc_call_combiner_init(grpc_call_combiner* call_combiner) { - gpr_atm_no_barrier_store(&call_combiner->cancel_state, 0); - gpr_atm_no_barrier_store(&call_combiner->size, 0); - gpr_mpscq_init(&call_combiner->queue); +} // namespace + +CallCombiner::CallCombiner() { + gpr_atm_no_barrier_store(&cancel_state_, 0); + gpr_atm_no_barrier_store(&size_, 0); + gpr_mpscq_init(&queue_); +#ifdef GRPC_TSAN_ENABLED + GRPC_CLOSURE_INIT(&tsan_closure_, TsanClosure, this, + grpc_schedule_on_exec_ctx); +#endif } -void grpc_call_combiner_destroy(grpc_call_combiner* call_combiner) { - gpr_mpscq_destroy(&call_combiner->queue); - GRPC_ERROR_UNREF(decode_cancel_state_error(call_combiner->cancel_state)); +CallCombiner::~CallCombiner() { + gpr_mpscq_destroy(&queue_); + GRPC_ERROR_UNREF(DecodeCancelStateError(cancel_state_)); +} + +#ifdef GRPC_TSAN_ENABLED +void CallCombiner::TsanClosure(void* arg, grpc_error* error) { + CallCombiner* self = static_cast(arg); + // We ref-count the lock, and check if it's already taken. + // If it was taken, we should do nothing. Otherwise, we will mark it as + // locked. Note that if two different threads try to do this, only one of + // them will be able to mark the lock as acquired, while they both run their + // callbacks. In such cases (which should never happen for call_combiner), + // TSAN will correctly produce an error. + // + // TODO(soheil): This only covers the callbacks scheduled by + // CallCombiner::Start() and CallCombiner::Stop(). + // If in the future, a callback gets scheduled using other + // mechanisms, we will need to add APIs to externally lock + // call combiners. + RefCountedPtr lock = self->tsan_lock_; + bool prev = false; + if (lock->taken.compare_exchange_strong(prev, true)) { + TSAN_ANNOTATE_RWLOCK_ACQUIRED(&lock->taken, true); + } else { + lock.reset(); + } + GRPC_CLOSURE_RUN(self->original_closure_, GRPC_ERROR_REF(error)); + if (lock != nullptr) { + TSAN_ANNOTATE_RWLOCK_RELEASED(&lock->taken, true); + bool prev = true; + GPR_ASSERT(lock->taken.compare_exchange_strong(prev, false)); + } +} +#endif + +void CallCombiner::ScheduleClosure(grpc_closure* closure, grpc_error* error) { +#ifdef GRPC_TSAN_ENABLED + original_closure_ = closure; + GRPC_CLOSURE_SCHED(&tsan_closure_, error); +#else + GRPC_CLOSURE_SCHED(closure, error); +#endif } #ifndef NDEBUG -#define DEBUG_ARGS , const char *file, int line +#define DEBUG_ARGS const char *file, int line, #define DEBUG_FMT_STR "%s:%d: " #define DEBUG_FMT_ARGS , file, line #else @@ -60,122 +110,113 @@ void grpc_call_combiner_destroy(grpc_call_combiner* call_combiner) { #define DEBUG_FMT_ARGS #endif -void grpc_call_combiner_start(grpc_call_combiner* call_combiner, - grpc_closure* closure, - grpc_error* error DEBUG_ARGS, - const char* reason) { - GPR_TIMER_SCOPE("call_combiner_start", 0); - if (grpc_call_combiner_trace.enabled()) { +void CallCombiner::Start(grpc_closure* closure, grpc_error* error, + DEBUG_ARGS const char* reason) { + GPR_TIMER_SCOPE("CallCombiner::Start", 0); + if (GRPC_TRACE_FLAG_ENABLED(grpc_call_combiner_trace)) { gpr_log(GPR_INFO, - "==> grpc_call_combiner_start() [%p] closure=%p [" DEBUG_FMT_STR + "==> CallCombiner::Start() [%p] closure=%p [" DEBUG_FMT_STR "%s] error=%s", - call_combiner, closure DEBUG_FMT_ARGS, reason, - grpc_error_string(error)); + this, closure DEBUG_FMT_ARGS, reason, grpc_error_string(error)); } - size_t prev_size = static_cast( - gpr_atm_full_fetch_add(&call_combiner->size, (gpr_atm)1)); - if (grpc_call_combiner_trace.enabled()) { + size_t prev_size = + static_cast(gpr_atm_full_fetch_add(&size_, (gpr_atm)1)); + if (GRPC_TRACE_FLAG_ENABLED(grpc_call_combiner_trace)) { gpr_log(GPR_INFO, " size: %" PRIdPTR " -> %" PRIdPTR, prev_size, prev_size + 1); } GRPC_STATS_INC_CALL_COMBINER_LOCKS_SCHEDULED_ITEMS(); if (prev_size == 0) { GRPC_STATS_INC_CALL_COMBINER_LOCKS_INITIATED(); - GPR_TIMER_MARK("call_combiner_initiate", 0); - if (grpc_call_combiner_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_call_combiner_trace)) { gpr_log(GPR_INFO, " EXECUTING IMMEDIATELY"); } // Queue was empty, so execute this closure immediately. - GRPC_CLOSURE_SCHED(closure, error); + ScheduleClosure(closure, error); } else { - if (grpc_call_combiner_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_call_combiner_trace)) { gpr_log(GPR_INFO, " QUEUING"); } // Queue was not empty, so add closure to queue. closure->error_data.error = error; - gpr_mpscq_push(&call_combiner->queue, - reinterpret_cast(closure)); + gpr_mpscq_push(&queue_, reinterpret_cast(closure)); } } -void grpc_call_combiner_stop(grpc_call_combiner* call_combiner DEBUG_ARGS, - const char* reason) { - GPR_TIMER_SCOPE("call_combiner_stop", 0); - if (grpc_call_combiner_trace.enabled()) { - gpr_log(GPR_INFO, - "==> grpc_call_combiner_stop() [%p] [" DEBUG_FMT_STR "%s]", - call_combiner DEBUG_FMT_ARGS, reason); +void CallCombiner::Stop(DEBUG_ARGS const char* reason) { + GPR_TIMER_SCOPE("CallCombiner::Stop", 0); + if (GRPC_TRACE_FLAG_ENABLED(grpc_call_combiner_trace)) { + gpr_log(GPR_INFO, "==> CallCombiner::Stop() [%p] [" DEBUG_FMT_STR "%s]", + this DEBUG_FMT_ARGS, reason); } - size_t prev_size = static_cast( - gpr_atm_full_fetch_add(&call_combiner->size, (gpr_atm)-1)); - if (grpc_call_combiner_trace.enabled()) { + size_t prev_size = + static_cast(gpr_atm_full_fetch_add(&size_, (gpr_atm)-1)); + if (GRPC_TRACE_FLAG_ENABLED(grpc_call_combiner_trace)) { 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()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_call_combiner_trace)) { gpr_log(GPR_INFO, " checking queue"); } bool empty; grpc_closure* closure = reinterpret_cast( - gpr_mpscq_pop_and_check_end(&call_combiner->queue, &empty)); + gpr_mpscq_pop_and_check_end(&queue_, &empty)); if (closure == nullptr) { // 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()) { + // code or because of a race with Start(). + if (GRPC_TRACE_FLAG_ENABLED(grpc_call_combiner_trace)) { gpr_log(GPR_INFO, " queue returned no result; checking again"); } continue; } - if (grpc_call_combiner_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_call_combiner_trace)) { 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); + ScheduleClosure(closure, closure->error_data.error); break; } - } else if (grpc_call_combiner_trace.enabled()) { + } else if (GRPC_TRACE_FLAG_ENABLED(grpc_call_combiner_trace)) { gpr_log(GPR_INFO, " queue empty"); } } -void grpc_call_combiner_set_notify_on_cancel(grpc_call_combiner* call_combiner, - grpc_closure* closure) { +void CallCombiner::SetNotifyOnCancel(grpc_closure* closure) { GRPC_STATS_INC_CALL_COMBINER_SET_NOTIFY_ON_CANCEL(); while (true) { // Decode original state. - gpr_atm original_state = gpr_atm_acq_load(&call_combiner->cancel_state); - grpc_error* original_error = decode_cancel_state_error(original_state); + gpr_atm original_state = gpr_atm_acq_load(&cancel_state_); + grpc_error* original_error = DecodeCancelStateError(original_state); // If error is set, invoke the cancellation closure immediately. // Otherwise, store the new closure. if (original_error != GRPC_ERROR_NONE) { - if (grpc_call_combiner_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_call_combiner_trace)) { gpr_log(GPR_INFO, "call_combiner=%p: scheduling notify_on_cancel callback=%p " "for pre-existing cancellation", - call_combiner, closure); + this, closure); } GRPC_CLOSURE_SCHED(closure, GRPC_ERROR_REF(original_error)); break; } else { - if (gpr_atm_full_cas(&call_combiner->cancel_state, original_state, - (gpr_atm)closure)) { - if (grpc_call_combiner_trace.enabled()) { + if (gpr_atm_full_cas(&cancel_state_, original_state, (gpr_atm)closure)) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_call_combiner_trace)) { gpr_log(GPR_INFO, "call_combiner=%p: setting notify_on_cancel=%p", - call_combiner, closure); + this, closure); } // If we replaced an earlier closure, invoke the original // closure with GRPC_ERROR_NONE. This allows callers to clean // up any resources they may be holding for the callback. if (original_state != 0) { closure = (grpc_closure*)original_state; - if (grpc_call_combiner_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_call_combiner_trace)) { gpr_log(GPR_INFO, - "call_combiner=%p: scheduling old cancel callback=%p", - call_combiner, closure); + "call_combiner=%p: scheduling old cancel callback=%p", this, + closure); } GRPC_CLOSURE_SCHED(closure, GRPC_ERROR_NONE); } @@ -186,24 +227,23 @@ void grpc_call_combiner_set_notify_on_cancel(grpc_call_combiner* call_combiner, } } -void grpc_call_combiner_cancel(grpc_call_combiner* call_combiner, - grpc_error* error) { +void CallCombiner::Cancel(grpc_error* error) { GRPC_STATS_INC_CALL_COMBINER_CANCELLED(); while (true) { - gpr_atm original_state = gpr_atm_acq_load(&call_combiner->cancel_state); - grpc_error* original_error = decode_cancel_state_error(original_state); + gpr_atm original_state = gpr_atm_acq_load(&cancel_state_); + grpc_error* original_error = DecodeCancelStateError(original_state); if (original_error != GRPC_ERROR_NONE) { GRPC_ERROR_UNREF(error); break; } - if (gpr_atm_full_cas(&call_combiner->cancel_state, original_state, - encode_cancel_state_error(error))) { + if (gpr_atm_full_cas(&cancel_state_, original_state, + EncodeCancelStateError(error))) { if (original_state != 0) { grpc_closure* notify_on_cancel = (grpc_closure*)original_state; - if (grpc_call_combiner_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_call_combiner_trace)) { gpr_log(GPR_INFO, "call_combiner=%p: scheduling notify_on_cancel callback=%p", - call_combiner, notify_on_cancel); + this, notify_on_cancel); } GRPC_CLOSURE_SCHED(notify_on_cancel, GRPC_ERROR_REF(error)); } @@ -212,3 +252,5 @@ void grpc_call_combiner_cancel(grpc_call_combiner* call_combiner, // cas failed, try again. } } + +} // namespace grpc_core diff --git a/src/core/lib/iomgr/call_combiner.h b/src/core/lib/iomgr/call_combiner.h index c943fb15570..a10b437c15a 100644 --- a/src/core/lib/iomgr/call_combiner.h +++ b/src/core/lib/iomgr/call_combiner.h @@ -27,7 +27,10 @@ #include "src/core/lib/gpr/mpscq.h" #include "src/core/lib/gprpp/inlined_vector.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/dynamic_annotations.h" // A simple, lock-free mechanism for serializing activity related to a // single call. This is similar to a combiner but is more lightweight. @@ -38,82 +41,99 @@ // when it is done with the action that was kicked off by the original // callback. -extern grpc_core::TraceFlag grpc_call_combiner_trace; +namespace grpc_core { -typedef struct { - gpr_atm size = 0; // size_t, num closures in queue or currently executing - gpr_mpscq queue; +extern TraceFlag grpc_call_combiner_trace; + +class CallCombiner { + public: + CallCombiner(); + ~CallCombiner(); + +#ifndef NDEBUG +#define GRPC_CALL_COMBINER_START(call_combiner, closure, error, reason) \ + (call_combiner)->Start((closure), (error), __FILE__, __LINE__, (reason)) +#define GRPC_CALL_COMBINER_STOP(call_combiner, reason) \ + (call_combiner)->Stop(__FILE__, __LINE__, (reason)) + /// Starts processing \a closure. + void Start(grpc_closure* closure, grpc_error* error, const char* file, + int line, const char* reason); + /// Yields the call combiner to the next closure in the queue, if any. + void Stop(const char* file, int line, const char* reason); +#else +#define GRPC_CALL_COMBINER_START(call_combiner, closure, error, reason) \ + (call_combiner)->Start((closure), (error), (reason)) +#define GRPC_CALL_COMBINER_STOP(call_combiner, reason) \ + (call_combiner)->Stop((reason)) + /// Starts processing \a closure. + void Start(grpc_closure* closure, grpc_error* error, const char* reason); + /// Yields the call combiner to the next closure in the queue, if any. + void Stop(const char* reason); +#endif + + /// Registers \a closure to be invoked when Cancel() is called. + /// + /// Once a closure is registered, it will always be scheduled exactly + /// once; this allows the closure to hold references that will be freed + /// regardless of whether or not the call was cancelled. If a cancellation + /// does occur, the closure will be scheduled with the cancellation error; + /// otherwise, it will be scheduled with GRPC_ERROR_NONE. + /// + /// The closure will be scheduled in the following cases: + /// - If Cancel() was called prior to registering the closure, it will be + /// scheduled immediately with the cancelation error. + /// - If Cancel() is called after registering the closure, the closure will + /// be scheduled with the cancellation error. + /// - If SetNotifyOnCancel() is called again to register a new cancellation + /// closure, the previous cancellation closure will be scheduled with + /// GRPC_ERROR_NONE. + /// + /// If \a closure is NULL, then no closure will be invoked on + /// cancellation; this effectively unregisters the previously set closure. + /// However, most filters will not need to explicitly unregister their + /// callbacks, as this is done automatically when the call is destroyed. + /// Filters that schedule the cancellation closure on ExecCtx do not need + /// to take a ref on the call stack to guarantee closure liveness. This is + /// done by explicitly flushing ExecCtx after the unregistration during + /// call destruction. + void SetNotifyOnCancel(grpc_closure* closure); + + /// Indicates that the call has been cancelled. + void Cancel(grpc_error* error); + + private: + void ScheduleClosure(grpc_closure* closure, grpc_error* error); +#ifdef GRPC_TSAN_ENABLED + static void TsanClosure(void* arg, grpc_error* error); +#endif + + gpr_atm size_ = 0; // size_t, num closures in queue or currently executing + gpr_mpscq queue_; // Either 0 (if not cancelled and no cancellation closure set), // a grpc_closure* (if the lowest bit is 0), // or a grpc_error* (if the lowest bit is 1). - gpr_atm cancel_state = 0; -} grpc_call_combiner; - -// Assumes memory was initialized to zero. -void grpc_call_combiner_init(grpc_call_combiner* call_combiner); - -void grpc_call_combiner_destroy(grpc_call_combiner* call_combiner); - -#ifndef NDEBUG -#define GRPC_CALL_COMBINER_START(call_combiner, closure, error, reason) \ - grpc_call_combiner_start((call_combiner), (closure), (error), __FILE__, \ - __LINE__, (reason)) -#define GRPC_CALL_COMBINER_STOP(call_combiner, reason) \ - grpc_call_combiner_stop((call_combiner), __FILE__, __LINE__, (reason)) -/// Starts processing \a closure on \a call_combiner. -void grpc_call_combiner_start(grpc_call_combiner* call_combiner, - grpc_closure* closure, grpc_error* error, - const char* file, int line, const char* reason); -/// Yields the call combiner to the next closure in the queue, if any. -void grpc_call_combiner_stop(grpc_call_combiner* call_combiner, - const char* file, int line, const char* reason); -#else -#define GRPC_CALL_COMBINER_START(call_combiner, closure, error, reason) \ - grpc_call_combiner_start((call_combiner), (closure), (error), (reason)) -#define GRPC_CALL_COMBINER_STOP(call_combiner, reason) \ - grpc_call_combiner_stop((call_combiner), (reason)) -/// Starts processing \a closure on \a call_combiner. -void grpc_call_combiner_start(grpc_call_combiner* call_combiner, - grpc_closure* closure, grpc_error* error, - const char* reason); -/// Yields the call combiner to the next closure in the queue, if any. -void grpc_call_combiner_stop(grpc_call_combiner* call_combiner, - const char* reason); + gpr_atm cancel_state_ = 0; +#ifdef GRPC_TSAN_ENABLED + // A fake ref-counted lock that is kept alive after the destruction of + // grpc_call_combiner, when we are running the original closure. + // + // Ideally we want to lock and unlock the call combiner as a pointer, when the + // callback is called. However, original_closure is free to trigger + // anything on the call combiner (including destruction of grpc_call). + // Thus, we need a ref-counted structure that can outlive the call combiner. + struct TsanLock : public RefCounted { + TsanLock() { TSAN_ANNOTATE_RWLOCK_CREATE(&taken); } + ~TsanLock() { TSAN_ANNOTATE_RWLOCK_DESTROY(&taken); } + // To avoid double-locking by the same thread, we should acquire/release + // the lock only when taken is false. On each acquire taken must be set to + // true. + std::atomic taken{false}; + }; + RefCountedPtr tsan_lock_ = MakeRefCounted(); + grpc_closure tsan_closure_; + grpc_closure* original_closure_; #endif - -/// Registers \a closure to be invoked by \a call_combiner when -/// grpc_call_combiner_cancel() is called. -/// -/// Once a closure is registered, it will always be scheduled exactly -/// once; this allows the closure to hold references that will be freed -/// regardless of whether or not the call was cancelled. If a cancellation -/// does occur, the closure will be scheduled with the cancellation error; -/// otherwise, it will be scheduled with GRPC_ERROR_NONE. -/// -/// The closure will be scheduled in the following cases: -/// - If grpc_call_combiner_cancel() was called prior to registering the -/// closure, it will be scheduled immediately with the cancelation error. -/// - If grpc_call_combiner_cancel() is called after registering the -/// closure, the closure will be scheduled with the cancellation error. -/// - If grpc_call_combiner_set_notify_on_cancel() is called again to -/// register a new cancellation closure, the previous cancellation -/// closure will be scheduled with GRPC_ERROR_NONE. -/// -/// If \a closure is NULL, then no closure will be invoked on -/// cancellation; this effectively unregisters the previously set closure. -/// However, most filters will not need to explicitly unregister their -/// callbacks, as this is done automatically when the call is destroyed. Filters -/// that schedule the cancellation closure on ExecCtx do not need to take a ref -/// on the call stack to guarantee closure liveness. This is done by explicitly -/// flushing ExecCtx after the unregistration during call destruction. -void grpc_call_combiner_set_notify_on_cancel(grpc_call_combiner* call_combiner, - grpc_closure* closure); - -/// Indicates that the call has been cancelled. -void grpc_call_combiner_cancel(grpc_call_combiner* call_combiner, - grpc_error* error); - -namespace grpc_core { +}; // Helper for running a list of closures in a call combiner. // @@ -139,7 +159,7 @@ class CallCombinerClosureList { // scheduled via GRPC_CLOSURE_SCHED(), which will eventually result in // yielding the call combiner. If the list is empty, then the call // combiner will be yielded immediately. - void RunClosures(grpc_call_combiner* call_combiner) { + void RunClosures(CallCombiner* call_combiner) { if (closures_.empty()) { GRPC_CALL_COMBINER_STOP(call_combiner, "no closures to schedule"); return; @@ -149,7 +169,7 @@ class CallCombinerClosureList { GRPC_CALL_COMBINER_START(call_combiner, closure.closure, closure.error, closure.reason); } - if (grpc_call_combiner_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_call_combiner_trace)) { gpr_log(GPR_INFO, "CallCombinerClosureList executing closure while already " "holding call_combiner %p: closure=%p error=%s reason=%s", @@ -163,7 +183,7 @@ class CallCombinerClosureList { // Runs all closures in the call combiner, but does NOT yield the call // combiner. All closures will be scheduled via GRPC_CALL_COMBINER_START(). - void RunClosuresWithoutYielding(grpc_call_combiner* call_combiner) { + void RunClosuresWithoutYielding(CallCombiner* call_combiner) { for (size_t i = 0; i < closures_.size(); ++i) { auto& closure = closures_[i]; GRPC_CALL_COMBINER_START(call_combiner, closure.closure, closure.error, diff --git a/src/core/lib/iomgr/cfstream_handle.cc b/src/core/lib/iomgr/cfstream_handle.cc index 827fd24831e..2fda160f68a 100644 --- a/src/core/lib/iomgr/cfstream_handle.cc +++ b/src/core/lib/iomgr/cfstream_handle.cc @@ -29,6 +29,7 @@ #include "src/core/lib/debug/trace.h" #include "src/core/lib/iomgr/closure.h" +#include "src/core/lib/iomgr/error_cfstream.h" #include "src/core/lib/iomgr/exec_ctx.h" extern grpc_core::TraceFlag grpc_tcp_trace; @@ -52,62 +53,72 @@ CFStreamHandle* CFStreamHandle::CreateStreamHandle( void CFStreamHandle::ReadCallback(CFReadStreamRef stream, CFStreamEventType type, void* client_callback_info) { + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; + grpc_core::ExecCtx exec_ctx; + grpc_error* error; + CFErrorRef stream_error; CFStreamHandle* handle = static_cast(client_callback_info); - CFSTREAM_HANDLE_REF(handle, "read callback"); - dispatch_async( - dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - grpc_core::ExecCtx exec_ctx; - if (grpc_tcp_trace.enabled()) { - gpr_log(GPR_DEBUG, "CFStream ReadCallback (%p, %p, %lu, %p)", handle, - stream, type, client_callback_info); - } - switch (type) { - case kCFStreamEventOpenCompleted: - handle->open_event_.SetReady(); - break; - case kCFStreamEventHasBytesAvailable: - case kCFStreamEventEndEncountered: - handle->read_event_.SetReady(); - break; - case kCFStreamEventErrorOccurred: - handle->open_event_.SetReady(); - handle->read_event_.SetReady(); - break; - default: - GPR_UNREACHABLE_CODE(return ); - } - CFSTREAM_HANDLE_UNREF(handle, "read callback"); - }); + if (grpc_tcp_trace.enabled()) { + gpr_log(GPR_DEBUG, "CFStream ReadCallback (%p, %p, %lu, %p)", handle, + stream, type, client_callback_info); + } + switch (type) { + case kCFStreamEventOpenCompleted: + handle->open_event_.SetReady(); + break; + case kCFStreamEventHasBytesAvailable: + case kCFStreamEventEndEncountered: + handle->read_event_.SetReady(); + break; + case kCFStreamEventErrorOccurred: + stream_error = CFReadStreamCopyError(stream); + error = grpc_error_set_int( + GRPC_ERROR_CREATE_FROM_CFERROR(stream_error, "read error"), + GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE); + CFRelease(stream_error); + handle->open_event_.SetShutdown(GRPC_ERROR_REF(error)); + handle->write_event_.SetShutdown(GRPC_ERROR_REF(error)); + handle->read_event_.SetShutdown(GRPC_ERROR_REF(error)); + GRPC_ERROR_UNREF(error); + break; + default: + GPR_UNREACHABLE_CODE(return ); + } } void CFStreamHandle::WriteCallback(CFWriteStreamRef stream, CFStreamEventType type, void* clientCallBackInfo) { + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; + grpc_core::ExecCtx exec_ctx; + grpc_error* error; + CFErrorRef stream_error; CFStreamHandle* handle = static_cast(clientCallBackInfo); - CFSTREAM_HANDLE_REF(handle, "write callback"); - dispatch_async( - dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - grpc_core::ExecCtx exec_ctx; - if (grpc_tcp_trace.enabled()) { - gpr_log(GPR_DEBUG, "CFStream WriteCallback (%p, %p, %lu, %p)", handle, - stream, type, clientCallBackInfo); - } - switch (type) { - case kCFStreamEventOpenCompleted: - handle->open_event_.SetReady(); - break; - case kCFStreamEventCanAcceptBytes: - case kCFStreamEventEndEncountered: - handle->write_event_.SetReady(); - break; - case kCFStreamEventErrorOccurred: - handle->open_event_.SetReady(); - handle->write_event_.SetReady(); - break; - default: - GPR_UNREACHABLE_CODE(return ); - } - CFSTREAM_HANDLE_UNREF(handle, "write callback"); - }); + if (grpc_tcp_trace.enabled()) { + gpr_log(GPR_DEBUG, "CFStream WriteCallback (%p, %p, %lu, %p)", handle, + stream, type, clientCallBackInfo); + } + switch (type) { + case kCFStreamEventOpenCompleted: + handle->open_event_.SetReady(); + break; + case kCFStreamEventCanAcceptBytes: + case kCFStreamEventEndEncountered: + handle->write_event_.SetReady(); + break; + case kCFStreamEventErrorOccurred: + stream_error = CFWriteStreamCopyError(stream); + error = grpc_error_set_int( + GRPC_ERROR_CREATE_FROM_CFERROR(stream_error, "write error"), + GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE); + CFRelease(stream_error); + handle->open_event_.SetShutdown(GRPC_ERROR_REF(error)); + handle->write_event_.SetShutdown(GRPC_ERROR_REF(error)); + handle->read_event_.SetShutdown(GRPC_ERROR_REF(error)); + GRPC_ERROR_UNREF(error); + break; + default: + GPR_UNREACHABLE_CODE(return ); + } } CFStreamHandle::CFStreamHandle(CFReadStreamRef read_stream, @@ -116,6 +127,7 @@ CFStreamHandle::CFStreamHandle(CFReadStreamRef read_stream, open_event_.InitEvent(); read_event_.InitEvent(); write_event_.InitEvent(); + dispatch_queue_ = dispatch_queue_create(nullptr, DISPATCH_QUEUE_SERIAL); CFStreamClientContext ctx = {0, static_cast(this), CFStreamHandle::Retain, CFStreamHandle::Release, nil}; @@ -129,10 +141,8 @@ CFStreamHandle::CFStreamHandle(CFReadStreamRef read_stream, kCFStreamEventOpenCompleted | kCFStreamEventCanAcceptBytes | kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered, CFStreamHandle::WriteCallback, &ctx); - CFReadStreamScheduleWithRunLoop(read_stream, CFRunLoopGetMain(), - kCFRunLoopCommonModes); - CFWriteStreamScheduleWithRunLoop(write_stream, CFRunLoopGetMain(), - kCFRunLoopCommonModes); + CFReadStreamSetDispatchQueue(read_stream, dispatch_queue_); + CFWriteStreamSetDispatchQueue(write_stream, dispatch_queue_); } CFStreamHandle::~CFStreamHandle() { @@ -182,4 +192,11 @@ void CFStreamHandle::Unref(const char* file, int line, const char* reason) { } } +#else + +/* Creating a dummy function so that the grpc_cfstream library will be + * non-empty. + */ +void CFStreamDummy() {} + #endif diff --git a/src/core/lib/iomgr/cfstream_handle.h b/src/core/lib/iomgr/cfstream_handle.h index 4258e72431c..4f4d15966e4 100644 --- a/src/core/lib/iomgr/cfstream_handle.h +++ b/src/core/lib/iomgr/cfstream_handle.h @@ -37,8 +37,8 @@ class CFStreamHandle final { static CFStreamHandle* CreateStreamHandle(CFReadStreamRef read_stream, CFWriteStreamRef write_stream); ~CFStreamHandle(); - CFStreamHandle(const CFReadStreamRef& ref) = delete; - CFStreamHandle(CFReadStreamRef&& ref) = delete; + CFStreamHandle(const CFStreamHandle& ref) = delete; + CFStreamHandle(CFStreamHandle&& ref) = delete; CFStreamHandle& operator=(const CFStreamHandle& rhs) = delete; void NotifyOnOpen(grpc_closure* closure); @@ -62,6 +62,8 @@ class CFStreamHandle final { grpc_core::LockfreeEvent read_event_; grpc_core::LockfreeEvent write_event_; + dispatch_queue_t dispatch_queue_; + gpr_refcount refcount_; }; diff --git a/src/core/lib/iomgr/combiner.cc b/src/core/lib/iomgr/combiner.cc index 7c0062eb4ec..4fc4a9dccf4 100644 --- a/src/core/lib/iomgr/combiner.cc +++ b/src/core/lib/iomgr/combiner.cc @@ -29,6 +29,7 @@ #include "src/core/lib/debug/stats.h" #include "src/core/lib/iomgr/executor.h" +#include "src/core/lib/iomgr/iomgr.h" #include "src/core/lib/profiling/timers.h" grpc_core::DebugOnlyTraceFlag grpc_combiner_trace(false, "combiner"); @@ -82,8 +83,9 @@ grpc_combiner* grpc_combiner_create(void) { gpr_atm_no_barrier_store(&lock->state, STATE_UNORPHANED); gpr_mpscq_init(&lock->queue); grpc_closure_list_init(&lock->final_list); - GRPC_CLOSURE_INIT(&lock->offload, offload, lock, - grpc_executor_scheduler(GRPC_EXECUTOR_SHORT)); + GRPC_CLOSURE_INIT( + &lock->offload, offload, lock, + grpc_core::Executor::Scheduler(grpc_core::ExecutorJobType::SHORT)); GRPC_COMBINER_TRACE(gpr_log(GPR_INFO, "C:%p create", lock)); return lock; } @@ -228,8 +230,14 @@ bool grpc_combiner_continue_exec_ctx() { grpc_core::ExecCtx::Get()->IsReadyToFinish(), lock->time_to_execute_final_list)); + // offload only if all the following conditions are true: + // 1. the combiner is contended and has more than one closure to execute + // 2. the current execution context needs to finish as soon as possible + // 3. the DEFAULT executor is threaded + // 4. the current thread is not a worker for any background poller if (contended && grpc_core::ExecCtx::Get()->IsReadyToFinish() && - grpc_executor_is_threaded()) { + grpc_core::Executor::IsThreadedDefault() && + !grpc_iomgr_is_any_background_poller_thread()) { GPR_TIMER_MARK("offload_from_finished_exec_ctx", 0); // this execution context wants to move on: schedule remaining work to be // picked up on the executor diff --git a/src/core/lib/iomgr/combiner.h b/src/core/lib/iomgr/combiner.h index 3c947bf9d64..b9274216993 100644 --- a/src/core/lib/iomgr/combiner.h +++ b/src/core/lib/iomgr/combiner.h @@ -31,7 +31,7 @@ // Provides serialized access to some resource. // Each action queued on a combiner is executed serially in a borrowed thread. // The actual thread executing actions may change over time (but there will only -// every be one at a time). +// ever be one at a time). // Initialize the lock, with an optional workqueue to shift load to when // necessary diff --git a/src/core/lib/iomgr/dynamic_annotations.h b/src/core/lib/iomgr/dynamic_annotations.h new file mode 100644 index 00000000000..713928023ae --- /dev/null +++ b/src/core/lib/iomgr/dynamic_annotations.h @@ -0,0 +1,67 @@ +/* + * + * 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_DYNAMIC_ANNOTATIONS_H +#define GRPC_CORE_LIB_IOMGR_DYNAMIC_ANNOTATIONS_H + +#include + +#ifdef GRPC_TSAN_ENABLED + +#define TSAN_ANNOTATE_HAPPENS_BEFORE(addr) \ + AnnotateHappensBefore(__FILE__, __LINE__, (void*)(addr)) +#define TSAN_ANNOTATE_HAPPENS_AFTER(addr) \ + AnnotateHappensAfter(__FILE__, __LINE__, (void*)(addr)) +#define TSAN_ANNOTATE_RWLOCK_CREATE(addr) \ + AnnotateRWLockCreate(__FILE__, __LINE__, (void*)(addr)) +#define TSAN_ANNOTATE_RWLOCK_DESTROY(addr) \ + AnnotateRWLockDestroy(__FILE__, __LINE__, (void*)(addr)) +#define TSAN_ANNOTATE_RWLOCK_ACQUIRED(addr, is_w) \ + AnnotateRWLockAcquired(__FILE__, __LINE__, (void*)(addr), (is_w)) +#define TSAN_ANNOTATE_RWLOCK_RELEASED(addr, is_w) \ + AnnotateRWLockReleased(__FILE__, __LINE__, (void*)(addr), (is_w)) + +#ifdef __cplusplus +extern "C" { +#endif +void AnnotateHappensBefore(const char* file, int line, const volatile void* cv); +void AnnotateHappensAfter(const char* file, int line, const volatile void* cv); +void AnnotateRWLockCreate(const char* file, int line, + const volatile void* lock); +void AnnotateRWLockDestroy(const char* file, int line, + const volatile void* lock); +void AnnotateRWLockAcquired(const char* file, int line, + const volatile void* lock, long is_w); +void AnnotateRWLockReleased(const char* file, int line, + const volatile void* lock, long is_w); +#ifdef __cplusplus +} +#endif + +#else /* GRPC_TSAN_ENABLED */ + +#define TSAN_ANNOTATE_HAPPENS_BEFORE(addr) +#define TSAN_ANNOTATE_HAPPENS_AFTER(addr) +#define TSAN_ANNOTATE_RWLOCK_CREATE(addr) +#define TSAN_ANNOTATE_RWLOCK_DESTROY(addr) +#define TSAN_ANNOTATE_RWLOCK_ACQUIRED(addr, is_w) +#define TSAN_ANNOTATE_RWLOCK_RELEASED(addr, is_w) + +#endif /* GRPC_TSAN_ENABLED */ + +#endif /* GRPC_CORE_LIB_IOMGR_DYNAMIC_ANNOTATIONS_H */ diff --git a/src/core/lib/iomgr/endpoint.cc b/src/core/lib/iomgr/endpoint.cc index 44fb47e19d9..bb07fe79608 100644 --- a/src/core/lib/iomgr/endpoint.cc +++ b/src/core/lib/iomgr/endpoint.cc @@ -23,8 +23,8 @@ grpc_core::TraceFlag grpc_tcp_trace(false, "tcp"); void grpc_endpoint_read(grpc_endpoint* ep, grpc_slice_buffer* slices, - grpc_closure* cb) { - ep->vtable->read(ep, slices, cb); + grpc_closure* cb, bool urgent) { + ep->vtable->read(ep, slices, cb, urgent); } void grpc_endpoint_write(grpc_endpoint* ep, grpc_slice_buffer* slices, @@ -61,3 +61,7 @@ int grpc_endpoint_get_fd(grpc_endpoint* ep) { return ep->vtable->get_fd(ep); } grpc_resource_user* grpc_endpoint_get_resource_user(grpc_endpoint* ep) { return ep->vtable->get_resource_user(ep); } + +bool grpc_endpoint_can_track_err(grpc_endpoint* ep) { + return ep->vtable->can_track_err(ep); +} diff --git a/src/core/lib/iomgr/endpoint.h b/src/core/lib/iomgr/endpoint.h index 1f590a80cae..932e7e15b9a 100644 --- a/src/core/lib/iomgr/endpoint.h +++ b/src/core/lib/iomgr/endpoint.h @@ -36,7 +36,8 @@ typedef struct grpc_endpoint_vtable grpc_endpoint_vtable; class Timestamps; struct grpc_endpoint_vtable { - void (*read)(grpc_endpoint* ep, grpc_slice_buffer* slices, grpc_closure* cb); + void (*read)(grpc_endpoint* ep, grpc_slice_buffer* slices, grpc_closure* cb, + bool urgent); void (*write)(grpc_endpoint* ep, grpc_slice_buffer* slices, grpc_closure* cb, void* arg); void (*add_to_pollset)(grpc_endpoint* ep, grpc_pollset* pollset); @@ -47,6 +48,7 @@ struct grpc_endpoint_vtable { grpc_resource_user* (*get_resource_user)(grpc_endpoint* ep); char* (*get_peer)(grpc_endpoint* ep); int (*get_fd)(grpc_endpoint* ep); + bool (*can_track_err)(grpc_endpoint* ep); }; /* When data is available on the connection, calls the callback with slices. @@ -55,7 +57,7 @@ struct grpc_endpoint_vtable { Valid slices may be placed into \a slices even when the callback is invoked with error != GRPC_ERROR_NONE. */ void grpc_endpoint_read(grpc_endpoint* ep, grpc_slice_buffer* slices, - grpc_closure* cb); + grpc_closure* cb, bool urgent); char* grpc_endpoint_get_peer(grpc_endpoint* ep); @@ -95,6 +97,8 @@ void grpc_endpoint_delete_from_pollset_set(grpc_endpoint* ep, grpc_resource_user* grpc_endpoint_get_resource_user(grpc_endpoint* endpoint); +bool grpc_endpoint_can_track_err(grpc_endpoint* ep); + struct grpc_endpoint { const grpc_endpoint_vtable* vtable; }; diff --git a/src/core/lib/iomgr/endpoint_cfstream.cc b/src/core/lib/iomgr/endpoint_cfstream.cc index df2cf508c8f..6de22972dbf 100644 --- a/src/core/lib/iomgr/endpoint_cfstream.cc +++ b/src/core/lib/iomgr/endpoint_cfstream.cc @@ -182,7 +182,7 @@ static void ReadAction(void* arg, grpc_error* error) { GRPC_ERROR_CREATE_FROM_STATIC_STRING("Socket closed"), ep)); EP_UNREF(ep, "read"); } else { - if (read_size < len) { + if (read_size < static_cast(len)) { grpc_slice_buffer_trim_end(ep->read_slices, len - read_size, nullptr); } CallReadCb(ep, GRPC_ERROR_NONE); @@ -217,7 +217,7 @@ static void WriteAction(void* arg, grpc_error* error) { CallWriteCb(ep, error); EP_UNREF(ep, "write"); } else { - if (write_size < GRPC_SLICE_LENGTH(slice)) { + if (write_size < static_cast(GRPC_SLICE_LENGTH(slice))) { grpc_slice_buffer_undo_take_first( ep->write_slices, grpc_slice_sub(slice, write_size, slice_len)); } @@ -251,7 +251,7 @@ static void CFStreamReadAllocationDone(void* arg, grpc_error* error) { } static void CFStreamRead(grpc_endpoint* ep, grpc_slice_buffer* slices, - grpc_closure* cb) { + grpc_closure* cb, bool urgent) { CFStreamEndpoint* ep_impl = reinterpret_cast(ep); if (grpc_tcp_trace.enabled()) { gpr_log(GPR_DEBUG, "CFStream endpoint:%p read (%p, %p) length:%zu", ep_impl, @@ -315,6 +315,8 @@ char* CFStreamGetPeer(grpc_endpoint* ep) { int CFStreamGetFD(grpc_endpoint* ep) { return 0; } +bool CFStreamCanTrackErr(grpc_endpoint* ep) { return false; } + void CFStreamAddToPollset(grpc_endpoint* ep, grpc_pollset* pollset) {} void CFStreamAddToPollsetSet(grpc_endpoint* ep, grpc_pollset_set* pollset) {} void CFStreamDeleteFromPollsetSet(grpc_endpoint* ep, @@ -329,7 +331,8 @@ static const grpc_endpoint_vtable vtable = {CFStreamRead, CFStreamDestroy, CFStreamGetResourceUser, CFStreamGetPeer, - CFStreamGetFD}; + CFStreamGetFD, + CFStreamCanTrackErr}; grpc_endpoint* grpc_cfstream_endpoint_create( CFReadStreamRef read_stream, CFWriteStreamRef write_stream, diff --git a/src/core/lib/iomgr/endpoint_pair_posix.cc b/src/core/lib/iomgr/endpoint_pair_posix.cc index 3afbfd72543..5c5c246f998 100644 --- a/src/core/lib/iomgr/endpoint_pair_posix.cc +++ b/src/core/lib/iomgr/endpoint_pair_posix.cc @@ -59,11 +59,11 @@ grpc_endpoint_pair grpc_iomgr_create_endpoint_pair(const char* name, grpc_core::ExecCtx exec_ctx; gpr_asprintf(&final_name, "%s:client", name); - p.client = grpc_tcp_create(grpc_fd_create(sv[1], final_name, true), args, + p.client = grpc_tcp_create(grpc_fd_create(sv[1], final_name, false), args, "socketpair-server"); gpr_free(final_name); gpr_asprintf(&final_name, "%s:server", name); - p.server = grpc_tcp_create(grpc_fd_create(sv[0], final_name, true), args, + p.server = grpc_tcp_create(grpc_fd_create(sv[0], final_name, false), args, "socketpair-client"); gpr_free(final_name); diff --git a/src/core/lib/iomgr/endpoint_pair_windows.cc b/src/core/lib/iomgr/endpoint_pair_windows.cc index 177331d6812..9962809a27b 100644 --- a/src/core/lib/iomgr/endpoint_pair_windows.cc +++ b/src/core/lib/iomgr/endpoint_pair_windows.cc @@ -41,7 +41,7 @@ static void create_sockets(SOCKET sv[2]) { int addr_len = sizeof(addr); lst_sock = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, - WSA_FLAG_OVERLAPPED); + grpc_get_default_wsa_socket_flags()); GPR_ASSERT(lst_sock != INVALID_SOCKET); memset(&addr, 0, sizeof(addr)); @@ -54,7 +54,7 @@ static void create_sockets(SOCKET sv[2]) { SOCKET_ERROR); cli_sock = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, - WSA_FLAG_OVERLAPPED); + grpc_get_default_wsa_socket_flags()); GPR_ASSERT(cli_sock != INVALID_SOCKET); GPR_ASSERT(WSAConnect(cli_sock, (grpc_sockaddr*)&addr, addr_len, NULL, NULL, diff --git a/src/core/lib/iomgr/error.cc b/src/core/lib/iomgr/error.cc index 6ae077fd548..f194eb62d48 100644 --- a/src/core/lib/iomgr/error.cc +++ b/src/core/lib/iomgr/error.cc @@ -150,13 +150,12 @@ static void unref_errs(grpc_error* err) { } } -static void unref_slice(grpc_slice slice) { grpc_slice_unref_internal(slice); } - static void unref_strs(grpc_error* err) { for (size_t which = 0; which < GRPC_ERROR_STR_MAX; ++which) { uint8_t slot = err->strs[which]; if (slot != UINT8_MAX) { - unref_slice(*reinterpret_cast(err->arena + slot)); + grpc_slice_unref_internal( + *reinterpret_cast(err->arena + slot)); } } } @@ -231,7 +230,7 @@ static void internal_set_int(grpc_error** err, grpc_error_ints which, } static void internal_set_str(grpc_error** err, grpc_error_strs which, - grpc_slice value) { + const grpc_slice& value) { uint8_t slot = (*err)->strs[which]; if (slot == UINT8_MAX) { slot = get_placement(err, sizeof(value)); @@ -243,7 +242,8 @@ static void internal_set_str(grpc_error** err, grpc_error_strs which, return; } } else { - unref_slice(*reinterpret_cast((*err)->arena + slot)); + grpc_slice_unref_internal( + *reinterpret_cast((*err)->arena + slot)); } (*err)->strs[which] = slot; memcpy((*err)->arena + slot, &value, sizeof(value)); @@ -303,14 +303,18 @@ static void internal_add_error(grpc_error** err, grpc_error* new_err) { // It is very common to include and extra int and string in an error #define SURPLUS_CAPACITY (2 * SLOTS_PER_INT + SLOTS_PER_TIME) -static bool g_error_creation_allowed = true; +static gpr_atm g_error_creation_allowed = true; -void grpc_disable_error_creation() { g_error_creation_allowed = false; } +void grpc_disable_error_creation() { + gpr_atm_no_barrier_store(&g_error_creation_allowed, false); +} -void grpc_enable_error_creation() { g_error_creation_allowed = true; } +void grpc_enable_error_creation() { + gpr_atm_no_barrier_store(&g_error_creation_allowed, true); +} -grpc_error* grpc_error_create(const char* file, int line, grpc_slice desc, - grpc_error** referencing, +grpc_error* grpc_error_create(const char* file, int line, + const grpc_slice& desc, grpc_error** referencing, size_t num_referencing) { GPR_TIMER_SCOPE("grpc_error_create", 0); uint8_t initial_arena_capacity = static_cast( @@ -323,7 +327,7 @@ grpc_error* grpc_error_create(const char* file, int line, grpc_slice desc, return GRPC_ERROR_OOM; } #ifndef NDEBUG - if (!g_error_creation_allowed) { + if (!gpr_atm_no_barrier_load(&g_error_creation_allowed)) { gpr_log(GPR_ERROR, "Error creation occurred when error creation was disabled [%s:%d]", file, line); @@ -468,7 +472,7 @@ bool grpc_error_get_int(grpc_error* err, grpc_error_ints which, intptr_t* p) { } grpc_error* grpc_error_set_str(grpc_error* src, grpc_error_strs which, - grpc_slice str) { + const grpc_slice& str) { GPR_TIMER_SCOPE("grpc_error_set_str", 0); grpc_error* new_err = copy_error_and_unref(src); internal_set_str(&new_err, which, str); @@ -616,7 +620,7 @@ static char* key_str(grpc_error_strs which) { return gpr_strdup(error_str_name(which)); } -static char* fmt_str(grpc_slice slice) { +static char* fmt_str(const grpc_slice& slice) { char* s = nullptr; size_t sz = 0; size_t cap = 0; @@ -765,7 +769,7 @@ grpc_error* grpc_os_error(const char* file, int line, int err, grpc_error_set_str( grpc_error_set_int( grpc_error_create(file, line, - grpc_slice_from_static_string("OS Error"), + grpc_slice_from_static_string(strerror(err)), nullptr, 0), GRPC_ERROR_INT_ERRNO, err), GRPC_ERROR_STR_OS_ERROR, diff --git a/src/core/lib/iomgr/error.h b/src/core/lib/iomgr/error.h index cb740d5b01c..7b04888e9ec 100644 --- a/src/core/lib/iomgr/error.h +++ b/src/core/lib/iomgr/error.h @@ -30,6 +30,7 @@ #include #include "src/core/lib/debug/trace.h" +#include "src/core/lib/gprpp/inlined_vector.h" /// Opaque representation of an error. /// See https://github.com/grpc/grpc/blob/master/doc/core/grpc-error.md for a @@ -138,8 +139,9 @@ void grpc_enable_error_creation(); const char* grpc_error_string(grpc_error* error); /// Create an error - but use GRPC_ERROR_CREATE instead -grpc_error* grpc_error_create(const char* file, int line, grpc_slice desc, - grpc_error** referencing, size_t num_referencing); +grpc_error* grpc_error_create(const char* file, int line, + const grpc_slice& desc, grpc_error** referencing, + size_t num_referencing); /// Create an error (this is the preferred way of generating an error that is /// not due to a system call - for system calls, use GRPC_OS_ERROR or /// GRPC_WSA_ERROR as appropriate) @@ -164,6 +166,9 @@ grpc_error* grpc_error_create(const char* file, int line, grpc_slice desc, grpc_error_create(__FILE__, __LINE__, grpc_slice_from_copied_string(desc), \ errs, count) +#define GRPC_ERROR_CREATE_FROM_VECTOR(desc, error_list) \ + grpc_error_create_from_vector(__FILE__, __LINE__, desc, error_list) + #ifndef NDEBUG grpc_error* grpc_error_do_ref(grpc_error* err, const char* file, int line); void grpc_error_do_unref(grpc_error* err, const char* file, int line); @@ -192,6 +197,25 @@ inline void grpc_error_unref(grpc_error* err) { #define GRPC_ERROR_UNREF(err) grpc_error_unref(err) #endif +// Consumes all the errors in the vector and forms a referencing error from +// them. If the vector is empty, return GRPC_ERROR_NONE. +template +static grpc_error* grpc_error_create_from_vector( + const char* file, int line, const char* desc, + grpc_core::InlinedVector* error_list) { + grpc_error* error = GRPC_ERROR_NONE; + if (error_list->size() != 0) { + error = grpc_error_create(file, line, grpc_slice_from_static_string(desc), + error_list->data(), error_list->size()); + // Remove refs to all errors in error_list. + for (size_t i = 0; i < error_list->size(); i++) { + GRPC_ERROR_UNREF((*error_list)[i]); + } + error_list->clear(); + } + return error; +} + grpc_error* grpc_error_set_int(grpc_error* src, grpc_error_ints which, intptr_t value) GRPC_MUST_USE_RESULT; /// It is an error to pass nullptr as `p`. Caller should allocate a dummy @@ -200,7 +224,7 @@ bool grpc_error_get_int(grpc_error* error, grpc_error_ints which, intptr_t* p); /// This call takes ownership of the slice; the error is responsible for /// eventually unref-ing it. grpc_error* grpc_error_set_str(grpc_error* src, grpc_error_strs which, - grpc_slice str) GRPC_MUST_USE_RESULT; + const grpc_slice& str) GRPC_MUST_USE_RESULT; /// Returns false if the specified string is not set. /// Caller does NOT own the slice. bool grpc_error_get_str(grpc_error* error, grpc_error_strs which, diff --git a/src/core/lib/iomgr/error_internal.h b/src/core/lib/iomgr/error_internal.h index 80273960198..7b0cbd6d98f 100644 --- a/src/core/lib/iomgr/error_internal.h +++ b/src/core/lib/iomgr/error_internal.h @@ -49,7 +49,7 @@ struct grpc_error { uint8_t strs[GRPC_ERROR_STR_MAX]; uint8_t times[GRPC_ERROR_TIME_MAX]; // The child errors are stored in the arena, but are effectively a linked list - // structure, since they are contained withing grpc_linked_error objects. + // structure, since they are contained within grpc_linked_error objects. uint8_t first_err; uint8_t last_err; // The arena is dynamically reallocated with a grow factor of 1.5. diff --git a/src/core/lib/iomgr/ev_epoll1_linux.cc b/src/core/lib/iomgr/ev_epoll1_linux.cc index 38571b1957b..0c357dd2758 100644 --- a/src/core/lib/iomgr/ev_epoll1_linux.cc +++ b/src/core/lib/iomgr/ev_epoll1_linux.cc @@ -213,7 +213,7 @@ struct grpc_pollset { poll */ bool seen_inactive; bool shutting_down; /* Is the pollset shutting down ? */ - grpc_closure* shutdown_closure; /* Called after after shutdown is complete */ + grpc_closure* shutdown_closure; /* Called after shutdown is complete */ /* Number of workers who are *about-to* attach themselves to the pollset * worker list */ @@ -351,7 +351,7 @@ static grpc_fd* fd_create(int fd, const char* name, bool track_err) { grpc_iomgr_register_object(&new_fd->iomgr_object, fd_name); fork_fd_list_add_grpc_fd(new_fd); #ifndef NDEBUG - if (grpc_trace_fd_refcount.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_trace_fd_refcount)) { gpr_log(GPR_DEBUG, "FD %d %p create %s", fd, new_fd, fd_name); } #endif @@ -383,6 +383,13 @@ static void fd_shutdown_internal(grpc_fd* fd, grpc_error* why, if (fd->read_closure->SetShutdown(GRPC_ERROR_REF(why))) { if (!releasing_fd) { shutdown(fd->fd, SHUT_RDWR); + } else { + /* we need a dummy event for earlier linux versions. */ + epoll_event dummy_event; + if (epoll_ctl(g_epoll_set.epfd, EPOLL_CTL_DEL, fd->fd, &dummy_event) != + 0) { + gpr_log(GPR_ERROR, "epoll_ctl failed: %s", strerror(errno)); + } } fd->write_closure->SetShutdown(GRPC_ERROR_REF(why)); fd->error_closure->SetShutdown(GRPC_ERROR_REF(why)); @@ -724,7 +731,7 @@ static grpc_error* do_epoll_wait(grpc_pollset* ps, grpc_millis deadline) { GRPC_STATS_INC_POLL_EVENTS_RETURNED(r); - if (grpc_polling_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { gpr_log(GPR_INFO, "ps: %p poll got %d events", ps, r); } @@ -744,7 +751,7 @@ static bool begin_worker(grpc_pollset* pollset, grpc_pollset_worker* worker, worker->schedule_on_end_work = (grpc_closure_list)GRPC_CLOSURE_LIST_INIT; pollset->begin_refs++; - if (grpc_polling_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { gpr_log(GPR_INFO, "PS:%p BEGIN_STARTS:%p", pollset, worker); } @@ -763,7 +770,7 @@ static bool begin_worker(grpc_pollset* pollset, grpc_pollset_worker* worker, retry_lock_neighborhood: gpr_mu_lock(&neighborhood->mu); gpr_mu_lock(&pollset->mu); - if (grpc_polling_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { gpr_log(GPR_INFO, "PS:%p BEGIN_REORG:%p kick_state=%s is_reassigning=%d", pollset, worker, kick_state_string(worker->state), is_reassigning); @@ -815,7 +822,7 @@ static bool begin_worker(grpc_pollset* pollset, grpc_pollset_worker* worker, worker->initialized_cv = true; gpr_cv_init(&worker->cv); while (worker->state == UNKICKED && !pollset->shutting_down) { - if (grpc_polling_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { gpr_log(GPR_INFO, "PS:%p BEGIN_WAIT:%p kick_state=%s shutdown=%d", pollset, worker, kick_state_string(worker->state), pollset->shutting_down); @@ -832,7 +839,7 @@ static bool begin_worker(grpc_pollset* pollset, grpc_pollset_worker* worker, grpc_core::ExecCtx::Get()->InvalidateNow(); } - if (grpc_polling_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { gpr_log(GPR_INFO, "PS:%p BEGIN_DONE:%p kick_state=%s shutdown=%d " "kicked_without_poller: %d", @@ -875,7 +882,7 @@ static bool check_neighborhood_for_available_poller( case UNKICKED: if (gpr_atm_no_barrier_cas(&g_active_poller, 0, (gpr_atm)inspect_worker)) { - if (grpc_polling_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { gpr_log(GPR_INFO, " .. choose next poller to be %p", inspect_worker); } @@ -886,7 +893,7 @@ static bool check_neighborhood_for_available_poller( gpr_cv_signal(&inspect_worker->cv); } } else { - if (grpc_polling_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { gpr_log(GPR_INFO, " .. beaten to choose next poller"); } } @@ -904,7 +911,7 @@ static bool check_neighborhood_for_available_poller( } while (!found_worker && inspect_worker != inspect->root_worker); } if (!found_worker) { - if (grpc_polling_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { gpr_log(GPR_INFO, " .. mark pollset %p inactive", inspect); } inspect->seen_inactive = true; @@ -924,7 +931,7 @@ static bool check_neighborhood_for_available_poller( static void end_worker(grpc_pollset* pollset, grpc_pollset_worker* worker, grpc_pollset_worker** worker_hdl) { GPR_TIMER_SCOPE("end_worker", 0); - if (grpc_polling_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { gpr_log(GPR_INFO, "PS:%p END_WORKER:%p", pollset, worker); } if (worker_hdl != nullptr) *worker_hdl = nullptr; @@ -934,7 +941,7 @@ static void end_worker(grpc_pollset* pollset, grpc_pollset_worker* worker, grpc_core::ExecCtx::Get()->closure_list()); 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()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { gpr_log(GPR_INFO, " .. choose next poller to be peer %p", worker); } GPR_ASSERT(worker->next->initialized_cv); @@ -986,7 +993,7 @@ static void end_worker(grpc_pollset* pollset, grpc_pollset_worker* worker, if (worker->initialized_cv) { gpr_cv_destroy(&worker->cv); } - if (grpc_polling_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { gpr_log(GPR_INFO, " .. remove worker"); } if (EMPTIED == worker_remove(pollset, worker)) { @@ -1024,7 +1031,7 @@ static grpc_error* pollset_work(grpc_pollset* ps, process the pending epoll events. The reason for decoupling do_epoll_wait and process_epoll_events is to - better distrubute the work (i.e handling epoll events) across multiple + better distribute the work (i.e handling epoll events) across multiple threads process_epoll_events() returns very quickly: It just queues the work on @@ -1055,7 +1062,7 @@ static grpc_error* pollset_kick(grpc_pollset* pollset, GPR_TIMER_SCOPE("pollset_kick", 0); GRPC_STATS_INC_POLLSET_KICK(); grpc_error* ret_err = GRPC_ERROR_NONE; - if (grpc_polling_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { gpr_strvec log; gpr_strvec_init(&log); char* tmp; @@ -1088,7 +1095,7 @@ static grpc_error* pollset_kick(grpc_pollset* pollset, if (root_worker == nullptr) { GRPC_STATS_INC_POLLSET_KICKED_WITHOUT_POLLER(); pollset->kicked_without_poller = true; - if (grpc_polling_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { gpr_log(GPR_INFO, " .. kicked_without_poller"); } goto done; @@ -1096,14 +1103,14 @@ static grpc_error* pollset_kick(grpc_pollset* pollset, grpc_pollset_worker* next_worker = root_worker->next; if (root_worker->state == KICKED) { GRPC_STATS_INC_POLLSET_KICKED_AGAIN(); - if (grpc_polling_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { 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()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { gpr_log(GPR_INFO, " .. already kicked %p", next_worker); } SET_KICK_STATE(next_worker, KICKED); @@ -1114,7 +1121,7 @@ static grpc_error* pollset_kick(grpc_pollset* pollset, root_worker == (grpc_pollset_worker*)gpr_atm_no_barrier_load( &g_active_poller)) { GRPC_STATS_INC_POLLSET_KICK_WAKEUP_FD(); - if (grpc_polling_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { gpr_log(GPR_INFO, " .. kicked %p", root_worker); } SET_KICK_STATE(root_worker, KICKED); @@ -1122,7 +1129,7 @@ static grpc_error* pollset_kick(grpc_pollset* pollset, goto done; } else if (next_worker->state == UNKICKED) { GRPC_STATS_INC_POLLSET_KICK_WAKEUP_CV(); - if (grpc_polling_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { gpr_log(GPR_INFO, " .. kicked %p", next_worker); } GPR_ASSERT(next_worker->initialized_cv); @@ -1131,7 +1138,7 @@ static grpc_error* pollset_kick(grpc_pollset* pollset, goto done; } else if (next_worker->state == DESIGNATED_POLLER) { if (root_worker->state != DESIGNATED_POLLER) { - if (grpc_polling_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { gpr_log( GPR_INFO, " .. kicked root non-poller %p (initialized_cv=%d) (poller=%p)", @@ -1145,7 +1152,7 @@ static grpc_error* pollset_kick(grpc_pollset* pollset, goto done; } else { GRPC_STATS_INC_POLLSET_KICK_WAKEUP_FD(); - if (grpc_polling_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { gpr_log(GPR_INFO, " .. non-root poller %p (root=%p)", next_worker, root_worker); } @@ -1161,7 +1168,7 @@ static grpc_error* pollset_kick(grpc_pollset* pollset, } } else { GRPC_STATS_INC_POLLSET_KICK_OWN_THREAD(); - if (grpc_polling_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { gpr_log(GPR_INFO, " .. kicked while waking up"); } goto done; @@ -1171,14 +1178,14 @@ static grpc_error* pollset_kick(grpc_pollset* pollset, } if (specific_worker->state == KICKED) { - if (grpc_polling_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { 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()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { gpr_log(GPR_INFO, " .. mark %p kicked", specific_worker); } SET_KICK_STATE(specific_worker, KICKED); @@ -1186,7 +1193,7 @@ static grpc_error* pollset_kick(grpc_pollset* pollset, } else if (specific_worker == (grpc_pollset_worker*)gpr_atm_no_barrier_load(&g_active_poller)) { GRPC_STATS_INC_POLLSET_KICK_WAKEUP_FD(); - if (grpc_polling_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { gpr_log(GPR_INFO, " .. kick active poller"); } SET_KICK_STATE(specific_worker, KICKED); @@ -1194,7 +1201,7 @@ static grpc_error* pollset_kick(grpc_pollset* pollset, goto done; } else if (specific_worker->initialized_cv) { GRPC_STATS_INC_POLLSET_KICK_WAKEUP_CV(); - if (grpc_polling_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { gpr_log(GPR_INFO, " .. kick waiting worker"); } SET_KICK_STATE(specific_worker, KICKED); @@ -1202,7 +1209,7 @@ static grpc_error* pollset_kick(grpc_pollset* pollset, goto done; } else { GRPC_STATS_INC_POLLSET_KICKED_AGAIN(); - if (grpc_polling_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { gpr_log(GPR_INFO, " .. kick non-waiting worker"); } SET_KICK_STATE(specific_worker, KICKED); @@ -1242,6 +1249,15 @@ static void pollset_set_del_pollset_set(grpc_pollset_set* bag, * Event engine binding */ +static bool is_any_background_poller_thread(void) { return false; } + +static void shutdown_background_closure(void) {} + +static bool add_closure_to_background_poller(grpc_closure* closure, + grpc_error* error) { + return false; +} + static void shutdown_engine(void) { fd_global_shutdown(); pollset_global_shutdown(); @@ -1255,6 +1271,7 @@ static void shutdown_engine(void) { static const grpc_event_engine_vtable vtable = { sizeof(grpc_pollset), true, + false, fd_create, fd_wrapped_fd, @@ -1284,7 +1301,10 @@ static const grpc_event_engine_vtable vtable = { pollset_set_add_fd, pollset_set_del_fd, + is_any_background_poller_thread, + shutdown_background_closure, shutdown_engine, + add_closure_to_background_poller, }; /* Called by the child process's post-fork handler to close open fds, including diff --git a/src/core/lib/iomgr/ev_epollex_linux.cc b/src/core/lib/iomgr/ev_epollex_linux.cc index 06a382c5560..08116b3ab53 100644 --- a/src/core/lib/iomgr/ev_epollex_linux.cc +++ b/src/core/lib/iomgr/ev_epollex_linux.cc @@ -45,8 +45,9 @@ #include "src/core/lib/gpr/spinlock.h" #include "src/core/lib/gpr/tls.h" #include "src/core/lib/gpr/useful.h" +#include "src/core/lib/gprpp/inlined_vector.h" #include "src/core/lib/gprpp/manual_constructor.h" -#include "src/core/lib/gprpp/mutex_lock.h" +#include "src/core/lib/gprpp/sync.h" #include "src/core/lib/iomgr/block_annotate.h" #include "src/core/lib/iomgr/iomgr_internal.h" #include "src/core/lib/iomgr/is_epollexclusive_available.h" @@ -78,18 +79,6 @@ typedef enum { PO_MULTI, PO_FD, PO_EMPTY } pollable_type; typedef struct pollable pollable; -typedef struct cached_fd { - // Set to the grpc_fd's salt value. See 'salt' variable' in grpc_fd for more - // details - intptr_t salt; - - // The underlying fd - int fd; - - // A recency time counter that helps to determine the LRU fd in the cache - uint64_t last_used; -} cached_fd; - /// A pollable is something that can be polled: it has an epoll set to poll on, /// and a wakeup fd for kicks /// There are three broad types: @@ -120,33 +109,6 @@ struct pollable { int event_cursor; int event_count; struct epoll_event events[MAX_EPOLL_EVENTS]; - - // We may be calling pollable_add_fd() on the same (pollable, fd) multiple - // times. To prevent pollable_add_fd() from making multiple sys calls to - // epoll_ctl() to add the fd, we maintain a cache of what fds are already - // present in the underlying epoll-set. - // - // Since this is not a correctness issue, we do not need to maintain all the - // fds in the cache. Hence we just use an LRU cache of size 'MAX_FDS_IN_CACHE' - // - // NOTE: An ideal implementation of this should do the following: - // 1) Add fds to the cache in pollable_add_fd() function (i.e whenever the fd - // is added to the pollable's epoll set) - // 2) Remove the fd from the cache whenever the fd is removed from the - // underlying epoll set (i.e whenever fd_orphan() is called). - // - // Implementing (2) above (i.e removing fds from cache on fd_orphan) adds a - // lot of complexity since an fd can be present in multiple pollables. So our - // implementation ONLY DOES (1) and NOT (2). - // - // The cache_fd.salt variable helps here to maintain correctness (it serves as - // an epoch that differentiates one grpc_fd from the other even though both of - // them may have the same fd number) - // - // The following implements LRU-eviction cache of fds in this pollable - cached_fd fd_cache[MAX_FDS_IN_CACHE]; - int fd_cache_size; - uint64_t fd_cache_counter; // Recency timer tick counter }; static const char* pollable_type_string(pollable_type t) { @@ -189,37 +151,86 @@ static void pollable_unref(pollable* p, int line, const char* reason); * Fd Declarations */ -// Monotonically increasing Epoch counter that is assinged to each grpc_fd. See -// the description of 'salt' variable in 'grpc_fd' for more details -// TODO: (sreek/kpayson) gpr_atm is intptr_t which may not be wide-enough on -// 32-bit systems. Change this to int_64 - atleast on 32-bit systems -static gpr_atm g_fd_salt; - struct grpc_fd { - int fd; + grpc_fd(int fd, const char* name, bool track_err) + : fd(fd), track_err(track_err) { + gpr_mu_init(&orphan_mu); + gpr_mu_init(&pollable_mu); + read_closure.InitEvent(); + write_closure.InitEvent(); + error_closure.InitEvent(); - // Since fd numbers can be reused (after old fds are closed), this serves as - // an epoch that uniquely identifies this fd (i.e the pair (salt, fd) is - // unique (until the salt counter (i.e g_fd_salt) overflows) - intptr_t salt; + char* fd_name; + gpr_asprintf(&fd_name, "%s fd=%d", name, fd); + grpc_iomgr_register_object(&iomgr_object, fd_name); +#ifndef NDEBUG + if (GRPC_TRACE_FLAG_ENABLED(grpc_trace_fd_refcount)) { + gpr_log(GPR_DEBUG, "FD %d %p create %s", fd, this, fd_name); + } +#endif + gpr_free(fd_name); + } + + // This is really the dtor, but the poller threads waking up from + // epoll_wait() may access the (read|write|error)_closure after destruction. + // Since the object will be added to the free pool, this behavior is + // not going to cause issues, except spurious events if the FD is reused + // while the race happens. + void destroy() { + grpc_iomgr_unregister_object(&iomgr_object); + + POLLABLE_UNREF(pollable_obj, "fd_pollable"); + pollset_fds.clear(); + gpr_mu_destroy(&pollable_mu); + gpr_mu_destroy(&orphan_mu); + + read_closure.DestroyEvent(); + write_closure.DestroyEvent(); + error_closure.DestroyEvent(); + + invalidate(); + } + +#ifndef NDEBUG + /* Since an fd is never really destroyed (i.e gpr_free() is not called), it is + * hard-to-debug cases where fd fields are accessed even after calling + * fd_destroy(). The following invalidates fd fields to make catching such + * errors easier */ + void invalidate() { + fd = -1; + gpr_atm_no_barrier_store(&refst, -1); + memset(&orphan_mu, -1, sizeof(orphan_mu)); + memset(&pollable_mu, -1, sizeof(pollable_mu)); + pollable_obj = nullptr; + on_done_closure = nullptr; + memset(&iomgr_object, -1, sizeof(iomgr_object)); + track_err = false; + } +#else + void invalidate() {} +#endif + + int fd; // refst format: // bit 0 : 1=Active / 0=Orphaned // bits 1-n : refcount // Ref/Unref by two to avoid altering the orphaned bit - gpr_atm refst; + gpr_atm refst = 1; gpr_mu orphan_mu; + // Protects pollable_obj and pollset_fds. gpr_mu pollable_mu; - pollable* pollable_obj; + grpc_core::InlinedVector pollset_fds; // Used in PO_MULTI. + pollable* pollable_obj = nullptr; // Used in PO_FD. - grpc_core::ManualConstructor read_closure; - grpc_core::ManualConstructor write_closure; - grpc_core::ManualConstructor error_closure; + grpc_core::LockfreeEvent read_closure; + grpc_core::LockfreeEvent write_closure; + grpc_core::LockfreeEvent error_closure; - struct grpc_fd* freelist_next; - grpc_closure* on_done_closure; + struct grpc_fd* freelist_next = nullptr; + grpc_closure* on_done_closure = nullptr; grpc_iomgr_object iomgr_object; @@ -258,6 +269,7 @@ struct grpc_pollset_worker { struct grpc_pollset { gpr_mu mu; gpr_atm worker_count; + gpr_atm active_pollable_type; pollable* active_pollable; bool kicked_without_poller; grpc_closure* shutdown_closure; @@ -323,7 +335,7 @@ static gpr_mu fd_freelist_mu; #define UNREF_BY(fd, n, reason) unref_by(fd, n, reason, __FILE__, __LINE__) static void ref_by(grpc_fd* fd, int n, const char* reason, const char* file, int line) { - if (grpc_trace_fd_refcount.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_trace_fd_refcount)) { gpr_log(GPR_DEBUG, "FD %d %p ref %d %" PRIdPTR " -> %" PRIdPTR " [%s; %s:%d]", fd->fd, fd, n, gpr_atm_no_barrier_load(&fd->refst), @@ -337,39 +349,10 @@ static void ref_by(grpc_fd* fd, int n) { GPR_ASSERT(gpr_atm_no_barrier_fetch_add(&fd->refst, n) > 0); } -#ifndef NDEBUG -#define INVALIDATE_FD(fd) invalidate_fd(fd) -/* Since an fd is never really destroyed (i.e gpr_free() is not called), it is - * hard to cases where fd fields are accessed even after calling fd_destroy(). - * The following invalidates fd fields to make catching such errors easier */ -static void invalidate_fd(grpc_fd* fd) { - fd->fd = -1; - fd->salt = -1; - gpr_atm_no_barrier_store(&fd->refst, -1); - memset(&fd->orphan_mu, -1, sizeof(fd->orphan_mu)); - memset(&fd->pollable_mu, -1, sizeof(fd->pollable_mu)); - fd->pollable_obj = nullptr; - fd->on_done_closure = nullptr; - memset(&fd->iomgr_object, -1, sizeof(fd->iomgr_object)); - fd->track_err = false; -} -#else -#define INVALIDATE_FD(fd) -#endif - /* Uninitialize and add to the freelist */ static void fd_destroy(void* arg, grpc_error* error) { grpc_fd* fd = static_cast(arg); - grpc_iomgr_unregister_object(&fd->iomgr_object); - POLLABLE_UNREF(fd->pollable_obj, "fd_pollable"); - gpr_mu_destroy(&fd->pollable_mu); - gpr_mu_destroy(&fd->orphan_mu); - - fd->read_closure->DestroyEvent(); - fd->write_closure->DestroyEvent(); - fd->error_closure->DestroyEvent(); - - INVALIDATE_FD(fd); + fd->destroy(); /* Add the fd to the freelist */ gpr_mu_lock(&fd_freelist_mu); @@ -381,7 +364,7 @@ static void fd_destroy(void* arg, grpc_error* error) { #ifndef NDEBUG static void unref_by(grpc_fd* fd, int n, const char* reason, const char* file, int line) { - if (grpc_trace_fd_refcount.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_trace_fd_refcount)) { gpr_log(GPR_DEBUG, "FD %d %p unref %d %" PRIdPTR " -> %" PRIdPTR " [%s; %s:%d]", fd->fd, fd, n, gpr_atm_no_barrier_load(&fd->refst), @@ -429,35 +412,9 @@ static grpc_fd* fd_create(int fd, const char* name, bool track_err) { if (new_fd == nullptr) { new_fd = static_cast(gpr_malloc(sizeof(grpc_fd))); - new_fd->read_closure.Init(); - new_fd->write_closure.Init(); - new_fd->error_closure.Init(); } - new_fd->fd = fd; - new_fd->salt = gpr_atm_no_barrier_fetch_add(&g_fd_salt, 1); - gpr_atm_rel_store(&new_fd->refst, (gpr_atm)1); - gpr_mu_init(&new_fd->orphan_mu); - gpr_mu_init(&new_fd->pollable_mu); - new_fd->pollable_obj = nullptr; - new_fd->read_closure->InitEvent(); - new_fd->write_closure->InitEvent(); - new_fd->error_closure->InitEvent(); - new_fd->freelist_next = nullptr; - new_fd->on_done_closure = nullptr; - - char* fd_name; - gpr_asprintf(&fd_name, "%s fd=%d", name, fd); - grpc_iomgr_register_object(&new_fd->iomgr_object, fd_name); -#ifndef NDEBUG - if (grpc_trace_fd_refcount.enabled()) { - gpr_log(GPR_DEBUG, "FD %d %p create %s", fd, new_fd, fd_name); - } -#endif - gpr_free(fd_name); - - new_fd->track_err = track_err; - return new_fd; + return new (new_fd) grpc_fd(fd, name, track_err); } static int fd_wrapped_fd(grpc_fd* fd) { @@ -475,7 +432,6 @@ static void fd_orphan(grpc_fd* fd, grpc_closure* on_done, int* release_fd, // true so that the pollable will no longer access its owner_fd field. gpr_mu_lock(&fd->pollable_mu); pollable* pollable_obj = fd->pollable_obj; - gpr_mu_unlock(&fd->pollable_mu); if (pollable_obj) { gpr_mu_lock(&pollable_obj->owner_orphan_mu); @@ -487,6 +443,17 @@ static void fd_orphan(grpc_fd* fd, grpc_closure* on_done, int* release_fd, /* If release_fd is not NULL, we should be relinquishing control of the file descriptor fd->fd (but we still own the grpc_fd structure). */ if (release_fd != nullptr) { + // Remove the FD from all epolls sets, before releasing it. + // Otherwise, we will receive epoll events after we release the FD. + epoll_event ev_fd; + memset(&ev_fd, 0, sizeof(ev_fd)); + if (pollable_obj != nullptr) { // For PO_FD. + epoll_ctl(pollable_obj->epfd, EPOLL_CTL_DEL, fd->fd, &ev_fd); + } + for (size_t i = 0; i < fd->pollset_fds.size(); ++i) { // For PO_MULTI. + const int epfd = fd->pollset_fds[i]; + epoll_ctl(epfd, EPOLL_CTL_DEL, fd->fd, &ev_fd); + } *release_fd = fd->fd; } else { close(fd->fd); @@ -508,40 +475,58 @@ static void fd_orphan(grpc_fd* fd, grpc_closure* on_done, int* release_fd, gpr_mu_unlock(&pollable_obj->owner_orphan_mu); } + gpr_mu_unlock(&fd->pollable_mu); gpr_mu_unlock(&fd->orphan_mu); UNREF_BY(fd, 2, reason); /* Drop the reference */ } static bool fd_is_shutdown(grpc_fd* fd) { - return fd->read_closure->IsShutdown(); + return fd->read_closure.IsShutdown(); } /* Might be called multiple times */ static void fd_shutdown(grpc_fd* fd, grpc_error* why) { - if (fd->read_closure->SetShutdown(GRPC_ERROR_REF(why))) { + if (fd->read_closure.SetShutdown(GRPC_ERROR_REF(why))) { if (shutdown(fd->fd, SHUT_RDWR)) { if (errno != ENOTCONN) { gpr_log(GPR_ERROR, "Error shutting down fd %d. errno: %d", grpc_fd_wrapped_fd(fd), errno); } } - fd->write_closure->SetShutdown(GRPC_ERROR_REF(why)); - fd->error_closure->SetShutdown(GRPC_ERROR_REF(why)); + fd->write_closure.SetShutdown(GRPC_ERROR_REF(why)); + fd->error_closure.SetShutdown(GRPC_ERROR_REF(why)); } GRPC_ERROR_UNREF(why); } static void fd_notify_on_read(grpc_fd* fd, grpc_closure* closure) { - fd->read_closure->NotifyOn(closure); + fd->read_closure.NotifyOn(closure); } static void fd_notify_on_write(grpc_fd* fd, grpc_closure* closure) { - fd->write_closure->NotifyOn(closure); + fd->write_closure.NotifyOn(closure); } static void fd_notify_on_error(grpc_fd* fd, grpc_closure* closure) { - fd->error_closure->NotifyOn(closure); + fd->error_closure.NotifyOn(closure); +} + +static bool fd_has_pollset(grpc_fd* fd, grpc_pollset* pollset) { + const int epfd = pollset->active_pollable->epfd; + grpc_core::MutexLock lock(&fd->pollable_mu); + for (size_t i = 0; i < fd->pollset_fds.size(); ++i) { + if (fd->pollset_fds[i] == epfd) { + return true; + } + } + return false; +} + +static void fd_add_pollset(grpc_fd* fd, grpc_pollset* pollset) { + const int epfd = pollset->active_pollable->epfd; + grpc_core::MutexLock lock(&fd->pollable_mu); + fd->pollset_fds.push_back(epfd); } /******************************************************************************* @@ -594,8 +579,6 @@ static grpc_error* pollable_create(pollable_type type, pollable** p) { (*p)->root_worker = nullptr; (*p)->event_cursor = 0; (*p)->event_count = 0; - (*p)->fd_cache_size = 0; - (*p)->fd_cache_counter = 0; return GRPC_ERROR_NONE; } @@ -603,7 +586,7 @@ static grpc_error* pollable_create(pollable_type type, pollable** p) { static pollable* pollable_ref(pollable* p) { #else static pollable* pollable_ref(pollable* p, int line, const char* reason) { - if (grpc_trace_pollable_refcount.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_trace_pollable_refcount)) { int r = static_cast gpr_atm_no_barrier_load(&p->refs.count); gpr_log(__FILE__, line, GPR_LOG_SEVERITY_DEBUG, "POLLABLE:%p ref %d->%d %s", p, r, r + 1, reason); @@ -618,7 +601,7 @@ static void pollable_unref(pollable* p) { #else static void pollable_unref(pollable* p, int line, const char* reason) { if (p == nullptr) return; - if (grpc_trace_pollable_refcount.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_trace_pollable_refcount)) { int r = static_cast gpr_atm_no_barrier_load(&p->refs.count); gpr_log(__FILE__, line, GPR_LOG_SEVERITY_DEBUG, "POLLABLE:%p unref %d->%d %s", p, r, r - 1, reason); @@ -629,6 +612,7 @@ static void pollable_unref(pollable* p, int line, const char* reason) { close(p->epfd); grpc_wakeup_fd_destroy(&p->wakeup); gpr_mu_destroy(&p->owner_orphan_mu); + gpr_mu_destroy(&p->mu); gpr_free(p); } } @@ -637,40 +621,7 @@ static grpc_error* pollable_add_fd(pollable* p, grpc_fd* fd) { grpc_error* error = GRPC_ERROR_NONE; static const char* err_desc = "pollable_add_fd"; const int epfd = p->epfd; - gpr_mu_lock(&p->mu); - p->fd_cache_counter++; - - // Handle the case of overflow for our cache counter by - // reseting the recency-counter on all cache objects - if (p->fd_cache_counter == 0) { - for (int i = 0; i < p->fd_cache_size; i++) { - p->fd_cache[i].last_used = 0; - } - } - - int lru_idx = 0; - for (int i = 0; i < p->fd_cache_size; i++) { - if (p->fd_cache[i].fd == fd->fd && p->fd_cache[i].salt == fd->salt) { - GRPC_STATS_INC_POLLSET_FD_CACHE_HITS(); - p->fd_cache[i].last_used = p->fd_cache_counter; - gpr_mu_unlock(&p->mu); - return GRPC_ERROR_NONE; - } else if (p->fd_cache[i].last_used < p->fd_cache[lru_idx].last_used) { - lru_idx = i; - } - } - - // Add to cache - if (p->fd_cache_size < MAX_FDS_IN_CACHE) { - lru_idx = p->fd_cache_size; - p->fd_cache_size++; - } - p->fd_cache[lru_idx].fd = fd->fd; - p->fd_cache[lru_idx].salt = fd->salt; - p->fd_cache[lru_idx].last_used = p->fd_cache_counter; - gpr_mu_unlock(&p->mu); - - if (grpc_polling_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { gpr_log(GPR_INFO, "add fd %p (%d) to pollable %p", fd, fd->fd, p); } @@ -718,7 +669,7 @@ static void pollset_global_shutdown(void) { /* pollset->mu must be held while calling this function */ static void pollset_maybe_finish_shutdown(grpc_pollset* pollset) { - if (grpc_polling_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { gpr_log(GPR_INFO, "PS:%p (pollable:%p) maybe_finish_shutdown sc=%p (target:!NULL) " "rw=%p (target:NULL) cpsc=%d (target:0)", @@ -743,14 +694,14 @@ static grpc_error* kick_one_worker(grpc_pollset_worker* specific_worker) { grpc_core::MutexLock lock(&p->mu); GPR_ASSERT(specific_worker != nullptr); if (specific_worker->kicked) { - if (grpc_polling_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { 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()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { gpr_log(GPR_INFO, "PS:%p kicked_specific_but_awake", p); } GRPC_STATS_INC_POLLSET_KICK_OWN_THREAD(); @@ -759,7 +710,7 @@ static grpc_error* kick_one_worker(grpc_pollset_worker* specific_worker) { } if (specific_worker == p->root_worker) { GRPC_STATS_INC_POLLSET_KICK_WAKEUP_FD(); - if (grpc_polling_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { gpr_log(GPR_INFO, "PS:%p kicked_specific_via_wakeup_fd", p); } specific_worker->kicked = true; @@ -768,7 +719,7 @@ static grpc_error* kick_one_worker(grpc_pollset_worker* specific_worker) { } if (specific_worker->initialized_cv) { GRPC_STATS_INC_POLLSET_KICK_WAKEUP_CV(); - if (grpc_polling_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { gpr_log(GPR_INFO, "PS:%p kicked_specific_via_cv", p); } specific_worker->kicked = true; @@ -784,7 +735,7 @@ static grpc_error* pollset_kick(grpc_pollset* pollset, grpc_pollset_worker* specific_worker) { GPR_TIMER_SCOPE("pollset_kick", 0); GRPC_STATS_INC_POLLSET_KICK(); - if (grpc_polling_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { gpr_log(GPR_INFO, "PS:%p kick %p tls_pollset=%p tls_worker=%p pollset.root_worker=%p", pollset, specific_worker, @@ -794,7 +745,7 @@ static grpc_error* pollset_kick(grpc_pollset* pollset, if (specific_worker == nullptr) { if (gpr_tls_get(&g_current_thread_pollset) != (intptr_t)pollset) { if (pollset->root_worker == nullptr) { - if (grpc_polling_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { gpr_log(GPR_INFO, "PS:%p kicked_any_without_poller", pollset); } GRPC_STATS_INC_POLLSET_KICKED_WITHOUT_POLLER(); @@ -820,7 +771,7 @@ static grpc_error* pollset_kick(grpc_pollset* pollset, pollset->root_worker->links[PWLINK_POLLSET].next); } } else { - if (grpc_polling_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { gpr_log(GPR_INFO, "PS:%p kicked_any_but_awake", pollset); } GRPC_STATS_INC_POLLSET_KICK_OWN_THREAD(); @@ -849,6 +800,7 @@ static grpc_error* pollset_kick_all(grpc_pollset* pollset) { static void pollset_init(grpc_pollset* pollset, gpr_mu** mu) { gpr_mu_init(&pollset->mu); gpr_atm_no_barrier_store(&pollset->worker_count, 0); + gpr_atm_no_barrier_store(&pollset->active_pollable_type, PO_EMPTY); pollset->active_pollable = POLLABLE_REF(g_empty_pollable, "pollset"); pollset->kicked_without_poller = false; pollset->shutdown_closure = nullptr; @@ -869,11 +821,11 @@ static int poll_deadline_to_millis_timeout(grpc_millis millis) { return static_cast(delta); } -static void fd_become_readable(grpc_fd* fd) { fd->read_closure->SetReady(); } +static void fd_become_readable(grpc_fd* fd) { fd->read_closure.SetReady(); } -static void fd_become_writable(grpc_fd* fd) { fd->write_closure->SetReady(); } +static void fd_become_writable(grpc_fd* fd) { fd->write_closure.SetReady(); } -static void fd_has_errors(grpc_fd* fd) { fd->error_closure->SetReady(); } +static void fd_has_errors(grpc_fd* fd) { fd->error_closure.SetReady(); } /* Get the pollable_obj attached to this fd. If none is attached, create a new * pollable object (of type PO_FD), attach it to the fd and return it @@ -939,7 +891,7 @@ static grpc_error* pollable_process_events(grpc_pollset* pollset, struct epoll_event* ev = &pollable_obj->events[n]; void* data_ptr = ev->data.ptr; if (1 & (intptr_t)data_ptr) { - if (grpc_polling_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { gpr_log(GPR_INFO, "PS:%p got pollset_wakeup %p", pollset, data_ptr); } append_error(&error, @@ -957,7 +909,7 @@ static grpc_error* pollable_process_events(grpc_pollset* pollset, bool write_ev = (ev->events & EPOLLOUT) != 0; bool err_fallback = error && !track_err; - if (grpc_polling_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { gpr_log(GPR_INFO, "PS:%p got fd %p: cancel=%d read=%d " "write=%d", @@ -989,7 +941,7 @@ static grpc_error* pollable_epoll(pollable* p, grpc_millis deadline) { GPR_TIMER_SCOPE("pollable_epoll", 0); int timeout = poll_deadline_to_millis_timeout(deadline); - if (grpc_polling_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { char* desc = pollable_desc(p); gpr_log(GPR_INFO, "POLLABLE:%p[%s] poll for %dms", p, desc, timeout); gpr_free(desc); @@ -1009,7 +961,7 @@ static grpc_error* pollable_epoll(pollable* p, grpc_millis deadline) { if (r < 0) return GRPC_OS_ERROR(errno, "epoll_wait"); - if (grpc_polling_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { gpr_log(GPR_INFO, "POLLABLE:%p got %d events", p, r); } @@ -1079,7 +1031,7 @@ static bool begin_worker(grpc_pollset* pollset, grpc_pollset_worker* worker, worker->initialized_cv = true; gpr_cv_init(&worker->cv); gpr_mu_unlock(&pollset->mu); - if (grpc_polling_trace.enabled() && + if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace) && worker->pollable_obj->root_worker != worker) { gpr_log(GPR_INFO, "PS:%p wait %p w=%p for %dms", pollset, worker->pollable_obj, worker, @@ -1088,18 +1040,18 @@ static bool begin_worker(grpc_pollset* pollset, grpc_pollset_worker* worker, while (do_poll && worker->pollable_obj->root_worker != worker) { if (gpr_cv_wait(&worker->cv, &worker->pollable_obj->mu, grpc_millis_to_timespec(deadline, GPR_CLOCK_REALTIME))) { - if (grpc_polling_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { 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()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { gpr_log(GPR_INFO, "PS:%p wakeup %p w=%p", pollset, worker->pollable_obj, worker); } do_poll = false; - } else if (grpc_polling_trace.enabled() && + } else if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace) && worker->pollable_obj->root_worker != worker) { gpr_log(GPR_INFO, "PS:%p spurious_wakeup %p w=%p", pollset, worker->pollable_obj, worker); @@ -1172,7 +1124,7 @@ static grpc_error* pollset_work(grpc_pollset* pollset, #ifndef NDEBUG WORKER_PTR->originator = gettid(); #endif - if (grpc_polling_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { gpr_log(GPR_INFO, "PS:%p work hdl=%p worker=%p now=%" PRId64 " deadline=%" PRId64 " kwp=%d pollable=%p", @@ -1213,7 +1165,7 @@ static grpc_error* pollset_transition_pollable_from_empty_to_fd_locked( grpc_pollset* pollset, grpc_fd* fd) { static const char* err_desc = "pollset_transition_pollable_from_empty_to_fd"; grpc_error* error = GRPC_ERROR_NONE; - if (grpc_polling_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { gpr_log(GPR_INFO, "PS:%p add fd %p (%d); transition pollable from empty to fd", pollset, fd, fd->fd); @@ -1229,7 +1181,7 @@ static grpc_error* pollset_transition_pollable_from_fd_to_multi_locked( grpc_pollset* pollset, grpc_fd* and_add_fd) { static const char* err_desc = "pollset_transition_pollable_from_fd_to_multi"; grpc_error* error = GRPC_ERROR_NONE; - if (grpc_polling_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { gpr_log( GPR_INFO, "PS:%p add fd %p (%d); transition pollable from fd %p to multipoller", @@ -1283,6 +1235,8 @@ static grpc_error* pollset_add_fd_locked(grpc_pollset* pollset, grpc_fd* fd) { POLLABLE_UNREF(pollset->active_pollable, "pollset"); pollset->active_pollable = po_at_start; } else { + gpr_atm_rel_store(&pollset->active_pollable_type, + pollset->active_pollable->type); POLLABLE_UNREF(po_at_start, "pollset_add_fd"); } return error; @@ -1299,7 +1253,7 @@ static grpc_error* pollset_as_multipollable_locked(grpc_pollset* pollset, error = pollable_create(PO_MULTI, &pollset->active_pollable); /* 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()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { gpr_log(GPR_INFO, "PS:%p active pollable transition from empty to multi", pollset); @@ -1329,6 +1283,8 @@ static grpc_error* pollset_as_multipollable_locked(grpc_pollset* pollset, pollset->active_pollable = po_at_start; *pollable_obj = nullptr; } else { + gpr_atm_rel_store(&pollset->active_pollable_type, + pollset->active_pollable->type); *pollable_obj = POLLABLE_REF(pollset->active_pollable, "pollset_set"); POLLABLE_UNREF(po_at_start, "pollset_as_multipollable"); } @@ -1337,9 +1293,23 @@ static grpc_error* pollset_as_multipollable_locked(grpc_pollset* pollset, static void pollset_add_fd(grpc_pollset* pollset, grpc_fd* fd) { GPR_TIMER_SCOPE("pollset_add_fd", 0); - gpr_mu_lock(&pollset->mu); + + // We never transition from PO_MULTI to other modes (i.e., PO_FD or PO_EMPTY) + // and, thus, it is safe to simply store and check whether the FD has already + // been added to the active pollable previously. + if (gpr_atm_acq_load(&pollset->active_pollable_type) == PO_MULTI && + fd_has_pollset(fd, pollset)) { + return; + } + + grpc_core::MutexLock lock(&pollset->mu); grpc_error* error = pollset_add_fd_locked(pollset, fd); - gpr_mu_unlock(&pollset->mu); + + // If we are in PO_MULTI mode, we should update the pollsets of the FD. + if (gpr_atm_no_barrier_load(&pollset->active_pollable_type) == PO_MULTI) { + fd_add_pollset(fd, pollset); + } + GRPC_LOG_IF_ERROR("pollset_add_fd", error); } @@ -1387,7 +1357,7 @@ static void pollset_set_unref(grpc_pollset_set* pss) { 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()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { gpr_log(GPR_INFO, "PSS:%p: add fd %p (%d)", pss, fd, fd->fd); } grpc_error* error = GRPC_ERROR_NONE; @@ -1411,7 +1381,7 @@ static void pollset_set_add_fd(grpc_pollset_set* pss, grpc_fd* fd) { 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()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { gpr_log(GPR_INFO, "PSS:%p: del fd %p", pss, fd); } pss = pss_lock_adam(pss); @@ -1432,7 +1402,7 @@ static void pollset_set_del_fd(grpc_pollset_set* pss, grpc_fd* fd) { 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()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { gpr_log(GPR_INFO, "PSS:%p: del pollset %p", pss, ps); } pss = pss_lock_adam(pss); @@ -1484,7 +1454,7 @@ static grpc_error* add_fds_to_pollsets(grpc_fd** fds, size_t fd_count, 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()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { gpr_log(GPR_INFO, "PSS:%p: add pollset %p", pss, ps); } grpc_error* error = GRPC_ERROR_NONE; @@ -1521,7 +1491,7 @@ static void pollset_set_add_pollset(grpc_pollset_set* pss, grpc_pollset* ps) { static void pollset_set_add_pollset_set(grpc_pollset_set* a, grpc_pollset_set* b) { GPR_TIMER_SCOPE("pollset_set_add_pollset_set", 0); - if (grpc_polling_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { gpr_log(GPR_INFO, "PSS: merge (%p, %p)", a, b); } grpc_error* error = GRPC_ERROR_NONE; @@ -1555,7 +1525,7 @@ static void pollset_set_add_pollset_set(grpc_pollset_set* a, if (b_size > a_size) { GPR_SWAP(grpc_pollset_set*, a, b); } - if (grpc_polling_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { gpr_log(GPR_INFO, "PSS: parent %p to %p", b, a); } gpr_ref(&a->refs); @@ -1604,6 +1574,15 @@ static void pollset_set_del_pollset_set(grpc_pollset_set* bag, * Event engine binding */ +static bool is_any_background_poller_thread(void) { return false; } + +static void shutdown_background_closure(void) {} + +static bool add_closure_to_background_poller(grpc_closure* closure, + grpc_error* error) { + return false; +} + static void shutdown_engine(void) { fd_global_shutdown(); pollset_global_shutdown(); @@ -1612,6 +1591,7 @@ static void shutdown_engine(void) { static const grpc_event_engine_vtable vtable = { sizeof(grpc_pollset), true, + false, fd_create, fd_wrapped_fd, @@ -1641,7 +1621,10 @@ static const grpc_event_engine_vtable vtable = { pollset_set_add_fd, pollset_set_del_fd, + is_any_background_poller_thread, + shutdown_background_closure, shutdown_engine, + add_closure_to_background_poller, }; const grpc_event_engine_vtable* grpc_init_epollex_linux( diff --git a/src/core/lib/iomgr/ev_poll_posix.cc b/src/core/lib/iomgr/ev_poll_posix.cc index 16562538a63..cee6dcbe530 100644 --- a/src/core/lib/iomgr/ev_poll_posix.cc +++ b/src/core/lib/iomgr/ev_poll_posix.cc @@ -43,7 +43,6 @@ #include "src/core/lib/gprpp/thd.h" #include "src/core/lib/iomgr/block_annotate.h" #include "src/core/lib/iomgr/iomgr_internal.h" -#include "src/core/lib/iomgr/wakeup_fd_cv.h" #include "src/core/lib/iomgr/wakeup_fd_posix.h" #include "src/core/lib/profiling/timers.h" @@ -126,7 +125,7 @@ struct grpc_fd { grpc_fork_fd_list* fork_fd_list; }; -/* True when GRPC_ENABLE_FORK_SUPPORT=1. We do not support fork with poll-cv */ +/* True when GRPC_ENABLE_FORK_SUPPORT=1. */ static bool track_fds_for_fork = false; /* Only used when GRPC_ENABLE_FORK_SUPPORT=1 */ @@ -256,56 +255,6 @@ struct grpc_pollset_set { grpc_fd** fds; }; -/******************************************************************************* - * condition variable polling definitions - */ - -#define POLLCV_THREAD_GRACE_MS 1000 -#define CV_POLL_PERIOD_MS 1000 -#define CV_DEFAULT_TABLE_SIZE 16 - -typedef struct poll_result { - gpr_refcount refcount; - grpc_cv_node* watchers; - int watchcount; - struct pollfd* fds; - nfds_t nfds; - int retval; - int err; - int completed; -} poll_result; - -typedef struct poll_args { - grpc_core::Thread poller_thd; - gpr_cv trigger; - int trigger_set; - bool harvestable; - gpr_cv harvest; - bool joinable; - gpr_cv join; - struct pollfd* fds; - nfds_t nfds; - poll_result* result; - struct poll_args* next; - struct poll_args* prev; -} poll_args; - -// This is a 2-tiered cache, we mantain a hash table -// of active poll calls, so we can wait on the result -// of that call. We also maintain freelists of inactive -// poll args and of dead poller threads. -typedef struct poll_hash_table { - poll_args* free_pollers; - poll_args** active_pollers; - poll_args* dead_pollers; - unsigned int size; - unsigned int count; -} poll_hash_table; - -// TODO(kpayson64): Eliminate use of global non-POD variables -poll_hash_table poll_cache; -grpc_cv_fd_table g_cvfds; - /******************************************************************************* * functions to track opened fds. No-ops unless track_fds_for_fork is true. */ @@ -367,7 +316,7 @@ static void fork_fd_list_add_wakeup_fd(grpc_cached_wakeup_fd* fd) { #define UNREF_BY(fd, n, reason) unref_by(fd, n, reason, __FILE__, __LINE__) static void ref_by(grpc_fd* fd, int n, const char* reason, const char* file, int line) { - if (grpc_trace_fd_refcount.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_trace_fd_refcount)) { gpr_log(GPR_DEBUG, "FD %d %p ref %d %" PRIdPTR " -> %" PRIdPTR " [%s; %s:%d]", fd->fd, fd, n, gpr_atm_no_barrier_load(&fd->refst), @@ -384,7 +333,7 @@ static void ref_by(grpc_fd* fd, int n) { #ifndef NDEBUG static void unref_by(grpc_fd* fd, int n, const char* reason, const char* file, int line) { - if (grpc_trace_fd_refcount.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_trace_fd_refcount)) { gpr_log(GPR_DEBUG, "FD %d %p unref %d %" PRIdPTR " -> %" PRIdPTR " [%s; %s:%d]", fd->fd, fd, n, gpr_atm_no_barrier_load(&fd->refst), @@ -612,7 +561,7 @@ static void fd_notify_on_write(grpc_fd* fd, grpc_closure* closure) { } static void fd_notify_on_error(grpc_fd* fd, grpc_closure* closure) { - if (grpc_polling_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { gpr_log(GPR_ERROR, "Polling engine does not support tracking errors."); } GRPC_CLOSURE_SCHED(closure, GRPC_ERROR_CANCELLED); @@ -631,7 +580,7 @@ static void fd_set_writable(grpc_fd* fd) { } static void fd_set_error(grpc_fd* fd) { - if (grpc_polling_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { gpr_log(GPR_ERROR, "Polling engine does not support tracking errors."); } } @@ -1063,7 +1012,7 @@ static grpc_error* pollset_work(grpc_pollset* pollset, r = grpc_poll_function(pfds, pfd_count, timeout); GRPC_SCHEDULING_END_BLOCKING_REGION; - if (grpc_polling_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { gpr_log(GPR_INFO, "%p poll=%d", pollset, r); } @@ -1087,7 +1036,7 @@ static grpc_error* pollset_work(grpc_pollset* pollset, } } else { if (pfds[0].revents & POLLIN_CHECK) { - if (grpc_polling_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { gpr_log(GPR_INFO, "%p: got_wakeup", pollset); } work_combine_error( @@ -1097,7 +1046,7 @@ static grpc_error* pollset_work(grpc_pollset* pollset, if (watchers[i].fd == nullptr) { fd_end_poll(&watchers[i], 0, 0); } else { - if (grpc_polling_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { 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); @@ -1363,430 +1312,21 @@ static void pollset_set_del_fd(grpc_pollset_set* pollset_set, grpc_fd* fd) { gpr_mu_unlock(&pollset_set->mu); } -/******************************************************************************* - * Condition Variable polling extensions - */ - -static void run_poll(void* args); -static void cache_poller_locked(poll_args* args); -static void cache_harvest_locked(); - -static void cache_insert_locked(poll_args* args) { - uint32_t key = gpr_murmur_hash3(args->fds, args->nfds * sizeof(struct pollfd), - 0xDEADBEEF); - key = key % poll_cache.size; - if (poll_cache.active_pollers[key]) { - poll_cache.active_pollers[key]->prev = args; - } - args->next = poll_cache.active_pollers[key]; - args->prev = nullptr; - poll_cache.active_pollers[key] = args; - poll_cache.count++; -} - -static void init_result(poll_args* pargs) { - pargs->result = static_cast(gpr_malloc(sizeof(poll_result))); - gpr_ref_init(&pargs->result->refcount, 1); - pargs->result->watchers = nullptr; - pargs->result->watchcount = 0; - pargs->result->fds = static_cast( - gpr_malloc(sizeof(struct pollfd) * pargs->nfds)); - memcpy(pargs->result->fds, pargs->fds, sizeof(struct pollfd) * pargs->nfds); - pargs->result->nfds = pargs->nfds; - pargs->result->retval = 0; - pargs->result->err = 0; - pargs->result->completed = 0; -} - -// Creates a poll_args object for a given arguments to poll(). -// This object may return a poll_args in the cache. -static poll_args* get_poller_locked(struct pollfd* fds, nfds_t count) { - uint32_t key = - gpr_murmur_hash3(fds, count * sizeof(struct pollfd), 0xDEADBEEF); - key = key % poll_cache.size; - poll_args* curr = poll_cache.active_pollers[key]; - while (curr) { - if (curr->nfds == count && - memcmp(curr->fds, fds, count * sizeof(struct pollfd)) == 0) { - gpr_free(fds); - return curr; - } - curr = curr->next; - } - - if (poll_cache.free_pollers) { - poll_args* pargs = poll_cache.free_pollers; - poll_cache.free_pollers = pargs->next; - if (poll_cache.free_pollers) { - poll_cache.free_pollers->prev = nullptr; - } - pargs->fds = fds; - pargs->nfds = count; - pargs->next = nullptr; - pargs->prev = nullptr; - init_result(pargs); - cache_poller_locked(pargs); - return pargs; - } - - poll_args* pargs = - static_cast(gpr_malloc(sizeof(struct poll_args))); - gpr_cv_init(&pargs->trigger); - gpr_cv_init(&pargs->harvest); - gpr_cv_init(&pargs->join); - pargs->harvestable = false; - pargs->joinable = false; - pargs->fds = fds; - pargs->nfds = count; - pargs->next = nullptr; - pargs->prev = nullptr; - pargs->trigger_set = 0; - init_result(pargs); - cache_poller_locked(pargs); - gpr_ref(&g_cvfds.pollcount); - pargs->poller_thd = grpc_core::Thread("grpc_poller", &run_poll, pargs); - pargs->poller_thd.Start(); - return pargs; -} - -static void cache_delete_locked(poll_args* args) { - if (!args->prev) { - uint32_t key = gpr_murmur_hash3( - args->fds, args->nfds * sizeof(struct pollfd), 0xDEADBEEF); - key = key % poll_cache.size; - GPR_ASSERT(poll_cache.active_pollers[key] == args); - poll_cache.active_pollers[key] = args->next; - } else { - args->prev->next = args->next; - } - - if (args->next) { - args->next->prev = args->prev; - } - - poll_cache.count--; - if (poll_cache.free_pollers) { - poll_cache.free_pollers->prev = args; - } - args->prev = nullptr; - args->next = poll_cache.free_pollers; - gpr_free(args->fds); - poll_cache.free_pollers = args; -} - -static void cache_poller_locked(poll_args* args) { - if (poll_cache.count + 1 > poll_cache.size / 2) { - poll_args** old_active_pollers = poll_cache.active_pollers; - poll_cache.size = poll_cache.size * 2; - poll_cache.count = 0; - poll_cache.active_pollers = - static_cast(gpr_malloc(sizeof(void*) * poll_cache.size)); - for (unsigned int i = 0; i < poll_cache.size; i++) { - poll_cache.active_pollers[i] = nullptr; - } - for (unsigned int i = 0; i < poll_cache.size / 2; i++) { - poll_args* curr = old_active_pollers[i]; - poll_args* next = nullptr; - while (curr) { - next = curr->next; - cache_insert_locked(curr); - curr = next; - } - } - gpr_free(old_active_pollers); - } - - cache_insert_locked(args); -} - -static void cache_destroy_locked(poll_args* args) { - if (args->next) { - args->next->prev = args->prev; - } - - if (args->prev) { - args->prev->next = args->next; - } else { - poll_cache.free_pollers = args->next; - } - - // Now move this args to the dead poller list for later join - if (poll_cache.dead_pollers != nullptr) { - poll_cache.dead_pollers->prev = args; - } - args->prev = nullptr; - args->next = poll_cache.dead_pollers; - poll_cache.dead_pollers = args; -} - -static void cache_harvest_locked() { - while (poll_cache.dead_pollers) { - poll_args* args = poll_cache.dead_pollers; - poll_cache.dead_pollers = poll_cache.dead_pollers->next; - // Keep the list consistent in case new dead pollers get added when we - // release the lock below to wait on joining - if (poll_cache.dead_pollers) { - poll_cache.dead_pollers->prev = nullptr; - } - args->harvestable = true; - gpr_cv_signal(&args->harvest); - while (!args->joinable) { - gpr_cv_wait(&args->join, &g_cvfds.mu, - gpr_inf_future(GPR_CLOCK_MONOTONIC)); - } - args->poller_thd.Join(); - gpr_free(args); - } -} - -static void decref_poll_result(poll_result* res) { - if (gpr_unref(&res->refcount)) { - GPR_ASSERT(!res->watchers); - gpr_free(res->fds); - gpr_free(res); - } -} - -void remove_cvn(grpc_cv_node** head, grpc_cv_node* target) { - if (target->next) { - target->next->prev = target->prev; - } - - if (target->prev) { - target->prev->next = target->next; - } else { - *head = target->next; - } -} - -gpr_timespec thread_grace; - -// Poll in a background thread -static void run_poll(void* args) { - poll_args* pargs = static_cast(args); - while (1) { - poll_result* result = pargs->result; - int retval = g_cvfds.poll(result->fds, result->nfds, CV_POLL_PERIOD_MS); - gpr_mu_lock(&g_cvfds.mu); - cache_harvest_locked(); - if (retval != 0) { - result->completed = 1; - result->retval = retval; - result->err = errno; - grpc_cv_node* watcher = result->watchers; - while (watcher) { - gpr_cv_signal(watcher->cv); - watcher = watcher->next; - } - } - if (result->watchcount == 0 || result->completed) { - cache_delete_locked(pargs); - decref_poll_result(result); - // Leave this polling thread alive for a grace period to do another poll() - // op - gpr_timespec deadline = gpr_now(GPR_CLOCK_MONOTONIC); - deadline = gpr_time_add(deadline, thread_grace); - pargs->trigger_set = 0; - gpr_cv_wait(&pargs->trigger, &g_cvfds.mu, deadline); - cache_harvest_locked(); - if (!pargs->trigger_set) { - cache_destroy_locked(pargs); - break; - } - } - gpr_mu_unlock(&g_cvfds.mu); - } - - if (gpr_unref(&g_cvfds.pollcount)) { - gpr_cv_signal(&g_cvfds.shutdown_cv); - } - while (!pargs->harvestable) { - gpr_cv_wait(&pargs->harvest, &g_cvfds.mu, - gpr_inf_future(GPR_CLOCK_MONOTONIC)); - } - pargs->joinable = true; - gpr_cv_signal(&pargs->join); - gpr_mu_unlock(&g_cvfds.mu); -} - -// 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; - int skip_poll = 0; - nfds_t nsockfds = 0; - poll_result* result = nullptr; - gpr_mu_lock(&g_cvfds.mu); - cache_harvest_locked(); - pollcv = static_cast(gpr_malloc(sizeof(grpc_cv_node))); - pollcv->next = nullptr; - gpr_cv pollcv_cv; - gpr_cv_init(&pollcv_cv); - pollcv->cv = &pollcv_cv; - grpc_cv_node* fd_cvs = - static_cast(gpr_malloc(nfds * sizeof(grpc_cv_node))); - - for (i = 0; i < nfds; i++) { - fds[i].revents = 0; - if (fds[i].fd < 0 && (fds[i].events & POLLIN)) { - idx = GRPC_FD_TO_IDX(fds[i].fd); - fd_cvs[i].cv = &pollcv_cv; - fd_cvs[i].prev = nullptr; - fd_cvs[i].next = g_cvfds.cvfds[idx].cvs; - if (g_cvfds.cvfds[idx].cvs) { - g_cvfds.cvfds[idx].cvs->prev = &(fd_cvs[i]); - } - g_cvfds.cvfds[idx].cvs = &(fd_cvs[i]); - // Don't bother polling if a wakeup fd is ready - if (g_cvfds.cvfds[idx].is_set) { - skip_poll = 1; - } - } else if (fds[i].fd >= 0) { - nsockfds++; - } - } - - gpr_timespec deadline = gpr_now(GPR_CLOCK_MONOTONIC); - if (timeout < 0) { - deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC); - } else { - deadline = - gpr_time_add(deadline, gpr_time_from_millis(timeout, GPR_TIMESPAN)); - } - - res = 0; - if (!skip_poll && nsockfds > 0) { - struct pollfd* pollfds = static_cast( - gpr_malloc(sizeof(struct pollfd) * nsockfds)); - idx = 0; - for (i = 0; i < nfds; i++) { - if (fds[i].fd >= 0) { - pollfds[idx].fd = fds[i].fd; - pollfds[idx].events = fds[i].events; - pollfds[idx].revents = 0; - idx++; - } - } - poll_args* pargs = get_poller_locked(pollfds, nsockfds); - result = pargs->result; - pollcv->next = result->watchers; - pollcv->prev = nullptr; - if (result->watchers) { - result->watchers->prev = pollcv; - } - result->watchers = pollcv; - result->watchcount++; - gpr_ref(&result->refcount); - - pargs->trigger_set = 1; - gpr_cv_signal(&pargs->trigger); - gpr_cv_wait(&pollcv_cv, &g_cvfds.mu, deadline); - cache_harvest_locked(); - res = result->retval; - errno = result->err; - result->watchcount--; - remove_cvn(&result->watchers, pollcv); - } else if (!skip_poll) { - gpr_cv_wait(&pollcv_cv, &g_cvfds.mu, deadline); - cache_harvest_locked(); - } - - idx = 0; - for (i = 0; i < nfds; i++) { - if (fds[i].fd < 0 && (fds[i].events & POLLIN)) { - remove_cvn(&g_cvfds.cvfds[GRPC_FD_TO_IDX(fds[i].fd)].cvs, &(fd_cvs[i])); - if (g_cvfds.cvfds[GRPC_FD_TO_IDX(fds[i].fd)].is_set) { - fds[i].revents = POLLIN; - if (res >= 0) res++; - } - } else if (!skip_poll && fds[i].fd >= 0 && result->completed) { - fds[i].revents = result->fds[idx].revents; - idx++; - } - } - - gpr_free(fd_cvs); - gpr_free(pollcv); - if (result) { - decref_poll_result(result); - } - - gpr_mu_unlock(&g_cvfds.mu); - - return res; -} - -static void global_cv_fd_table_init() { - gpr_mu_init(&g_cvfds.mu); - gpr_mu_lock(&g_cvfds.mu); - gpr_cv_init(&g_cvfds.shutdown_cv); - gpr_ref_init(&g_cvfds.pollcount, 1); - g_cvfds.size = CV_DEFAULT_TABLE_SIZE; - g_cvfds.cvfds = static_cast( - gpr_malloc(sizeof(grpc_fd_node) * CV_DEFAULT_TABLE_SIZE)); - g_cvfds.free_fds = nullptr; - thread_grace = gpr_time_from_millis(POLLCV_THREAD_GRACE_MS, GPR_TIMESPAN); - for (int i = 0; i < CV_DEFAULT_TABLE_SIZE; i++) { - g_cvfds.cvfds[i].is_set = 0; - g_cvfds.cvfds[i].cvs = nullptr; - g_cvfds.cvfds[i].next_free = g_cvfds.free_fds; - g_cvfds.free_fds = &g_cvfds.cvfds[i]; - } - // Override the poll function with one that supports cvfds - g_cvfds.poll = grpc_poll_function; - grpc_poll_function = &cvfd_poll; - - // Initialize the cache - poll_cache.size = 32; - poll_cache.count = 0; - poll_cache.free_pollers = nullptr; - poll_cache.active_pollers = - static_cast(gpr_malloc(sizeof(void*) * 32)); - for (unsigned int i = 0; i < poll_cache.size; i++) { - poll_cache.active_pollers[i] = nullptr; - } - poll_cache.dead_pollers = nullptr; - - gpr_mu_unlock(&g_cvfds.mu); -} - -static void global_cv_fd_table_shutdown() { - gpr_mu_lock(&g_cvfds.mu); - // Attempt to wait for all abandoned poll() threads to terminate - // Not doing so will result in reported memory leaks - if (!gpr_unref(&g_cvfds.pollcount)) { - int res = gpr_cv_wait(&g_cvfds.shutdown_cv, &g_cvfds.mu, - gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), - gpr_time_from_seconds(3, GPR_TIMESPAN))); - GPR_ASSERT(res == 0); - } - gpr_cv_destroy(&g_cvfds.shutdown_cv); - grpc_poll_function = g_cvfds.poll; - gpr_free(g_cvfds.cvfds); - - cache_harvest_locked(); - gpr_free(poll_cache.active_pollers); - - gpr_mu_unlock(&g_cvfds.mu); - gpr_mu_destroy(&g_cvfds.mu); -} - /******************************************************************************* * event engine binding */ +static bool is_any_background_poller_thread(void) { return false; } + +static void shutdown_background_closure(void) {} + +static bool add_closure_to_background_poller(grpc_closure* closure, + grpc_error* error) { + return false; +} + static void shutdown_engine(void) { pollset_global_shutdown(); - if (grpc_cv_wakeup_fds_enabled()) { - global_cv_fd_table_shutdown(); - } if (track_fds_for_fork) { gpr_mu_destroy(&fork_fd_list_mu); grpc_core::Fork::SetResetChildPollingEngineFunc(nullptr); @@ -1796,6 +1336,7 @@ static void shutdown_engine(void) { static const grpc_event_engine_vtable vtable = { sizeof(grpc_pollset), false, + false, fd_create, fd_wrapped_fd, @@ -1825,7 +1366,10 @@ static const grpc_event_engine_vtable vtable = { pollset_set_add_fd, pollset_set_del_fd, + is_any_background_poller_thread, + shutdown_background_closure, shutdown_engine, + add_closure_to_background_poller, }; /* Called by the child process's post-fork handler to close open fds, including @@ -1865,15 +1409,4 @@ const grpc_event_engine_vtable* grpc_init_poll_posix(bool explicit_request) { return &vtable; } -const grpc_event_engine_vtable* grpc_init_poll_cv_posix(bool explicit_request) { - global_cv_fd_table_init(); - grpc_enable_cv_wakeup_fds(1); - if (!GRPC_LOG_IF_ERROR("pollset_global_init", pollset_global_init())) { - global_cv_fd_table_shutdown(); - grpc_enable_cv_wakeup_fds(0); - return nullptr; - } - return &vtable; -} - #endif /* GRPC_POSIX_SOCKET_EV_POLL */ diff --git a/src/core/lib/iomgr/ev_posix.cc b/src/core/lib/iomgr/ev_posix.cc index 8a7dc7b004a..47cf5b83b17 100644 --- a/src/core/lib/iomgr/ev_posix.cc +++ b/src/core/lib/iomgr/ev_posix.cc @@ -36,6 +36,7 @@ #include "src/core/lib/iomgr/ev_epoll1_linux.h" #include "src/core/lib/iomgr/ev_epollex_linux.h" #include "src/core/lib/iomgr/ev_poll_posix.h" +#include "src/core/lib/iomgr/internal_errqueue.h" grpc_core::TraceFlag grpc_polling_trace(false, "polling"); /* Disabled by default */ @@ -49,7 +50,7 @@ grpc_core::DebugOnlyTraceFlag grpc_polling_api_trace(false, "polling_api"); // Polling API trace only enabled in debug builds #define GRPC_POLLING_API_TRACE(format, ...) \ - if (grpc_polling_api_trace.enabled()) { \ + if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_api_trace)) { \ gpr_log(GPR_INFO, "(polling-api) " format, __VA_ARGS__); \ } #else @@ -125,10 +126,9 @@ static event_engine_factory g_factories[] = { {ENGINE_HEAD_CUSTOM, nullptr}, {ENGINE_HEAD_CUSTOM, nullptr}, {ENGINE_HEAD_CUSTOM, nullptr}, {ENGINE_HEAD_CUSTOM, nullptr}, {"epollex", grpc_init_epollex_linux}, {"epoll1", grpc_init_epoll1_linux}, - {"poll", grpc_init_poll_posix}, {"poll-cv", grpc_init_poll_cv_posix}, - {"none", init_non_polling}, {ENGINE_TAIL_CUSTOM, nullptr}, + {"poll", grpc_init_poll_posix}, {"none", init_non_polling}, + {ENGINE_TAIL_CUSTOM, nullptr}, {ENGINE_TAIL_CUSTOM, nullptr}, {ENGINE_TAIL_CUSTOM, nullptr}, {ENGINE_TAIL_CUSTOM, nullptr}, - {ENGINE_TAIL_CUSTOM, nullptr}, }; static void add(const char* beg, const char* end, char*** ss, size_t* ns) { @@ -236,19 +236,22 @@ void grpc_event_engine_shutdown(void) { } bool grpc_event_engine_can_track_errors(void) { -/* Only track errors if platform supports errqueue. */ -#ifdef GRPC_LINUX_ERRQUEUE - return g_event_engine->can_track_err; -#else + /* Only track errors if platform supports errqueue. */ + if (grpc_core::kernel_supports_errqueue()) { + return g_event_engine->can_track_err; + } return false; -#endif /* GRPC_LINUX_ERRQUEUE */ +} + +bool grpc_event_engine_run_in_background(void) { + return g_event_engine->run_in_background; } grpc_fd* grpc_fd_create(int fd, const char* name, bool track_err) { GRPC_POLLING_API_TRACE("fd_create(%d, %s, %d)", fd, name, track_err); GRPC_FD_TRACE("fd_create(%d, %s, %d)", fd, name, track_err); - return g_event_engine->fd_create(fd, name, - track_err && g_event_engine->can_track_err); + return g_event_engine->fd_create( + fd, name, track_err && grpc_event_engine_can_track_errors()); } int grpc_fd_wrapped_fd(grpc_fd* fd) { @@ -395,4 +398,17 @@ void grpc_pollset_set_del_fd(grpc_pollset_set* pollset_set, grpc_fd* fd) { g_event_engine->pollset_set_del_fd(pollset_set, fd); } +bool grpc_is_any_background_poller_thread(void) { + return g_event_engine->is_any_background_poller_thread(); +} + +bool grpc_add_closure_to_background_poller(grpc_closure* closure, + grpc_error* error) { + return g_event_engine->add_closure_to_background_poller(closure, error); +} + +void grpc_shutdown_background_closure(void) { + g_event_engine->shutdown_background_closure(); +} + #endif // GRPC_POSIX_SOCKET_EV diff --git a/src/core/lib/iomgr/ev_posix.h b/src/core/lib/iomgr/ev_posix.h index b8fb8f534b4..0ca3a6f82fd 100644 --- a/src/core/lib/iomgr/ev_posix.h +++ b/src/core/lib/iomgr/ev_posix.h @@ -33,7 +33,7 @@ extern grpc_core::TraceFlag grpc_fd_trace; /* Disabled by default */ extern grpc_core::TraceFlag grpc_polling_trace; /* Disabled by default */ #define GRPC_FD_TRACE(format, ...) \ - if (grpc_fd_trace.enabled()) { \ + if (GRPC_TRACE_FLAG_ENABLED(grpc_fd_trace)) { \ gpr_log(GPR_INFO, "(fd-trace) " format, __VA_ARGS__); \ } @@ -42,6 +42,7 @@ typedef struct grpc_fd grpc_fd; typedef struct grpc_event_engine_vtable { size_t pollset_size; bool can_track_err; + bool run_in_background; grpc_fd* (*fd_create)(int fd, const char* name, bool track_err); int (*fd_wrapped_fd)(grpc_fd* fd); @@ -79,7 +80,11 @@ typedef struct grpc_event_engine_vtable { void (*pollset_set_add_fd)(grpc_pollset_set* pollset_set, grpc_fd* fd); void (*pollset_set_del_fd)(grpc_pollset_set* pollset_set, grpc_fd* fd); + bool (*is_any_background_poller_thread)(void); + void (*shutdown_background_closure)(void); void (*shutdown_engine)(void); + bool (*add_closure_to_background_poller)(grpc_closure* closure, + grpc_error* error); } grpc_event_engine_vtable; /* register a new event engine factory */ @@ -101,6 +106,11 @@ const char* grpc_get_poll_strategy_name(); */ bool grpc_event_engine_can_track_errors(); +/* Returns true if polling engine runs in the background, false otherwise. + * Currently only 'epollbg' runs in the background. + */ +bool grpc_event_engine_run_in_background(); + /* Create a wrapped file descriptor. Requires fd is a non-blocking file descriptor. \a track_err if true means that error events would be tracked separately @@ -174,6 +184,18 @@ void grpc_pollset_add_fd(grpc_pollset* pollset, struct grpc_fd* fd); void grpc_pollset_set_add_fd(grpc_pollset_set* pollset_set, grpc_fd* fd); void grpc_pollset_set_del_fd(grpc_pollset_set* pollset_set, grpc_fd* fd); +/* Returns true if the caller is a worker thread for any background poller. */ +bool grpc_is_any_background_poller_thread(); + +/* Returns true if the closure is registered into the background poller. Note + * that the closure may or may not run yet when this function returns, and the + * closure should not be blocking or long-running. */ +bool grpc_add_closure_to_background_poller(grpc_closure* closure, + grpc_error* error); + +/* Shut down all the closures registered in the background poller. */ +void grpc_shutdown_background_closure(); + /* override to allow tests to hook poll() usage */ typedef int (*grpc_poll_function_type)(struct pollfd*, nfds_t, int); extern grpc_poll_function_type grpc_poll_function; diff --git a/src/core/lib/iomgr/exec_ctx.cc b/src/core/lib/iomgr/exec_ctx.cc index d68fa0714bf..f45def43397 100644 --- a/src/core/lib/iomgr/exec_ctx.cc +++ b/src/core/lib/iomgr/exec_ctx.cc @@ -53,6 +53,13 @@ static void exec_ctx_sched(grpc_closure* closure, grpc_error* error) { static gpr_timespec g_start_time; +// For debug of the timer manager crash only. +// TODO (mxyan): remove after bug is fixed. +#ifdef GRPC_DEBUG_TIMER_MANAGER +extern int64_t g_start_time_sec; +extern int64_t g_start_time_nsec; +#endif // GRPC_DEBUG_TIMER_MANAGER + static grpc_millis timespec_to_millis_round_down(gpr_timespec ts) { ts = gpr_time_sub(ts, g_start_time); double x = GPR_MS_PER_SEC * static_cast(ts.tv_sec) + @@ -108,6 +115,7 @@ grpc_closure_scheduler* grpc_schedule_on_exec_ctx = &exec_ctx_scheduler; namespace grpc_core { GPR_TLS_CLASS_DEF(ExecCtx::exec_ctx_); +GPR_TLS_CLASS_DEF(ApplicationCallbackExecCtx::callback_exec_ctx_); // WARNING: for testing purposes only! void ExecCtx::TestOnlyGlobalInit(gpr_timespec new_val) { @@ -117,6 +125,12 @@ void ExecCtx::TestOnlyGlobalInit(gpr_timespec new_val) { void ExecCtx::GlobalInit(void) { g_start_time = gpr_now(GPR_CLOCK_MONOTONIC); + // For debug of the timer manager crash only. + // TODO (mxyan): remove after bug is fixed. +#ifdef GRPC_DEBUG_TIMER_MANAGER + g_start_time_sec = g_start_time.tv_sec; + g_start_time_nsec = g_start_time.tv_nsec; +#endif gpr_tls_init(&exec_ctx_); } diff --git a/src/core/lib/iomgr/exec_ctx.h b/src/core/lib/iomgr/exec_ctx.h index e90eb54cd35..daf019c41ee 100644 --- a/src/core/lib/iomgr/exec_ctx.h +++ b/src/core/lib/iomgr/exec_ctx.h @@ -21,6 +21,7 @@ #include +#include #include #include #include @@ -34,9 +35,8 @@ typedef int64_t grpc_millis; #define GRPC_MILLIS_INF_FUTURE INT64_MAX #define GRPC_MILLIS_INF_PAST INT64_MIN -/** A workqueue represents a list of work to be executed asynchronously. - Forward declared here to avoid a circular dependency with workqueue.h. */ -typedef struct grpc_workqueue grpc_workqueue; +/** A combiner represents a list of work to be executed later. + Forward declared here to avoid a circular dependency with combiner.h. */ typedef struct grpc_combiner grpc_combiner; /* This exec_ctx is ready to return: either pre-populated, or cached as soon as @@ -49,6 +49,10 @@ typedef struct grpc_combiner grpc_combiner; be counted by fork handlers */ #define GRPC_EXEC_CTX_FLAG_IS_INTERNAL_THREAD 4 +/* This application callback exec ctx was initialized by an internal thread, and + should not be counted by fork handlers */ +#define GRPC_APP_CALLBACK_EXEC_CTX_FLAG_IS_INTERNAL_THREAD 1 + extern grpc_closure_scheduler* grpc_schedule_on_exec_ctx; gpr_timespec grpc_millis_to_timespec(grpc_millis millis, gpr_clock_type clock); @@ -58,8 +62,8 @@ grpc_millis grpc_timespec_to_millis_round_up(gpr_timespec timespec); namespace grpc_core { /** Execution context. * A bag of data that collects information along a callstack. - * It is created on the stack at public API entry points, and stored internally - * as a thread-local variable. + * It is created on the stack at core entry points (public API or iomgr), and + * stored internally as a thread-local variable. * * Generally, to create an exec_ctx instance, add the following line at the top * of the public API entry point or at the start of a thread's work function : @@ -70,7 +74,7 @@ namespace grpc_core { * grpc_core::ExecCtx::Get() * * Specific responsibilities (this may grow in the future): - * - track a list of work that needs to be delayed until the top of the + * - track a list of core work that needs to be delayed until the base of the * call stack (this provides a convenient mechanism to run callbacks * without worrying about locking issues) * - provide a decision maker (via IsReadyToFinish) that provides a @@ -80,10 +84,19 @@ namespace grpc_core { * CONVENTIONS: * - Instance of this must ALWAYS be constructed on the stack, never * heap allocated. - * - Exactly one instance of ExecCtx must be created per thread. Instances must - * always be called exec_ctx. * - Do not pass exec_ctx as a parameter to a function. Always access it using * grpc_core::ExecCtx::Get(). + * - NOTE: In the future, the convention is likely to change to allow only one + * ExecCtx on a thread's stack at the same time. The TODO below + * discusses this plan in more detail. + * + * TODO(yashykt): Only allow one "active" ExecCtx on a thread at the same time. + * Stage 1: If a new one is created on the stack, it should just + * pass-through to the underlying ExecCtx deeper in the thread's + * stack. + * Stage 2: Assert if a 2nd one is ever created on the stack + * since that implies a core re-entry outside of application + * callbacks. */ class ExecCtx { public: @@ -226,6 +239,122 @@ class ExecCtx { GPR_TLS_CLASS_DECL(exec_ctx_); ExecCtx* last_exec_ctx_ = Get(); }; + +/** Application-callback execution context. + * A bag of data that collects information along a callstack. + * It is created on the stack at core entry points, and stored internally + * as a thread-local variable. + * + * There are three key differences between this structure and ExecCtx: + * 1. ApplicationCallbackExecCtx builds a list of application-level + * callbacks, but ExecCtx builds a list of internal callbacks to invoke. + * 2. ApplicationCallbackExecCtx invokes its callbacks only at destruction; + * there is no explicit Flush method. + * 3. If more than one ApplicationCallbackExecCtx is created on the thread's + * stack, only the one closest to the base of the stack is actually + * active and this is the only one that enqueues application callbacks. + * (Unlike ExecCtx, it is not feasible to prevent multiple of these on the + * stack since the executing application callback may itself enter core. + * However, the new one created will just pass callbacks through to the + * base one and those will not be executed until the return to the + * destructor of the base one, preventing unlimited stack growth.) + * + * This structure exists because application callbacks may themselves cause a + * core re-entry (e.g., through a public API call) and if that call in turn + * causes another application-callback, there could be arbitrarily growing + * stacks of core re-entries. Instead, any application callbacks instead should + * not be invoked until other core work is done and other application callbacks + * have completed. To accomplish this, any application callback should be + * enqueued using grpc_core::ApplicationCallbackExecCtx::Enqueue . + * + * CONVENTIONS: + * - Instances of this must ALWAYS be constructed on the stack, never + * heap allocated. + * - Instances of this are generally constructed before ExecCtx when needed. + * The only exception is for ExecCtx's that are explicitly flushed and + * that survive beyond the scope of the function that can cause application + * callbacks to be invoked (e.g., in the timer thread). + * + * Generally, core entry points that may trigger application-level callbacks + * will have the following declarations: + * + * grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; + * grpc_core::ExecCtx exec_ctx; + * + * This ordering is important to make sure that the ApplicationCallbackExecCtx + * is destroyed after the ExecCtx (to prevent the re-entry problem described + * above, as well as making sure that ExecCtx core callbacks are invoked first) + * + */ + +class ApplicationCallbackExecCtx { + public: + /** Default Constructor */ + ApplicationCallbackExecCtx() { Set(this, flags_); } + + /** Parameterised Constructor */ + ApplicationCallbackExecCtx(uintptr_t fl) : flags_(fl) { Set(this, flags_); } + + ~ApplicationCallbackExecCtx() { + if (reinterpret_cast( + gpr_tls_get(&callback_exec_ctx_)) == this) { + while (head_ != nullptr) { + auto* f = head_; + head_ = f->internal_next; + if (f->internal_next == nullptr) { + tail_ = nullptr; + } + (*f->functor_run)(f, f->internal_success); + } + gpr_tls_set(&callback_exec_ctx_, reinterpret_cast(nullptr)); + if (!(GRPC_APP_CALLBACK_EXEC_CTX_FLAG_IS_INTERNAL_THREAD & flags_)) { + grpc_core::Fork::DecExecCtxCount(); + } + } else { + GPR_DEBUG_ASSERT(head_ == nullptr); + GPR_DEBUG_ASSERT(tail_ == nullptr); + } + } + + static void Set(ApplicationCallbackExecCtx* exec_ctx, uintptr_t flags) { + if (reinterpret_cast( + gpr_tls_get(&callback_exec_ctx_)) == nullptr) { + if (!(GRPC_APP_CALLBACK_EXEC_CTX_FLAG_IS_INTERNAL_THREAD & flags)) { + grpc_core::Fork::IncExecCtxCount(); + } + gpr_tls_set(&callback_exec_ctx_, reinterpret_cast(exec_ctx)); + } + } + + static void Enqueue(grpc_experimental_completion_queue_functor* functor, + int is_success) { + functor->internal_success = is_success; + functor->internal_next = nullptr; + + auto* ctx = reinterpret_cast( + gpr_tls_get(&callback_exec_ctx_)); + + if (ctx->head_ == nullptr) { + ctx->head_ = functor; + } + if (ctx->tail_ != nullptr) { + ctx->tail_->internal_next = functor; + } + ctx->tail_ = functor; + } + + /** Global initialization for ApplicationCallbackExecCtx. Called by init. */ + static void GlobalInit(void) { gpr_tls_init(&callback_exec_ctx_); } + + /** Global shutdown for ApplicationCallbackExecCtx. Called by init. */ + static void GlobalShutdown(void) { gpr_tls_destroy(&callback_exec_ctx_); } + + private: + uintptr_t flags_{0u}; + grpc_experimental_completion_queue_functor* head_{nullptr}; + grpc_experimental_completion_queue_functor* tail_{nullptr}; + GPR_TLS_CLASS_DECL(callback_exec_ctx_); +}; } // namespace grpc_core #endif /* GRPC_CORE_LIB_IOMGR_EXEC_CTX_H */ diff --git a/src/core/lib/iomgr/executor.cc b/src/core/lib/iomgr/executor.cc index 45d96b80eb4..8adc0902bd1 100644 --- a/src/core/lib/iomgr/executor.cc +++ b/src/core/lib/iomgr/executor.cc @@ -32,35 +32,98 @@ #include "src/core/lib/gpr/useful.h" #include "src/core/lib/gprpp/memory.h" #include "src/core/lib/iomgr/exec_ctx.h" +#include "src/core/lib/iomgr/iomgr.h" #define MAX_DEPTH 2 -#define EXECUTOR_TRACE(format, ...) \ - if (executor_trace.enabled()) { \ - gpr_log(GPR_INFO, "EXECUTOR " format, __VA_ARGS__); \ - } +#define EXECUTOR_TRACE(format, ...) \ + do { \ + if (GRPC_TRACE_FLAG_ENABLED(executor_trace)) { \ + gpr_log(GPR_INFO, "EXECUTOR " format, __VA_ARGS__); \ + } \ + } while (0) -#define EXECUTOR_TRACE0(str) \ - if (executor_trace.enabled()) { \ - gpr_log(GPR_INFO, "EXECUTOR " str); \ - } +#define EXECUTOR_TRACE0(str) \ + do { \ + if (GRPC_TRACE_FLAG_ENABLED(executor_trace)) { \ + gpr_log(GPR_INFO, "EXECUTOR " str); \ + } \ + } while (0) -grpc_core::TraceFlag executor_trace(false, "executor"); +namespace grpc_core { +namespace { GPR_TLS_DECL(g_this_thread_state); -GrpcExecutor::GrpcExecutor(const char* name) : name_(name) { +Executor* executors[static_cast(ExecutorType::NUM_EXECUTORS)]; + +void default_enqueue_short(grpc_closure* closure, grpc_error* error) { + executors[static_cast(ExecutorType::DEFAULT)]->Enqueue( + closure, error, true /* is_short */); +} + +void default_enqueue_long(grpc_closure* closure, grpc_error* error) { + executors[static_cast(ExecutorType::DEFAULT)]->Enqueue( + closure, error, false /* is_short */); +} + +void resolver_enqueue_short(grpc_closure* closure, grpc_error* error) { + executors[static_cast(ExecutorType::RESOLVER)]->Enqueue( + closure, error, true /* is_short */); +} + +void resolver_enqueue_long(grpc_closure* closure, grpc_error* error) { + executors[static_cast(ExecutorType::RESOLVER)]->Enqueue( + closure, error, false /* is_short */); +} + +const grpc_closure_scheduler_vtable + vtables_[static_cast(ExecutorType::NUM_EXECUTORS)] + [static_cast(ExecutorJobType::NUM_JOB_TYPES)] = { + {{&default_enqueue_short, &default_enqueue_short, + "def-ex-short"}, + {&default_enqueue_long, &default_enqueue_long, "def-ex-long"}}, + {{&resolver_enqueue_short, &resolver_enqueue_short, + "res-ex-short"}, + {&resolver_enqueue_long, &resolver_enqueue_long, + "res-ex-long"}}}; + +grpc_closure_scheduler + schedulers_[static_cast(ExecutorType::NUM_EXECUTORS)] + [static_cast(ExecutorJobType::NUM_JOB_TYPES)] = { + {{&vtables_[static_cast(ExecutorType::DEFAULT)] + [static_cast(ExecutorJobType::SHORT)]}, + {&vtables_[static_cast(ExecutorType::DEFAULT)] + [static_cast(ExecutorJobType::LONG)]}}, + {{&vtables_[static_cast(ExecutorType::RESOLVER)] + [static_cast(ExecutorJobType::SHORT)]}, + {&vtables_[static_cast(ExecutorType::RESOLVER)] + [static_cast(ExecutorJobType::LONG)]}}}; + +} // namespace + +TraceFlag executor_trace(false, "executor"); + +Executor::Executor(const char* name) : name_(name) { adding_thread_lock_ = GPR_SPINLOCK_STATIC_INITIALIZER; gpr_atm_rel_store(&num_threads_, 0); max_threads_ = GPR_MAX(1, 2 * gpr_cpu_num_cores()); } -void GrpcExecutor::Init() { SetThreading(true); } +void Executor::Init() { SetThreading(true); } -size_t GrpcExecutor::RunClosures(const char* executor_name, - grpc_closure_list list) { +size_t Executor::RunClosures(const char* executor_name, + grpc_closure_list list) { size_t n = 0; + // In the executor, the ExecCtx for the thread is declared in the executor + // thread itself, but this is the point where we could start seeing + // application-level callbacks. No need to create a new ExecCtx, though, + // since there already is one and it is flushed (but not destructed) in this + // function itself. + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx( + GRPC_APP_CALLBACK_EXEC_CTX_FLAG_IS_INTERNAL_THREAD); + grpc_closure* c = list.head; while (c != nullptr) { grpc_closure* next = c->next_data.next; @@ -82,11 +145,11 @@ size_t GrpcExecutor::RunClosures(const char* executor_name, return n; } -bool GrpcExecutor::IsThreaded() const { +bool Executor::IsThreaded() const { return gpr_atm_acq_load(&num_threads_) > 0; } -void GrpcExecutor::SetThreading(bool threading) { +void Executor::SetThreading(bool threading) { gpr_atm curr_num_threads = gpr_atm_acq_load(&num_threads_); EXECUTOR_TRACE("(%s) SetThreading(%d) begin", name_, threading); @@ -112,7 +175,7 @@ void GrpcExecutor::SetThreading(bool threading) { } thd_state_[0].thd = - grpc_core::Thread(name_, &GrpcExecutor::ThreadMain, &thd_state_[0]); + grpc_core::Thread(name_, &Executor::ThreadMain, &thd_state_[0]); thd_state_[0].thd.Start(); } else { // !threading if (curr_num_threads == 0) { @@ -148,14 +211,22 @@ void GrpcExecutor::SetThreading(bool threading) { gpr_free(thd_state_); gpr_tls_destroy(&g_this_thread_state); + + // grpc_iomgr_shutdown_background_closure() will close all the registered + // fds in the background poller, and wait for all pending closures to + // finish. Thus, never call Executor::SetThreading(false) in the middle of + // an application. + // TODO(guantaol): create another method to finish all the pending closures + // registered in the background poller by grpc_core::Executor. + grpc_iomgr_shutdown_background_closure(); } EXECUTOR_TRACE("(%s) SetThreading(%d) done", name_, threading); } -void GrpcExecutor::Shutdown() { SetThreading(false); } +void Executor::Shutdown() { SetThreading(false); } -void GrpcExecutor::ThreadMain(void* arg) { +void Executor::ThreadMain(void* arg) { ThreadState* ts = static_cast(arg); gpr_tls_set(&g_this_thread_state, reinterpret_cast(ts)); @@ -192,8 +263,8 @@ void GrpcExecutor::ThreadMain(void* arg) { } } -void GrpcExecutor::Enqueue(grpc_closure* closure, grpc_error* error, - bool is_short) { +void Executor::Enqueue(grpc_closure* closure, grpc_error* error, + bool is_short) { bool retry_push; if (is_short) { GRPC_STATS_INC_EXECUTOR_SCHEDULED_SHORT_ITEMS(); @@ -220,6 +291,10 @@ void GrpcExecutor::Enqueue(grpc_closure* closure, grpc_error* error, return; } + if (grpc_iomgr_add_closure_to_background_poller(closure, error)) { + return; + } + ThreadState* ts = (ThreadState*)gpr_tls_get(&g_this_thread_state); if (ts == nullptr) { ts = &thd_state_[GPR_HASH_POINTER(grpc_core::ExecCtx::Get(), @@ -304,7 +379,7 @@ void GrpcExecutor::Enqueue(grpc_closure* closure, grpc_error* error, gpr_atm_rel_store(&num_threads_, cur_thread_count + 1); thd_state_[cur_thread_count].thd = grpc_core::Thread( - name_, &GrpcExecutor::ThreadMain, &thd_state_[cur_thread_count]); + name_, &Executor::ThreadMain, &thd_state_[cur_thread_count]); thd_state_[cur_thread_count].thd.Start(); } gpr_spinlock_unlock(&adding_thread_lock_); @@ -316,85 +391,52 @@ void GrpcExecutor::Enqueue(grpc_closure* closure, grpc_error* error, } while (retry_push); } -static GrpcExecutor* executors[GRPC_NUM_EXECUTORS]; - -void default_enqueue_short(grpc_closure* closure, grpc_error* error) { - executors[GRPC_DEFAULT_EXECUTOR]->Enqueue(closure, error, - true /* is_short */); -} - -void default_enqueue_long(grpc_closure* closure, grpc_error* error) { - executors[GRPC_DEFAULT_EXECUTOR]->Enqueue(closure, error, - false /* is_short */); -} - -void resolver_enqueue_short(grpc_closure* closure, grpc_error* error) { - executors[GRPC_RESOLVER_EXECUTOR]->Enqueue(closure, error, - true /* is_short */); -} - -void resolver_enqueue_long(grpc_closure* closure, grpc_error* error) { - executors[GRPC_RESOLVER_EXECUTOR]->Enqueue(closure, error, - false /* is_short */); -} - -static const grpc_closure_scheduler_vtable - vtables_[GRPC_NUM_EXECUTORS][GRPC_NUM_EXECUTOR_JOB_TYPES] = { - {{&default_enqueue_short, &default_enqueue_short, "def-ex-short"}, - {&default_enqueue_long, &default_enqueue_long, "def-ex-long"}}, - {{&resolver_enqueue_short, &resolver_enqueue_short, "res-ex-short"}, - {&resolver_enqueue_long, &resolver_enqueue_long, "res-ex-long"}}}; - -static grpc_closure_scheduler - schedulers_[GRPC_NUM_EXECUTORS][GRPC_NUM_EXECUTOR_JOB_TYPES] = { - {{&vtables_[GRPC_DEFAULT_EXECUTOR][GRPC_EXECUTOR_SHORT]}, - {&vtables_[GRPC_DEFAULT_EXECUTOR][GRPC_EXECUTOR_LONG]}}, - {{&vtables_[GRPC_RESOLVER_EXECUTOR][GRPC_EXECUTOR_SHORT]}, - {&vtables_[GRPC_RESOLVER_EXECUTOR][GRPC_EXECUTOR_LONG]}}}; - -// grpc_executor_init() and grpc_executor_shutdown() functions are called in the +// Executor::InitAll() and Executor::ShutdownAll() functions are called in the // the grpc_init() and grpc_shutdown() code paths which are protected by a // global mutex. So it is okay to assume that these functions are thread-safe -void grpc_executor_init() { - EXECUTOR_TRACE0("grpc_executor_init() enter"); +void Executor::InitAll() { + EXECUTOR_TRACE0("Executor::InitAll() enter"); - // Return if grpc_executor_init() is already called earlier - if (executors[GRPC_DEFAULT_EXECUTOR] != nullptr) { - GPR_ASSERT(executors[GRPC_RESOLVER_EXECUTOR] != nullptr); + // Return if Executor::InitAll() is already called earlier + if (executors[static_cast(ExecutorType::DEFAULT)] != nullptr) { + GPR_ASSERT(executors[static_cast(ExecutorType::RESOLVER)] != + nullptr); return; } - executors[GRPC_DEFAULT_EXECUTOR] = - grpc_core::New("default-executor"); - executors[GRPC_RESOLVER_EXECUTOR] = - grpc_core::New("resolver-executor"); + executors[static_cast(ExecutorType::DEFAULT)] = + grpc_core::New("default-executor"); + executors[static_cast(ExecutorType::RESOLVER)] = + grpc_core::New("resolver-executor"); - executors[GRPC_DEFAULT_EXECUTOR]->Init(); - executors[GRPC_RESOLVER_EXECUTOR]->Init(); + executors[static_cast(ExecutorType::DEFAULT)]->Init(); + executors[static_cast(ExecutorType::RESOLVER)]->Init(); - EXECUTOR_TRACE0("grpc_executor_init() done"); + EXECUTOR_TRACE0("Executor::InitAll() done"); } -grpc_closure_scheduler* grpc_executor_scheduler(GrpcExecutorType executor_type, - GrpcExecutorJobType job_type) { - return &schedulers_[executor_type][job_type]; +grpc_closure_scheduler* Executor::Scheduler(ExecutorType executor_type, + ExecutorJobType job_type) { + return &schedulers_[static_cast(executor_type)] + [static_cast(job_type)]; } -grpc_closure_scheduler* grpc_executor_scheduler(GrpcExecutorJobType job_type) { - return grpc_executor_scheduler(GRPC_DEFAULT_EXECUTOR, job_type); +grpc_closure_scheduler* Executor::Scheduler(ExecutorJobType job_type) { + return Executor::Scheduler(ExecutorType::DEFAULT, job_type); } -void grpc_executor_shutdown() { - EXECUTOR_TRACE0("grpc_executor_shutdown() enter"); +void Executor::ShutdownAll() { + EXECUTOR_TRACE0("Executor::ShutdownAll() enter"); - // Return if grpc_executor_shutdown() is already called earlier - if (executors[GRPC_DEFAULT_EXECUTOR] == nullptr) { - GPR_ASSERT(executors[GRPC_RESOLVER_EXECUTOR] == nullptr); + // Return if Executor:SshutdownAll() is already called earlier + if (executors[static_cast(ExecutorType::DEFAULT)] == nullptr) { + GPR_ASSERT(executors[static_cast(ExecutorType::RESOLVER)] == + nullptr); return; } - executors[GRPC_DEFAULT_EXECUTOR]->Shutdown(); - executors[GRPC_RESOLVER_EXECUTOR]->Shutdown(); + executors[static_cast(ExecutorType::DEFAULT)]->Shutdown(); + executors[static_cast(ExecutorType::RESOLVER)]->Shutdown(); // Delete the executor objects. // @@ -408,26 +450,36 @@ void grpc_executor_shutdown() { // By ensuring that all executors are shutdown first, we are also ensuring // that no thread is active across all executors. - grpc_core::Delete(executors[GRPC_DEFAULT_EXECUTOR]); - grpc_core::Delete(executors[GRPC_RESOLVER_EXECUTOR]); - executors[GRPC_DEFAULT_EXECUTOR] = nullptr; - executors[GRPC_RESOLVER_EXECUTOR] = nullptr; + grpc_core::Delete( + executors[static_cast(ExecutorType::DEFAULT)]); + grpc_core::Delete( + executors[static_cast(ExecutorType::RESOLVER)]); + executors[static_cast(ExecutorType::DEFAULT)] = nullptr; + executors[static_cast(ExecutorType::RESOLVER)] = nullptr; - EXECUTOR_TRACE0("grpc_executor_shutdown() done"); + EXECUTOR_TRACE0("Executor::ShutdownAll() done"); } -bool grpc_executor_is_threaded(GrpcExecutorType executor_type) { - GPR_ASSERT(executor_type < GRPC_NUM_EXECUTORS); - return executors[executor_type]->IsThreaded(); +bool Executor::IsThreaded(ExecutorType executor_type) { + GPR_ASSERT(executor_type < ExecutorType::NUM_EXECUTORS); + return executors[static_cast(executor_type)]->IsThreaded(); } -bool grpc_executor_is_threaded() { - return grpc_executor_is_threaded(GRPC_DEFAULT_EXECUTOR); +bool Executor::IsThreadedDefault() { + return Executor::IsThreaded(ExecutorType::DEFAULT); } -void grpc_executor_set_threading(bool enable) { - EXECUTOR_TRACE("grpc_executor_set_threading(%d) called", enable); - for (int i = 0; i < GRPC_NUM_EXECUTORS; i++) { +void Executor::SetThreadingAll(bool enable) { + EXECUTOR_TRACE("Executor::SetThreadingAll(%d) called", enable); + for (size_t i = 0; i < static_cast(ExecutorType::NUM_EXECUTORS); + i++) { executors[i]->SetThreading(enable); } } + +void Executor::SetThreadingDefault(bool enable) { + EXECUTOR_TRACE("Executor::SetThreadingDefault(%d) called", enable); + executors[static_cast(ExecutorType::DEFAULT)]->SetThreading(enable); +} + +} // namespace grpc_core diff --git a/src/core/lib/iomgr/executor.h b/src/core/lib/iomgr/executor.h index 8829138c5fa..a9c609bd7d5 100644 --- a/src/core/lib/iomgr/executor.h +++ b/src/core/lib/iomgr/executor.h @@ -25,7 +25,9 @@ #include "src/core/lib/gprpp/thd.h" #include "src/core/lib/iomgr/closure.h" -typedef struct { +namespace grpc_core { + +struct ThreadState { gpr_mu mu; size_t id; // For debugging purposes const char* name; // Thread state name @@ -35,24 +37,32 @@ typedef struct { bool shutdown; bool queued_long_job; grpc_core::Thread thd; -} ThreadState; +}; -typedef enum { - GRPC_EXECUTOR_SHORT = 0, - GRPC_EXECUTOR_LONG, - GRPC_NUM_EXECUTOR_JOB_TYPES // Add new values above this -} GrpcExecutorJobType; +enum class ExecutorType { + DEFAULT = 0, + RESOLVER, -class GrpcExecutor { + NUM_EXECUTORS // Add new values above this +}; + +enum class ExecutorJobType { + SHORT = 0, + LONG, + NUM_JOB_TYPES // Add new values above this +}; + +class Executor { public: - GrpcExecutor(const char* executor_name); + Executor(const char* executor_name); void Init(); /** Is the executor multi-threaded? */ bool IsThreaded() const; - /* Enable/disable threading - must be called after Init and Shutdown() */ + /* Enable/disable threading - must be called after Init and Shutdown(). Never + * call SetThreading(false) in the middle of an application */ void SetThreading(bool threading); /** Shutdown the executor, running all pending work as part of the call */ @@ -62,6 +72,40 @@ class GrpcExecutor { * a short job (i.e expected to not block and complete quickly) */ void Enqueue(grpc_closure* closure, grpc_error* error, bool is_short); + // TODO(sreek): Currently we have two executors (available globally): The + // default executor and the resolver executor. + // + // Some of the functions below operate on the DEFAULT executor only while some + // operate of ALL the executors. This is a bit confusing and should be cleaned + // up in future (where we make all the following functions take ExecutorType + // and/or JobType) + + // Initialize ALL the executors + static void InitAll(); + + // Shutdown ALL the executors + static void ShutdownAll(); + + // Set the threading mode for ALL the executors + static void SetThreadingAll(bool enable); + + // Set the threading mode for ALL the executors + static void SetThreadingDefault(bool enable); + + // Get the DEFAULT executor scheduler for the given job_type + static grpc_closure_scheduler* Scheduler(ExecutorJobType job_type); + + // Get the executor scheduler for a given executor_type and a job_type + static grpc_closure_scheduler* Scheduler(ExecutorType executor_type, + ExecutorJobType job_type); + + // Return if a given executor is running in threaded mode (i.e if + // SetThreading(true) was called previously on that executor) + static bool IsThreaded(ExecutorType executor_type); + + // Return if the DEFAULT executor is threaded + static bool IsThreadedDefault(); + private: static size_t RunClosures(const char* executor_name, grpc_closure_list list); static void ThreadMain(void* arg); @@ -73,44 +117,6 @@ class GrpcExecutor { gpr_spinlock adding_thread_lock_; }; -// == Global executor functions == - -typedef enum { - GRPC_DEFAULT_EXECUTOR = 0, - GRPC_RESOLVER_EXECUTOR, - - GRPC_NUM_EXECUTORS // Add new values above this -} GrpcExecutorType; - -// TODO(sreek): Currently we have two executors (available globally): The -// default executor and the resolver executor. -// -// Some of the functions below operate on the DEFAULT executor only while some -// operate of ALL the executors. This is a bit confusing and should be cleaned -// up in future (where we make all the following functions take executor_type -// and/or job_type) - -// Initialize ALL the executors -void grpc_executor_init(); - -// Shutdown ALL the executors -void grpc_executor_shutdown(); - -// Set the threading mode for ALL the executors -void grpc_executor_set_threading(bool enable); - -// Get the DEFAULT executor scheduler for the given job_type -grpc_closure_scheduler* grpc_executor_scheduler(GrpcExecutorJobType job_type); - -// Get the executor scheduler for a given executor_type and a job_type -grpc_closure_scheduler* grpc_executor_scheduler(GrpcExecutorType executor_type, - GrpcExecutorJobType job_type); - -// Return if a given executor is running in threaded mode (i.e if -// grpc_executor_set_threading(true) was called previously on that executor) -bool grpc_executor_is_threaded(GrpcExecutorType executor_type); - -// Return if the DEFAULT executor is threaded -bool grpc_executor_is_threaded(); +} // namespace grpc_core #endif /* GRPC_CORE_LIB_IOMGR_EXECUTOR_H */ diff --git a/src/core/lib/iomgr/fork_posix.cc b/src/core/lib/iomgr/fork_posix.cc index e957bad73d3..7f8fb7e828b 100644 --- a/src/core/lib/iomgr/fork_posix.cc +++ b/src/core/lib/iomgr/fork_posix.cc @@ -47,11 +47,13 @@ bool registered_handlers = false; } // namespace void grpc_prefork() { - grpc_core::ExecCtx exec_ctx; skipped_handler = true; + // This may be called after core shuts down, so verify initialized before + // instantiating an ExecCtx. if (!grpc_is_initialized()) { return; } + grpc_core::ExecCtx exec_ctx; if (!grpc_core::Fork::Enabled()) { gpr_log(GPR_ERROR, "Fork support not enabled; try running with the " @@ -60,7 +62,7 @@ void grpc_prefork() { } if (strcmp(grpc_get_poll_strategy_name(), "epoll1") != 0 && strcmp(grpc_get_poll_strategy_name(), "poll") != 0) { - gpr_log(GPR_ERROR, + gpr_log(GPR_INFO, "Fork support is only compatible with the epoll1 and poll polling " "strategies"); } @@ -71,7 +73,7 @@ void grpc_prefork() { return; } grpc_timer_manager_set_threading(false); - grpc_executor_set_threading(false); + grpc_core::Executor::SetThreadingAll(false); grpc_core::ExecCtx::Get()->Flush(); grpc_core::Fork::AwaitThreads(); skipped_handler = false; @@ -82,7 +84,7 @@ void grpc_postfork_parent() { grpc_core::Fork::AllowExecCtx(); grpc_core::ExecCtx exec_ctx; grpc_timer_manager_set_threading(true); - grpc_executor_set_threading(true); + grpc_core::Executor::SetThreadingAll(true); } } @@ -96,7 +98,7 @@ void grpc_postfork_child() { reset_polling_engine(); } grpc_timer_manager_set_threading(true); - grpc_executor_set_threading(true); + grpc_core::Executor::SetThreadingAll(true); } } diff --git a/src/core/lib/gprpp/atomic_with_std.h b/src/core/lib/iomgr/grpc_if_nametoindex.h similarity index 61% rename from src/core/lib/gprpp/atomic_with_std.h rename to src/core/lib/iomgr/grpc_if_nametoindex.h index a4ad16e5cf7..ed9612dcb93 100644 --- a/src/core/lib/gprpp/atomic_with_std.h +++ b/src/core/lib/iomgr/grpc_if_nametoindex.h @@ -1,6 +1,6 @@ /* * - * Copyright 2017 gRPC authors. + * 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. @@ -16,20 +16,15 @@ * */ -#ifndef GRPC_CORE_LIB_GPRPP_ATOMIC_WITH_STD_H -#define GRPC_CORE_LIB_GPRPP_ATOMIC_WITH_STD_H +#ifndef GRPC_CORE_LIB_IOMGR_GRPC_IF_NAMETOINDEX_H +#define GRPC_CORE_LIB_IOMGR_GRPC_IF_NAMETOINDEX_H #include -#include +#include -namespace grpc_core { +/* Returns the interface index corresponding to the interface "name" provided. + * Returns non-zero upon success, and zero upon failure. */ +uint32_t grpc_if_nametoindex(char* name); -template -using atomic = std::atomic; - -typedef std::memory_order memory_order; - -} // namespace grpc_core - -#endif /* GRPC_CORE_LIB_GPRPP_ATOMIC_WITH_STD_H */ +#endif /* GRPC_CORE_LIB_IOMGR_GRPC_IF_NAMETOINDEX_H */ diff --git a/src/core/lib/iomgr/grpc_if_nametoindex_posix.cc b/src/core/lib/iomgr/grpc_if_nametoindex_posix.cc new file mode 100644 index 00000000000..f1ba20dcec7 --- /dev/null +++ b/src/core/lib/iomgr/grpc_if_nametoindex_posix.cc @@ -0,0 +1,42 @@ +/* + * + * 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. + * + */ + +#include + +#include "src/core/lib/iomgr/port.h" + +#if GRPC_IF_NAMETOINDEX == 1 && defined(GRPC_POSIX_SOCKET_IF_NAMETOINDEX) + +#include "src/core/lib/iomgr/grpc_if_nametoindex.h" + +#include +#include + +#include + +uint32_t grpc_if_nametoindex(char* name) { + uint32_t out = if_nametoindex(name); + if (out == 0) { + gpr_log(GPR_DEBUG, "if_nametoindex failed for name %s. errno %d", name, + errno); + } + return out; +} + +#endif /* GRPC_IF_NAMETOINDEX == 1 && \ + defined(GRPC_POSIX_SOCKET_IF_NAMETOINDEX) */ diff --git a/src/core/lib/iomgr/network_status_tracker.h b/src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc similarity index 57% rename from src/core/lib/iomgr/network_status_tracker.h rename to src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc index 198877f60f8..08644cccf3e 100644 --- a/src/core/lib/iomgr/network_status_tracker.h +++ b/src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc @@ -16,17 +16,23 @@ * */ -#ifndef GRPC_CORE_LIB_IOMGR_NETWORK_STATUS_TRACKER_H -#define GRPC_CORE_LIB_IOMGR_NETWORK_STATUS_TRACKER_H #include -#include "src/core/lib/iomgr/endpoint.h" +#include "src/core/lib/iomgr/port.h" -void grpc_network_status_init(void); -void grpc_network_status_shutdown(void); +#if GRPC_IF_NAMETOINDEX == 0 || !defined(GRPC_POSIX_SOCKET_IF_NAMETOINDEX) -void grpc_network_status_register_endpoint(grpc_endpoint* ep); -void grpc_network_status_unregister_endpoint(grpc_endpoint* ep); -void grpc_network_status_shutdown_all_endpoints(); +#include "src/core/lib/iomgr/grpc_if_nametoindex.h" -#endif /* GRPC_CORE_LIB_IOMGR_NETWORK_STATUS_TRACKER_H */ +#include + +uint32_t grpc_if_nametoindex(char* name) { + gpr_log(GPR_DEBUG, + "Not attempting to convert interface name %s to index for current " + "platform.", + name); + return 0; +} + +#endif /* GRPC_IF_NAMETOINDEX == 0 || \ + !defined(GRPC_POSIX_SOCKET_IF_NAMETOINDEX) */ diff --git a/src/core/lib/iomgr/internal_errqueue.cc b/src/core/lib/iomgr/internal_errqueue.cc index 99c22e90555..b68c66b7575 100644 --- a/src/core/lib/iomgr/internal_errqueue.cc +++ b/src/core/lib/iomgr/internal_errqueue.cc @@ -20,17 +20,48 @@ #include "src/core/lib/iomgr/port.h" +#include #include "src/core/lib/iomgr/internal_errqueue.h" #ifdef GRPC_POSIX_SOCKET_TCP -bool kernel_supports_errqueue() { -#ifdef LINUX_VERSION_CODE -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0) - return true; -#endif /* LINUX_VERSION_CODE <= KERNEL_VERSION(4, 0, 0) */ -#endif /* LINUX_VERSION_CODE */ - return false; +#include +#include +#include +#include + +namespace grpc_core { +static bool errqueue_supported = false; + +bool kernel_supports_errqueue() { return errqueue_supported; } + +void grpc_errqueue_init() { +/* Both-compile time and run-time linux kernel versions should be at least 4.0.0 + */ +#ifdef GRPC_LINUX_ERRQUEUE + struct utsname buffer; + if (uname(&buffer) != 0) { + gpr_log(GPR_ERROR, "uname: %s", strerror(errno)); + return; + } + char* release = buffer.release; + if (release == nullptr) { + return; + } + + if (strtol(release, nullptr, 10) >= 4) { + errqueue_supported = true; + } else { + gpr_log(GPR_DEBUG, "ERRQUEUE support not enabled"); + } +#endif /* GRPC_LINUX_ERRQUEUE */ } +} /* namespace grpc_core */ + +#else + +namespace grpc_core { +void grpc_errqueue_init() {} +} /* namespace grpc_core */ #endif /* GRPC_POSIX_SOCKET_TCP */ diff --git a/src/core/lib/iomgr/internal_errqueue.h b/src/core/lib/iomgr/internal_errqueue.h index 9d122808f9b..b9fe411769f 100644 --- a/src/core/lib/iomgr/internal_errqueue.h +++ b/src/core/lib/iomgr/internal_errqueue.h @@ -37,6 +37,7 @@ #ifdef GRPC_LINUX_ERRQUEUE #include #include +#include #include #endif /* GRPC_LINUX_ERRQUEUE */ @@ -56,6 +57,12 @@ constexpr int SCM_TSTAMP_SND = 0; constexpr int SCM_TSTAMP_SCHED = 1; /* The timestamp type for when data acknowledged by peer. */ constexpr int SCM_TSTAMP_ACK = 2; + +/* Control message type containing OPT_STATS */ +#ifndef SCM_TIMESTAMPING_OPT_STATS +#define SCM_TIMESTAMPING_OPT_STATS 54 +#endif + /* Redefine required constants from */ constexpr uint32_t SOF_TIMESTAMPING_TX_SOFTWARE = 1u << 1; constexpr uint32_t SOF_TIMESTAMPING_SOFTWARE = 1u << 4; @@ -63,21 +70,122 @@ constexpr uint32_t SOF_TIMESTAMPING_OPT_ID = 1u << 7; constexpr uint32_t SOF_TIMESTAMPING_TX_SCHED = 1u << 8; constexpr uint32_t SOF_TIMESTAMPING_TX_ACK = 1u << 9; constexpr uint32_t SOF_TIMESTAMPING_OPT_TSONLY = 1u << 11; +constexpr uint32_t SOF_TIMESTAMPING_OPT_STATS = 1u << 12; -constexpr uint32_t kTimestampingSocketOptions = SOF_TIMESTAMPING_SOFTWARE | - SOF_TIMESTAMPING_OPT_ID | - SOF_TIMESTAMPING_OPT_TSONLY; +constexpr uint32_t kTimestampingSocketOptions = + SOF_TIMESTAMPING_SOFTWARE | SOF_TIMESTAMPING_OPT_ID | + SOF_TIMESTAMPING_OPT_TSONLY | SOF_TIMESTAMPING_OPT_STATS; constexpr uint32_t kTimestampingRecordingOptions = SOF_TIMESTAMPING_TX_SCHED | SOF_TIMESTAMPING_TX_SOFTWARE | SOF_TIMESTAMPING_TX_ACK; + +/* Netlink attribute types used for TCP opt stats. */ +enum TCPOptStats { + TCP_NLA_PAD, + TCP_NLA_BUSY, /* Time (usec) busy sending data. */ + TCP_NLA_RWND_LIMITED, /* Time (usec) limited by receive window. */ + TCP_NLA_SNDBUF_LIMITED, /* Time (usec) limited by send buffer. */ + TCP_NLA_DATA_SEGS_OUT, /* Data pkts sent including retransmission. */ + TCP_NLA_TOTAL_RETRANS, /* Data pkts retransmitted. */ + TCP_NLA_PACING_RATE, /* Pacing rate in Bps. */ + TCP_NLA_DELIVERY_RATE, /* Delivery rate in Bps. */ + TCP_NLA_SND_CWND, /* Sending congestion window. */ + TCP_NLA_REORDERING, /* Reordering metric. */ + TCP_NLA_MIN_RTT, /* minimum RTT. */ + TCP_NLA_RECUR_RETRANS, /* Recurring retransmits for the current pkt. */ + TCP_NLA_DELIVERY_RATE_APP_LMT, /* Delivery rate application limited? */ + TCP_NLA_SNDQ_SIZE, /* Data (bytes) pending in send queue */ + TCP_NLA_CA_STATE, /* ca_state of socket */ + TCP_NLA_SND_SSTHRESH, /* Slow start size threshold */ + TCP_NLA_DELIVERED, /* Data pkts delivered incl. out-of-order */ + TCP_NLA_DELIVERED_CE, /* Like above but only ones w/ CE marks */ + TCP_NLA_BYTES_SENT, /* Data bytes sent including retransmission */ + TCP_NLA_BYTES_RETRANS, /* Data bytes retransmitted */ + TCP_NLA_DSACK_DUPS, /* DSACK blocks received */ + TCP_NLA_REORD_SEEN, /* reordering events seen */ + TCP_NLA_SRTT, /* smoothed RTT in usecs */ +}; + +/* tcp_info from from linux/tcp.h */ +struct tcp_info { + uint8_t tcpi_state; + uint8_t tcpi_ca_state; + uint8_t tcpi_retransmits; + uint8_t tcpi_probes; + uint8_t tcpi_backoff; + uint8_t tcpi_options; + uint8_t tcpi_snd_wscale : 4, tcpi_rcv_wscale : 4; + uint8_t tcpi_delivery_rate_app_limited : 1; + uint32_t tcpi_rto; + uint32_t tcpi_ato; + uint32_t tcpi_snd_mss; + uint32_t tcpi_rcv_mss; + uint32_t tcpi_unacked; + uint32_t tcpi_sacked; + uint32_t tcpi_lost; + uint32_t tcpi_retrans; + uint32_t tcpi_fackets; + /* Times. */ + uint32_t tcpi_last_data_sent; + uint32_t tcpi_last_ack_sent; /* Not remembered, sorry. */ + uint32_t tcpi_last_data_recv; + uint32_t tcpi_last_ack_recv; + /* Metrics. */ + uint32_t tcpi_pmtu; + uint32_t tcpi_rcv_ssthresh; + uint32_t tcpi_rtt; + uint32_t tcpi_rttvar; + uint32_t tcpi_snd_ssthresh; + uint32_t tcpi_snd_cwnd; + uint32_t tcpi_advmss; + uint32_t tcpi_reordering; + uint32_t tcpi_rcv_rtt; + uint32_t tcpi_rcv_space; + uint32_t tcpi_total_retrans; + uint64_t tcpi_pacing_rate; + uint64_t tcpi_max_pacing_rate; + uint64_t tcpi_bytes_acked; /* RFC4898 tcpEStatsAppHCThruOctetsAcked */ + uint64_t tcpi_bytes_received; /* RFC4898 tcpEStatsAppHCThruOctetsReceived */ + + uint32_t tcpi_segs_out; /* RFC4898 tcpEStatsPerfSegsOut */ + uint32_t tcpi_segs_in; /* RFC4898 tcpEStatsPerfSegsIn */ + uint32_t tcpi_notsent_bytes; + uint32_t tcpi_min_rtt; + + uint32_t tcpi_data_segs_in; /* RFC4898 tcpEStatsDataSegsIn */ + uint32_t tcpi_data_segs_out; /* RFC4898 tcpEStatsDataSegsOut */ + + uint64_t tcpi_delivery_rate; + uint64_t tcpi_busy_time; /* Time (usec) busy sending data */ + uint64_t tcpi_rwnd_limited; /* Time (usec) limited by receive window */ + uint64_t tcpi_sndbuf_limited; /* Time (usec) limited by send buffer */ + + uint32_t tcpi_delivered; + uint32_t tcpi_delivered_ce; + uint64_t tcpi_bytes_sent; /* RFC4898 tcpEStatsPerfHCDataOctetsOut */ + uint64_t tcpi_bytes_retrans; /* RFC4898 tcpEStatsPerfOctetsRetrans */ + uint32_t tcpi_dsack_dups; /* RFC4898 tcpEStatsStackDSACKDups */ + uint32_t tcpi_reord_seen; /* reordering events seen */ + socklen_t length; /* Length of struct returned by kernel */ +}; + +#ifndef TCP_INFO +#define TCP_INFO 11 +#endif #endif /* GRPC_LINUX_ERRQUEUE */ /* Returns true if kernel is capable of supporting errqueue and timestamping. * Currently allowing only linux kernels above 4.0.0 */ bool kernel_supports_errqueue(); -} // namespace grpc_core + +} /* namespace grpc_core */ #endif /* GRPC_POSIX_SOCKET_TCP */ +namespace grpc_core { +/* Initializes errqueue support */ +void grpc_errqueue_init(); +} /* namespace grpc_core */ + #endif /* GRPC_CORE_LIB_IOMGR_INTERNAL_ERRQUEUE_H */ diff --git a/src/core/lib/iomgr/iomgr.cc b/src/core/lib/iomgr/iomgr.cc index 46afda17742..fd011788a06 100644 --- a/src/core/lib/iomgr/iomgr.cc +++ b/src/core/lib/iomgr/iomgr.cc @@ -29,17 +29,21 @@ #include #include -#include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/useful.h" +#include "src/core/lib/gprpp/global_config.h" #include "src/core/lib/gprpp/thd.h" +#include "src/core/lib/iomgr/buffer_list.h" #include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/iomgr/executor.h" +#include "src/core/lib/iomgr/internal_errqueue.h" #include "src/core/lib/iomgr/iomgr_internal.h" -#include "src/core/lib/iomgr/network_status_tracker.h" #include "src/core/lib/iomgr/timer.h" #include "src/core/lib/iomgr/timer_manager.h" +GPR_GLOBAL_CONFIG_DEFINE_BOOL(grpc_abort_on_leaks, false, + "Abort when leak is found"); + static gpr_mu g_mu; static gpr_cv g_rcv; static int g_shutdown; @@ -51,12 +55,12 @@ void grpc_iomgr_init() { g_shutdown = 0; gpr_mu_init(&g_mu); gpr_cv_init(&g_rcv); - grpc_executor_init(); + grpc_core::Executor::InitAll(); grpc_timer_list_init(); g_root_object.next = g_root_object.prev = &g_root_object; g_root_object.name = (char*)"root"; - grpc_network_status_init(); grpc_iomgr_platform_init(); + grpc_core::grpc_errqueue_init(); } void grpc_iomgr_start() { grpc_timer_manager_init(); } @@ -87,7 +91,7 @@ void grpc_iomgr_shutdown() { { grpc_timer_manager_shutdown(); grpc_iomgr_platform_flush(); - grpc_executor_shutdown(); + grpc_core::Executor::ShutdownAll(); gpr_mu_lock(&g_mu); g_shutdown = 1; @@ -149,11 +153,23 @@ void grpc_iomgr_shutdown() { gpr_mu_unlock(&g_mu); grpc_iomgr_platform_shutdown(); - grpc_network_status_shutdown(); gpr_mu_destroy(&g_mu); gpr_cv_destroy(&g_rcv); } +void grpc_iomgr_shutdown_background_closure() { + grpc_iomgr_platform_shutdown_background_closure(); +} + +bool grpc_iomgr_is_any_background_poller_thread() { + return grpc_iomgr_platform_is_any_background_poller_thread(); +} + +bool grpc_iomgr_add_closure_to_background_poller(grpc_closure* closure, + grpc_error* error) { + return grpc_iomgr_platform_add_closure_to_background_poller(closure, error); +} + void grpc_iomgr_register_object(grpc_iomgr_object* obj, const char* name) { obj->name = gpr_strdup(name); gpr_mu_lock(&g_mu); @@ -173,8 +189,5 @@ void grpc_iomgr_unregister_object(grpc_iomgr_object* obj) { } bool grpc_iomgr_abort_on_leaks(void) { - char* env = gpr_getenv("GRPC_ABORT_ON_LEAKS"); - bool should_we = gpr_is_true(env); - gpr_free(env); - return should_we; + return GPR_GLOBAL_CONFIG_GET(grpc_abort_on_leaks); } diff --git a/src/core/lib/iomgr/iomgr.h b/src/core/lib/iomgr/iomgr.h index 537ef8a6ffe..e02f15e551c 100644 --- a/src/core/lib/iomgr/iomgr.h +++ b/src/core/lib/iomgr/iomgr.h @@ -21,6 +21,7 @@ #include +#include "src/core/lib/iomgr/closure.h" #include "src/core/lib/iomgr/port.h" #include @@ -35,6 +36,24 @@ void grpc_iomgr_start(); * exec_ctx. */ void grpc_iomgr_shutdown(); +/** Signals the intention to shutdown all the closures registered in the + * background poller. */ +void grpc_iomgr_shutdown_background_closure(); + +/* Returns true if polling engine runs in the background, false otherwise. + * Currently only 'epollbg' runs in the background. + */ +bool grpc_iomgr_run_in_background(); + +/** Returns true if the caller is a worker thread for any background poller. */ +bool grpc_iomgr_is_any_background_poller_thread(); + +/** Returns true if the closure is registered into the background poller. Note + * that the closure may or may not run yet when this function returns, and the + * closure should not be blocking or long-running. */ +bool grpc_iomgr_add_closure_to_background_poller(grpc_closure* closure, + grpc_error* error); + /* Exposed only for testing */ size_t grpc_iomgr_count_objects_for_testing(); diff --git a/src/core/lib/iomgr/iomgr_custom.cc b/src/core/lib/iomgr/iomgr_custom.cc index d34c8e7cd14..f5ac8a0670a 100644 --- a/src/core/lib/iomgr/iomgr_custom.cc +++ b/src/core/lib/iomgr/iomgr_custom.cc @@ -34,20 +34,36 @@ gpr_thd_id g_init_thread; static void iomgr_platform_init(void) { grpc_core::ExecCtx exec_ctx; - grpc_executor_set_threading(false); + grpc_core::Executor::SetThreadingAll(false); g_init_thread = gpr_thd_currentid(); grpc_pollset_global_init(); } static void iomgr_platform_flush(void) {} static void iomgr_platform_shutdown(void) { grpc_pollset_global_shutdown(); } +static void iomgr_platform_shutdown_background_closure(void) {} +static bool iomgr_platform_is_any_background_poller_thread(void) { + return false; +} +static bool iomgr_platform_add_closure_to_background_poller( + grpc_closure* closure, grpc_error* error) { + return false; +} + +bool g_custom_iomgr_enabled = false; static grpc_iomgr_platform_vtable vtable = { - iomgr_platform_init, iomgr_platform_flush, iomgr_platform_shutdown}; + iomgr_platform_init, + iomgr_platform_flush, + iomgr_platform_shutdown, + iomgr_platform_shutdown_background_closure, + iomgr_platform_is_any_background_poller_thread, + iomgr_platform_add_closure_to_background_poller}; void grpc_custom_iomgr_init(grpc_socket_vtable* socket, grpc_custom_resolver_vtable* resolver, grpc_custom_timer_vtable* timer, grpc_custom_poller_vtable* poller) { + g_custom_iomgr_enabled = true; grpc_custom_endpoint_init(socket); grpc_custom_timer_init(timer); grpc_custom_pollset_init(poller); diff --git a/src/core/lib/iomgr/iomgr_custom.h b/src/core/lib/iomgr/iomgr_custom.h index 57cc2f9b923..e6a88843e5c 100644 --- a/src/core/lib/iomgr/iomgr_custom.h +++ b/src/core/lib/iomgr/iomgr_custom.h @@ -39,6 +39,8 @@ extern gpr_thd_id g_init_thread; #define GRPC_CUSTOM_IOMGR_ASSERT_SAME_THREAD() #endif /* GRPC_CUSTOM_IOMGR_THREAD_CHECK */ +extern bool g_custom_iomgr_enabled; + void grpc_custom_iomgr_init(grpc_socket_vtable* socket, grpc_custom_resolver_vtable* resolver, grpc_custom_timer_vtable* timer, diff --git a/src/core/lib/iomgr/iomgr_internal.cc b/src/core/lib/iomgr/iomgr_internal.cc index 32dbabb79dc..896d9fce67c 100644 --- a/src/core/lib/iomgr/iomgr_internal.cc +++ b/src/core/lib/iomgr/iomgr_internal.cc @@ -41,3 +41,17 @@ void grpc_iomgr_platform_init() { iomgr_platform_vtable->init(); } void grpc_iomgr_platform_flush() { iomgr_platform_vtable->flush(); } void grpc_iomgr_platform_shutdown() { iomgr_platform_vtable->shutdown(); } + +void grpc_iomgr_platform_shutdown_background_closure() { + iomgr_platform_vtable->shutdown_background_closure(); +} + +bool grpc_iomgr_platform_is_any_background_poller_thread() { + return iomgr_platform_vtable->is_any_background_poller_thread(); +} + +bool grpc_iomgr_platform_add_closure_to_background_poller(grpc_closure* closure, + grpc_error* error) { + return iomgr_platform_vtable->add_closure_to_background_poller(closure, + error); +} diff --git a/src/core/lib/iomgr/iomgr_internal.h b/src/core/lib/iomgr/iomgr_internal.h index b011d9c7b19..17607f98f11 100644 --- a/src/core/lib/iomgr/iomgr_internal.h +++ b/src/core/lib/iomgr/iomgr_internal.h @@ -35,6 +35,10 @@ typedef struct grpc_iomgr_platform_vtable { void (*init)(void); void (*flush)(void); void (*shutdown)(void); + void (*shutdown_background_closure)(void); + bool (*is_any_background_poller_thread)(void); + bool (*add_closure_to_background_poller)(grpc_closure* closure, + grpc_error* error); } grpc_iomgr_platform_vtable; void grpc_iomgr_register_object(grpc_iomgr_object* obj, const char* name); @@ -52,6 +56,18 @@ void grpc_iomgr_platform_flush(void); /** tear down all platform specific global iomgr structures */ void grpc_iomgr_platform_shutdown(void); +/** shut down all the closures registered in the background poller */ +void grpc_iomgr_platform_shutdown_background_closure(void); + +/** return true if the caller is a worker thread for any background poller */ +bool grpc_iomgr_platform_is_any_background_poller_thread(void); + +/** Return true if the closure is registered into the background poller. Note + * that the closure may or may not run yet when this function returns, and the + * closure should not be blocking or long-running. */ +bool grpc_iomgr_platform_add_closure_to_background_poller(grpc_closure* closure, + grpc_error* error); + bool grpc_iomgr_abort_on_leaks(void); #endif /* GRPC_CORE_LIB_IOMGR_IOMGR_INTERNAL_H */ diff --git a/src/core/lib/iomgr/iomgr_posix.cc b/src/core/lib/iomgr/iomgr_posix.cc index ca7334c9a4b..de22d20a639 100644 --- a/src/core/lib/iomgr/iomgr_posix.cc +++ b/src/core/lib/iomgr/iomgr_posix.cc @@ -51,8 +51,26 @@ static void iomgr_platform_shutdown(void) { grpc_wakeup_fd_global_destroy(); } +static void iomgr_platform_shutdown_background_closure(void) { + grpc_shutdown_background_closure(); +} + +static bool iomgr_platform_is_any_background_poller_thread(void) { + return grpc_is_any_background_poller_thread(); +} + +static bool iomgr_platform_add_closure_to_background_poller( + grpc_closure* closure, grpc_error* error) { + return grpc_add_closure_to_background_poller(closure, error); +} + static grpc_iomgr_platform_vtable vtable = { - iomgr_platform_init, iomgr_platform_flush, iomgr_platform_shutdown}; + iomgr_platform_init, + iomgr_platform_flush, + iomgr_platform_shutdown, + iomgr_platform_shutdown_background_closure, + iomgr_platform_is_any_background_poller_thread, + iomgr_platform_add_closure_to_background_poller}; void grpc_set_default_iomgr_platform() { grpc_set_tcp_client_impl(&grpc_posix_tcp_client_vtable); @@ -64,4 +82,8 @@ void grpc_set_default_iomgr_platform() { grpc_set_iomgr_platform_vtable(&vtable); } +bool grpc_iomgr_run_in_background() { + return grpc_event_engine_run_in_background(); +} + #endif /* GRPC_POSIX_SOCKET_IOMGR */ diff --git a/src/core/lib/iomgr/iomgr_posix_cfstream.cc b/src/core/lib/iomgr/iomgr_posix_cfstream.cc index 235a9e0712f..cf4d05318ea 100644 --- a/src/core/lib/iomgr/iomgr_posix_cfstream.cc +++ b/src/core/lib/iomgr/iomgr_posix_cfstream.cc @@ -54,8 +54,26 @@ static void iomgr_platform_shutdown(void) { grpc_wakeup_fd_global_destroy(); } +static void iomgr_platform_shutdown_background_closure(void) { + grpc_shutdown_background_closure(); +} + +static bool iomgr_platform_is_any_background_poller_thread(void) { + return grpc_is_any_background_poller_thread(); +} + +static bool iomgr_platform_add_closure_to_background_poller( + grpc_closure* closure, grpc_error* error) { + return grpc_add_closure_to_background_poller(closure, error); +} + static grpc_iomgr_platform_vtable vtable = { - iomgr_platform_init, iomgr_platform_flush, iomgr_platform_shutdown}; + iomgr_platform_init, + iomgr_platform_flush, + iomgr_platform_shutdown, + iomgr_platform_shutdown_background_closure, + iomgr_platform_is_any_background_poller_thread, + iomgr_platform_add_closure_to_background_poller}; void grpc_set_default_iomgr_platform() { char* enable_cfstream = getenv(grpc_cfstream_env_var); diff --git a/src/core/lib/iomgr/iomgr_windows.cc b/src/core/lib/iomgr/iomgr_windows.cc index cdef89cbf04..728d4040818 100644 --- a/src/core/lib/iomgr/iomgr_windows.cc +++ b/src/core/lib/iomgr/iomgr_windows.cc @@ -61,6 +61,7 @@ static void iomgr_platform_init(void) { winsock_init(); grpc_iocp_init(); grpc_pollset_global_init(); + grpc_wsa_socket_flags_init(); } static void iomgr_platform_flush(void) { grpc_iocp_flush(); } @@ -71,8 +72,24 @@ static void iomgr_platform_shutdown(void) { winsock_shutdown(); } +static void iomgr_platform_shutdown_background_closure(void) {} + +static bool iomgr_platform_is_any_background_poller_thread(void) { + return false; +} + +static bool iomgr_platform_add_closure_to_background_poller( + grpc_closure* closure, grpc_error* error) { + return false; +} + static grpc_iomgr_platform_vtable vtable = { - iomgr_platform_init, iomgr_platform_flush, iomgr_platform_shutdown}; + iomgr_platform_init, + iomgr_platform_flush, + iomgr_platform_shutdown, + iomgr_platform_shutdown_background_closure, + iomgr_platform_is_any_background_poller_thread, + iomgr_platform_add_closure_to_background_poller}; void grpc_set_default_iomgr_platform() { grpc_set_tcp_client_impl(&grpc_windows_tcp_client_vtable); @@ -84,4 +101,6 @@ void grpc_set_default_iomgr_platform() { grpc_set_iomgr_platform_vtable(&vtable); } +bool grpc_iomgr_run_in_background() { return false; } + #endif /* GRPC_WINSOCK_SOCKET */ diff --git a/src/core/lib/iomgr/lockfree_event.cc b/src/core/lib/iomgr/lockfree_event.cc index 085fea40a40..f0c40b4827d 100644 --- a/src/core/lib/iomgr/lockfree_event.cc +++ b/src/core/lib/iomgr/lockfree_event.cc @@ -94,7 +94,7 @@ void LockfreeEvent::NotifyOn(grpc_closure* closure) { * sure that the shutdown error has been initialized properly before us * referencing it. */ gpr_atm curr = gpr_atm_acq_load(&state_); - if (grpc_polling_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { gpr_log(GPR_ERROR, "LockfreeEvent::NotifyOn: %p curr=%p closure=%p", this, (void*)curr, closure); } @@ -160,7 +160,7 @@ bool LockfreeEvent::SetShutdown(grpc_error* shutdown_err) { while (true) { gpr_atm curr = gpr_atm_no_barrier_load(&state_); - if (grpc_polling_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { gpr_log(GPR_ERROR, "LockfreeEvent::SetShutdown: %p curr=%p err=%s", &state_, (void*)curr, grpc_error_string(shutdown_err)); } @@ -209,7 +209,7 @@ void LockfreeEvent::SetReady() { while (true) { gpr_atm curr = gpr_atm_no_barrier_load(&state_); - if (grpc_polling_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { gpr_log(GPR_ERROR, "LockfreeEvent::SetReady: %p curr=%p", &state_, (void*)curr); } diff --git a/src/core/lib/iomgr/port.h b/src/core/lib/iomgr/port.h index bf56a7298d2..d387de5b13c 100644 --- a/src/core/lib/iomgr/port.h +++ b/src/core/lib/iomgr/port.h @@ -60,10 +60,12 @@ #define GRPC_HAVE_IP_PKTINFO 1 #define GRPC_HAVE_MSG_NOSIGNAL 1 #define GRPC_HAVE_UNIX_SOCKET 1 +/* Linux has TCP_INQ support since 4.18, but it is safe to set + the socket option on older kernels. */ +#define GRPC_HAVE_TCP_INQ 1 #ifdef LINUX_VERSION_CODE #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0) -/* TODO(yashykt): Re-enable once Fathom changes are commited. -#define GRPC_LINUX_ERRQUEUE 1 */ +#define GRPC_LINUX_ERRQUEUE 1 #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0) */ #endif /* LINUX_VERSION_CODE */ #define GRPC_LINUX_MULTIPOLL_WITH_EPOLL 1 @@ -86,6 +88,15 @@ #ifdef LINUX_VERSION_CODE #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37) #define GRPC_HAVE_TCP_USER_TIMEOUT +#ifdef __GLIBC_PREREQ +#if !(__GLIBC_PREREQ(2, 17)) +/* + * TCP_USER_TIMEOUT wasn't imported to glibc until 2.17. Use Linux system + * header instead. + */ +#define GRPC_LINUX_TCP_H 1 +#endif /* __GLIBC_PREREQ(2, 17) */ +#endif /* ifdef __GLIBC_PREREQ */ #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37) */ #endif /* LINUX_VERSION_CODE */ #ifndef __GLIBC__ @@ -168,6 +179,22 @@ #define GRPC_POSIX_SOCKET 1 #define GRPC_POSIX_SOCKETUTILS 1 #define GRPC_POSIX_WAKEUP_FD 1 +#elif defined(GPR_FUCHSIA) +#define GRPC_HAVE_IFADDRS 1 +#define GRPC_HAVE_IPV6_RECVPKTINFO 1 +#define GRPC_HAVE_IP_PKTINFO 1 +// Zircon does not support the MSG_NOSIGNAL flag since it doesn't support +// signals. +#undef GRPC_HAVE_MSG_NOSIGNAL +#define GRPC_HAVE_UNIX_SOCKET 1 +#define GRPC_POSIX_WAKEUP_FD 1 +// TODO(rudominer) Check that this does something we want. +#define GRPC_POSIX_NO_SPECIAL_WAKEUP_FD 1 +#define GRPC_POSIX_SOCKET 1 +#define GRPC_POSIX_SOCKETADDR 1 +// TODO(rudominer) Check this does something we want. +#define GRPC_POSIX_SOCKETUTILS 1 +#define GRPC_TIMER_USE_GENERIC 1 #elif !defined(GPR_NO_AUTODETECT_PLATFORM) #error "Platform not recognized" #endif @@ -185,6 +212,7 @@ #define GRPC_POSIX_SOCKET_EV_EPOLLEX 1 #define GRPC_POSIX_SOCKET_EV_POLL 1 #define GRPC_POSIX_SOCKET_EV_EPOLL1 1 +#define GRPC_POSIX_SOCKET_IF_NAMETOINDEX 1 #define GRPC_POSIX_SOCKET_IOMGR 1 #define GRPC_POSIX_SOCKET_RESOLVE_ADDRESS 1 #define GRPC_POSIX_SOCKET_SOCKADDR 1 diff --git a/src/core/lib/iomgr/resolve_address.h b/src/core/lib/iomgr/resolve_address.h index 6afe94a7a92..7016ffc31aa 100644 --- a/src/core/lib/iomgr/resolve_address.h +++ b/src/core/lib/iomgr/resolve_address.h @@ -65,7 +65,7 @@ void grpc_set_resolver_impl(grpc_address_resolver_vtable* vtable); /* Asynchronously resolve addr. Use default_port if a port isn't designated in addr, otherwise use the port in addr. */ -/* TODO(ctiller): add a timeout here */ +/* TODO(apolcyn): add a timeout here */ void grpc_resolve_address(const char* addr, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, diff --git a/src/core/lib/iomgr/resolve_address_posix.cc b/src/core/lib/iomgr/resolve_address_posix.cc index c285d7eca66..e6dd8f1ceab 100644 --- a/src/core/lib/iomgr/resolve_address_posix.cc +++ b/src/core/lib/iomgr/resolve_address_posix.cc @@ -105,7 +105,7 @@ static grpc_error* posix_blocking_resolve_address( grpc_error_set_str( grpc_error_set_str( grpc_error_set_int( - GRPC_ERROR_CREATE_FROM_STATIC_STRING("OS Error"), + GRPC_ERROR_CREATE_FROM_STATIC_STRING(gai_strerror(s)), GRPC_ERROR_INT_ERRNO, s), GRPC_ERROR_STR_OS_ERROR, grpc_slice_from_static_string(gai_strerror(s))), @@ -150,7 +150,7 @@ typedef struct { void* arg; } request; -/* Callback to be passed to grpc_executor to asynch-ify +/* Callback to be passed to grpc Executor to asynch-ify * grpc_blocking_resolve_address */ static void do_request_thread(void* rp, grpc_error* error) { request* r = static_cast(rp); @@ -168,7 +168,8 @@ static void posix_resolve_address(const char* name, const char* default_port, request* r = static_cast(gpr_malloc(sizeof(request))); GRPC_CLOSURE_INIT( &r->request_closure, do_request_thread, r, - grpc_executor_scheduler(GRPC_RESOLVER_EXECUTOR, GRPC_EXECUTOR_SHORT)); + grpc_core::Executor::Scheduler(grpc_core::ExecutorType::RESOLVER, + grpc_core::ExecutorJobType::SHORT)); r->name = gpr_strdup(name); r->default_port = gpr_strdup(default_port); r->on_done = on_done; diff --git a/src/core/lib/iomgr/resolve_address_windows.cc b/src/core/lib/iomgr/resolve_address_windows.cc index 3e977dca2da..64351c38a8f 100644 --- a/src/core/lib/iomgr/resolve_address_windows.cc +++ b/src/core/lib/iomgr/resolve_address_windows.cc @@ -153,7 +153,8 @@ static void windows_resolve_address(const char* name, const char* default_port, request* r = (request*)gpr_malloc(sizeof(request)); GRPC_CLOSURE_INIT( &r->request_closure, do_request_thread, r, - grpc_executor_scheduler(GRPC_RESOLVER_EXECUTOR, GRPC_EXECUTOR_SHORT)); + grpc_core::Executor::Scheduler(grpc_core::ExecutorType::RESOLVER, + grpc_core::ExecutorJobType::SHORT)); r->name = gpr_strdup(name); r->default_port = gpr_strdup(default_port); r->on_done = on_done; diff --git a/src/core/lib/iomgr/resource_quota.cc b/src/core/lib/iomgr/resource_quota.cc index 7e4b3c9b2ff..dffac348c52 100644 --- a/src/core/lib/iomgr/resource_quota.cc +++ b/src/core/lib/iomgr/resource_quota.cc @@ -32,6 +32,7 @@ #include "src/core/lib/gpr/useful.h" #include "src/core/lib/iomgr/combiner.h" +#include "src/core/lib/slice/slice_internal.h" grpc_core::TraceFlag grpc_resource_quota_trace(false, "resource_quota"); @@ -316,7 +317,7 @@ static bool rq_alloc(grpc_resource_quota* resource_quota) { while ((resource_user = rulist_pop_head(resource_quota, GRPC_RULIST_AWAITING_ALLOCATION))) { gpr_mu_lock(&resource_user->mu); - if (grpc_resource_quota_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_resource_quota_trace)) { gpr_log(GPR_INFO, "RQ: check allocation for user %p shutdown=%" PRIdPTR " free_pool=%" PRId64, @@ -342,14 +343,14 @@ static bool rq_alloc(grpc_resource_quota* resource_quota) { resource_user->free_pool = 0; resource_quota->free_pool -= amt; rq_update_estimate(resource_quota); - if (grpc_resource_quota_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_resource_quota_trace)) { gpr_log(GPR_INFO, "RQ %s %s: grant alloc %" PRId64 " bytes; rq_free_pool -> %" PRId64, resource_quota->name, resource_user->name, amt, resource_quota->free_pool); } - } else if (grpc_resource_quota_trace.enabled() && + } else if (GRPC_TRACE_FLAG_ENABLED(grpc_resource_quota_trace) && resource_user->free_pool >= 0) { gpr_log(GPR_INFO, "RQ %s %s: discard already satisfied alloc request", resource_quota->name, resource_user->name); @@ -381,7 +382,7 @@ static bool rq_reclaim_from_per_user_free_pool( resource_user->free_pool = 0; resource_quota->free_pool += amt; rq_update_estimate(resource_quota); - if (grpc_resource_quota_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_resource_quota_trace)) { gpr_log(GPR_INFO, "RQ %s %s: reclaim_from_per_user_free_pool %" PRId64 " bytes; rq_free_pool -> %" PRId64, @@ -391,7 +392,7 @@ static bool rq_reclaim_from_per_user_free_pool( gpr_mu_unlock(&resource_user->mu); return true; } else { - if (grpc_resource_quota_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_resource_quota_trace)) { gpr_log(GPR_INFO, "RQ %s %s: failed to reclaim_from_per_user_free_pool; " "free_pool = %" PRId64 "; rq_free_pool = %" PRId64, @@ -411,7 +412,7 @@ static bool rq_reclaim(grpc_resource_quota* resource_quota, bool destructive) { : GRPC_RULIST_RECLAIMER_BENIGN; grpc_resource_user* resource_user = rulist_pop_head(resource_quota, list); if (resource_user == nullptr) return false; - if (grpc_resource_quota_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_resource_quota_trace)) { gpr_log(GPR_INFO, "RQ %s %s: initiate %s reclamation", resource_quota->name, resource_user->name, destructive ? "destructive" : "benign"); } @@ -430,41 +431,43 @@ static bool rq_reclaim(grpc_resource_quota* resource_quota, bool destructive) { * ru_slice: a slice implementation that is backed by a grpc_resource_user */ -typedef struct { - grpc_slice_refcount base; - gpr_refcount refs; - grpc_resource_user* resource_user; - size_t size; -} ru_slice_refcount; +namespace grpc_core { -static void ru_slice_ref(void* p) { - ru_slice_refcount* rc = static_cast(p); - gpr_ref(&rc->refs); -} - -static void ru_slice_unref(void* p) { - ru_slice_refcount* rc = static_cast(p); - if (gpr_unref(&rc->refs)) { - grpc_resource_user_free(rc->resource_user, rc->size); +class RuSliceRefcount { + public: + static void Destroy(void* p) { + auto* rc = static_cast(p); + rc->~RuSliceRefcount(); gpr_free(rc); } -} + RuSliceRefcount(grpc_resource_user* resource_user, size_t size) + : base_(grpc_slice_refcount::Type::REGULAR, &refs_, Destroy, this, + &base_), + resource_user_(resource_user), + size_(size) { + // Nothing to do here. + } + ~RuSliceRefcount() { grpc_resource_user_free(resource_user_, size_); } -static const grpc_slice_refcount_vtable ru_slice_vtable = { - ru_slice_ref, ru_slice_unref, grpc_slice_default_eq_impl, - grpc_slice_default_hash_impl}; + grpc_slice_refcount* base_refcount() { return &base_; } + + private: + grpc_slice_refcount base_; + RefCount refs_; + grpc_resource_user* resource_user_; + size_t size_; +}; + +} // namespace grpc_core static grpc_slice ru_slice_create(grpc_resource_user* resource_user, size_t size) { - ru_slice_refcount* rc = static_cast( - gpr_malloc(sizeof(ru_slice_refcount) + size)); - rc->base.vtable = &ru_slice_vtable; - rc->base.sub_refcount = &rc->base; - gpr_ref_init(&rc->refs, 1); - rc->resource_user = resource_user; - rc->size = size; + auto* rc = static_cast( + gpr_malloc(sizeof(grpc_core::RuSliceRefcount) + size)); + new (rc) grpc_core::RuSliceRefcount(resource_user, size); grpc_slice slice; - slice.refcount = &rc->base; + + slice.refcount = rc->base_refcount(); slice.data.refcounted.bytes = reinterpret_cast(rc + 1); slice.data.refcounted.length = size; return slice; @@ -540,7 +543,7 @@ static void ru_post_destructive_reclaimer(void* ru, grpc_error* error) { } static void ru_shutdown(void* ru, grpc_error* error) { - if (grpc_resource_quota_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_resource_quota_trace)) { gpr_log(GPR_INFO, "RU shutdown %p", ru); } grpc_resource_user* resource_user = static_cast(ru); @@ -665,6 +668,7 @@ void grpc_resource_quota_unref_internal(grpc_resource_quota* resource_quota) { GPR_ASSERT(resource_quota->num_threads_allocated == 0); GRPC_COMBINER_UNREF(resource_quota->combiner, "resource_quota"); gpr_free(resource_quota->name); + gpr_mu_destroy(&resource_quota->thread_count_mu); gpr_free(resource_quota); } } @@ -881,7 +885,7 @@ static void resource_user_alloc_locked(grpc_resource_user* resource_user, grpc_closure* optional_on_done) { ru_ref_by(resource_user, static_cast(size)); resource_user->free_pool -= static_cast(size); - if (grpc_resource_quota_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_resource_quota_trace)) { 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); @@ -940,7 +944,7 @@ void grpc_resource_user_free(grpc_resource_user* resource_user, size_t size) { GPR_ASSERT(prior >= static_cast(size)); bool was_zero_or_negative = resource_user->free_pool <= 0; resource_user->free_pool += static_cast(size); - if (grpc_resource_quota_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_resource_quota_trace)) { 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); @@ -966,7 +970,7 @@ void grpc_resource_user_post_reclaimer(grpc_resource_user* resource_user, } void grpc_resource_user_finish_reclamation(grpc_resource_user* resource_user) { - if (grpc_resource_quota_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_resource_quota_trace)) { gpr_log(GPR_INFO, "RQ %s %s: reclamation complete", resource_user->resource_quota->name, resource_user->name); } diff --git a/src/core/lib/iomgr/sockaddr_utils.cc b/src/core/lib/iomgr/sockaddr_utils.cc index 1b66dceb130..0839bdfef2d 100644 --- a/src/core/lib/iomgr/sockaddr_utils.cc +++ b/src/core/lib/iomgr/sockaddr_utils.cc @@ -217,6 +217,7 @@ void grpc_string_to_sockaddr(grpc_resolved_address* out, char* addr, int port) { } char* grpc_sockaddr_to_uri(const grpc_resolved_address* resolved_addr) { + if (resolved_addr->len == 0) return nullptr; grpc_resolved_address addr_normalized; if (grpc_sockaddr_is_v4mapped(resolved_addr, &addr_normalized)) { resolved_addr = &addr_normalized; diff --git a/src/core/lib/iomgr/socket_utils_common_posix.cc b/src/core/lib/iomgr/socket_utils_common_posix.cc index 4c337a05210..2101651b33f 100644 --- a/src/core/lib/iomgr/socket_utils_common_posix.cc +++ b/src/core/lib/iomgr/socket_utils_common_posix.cc @@ -30,7 +30,11 @@ #include #include #include +#ifdef GRPC_LINUX_TCP_H +#include +#else #include +#endif #include #include #include @@ -288,7 +292,7 @@ grpc_error* grpc_set_socket_tcp_user_timeout( } if (enable) { extern grpc_core::TraceFlag grpc_tcp_trace; - if (grpc_tcp_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { gpr_log(GPR_INFO, "Enabling TCP_USER_TIMEOUT with a timeout of %d ms", timeout); } @@ -311,7 +315,7 @@ grpc_error* grpc_set_socket_tcp_user_timeout( } #else extern grpc_core::TraceFlag grpc_tcp_trace; - if (grpc_tcp_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { gpr_log(GPR_INFO, "TCP_USER_TIMEOUT not supported for this platform"); } #endif /* GRPC_HAVE_TCP_USER_TIMEOUT */ diff --git a/src/core/lib/iomgr/socket_windows.cc b/src/core/lib/iomgr/socket_windows.cc index 999c6646ad4..c87cfa8e831 100644 --- a/src/core/lib/iomgr/socket_windows.cc +++ b/src/core/lib/iomgr/socket_windows.cc @@ -39,6 +39,8 @@ #include "src/core/lib/iomgr/sockaddr_windows.h" #include "src/core/lib/iomgr/socket_windows.h" +static DWORD s_wsa_socket_flags; + grpc_winsocket* grpc_winsocket_create(SOCKET socket, const char* name) { char* final_name; grpc_winsocket* r = (grpc_winsocket*)gpr_malloc(sizeof(grpc_winsocket)); @@ -181,4 +183,21 @@ int grpc_ipv6_loopback_available(void) { return g_ipv6_loopback_available; } +DWORD grpc_get_default_wsa_socket_flags() { return s_wsa_socket_flags; } + +void grpc_wsa_socket_flags_init() { + s_wsa_socket_flags = WSA_FLAG_OVERLAPPED; + /* WSA_FLAG_NO_HANDLE_INHERIT may be not supported on the older Windows + versions, see + https://msdn.microsoft.com/en-us/library/windows/desktop/ms742212(v=vs.85).aspx + for details. */ + SOCKET sock = WSASocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, + s_wsa_socket_flags | WSA_FLAG_NO_HANDLE_INHERIT); + if (sock != INVALID_SOCKET) { + /* Windows 7, Windows 2008 R2 with SP1 or later */ + s_wsa_socket_flags |= WSA_FLAG_NO_HANDLE_INHERIT; + closesocket(sock); + } +} + #endif /* GRPC_WINSOCK_SOCKET */ diff --git a/src/core/lib/iomgr/socket_windows.h b/src/core/lib/iomgr/socket_windows.h index 46d7d583560..5fed6909e6f 100644 --- a/src/core/lib/iomgr/socket_windows.h +++ b/src/core/lib/iomgr/socket_windows.h @@ -32,6 +32,10 @@ #include "src/core/lib/iomgr/closure.h" #include "src/core/lib/iomgr/iomgr_internal.h" +#ifndef WSA_FLAG_NO_HANDLE_INHERIT +#define WSA_FLAG_NO_HANDLE_INHERIT 0x80 +#endif + /* This holds the data for an outstanding read or write on a socket. The mutex to protect the concurrent access to that data is the one inside the winsocket wrapper. */ @@ -114,6 +118,10 @@ void grpc_socket_become_ready(grpc_winsocket* winsocket, The value is probed once, and cached for the life of the process. */ int grpc_ipv6_loopback_available(void); +void grpc_wsa_socket_flags_init(); + +DWORD grpc_get_default_wsa_socket_flags(); + #endif #endif /* GRPC_CORE_LIB_IOMGR_SOCKET_WINDOWS_H */ diff --git a/src/core/lib/iomgr/tcp_client_custom.cc b/src/core/lib/iomgr/tcp_client_custom.cc index 73344b18d8b..14a8b78dc68 100644 --- a/src/core/lib/iomgr/tcp_client_custom.cc +++ b/src/core/lib/iomgr/tcp_client_custom.cc @@ -64,7 +64,7 @@ static void on_alarm(void* acp, grpc_error* error) { int done; grpc_custom_socket* socket = (grpc_custom_socket*)acp; grpc_custom_tcp_connect* connect = socket->connector; - if (grpc_tcp_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { const char* str = grpc_error_string(error); gpr_log(GPR_INFO, "CLIENT_CONNECT: %s: on_alarm: error=%s", connect->addr_name, str); @@ -146,7 +146,7 @@ static void tcp_connect(grpc_closure* closure, grpc_endpoint** ep, socket->listener = nullptr; connect->refs = 2; - if (grpc_tcp_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { 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 0bff74e88b3..ad9d7798d05 100644 --- a/src/core/lib/iomgr/tcp_client_posix.cc +++ b/src/core/lib/iomgr/tcp_client_posix.cc @@ -108,7 +108,7 @@ done: static void tc_on_alarm(void* acp, grpc_error* error) { int done; async_connect* ac = static_cast(acp); - if (grpc_tcp_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { const char* str = grpc_error_string(error); gpr_log(GPR_INFO, "CLIENT_CONNECT: %s: on_alarm: error=%s", ac->addr_str, str); @@ -145,7 +145,7 @@ static void on_writable(void* acp, grpc_error* error) { GRPC_ERROR_REF(error); - if (grpc_tcp_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { const char* str = grpc_error_string(error); gpr_log(GPR_INFO, "CLIENT_CONNECT: %s: on_writable: error=%s", ac->addr_str, str); @@ -328,7 +328,7 @@ void grpc_tcp_client_create_from_prepared_fd( grpc_schedule_on_exec_ctx); ac->channel_args = grpc_channel_args_copy(channel_args); - if (grpc_tcp_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { gpr_log(GPR_INFO, "CLIENT_CONNECT: %s: asynchronously connecting fd %p", ac->addr_str, fdobj); } diff --git a/src/core/lib/iomgr/tcp_client_windows.cc b/src/core/lib/iomgr/tcp_client_windows.cc index e5b5502597e..66699533d7a 100644 --- a/src/core/lib/iomgr/tcp_client_windows.cc +++ b/src/core/lib/iomgr/tcp_client_windows.cc @@ -148,7 +148,7 @@ static void tcp_connect(grpc_closure* on_done, grpc_endpoint** endpoint, } sock = WSASocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, - WSA_FLAG_OVERLAPPED); + grpc_get_default_wsa_socket_flags()); if (sock == INVALID_SOCKET) { error = GRPC_WSA_ERROR(WSAGetLastError(), "WSASocket"); goto failure; @@ -213,10 +213,12 @@ static void tcp_connect(grpc_closure* on_done, grpc_endpoint** endpoint, failure: GPR_ASSERT(error != GRPC_ERROR_NONE); char* target_uri = grpc_sockaddr_to_uri(addr); - grpc_error* final_error = grpc_error_set_str( - GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING("Failed to connect", - &error, 1), - GRPC_ERROR_STR_TARGET_ADDRESS, grpc_slice_from_copied_string(target_uri)); + grpc_error* final_error = + grpc_error_set_str(GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + "Failed to connect", &error, 1), + GRPC_ERROR_STR_TARGET_ADDRESS, + grpc_slice_from_copied_string( + target_uri == nullptr ? "NULL" : target_uri)); GRPC_ERROR_UNREF(error); if (socket != NULL) { grpc_winsocket_destroy(socket); diff --git a/src/core/lib/iomgr/tcp_custom.cc b/src/core/lib/iomgr/tcp_custom.cc index e02a1898f25..66df5082e98 100644 --- a/src/core/lib/iomgr/tcp_custom.cc +++ b/src/core/lib/iomgr/tcp_custom.cc @@ -31,7 +31,6 @@ #include "src/core/lib/iomgr/error.h" #include "src/core/lib/iomgr/iomgr_custom.h" -#include "src/core/lib/iomgr/network_status_tracker.h" #include "src/core/lib/iomgr/resource_quota.h" #include "src/core/lib/iomgr/tcp_client.h" #include "src/core/lib/iomgr/tcp_custom.h" @@ -89,7 +88,7 @@ static void tcp_free(grpc_custom_socket* s) { #define TCP_REF(tcp, reason) tcp_ref((tcp), (reason), __FILE__, __LINE__) static void tcp_unref(custom_tcp_endpoint* tcp, const char* reason, const char* file, int line) { - if (grpc_tcp_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { gpr_atm val = gpr_atm_no_barrier_load(&tcp->refcount.count); gpr_log(file, line, GPR_LOG_SEVERITY_ERROR, "TCP unref %p : %s %" PRIdPTR " -> %" PRIdPTR, tcp->socket, reason, @@ -102,7 +101,7 @@ static void tcp_unref(custom_tcp_endpoint* tcp, const char* reason, static void tcp_ref(custom_tcp_endpoint* tcp, const char* reason, const char* file, int line) { - if (grpc_tcp_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { gpr_atm val = gpr_atm_no_barrier_load(&tcp->refcount.count); gpr_log(file, line, GPR_LOG_SEVERITY_ERROR, "TCP ref %p : %s %" PRIdPTR " -> %" PRIdPTR, tcp->socket, reason, @@ -124,7 +123,7 @@ static void tcp_ref(custom_tcp_endpoint* tcp) { gpr_ref(&tcp->refcount); } static void call_read_cb(custom_tcp_endpoint* tcp, grpc_error* error) { grpc_closure* cb = tcp->read_cb; - if (grpc_tcp_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { gpr_log(GPR_INFO, "TCP:%p call_cb %p %p:%p", tcp->socket, cb, cb->cb, cb->cb_arg); size_t i; @@ -170,7 +169,7 @@ static void custom_read_callback(grpc_custom_socket* socket, size_t nread, static void tcp_read_allocation_done(void* tcpp, grpc_error* error) { custom_tcp_endpoint* tcp = (custom_tcp_endpoint*)tcpp; - if (grpc_tcp_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { gpr_log(GPR_INFO, "TCP:%p read_allocation_done: %s", tcp->socket, grpc_error_string(error)); } @@ -186,14 +185,14 @@ static void tcp_read_allocation_done(void* tcpp, grpc_error* error) { grpc_slice_buffer_reset_and_unref_internal(tcp->read_slices); call_read_cb(tcp, GRPC_ERROR_REF(error)); } - if (grpc_tcp_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { const char* str = grpc_error_string(error); gpr_log(GPR_INFO, "Initiating read on %p: error=%s", tcp->socket, str); } } static void endpoint_read(grpc_endpoint* ep, grpc_slice_buffer* read_slices, - grpc_closure* cb) { + grpc_closure* cb, bool urgent) { custom_tcp_endpoint* tcp = (custom_tcp_endpoint*)ep; GRPC_CUSTOM_IOMGR_ASSERT_SAME_THREAD(); GPR_ASSERT(tcp->read_cb == nullptr); @@ -212,7 +211,7 @@ static void custom_write_callback(grpc_custom_socket* socket, custom_tcp_endpoint* tcp = (custom_tcp_endpoint*)socket->endpoint; grpc_closure* cb = tcp->write_cb; tcp->write_cb = nullptr; - if (grpc_tcp_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { const char* str = grpc_error_string(error); gpr_log(GPR_INFO, "write complete on %p: error=%s", tcp->socket, str); } @@ -225,7 +224,7 @@ static void endpoint_write(grpc_endpoint* ep, grpc_slice_buffer* write_slices, custom_tcp_endpoint* tcp = (custom_tcp_endpoint*)ep; GRPC_CUSTOM_IOMGR_ASSERT_SAME_THREAD(); - if (grpc_tcp_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { size_t j; for (j = 0; j < write_slices->count; j++) { @@ -281,7 +280,7 @@ static void endpoint_delete_from_pollset_set(grpc_endpoint* ep, static void endpoint_shutdown(grpc_endpoint* ep, grpc_error* why) { custom_tcp_endpoint* tcp = (custom_tcp_endpoint*)ep; if (!tcp->shutting_down) { - if (grpc_tcp_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { const char* str = grpc_error_string(why); gpr_log(GPR_INFO, "TCP %p shutdown why=%s", tcp->socket, str); } @@ -309,7 +308,6 @@ static void custom_close_callback(grpc_custom_socket* socket) { } static void endpoint_destroy(grpc_endpoint* ep) { - grpc_network_status_unregister_endpoint(ep); custom_tcp_endpoint* tcp = (custom_tcp_endpoint*)ep; grpc_custom_socket_vtable->close(tcp->socket, custom_close_callback); } @@ -326,6 +324,8 @@ static grpc_resource_user* endpoint_get_resource_user(grpc_endpoint* ep) { static int endpoint_get_fd(grpc_endpoint* ep) { return -1; } +static bool endpoint_can_track_err(grpc_endpoint* ep) { return false; } + static grpc_endpoint_vtable vtable = {endpoint_read, endpoint_write, endpoint_add_to_pollset, @@ -335,7 +335,8 @@ static grpc_endpoint_vtable vtable = {endpoint_read, endpoint_destroy, endpoint_get_resource_user, endpoint_get_peer, - endpoint_get_fd}; + endpoint_get_fd, + endpoint_can_track_err}; grpc_endpoint* custom_tcp_endpoint_create(grpc_custom_socket* socket, grpc_resource_quota* resource_quota, @@ -344,7 +345,7 @@ grpc_endpoint* custom_tcp_endpoint_create(grpc_custom_socket* socket, (custom_tcp_endpoint*)gpr_malloc(sizeof(custom_tcp_endpoint)); grpc_core::ExecCtx exec_ctx; - if (grpc_tcp_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { gpr_log(GPR_INFO, "Creating TCP endpoint %p", socket); } memset(tcp, 0, sizeof(custom_tcp_endpoint)); @@ -358,8 +359,6 @@ grpc_endpoint* custom_tcp_endpoint_create(grpc_custom_socket* socket, tcp->resource_user = grpc_resource_user_create(resource_quota, peer_string); grpc_resource_user_slice_allocator_init( &tcp->slice_allocator, tcp->resource_user, tcp_read_allocation_done, tcp); - /* Tell network status tracking code about the new endpoint */ - grpc_network_status_register_endpoint(&tcp->base); return &tcp->base; } diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index aa2704ce263..cda7bba0d3a 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -22,12 +22,12 @@ #ifdef GRPC_POSIX_SOCKET_TCP -#include "src/core/lib/iomgr/network_status_tracker.h" #include "src/core/lib/iomgr/tcp_posix.h" #include #include #include +#include #include #include #include @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -55,6 +56,15 @@ #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/slice/slice_string_helpers.h" +#ifndef SOL_TCP +#define SOL_TCP IPPROTO_TCP +#endif + +#ifndef TCP_INQ +#define TCP_INQ 36 +#define TCP_CM_INQ TCP_INQ +#endif + #ifdef GRPC_HAVE_MSG_NOSIGNAL #define SENDMSG_FLAGS MSG_NOSIGNAL #else @@ -89,8 +99,11 @@ struct grpc_tcp { grpc_slice_buffer last_read_buffer; grpc_slice_buffer* incoming_buffer; + int inq; /* bytes pending on the socket from the last read. */ + bool inq_capable; /* cache whether kernel supports inq */ + grpc_slice_buffer* outgoing_buffer; - /** byte within outgoing_buffer->slices[0] to write next */ + /* byte within outgoing_buffer->slices[0] to write next */ size_t outgoing_byte_idx; grpc_closure* read_cb; @@ -126,9 +139,9 @@ struct grpc_tcp { int bytes_counter; bool socket_ts_enabled; /* True if timestamping options are set on the socket */ - gpr_atm - stop_error_notification; /* Set to 1 if we do not want to be notified on - errors anymore */ + bool ts_capable; /* Cache whether we can set timestamping options */ + gpr_atm stop_error_notification; /* Set to 1 if we do not want to be notified + on errors anymore */ }; struct backup_poller { @@ -150,7 +163,7 @@ static void tcp_drop_uncovered_then_handle_write(void* arg /* grpc_tcp */, static void done_poller(void* bp, grpc_error* error_ignored) { backup_poller* p = static_cast(bp); - if (grpc_tcp_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { gpr_log(GPR_INFO, "BACKUP_POLLER:%p destroy", p); } grpc_pollset_destroy(BACKUP_POLLER_POLLSET(p)); @@ -159,7 +172,7 @@ static void done_poller(void* bp, grpc_error* error_ignored) { static void run_poller(void* bp, grpc_error* error_ignored) { backup_poller* p = static_cast(bp); - if (grpc_tcp_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { gpr_log(GPR_INFO, "BACKUP_POLLER:%p run", p); } gpr_mu_lock(p->pollset_mu); @@ -175,18 +188,18 @@ static void run_poller(void* bp, grpc_error* error_ignored) { gpr_atm_full_cas(&g_uncovered_notifications_pending, 1, 0)) { 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()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { 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()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { 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()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { gpr_log(GPR_INFO, "BACKUP_POLLER:%p reschedule", p); } GRPC_CLOSURE_SCHED(&p->run_poller, GRPC_ERROR_NONE); @@ -196,8 +209,8 @@ static void run_poller(void* bp, grpc_error* error_ignored) { static void drop_uncovered(grpc_tcp* tcp) { backup_poller* p = (backup_poller*)gpr_atm_acq_load(&g_backup_poller); gpr_atm old_count = - gpr_atm_no_barrier_fetch_add(&g_uncovered_notifications_pending, -1); - if (grpc_tcp_trace.enabled()) { + gpr_atm_full_fetch_add(&g_uncovered_notifications_pending, -1); + if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { gpr_log(GPR_INFO, "BACKUP_POLLER:%p uncover cnt %d->%d", p, static_cast(old_count), static_cast(old_count) - 1); } @@ -215,7 +228,7 @@ static void cover_self(grpc_tcp* tcp) { backup_poller* p; gpr_atm old_count = gpr_atm_no_barrier_fetch_add(&g_uncovered_notifications_pending, 2); - if (grpc_tcp_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { gpr_log(GPR_INFO, "BACKUP_POLLER: cover cnt %d->%d", static_cast(old_count), 2 + static_cast(old_count)); } @@ -223,22 +236,22 @@ static void cover_self(grpc_tcp* tcp) { GRPC_STATS_INC_TCP_BACKUP_POLLERS_CREATED(); p = static_cast( gpr_zalloc(sizeof(*p) + grpc_pollset_size())); - if (grpc_tcp_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { 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); - GRPC_CLOSURE_SCHED( - GRPC_CLOSURE_INIT(&p->run_poller, run_poller, p, - grpc_executor_scheduler(GRPC_EXECUTOR_LONG)), - GRPC_ERROR_NONE); + GRPC_CLOSURE_SCHED(GRPC_CLOSURE_INIT(&p->run_poller, run_poller, p, + grpc_core::Executor::Scheduler( + grpc_core::ExecutorJobType::LONG)), + GRPC_ERROR_NONE); } else { while ((p = (backup_poller*)gpr_atm_acq_load(&g_backup_poller)) == nullptr) { // spin waiting for backup poller } } - if (grpc_tcp_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { gpr_log(GPR_INFO, "BACKUP_POLLER:%p add %p", p, tcp); } grpc_pollset_add_fd(BACKUP_POLLER_POLLSET(p), tcp->em_fd); @@ -248,27 +261,24 @@ static void cover_self(grpc_tcp* tcp) { } static void notify_on_read(grpc_tcp* tcp) { - if (grpc_tcp_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { 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); grpc_fd_notify_on_read(tcp->em_fd, &tcp->read_done_closure); } static void notify_on_write(grpc_tcp* tcp) { - if (grpc_tcp_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { gpr_log(GPR_INFO, "TCP:%p notify_on_write", tcp); } - cover_self(tcp); - GRPC_CLOSURE_INIT(&tcp->write_done_closure, - tcp_drop_uncovered_then_handle_write, tcp, - grpc_schedule_on_exec_ctx); + if (!grpc_event_engine_run_in_background()) { + cover_self(tcp); + } grpc_fd_notify_on_write(tcp->em_fd, &tcp->write_done_closure); } static void tcp_drop_uncovered_then_handle_write(void* arg, grpc_error* error) { - if (grpc_tcp_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { gpr_log(GPR_INFO, "TCP:%p got_write: %s", arg, grpc_error_string(error)); } drop_uncovered(static_cast(arg)); @@ -337,6 +347,13 @@ static void tcp_free(grpc_tcp* tcp) { grpc_slice_buffer_destroy_internal(&tcp->last_read_buffer); grpc_resource_user_unref(tcp->resource_user); gpr_free(tcp->peer_string); + /* The lock is not really necessary here, since all refs have been released */ + gpr_mu_lock(&tcp->tb_mu); + grpc_core::TracedBuffer::Shutdown( + &tcp->tb_head, tcp->outgoing_buffer_arg, + GRPC_ERROR_CREATE_FROM_STATIC_STRING("endpoint destroyed")); + gpr_mu_unlock(&tcp->tb_mu); + tcp->outgoing_buffer_arg = nullptr; gpr_mu_destroy(&tcp->tb_mu); gpr_free(tcp); } @@ -346,7 +363,7 @@ static void tcp_free(grpc_tcp* tcp) { #define TCP_REF(tcp, reason) tcp_ref((tcp), (reason), __FILE__, __LINE__) static void tcp_unref(grpc_tcp* tcp, const char* reason, const char* file, int line) { - if (grpc_tcp_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { gpr_atm val = gpr_atm_no_barrier_load(&tcp->refcount.count); gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "TCP unref %p : %s %" PRIdPTR " -> %" PRIdPTR, tcp, reason, val, @@ -359,7 +376,7 @@ static void tcp_unref(grpc_tcp* tcp, const char* reason, const char* file, static void tcp_ref(grpc_tcp* tcp, const char* reason, const char* file, int line) { - if (grpc_tcp_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { gpr_atm val = gpr_atm_no_barrier_load(&tcp->refcount.count); gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "TCP ref %p : %s %" PRIdPTR " -> %" PRIdPTR, tcp, reason, val, @@ -380,7 +397,6 @@ static void tcp_ref(grpc_tcp* tcp) { gpr_ref(&tcp->refcount); } #endif static void tcp_destroy(grpc_endpoint* ep) { - grpc_network_status_unregister_endpoint(ep); grpc_tcp* tcp = reinterpret_cast(ep); grpc_slice_buffer_reset_and_unref_internal(&tcp->last_read_buffer); if (grpc_event_engine_can_track_errors()) { @@ -393,17 +409,19 @@ static void tcp_destroy(grpc_endpoint* ep) { static void call_read_cb(grpc_tcp* tcp, grpc_error* error) { grpc_closure* cb = tcp->read_cb; - if (grpc_tcp_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { 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_INFO, "read: error=%s", str); + gpr_log(GPR_INFO, "READ %p (peer=%s) error=%s", tcp, tcp->peer_string, 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_INFO, "READ %p (peer=%s): %s", tcp, tcp->peer_string, dump); - gpr_free(dump); + if (gpr_should_log(GPR_LOG_SEVERITY_DEBUG)) { + 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, "DATA: %s", dump); + gpr_free(dump); + } } } @@ -417,74 +435,145 @@ static void tcp_do_read(grpc_tcp* tcp) { GPR_TIMER_SCOPE("tcp_do_read", 0); struct msghdr msg; struct iovec iov[MAX_READ_IOVEC]; + char cmsgbuf[24 /*CMSG_SPACE(sizeof(int))*/]; ssize_t read_bytes; - size_t i; + size_t total_read_bytes = 0; - GPR_ASSERT(tcp->incoming_buffer->count <= MAX_READ_IOVEC); - - for (i = 0; i < tcp->incoming_buffer->count; i++) { + size_t iov_len = + std::min(MAX_READ_IOVEC, tcp->incoming_buffer->count); + for (size_t i = 0; i < iov_len; i++) { iov[i].iov_base = GRPC_SLICE_START_PTR(tcp->incoming_buffer->slices[i]); iov[i].iov_len = GRPC_SLICE_LENGTH(tcp->incoming_buffer->slices[i]); } - msg.msg_name = nullptr; - msg.msg_namelen = 0; - msg.msg_iov = iov; - msg.msg_iovlen = static_cast(tcp->incoming_buffer->count); - msg.msg_control = nullptr; - msg.msg_controllen = 0; - msg.msg_flags = 0; - - GRPC_STATS_INC_TCP_READ_OFFER(tcp->incoming_buffer->length); - GRPC_STATS_INC_TCP_READ_OFFER_IOV_SIZE(tcp->incoming_buffer->count); - do { - GPR_TIMER_SCOPE("recvmsg", 0); - GRPC_STATS_INC_SYSCALL_READ(); - read_bytes = recvmsg(tcp->fd, &msg, 0); - } while (read_bytes < 0 && errno == EINTR); + /* Assume there is something on the queue. If we receive TCP_INQ from + * kernel, we will update this value, otherwise, we have to assume there is + * always something to read until we get EAGAIN. */ + tcp->inq = 1; - if (read_bytes < 0) { - /* NB: After calling call_read_cb a parallel call of the read handler may - * be running. */ - if (errno == EAGAIN) { - finish_estimate(tcp); - /* We've consumed the edge, request a new one */ - notify_on_read(tcp); + msg.msg_name = nullptr; + msg.msg_namelen = 0; + msg.msg_iov = iov; + msg.msg_iovlen = static_cast(iov_len); + if (tcp->inq_capable) { + msg.msg_control = cmsgbuf; + msg.msg_controllen = sizeof(cmsgbuf); } else { - grpc_slice_buffer_reset_and_unref_internal(tcp->incoming_buffer); - call_read_cb(tcp, - tcp_annotate_error(GRPC_OS_ERROR(errno, "recvmsg"), tcp)); - TCP_UNREF(tcp, "read"); + msg.msg_control = nullptr; + msg.msg_controllen = 0; } - } else if (read_bytes == 0) { - /* 0 read size ==> end of stream */ - grpc_slice_buffer_reset_and_unref_internal(tcp->incoming_buffer); - call_read_cb( - tcp, tcp_annotate_error( - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Socket closed"), tcp)); - TCP_UNREF(tcp, "read"); - } else { + msg.msg_flags = 0; + + GRPC_STATS_INC_TCP_READ_OFFER(tcp->incoming_buffer->length); + GRPC_STATS_INC_TCP_READ_OFFER_IOV_SIZE(tcp->incoming_buffer->count); + + do { + GPR_TIMER_SCOPE("recvmsg", 0); + GRPC_STATS_INC_SYSCALL_READ(); + read_bytes = recvmsg(tcp->fd, &msg, 0); + } while (read_bytes < 0 && errno == EINTR); + + /* We have read something in previous reads. We need to deliver those + * bytes to the upper layer. */ + if (read_bytes <= 0 && total_read_bytes > 0) { + tcp->inq = 1; + break; + } + + if (read_bytes < 0) { + /* NB: After calling call_read_cb a parallel call of the read handler may + * be running. */ + if (errno == EAGAIN) { + finish_estimate(tcp); + tcp->inq = 0; + /* We've consumed the edge, request a new one */ + notify_on_read(tcp); + } else { + grpc_slice_buffer_reset_and_unref_internal(tcp->incoming_buffer); + call_read_cb(tcp, + tcp_annotate_error(GRPC_OS_ERROR(errno, "recvmsg"), tcp)); + TCP_UNREF(tcp, "read"); + } + return; + } + if (read_bytes == 0) { + /* 0 read size ==> end of stream + * + * We may have read something, i.e., total_read_bytes > 0, but + * since the connection is closed we will drop the data here, because we + * can't call the callback multiple times. */ + grpc_slice_buffer_reset_and_unref_internal(tcp->incoming_buffer); + call_read_cb( + tcp, tcp_annotate_error( + GRPC_ERROR_CREATE_FROM_STATIC_STRING("Socket closed"), tcp)); + TCP_UNREF(tcp, "read"); + return; + } + GRPC_STATS_INC_TCP_READ_SIZE(read_bytes); add_to_estimate(tcp, static_cast(read_bytes)); - GPR_ASSERT((size_t)read_bytes <= tcp->incoming_buffer->length); - if (static_cast(read_bytes) == tcp->incoming_buffer->length) { - finish_estimate(tcp); - } else if (static_cast(read_bytes) < tcp->incoming_buffer->length) { - grpc_slice_buffer_trim_end( - tcp->incoming_buffer, - tcp->incoming_buffer->length - static_cast(read_bytes), - &tcp->last_read_buffer); + GPR_DEBUG_ASSERT((size_t)read_bytes <= + tcp->incoming_buffer->length - total_read_bytes); + +#ifdef GRPC_HAVE_TCP_INQ + if (tcp->inq_capable) { + GPR_DEBUG_ASSERT(!(msg.msg_flags & MSG_CTRUNC)); + struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg); + for (; cmsg != nullptr; cmsg = CMSG_NXTHDR(&msg, cmsg)) { + if (cmsg->cmsg_level == SOL_TCP && cmsg->cmsg_type == TCP_CM_INQ && + cmsg->cmsg_len == CMSG_LEN(sizeof(int))) { + tcp->inq = *reinterpret_cast(CMSG_DATA(cmsg)); + } + } } - GPR_ASSERT((size_t)read_bytes == tcp->incoming_buffer->length); - call_read_cb(tcp, GRPC_ERROR_NONE); - TCP_UNREF(tcp, "read"); +#endif /* GRPC_HAVE_TCP_INQ */ + + total_read_bytes += read_bytes; + if (tcp->inq == 0 || total_read_bytes == tcp->incoming_buffer->length) { + /* We have filled incoming_buffer, and we cannot read any more. */ + break; + } + + /* We had a partial read, and still have space to read more data. + * So, adjust IOVs and try to read more. */ + size_t remaining = read_bytes; + size_t j = 0; + for (size_t i = 0; i < iov_len; i++) { + if (remaining >= iov[i].iov_len) { + remaining -= iov[i].iov_len; + continue; + } + if (remaining > 0) { + iov[j].iov_base = static_cast(iov[i].iov_base) + remaining; + iov[j].iov_len = iov[i].iov_len - remaining; + remaining = 0; + } else { + iov[j].iov_base = iov[i].iov_base; + iov[j].iov_len = iov[i].iov_len; + } + ++j; + } + iov_len = j; + } while (true); + + if (tcp->inq == 0) { + finish_estimate(tcp); } + + GPR_DEBUG_ASSERT(total_read_bytes > 0); + if (total_read_bytes < tcp->incoming_buffer->length) { + grpc_slice_buffer_trim_end(tcp->incoming_buffer, + tcp->incoming_buffer->length - total_read_bytes, + &tcp->last_read_buffer); + } + call_read_cb(tcp, GRPC_ERROR_NONE); + TCP_UNREF(tcp, "read"); } static void tcp_read_allocation_done(void* tcpp, grpc_error* error) { grpc_tcp* tcp = static_cast(tcpp); - if (grpc_tcp_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { gpr_log(GPR_INFO, "TCP:%p read_allocation_done: %s", tcp, grpc_error_string(error)); } @@ -500,15 +589,16 @@ static void tcp_read_allocation_done(void* tcpp, grpc_error* error) { static void tcp_continue_read(grpc_tcp* tcp) { size_t target_read_size = get_target_read_size(tcp); - if (tcp->incoming_buffer->length < target_read_size / 2 && + /* Wait for allocation only when there is no buffer left. */ + if (tcp->incoming_buffer->length == 0 && tcp->incoming_buffer->count < MAX_READ_IOVEC) { - if (grpc_tcp_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { 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()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { gpr_log(GPR_INFO, "TCP:%p do_read", tcp); } tcp_do_read(tcp); @@ -517,7 +607,7 @@ static void tcp_continue_read(grpc_tcp* tcp) { static void tcp_handle_read(void* arg /* grpc_tcp */, grpc_error* error) { grpc_tcp* tcp = static_cast(arg); - if (grpc_tcp_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { gpr_log(GPR_INFO, "TCP:%p got_read: %s", tcp, grpc_error_string(error)); } @@ -532,7 +622,7 @@ static void tcp_handle_read(void* arg /* grpc_tcp */, grpc_error* error) { } static void tcp_read(grpc_endpoint* ep, grpc_slice_buffer* incoming_buffer, - grpc_closure* cb) { + grpc_closure* cb, bool urgent) { grpc_tcp* tcp = reinterpret_cast(ep); GPR_ASSERT(tcp->read_cb == nullptr); tcp->read_cb = cb; @@ -545,6 +635,11 @@ static void tcp_read(grpc_endpoint* ep, grpc_slice_buffer* incoming_buffer, * the polling engine */ tcp->is_first_read = false; notify_on_read(tcp); + } else if (!urgent && tcp->inq == 0) { + /* Upper layer asked to read more but we know there is no pending data + * to read from previous reads. So, wait for POLLIN. + */ + notify_on_read(tcp); } else { /* Not the first time. We may or may not have more bytes available. In any * case call tcp->read_done_closure (i.e tcp_handle_read()) which does the @@ -576,23 +671,22 @@ ssize_t tcp_send(int fd, const struct msghdr* msg) { */ static bool tcp_write_with_timestamps(grpc_tcp* tcp, struct msghdr* msg, size_t sending_length, - ssize_t* sent_length, grpc_error** error); + ssize_t* sent_length); /** The callback function to be invoked when we get an error on the socket. */ static void tcp_handle_error(void* arg /* grpc_tcp */, grpc_error* error); #ifdef GRPC_LINUX_ERRQUEUE + static bool tcp_write_with_timestamps(grpc_tcp* tcp, struct msghdr* msg, size_t sending_length, - ssize_t* sent_length, - grpc_error** error) { + ssize_t* sent_length) { if (!tcp->socket_ts_enabled) { uint32_t opt = grpc_core::kTimestampingSocketOptions; if (setsockopt(tcp->fd, SOL_SOCKET, SO_TIMESTAMPING, static_cast(&opt), sizeof(opt)) != 0) { - *error = tcp_annotate_error(GRPC_OS_ERROR(errno, "setsockopt"), tcp); grpc_slice_buffer_reset_and_unref_internal(tcp->outgoing_buffer); - if (grpc_tcp_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { gpr_log(GPR_ERROR, "Failed to set timestamping options on the socket."); } return false; @@ -621,8 +715,8 @@ static bool tcp_write_with_timestamps(grpc_tcp* tcp, struct msghdr* msg, if (sending_length == static_cast(length)) { gpr_mu_lock(&tcp->tb_mu); grpc_core::TracedBuffer::AddNewEntry( - &tcp->tb_head, static_cast(tcp->bytes_counter + length), - tcp->outgoing_buffer_arg); + &tcp->tb_head, static_cast(tcp->bytes_counter + length), + tcp->fd, tcp->outgoing_buffer_arg); gpr_mu_unlock(&tcp->tb_mu); tcp->outgoing_buffer_arg = nullptr; } @@ -639,17 +733,31 @@ static bool tcp_write_with_timestamps(grpc_tcp* tcp, struct msghdr* msg, struct cmsghdr* process_timestamp(grpc_tcp* tcp, msghdr* msg, struct cmsghdr* cmsg) { auto next_cmsg = CMSG_NXTHDR(msg, cmsg); + cmsghdr* opt_stats = nullptr; if (next_cmsg == nullptr) { - if (grpc_tcp_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { gpr_log(GPR_ERROR, "Received timestamp without extended error"); } return cmsg; } + /* Check if next_cmsg is an OPT_STATS msg */ + if (next_cmsg->cmsg_level == SOL_SOCKET && + next_cmsg->cmsg_type == SCM_TIMESTAMPING_OPT_STATS) { + opt_stats = next_cmsg; + next_cmsg = CMSG_NXTHDR(msg, opt_stats); + if (next_cmsg == nullptr) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { + gpr_log(GPR_ERROR, "Received timestamp without extended error"); + } + return opt_stats; + } + } + if (!(next_cmsg->cmsg_level == SOL_IP || next_cmsg->cmsg_level == SOL_IPV6) || !(next_cmsg->cmsg_type == IP_RECVERR || next_cmsg->cmsg_type == IPV6_RECVERR)) { - if (grpc_tcp_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { gpr_log(GPR_ERROR, "Unexpected control message"); } return cmsg; @@ -667,17 +775,16 @@ struct cmsghdr* process_timestamp(grpc_tcp* tcp, msghdr* msg, * to protect the traced buffer list. A lock free list might be better. Using * a simple mutex for now. */ gpr_mu_lock(&tcp->tb_mu); - grpc_core::TracedBuffer::ProcessTimestamp(&tcp->tb_head, serr, tss); + grpc_core::TracedBuffer::ProcessTimestamp(&tcp->tb_head, serr, opt_stats, + tss); gpr_mu_unlock(&tcp->tb_mu); return next_cmsg; } /** For linux platforms, reads the socket's error queue and processes error - * messages from the queue. Returns true if all the errors processed were - * timestamps. Returns false if any of the errors were not timestamps. For - * non-linux platforms, error processing is not used/enabled currently. + * messages from the queue. */ -static bool process_errors(grpc_tcp* tcp) { +static void process_errors(grpc_tcp* tcp) { while (true) { struct iovec iov; iov.iov_base = nullptr; @@ -689,9 +796,15 @@ static bool process_errors(grpc_tcp* tcp) { msg.msg_iovlen = 0; msg.msg_flags = 0; + /* Allocate enough space so we don't need to keep increasing this as size + * of OPT_STATS increase */ + constexpr size_t cmsg_alloc_space = + CMSG_SPACE(sizeof(grpc_core::scm_timestamping)) + + CMSG_SPACE(sizeof(sock_extended_err) + sizeof(sockaddr_in)) + + CMSG_SPACE(32 * NLA_ALIGN(NLA_HDRLEN + sizeof(uint64_t))); + /* Allocate aligned space for cmsgs received along with timestamps */ union { - char rbuf[1024 /*CMSG_SPACE(sizeof(scm_timestamping)) + - CMSG_SPACE(sizeof(sock_extended_err) + sizeof(sockaddr_in))*/]; + char rbuf[cmsg_alloc_space]; struct cmsghdr align; } aligned_buf; memset(&aligned_buf, 0, sizeof(aligned_buf)); @@ -706,42 +819,45 @@ static bool process_errors(grpc_tcp* tcp) { } while (r < 0 && saved_errno == EINTR); if (r == -1 && saved_errno == EAGAIN) { - return true; /* No more errors to process */ + return; /* No more errors to process */ } if (r == -1) { - return false; + return; } - if (grpc_tcp_trace.enabled()) { - if ((msg.msg_flags & MSG_CTRUNC) == 1) { - gpr_log(GPR_INFO, "Error message was truncated."); - } + if ((msg.msg_flags & MSG_CTRUNC) != 0) { + gpr_log(GPR_ERROR, "Error message was truncated."); } if (msg.msg_controllen == 0) { /* There was no control message found. It was probably spurious. */ - return true; + return; } + bool seen = false; for (auto cmsg = CMSG_FIRSTHDR(&msg); cmsg && cmsg->cmsg_len; cmsg = CMSG_NXTHDR(&msg, cmsg)) { if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_TIMESTAMPING) { /* Got a control message that is not a timestamp. Don't know how to * handle this. */ - if (grpc_tcp_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { gpr_log(GPR_INFO, "unknown control message cmsg_level:%d cmsg_type:%d", cmsg->cmsg_level, cmsg->cmsg_type); } - return false; + return; } - process_timestamp(tcp, &msg, cmsg); + cmsg = process_timestamp(tcp, &msg, cmsg); + seen = true; + } + if (!seen) { + return; } } } static void tcp_handle_error(void* arg /* grpc_tcp */, grpc_error* error) { grpc_tcp* tcp = static_cast(arg); - if (grpc_tcp_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { gpr_log(GPR_INFO, "TCP:%p got_error: %s", tcp, grpc_error_string(error)); } @@ -749,30 +865,24 @@ static void tcp_handle_error(void* arg /* grpc_tcp */, grpc_error* error) { static_cast(gpr_atm_acq_load(&tcp->stop_error_notification))) { /* We aren't going to register to hear on error anymore, so it is safe to * unref. */ - grpc_core::TracedBuffer::Shutdown(&tcp->tb_head, GRPC_ERROR_REF(error)); TCP_UNREF(tcp, "error-tracking"); return; } /* We are still interested in collecting timestamps, so let's try reading * them. */ - if (!process_errors(tcp)) { - /* This was not a timestamps error. This was an actual error. Set the - * read and write closures to be ready. - */ - grpc_fd_set_readable(tcp->em_fd); - grpc_fd_set_writable(tcp->em_fd); - } - GRPC_CLOSURE_INIT(&tcp->error_closure, tcp_handle_error, tcp, - grpc_schedule_on_exec_ctx); + process_errors(tcp); + /* This might not a timestamps error. Set the read and write closures to be + * ready. */ + grpc_fd_set_readable(tcp->em_fd); + grpc_fd_set_writable(tcp->em_fd); grpc_fd_notify_on_error(tcp->em_fd, &tcp->error_closure); } #else /* GRPC_LINUX_ERRQUEUE */ static bool tcp_write_with_timestamps(grpc_tcp* tcp, struct msghdr* msg, size_t sending_length, - ssize_t* sent_length, - grpc_error** error) { + ssize_t* sent_length) { gpr_log(GPR_ERROR, "Write with timestamps not supported for this platform"); GPR_ASSERT(0); return false; @@ -784,6 +894,19 @@ static void tcp_handle_error(void* arg /* grpc_tcp */, grpc_error* error) { } #endif /* GRPC_LINUX_ERRQUEUE */ +/* If outgoing_buffer_arg is filled, shuts down the list early, so that any + * release operations needed can be performed on the arg */ +void tcp_shutdown_buffer_list(grpc_tcp* tcp) { + if (tcp->outgoing_buffer_arg) { + gpr_mu_lock(&tcp->tb_mu); + grpc_core::TracedBuffer::Shutdown( + &tcp->tb_head, tcp->outgoing_buffer_arg, + GRPC_ERROR_CREATE_FROM_STATIC_STRING("TracedBuffer list shutdown")); + gpr_mu_unlock(&tcp->tb_mu); + tcp->outgoing_buffer_arg = nullptr; + } +} + /* returns true if done, false if pending; if returning true, *error is set */ #if defined(IOV_MAX) && IOV_MAX < 1000 #define MAX_WRITE_IOVEC IOV_MAX @@ -794,7 +917,7 @@ static bool tcp_flush(grpc_tcp* tcp, grpc_error** error) { struct msghdr msg; struct iovec iov[MAX_WRITE_IOVEC]; msg_iovlen_type iov_size; - ssize_t sent_length; + ssize_t sent_length = 0; size_t sending_length; size_t trailing; size_t unwind_slice_idx; @@ -829,11 +952,19 @@ static bool tcp_flush(grpc_tcp* tcp, grpc_error** error) { msg.msg_iov = iov; msg.msg_iovlen = iov_size; msg.msg_flags = 0; + bool tried_sending_message = false; if (tcp->outgoing_buffer_arg != nullptr) { - if (!tcp_write_with_timestamps(tcp, &msg, sending_length, &sent_length, - error)) - return true; /* something went wrong with timestamps */ - } else { + if (!tcp->ts_capable || + !tcp_write_with_timestamps(tcp, &msg, sending_length, &sent_length)) { + /* We could not set socket options to collect Fathom timestamps. + * Fallback on writing without timestamps. */ + tcp->ts_capable = false; + tcp_shutdown_buffer_list(tcp); + } else { + tried_sending_message = true; + } + } + if (!tried_sending_message) { msg.msg_control = nullptr; msg.msg_controllen = 0; @@ -849,17 +980,18 @@ static bool tcp_flush(grpc_tcp* tcp, grpc_error** error) { // unref all and forget about all slices that have been written to this // point for (size_t idx = 0; idx < unwind_slice_idx; ++idx) { - grpc_slice_unref_internal( - grpc_slice_buffer_take_first(tcp->outgoing_buffer)); + grpc_slice_buffer_remove_first(tcp->outgoing_buffer); } return false; } else if (errno == EPIPE) { *error = tcp_annotate_error(GRPC_OS_ERROR(errno, "sendmsg"), tcp); grpc_slice_buffer_reset_and_unref_internal(tcp->outgoing_buffer); + tcp_shutdown_buffer_list(tcp); return true; } else { *error = tcp_annotate_error(GRPC_OS_ERROR(errno, "sendmsg"), tcp); grpc_slice_buffer_reset_and_unref_internal(tcp->outgoing_buffer); + tcp_shutdown_buffer_list(tcp); return true; } } @@ -901,14 +1033,14 @@ static void tcp_handle_write(void* arg /* grpc_tcp */, grpc_error* error) { } if (!tcp_flush(tcp, &error)) { - if (grpc_tcp_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { gpr_log(GPR_INFO, "write: delayed"); } notify_on_write(tcp); } else { cb = tcp->write_cb; tcp->write_cb = nullptr; - if (grpc_tcp_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { const char* str = grpc_error_string(error); gpr_log(GPR_INFO, "write: %s", str); } @@ -923,30 +1055,34 @@ static void tcp_write(grpc_endpoint* ep, grpc_slice_buffer* buf, grpc_tcp* tcp = reinterpret_cast(ep); grpc_error* error = GRPC_ERROR_NONE; - if (grpc_tcp_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { size_t i; for (i = 0; i < buf->count; i++) { - char* data = - grpc_dump_slice(buf->slices[i], GPR_DUMP_HEX | GPR_DUMP_ASCII); - gpr_log(GPR_INFO, "WRITE %p (peer=%s): %s", tcp, tcp->peer_string, data); - gpr_free(data); + gpr_log(GPR_INFO, "WRITE %p (peer=%s)", tcp, tcp->peer_string); + if (gpr_should_log(GPR_LOG_SEVERITY_DEBUG)) { + char* data = + grpc_dump_slice(buf->slices[i], GPR_DUMP_HEX | GPR_DUMP_ASCII); + gpr_log(GPR_DEBUG, "DATA: %s", data); + gpr_free(data); + } } } GPR_ASSERT(tcp->write_cb == nullptr); + tcp->outgoing_buffer_arg = arg; if (buf->length == 0) { GRPC_CLOSURE_SCHED( cb, grpc_fd_is_shutdown(tcp->em_fd) ? tcp_annotate_error( GRPC_ERROR_CREATE_FROM_STATIC_STRING("EOF"), tcp) : GRPC_ERROR_NONE); + tcp_shutdown_buffer_list(tcp); return; } tcp->outgoing_buffer = buf; tcp->outgoing_byte_idx = 0; - tcp->outgoing_buffer_arg = arg; if (arg) { GPR_ASSERT(grpc_event_engine_can_track_errors()); } @@ -954,12 +1090,12 @@ static void tcp_write(grpc_endpoint* ep, grpc_slice_buffer* buf, if (!tcp_flush(tcp, &error)) { TCP_REF(tcp, "write"); tcp->write_cb = cb; - if (grpc_tcp_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { gpr_log(GPR_INFO, "write: delayed"); } notify_on_write(tcp); } else { - if (grpc_tcp_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { const char* str = grpc_error_string(error); gpr_log(GPR_INFO, "write: %s", str); } @@ -999,6 +1135,22 @@ static grpc_resource_user* tcp_get_resource_user(grpc_endpoint* ep) { return tcp->resource_user; } +static bool tcp_can_track_err(grpc_endpoint* ep) { + grpc_tcp* tcp = reinterpret_cast(ep); + if (!grpc_event_engine_can_track_errors()) { + return false; + } + struct sockaddr addr; + socklen_t len = sizeof(addr); + if (getsockname(tcp->fd, &addr, &len) < 0) { + return false; + } + if (addr.sa_family == AF_INET || addr.sa_family == AF_INET6) { + return true; + } + return false; +} + static const grpc_endpoint_vtable vtable = {tcp_read, tcp_write, tcp_add_to_pollset, @@ -1008,7 +1160,8 @@ static const grpc_endpoint_vtable vtable = {tcp_read, tcp_destroy, tcp_get_resource_user, tcp_get_peer, - tcp_get_fd}; + tcp_get_fd, + tcp_can_track_err}; #define MAX_CHUNK_SIZE 32 * 1024 * 1024 @@ -1069,6 +1222,8 @@ grpc_endpoint* grpc_tcp_create(grpc_fd* em_fd, tcp->is_first_read = true; tcp->bytes_counter = -1; tcp->socket_ts_enabled = false; + tcp->ts_capable = true; + tcp->outgoing_buffer_arg = nullptr; /* paired with unref in grpc_tcp_destroy */ gpr_ref_init(&tcp->refcount, 1); gpr_atm_no_barrier_store(&tcp->shutdown_count, 0); @@ -1077,11 +1232,34 @@ grpc_endpoint* grpc_tcp_create(grpc_fd* em_fd, tcp->resource_user = grpc_resource_user_create(resource_quota, peer_string); grpc_resource_user_slice_allocator_init( &tcp->slice_allocator, tcp->resource_user, tcp_read_allocation_done, tcp); - /* Tell network status tracker about new endpoint */ - grpc_network_status_register_endpoint(&tcp->base); grpc_resource_quota_unref_internal(resource_quota); gpr_mu_init(&tcp->tb_mu); tcp->tb_head = nullptr; + GRPC_CLOSURE_INIT(&tcp->read_done_closure, tcp_handle_read, tcp, + grpc_schedule_on_exec_ctx); + if (grpc_event_engine_run_in_background()) { + // If there is a polling engine always running in the background, there is + // no need to run the backup poller. + GRPC_CLOSURE_INIT(&tcp->write_done_closure, tcp_handle_write, tcp, + grpc_schedule_on_exec_ctx); + } else { + GRPC_CLOSURE_INIT(&tcp->write_done_closure, + tcp_drop_uncovered_then_handle_write, tcp, + grpc_schedule_on_exec_ctx); + } + /* Always assume there is something on the queue to read. */ + tcp->inq = 1; +#ifdef GRPC_HAVE_TCP_INQ + int one = 1; + if (setsockopt(tcp->fd, SOL_TCP, TCP_INQ, &one, sizeof(one)) == 0) { + tcp->inq_capable = true; + } else { + gpr_log(GPR_DEBUG, "cannot set inq fd=%d errno=%d", tcp->fd, errno); + tcp->inq_capable = false; + } +#else + tcp->inq_capable = false; +#endif /* GRPC_HAVE_TCP_INQ */ /* Start being notified on errors if event engine can track errors. */ if (grpc_event_engine_can_track_errors()) { /* Grab a ref to tcp so that we can safely access the tcp struct when @@ -1105,7 +1283,6 @@ int grpc_tcp_fd(grpc_endpoint* ep) { void grpc_tcp_destroy_and_release_fd(grpc_endpoint* ep, int* fd, grpc_closure* done) { - grpc_network_status_unregister_endpoint(ep); grpc_tcp* tcp = reinterpret_cast(ep); GPR_ASSERT(ep->vtable == &vtable); tcp->release_fd = fd; diff --git a/src/core/lib/iomgr/tcp_server_custom.cc b/src/core/lib/iomgr/tcp_server_custom.cc index 019b354473b..133847d3cd3 100644 --- a/src/core/lib/iomgr/tcp_server_custom.cc +++ b/src/core/lib/iomgr/tcp_server_custom.cc @@ -220,7 +220,7 @@ static void finish_accept(grpc_tcp_listener* sp, grpc_custom_socket* socket) { GRPC_LOG_IF_ERROR("getpeername error", err); GRPC_ERROR_UNREF(err); } - if (grpc_tcp_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { if (peer_name_string) { gpr_log(GPR_INFO, "SERVER_CONNECT: %p accepted connection: %s", sp->server, peer_name_string); @@ -372,7 +372,7 @@ static grpc_error* tcp_server_add_port(grpc_tcp_server* s, addr = &wildcard; } - if (grpc_tcp_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { char* port_string; grpc_sockaddr_to_string(&port_string, addr, 0); const char* str = grpc_error_string(error); @@ -418,7 +418,7 @@ static void tcp_server_start(grpc_tcp_server* server, grpc_pollset** pollsets, (void)pollsets; (void)pollset_count; GRPC_CUSTOM_IOMGR_ASSERT_SAME_THREAD(); - if (grpc_tcp_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { gpr_log(GPR_INFO, "SERVER_START %p", server); } GPR_ASSERT(on_accept_cb); diff --git a/src/core/lib/iomgr/tcp_server_posix.cc b/src/core/lib/iomgr/tcp_server_posix.cc index 824db07fbfd..0133972e5f7 100644 --- a/src/core/lib/iomgr/tcp_server_posix.cc +++ b/src/core/lib/iomgr/tcp_server_posix.cc @@ -217,12 +217,25 @@ static void on_read(void* arg, grpc_error* err) { } } + /* For UNIX sockets, the accept call might not fill up the member sun_path + * of sockaddr_un, so explicitly call getsockname to get it. */ + if (grpc_is_unix_socket(&addr)) { + memset(&addr, 0, sizeof(addr)); + addr.len = static_cast(sizeof(struct sockaddr_storage)); + if (getsockname(fd, reinterpret_cast(addr.addr), + &(addr.len)) < 0) { + gpr_log(GPR_ERROR, "Failed getsockname: %s", strerror(errno)); + close(fd); + goto error; + } + } + grpc_set_socket_no_sigpipe_if_possible(fd); addr_str = grpc_sockaddr_to_uri(&addr); gpr_asprintf(&name, "tcp-server-connection:%s", addr_str); - if (grpc_tcp_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { gpr_log(GPR_INFO, "SERVER_CONNECT: incoming connection: %s", addr_str); } diff --git a/src/core/lib/iomgr/tcp_server_windows.cc b/src/core/lib/iomgr/tcp_server_windows.cc index b01afdcc9db..7ac423440e2 100644 --- a/src/core/lib/iomgr/tcp_server_windows.cc +++ b/src/core/lib/iomgr/tcp_server_windows.cc @@ -255,7 +255,7 @@ static grpc_error* start_accept_locked(grpc_tcp_listener* port) { } sock = WSASocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, - WSA_FLAG_OVERLAPPED); + grpc_get_default_wsa_socket_flags()); if (sock == INVALID_SOCKET) { error = GRPC_WSA_ERROR(WSAGetLastError(), "WSASocket"); goto failure; @@ -493,7 +493,7 @@ static grpc_error* tcp_server_add_port(grpc_tcp_server* s, } sock = WSASocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, - WSA_FLAG_OVERLAPPED); + grpc_get_default_wsa_socket_flags()); if (sock == INVALID_SOCKET) { error = GRPC_WSA_ERROR(WSAGetLastError(), "WSASocket"); goto done; diff --git a/src/core/lib/iomgr/tcp_uv.cc b/src/core/lib/iomgr/tcp_uv.cc index 8d0e4a5e79e..e53ff472fef 100644 --- a/src/core/lib/iomgr/tcp_uv.cc +++ b/src/core/lib/iomgr/tcp_uv.cc @@ -33,7 +33,6 @@ #include "src/core/lib/gpr/string.h" #include "src/core/lib/iomgr/error.h" #include "src/core/lib/iomgr/iomgr_custom.h" -#include "src/core/lib/iomgr/network_status_tracker.h" #include "src/core/lib/iomgr/resolve_address_custom.h" #include "src/core/lib/iomgr/resource_quota.h" #include "src/core/lib/iomgr/tcp_custom.h" diff --git a/src/core/lib/iomgr/tcp_windows.cc b/src/core/lib/iomgr/tcp_windows.cc index 64c4a56ae95..ae6b2b68e62 100644 --- a/src/core/lib/iomgr/tcp_windows.cc +++ b/src/core/lib/iomgr/tcp_windows.cc @@ -24,7 +24,6 @@ #include -#include "src/core/lib/iomgr/network_status_tracker.h" #include "src/core/lib/iomgr/sockaddr_windows.h" #include @@ -42,6 +41,7 @@ #include "src/core/lib/iomgr/tcp_windows.h" #include "src/core/lib/iomgr/timer.h" #include "src/core/lib/slice/slice_internal.h" +#include "src/core/lib/slice/slice_string_helpers.h" #if defined(__MSYS__) && defined(GPR_ARCH_64) /* Nasty workaround for nasty bug when using the 64 bits msys compiler @@ -74,18 +74,16 @@ static grpc_error* set_dualstack(SOCKET sock) { : GRPC_WSA_ERROR(WSAGetLastError(), "setsockopt(IPV6_V6ONLY)"); } -static grpc_error* enable_loopback_fast_path(SOCKET sock) { +static grpc_error* enable_socket_low_latency(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); + BOOL param = TRUE; + status = ::setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, + reinterpret_cast(¶m), sizeof(param)); if (status == SOCKET_ERROR) { status = WSAGetLastError(); } - return status == 0 || status == WSAEOPNOTSUPP - ? GRPC_ERROR_NONE - : GRPC_WSA_ERROR(status, "WSAIoctl(SIO_LOOPBACK_FAST_PATH)"); + return status == 0 ? GRPC_ERROR_NONE + : GRPC_WSA_ERROR(status, "setsockopt(TCP_NODELAY)"); } grpc_error* grpc_tcp_prepare_socket(SOCKET sock) { @@ -94,7 +92,7 @@ grpc_error* grpc_tcp_prepare_socket(SOCKET 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); + err = enable_socket_low_latency(sock); if (err != GRPC_ERROR_NONE) return err; return GRPC_ERROR_NONE; } @@ -112,7 +110,10 @@ typedef struct grpc_tcp { grpc_closure* read_cb; grpc_closure* write_cb; - grpc_slice read_slice; + + /* garbage after the last read */ + grpc_slice_buffer last_read_buffer; + grpc_slice_buffer* write_slices; grpc_slice_buffer* read_slices; @@ -131,6 +132,7 @@ static void tcp_free(grpc_tcp* tcp) { grpc_winsocket_destroy(tcp->socket); gpr_mu_destroy(&tcp->mu); gpr_free(tcp->peer_string); + grpc_slice_buffer_destroy_internal(&tcp->last_read_buffer); grpc_resource_user_unref(tcp->resource_user); if (tcp->shutting_down) GRPC_ERROR_UNREF(tcp->shutdown_error); gpr_free(tcp); @@ -179,9 +181,12 @@ static void on_read(void* tcpp, grpc_error* error) { grpc_tcp* tcp = (grpc_tcp*)tcpp; grpc_closure* cb = tcp->read_cb; grpc_winsocket* socket = tcp->socket; - grpc_slice sub; grpc_winsocket_callback_info* info = &socket->read_info; + if (grpc_tcp_trace.enabled()) { + gpr_log(GPR_INFO, "TCP:%p on_read", tcp); + } + GRPC_ERROR_REF(error); if (error == GRPC_ERROR_NONE) { @@ -189,13 +194,35 @@ static void on_read(void* tcpp, grpc_error* error) { char* utf8_message = gpr_format_message(info->wsa_error); error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(utf8_message); gpr_free(utf8_message); - grpc_slice_unref_internal(tcp->read_slice); + grpc_slice_buffer_reset_and_unref_internal(tcp->read_slices); } else { if (info->bytes_transfered != 0 && !tcp->shutting_down) { - sub = grpc_slice_sub_no_ref(tcp->read_slice, 0, info->bytes_transfered); - grpc_slice_buffer_add(tcp->read_slices, sub); + GPR_ASSERT((size_t)info->bytes_transfered <= tcp->read_slices->length); + if (static_cast(info->bytes_transfered) != + tcp->read_slices->length) { + grpc_slice_buffer_trim_end( + tcp->read_slices, + tcp->read_slices->length - + static_cast(info->bytes_transfered), + &tcp->last_read_buffer); + } + GPR_ASSERT((size_t)info->bytes_transfered == tcp->read_slices->length); + + if (grpc_tcp_trace.enabled()) { + size_t i; + 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_INFO, "READ %p (peer=%s): %s", tcp, tcp->peer_string, + dump); + gpr_free(dump); + } + } } else { - grpc_slice_unref_internal(tcp->read_slice); + if (grpc_tcp_trace.enabled()) { + gpr_log(GPR_INFO, "TCP:%p unref read_slice", tcp); + } + grpc_slice_buffer_reset_and_unref_internal(tcp->read_slices); error = tcp->shutting_down ? GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( "TCP stream shutting down", &tcp->shutdown_error, 1) @@ -209,15 +236,22 @@ static void on_read(void* tcpp, grpc_error* error) { GRPC_CLOSURE_SCHED(cb, error); } +#define DEFAULT_TARGET_READ_SIZE 8192 +#define MAX_WSABUF_COUNT 16 static void win_read(grpc_endpoint* ep, grpc_slice_buffer* read_slices, - grpc_closure* cb) { + grpc_closure* cb, bool urgent) { grpc_tcp* tcp = (grpc_tcp*)ep; grpc_winsocket* handle = tcp->socket; grpc_winsocket_callback_info* info = &handle->read_info; int status; DWORD bytes_read = 0; DWORD flags = 0; - WSABUF buffer; + WSABUF buffers[MAX_WSABUF_COUNT]; + size_t i; + + if (grpc_tcp_trace.enabled()) { + gpr_log(GPR_INFO, "TCP:%p win_read", tcp); + } if (tcp->shutting_down) { GRPC_CLOSURE_SCHED( @@ -229,18 +263,27 @@ static void win_read(grpc_endpoint* ep, grpc_slice_buffer* read_slices, tcp->read_cb = cb; tcp->read_slices = read_slices; grpc_slice_buffer_reset_and_unref_internal(read_slices); + grpc_slice_buffer_swap(read_slices, &tcp->last_read_buffer); - tcp->read_slice = GRPC_SLICE_MALLOC(8192); + if (tcp->read_slices->length < DEFAULT_TARGET_READ_SIZE / 2 && + tcp->read_slices->count < MAX_WSABUF_COUNT) { + // TODO(jtattermusch): slice should be allocated using resource quota + grpc_slice_buffer_add(tcp->read_slices, + GRPC_SLICE_MALLOC(DEFAULT_TARGET_READ_SIZE)); + } - buffer.len = (ULONG)GRPC_SLICE_LENGTH( - tcp->read_slice); // we know slice size fits in 32bit. - buffer.buf = (char*)GRPC_SLICE_START_PTR(tcp->read_slice); + GPR_ASSERT(tcp->read_slices->count <= MAX_WSABUF_COUNT); + for (i = 0; i < tcp->read_slices->count; i++) { + buffers[i].len = (ULONG)GRPC_SLICE_LENGTH( + tcp->read_slices->slices[i]); // we know slice size fits in 32bit. + buffers[i].buf = (char*)GRPC_SLICE_START_PTR(tcp->read_slices->slices[i]); + } TCP_REF(tcp, "read"); /* First let's try a synchronous, non-blocking read. */ - status = - WSARecv(tcp->socket->socket, &buffer, 1, &bytes_read, &flags, NULL, NULL); + status = WSARecv(tcp->socket->socket, buffers, (DWORD)tcp->read_slices->count, + &bytes_read, &flags, NULL, NULL); info->wsa_error = status == 0 ? 0 : WSAGetLastError(); /* Did we get data immediately ? Yay. */ @@ -252,8 +295,8 @@ static void win_read(grpc_endpoint* ep, grpc_slice_buffer* read_slices, /* Otherwise, let's retry, by queuing a read. */ memset(&tcp->socket->read_info.overlapped, 0, sizeof(OVERLAPPED)); - status = WSARecv(tcp->socket->socket, &buffer, 1, &bytes_read, &flags, - &info->overlapped, NULL); + status = WSARecv(tcp->socket->socket, buffers, (DWORD)tcp->read_slices->count, + &bytes_read, &flags, &info->overlapped, NULL); if (status != 0) { int wsa_error = WSAGetLastError(); @@ -275,6 +318,10 @@ static void on_write(void* tcpp, grpc_error* error) { grpc_winsocket_callback_info* info = &handle->write_info; grpc_closure* cb; + if (grpc_tcp_trace.enabled()) { + gpr_log(GPR_INFO, "TCP:%p on_write", tcp); + } + GRPC_ERROR_REF(error); gpr_mu_lock(&tcp->mu); @@ -303,11 +350,21 @@ static void win_write(grpc_endpoint* ep, grpc_slice_buffer* slices, unsigned i; DWORD bytes_sent; int status; - WSABUF local_buffers[16]; + WSABUF local_buffers[MAX_WSABUF_COUNT]; WSABUF* allocated = NULL; WSABUF* buffers = local_buffers; size_t len; + if (grpc_tcp_trace.enabled()) { + size_t i; + for (i = 0; i < slices->count; i++) { + char* data = + grpc_dump_slice(slices->slices[i], GPR_DUMP_HEX | GPR_DUMP_ASCII); + gpr_log(GPR_INFO, "WRITE %p (peer=%s): %s", tcp, tcp->peer_string, data); + gpr_free(data); + } + } + if (tcp->shutting_down) { GRPC_CLOSURE_SCHED( cb, GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( @@ -410,8 +467,8 @@ static void win_shutdown(grpc_endpoint* ep, grpc_error* why) { } static void win_destroy(grpc_endpoint* ep) { - grpc_network_status_unregister_endpoint(ep); grpc_tcp* tcp = (grpc_tcp*)ep; + grpc_slice_buffer_reset_and_unref_internal(&tcp->last_read_buffer); TCP_UNREF(tcp, "destroy"); } @@ -427,6 +484,8 @@ static grpc_resource_user* win_get_resource_user(grpc_endpoint* ep) { static int win_get_fd(grpc_endpoint* ep) { return -1; } +static bool win_can_track_err(grpc_endpoint* ep) { return false; } + static grpc_endpoint_vtable vtable = {win_read, win_write, win_add_to_pollset, @@ -436,7 +495,8 @@ static grpc_endpoint_vtable vtable = {win_read, win_destroy, win_get_resource_user, win_get_peer, - win_get_fd}; + win_get_fd, + win_can_track_err}; grpc_endpoint* grpc_tcp_create(grpc_winsocket* socket, grpc_channel_args* channel_args, @@ -460,9 +520,8 @@ grpc_endpoint* grpc_tcp_create(grpc_winsocket* socket, GRPC_CLOSURE_INIT(&tcp->on_read, on_read, tcp, grpc_schedule_on_exec_ctx); GRPC_CLOSURE_INIT(&tcp->on_write, on_write, tcp, grpc_schedule_on_exec_ctx); tcp->peer_string = gpr_strdup(peer_string); + grpc_slice_buffer_init(&tcp->last_read_buffer); tcp->resource_user = grpc_resource_user_create(resource_quota, peer_string); - /* Tell network status tracking code about the new endpoint */ - grpc_network_status_register_endpoint(&tcp->base); grpc_resource_quota_unref_internal(resource_quota); return &tcp->base; diff --git a/src/core/lib/iomgr/timer_generic.cc b/src/core/lib/iomgr/timer_generic.cc index 6a925add80c..00c18789481 100644 --- a/src/core/lib/iomgr/timer_generic.cc +++ b/src/core/lib/iomgr/timer_generic.cc @@ -361,7 +361,7 @@ static void timer_init(grpc_timer* timer, grpc_millis deadline, timer->hash_table_next = nullptr; #endif - if (grpc_timer_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_timer_trace)) { gpr_log(GPR_INFO, "TIMER %p: SET %" PRId64 " now %" PRId64 " call %p[%p]", timer, deadline, grpc_core::ExecCtx::Get()->Now(), closure, closure->cb); @@ -397,7 +397,7 @@ static void timer_init(grpc_timer* timer, grpc_millis deadline, timer->heap_index = INVALID_HEAP_INDEX; list_join(&shard->list, timer); } - if (grpc_timer_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_timer_trace)) { gpr_log(GPR_INFO, " .. add to shard %d with queue_deadline_cap=%" PRId64 " => is_first_timer=%s", @@ -419,7 +419,7 @@ static void timer_init(grpc_timer* timer, grpc_millis deadline, grpc_timer_check. */ if (is_first_timer) { gpr_mu_lock(&g_shared_mutables.mu); - if (grpc_timer_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_timer_trace)) { gpr_log(GPR_INFO, " .. old shard min_deadline=%" PRId64, shard->min_deadline); } @@ -463,7 +463,7 @@ static void timer_cancel(grpc_timer* timer) { timer_shard* shard = &g_shards[GPR_HASH_POINTER(timer, g_num_shards)]; gpr_mu_lock(&shard->mu); - if (grpc_timer_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_timer_trace)) { gpr_log(GPR_INFO, "TIMER %p: CANCEL pending=%s", timer, timer->pending ? "true" : "false"); } @@ -487,7 +487,7 @@ static void timer_cancel(grpc_timer* timer) { /* Rebalances the timer shard by computing a new 'queue_deadline_cap' and moving all relevant timers in shard->list (i.e timers with deadlines earlier than 'queue_deadline_cap') into into shard->heap. - Returns 'true' if shard->heap has atleast ONE element + Returns 'true' if shard->heap has at least ONE element REQUIRES: shard->mu locked */ static bool refill_heap(timer_shard* shard, grpc_millis now) { /* Compute the new queue window width and bound by the limits: */ @@ -504,7 +504,7 @@ static bool refill_heap(timer_shard* shard, grpc_millis now) { saturating_add(GPR_MAX(now, shard->queue_deadline_cap), static_cast(deadline_delta * 1000.0)); - if (grpc_timer_check_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_timer_check_trace)) { gpr_log(GPR_INFO, " .. shard[%d]->queue_deadline_cap --> %" PRId64, static_cast(shard - g_shards), shard->queue_deadline_cap); } @@ -512,7 +512,7 @@ static bool refill_heap(timer_shard* shard, grpc_millis now) { next = timer->next; if (timer->deadline < shard->queue_deadline_cap) { - if (grpc_timer_check_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_timer_check_trace)) { gpr_log(GPR_INFO, " .. add timer with deadline %" PRId64 " to heap", timer->deadline); } @@ -529,7 +529,7 @@ static bool refill_heap(timer_shard* shard, grpc_millis now) { static grpc_timer* pop_one(timer_shard* shard, grpc_millis now) { grpc_timer* timer; for (;;) { - if (grpc_timer_check_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_timer_check_trace)) { gpr_log(GPR_INFO, " .. shard[%d]: heap_empty=%s", static_cast(shard - g_shards), grpc_timer_heap_is_empty(&shard->heap) ? "true" : "false"); @@ -539,13 +539,13 @@ static grpc_timer* pop_one(timer_shard* shard, grpc_millis now) { if (!refill_heap(shard, now)) return nullptr; } timer = grpc_timer_heap_top(&shard->heap); - if (grpc_timer_check_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_timer_check_trace)) { gpr_log(GPR_INFO, " .. check top timer deadline=%" PRId64 " now=%" PRId64, timer->deadline, now); } if (timer->deadline > now) return nullptr; - if (grpc_timer_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_timer_trace)) { gpr_log(GPR_INFO, "TIMER %p: FIRE %" PRId64 "ms late via %s scheduler", timer, now - timer->deadline, timer->closure->scheduler->vtable->name); @@ -569,7 +569,7 @@ static size_t pop_timers(timer_shard* shard, grpc_millis now, } *new_min_deadline = compute_min_deadline(shard); gpr_mu_unlock(&shard->mu); - if (grpc_timer_check_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_timer_check_trace)) { gpr_log(GPR_INFO, " .. shard[%d] popped %" PRIdPTR, static_cast(shard - g_shards), n); } @@ -606,7 +606,7 @@ static grpc_timer_check_result run_some_expired_timers(grpc_millis now, gpr_mu_lock(&g_shared_mutables.mu); result = GRPC_TIMERS_CHECKED_AND_EMPTY; - if (grpc_timer_check_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_timer_check_trace)) { gpr_log(GPR_INFO, " .. shard[%d]->min_deadline = %" PRId64, static_cast(g_shard_queue[0] - g_shards), g_shard_queue[0]->min_deadline); @@ -624,7 +624,7 @@ static grpc_timer_check_result run_some_expired_timers(grpc_millis now, result = GRPC_TIMERS_FIRED; } - if (grpc_timer_check_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_timer_check_trace)) { gpr_log(GPR_INFO, " .. result --> %d" ", shard[%d]->min_deadline %" PRId64 " --> %" PRId64 @@ -691,7 +691,7 @@ static grpc_timer_check_result timer_check(grpc_millis* next) { if (next != nullptr) { *next = GPR_MIN(*next, min_timer); } - if (grpc_timer_check_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_timer_check_trace)) { gpr_log(GPR_INFO, "TIMER CHECK SKIP: now=%" PRId64 " min_timer=%" PRId64, now, min_timer); } @@ -704,7 +704,7 @@ static grpc_timer_check_result timer_check(grpc_millis* next) { : GRPC_ERROR_CREATE_FROM_STATIC_STRING("Shutting down timer system"); // tracing - if (grpc_timer_check_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_timer_check_trace)) { char* next_str; if (next == nullptr) { next_str = gpr_strdup("NULL"); @@ -728,7 +728,7 @@ static grpc_timer_check_result timer_check(grpc_millis* next) { grpc_timer_check_result r = run_some_expired_timers(now, next, shutdown_error); // tracing - if (grpc_timer_check_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_timer_check_trace)) { char* next_str; if (next == nullptr) { next_str = gpr_strdup("NULL"); diff --git a/src/core/lib/iomgr/timer_manager.cc b/src/core/lib/iomgr/timer_manager.cc index ceba79f6783..bdf54909b4c 100644 --- a/src/core/lib/iomgr/timer_manager.cc +++ b/src/core/lib/iomgr/timer_manager.cc @@ -67,6 +67,7 @@ static void timer_thread(void* completed_thread_ptr); extern int64_t g_timer_manager_init_count; extern int64_t g_timer_manager_shutdown_count; extern int64_t g_fork_count; +extern int64_t g_next_value; #endif // GRPC_DEBUG_TIMER_MANAGER static void gc_completed_threads(void) { @@ -89,7 +90,7 @@ static void start_timer_thread_and_unlock(void) { ++g_waiter_count; ++g_thread_count; gpr_mu_unlock(&g_mu); - if (grpc_timer_check_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_timer_check_trace)) { gpr_log(GPR_INFO, "Spawn timer thread"); } completed_thread* ct = @@ -104,6 +105,14 @@ void grpc_timer_manager_tick() { } static void run_some_timers() { + // In the case of timers, the ExecCtx for the thread is declared + // in the timer thread itself, but this is the point where we + // could start seeing application-level callbacks. No need to + // create a new ExecCtx, though, since there already is one and it is + // flushed (but not destructed) in this function itself + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx( + GRPC_APP_CALLBACK_EXEC_CTX_FLAG_IS_INTERNAL_THREAD); + // if there's something to execute... gpr_mu_lock(&g_mu); // remove a waiter from the pool, and start another thread if necessary @@ -117,7 +126,7 @@ static void run_some_timers() { // if there's no thread waiting with a timeout, kick an existing untimed // waiter so that the next deadline is not missed if (!g_has_timed_waiter) { - if (grpc_timer_check_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_timer_check_trace)) { gpr_log(GPR_INFO, "kick untimed waiter"); } gpr_cv_signal(&g_cv_wait); @@ -125,7 +134,7 @@ static void run_some_timers() { gpr_mu_unlock(&g_mu); } // without our lock, flush the exec_ctx - if (grpc_timer_check_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_timer_check_trace)) { gpr_log(GPR_INFO, "flush exec_ctx"); } grpc_core::ExecCtx::Get()->Flush(); @@ -180,7 +189,7 @@ static bool wait_until(grpc_millis next) { g_has_timed_waiter = true; g_timed_waiter_deadline = next; - if (grpc_timer_check_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_timer_check_trace)) { grpc_millis wait_time = next - grpc_core::ExecCtx::Get()->Now(); gpr_log(GPR_INFO, "sleep for a %" PRId64 " milliseconds", wait_time); } @@ -189,14 +198,20 @@ static bool wait_until(grpc_millis next) { } } - if (grpc_timer_check_trace.enabled() && next == GRPC_MILLIS_INF_FUTURE) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_timer_check_trace) && + next == GRPC_MILLIS_INF_FUTURE) { gpr_log(GPR_INFO, "sleep until kicked"); } + // For debug of the timer manager crash only. + // TODO (mxyan): remove after bug is fixed. +#ifdef GRPC_DEBUG_TIMER_MANAGER + g_next_value = next; +#endif gpr_cv_wait(&g_cv_wait, &g_mu, grpc_millis_to_timespec(next, GPR_CLOCK_MONOTONIC)); - if (grpc_timer_check_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_timer_check_trace)) { gpr_log(GPR_INFO, "wait ended: was_timed:%d kicked:%d", my_timed_waiter_generation == g_timed_waiter_generation, g_kicked); @@ -241,7 +256,7 @@ static void timer_main_loop() { Consequently, we can just sleep forever here and be happy at some saved wakeup cycles. */ - if (grpc_timer_check_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_timer_check_trace)) { gpr_log(GPR_INFO, "timers not checked: expect another thread to"); } next = GRPC_MILLIS_INF_FUTURE; @@ -267,7 +282,7 @@ static void timer_thread_cleanup(completed_thread* ct) { ct->next = g_completed_threads; g_completed_threads = ct; gpr_mu_unlock(&g_mu); - if (grpc_timer_check_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_timer_check_trace)) { gpr_log(GPR_INFO, "End timer thread"); } } @@ -313,18 +328,18 @@ void grpc_timer_manager_init(void) { static void stop_threads(void) { gpr_mu_lock(&g_mu); - if (grpc_timer_check_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_timer_check_trace)) { 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()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_timer_check_trace)) { 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()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_timer_check_trace)) { gpr_log(GPR_INFO, "num timer threads: %d", g_thread_count); } gc_completed_threads(); diff --git a/src/core/lib/iomgr/udp_server.cc b/src/core/lib/iomgr/udp_server.cc index 3dd7cab855c..3e853945555 100644 --- a/src/core/lib/iomgr/udp_server.cc +++ b/src/core/lib/iomgr/udp_server.cc @@ -332,7 +332,7 @@ void GrpcUdpListener::OnFdAboutToOrphan() { GRPC_CLOSURE_INIT(&destroyed_closure_, destroyed_port, server_, grpc_schedule_on_exec_ctx); if (!orphan_notified_ && udp_handler_ != nullptr) { - /* Singals udp_handler that the FD is about to be closed and + /* Signals udp_handler that the FD is about to be closed and * should no longer be used. */ GRPC_CLOSURE_INIT(&orphan_fd_closure_, shutdown_fd, this, grpc_schedule_on_exec_ctx); @@ -481,8 +481,9 @@ void GrpcUdpListener::OnRead(grpc_error* error, void* do_read_arg) { if (udp_handler_->Read()) { /* There maybe more packets to read. Schedule read_more_cb_ closure to run * after finishing this event loop. */ - GRPC_CLOSURE_INIT(&do_read_closure_, do_read, do_read_arg, - grpc_executor_scheduler(GRPC_EXECUTOR_LONG)); + GRPC_CLOSURE_INIT( + &do_read_closure_, do_read, do_read_arg, + grpc_core::Executor::Scheduler(grpc_core::ExecutorJobType::LONG)); GRPC_CLOSURE_SCHED(&do_read_closure_, GRPC_ERROR_NONE); } else { /* Finish reading all the packets, re-arm the notification event so we can @@ -542,8 +543,9 @@ void GrpcUdpListener::OnCanWrite(grpc_error* error, void* do_write_arg) { } /* Schedule actual write in another thread. */ - GRPC_CLOSURE_INIT(&do_write_closure_, do_write, do_write_arg, - grpc_executor_scheduler(GRPC_EXECUTOR_LONG)); + GRPC_CLOSURE_INIT( + &do_write_closure_, do_write, do_write_arg, + grpc_core::Executor::Scheduler(grpc_core::ExecutorJobType::LONG)); GRPC_CLOSURE_SCHED(&do_write_closure_, GRPC_ERROR_NONE); } @@ -643,7 +645,7 @@ int grpc_udp_server_add_port(grpc_udp_server* s, 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 following successfully created socket should have same port as * the first one. */ GPR_ASSERT(port == allocated_port1); } diff --git a/src/core/lib/iomgr/wakeup_fd_cv.cc b/src/core/lib/iomgr/wakeup_fd_cv.cc deleted file mode 100644 index 74faa6379ef..00000000000 --- a/src/core/lib/iomgr/wakeup_fd_cv.cc +++ /dev/null @@ -1,107 +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. - * - */ - -#include - -#include "src/core/lib/iomgr/port.h" - -#ifdef GRPC_POSIX_WAKEUP_FD - -#include "src/core/lib/iomgr/wakeup_fd_cv.h" - -#include -#include - -#include -#include -#include -#include - -#include "src/core/lib/gpr/useful.h" -#include "src/core/lib/gprpp/thd.h" - -#define MAX_TABLE_RESIZE 256 - -extern grpc_cv_fd_table g_cvfds; - -static grpc_error* cv_fd_init(grpc_wakeup_fd* fd_info) { - unsigned int i, newsize; - int idx; - gpr_mu_lock(&g_cvfds.mu); - if (!g_cvfds.free_fds) { - newsize = GPR_MIN(g_cvfds.size * 2, g_cvfds.size + MAX_TABLE_RESIZE); - g_cvfds.cvfds = static_cast( - gpr_realloc(g_cvfds.cvfds, sizeof(grpc_fd_node) * newsize)); - for (i = g_cvfds.size; i < newsize; i++) { - g_cvfds.cvfds[i].is_set = 0; - g_cvfds.cvfds[i].cvs = nullptr; - g_cvfds.cvfds[i].next_free = g_cvfds.free_fds; - g_cvfds.free_fds = &g_cvfds.cvfds[i]; - } - g_cvfds.size = newsize; - } - - idx = static_cast(g_cvfds.free_fds - g_cvfds.cvfds); - g_cvfds.free_fds = g_cvfds.free_fds->next_free; - g_cvfds.cvfds[idx].cvs = nullptr; - g_cvfds.cvfds[idx].is_set = 0; - fd_info->read_fd = GRPC_IDX_TO_FD(idx); - fd_info->write_fd = -1; - gpr_mu_unlock(&g_cvfds.mu); - return GRPC_ERROR_NONE; -} - -static grpc_error* cv_fd_wakeup(grpc_wakeup_fd* fd_info) { - grpc_cv_node* cvn; - gpr_mu_lock(&g_cvfds.mu); - g_cvfds.cvfds[GRPC_FD_TO_IDX(fd_info->read_fd)].is_set = 1; - cvn = g_cvfds.cvfds[GRPC_FD_TO_IDX(fd_info->read_fd)].cvs; - while (cvn) { - gpr_cv_signal(cvn->cv); - cvn = cvn->next; - } - gpr_mu_unlock(&g_cvfds.mu); - return GRPC_ERROR_NONE; -} - -static grpc_error* cv_fd_consume(grpc_wakeup_fd* fd_info) { - gpr_mu_lock(&g_cvfds.mu); - g_cvfds.cvfds[GRPC_FD_TO_IDX(fd_info->read_fd)].is_set = 0; - gpr_mu_unlock(&g_cvfds.mu); - return GRPC_ERROR_NONE; -} - -static void cv_fd_destroy(grpc_wakeup_fd* fd_info) { - if (fd_info->read_fd == 0) { - return; - } - gpr_mu_lock(&g_cvfds.mu); - // Assert that there are no active pollers - GPR_ASSERT(!g_cvfds.cvfds[GRPC_FD_TO_IDX(fd_info->read_fd)].cvs); - g_cvfds.cvfds[GRPC_FD_TO_IDX(fd_info->read_fd)].next_free = g_cvfds.free_fds; - g_cvfds.free_fds = &g_cvfds.cvfds[GRPC_FD_TO_IDX(fd_info->read_fd)]; - gpr_mu_unlock(&g_cvfds.mu); -} - -static int cv_check_availability(void) { return 1; } - -const grpc_wakeup_fd_vtable grpc_cv_wakeup_fd_vtable = { - cv_fd_init, cv_fd_consume, cv_fd_wakeup, cv_fd_destroy, - cv_check_availability}; - -#endif /* GRPC_POSIX_WAKUP_FD */ diff --git a/src/core/lib/iomgr/wakeup_fd_cv.h b/src/core/lib/iomgr/wakeup_fd_cv.h deleted file mode 100644 index 86365f07e17..00000000000 --- a/src/core/lib/iomgr/wakeup_fd_cv.h +++ /dev/null @@ -1,69 +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. - * - */ - -/* - * wakeup_fd_cv uses condition variables to implement wakeup fds. - * - * It is intended for use only in cases when eventfd() and pipe() are not - * available. It can only be used with the "poll" engine. - * - * Implementation: - * A global table of cv wakeup fds is mantained. A cv wakeup fd is a negative - * file descriptor. poll() is then run in a background thread with only the - * real socket fds while we wait on a condition variable trigged by either the - * poll() completion or a wakeup_fd() call. - * - */ - -#ifndef GRPC_CORE_LIB_IOMGR_WAKEUP_FD_CV_H -#define GRPC_CORE_LIB_IOMGR_WAKEUP_FD_CV_H - -#include - -#include - -#include "src/core/lib/iomgr/ev_posix.h" - -#define GRPC_FD_TO_IDX(fd) (-(fd)-1) -#define GRPC_IDX_TO_FD(idx) (-(idx)-1) - -typedef struct grpc_cv_node { - gpr_cv* cv; - struct grpc_cv_node* next; - struct grpc_cv_node* prev; -} grpc_cv_node; - -typedef struct grpc_fd_node { - int is_set; - grpc_cv_node* cvs; - struct grpc_fd_node* next_free; -} grpc_fd_node; - -typedef struct grpc_cv_fd_table { - gpr_mu mu; - gpr_refcount pollcount; - gpr_cv shutdown_cv; - grpc_fd_node* cvfds; - grpc_fd_node* free_fds; - unsigned int size; - grpc_poll_function_type poll; -} grpc_cv_fd_table; - -extern const grpc_wakeup_fd_vtable grpc_cv_wakeup_fd_vtable; - -#endif /* GRPC_CORE_LIB_IOMGR_WAKEUP_FD_CV_H */ diff --git a/src/core/lib/iomgr/wakeup_fd_posix.cc b/src/core/lib/iomgr/wakeup_fd_posix.cc index b5b8b37a9af..3b66d6f34de 100644 --- a/src/core/lib/iomgr/wakeup_fd_posix.cc +++ b/src/core/lib/iomgr/wakeup_fd_posix.cc @@ -23,7 +23,6 @@ #ifdef GRPC_POSIX_WAKEUP_FD #include -#include "src/core/lib/iomgr/wakeup_fd_cv.h" #include "src/core/lib/iomgr/wakeup_fd_pipe.h" #include "src/core/lib/iomgr/wakeup_fd_posix.h" @@ -51,37 +50,20 @@ void grpc_wakeup_fd_global_destroy(void) { wakeup_fd_vtable = nullptr; } int grpc_has_wakeup_fd(void) { return has_real_wakeup_fd; } -int grpc_cv_wakeup_fds_enabled(void) { return cv_wakeup_fds_enabled; } - -void grpc_enable_cv_wakeup_fds(int enable) { cv_wakeup_fds_enabled = enable; } - grpc_error* grpc_wakeup_fd_init(grpc_wakeup_fd* fd_info) { - if (cv_wakeup_fds_enabled) { - return grpc_cv_wakeup_fd_vtable.init(fd_info); - } return wakeup_fd_vtable->init(fd_info); } grpc_error* grpc_wakeup_fd_consume_wakeup(grpc_wakeup_fd* fd_info) { - if (cv_wakeup_fds_enabled) { - return grpc_cv_wakeup_fd_vtable.consume(fd_info); - } return wakeup_fd_vtable->consume(fd_info); } grpc_error* grpc_wakeup_fd_wakeup(grpc_wakeup_fd* fd_info) { - if (cv_wakeup_fds_enabled) { - return grpc_cv_wakeup_fd_vtable.wakeup(fd_info); - } return wakeup_fd_vtable->wakeup(fd_info); } void grpc_wakeup_fd_destroy(grpc_wakeup_fd* fd_info) { - if (cv_wakeup_fds_enabled) { - grpc_cv_wakeup_fd_vtable.destroy(fd_info); - } else { - wakeup_fd_vtable->destroy(fd_info); - } + wakeup_fd_vtable->destroy(fd_info); } #endif /* GRPC_POSIX_WAKEUP_FD */ diff --git a/src/core/lib/json/json.cc b/src/core/lib/json/json.cc index e78b73cefd3..2ed45fe55fe 100644 --- a/src/core/lib/json/json.cc +++ b/src/core/lib/json/json.cc @@ -35,24 +35,21 @@ grpc_json* grpc_json_create(grpc_json_type type) { } void grpc_json_destroy(grpc_json* json) { + if (json == nullptr) return; while (json->child) { grpc_json_destroy(json->child); } - if (json->next) { json->next->prev = json->prev; } - if (json->prev) { json->prev->next = json->next; } else if (json->parent) { json->parent->child = json->next; } - if (json->owns_value) { gpr_free((void*)json->value); } - gpr_free(json); } diff --git a/src/core/lib/security/context/security_context.cc b/src/core/lib/security/context/security_context.cc index 16f40b4f55d..ef60165899d 100644 --- a/src/core/lib/security/context/security_context.cc +++ b/src/core/lib/security/context/security_context.cc @@ -21,8 +21,10 @@ #include #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/arena.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/arena.h" +#include "src/core/lib/gprpp/ref_counted.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/security/context/security_context.h" #include "src/core/lib/surface/api_trace.h" #include "src/core/lib/surface/call.h" @@ -50,13 +52,11 @@ grpc_call_error grpc_call_set_credentials(grpc_call* call, ctx = static_cast( grpc_call_context_get(call, GRPC_CONTEXT_SECURITY)); if (ctx == nullptr) { - ctx = grpc_client_security_context_create(grpc_call_get_arena(call)); - ctx->creds = grpc_call_credentials_ref(creds); + ctx = grpc_client_security_context_create(grpc_call_get_arena(call), creds); grpc_call_context_set(call, GRPC_CONTEXT_SECURITY, ctx, grpc_client_security_context_destroy); } else { - grpc_call_credentials_unref(ctx->creds); - ctx->creds = grpc_call_credentials_ref(creds); + ctx->creds = creds != nullptr ? creds->Ref() : nullptr; } return GRPC_CALL_OK; @@ -66,33 +66,45 @@ grpc_auth_context* grpc_call_auth_context(grpc_call* call) { void* sec_ctx = grpc_call_context_get(call, GRPC_CONTEXT_SECURITY); GRPC_API_TRACE("grpc_call_auth_context(call=%p)", 1, (call)); if (sec_ctx == nullptr) return nullptr; - return grpc_call_is_client(call) - ? GRPC_AUTH_CONTEXT_REF( - ((grpc_client_security_context*)sec_ctx)->auth_context, - "grpc_call_auth_context client") - : GRPC_AUTH_CONTEXT_REF( - ((grpc_server_security_context*)sec_ctx)->auth_context, - "grpc_call_auth_context server"); + if (grpc_call_is_client(call)) { + auto* sc = static_cast(sec_ctx); + if (sc->auth_context == nullptr) { + return nullptr; + } else { + return sc->auth_context + ->Ref(DEBUG_LOCATION, "grpc_call_auth_context client") + .release(); + } + } else { + auto* sc = static_cast(sec_ctx); + if (sc->auth_context == nullptr) { + return nullptr; + } else { + return sc->auth_context + ->Ref(DEBUG_LOCATION, "grpc_call_auth_context server") + .release(); + } + } } void grpc_auth_context_release(grpc_auth_context* context) { GRPC_API_TRACE("grpc_auth_context_release(context=%p)", 1, (context)); - GRPC_AUTH_CONTEXT_UNREF(context, "grpc_auth_context_unref"); + if (context == nullptr) return; + context->Unref(DEBUG_LOCATION, "grpc_auth_context_unref"); } /* --- grpc_client_security_context --- */ grpc_client_security_context::~grpc_client_security_context() { - grpc_call_credentials_unref(creds); - GRPC_AUTH_CONTEXT_UNREF(auth_context, "client_security_context"); + auth_context.reset(DEBUG_LOCATION, "client_security_context"); if (extension.instance != nullptr && extension.destroy != nullptr) { extension.destroy(extension.instance); } } grpc_client_security_context* grpc_client_security_context_create( - gpr_arena* arena) { - return new (gpr_arena_alloc(arena, sizeof(grpc_client_security_context))) - grpc_client_security_context(); + grpc_core::Arena* arena, grpc_call_credentials* creds) { + return arena->New( + creds != nullptr ? creds->Ref() : nullptr); } void grpc_client_security_context_destroy(void* ctx) { @@ -104,16 +116,15 @@ void grpc_client_security_context_destroy(void* ctx) { /* --- grpc_server_security_context --- */ grpc_server_security_context::~grpc_server_security_context() { - GRPC_AUTH_CONTEXT_UNREF(auth_context, "server_security_context"); + auth_context.reset(DEBUG_LOCATION, "server_security_context"); if (extension.instance != nullptr && extension.destroy != nullptr) { extension.destroy(extension.instance); } } grpc_server_security_context* grpc_server_security_context_create( - gpr_arena* arena) { - return new (gpr_arena_alloc(arena, sizeof(grpc_server_security_context))) - grpc_server_security_context(); + grpc_core::Arena* arena) { + return arena->New(); } void grpc_server_security_context_destroy(void* ctx) { @@ -126,69 +137,11 @@ void grpc_server_security_context_destroy(void* ctx) { static grpc_auth_property_iterator empty_iterator = {nullptr, 0, nullptr}; -grpc_auth_context* grpc_auth_context_create(grpc_auth_context* chained) { - grpc_auth_context* ctx = - static_cast(gpr_zalloc(sizeof(grpc_auth_context))); - gpr_ref_init(&ctx->refcount, 1); - if (chained != nullptr) { - ctx->chained = GRPC_AUTH_CONTEXT_REF(chained, "chained"); - ctx->peer_identity_property_name = - ctx->chained->peer_identity_property_name; - } - return ctx; -} - -#ifndef NDEBUG -grpc_auth_context* grpc_auth_context_ref(grpc_auth_context* ctx, - const char* file, int line, - const char* reason) { - if (ctx == nullptr) return nullptr; - if (grpc_trace_auth_context_refcount.enabled()) { - gpr_atm val = gpr_atm_no_barrier_load(&ctx->refcount.count); - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, - "AUTH_CONTEXT:%p ref %" PRIdPTR " -> %" PRIdPTR " %s", ctx, val, - val + 1, reason); - } -#else -grpc_auth_context* grpc_auth_context_ref(grpc_auth_context* ctx) { - if (ctx == nullptr) return nullptr; -#endif - gpr_ref(&ctx->refcount); - return ctx; -} - -#ifndef NDEBUG -void grpc_auth_context_unref(grpc_auth_context* ctx, const char* file, int line, - const char* reason) { - if (ctx == nullptr) return; - if (grpc_trace_auth_context_refcount.enabled()) { - gpr_atm val = gpr_atm_no_barrier_load(&ctx->refcount.count); - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, - "AUTH_CONTEXT:%p unref %" PRIdPTR " -> %" PRIdPTR " %s", ctx, val, - val - 1, reason); - } -#else -void grpc_auth_context_unref(grpc_auth_context* ctx) { - if (ctx == nullptr) return; -#endif - if (gpr_unref(&ctx->refcount)) { - size_t i; - GRPC_AUTH_CONTEXT_UNREF(ctx->chained, "chained"); - if (ctx->properties.array != nullptr) { - for (i = 0; i < ctx->properties.count; i++) { - grpc_auth_property_reset(&ctx->properties.array[i]); - } - gpr_free(ctx->properties.array); - } - gpr_free(ctx); - } -} - const char* grpc_auth_context_peer_identity_property_name( const grpc_auth_context* ctx) { GRPC_API_TRACE("grpc_auth_context_peer_identity_property_name(ctx=%p)", 1, (ctx)); - return ctx->peer_identity_property_name; + return ctx->peer_identity_property_name(); } int grpc_auth_context_set_peer_identity_property_name(grpc_auth_context* ctx, @@ -204,13 +157,13 @@ int grpc_auth_context_set_peer_identity_property_name(grpc_auth_context* ctx, name != nullptr ? name : "NULL"); return 0; } - ctx->peer_identity_property_name = prop->name; + ctx->set_peer_identity_property_name(prop->name); return 1; } int grpc_auth_context_peer_is_authenticated(const grpc_auth_context* ctx) { GRPC_API_TRACE("grpc_auth_context_peer_is_authenticated(ctx=%p)", 1, (ctx)); - return ctx->peer_identity_property_name == nullptr ? 0 : 1; + return ctx->is_authenticated(); } grpc_auth_property_iterator grpc_auth_context_property_iterator( @@ -226,16 +179,17 @@ const grpc_auth_property* grpc_auth_property_iterator_next( grpc_auth_property_iterator* it) { GRPC_API_TRACE("grpc_auth_property_iterator_next(it=%p)", 1, (it)); if (it == nullptr || it->ctx == nullptr) return nullptr; - while (it->index == it->ctx->properties.count) { - if (it->ctx->chained == nullptr) return nullptr; - it->ctx = it->ctx->chained; + while (it->index == it->ctx->properties().count) { + if (it->ctx->chained() == nullptr) return nullptr; + it->ctx = it->ctx->chained(); it->index = 0; } if (it->name == nullptr) { - return &it->ctx->properties.array[it->index++]; + return &it->ctx->properties().array[it->index++]; } else { - while (it->index < it->ctx->properties.count) { - const grpc_auth_property* prop = &it->ctx->properties.array[it->index++]; + while (it->index < it->ctx->properties().count) { + const grpc_auth_property* prop = + &it->ctx->properties().array[it->index++]; GPR_ASSERT(prop->name != nullptr); if (strcmp(it->name, prop->name) == 0) { return prop; @@ -262,30 +216,22 @@ grpc_auth_property_iterator grpc_auth_context_peer_identity( GRPC_API_TRACE("grpc_auth_context_peer_identity(ctx=%p)", 1, (ctx)); if (ctx == nullptr) return empty_iterator; return grpc_auth_context_find_properties_by_name( - ctx, ctx->peer_identity_property_name); + ctx, ctx->peer_identity_property_name()); } -static void ensure_auth_context_capacity(grpc_auth_context* ctx) { - if (ctx->properties.count == ctx->properties.capacity) { - ctx->properties.capacity = - GPR_MAX(ctx->properties.capacity + 8, ctx->properties.capacity * 2); - ctx->properties.array = static_cast( - gpr_realloc(ctx->properties.array, - ctx->properties.capacity * sizeof(grpc_auth_property))); +void grpc_auth_context::ensure_capacity() { + if (properties_.count == properties_.capacity) { + properties_.capacity = + GPR_MAX(properties_.capacity + 8, properties_.capacity * 2); + properties_.array = static_cast(gpr_realloc( + properties_.array, properties_.capacity * sizeof(grpc_auth_property))); } } -void grpc_auth_context_add_property(grpc_auth_context* ctx, const char* name, - const char* value, size_t value_length) { - grpc_auth_property* prop; - GRPC_API_TRACE( - "grpc_auth_context_add_property(ctx=%p, name=%s, value=%*.*s, " - "value_length=%lu)", - 6, - (ctx, name, (int)value_length, (int)value_length, value, - (unsigned long)value_length)); - ensure_auth_context_capacity(ctx); - prop = &ctx->properties.array[ctx->properties.count++]; +void grpc_auth_context::add_property(const char* name, const char* value, + size_t value_length) { + ensure_capacity(); + grpc_auth_property* prop = &properties_.array[properties_.count++]; prop->name = gpr_strdup(name); prop->value = static_cast(gpr_malloc(value_length + 1)); memcpy(prop->value, value, value_length); @@ -293,20 +239,35 @@ void grpc_auth_context_add_property(grpc_auth_context* ctx, const char* name, prop->value_length = value_length; } -void grpc_auth_context_add_cstring_property(grpc_auth_context* ctx, - const char* name, - const char* value) { - grpc_auth_property* prop; +void grpc_auth_context_add_property(grpc_auth_context* ctx, const char* name, + const char* value, size_t value_length) { GRPC_API_TRACE( - "grpc_auth_context_add_cstring_property(ctx=%p, name=%s, value=%s)", 3, - (ctx, name, value)); - ensure_auth_context_capacity(ctx); - prop = &ctx->properties.array[ctx->properties.count++]; + "grpc_auth_context_add_property(ctx=%p, name=%s, value=%*.*s, " + "value_length=%lu)", + 6, + (ctx, name, (int)value_length, (int)value_length, value, + (unsigned long)value_length)); + ctx->add_property(name, value, value_length); +} + +void grpc_auth_context::add_cstring_property(const char* name, + const char* value) { + ensure_capacity(); + grpc_auth_property* prop = &properties_.array[properties_.count++]; prop->name = gpr_strdup(name); prop->value = gpr_strdup(value); prop->value_length = strlen(value); } +void grpc_auth_context_add_cstring_property(grpc_auth_context* ctx, + const char* name, + const char* value) { + GRPC_API_TRACE( + "grpc_auth_context_add_cstring_property(ctx=%p, name=%s, value=%s)", 3, + (ctx, name, value)); + ctx->add_cstring_property(name, value); +} + void grpc_auth_property_reset(grpc_auth_property* property) { gpr_free(property->name); gpr_free(property->value); @@ -314,12 +275,17 @@ void grpc_auth_property_reset(grpc_auth_property* property) { } static void auth_context_pointer_arg_destroy(void* p) { - GRPC_AUTH_CONTEXT_UNREF((grpc_auth_context*)p, "auth_context_pointer_arg"); + if (p != nullptr) { + static_cast(p)->Unref(DEBUG_LOCATION, + "auth_context_pointer_arg"); + } } static void* auth_context_pointer_arg_copy(void* p) { - return GRPC_AUTH_CONTEXT_REF((grpc_auth_context*)p, - "auth_context_pointer_arg"); + auto* ctx = static_cast(p); + return ctx == nullptr + ? nullptr + : ctx->Ref(DEBUG_LOCATION, "auth_context_pointer_arg").release(); } static int auth_context_pointer_cmp(void* a, void* b) { return GPR_ICMP(a, b); } diff --git a/src/core/lib/security/context/security_context.h b/src/core/lib/security/context/security_context.h index e45415f63b8..b1991089ae5 100644 --- a/src/core/lib/security/context/security_context.h +++ b/src/core/lib/security/context/security_context.h @@ -21,13 +21,14 @@ #include +#include "src/core/lib/gprpp/arena.h" +#include "src/core/lib/gprpp/ref_counted.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/pollset.h" #include "src/core/lib/security/credentials/credentials.h" extern grpc_core::DebugOnlyTraceFlag grpc_trace_auth_context_refcount; -struct gpr_arena; - /* --- grpc_auth_context --- High level authentication context object. Can optionally be chained. */ @@ -40,39 +41,59 @@ struct grpc_auth_property_array { size_t capacity = 0; }; -struct grpc_auth_context { - grpc_auth_context() { gpr_ref_init(&refcount, 0); } - - struct grpc_auth_context* chained = nullptr; - grpc_auth_property_array properties; - gpr_refcount refcount; - const char* peer_identity_property_name = nullptr; - grpc_pollset* pollset = nullptr; -}; - -/* Creation. */ -grpc_auth_context* grpc_auth_context_create(grpc_auth_context* chained); - -/* Refcounting. */ -#ifndef NDEBUG -#define GRPC_AUTH_CONTEXT_REF(p, r) \ - grpc_auth_context_ref((p), __FILE__, __LINE__, (r)) -#define GRPC_AUTH_CONTEXT_UNREF(p, r) \ - grpc_auth_context_unref((p), __FILE__, __LINE__, (r)) -grpc_auth_context* grpc_auth_context_ref(grpc_auth_context* policy, - const char* file, int line, - const char* reason); -void grpc_auth_context_unref(grpc_auth_context* policy, const char* file, - int line, const char* reason); -#else -#define GRPC_AUTH_CONTEXT_REF(p, r) grpc_auth_context_ref((p)) -#define GRPC_AUTH_CONTEXT_UNREF(p, r) grpc_auth_context_unref((p)) -grpc_auth_context* grpc_auth_context_ref(grpc_auth_context* policy); -void grpc_auth_context_unref(grpc_auth_context* policy); -#endif - void grpc_auth_property_reset(grpc_auth_property* property); +// This type is forward declared as a C struct and we cannot define it as a +// class. Otherwise, compiler will complain about type mismatch due to +// -Wmismatched-tags. +struct grpc_auth_context + : public grpc_core::RefCounted { + public: + explicit grpc_auth_context( + grpc_core::RefCountedPtr chained) + : grpc_core::RefCounted( + &grpc_trace_auth_context_refcount), + chained_(std::move(chained)) { + if (chained_ != nullptr) { + peer_identity_property_name_ = chained_->peer_identity_property_name_; + } + } + + ~grpc_auth_context() { + chained_.reset(DEBUG_LOCATION, "chained"); + if (properties_.array != nullptr) { + for (size_t i = 0; i < properties_.count; i++) { + grpc_auth_property_reset(&properties_.array[i]); + } + gpr_free(properties_.array); + } + } + + const grpc_auth_context* chained() const { return chained_.get(); } + const grpc_auth_property_array& properties() const { return properties_; } + + bool is_authenticated() const { + return peer_identity_property_name_ != nullptr; + } + const char* peer_identity_property_name() const { + return peer_identity_property_name_; + } + void set_peer_identity_property_name(const char* name) { + peer_identity_property_name_ = name; + } + + void ensure_capacity(); + void add_property(const char* name, const char* value, size_t value_length); + void add_cstring_property(const char* name, const char* value); + + private: + grpc_core::RefCountedPtr chained_; + grpc_auth_property_array properties_; + const char* peer_identity_property_name_ = nullptr; +}; + /* --- grpc_security_context_extension --- Extension to the security context that may be set in a filter and accessed @@ -88,16 +109,18 @@ struct grpc_security_context_extension { Internal client-side security context. */ struct grpc_client_security_context { - grpc_client_security_context() = default; + explicit grpc_client_security_context( + grpc_core::RefCountedPtr creds) + : creds(std::move(creds)) {} ~grpc_client_security_context(); - grpc_call_credentials* creds = nullptr; - grpc_auth_context* auth_context = nullptr; + grpc_core::RefCountedPtr creds; + grpc_core::RefCountedPtr auth_context; grpc_security_context_extension extension; }; grpc_client_security_context* grpc_client_security_context_create( - gpr_arena* arena); + grpc_core::Arena* arena, grpc_call_credentials* creds); void grpc_client_security_context_destroy(void* ctx); /* --- grpc_server_security_context --- @@ -108,12 +131,12 @@ struct grpc_server_security_context { grpc_server_security_context() = default; ~grpc_server_security_context(); - grpc_auth_context* auth_context = nullptr; + grpc_core::RefCountedPtr auth_context; grpc_security_context_extension extension; }; grpc_server_security_context* grpc_server_security_context_create( - gpr_arena* arena); + grpc_core::Arena* arena); void grpc_server_security_context_destroy(void* ctx); /* --- Channel args for auth context --- */ diff --git a/src/core/lib/security/credentials/alts/alts_credentials.cc b/src/core/lib/security/credentials/alts/alts_credentials.cc index 1fbef4ae0c7..9a337903063 100644 --- a/src/core/lib/security/credentials/alts/alts_credentials.cc +++ b/src/core/lib/security/credentials/alts/alts_credentials.cc @@ -31,42 +31,49 @@ #include "src/core/lib/security/security_connector/alts/alts_security_connector.h" #define GRPC_CREDENTIALS_TYPE_ALTS "Alts" -#define GRPC_ALTS_HANDSHAKER_SERVICE_URL "metadata.google.internal:8080" +#define GRPC_ALTS_HANDSHAKER_SERVICE_URL "metadata.google.internal.:8080" -static void alts_credentials_destruct(grpc_channel_credentials* creds) { - grpc_alts_credentials* alts_creds = - reinterpret_cast(creds); - grpc_alts_credentials_options_destroy(alts_creds->options); - gpr_free(alts_creds->handshaker_service_url); +grpc_alts_credentials::grpc_alts_credentials( + const grpc_alts_credentials_options* options, + const char* handshaker_service_url) + : grpc_channel_credentials(GRPC_CREDENTIALS_TYPE_ALTS), + options_(grpc_alts_credentials_options_copy(options)), + handshaker_service_url_(handshaker_service_url == nullptr + ? gpr_strdup(GRPC_ALTS_HANDSHAKER_SERVICE_URL) + : gpr_strdup(handshaker_service_url)) {} + +grpc_alts_credentials::~grpc_alts_credentials() { + grpc_alts_credentials_options_destroy(options_); + gpr_free(handshaker_service_url_); } -static void alts_server_credentials_destruct(grpc_server_credentials* creds) { - grpc_alts_server_credentials* alts_creds = - reinterpret_cast(creds); - grpc_alts_credentials_options_destroy(alts_creds->options); - gpr_free(alts_creds->handshaker_service_url); -} - -static grpc_security_status alts_create_security_connector( - grpc_channel_credentials* creds, - grpc_call_credentials* request_metadata_creds, const char* target_name, - const grpc_channel_args* args, grpc_channel_security_connector** sc, +grpc_core::RefCountedPtr +grpc_alts_credentials::create_security_connector( + grpc_core::RefCountedPtr call_creds, + const char* target_name, const grpc_channel_args* args, grpc_channel_args** new_args) { return grpc_alts_channel_security_connector_create( - creds, request_metadata_creds, target_name, sc); + this->Ref(), std::move(call_creds), target_name); } -static grpc_security_status alts_server_create_security_connector( - grpc_server_credentials* creds, grpc_server_security_connector** sc) { - return grpc_alts_server_security_connector_create(creds, sc); +grpc_alts_server_credentials::grpc_alts_server_credentials( + const grpc_alts_credentials_options* options, + const char* handshaker_service_url) + : grpc_server_credentials(GRPC_CREDENTIALS_TYPE_ALTS), + options_(grpc_alts_credentials_options_copy(options)), + handshaker_service_url_(handshaker_service_url == nullptr + ? gpr_strdup(GRPC_ALTS_HANDSHAKER_SERVICE_URL) + : gpr_strdup(handshaker_service_url)) {} + +grpc_core::RefCountedPtr +grpc_alts_server_credentials::create_security_connector() { + return grpc_alts_server_security_connector_create(this->Ref()); } -static const grpc_channel_credentials_vtable alts_credentials_vtable = { - alts_credentials_destruct, alts_create_security_connector, - /*duplicate_without_call_credentials=*/nullptr}; - -static const grpc_server_credentials_vtable alts_server_credentials_vtable = { - alts_server_credentials_destruct, alts_server_create_security_connector}; +grpc_alts_server_credentials::~grpc_alts_server_credentials() { + grpc_alts_credentials_options_destroy(options_); + gpr_free(handshaker_service_url_); +} grpc_channel_credentials* grpc_alts_credentials_create_customized( const grpc_alts_credentials_options* options, @@ -74,17 +81,7 @@ grpc_channel_credentials* grpc_alts_credentials_create_customized( if (!enable_untrusted_alts && !grpc_alts_is_running_on_gcp()) { return nullptr; } - auto creds = static_cast( - gpr_zalloc(sizeof(grpc_alts_credentials))); - creds->options = grpc_alts_credentials_options_copy(options); - creds->handshaker_service_url = - handshaker_service_url == nullptr - ? gpr_strdup(GRPC_ALTS_HANDSHAKER_SERVICE_URL) - : gpr_strdup(handshaker_service_url); - creds->base.type = GRPC_CREDENTIALS_TYPE_ALTS; - creds->base.vtable = &alts_credentials_vtable; - gpr_ref_init(&creds->base.refcount, 1); - return &creds->base; + return grpc_core::New(options, handshaker_service_url); } grpc_server_credentials* grpc_alts_server_credentials_create_customized( @@ -93,17 +90,8 @@ grpc_server_credentials* grpc_alts_server_credentials_create_customized( if (!enable_untrusted_alts && !grpc_alts_is_running_on_gcp()) { return nullptr; } - auto creds = static_cast( - gpr_zalloc(sizeof(grpc_alts_server_credentials))); - creds->options = grpc_alts_credentials_options_copy(options); - creds->handshaker_service_url = - handshaker_service_url == nullptr - ? gpr_strdup(GRPC_ALTS_HANDSHAKER_SERVICE_URL) - : gpr_strdup(handshaker_service_url); - creds->base.type = GRPC_CREDENTIALS_TYPE_ALTS; - creds->base.vtable = &alts_server_credentials_vtable; - gpr_ref_init(&creds->base.refcount, 1); - return &creds->base; + return grpc_core::New(options, + handshaker_service_url); } grpc_channel_credentials* grpc_alts_credentials_create( diff --git a/src/core/lib/security/credentials/alts/alts_credentials.h b/src/core/lib/security/credentials/alts/alts_credentials.h index 810117f2bea..cc6d5222b16 100644 --- a/src/core/lib/security/credentials/alts/alts_credentials.h +++ b/src/core/lib/security/credentials/alts/alts_credentials.h @@ -27,18 +27,45 @@ #include "src/core/lib/security/credentials/credentials.h" /* Main struct for grpc ALTS channel credential. */ -typedef struct grpc_alts_credentials { - grpc_channel_credentials base; - grpc_alts_credentials_options* options; - char* handshaker_service_url; -} grpc_alts_credentials; +class grpc_alts_credentials final : public grpc_channel_credentials { + public: + grpc_alts_credentials(const grpc_alts_credentials_options* options, + const char* handshaker_service_url); + ~grpc_alts_credentials() override; + + grpc_core::RefCountedPtr + create_security_connector( + grpc_core::RefCountedPtr call_creds, + const char* target_name, const grpc_channel_args* args, + grpc_channel_args** new_args) override; + + const grpc_alts_credentials_options* options() const { return options_; } + grpc_alts_credentials_options* mutable_options() { return options_; } + const char* handshaker_service_url() const { return handshaker_service_url_; } + + private: + grpc_alts_credentials_options* options_; + char* handshaker_service_url_; +}; /* Main struct for grpc ALTS server credential. */ -typedef struct grpc_alts_server_credentials { - grpc_server_credentials base; - grpc_alts_credentials_options* options; - char* handshaker_service_url; -} grpc_alts_server_credentials; +class grpc_alts_server_credentials final : public grpc_server_credentials { + public: + grpc_alts_server_credentials(const grpc_alts_credentials_options* options, + const char* handshaker_service_url); + ~grpc_alts_server_credentials() override; + + grpc_core::RefCountedPtr + create_security_connector() override; + + const grpc_alts_credentials_options* options() const { return options_; } + grpc_alts_credentials_options* mutable_options() { return options_; } + const char* handshaker_service_url() const { return handshaker_service_url_; } + + private: + grpc_alts_credentials_options* options_; + char* handshaker_service_url_; +}; /** * This method creates an ALTS channel credential object with customized diff --git a/src/core/lib/security/credentials/alts/check_gcp_environment_no_op.cc b/src/core/lib/security/credentials/alts/check_gcp_environment_no_op.cc index d97681b86d2..b71f66a536a 100644 --- a/src/core/lib/security/credentials/alts/check_gcp_environment_no_op.cc +++ b/src/core/lib/security/credentials/alts/check_gcp_environment_no_op.cc @@ -25,8 +25,8 @@ #include bool grpc_alts_is_running_on_gcp() { - gpr_log(GPR_ERROR, - "Platforms other than Linux and Windows are not supported"); + gpr_log(GPR_INFO, + "ALTS: Platforms other than Linux and Windows are not supported"); return false; } diff --git a/src/core/lib/security/credentials/composite/composite_credentials.cc b/src/core/lib/security/credentials/composite/composite_credentials.cc index b8f409260f0..586bbed778e 100644 --- a/src/core/lib/security/credentials/composite/composite_credentials.cc +++ b/src/core/lib/security/credentials/composite/composite_credentials.cc @@ -20,8 +20,10 @@ #include "src/core/lib/security/credentials/composite/composite_credentials.h" -#include +#include +#include +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/polling_entity.h" #include "src/core/lib/surface/api_trace.h" @@ -31,35 +33,44 @@ /* -- Composite call credentials. -- */ -typedef struct { +static void composite_call_metadata_cb(void* arg, grpc_error* error); + +namespace { +struct grpc_composite_call_credentials_metadata_context { + grpc_composite_call_credentials_metadata_context( + grpc_composite_call_credentials* composite_creds, + grpc_polling_entity* pollent, grpc_auth_metadata_context auth_md_context, + grpc_credentials_mdelem_array* md_array, + grpc_closure* on_request_metadata) + : composite_creds(composite_creds), + pollent(pollent), + auth_md_context(auth_md_context), + md_array(md_array), + on_request_metadata(on_request_metadata) { + GRPC_CLOSURE_INIT(&internal_on_request_metadata, composite_call_metadata_cb, + this, grpc_schedule_on_exec_ctx); + } + grpc_composite_call_credentials* composite_creds; - size_t creds_index; + size_t creds_index = 0; grpc_polling_entity* pollent; grpc_auth_metadata_context auth_md_context; grpc_credentials_mdelem_array* md_array; grpc_closure* on_request_metadata; grpc_closure internal_on_request_metadata; -} grpc_composite_call_credentials_metadata_context; - -static void composite_call_destruct(grpc_call_credentials* creds) { - grpc_composite_call_credentials* c = - reinterpret_cast(creds); - for (size_t i = 0; i < c->inner.num_creds; i++) { - grpc_call_credentials_unref(c->inner.creds_array[i]); - } - gpr_free(c->inner.creds_array); -} +}; +} // namespace static void composite_call_metadata_cb(void* arg, grpc_error* error) { grpc_composite_call_credentials_metadata_context* ctx = static_cast(arg); if (error == GRPC_ERROR_NONE) { + const grpc_composite_call_credentials::CallCredentialsList& inner = + ctx->composite_creds->inner(); /* See if we need to get some more metadata. */ - if (ctx->creds_index < ctx->composite_creds->inner.num_creds) { - grpc_call_credentials* inner_creds = - ctx->composite_creds->inner.creds_array[ctx->creds_index++]; - if (grpc_call_credentials_get_request_metadata( - inner_creds, ctx->pollent, ctx->auth_md_context, ctx->md_array, + if (ctx->creds_index < inner.size()) { + if (inner[ctx->creds_index++]->get_request_metadata( + ctx->pollent, ctx->auth_md_context, ctx->md_array, &ctx->internal_on_request_metadata, &error)) { // Synchronous response, so call ourselves recursively. composite_call_metadata_cb(arg, error); @@ -73,29 +84,18 @@ static void composite_call_metadata_cb(void* arg, grpc_error* error) { gpr_free(ctx); } -static bool composite_call_get_request_metadata( - grpc_call_credentials* creds, grpc_polling_entity* pollent, - grpc_auth_metadata_context auth_md_context, +bool grpc_composite_call_credentials::get_request_metadata( + grpc_polling_entity* pollent, grpc_auth_metadata_context auth_md_context, grpc_credentials_mdelem_array* md_array, grpc_closure* on_request_metadata, grpc_error** error) { - grpc_composite_call_credentials* c = - reinterpret_cast(creds); grpc_composite_call_credentials_metadata_context* ctx; - ctx = static_cast( - gpr_zalloc(sizeof(grpc_composite_call_credentials_metadata_context))); - ctx->composite_creds = c; - ctx->pollent = pollent; - ctx->auth_md_context = auth_md_context; - ctx->md_array = md_array; - ctx->on_request_metadata = on_request_metadata; - GRPC_CLOSURE_INIT(&ctx->internal_on_request_metadata, - composite_call_metadata_cb, ctx, grpc_schedule_on_exec_ctx); + ctx = grpc_core::New( + this, pollent, auth_md_context, md_array, on_request_metadata); bool synchronous = true; - while (ctx->creds_index < ctx->composite_creds->inner.num_creds) { - grpc_call_credentials* inner_creds = - ctx->composite_creds->inner.creds_array[ctx->creds_index++]; - if (grpc_call_credentials_get_request_metadata( - inner_creds, ctx->pollent, ctx->auth_md_context, ctx->md_array, + const CallCredentialsList& inner = ctx->composite_creds->inner(); + while (ctx->creds_index < inner.size()) { + if (inner[ctx->creds_index++]->get_request_metadata( + ctx->pollent, ctx->auth_md_context, ctx->md_array, &ctx->internal_on_request_metadata, error)) { if (*error != GRPC_ERROR_NONE) break; } else { @@ -103,46 +103,66 @@ static bool composite_call_get_request_metadata( break; } } - if (synchronous) gpr_free(ctx); + if (synchronous) grpc_core::Delete(ctx); return synchronous; } -static void composite_call_cancel_get_request_metadata( - grpc_call_credentials* creds, grpc_credentials_mdelem_array* md_array, - grpc_error* error) { - grpc_composite_call_credentials* c = - reinterpret_cast(creds); - for (size_t i = 0; i < c->inner.num_creds; ++i) { - grpc_call_credentials_cancel_get_request_metadata( - c->inner.creds_array[i], md_array, GRPC_ERROR_REF(error)); +void grpc_composite_call_credentials::cancel_get_request_metadata( + grpc_credentials_mdelem_array* md_array, grpc_error* error) { + for (size_t i = 0; i < inner_.size(); ++i) { + inner_[i]->cancel_get_request_metadata(md_array, GRPC_ERROR_REF(error)); } GRPC_ERROR_UNREF(error); } -static grpc_call_credentials_vtable composite_call_credentials_vtable = { - composite_call_destruct, composite_call_get_request_metadata, - composite_call_cancel_get_request_metadata}; +static size_t get_creds_array_size(const grpc_call_credentials* creds, + bool is_composite) { + return is_composite + ? static_cast(creds) + ->inner() + .size() + : 1; +} -static grpc_call_credentials_array get_creds_array( - grpc_call_credentials** creds_addr) { - grpc_call_credentials_array result; - grpc_call_credentials* creds = *creds_addr; - result.creds_array = creds_addr; - result.num_creds = 1; - if (strcmp(creds->type, GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) == 0) { - result = *grpc_composite_call_credentials_get_credentials(creds); +void grpc_composite_call_credentials::push_to_inner( + grpc_core::RefCountedPtr creds, bool is_composite) { + if (!is_composite) { + inner_.push_back(std::move(creds)); + return; } - return result; + auto composite_creds = + static_cast(creds.get()); + for (size_t i = 0; i < composite_creds->inner().size(); ++i) { + inner_.push_back(std::move(composite_creds->inner_[i])); + } +} + +grpc_composite_call_credentials::grpc_composite_call_credentials( + grpc_core::RefCountedPtr creds1, + grpc_core::RefCountedPtr creds2) + : grpc_call_credentials(GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) { + const bool creds1_is_composite = + strcmp(creds1->type(), GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) == 0; + const bool creds2_is_composite = + strcmp(creds2->type(), GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) == 0; + const size_t size = get_creds_array_size(creds1.get(), creds1_is_composite) + + get_creds_array_size(creds2.get(), creds2_is_composite); + inner_.reserve(size); + push_to_inner(std::move(creds1), creds1_is_composite); + push_to_inner(std::move(creds2), creds2_is_composite); +} + +static grpc_core::RefCountedPtr +composite_call_credentials_create( + grpc_core::RefCountedPtr creds1, + grpc_core::RefCountedPtr creds2) { + return grpc_core::MakeRefCounted( + std::move(creds1), std::move(creds2)); } grpc_call_credentials* grpc_composite_call_credentials_create( grpc_call_credentials* creds1, grpc_call_credentials* creds2, void* reserved) { - size_t i; - size_t creds_array_byte_size; - grpc_call_credentials_array creds1_array; - grpc_call_credentials_array creds2_array; - grpc_composite_call_credentials* c; GRPC_API_TRACE( "grpc_composite_call_credentials_create(creds1=%p, creds2=%p, " "reserved=%p)", @@ -150,120 +170,40 @@ grpc_call_credentials* grpc_composite_call_credentials_create( GPR_ASSERT(reserved == nullptr); GPR_ASSERT(creds1 != nullptr); GPR_ASSERT(creds2 != nullptr); - c = static_cast( - gpr_zalloc(sizeof(grpc_composite_call_credentials))); - c->base.type = GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE; - c->base.vtable = &composite_call_credentials_vtable; - gpr_ref_init(&c->base.refcount, 1); - creds1_array = get_creds_array(&creds1); - creds2_array = get_creds_array(&creds2); - c->inner.num_creds = creds1_array.num_creds + creds2_array.num_creds; - creds_array_byte_size = c->inner.num_creds * sizeof(grpc_call_credentials*); - c->inner.creds_array = - static_cast(gpr_zalloc(creds_array_byte_size)); - for (i = 0; i < creds1_array.num_creds; i++) { - grpc_call_credentials* cur_creds = creds1_array.creds_array[i]; - c->inner.creds_array[i] = grpc_call_credentials_ref(cur_creds); - } - for (i = 0; i < creds2_array.num_creds; i++) { - grpc_call_credentials* cur_creds = creds2_array.creds_array[i]; - c->inner.creds_array[i + creds1_array.num_creds] = - grpc_call_credentials_ref(cur_creds); - } - return &c->base; -} -const grpc_call_credentials_array* -grpc_composite_call_credentials_get_credentials(grpc_call_credentials* creds) { - const grpc_composite_call_credentials* c = - reinterpret_cast(creds); - GPR_ASSERT(strcmp(creds->type, GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) == 0); - return &c->inner; -} - -grpc_call_credentials* grpc_credentials_contains_type( - grpc_call_credentials* creds, const char* type, - grpc_call_credentials** composite_creds) { - size_t i; - if (strcmp(creds->type, type) == 0) { - if (composite_creds != nullptr) *composite_creds = nullptr; - return creds; - } else if (strcmp(creds->type, GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) == 0) { - const grpc_call_credentials_array* inner_creds_array = - grpc_composite_call_credentials_get_credentials(creds); - for (i = 0; i < inner_creds_array->num_creds; i++) { - if (strcmp(type, inner_creds_array->creds_array[i]->type) == 0) { - if (composite_creds != nullptr) *composite_creds = creds; - return inner_creds_array->creds_array[i]; - } - } - } - return nullptr; + return composite_call_credentials_create(creds1->Ref(), creds2->Ref()) + .release(); } /* -- Composite channel credentials. -- */ -static void composite_channel_destruct(grpc_channel_credentials* creds) { - grpc_composite_channel_credentials* c = - reinterpret_cast(creds); - grpc_channel_credentials_unref(c->inner_creds); - grpc_call_credentials_unref(c->call_creds); -} - -static grpc_security_status composite_channel_create_security_connector( - grpc_channel_credentials* creds, grpc_call_credentials* call_creds, +grpc_core::RefCountedPtr +grpc_composite_channel_credentials::create_security_connector( + grpc_core::RefCountedPtr call_creds, const char* target, const grpc_channel_args* args, - grpc_channel_security_connector** sc, grpc_channel_args** new_args) { - grpc_composite_channel_credentials* c = - reinterpret_cast(creds); - grpc_security_status status = GRPC_SECURITY_ERROR; - - GPR_ASSERT(c->inner_creds != nullptr && c->call_creds != nullptr && - c->inner_creds->vtable != nullptr && - c->inner_creds->vtable->create_security_connector != nullptr); + grpc_channel_args** new_args) { + GPR_ASSERT(inner_creds_ != nullptr && call_creds_ != nullptr); /* If we are passed a call_creds, create a call composite to pass it downstream. */ if (call_creds != nullptr) { - grpc_call_credentials* composite_call_creds = - grpc_composite_call_credentials_create(c->call_creds, call_creds, - nullptr); - status = c->inner_creds->vtable->create_security_connector( - c->inner_creds, composite_call_creds, target, args, sc, new_args); - grpc_call_credentials_unref(composite_call_creds); + return inner_creds_->create_security_connector( + composite_call_credentials_create(call_creds_, std::move(call_creds)), + target, args, new_args); } else { - status = c->inner_creds->vtable->create_security_connector( - c->inner_creds, c->call_creds, target, args, sc, new_args); + return inner_creds_->create_security_connector(call_creds_, target, args, + new_args); } - return status; } -static grpc_channel_credentials* -composite_channel_duplicate_without_call_credentials( - grpc_channel_credentials* creds) { - grpc_composite_channel_credentials* c = - reinterpret_cast(creds); - return grpc_channel_credentials_ref(c->inner_creds); -} - -static grpc_channel_credentials_vtable composite_channel_credentials_vtable = { - composite_channel_destruct, composite_channel_create_security_connector, - composite_channel_duplicate_without_call_credentials}; - grpc_channel_credentials* grpc_composite_channel_credentials_create( grpc_channel_credentials* channel_creds, grpc_call_credentials* call_creds, void* reserved) { - grpc_composite_channel_credentials* c = - static_cast(gpr_zalloc(sizeof(*c))); GPR_ASSERT(channel_creds != nullptr && call_creds != nullptr && reserved == nullptr); GRPC_API_TRACE( "grpc_composite_channel_credentials_create(channel_creds=%p, " "call_creds=%p, reserved=%p)", 3, (channel_creds, call_creds, reserved)); - c->base.type = channel_creds->type; - c->base.vtable = &composite_channel_credentials_vtable; - gpr_ref_init(&c->base.refcount, 1); - c->inner_creds = grpc_channel_credentials_ref(channel_creds); - c->call_creds = grpc_call_credentials_ref(call_creds); - return &c->base; + return grpc_core::New( + channel_creds->Ref(), call_creds->Ref()); } diff --git a/src/core/lib/security/credentials/composite/composite_credentials.h b/src/core/lib/security/credentials/composite/composite_credentials.h index a952ad57f1e..0e6e5f9e14f 100644 --- a/src/core/lib/security/credentials/composite/composite_credentials.h +++ b/src/core/lib/security/credentials/composite/composite_credentials.h @@ -21,39 +21,79 @@ #include +#include "src/core/lib/gprpp/inlined_vector.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/security/credentials/credentials.h" -typedef struct { - grpc_call_credentials** creds_array; - size_t num_creds; -} grpc_call_credentials_array; - -const grpc_call_credentials_array* -grpc_composite_call_credentials_get_credentials( - grpc_call_credentials* composite_creds); - -/* Returns creds if creds is of the specified type or the inner creds of the - specified type (if found), if the creds is of type COMPOSITE. - If composite_creds is not NULL, *composite_creds will point to creds if of - type COMPOSITE in case of success. */ -grpc_call_credentials* grpc_credentials_contains_type( - grpc_call_credentials* creds, const char* type, - grpc_call_credentials** composite_creds); - /* -- Composite channel credentials. -- */ -typedef struct { - grpc_channel_credentials base; - grpc_channel_credentials* inner_creds; - grpc_call_credentials* call_creds; -} grpc_composite_channel_credentials; +class grpc_composite_channel_credentials : public grpc_channel_credentials { + public: + grpc_composite_channel_credentials( + grpc_core::RefCountedPtr channel_creds, + grpc_core::RefCountedPtr call_creds) + : grpc_channel_credentials(channel_creds->type()), + inner_creds_(std::move(channel_creds)), + call_creds_(std::move(call_creds)) {} + + ~grpc_composite_channel_credentials() override = default; + + grpc_core::RefCountedPtr + duplicate_without_call_credentials() override { + return inner_creds_; + } + + grpc_core::RefCountedPtr + create_security_connector( + grpc_core::RefCountedPtr call_creds, + const char* target, const grpc_channel_args* args, + grpc_channel_args** new_args) override; + + grpc_channel_args* update_arguments(grpc_channel_args* args) override { + return inner_creds_->update_arguments(args); + } + + const grpc_channel_credentials* inner_creds() const { + return inner_creds_.get(); + } + const grpc_call_credentials* call_creds() const { return call_creds_.get(); } + grpc_call_credentials* mutable_call_creds() { return call_creds_.get(); } + + private: + grpc_core::RefCountedPtr inner_creds_; + grpc_core::RefCountedPtr call_creds_; +}; /* -- Composite call credentials. -- */ -typedef struct { - grpc_call_credentials base; - grpc_call_credentials_array inner; -} grpc_composite_call_credentials; +class grpc_composite_call_credentials : public grpc_call_credentials { + public: + using CallCredentialsList = + grpc_core::InlinedVector, + 2>; + + grpc_composite_call_credentials( + grpc_core::RefCountedPtr creds1, + grpc_core::RefCountedPtr creds2); + ~grpc_composite_call_credentials() override = default; + + bool get_request_metadata(grpc_polling_entity* pollent, + grpc_auth_metadata_context context, + grpc_credentials_mdelem_array* md_array, + grpc_closure* on_request_metadata, + grpc_error** error) override; + + void cancel_get_request_metadata(grpc_credentials_mdelem_array* md_array, + grpc_error* error) override; + + const CallCredentialsList& inner() const { return inner_; } + + private: + void push_to_inner(grpc_core::RefCountedPtr creds, + bool is_composite); + + CallCredentialsList inner_; +}; #endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_COMPOSITE_COMPOSITE_CREDENTIALS_H \ */ diff --git a/src/core/lib/security/credentials/credentials.cc b/src/core/lib/security/credentials/credentials.cc index c43cb440ebf..90452d68d61 100644 --- a/src/core/lib/security/credentials/credentials.cc +++ b/src/core/lib/security/credentials/credentials.cc @@ -39,120 +39,24 @@ /* -- Common. -- */ -grpc_credentials_metadata_request* grpc_credentials_metadata_request_create( - grpc_call_credentials* creds) { - grpc_credentials_metadata_request* r = - static_cast( - gpr_zalloc(sizeof(grpc_credentials_metadata_request))); - r->creds = grpc_call_credentials_ref(creds); - return r; -} - -void grpc_credentials_metadata_request_destroy( - grpc_credentials_metadata_request* r) { - grpc_call_credentials_unref(r->creds); - grpc_http_response_destroy(&r->response); - gpr_free(r); -} - -grpc_channel_credentials* grpc_channel_credentials_ref( - grpc_channel_credentials* creds) { - if (creds == nullptr) return nullptr; - gpr_ref(&creds->refcount); - return creds; -} - -void grpc_channel_credentials_unref(grpc_channel_credentials* creds) { - if (creds == nullptr) return; - if (gpr_unref(&creds->refcount)) { - if (creds->vtable->destruct != nullptr) { - creds->vtable->destruct(creds); - } - gpr_free(creds); - } -} - void grpc_channel_credentials_release(grpc_channel_credentials* creds) { GRPC_API_TRACE("grpc_channel_credentials_release(creds=%p)", 1, (creds)); grpc_core::ExecCtx exec_ctx; - grpc_channel_credentials_unref(creds); -} - -grpc_call_credentials* grpc_call_credentials_ref(grpc_call_credentials* creds) { - if (creds == nullptr) return nullptr; - gpr_ref(&creds->refcount); - return creds; -} - -void grpc_call_credentials_unref(grpc_call_credentials* creds) { - if (creds == nullptr) return; - if (gpr_unref(&creds->refcount)) { - if (creds->vtable->destruct != nullptr) { - creds->vtable->destruct(creds); - } - gpr_free(creds); - } + if (creds) creds->Unref(); } void grpc_call_credentials_release(grpc_call_credentials* creds) { GRPC_API_TRACE("grpc_call_credentials_release(creds=%p)", 1, (creds)); grpc_core::ExecCtx exec_ctx; - grpc_call_credentials_unref(creds); -} - -bool grpc_call_credentials_get_request_metadata( - grpc_call_credentials* creds, grpc_polling_entity* pollent, - grpc_auth_metadata_context context, grpc_credentials_mdelem_array* md_array, - grpc_closure* on_request_metadata, grpc_error** error) { - if (creds == nullptr || creds->vtable->get_request_metadata == nullptr) { - return true; - } - return creds->vtable->get_request_metadata(creds, pollent, context, md_array, - on_request_metadata, error); -} - -void grpc_call_credentials_cancel_get_request_metadata( - grpc_call_credentials* creds, grpc_credentials_mdelem_array* md_array, - grpc_error* error) { - if (creds == nullptr || - creds->vtable->cancel_get_request_metadata == nullptr) { - return; - } - creds->vtable->cancel_get_request_metadata(creds, md_array, error); -} - -grpc_security_status grpc_channel_credentials_create_security_connector( - grpc_channel_credentials* channel_creds, const char* target, - const grpc_channel_args* args, grpc_channel_security_connector** sc, - grpc_channel_args** new_args) { - *new_args = nullptr; - if (channel_creds == nullptr) { - return GRPC_SECURITY_ERROR; - } - GPR_ASSERT(channel_creds->vtable->create_security_connector != nullptr); - return channel_creds->vtable->create_security_connector( - channel_creds, nullptr, target, args, sc, new_args); -} - -grpc_channel_credentials* -grpc_channel_credentials_duplicate_without_call_credentials( - grpc_channel_credentials* channel_creds) { - if (channel_creds != nullptr && channel_creds->vtable != nullptr && - channel_creds->vtable->duplicate_without_call_credentials != nullptr) { - return channel_creds->vtable->duplicate_without_call_credentials( - channel_creds); - } else { - return grpc_channel_credentials_ref(channel_creds); - } + if (creds) creds->Unref(); } static void credentials_pointer_arg_destroy(void* p) { - grpc_channel_credentials_unref(static_cast(p)); + static_cast(p)->Unref(); } static void* credentials_pointer_arg_copy(void* p) { - return grpc_channel_credentials_ref( - static_cast(p)); + return static_cast(p)->Ref().release(); } static int credentials_pointer_cmp(void* a, void* b) { return GPR_ICMP(a, b); } @@ -191,63 +95,35 @@ grpc_channel_credentials* grpc_channel_credentials_find_in_args( return nullptr; } -grpc_server_credentials* grpc_server_credentials_ref( - grpc_server_credentials* creds) { - if (creds == nullptr) return nullptr; - gpr_ref(&creds->refcount); - return creds; -} - -void grpc_server_credentials_unref(grpc_server_credentials* creds) { - if (creds == nullptr) return; - if (gpr_unref(&creds->refcount)) { - if (creds->vtable->destruct != nullptr) { - creds->vtable->destruct(creds); - } - if (creds->processor.destroy != nullptr && - creds->processor.state != nullptr) { - creds->processor.destroy(creds->processor.state); - } - gpr_free(creds); - } -} - void grpc_server_credentials_release(grpc_server_credentials* creds) { GRPC_API_TRACE("grpc_server_credentials_release(creds=%p)", 1, (creds)); grpc_core::ExecCtx exec_ctx; - grpc_server_credentials_unref(creds); + if (creds) creds->Unref(); } -grpc_security_status grpc_server_credentials_create_security_connector( - grpc_server_credentials* creds, grpc_server_security_connector** sc) { - if (creds == nullptr || creds->vtable->create_security_connector == nullptr) { - gpr_log(GPR_ERROR, "Server credentials cannot create security context."); - return GRPC_SECURITY_ERROR; - } - return creds->vtable->create_security_connector(creds, sc); -} - -void grpc_server_credentials_set_auth_metadata_processor( - grpc_server_credentials* creds, grpc_auth_metadata_processor processor) { +void grpc_server_credentials::set_auth_metadata_processor( + const grpc_auth_metadata_processor& processor) { GRPC_API_TRACE( "grpc_server_credentials_set_auth_metadata_processor(" "creds=%p, " "processor=grpc_auth_metadata_processor { process: %p, state: %p })", - 3, (creds, (void*)(intptr_t)processor.process, processor.state)); - if (creds == nullptr) return; - if (creds->processor.destroy != nullptr && - creds->processor.state != nullptr) { - creds->processor.destroy(creds->processor.state); - } - creds->processor = processor; + 3, (this, (void*)(intptr_t)processor.process, processor.state)); + DestroyProcessor(); + processor_ = processor; +} + +void grpc_server_credentials_set_auth_metadata_processor( + grpc_server_credentials* creds, grpc_auth_metadata_processor processor) { + GPR_DEBUG_ASSERT(creds != nullptr); + creds->set_auth_metadata_processor(processor); } static void server_credentials_pointer_arg_destroy(void* p) { - grpc_server_credentials_unref(static_cast(p)); + static_cast(p)->Unref(); } static void* server_credentials_pointer_arg_copy(void* p) { - return grpc_server_credentials_ref(static_cast(p)); + return static_cast(p)->Ref().release(); } static int server_credentials_pointer_cmp(void* a, void* b) { diff --git a/src/core/lib/security/credentials/credentials.h b/src/core/lib/security/credentials/credentials.h index 3878958b38b..a9d581280d1 100644 --- a/src/core/lib/security/credentials/credentials.h +++ b/src/core/lib/security/credentials/credentials.h @@ -26,6 +26,7 @@ #include #include "src/core/lib/transport/metadata_batch.h" +#include "src/core/lib/gprpp/ref_counted.h" #include "src/core/lib/http/httpcli.h" #include "src/core/lib/http/parser.h" #include "src/core/lib/iomgr/polling_entity.h" @@ -59,7 +60,7 @@ typedef enum { #define GRPC_SECURE_TOKEN_REFRESH_THRESHOLD_SECS 60 -#define GRPC_COMPUTE_ENGINE_METADATA_HOST "metadata.google.internal" +#define GRPC_COMPUTE_ENGINE_METADATA_HOST "metadata.google.internal." #define GRPC_COMPUTE_ENGINE_METADATA_TOKEN_PATH \ "/computeMetadata/v1/instance/service-accounts/default/token" @@ -90,44 +91,54 @@ void grpc_override_well_known_credentials_path_getter( #define GRPC_ARG_CHANNEL_CREDENTIALS "grpc.channel_credentials" -typedef struct { - void (*destruct)(grpc_channel_credentials* c); +// This type is forward declared as a C struct and we cannot define it as a +// class. Otherwise, compiler will complain about type mismatch due to +// -Wmismatched-tags. +struct grpc_channel_credentials + : grpc_core::RefCounted { + public: + explicit grpc_channel_credentials(const char* type) : type_(type) {} + virtual ~grpc_channel_credentials() = default; - grpc_security_status (*create_security_connector)( - grpc_channel_credentials* c, grpc_call_credentials* call_creds, + // Creates a security connector for the channel. May also create new channel + // args for the channel to be used in place of the passed in const args if + // returned non NULL. In that case the caller is responsible for destroying + // new_args after channel creation. + virtual grpc_core::RefCountedPtr + create_security_connector( + grpc_core::RefCountedPtr call_creds, const char* target, const grpc_channel_args* args, - grpc_channel_security_connector** sc, grpc_channel_args** new_args); + grpc_channel_args** new_args) { + // Tell clang-tidy that call_creds cannot be passed as const-ref. + call_creds.reset(); + GRPC_ABSTRACT; + } - grpc_channel_credentials* (*duplicate_without_call_credentials)( - grpc_channel_credentials* c); -} grpc_channel_credentials_vtable; + // Creates a version of the channel credentials without any attached call + // credentials. This can be used in order to open a channel to a non-trusted + // gRPC load balancer. + virtual grpc_core::RefCountedPtr + duplicate_without_call_credentials() { + // By default we just increment the refcount. + return Ref(); + } -struct grpc_channel_credentials { - const grpc_channel_credentials_vtable* vtable; - const char* type; - gpr_refcount refcount; + // Allows credentials to optionally modify a parent channel's args. + // By default, leave channel args as is. The callee takes ownership + // of the passed-in channel args, and the caller takes ownership + // of the returned channel args. + virtual grpc_channel_args* update_arguments(grpc_channel_args* args) { + return args; + } + + const char* type() const { return type_; } + + GRPC_ABSTRACT_BASE_CLASS + + private: + const char* type_; }; -grpc_channel_credentials* grpc_channel_credentials_ref( - grpc_channel_credentials* creds); -void grpc_channel_credentials_unref(grpc_channel_credentials* creds); - -/* Creates a security connector for the channel. May also create new channel - args for the channel to be used in place of the passed in const args if - returned non NULL. In that case the caller is responsible for destroying - new_args after channel creation. */ -grpc_security_status grpc_channel_credentials_create_security_connector( - grpc_channel_credentials* creds, const char* target, - const grpc_channel_args* args, grpc_channel_security_connector** sc, - grpc_channel_args** new_args); - -/* Creates a version of the channel credentials without any attached call - credentials. This can be used in order to open a channel to a non-trusted - gRPC load balancer. */ -grpc_channel_credentials* -grpc_channel_credentials_duplicate_without_call_credentials( - grpc_channel_credentials* creds); - /* Util to encapsulate the channel credentials in a channel arg. */ grpc_arg grpc_channel_credentials_to_arg(grpc_channel_credentials* credentials); @@ -158,44 +169,39 @@ void grpc_credentials_mdelem_array_destroy(grpc_credentials_mdelem_array* list); /* --- grpc_call_credentials. --- */ -typedef struct { - void (*destruct)(grpc_call_credentials* c); - bool (*get_request_metadata)(grpc_call_credentials* c, - grpc_polling_entity* pollent, - grpc_auth_metadata_context context, - grpc_credentials_mdelem_array* md_array, - grpc_closure* on_request_metadata, - grpc_error** error); - void (*cancel_get_request_metadata)(grpc_call_credentials* c, - grpc_credentials_mdelem_array* md_array, - grpc_error* error); -} grpc_call_credentials_vtable; +// This type is forward declared as a C struct and we cannot define it as a +// class. Otherwise, compiler will complain about type mismatch due to +// -Wmismatched-tags. +struct grpc_call_credentials + : public grpc_core::RefCounted { + public: + explicit grpc_call_credentials(const char* type) : type_(type) {} + virtual ~grpc_call_credentials() = default; -struct grpc_call_credentials { - const grpc_call_credentials_vtable* vtable; - const char* type; - gpr_refcount refcount; + // Returns true if completed synchronously, in which case \a error will + // be set to indicate the result. Otherwise, \a on_request_metadata will + // be invoked asynchronously when complete. \a md_array will be populated + // with the resulting metadata once complete. + virtual bool get_request_metadata(grpc_polling_entity* pollent, + grpc_auth_metadata_context context, + grpc_credentials_mdelem_array* md_array, + grpc_closure* on_request_metadata, + grpc_error** error) GRPC_ABSTRACT; + + // Cancels a pending asynchronous operation started by + // grpc_call_credentials_get_request_metadata() with the corresponding + // value of \a md_array. + virtual void cancel_get_request_metadata( + grpc_credentials_mdelem_array* md_array, grpc_error* error) GRPC_ABSTRACT; + + const char* type() const { return type_; } + + GRPC_ABSTRACT_BASE_CLASS + + private: + const char* type_; }; -grpc_call_credentials* grpc_call_credentials_ref(grpc_call_credentials* creds); -void grpc_call_credentials_unref(grpc_call_credentials* creds); - -/// Returns true if completed synchronously, in which case \a error will -/// be set to indicate the result. Otherwise, \a on_request_metadata will -/// be invoked asynchronously when complete. \a md_array will be populated -/// with the resulting metadata once complete. -bool grpc_call_credentials_get_request_metadata( - grpc_call_credentials* creds, grpc_polling_entity* pollent, - grpc_auth_metadata_context context, grpc_credentials_mdelem_array* md_array, - grpc_closure* on_request_metadata, grpc_error** error); - -/// Cancels a pending asynchronous operation started by -/// grpc_call_credentials_get_request_metadata() with the corresponding -/// value of \a md_array. -void grpc_call_credentials_cancel_get_request_metadata( - grpc_call_credentials* c, grpc_credentials_mdelem_array* md_array, - grpc_error* error); - /* Metadata-only credentials with the specified key and value where asynchronicity can be simulated for testing. */ grpc_call_credentials* grpc_md_only_test_credentials_create( @@ -203,27 +209,41 @@ grpc_call_credentials* grpc_md_only_test_credentials_create( /* --- grpc_server_credentials. --- */ -typedef struct { - void (*destruct)(grpc_server_credentials* c); - grpc_security_status (*create_security_connector)( - grpc_server_credentials* c, grpc_server_security_connector** sc); -} grpc_server_credentials_vtable; +// This type is forward declared as a C struct and we cannot define it as a +// class. Otherwise, compiler will complain about type mismatch due to +// -Wmismatched-tags. +struct grpc_server_credentials + : public grpc_core::RefCounted { + public: + explicit grpc_server_credentials(const char* type) : type_(type) {} -struct grpc_server_credentials { - const grpc_server_credentials_vtable* vtable; - const char* type; - gpr_refcount refcount; - grpc_auth_metadata_processor processor; + virtual ~grpc_server_credentials() { DestroyProcessor(); } + + virtual grpc_core::RefCountedPtr + create_security_connector() GRPC_ABSTRACT; + + const char* type() const { return type_; } + + const grpc_auth_metadata_processor& auth_metadata_processor() const { + return processor_; + } + void set_auth_metadata_processor( + const grpc_auth_metadata_processor& processor); + + GRPC_ABSTRACT_BASE_CLASS + + private: + void DestroyProcessor() { + if (processor_.destroy != nullptr && processor_.state != nullptr) { + processor_.destroy(processor_.state); + } + } + + const char* type_; + grpc_auth_metadata_processor processor_ = + grpc_auth_metadata_processor(); // Zero-initialize the C struct. }; -grpc_security_status grpc_server_credentials_create_security_connector( - grpc_server_credentials* creds, grpc_server_security_connector** sc); - -grpc_server_credentials* grpc_server_credentials_ref( - grpc_server_credentials* creds); - -void grpc_server_credentials_unref(grpc_server_credentials* creds); - #define GRPC_SERVER_CREDENTIALS_ARG "grpc.server_credentials" grpc_arg grpc_server_credentials_to_arg(grpc_server_credentials* c); @@ -233,15 +253,27 @@ grpc_server_credentials* grpc_find_server_credentials_in_args( /* -- Credentials Metadata Request. -- */ -typedef struct { - grpc_call_credentials* creds; +struct grpc_credentials_metadata_request { + explicit grpc_credentials_metadata_request( + grpc_core::RefCountedPtr creds) + : creds(std::move(creds)) {} + ~grpc_credentials_metadata_request() { + grpc_http_response_destroy(&response); + } + + grpc_core::RefCountedPtr creds; grpc_http_response response; -} grpc_credentials_metadata_request; +}; -grpc_credentials_metadata_request* grpc_credentials_metadata_request_create( - grpc_call_credentials* creds); +inline grpc_credentials_metadata_request* +grpc_credentials_metadata_request_create( + grpc_core::RefCountedPtr creds) { + return grpc_core::New(std::move(creds)); +} -void grpc_credentials_metadata_request_destroy( - grpc_credentials_metadata_request* r); +inline void grpc_credentials_metadata_request_destroy( + grpc_credentials_metadata_request* r) { + grpc_core::Delete(r); +} #endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_CREDENTIALS_H */ diff --git a/src/core/lib/security/credentials/fake/fake_credentials.cc b/src/core/lib/security/credentials/fake/fake_credentials.cc index d3e0e8c8168..337dd7679fd 100644 --- a/src/core/lib/security/credentials/fake/fake_credentials.cc +++ b/src/core/lib/security/credentials/fake/fake_credentials.cc @@ -33,49 +33,45 @@ /* -- Fake transport security credentials. -- */ -static grpc_security_status fake_transport_security_create_security_connector( - grpc_channel_credentials* c, grpc_call_credentials* call_creds, - const char* target, const grpc_channel_args* args, - grpc_channel_security_connector** sc, grpc_channel_args** new_args) { - *sc = - grpc_fake_channel_security_connector_create(c, call_creds, target, args); - return GRPC_SECURITY_OK; +namespace { +class grpc_fake_channel_credentials final : public grpc_channel_credentials { + public: + grpc_fake_channel_credentials() + : grpc_channel_credentials( + GRPC_CHANNEL_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY) {} + ~grpc_fake_channel_credentials() override = default; + + grpc_core::RefCountedPtr + create_security_connector( + grpc_core::RefCountedPtr call_creds, + const char* target, const grpc_channel_args* args, + grpc_channel_args** new_args) override { + return grpc_fake_channel_security_connector_create( + this->Ref(), std::move(call_creds), target, args); + } +}; + +class grpc_fake_server_credentials final : public grpc_server_credentials { + public: + grpc_fake_server_credentials() + : grpc_server_credentials( + GRPC_CHANNEL_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY) {} + ~grpc_fake_server_credentials() override = default; + + grpc_core::RefCountedPtr + create_security_connector() override { + return grpc_fake_server_security_connector_create(this->Ref()); + } +}; +} // namespace + +grpc_channel_credentials* grpc_fake_transport_security_credentials_create() { + return grpc_core::New(); } -static grpc_security_status -fake_transport_security_server_create_security_connector( - grpc_server_credentials* c, grpc_server_security_connector** sc) { - *sc = grpc_fake_server_security_connector_create(c); - return GRPC_SECURITY_OK; -} - -static grpc_channel_credentials_vtable - fake_transport_security_credentials_vtable = { - nullptr, fake_transport_security_create_security_connector, nullptr}; - -static grpc_server_credentials_vtable - fake_transport_security_server_credentials_vtable = { - nullptr, fake_transport_security_server_create_security_connector}; - -grpc_channel_credentials* grpc_fake_transport_security_credentials_create( - void) { - grpc_channel_credentials* c = static_cast( - gpr_zalloc(sizeof(grpc_channel_credentials))); - c->type = GRPC_CHANNEL_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY; - c->vtable = &fake_transport_security_credentials_vtable; - gpr_ref_init(&c->refcount, 1); - return c; -} - -grpc_server_credentials* grpc_fake_transport_security_server_credentials_create( - void) { - grpc_server_credentials* c = static_cast( - gpr_malloc(sizeof(grpc_server_credentials))); - memset(c, 0, sizeof(grpc_server_credentials)); - c->type = GRPC_CHANNEL_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY; - gpr_ref_init(&c->refcount, 1); - c->vtable = &fake_transport_security_server_credentials_vtable; - return c; +grpc_server_credentials* +grpc_fake_transport_security_server_credentials_create() { + return grpc_core::New(); } grpc_arg grpc_fake_transport_expected_targets_arg(char* expected_targets) { @@ -92,46 +88,25 @@ const char* grpc_fake_transport_get_expected_targets( /* -- Metadata-only test credentials. -- */ -static void md_only_test_destruct(grpc_call_credentials* creds) { - grpc_md_only_test_credentials* c = - reinterpret_cast(creds); - GRPC_MDELEM_UNREF(c->md); -} - -static bool md_only_test_get_request_metadata( - grpc_call_credentials* creds, grpc_polling_entity* pollent, - grpc_auth_metadata_context context, grpc_credentials_mdelem_array* md_array, - grpc_closure* on_request_metadata, grpc_error** error) { - grpc_md_only_test_credentials* c = - reinterpret_cast(creds); - grpc_credentials_mdelem_array_add(md_array, c->md); - if (c->is_async) { +bool grpc_md_only_test_credentials::get_request_metadata( + grpc_polling_entity* pollent, grpc_auth_metadata_context context, + grpc_credentials_mdelem_array* md_array, grpc_closure* on_request_metadata, + grpc_error** error) { + grpc_credentials_mdelem_array_add(md_array, md_); + if (is_async_) { GRPC_CLOSURE_SCHED(on_request_metadata, GRPC_ERROR_NONE); return false; } return true; } -static void md_only_test_cancel_get_request_metadata( - grpc_call_credentials* c, grpc_credentials_mdelem_array* md_array, - grpc_error* error) { +void grpc_md_only_test_credentials::cancel_get_request_metadata( + grpc_credentials_mdelem_array* md_array, grpc_error* error) { GRPC_ERROR_UNREF(error); } -static grpc_call_credentials_vtable md_only_test_vtable = { - md_only_test_destruct, md_only_test_get_request_metadata, - md_only_test_cancel_get_request_metadata}; - grpc_call_credentials* grpc_md_only_test_credentials_create( const char* md_key, const char* md_value, bool is_async) { - grpc_md_only_test_credentials* c = - static_cast( - gpr_zalloc(sizeof(grpc_md_only_test_credentials))); - c->base.type = GRPC_CALL_CREDENTIALS_TYPE_OAUTH2; - c->base.vtable = &md_only_test_vtable; - gpr_ref_init(&c->base.refcount, 1); - c->md = grpc_mdelem_from_slices(grpc_slice_from_copied_string(md_key), - grpc_slice_from_copied_string(md_value)); - c->is_async = is_async; - return &c->base; + return grpc_core::New(md_key, md_value, + is_async); } diff --git a/src/core/lib/security/credentials/fake/fake_credentials.h b/src/core/lib/security/credentials/fake/fake_credentials.h index e89e6e24cca..b7f6a1909fc 100644 --- a/src/core/lib/security/credentials/fake/fake_credentials.h +++ b/src/core/lib/security/credentials/fake/fake_credentials.h @@ -55,10 +55,28 @@ const char* grpc_fake_transport_get_expected_targets( /* -- Metadata-only Test credentials. -- */ -typedef struct { - grpc_call_credentials base; - grpc_mdelem md; - bool is_async; -} grpc_md_only_test_credentials; +class grpc_md_only_test_credentials : public grpc_call_credentials { + public: + grpc_md_only_test_credentials(const char* md_key, const char* md_value, + bool is_async) + : grpc_call_credentials(GRPC_CALL_CREDENTIALS_TYPE_OAUTH2), + md_(grpc_mdelem_from_slices(grpc_slice_from_copied_string(md_key), + grpc_slice_from_copied_string(md_value))), + is_async_(is_async) {} + ~grpc_md_only_test_credentials() override { GRPC_MDELEM_UNREF(md_); } + + bool get_request_metadata(grpc_polling_entity* pollent, + grpc_auth_metadata_context context, + grpc_credentials_mdelem_array* md_array, + grpc_closure* on_request_metadata, + grpc_error** error) override; + + void cancel_get_request_metadata(grpc_credentials_mdelem_array* md_array, + grpc_error* error) override; + + private: + grpc_mdelem md_; + bool is_async_; +}; #endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_FAKE_FAKE_CREDENTIALS_H */ 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 fcab2529592..adc76cb1740 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 @@ -30,6 +30,7 @@ #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/gprpp/ref_counted_ptr.h" #include "src/core/lib/http/httpcli.h" #include "src/core/lib/http/parser.h" #include "src/core/lib/iomgr/load_file.h" @@ -45,13 +46,20 @@ /* -- Constants. -- */ -#define GRPC_COMPUTE_ENGINE_DETECTION_HOST "metadata.google.internal" +#define GRPC_COMPUTE_ENGINE_DETECTION_HOST "metadata.google.internal." /* -- Default credentials. -- */ -static int g_compute_engine_detection_done = 0; -static int g_need_compute_engine_creds = 0; +/* A sticky bit that will be set only if the result of metadata server detection + * is positive. We do not set the bit if the result is negative. Because it + * means the detection is done via network test that is unreliable and the + * unreliable result should not be referred by successive calls. */ +static int g_metadata_server_available = 0; +static int g_is_on_gce = 0; static gpr_mu g_state_mu; +/* Protect a metadata_server_detector instance that can be modified by more than + * one gRPC threads */ +static gpr_mu* g_polling_mu; static gpr_once g_once = GPR_ONCE_INIT; static grpc_core::internal::grpc_gce_tenancy_checker g_gce_tenancy_checker = grpc_alts_is_running_on_gcp; @@ -63,22 +71,13 @@ typedef struct { int is_done; int success; grpc_http_response response; -} compute_engine_detector; +} metadata_server_detector; -static void google_default_credentials_destruct( - grpc_channel_credentials* creds) { - grpc_google_default_channel_credentials* c = - reinterpret_cast(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, +grpc_core::RefCountedPtr +grpc_google_default_channel_credentials::create_security_connector( + grpc_core::RefCountedPtr 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(creds); + grpc_channel_args** new_args) { bool is_grpclb_load_balancer = grpc_channel_arg_get_bool( grpc_channel_args_find(args, GRPC_ARG_ADDRESS_IS_GRPCLB_LOAD_BALANCER), false); @@ -88,11 +87,17 @@ static grpc_security_status google_default_create_security_connector( 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); + /* Return failure if ALTS is selected but not running on GCE. */ + if (use_alts && !g_is_on_gce) { + gpr_log(GPR_ERROR, "ALTS is selected, but not running on GCE."); + return nullptr; + } + + grpc_core::RefCountedPtr sc = + use_alts ? alts_creds_->create_security_connector(call_creds, target, + args, new_args) + : ssl_creds_->create_security_connector(call_creds, target, args, + 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 @@ -106,20 +111,115 @@ static grpc_security_status google_default_create_security_connector( *new_args = grpc_channel_args_copy_and_add_and_remove( args, args_to_remove, GPR_ARRAY_SIZE(args_to_remove), nullptr, 0); } - return status; + return sc; } -static grpc_channel_credentials_vtable google_default_credentials_vtable = { - google_default_credentials_destruct, - google_default_create_security_connector, nullptr}; +grpc_channel_args* grpc_google_default_channel_credentials::update_arguments( + grpc_channel_args* args) { + grpc_channel_args* updated = args; + if (grpc_channel_args_find(args, GRPC_ARG_DNS_ENABLE_SRV_QUERIES) == + nullptr) { + grpc_arg new_srv_arg = grpc_channel_arg_integer_create( + const_cast(GRPC_ARG_DNS_ENABLE_SRV_QUERIES), true); + updated = grpc_channel_args_copy_and_add(args, &new_srv_arg, 1); + grpc_channel_args_destroy(args); + } + return updated; +} + +static void on_metadata_server_detection_http_response(void* user_data, + grpc_error* error) { + metadata_server_detector* detector = + static_cast(user_data); + if (error == GRPC_ERROR_NONE && detector->response.status == 200 && + detector->response.hdr_count > 0) { + /* Internet providers can return a generic response to all requests, so + it is necessary to check that metadata header is present also. */ + size_t i; + for (i = 0; i < detector->response.hdr_count; i++) { + grpc_http_header* header = &detector->response.hdrs[i]; + if (strcmp(header->key, "Metadata-Flavor") == 0 && + strcmp(header->value, "Google") == 0) { + detector->success = 1; + break; + } + } + } + gpr_mu_lock(g_polling_mu); + detector->is_done = 1; + GRPC_LOG_IF_ERROR( + "Pollset kick", + grpc_pollset_kick(grpc_polling_entity_pollset(&detector->pollent), + nullptr)); + gpr_mu_unlock(g_polling_mu); +} + +static void destroy_pollset(void* p, grpc_error* e) { + grpc_pollset_destroy(static_cast(p)); +} + +static int is_metadata_server_reachable() { + metadata_server_detector detector; + grpc_httpcli_request request; + grpc_httpcli_context context; + grpc_closure destroy_closure; + /* The http call is local. If it takes more than one sec, it is for sure not + on compute engine. */ + grpc_millis max_detection_delay = GPR_MS_PER_SEC; + grpc_pollset* pollset = + static_cast(gpr_zalloc(grpc_pollset_size())); + grpc_pollset_init(pollset, &g_polling_mu); + detector.pollent = grpc_polling_entity_create_from_pollset(pollset); + detector.is_done = 0; + detector.success = 0; + memset(&request, 0, sizeof(grpc_httpcli_request)); + request.host = (char*)GRPC_COMPUTE_ENGINE_DETECTION_HOST; + request.http.path = (char*)"/"; + grpc_httpcli_context_init(&context); + grpc_resource_quota* resource_quota = + grpc_resource_quota_create("google_default_credentials"); + grpc_httpcli_get( + &context, &detector.pollent, resource_quota, &request, + grpc_core::ExecCtx::Get()->Now() + max_detection_delay, + GRPC_CLOSURE_CREATE(on_metadata_server_detection_http_response, &detector, + grpc_schedule_on_exec_ctx), + &detector.response); + grpc_resource_quota_unref_internal(resource_quota); + grpc_core::ExecCtx::Get()->Flush(); + /* Block until we get the response. This is not ideal but this should only be + called once for the lifetime of the process by the default credentials. */ + gpr_mu_lock(g_polling_mu); + while (!detector.is_done) { + grpc_pollset_worker* worker = nullptr; + if (!GRPC_LOG_IF_ERROR( + "pollset_work", + grpc_pollset_work(grpc_polling_entity_pollset(&detector.pollent), + &worker, GRPC_MILLIS_INF_FUTURE))) { + detector.is_done = 1; + detector.success = 0; + } + } + gpr_mu_unlock(g_polling_mu); + grpc_httpcli_context_destroy(&context); + GRPC_CLOSURE_INIT(&destroy_closure, destroy_pollset, + grpc_polling_entity_pollset(&detector.pollent), + grpc_schedule_on_exec_ctx); + grpc_pollset_shutdown(grpc_polling_entity_pollset(&detector.pollent), + &destroy_closure); + g_polling_mu = nullptr; + grpc_core::ExecCtx::Get()->Flush(); + gpr_free(grpc_polling_entity_pollset(&detector.pollent)); + grpc_http_response_destroy(&detector.response); + return detector.success; +} /* Takes ownership of creds_path if not NULL. */ static grpc_error* create_default_creds_from_path( - char* creds_path, grpc_call_credentials** creds) { + char* creds_path, grpc_core::RefCountedPtr* creds) { grpc_json* json = nullptr; grpc_auth_json_key key; grpc_auth_refresh_token token; - grpc_call_credentials* result = nullptr; + grpc_core::RefCountedPtr result; grpc_slice creds_data = grpc_empty_slice(); grpc_error* error = GRPC_ERROR_NONE; if (creds_path == nullptr) { @@ -171,18 +271,17 @@ end: GPR_ASSERT((result == nullptr) + (error == GRPC_ERROR_NONE) == 1); if (creds_path != nullptr) gpr_free(creds_path); grpc_slice_unref_internal(creds_data); - if (json != nullptr) grpc_json_destroy(json); + grpc_json_destroy(json); *creds = result; return error; } -grpc_channel_credentials* grpc_google_default_credentials_create(void) { +grpc_channel_credentials* grpc_google_default_credentials_create() { grpc_channel_credentials* result = nullptr; - grpc_call_credentials* call_creds = nullptr; + grpc_core::RefCountedPtr call_creds; grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( "Failed to create Google credentials"); grpc_error* err; - int need_compute_engine_creds = 0; grpc_core::ExecCtx exec_ctx; GRPC_API_TRACE("grpc_google_default_credentials_create(void)", 0, ()); @@ -202,17 +301,23 @@ grpc_channel_credentials* grpc_google_default_credentials_create(void) { error = grpc_error_add_child(error, err); gpr_mu_lock(&g_state_mu); - /* At last try to see if we're on compute engine (do the detection only once - since it requires a network test). */ - if (!g_compute_engine_detection_done) { - g_need_compute_engine_creds = g_gce_tenancy_checker(); - g_compute_engine_detection_done = 1; + + /* Try a platform-provided hint for GCE. */ + if (!g_metadata_server_available) { + g_is_on_gce = g_gce_tenancy_checker(); + g_metadata_server_available = g_is_on_gce; + } + /* TODO: Add a platform-provided hint for GAE. */ + + /* Do a network test for metadata server. */ + if (!g_metadata_server_available) { + g_metadata_server_available = is_metadata_server_reachable(); } - need_compute_engine_creds = g_need_compute_engine_creds; gpr_mu_unlock(&g_state_mu); - if (need_compute_engine_creds) { - call_creds = grpc_google_compute_engine_credentials_create(nullptr); + if (g_metadata_server_available) { + call_creds = grpc_core::RefCountedPtr( + grpc_google_compute_engine_credentials_create(nullptr)); if (call_creds == nullptr) { error = grpc_error_add_child( error, GRPC_ERROR_CREATE_FROM_STATIC_STRING( @@ -223,23 +328,23 @@ grpc_channel_credentials* grpc_google_default_credentials_create(void) { end: if (call_creds != nullptr) { /* Create google default credentials. */ - auto creds = static_cast( - 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_channel_credentials* ssl_creds = grpc_ssl_credentials_create(nullptr, nullptr, nullptr, nullptr); - GPR_ASSERT(creds->ssl_creds != nullptr); + GPR_ASSERT(ssl_creds != nullptr); grpc_alts_credentials_options* options = grpc_alts_credentials_client_options_create(); - creds->alts_creds = grpc_alts_credentials_create(options); + grpc_channel_credentials* alts_creds = + grpc_alts_credentials_create(options); grpc_alts_credentials_options_destroy(options); - result = grpc_composite_channel_credentials_create(&creds->base, call_creds, - nullptr); + auto creds = + grpc_core::MakeRefCounted( + alts_creds != nullptr ? alts_creds->Ref() : nullptr, + ssl_creds != nullptr ? ssl_creds->Ref() : nullptr); + if (ssl_creds) ssl_creds->Unref(); + if (alts_creds) alts_creds->Unref(); + result = grpc_composite_channel_credentials_create( + creds.get(), call_creds.get(), nullptr); GPR_ASSERT(result != nullptr); - grpc_channel_credentials_unref(&creds->base); - grpc_call_credentials_unref(call_creds); } else { gpr_log(GPR_ERROR, "Could not create google default credentials: %s", grpc_error_string(error)); @@ -259,7 +364,7 @@ void grpc_flush_cached_google_default_credentials(void) { grpc_core::ExecCtx exec_ctx; gpr_once_init(&g_once, init_default_credentials); gpr_mu_lock(&g_state_mu); - g_compute_engine_detection_done = 0; + g_metadata_server_available = 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 b9e2efb04fa..8a945da31e2 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 @@ -21,6 +21,7 @@ #include +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/security/credentials/credentials.h" #define GRPC_GOOGLE_CLOUD_SDK_CONFIG_DIRECTORY "gcloud" @@ -39,11 +40,35 @@ "/" 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; +class grpc_google_default_channel_credentials + : public grpc_channel_credentials { + public: + grpc_google_default_channel_credentials( + grpc_core::RefCountedPtr alts_creds, + grpc_core::RefCountedPtr ssl_creds) + : grpc_channel_credentials(GRPC_CHANNEL_CREDENTIALS_TYPE_GOOGLE_DEFAULT), + alts_creds_(std::move(alts_creds)), + ssl_creds_(std::move(ssl_creds)) {} + + ~grpc_google_default_channel_credentials() override = default; + + grpc_core::RefCountedPtr + create_security_connector( + grpc_core::RefCountedPtr call_creds, + const char* target, const grpc_channel_args* args, + grpc_channel_args** new_args) override; + + grpc_channel_args* update_arguments(grpc_channel_args* args) override; + + const grpc_channel_credentials* alts_creds() const { + return alts_creds_.get(); + } + const grpc_channel_credentials* ssl_creds() const { return ssl_creds_.get(); } + + private: + grpc_core::RefCountedPtr alts_creds_; + grpc_core::RefCountedPtr ssl_creds_; +}; namespace grpc_core { namespace internal { diff --git a/src/core/lib/security/credentials/iam/iam_credentials.cc b/src/core/lib/security/credentials/iam/iam_credentials.cc index 5d92fa88c45..5cd561f676a 100644 --- a/src/core/lib/security/credentials/iam/iam_credentials.cc +++ b/src/core/lib/security/credentials/iam/iam_credentials.cc @@ -22,6 +22,7 @@ #include +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/surface/api_trace.h" #include @@ -29,32 +30,37 @@ #include #include -static void iam_destruct(grpc_call_credentials* creds) { - grpc_google_iam_credentials* c = - reinterpret_cast(creds); - grpc_credentials_mdelem_array_destroy(&c->md_array); +grpc_google_iam_credentials::~grpc_google_iam_credentials() { + grpc_credentials_mdelem_array_destroy(&md_array_); } -static bool iam_get_request_metadata(grpc_call_credentials* creds, - grpc_polling_entity* pollent, - grpc_auth_metadata_context context, - grpc_credentials_mdelem_array* md_array, - grpc_closure* on_request_metadata, - grpc_error** error) { - grpc_google_iam_credentials* c = - reinterpret_cast(creds); - grpc_credentials_mdelem_array_append(md_array, &c->md_array); +bool grpc_google_iam_credentials::get_request_metadata( + grpc_polling_entity* pollent, grpc_auth_metadata_context context, + grpc_credentials_mdelem_array* md_array, grpc_closure* on_request_metadata, + grpc_error** error) { + grpc_credentials_mdelem_array_append(md_array, &md_array_); return true; } -static void iam_cancel_get_request_metadata( - grpc_call_credentials* c, grpc_credentials_mdelem_array* md_array, - grpc_error* error) { +void grpc_google_iam_credentials::cancel_get_request_metadata( + grpc_credentials_mdelem_array* md_array, grpc_error* error) { GRPC_ERROR_UNREF(error); } -static grpc_call_credentials_vtable iam_vtable = { - iam_destruct, iam_get_request_metadata, iam_cancel_get_request_metadata}; +grpc_google_iam_credentials::grpc_google_iam_credentials( + const char* token, const char* authority_selector) + : grpc_call_credentials(GRPC_CALL_CREDENTIALS_TYPE_IAM) { + grpc_mdelem md = grpc_mdelem_from_slices( + grpc_slice_from_static_string(GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY), + grpc_slice_from_copied_string(token)); + grpc_credentials_mdelem_array_add(&md_array_, md); + GRPC_MDELEM_UNREF(md); + md = grpc_mdelem_from_slices( + grpc_slice_from_static_string(GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY), + grpc_slice_from_copied_string(authority_selector)); + grpc_credentials_mdelem_array_add(&md_array_, md); + GRPC_MDELEM_UNREF(md); +} grpc_call_credentials* grpc_google_iam_credentials_create( const char* token, const char* authority_selector, void* reserved) { @@ -66,21 +72,7 @@ grpc_call_credentials* grpc_google_iam_credentials_create( GPR_ASSERT(reserved == nullptr); GPR_ASSERT(token != nullptr); GPR_ASSERT(authority_selector != nullptr); - grpc_google_iam_credentials* c = - static_cast(gpr_zalloc(sizeof(*c))); - c->base.type = GRPC_CALL_CREDENTIALS_TYPE_IAM; - c->base.vtable = &iam_vtable; - gpr_ref_init(&c->base.refcount, 1); - grpc_mdelem md = grpc_mdelem_from_slices( - grpc_slice_from_static_string(GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY), - grpc_slice_from_copied_string(token)); - grpc_credentials_mdelem_array_add(&c->md_array, md); - GRPC_MDELEM_UNREF(md); - md = grpc_mdelem_from_slices( - grpc_slice_from_static_string(GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY), - grpc_slice_from_copied_string(authority_selector)); - grpc_credentials_mdelem_array_add(&c->md_array, md); - GRPC_MDELEM_UNREF(md); - - return &c->base; + return grpc_core::MakeRefCounted( + token, authority_selector) + .release(); } diff --git a/src/core/lib/security/credentials/iam/iam_credentials.h b/src/core/lib/security/credentials/iam/iam_credentials.h index a45710fe0f8..36f5ee89307 100644 --- a/src/core/lib/security/credentials/iam/iam_credentials.h +++ b/src/core/lib/security/credentials/iam/iam_credentials.h @@ -23,9 +23,23 @@ #include "src/core/lib/security/credentials/credentials.h" -typedef struct { - grpc_call_credentials base; - grpc_credentials_mdelem_array md_array; -} grpc_google_iam_credentials; +class grpc_google_iam_credentials : public grpc_call_credentials { + public: + grpc_google_iam_credentials(const char* token, + const char* authority_selector); + ~grpc_google_iam_credentials() override; + + bool get_request_metadata(grpc_polling_entity* pollent, + grpc_auth_metadata_context context, + grpc_credentials_mdelem_array* md_array, + grpc_closure* on_request_metadata, + grpc_error** error) override; + + void cancel_get_request_metadata(grpc_credentials_mdelem_array* md_array, + grpc_error* error) override; + + private: + grpc_credentials_mdelem_array md_array_; +}; #endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_IAM_IAM_CREDENTIALS_H */ diff --git a/src/core/lib/security/credentials/jwt/json_token.cc b/src/core/lib/security/credentials/jwt/json_token.cc index 1c4827df0fc..113e2b83754 100644 --- a/src/core/lib/security/credentials/jwt/json_token.cc +++ b/src/core/lib/security/credentials/jwt/json_token.cc @@ -121,7 +121,7 @@ grpc_auth_json_key grpc_auth_json_key_create_from_string( char* scratchpad = gpr_strdup(json_string); grpc_json* json = grpc_json_parse_string(scratchpad); grpc_auth_json_key result = grpc_auth_json_key_create_from_json(json); - if (json != nullptr) grpc_json_destroy(json); + grpc_json_destroy(json); gpr_free(scratchpad); return result; } diff --git a/src/core/lib/security/credentials/jwt/jwt_credentials.cc b/src/core/lib/security/credentials/jwt/jwt_credentials.cc index 05c08a68b01..df1d05c83b3 100644 --- a/src/core/lib/security/credentials/jwt/jwt_credentials.cc +++ b/src/core/lib/security/credentials/jwt/jwt_credentials.cc @@ -23,6 +23,8 @@ #include #include +#include "src/core/lib/gprpp/ref_counted.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/surface/api_trace.h" #include @@ -30,71 +32,66 @@ #include #include -static void jwt_reset_cache(grpc_service_account_jwt_access_credentials* c) { - GRPC_MDELEM_UNREF(c->cached.jwt_md); - c->cached.jwt_md = GRPC_MDNULL; - if (c->cached.service_url != nullptr) { - gpr_free(c->cached.service_url); - c->cached.service_url = nullptr; +void grpc_service_account_jwt_access_credentials::reset_cache() { + GRPC_MDELEM_UNREF(cached_.jwt_md); + cached_.jwt_md = GRPC_MDNULL; + if (cached_.service_url != nullptr) { + gpr_free(cached_.service_url); + cached_.service_url = nullptr; } - c->cached.jwt_expiration = gpr_inf_past(GPR_CLOCK_REALTIME); + cached_.jwt_expiration = gpr_inf_past(GPR_CLOCK_REALTIME); } -static void jwt_destruct(grpc_call_credentials* creds) { - grpc_service_account_jwt_access_credentials* c = - reinterpret_cast(creds); - grpc_auth_json_key_destruct(&c->key); - jwt_reset_cache(c); - gpr_mu_destroy(&c->cache_mu); +grpc_service_account_jwt_access_credentials:: + ~grpc_service_account_jwt_access_credentials() { + grpc_auth_json_key_destruct(&key_); + reset_cache(); + gpr_mu_destroy(&cache_mu_); } -static bool jwt_get_request_metadata(grpc_call_credentials* creds, - grpc_polling_entity* pollent, - grpc_auth_metadata_context context, - grpc_credentials_mdelem_array* md_array, - grpc_closure* on_request_metadata, - grpc_error** error) { - grpc_service_account_jwt_access_credentials* c = - reinterpret_cast(creds); +bool grpc_service_account_jwt_access_credentials::get_request_metadata( + grpc_polling_entity* pollent, grpc_auth_metadata_context context, + grpc_credentials_mdelem_array* md_array, grpc_closure* on_request_metadata, + grpc_error** error) { gpr_timespec refresh_threshold = gpr_time_from_seconds( GRPC_SECURE_TOKEN_REFRESH_THRESHOLD_SECS, GPR_TIMESPAN); /* See if we can return a cached jwt. */ grpc_mdelem jwt_md = GRPC_MDNULL; { - gpr_mu_lock(&c->cache_mu); - if (c->cached.service_url != nullptr && - strcmp(c->cached.service_url, context.service_url) == 0 && - !GRPC_MDISNULL(c->cached.jwt_md) && - (gpr_time_cmp(gpr_time_sub(c->cached.jwt_expiration, - gpr_now(GPR_CLOCK_REALTIME)), - refresh_threshold) > 0)) { - jwt_md = GRPC_MDELEM_REF(c->cached.jwt_md); + gpr_mu_lock(&cache_mu_); + if (cached_.service_url != nullptr && + strcmp(cached_.service_url, context.service_url) == 0 && + !GRPC_MDISNULL(cached_.jwt_md) && + (gpr_time_cmp( + gpr_time_sub(cached_.jwt_expiration, gpr_now(GPR_CLOCK_REALTIME)), + refresh_threshold) > 0)) { + jwt_md = GRPC_MDELEM_REF(cached_.jwt_md); } - gpr_mu_unlock(&c->cache_mu); + gpr_mu_unlock(&cache_mu_); } if (GRPC_MDISNULL(jwt_md)) { char* jwt = nullptr; /* Generate a new jwt. */ - gpr_mu_lock(&c->cache_mu); - jwt_reset_cache(c); - jwt = grpc_jwt_encode_and_sign(&c->key, context.service_url, - c->jwt_lifetime, nullptr); + gpr_mu_lock(&cache_mu_); + reset_cache(); + jwt = grpc_jwt_encode_and_sign(&key_, context.service_url, jwt_lifetime_, + nullptr); if (jwt != nullptr) { char* md_value; gpr_asprintf(&md_value, "Bearer %s", jwt); gpr_free(jwt); - c->cached.jwt_expiration = - gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), c->jwt_lifetime); - c->cached.service_url = gpr_strdup(context.service_url); - c->cached.jwt_md = grpc_mdelem_from_slices( + cached_.jwt_expiration = + gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), jwt_lifetime_); + cached_.service_url = gpr_strdup(context.service_url); + cached_.jwt_md = grpc_mdelem_from_slices( grpc_slice_from_static_string(GRPC_AUTHORIZATION_METADATA_KEY), grpc_slice_from_copied_string(md_value)); gpr_free(md_value); - jwt_md = GRPC_MDELEM_REF(c->cached.jwt_md); + jwt_md = GRPC_MDELEM_REF(cached_.jwt_md); } - gpr_mu_unlock(&c->cache_mu); + gpr_mu_unlock(&cache_mu_); } if (!GRPC_MDISNULL(jwt_md)) { @@ -106,29 +103,15 @@ static bool jwt_get_request_metadata(grpc_call_credentials* creds, return true; } -static void jwt_cancel_get_request_metadata( - grpc_call_credentials* c, grpc_credentials_mdelem_array* md_array, - grpc_error* error) { +void grpc_service_account_jwt_access_credentials::cancel_get_request_metadata( + grpc_credentials_mdelem_array* md_array, grpc_error* error) { GRPC_ERROR_UNREF(error); } -static grpc_call_credentials_vtable jwt_vtable = { - jwt_destruct, jwt_get_request_metadata, jwt_cancel_get_request_metadata}; - -grpc_call_credentials* -grpc_service_account_jwt_access_credentials_create_from_auth_json_key( - grpc_auth_json_key key, gpr_timespec token_lifetime) { - grpc_service_account_jwt_access_credentials* c; - if (!grpc_auth_json_key_is_valid(&key)) { - gpr_log(GPR_ERROR, "Invalid input for jwt credentials creation"); - return nullptr; - } - c = static_cast( - gpr_zalloc(sizeof(grpc_service_account_jwt_access_credentials))); - c->base.type = GRPC_CALL_CREDENTIALS_TYPE_JWT; - gpr_ref_init(&c->base.refcount, 1); - c->base.vtable = &jwt_vtable; - c->key = key; +grpc_service_account_jwt_access_credentials:: + grpc_service_account_jwt_access_credentials(grpc_auth_json_key key, + gpr_timespec token_lifetime) + : grpc_call_credentials(GRPC_CALL_CREDENTIALS_TYPE_JWT), key_(key) { gpr_timespec max_token_lifetime = grpc_max_auth_token_lifetime(); if (gpr_time_cmp(token_lifetime, max_token_lifetime) > 0) { gpr_log(GPR_INFO, @@ -136,10 +119,20 @@ grpc_service_account_jwt_access_credentials_create_from_auth_json_key( static_cast(max_token_lifetime.tv_sec)); token_lifetime = grpc_max_auth_token_lifetime(); } - c->jwt_lifetime = token_lifetime; - gpr_mu_init(&c->cache_mu); - jwt_reset_cache(c); - return &c->base; + jwt_lifetime_ = token_lifetime; + gpr_mu_init(&cache_mu_); + reset_cache(); +} + +grpc_core::RefCountedPtr +grpc_service_account_jwt_access_credentials_create_from_auth_json_key( + grpc_auth_json_key key, gpr_timespec token_lifetime) { + if (!grpc_auth_json_key_is_valid(&key)) { + gpr_log(GPR_ERROR, "Invalid input for jwt credentials creation"); + return nullptr; + } + return grpc_core::MakeRefCounted( + key, token_lifetime); } static char* redact_private_key(const char* json_key) { @@ -167,7 +160,7 @@ static char* redact_private_key(const char* json_key) { grpc_call_credentials* grpc_service_account_jwt_access_credentials_create( const char* json_key, gpr_timespec token_lifetime, void* reserved) { - if (grpc_api_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_api_trace)) { char* clean_json = redact_private_key(json_key); gpr_log(GPR_INFO, "grpc_service_account_jwt_access_credentials_create(" @@ -181,10 +174,9 @@ grpc_call_credentials* grpc_service_account_jwt_access_credentials_create( gpr_free(clean_json); } GPR_ASSERT(reserved == nullptr); + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; grpc_core::ExecCtx exec_ctx; - grpc_call_credentials* creds = - grpc_service_account_jwt_access_credentials_create_from_auth_json_key( - grpc_auth_json_key_create_from_string(json_key), token_lifetime); - - return creds; + return grpc_service_account_jwt_access_credentials_create_from_auth_json_key( + grpc_auth_json_key_create_from_string(json_key), token_lifetime) + .release(); } diff --git a/src/core/lib/security/credentials/jwt/jwt_credentials.h b/src/core/lib/security/credentials/jwt/jwt_credentials.h index 5c3d34aa566..5af909f44df 100644 --- a/src/core/lib/security/credentials/jwt/jwt_credentials.h +++ b/src/core/lib/security/credentials/jwt/jwt_credentials.h @@ -24,25 +24,44 @@ #include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/security/credentials/jwt/json_token.h" -typedef struct { - grpc_call_credentials base; +class grpc_service_account_jwt_access_credentials + : public grpc_call_credentials { + public: + grpc_service_account_jwt_access_credentials(grpc_auth_json_key key, + gpr_timespec token_lifetime); + ~grpc_service_account_jwt_access_credentials() override; + + bool get_request_metadata(grpc_polling_entity* pollent, + grpc_auth_metadata_context context, + grpc_credentials_mdelem_array* md_array, + grpc_closure* on_request_metadata, + grpc_error** error) override; + + void cancel_get_request_metadata(grpc_credentials_mdelem_array* md_array, + grpc_error* error) override; + + const gpr_timespec& jwt_lifetime() const { return jwt_lifetime_; } + const grpc_auth_json_key& key() const { return key_; } + + private: + void reset_cache(); // Have a simple cache for now with just 1 entry. We could have a map based on // the service_url for a more sophisticated one. - gpr_mu cache_mu; + gpr_mu cache_mu_; struct { - grpc_mdelem jwt_md; - char* service_url; + grpc_mdelem jwt_md = GRPC_MDNULL; + char* service_url = nullptr; gpr_timespec jwt_expiration; - } cached; + } cached_; - grpc_auth_json_key key; - gpr_timespec jwt_lifetime; -} grpc_service_account_jwt_access_credentials; + grpc_auth_json_key key_; + gpr_timespec jwt_lifetime_; +}; // Private constructor for jwt credentials from an already parsed json key. // Takes ownership of the key. -grpc_call_credentials* +grpc_core::RefCountedPtr grpc_service_account_jwt_access_credentials_create_from_auth_json_key( grpc_auth_json_key key, gpr_timespec token_lifetime); diff --git a/src/core/lib/security/credentials/jwt/jwt_verifier.cc b/src/core/lib/security/credentials/jwt/jwt_verifier.cc index c7d1b36ff0a..5b120eddb43 100644 --- a/src/core/lib/security/credentials/jwt/jwt_verifier.cc +++ b/src/core/lib/security/credentials/jwt/jwt_verifier.cc @@ -31,7 +31,9 @@ #include extern "C" { +#include #include +#include } #include "src/core/lib/gpr/string.h" @@ -132,7 +134,8 @@ static void jose_header_destroy(jose_header* h) { } /* Takes ownership of json and buffer. */ -static jose_header* jose_header_from_json(grpc_json* json, grpc_slice buffer) { +static jose_header* jose_header_from_json(grpc_json* json, + const grpc_slice& buffer) { grpc_json* cur; jose_header* h = static_cast(gpr_zalloc(sizeof(jose_header))); h->buffer = buffer; @@ -233,7 +236,8 @@ gpr_timespec grpc_jwt_claims_not_before(const grpc_jwt_claims* claims) { } /* Takes ownership of json and buffer even in case of failure. */ -grpc_jwt_claims* grpc_jwt_claims_from_json(grpc_json* json, grpc_slice buffer) { +grpc_jwt_claims* grpc_jwt_claims_from_json(grpc_json* json, + const grpc_slice& buffer) { grpc_json* cur; grpc_jwt_claims* claims = static_cast(gpr_malloc(sizeof(grpc_jwt_claims))); @@ -348,9 +352,10 @@ typedef struct { /* Takes ownership of the header, claims and signature. */ static verifier_cb_ctx* verifier_cb_ctx_create( grpc_jwt_verifier* verifier, grpc_pollset* pollset, jose_header* header, - grpc_jwt_claims* claims, const char* audience, grpc_slice signature, + grpc_jwt_claims* claims, const char* audience, const grpc_slice& signature, const char* signed_jwt, size_t signed_jwt_len, void* user_data, grpc_jwt_verification_done_cb cb) { + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; grpc_core::ExecCtx exec_ctx; verifier_cb_ctx* ctx = static_cast(gpr_zalloc(sizeof(verifier_cb_ctx))); @@ -599,7 +604,8 @@ static EVP_PKEY* find_verification_key(const grpc_json* json, } static int verify_jwt_signature(EVP_PKEY* key, const char* alg, - grpc_slice signature, grpc_slice signed_data) { + const grpc_slice& signature, + const grpc_slice& signed_data) { EVP_MD_CTX* md_ctx = EVP_MD_CTX_create(); const EVP_MD* md = evp_md_from_alg(alg); int result = 0; @@ -664,7 +670,7 @@ static void on_keys_retrieved(void* user_data, grpc_error* error) { } end: - if (json != nullptr) grpc_json_destroy(json); + grpc_json_destroy(json); EVP_PKEY_free(verification_key); ctx->user_cb(ctx->user_data, status, claims); verifier_cb_ctx_destroy(ctx); @@ -717,7 +723,7 @@ static void on_openid_config_retrieved(void* user_data, grpc_error* error) { return; error: - if (json != nullptr) grpc_json_destroy(json); + grpc_json_destroy(json); ctx->user_cb(ctx->user_data, GRPC_JWT_VERIFIER_KEY_RETRIEVAL_ERROR, nullptr); verifier_cb_ctx_destroy(ctx); } diff --git a/src/core/lib/security/credentials/jwt/jwt_verifier.h b/src/core/lib/security/credentials/jwt/jwt_verifier.h index cdb09870bd5..3f69ada98d5 100644 --- a/src/core/lib/security/credentials/jwt/jwt_verifier.h +++ b/src/core/lib/security/credentials/jwt/jwt_verifier.h @@ -115,7 +115,8 @@ void grpc_jwt_verifier_verify(grpc_jwt_verifier* verifier, /* --- TESTING ONLY exposed functions. --- */ -grpc_jwt_claims* grpc_jwt_claims_from_json(grpc_json* json, grpc_slice buffer); +grpc_jwt_claims* grpc_jwt_claims_from_json(grpc_json* json, + const grpc_slice& buffer); grpc_jwt_verifier_status grpc_jwt_claims_check(const grpc_jwt_claims* claims, const char* audience); const char* grpc_jwt_issuer_email_domain(const char* issuer); diff --git a/src/core/lib/security/credentials/local/local_credentials.cc b/src/core/lib/security/credentials/local/local_credentials.cc index 3ccfa2b9086..6f6f95a34a7 100644 --- a/src/core/lib/security/credentials/local/local_credentials.cc +++ b/src/core/lib/security/credentials/local/local_credentials.cc @@ -29,49 +29,36 @@ #define GRPC_CREDENTIALS_TYPE_LOCAL "Local" -static void local_credentials_destruct(grpc_channel_credentials* creds) {} - -static void local_server_credentials_destruct(grpc_server_credentials* creds) {} - -static grpc_security_status local_create_security_connector( - grpc_channel_credentials* creds, - grpc_call_credentials* request_metadata_creds, const char* target_name, - const grpc_channel_args* args, grpc_channel_security_connector** sc, +grpc_core::RefCountedPtr +grpc_local_credentials::create_security_connector( + grpc_core::RefCountedPtr request_metadata_creds, + const char* target_name, const grpc_channel_args* args, grpc_channel_args** new_args) { return grpc_local_channel_security_connector_create( - creds, request_metadata_creds, args, target_name, sc); + this->Ref(), std::move(request_metadata_creds), args, target_name); } -static grpc_security_status local_server_create_security_connector( - grpc_server_credentials* creds, grpc_server_security_connector** sc) { - return grpc_local_server_security_connector_create(creds, sc); +grpc_core::RefCountedPtr +grpc_local_server_credentials::create_security_connector() { + return grpc_local_server_security_connector_create(this->Ref()); } -static const grpc_channel_credentials_vtable local_credentials_vtable = { - local_credentials_destruct, local_create_security_connector, - /*duplicate_without_call_credentials=*/nullptr}; - -static const grpc_server_credentials_vtable local_server_credentials_vtable = { - local_server_credentials_destruct, local_server_create_security_connector}; +grpc_local_credentials::grpc_local_credentials( + grpc_local_connect_type connect_type) + : grpc_channel_credentials(GRPC_CREDENTIALS_TYPE_LOCAL), + connect_type_(connect_type) {} grpc_channel_credentials* grpc_local_credentials_create( grpc_local_connect_type connect_type) { - auto creds = static_cast( - gpr_zalloc(sizeof(grpc_local_credentials))); - creds->connect_type = connect_type; - creds->base.type = GRPC_CREDENTIALS_TYPE_LOCAL; - creds->base.vtable = &local_credentials_vtable; - gpr_ref_init(&creds->base.refcount, 1); - return &creds->base; + return grpc_core::New(connect_type); } +grpc_local_server_credentials::grpc_local_server_credentials( + grpc_local_connect_type connect_type) + : grpc_server_credentials(GRPC_CREDENTIALS_TYPE_LOCAL), + connect_type_(connect_type) {} + grpc_server_credentials* grpc_local_server_credentials_create( grpc_local_connect_type connect_type) { - auto creds = static_cast( - gpr_zalloc(sizeof(grpc_local_server_credentials))); - creds->connect_type = connect_type; - creds->base.type = GRPC_CREDENTIALS_TYPE_LOCAL; - creds->base.vtable = &local_server_credentials_vtable; - gpr_ref_init(&creds->base.refcount, 1); - return &creds->base; + return grpc_core::New(connect_type); } diff --git a/src/core/lib/security/credentials/local/local_credentials.h b/src/core/lib/security/credentials/local/local_credentials.h index 47358b04bc1..60a8a4f64ca 100644 --- a/src/core/lib/security/credentials/local/local_credentials.h +++ b/src/core/lib/security/credentials/local/local_credentials.h @@ -25,16 +25,37 @@ #include "src/core/lib/security/credentials/credentials.h" -/* Main struct for grpc local channel credential. */ -typedef struct grpc_local_credentials { - grpc_channel_credentials base; - grpc_local_connect_type connect_type; -} grpc_local_credentials; +/* Main class for grpc local channel credential. */ +class grpc_local_credentials final : public grpc_channel_credentials { + public: + explicit grpc_local_credentials(grpc_local_connect_type connect_type); + ~grpc_local_credentials() override = default; -/* Main struct for grpc local server credential. */ -typedef struct grpc_local_server_credentials { - grpc_server_credentials base; - grpc_local_connect_type connect_type; -} grpc_local_server_credentials; + grpc_core::RefCountedPtr + create_security_connector( + grpc_core::RefCountedPtr request_metadata_creds, + const char* target_name, const grpc_channel_args* args, + grpc_channel_args** new_args) override; + + grpc_local_connect_type connect_type() const { return connect_type_; } + + private: + grpc_local_connect_type connect_type_; +}; + +/* Main class for grpc local server credential. */ +class grpc_local_server_credentials final : public grpc_server_credentials { + public: + explicit grpc_local_server_credentials(grpc_local_connect_type connect_type); + ~grpc_local_server_credentials() override = default; + + grpc_core::RefCountedPtr + create_security_connector() override; + + grpc_local_connect_type connect_type() const { return connect_type_; } + + private: + grpc_local_connect_type connect_type_; +}; #endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_LOCAL_LOCAL_CREDENTIALS_H */ diff --git a/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc b/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc index 44b093557f3..b001868b3d3 100644 --- a/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc +++ b/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc @@ -22,6 +22,7 @@ #include +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/security/util/json_util.h" #include "src/core/lib/surface/api_trace.h" @@ -79,7 +80,7 @@ grpc_auth_refresh_token grpc_auth_refresh_token_create_from_string( grpc_json* json = grpc_json_parse_string(scratchpad); grpc_auth_refresh_token result = grpc_auth_refresh_token_create_from_json(json); - if (json != nullptr) grpc_json_destroy(json); + grpc_json_destroy(json); gpr_free(scratchpad); return result; } @@ -105,13 +106,12 @@ void grpc_auth_refresh_token_destruct(grpc_auth_refresh_token* refresh_token) { // Oauth2 Token Fetcher credentials. // -static void oauth2_token_fetcher_destruct(grpc_call_credentials* creds) { - grpc_oauth2_token_fetcher_credentials* c = - reinterpret_cast(creds); - GRPC_MDELEM_UNREF(c->access_token_md); - gpr_mu_destroy(&c->mu); - grpc_pollset_set_destroy(grpc_polling_entity_pollset_set(&c->pollent)); - grpc_httpcli_context_destroy(&c->httpcli_context); +grpc_oauth2_token_fetcher_credentials:: + ~grpc_oauth2_token_fetcher_credentials() { + GRPC_MDELEM_UNREF(access_token_md_); + gpr_mu_destroy(&mu_); + grpc_pollset_set_destroy(grpc_polling_entity_pollset_set(&pollent_)); + grpc_httpcli_context_destroy(&httpcli_context_); } grpc_credentials_status @@ -199,7 +199,7 @@ end: } if (null_terminated_body != nullptr) gpr_free(null_terminated_body); if (new_access_token != nullptr) gpr_free(new_access_token); - if (json != nullptr) grpc_json_destroy(json); + grpc_json_destroy(json); return status; } @@ -209,25 +209,29 @@ static void on_oauth2_token_fetcher_http_response(void* user_data, grpc_credentials_metadata_request* r = static_cast(user_data); grpc_oauth2_token_fetcher_credentials* c = - reinterpret_cast(r->creds); + reinterpret_cast(r->creds.get()); + c->on_http_response(r, error); +} + +void grpc_oauth2_token_fetcher_credentials::on_http_response( + grpc_credentials_metadata_request* r, grpc_error* error) { grpc_mdelem access_token_md = GRPC_MDNULL; grpc_millis token_lifetime; grpc_credentials_status status = grpc_oauth2_token_fetcher_credentials_parse_server_response( &r->response, &access_token_md, &token_lifetime); // Update cache and grab list of pending requests. - gpr_mu_lock(&c->mu); - c->token_fetch_pending = false; - c->access_token_md = GRPC_MDELEM_REF(access_token_md); - c->token_expiration = + gpr_mu_lock(&mu_); + token_fetch_pending_ = false; + access_token_md_ = GRPC_MDELEM_REF(access_token_md); + token_expiration_ = status == GRPC_CREDENTIALS_OK ? gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), gpr_time_from_millis(token_lifetime, GPR_TIMESPAN)) : gpr_inf_past(GPR_CLOCK_MONOTONIC); - grpc_oauth2_pending_get_request_metadata* pending_request = - c->pending_requests; - c->pending_requests = nullptr; - gpr_mu_unlock(&c->mu); + grpc_oauth2_pending_get_request_metadata* pending_request = pending_requests_; + pending_requests_ = nullptr; + gpr_mu_unlock(&mu_); // Invoke callbacks for all pending requests. while (pending_request != nullptr) { if (status == GRPC_CREDENTIALS_OK) { @@ -239,42 +243,40 @@ static void on_oauth2_token_fetcher_http_response(void* user_data, } GRPC_CLOSURE_SCHED(pending_request->on_request_metadata, error); grpc_polling_entity_del_from_pollset_set( - pending_request->pollent, grpc_polling_entity_pollset_set(&c->pollent)); + pending_request->pollent, grpc_polling_entity_pollset_set(&pollent_)); grpc_oauth2_pending_get_request_metadata* prev = pending_request; pending_request = pending_request->next; gpr_free(prev); } GRPC_MDELEM_UNREF(access_token_md); - grpc_call_credentials_unref(r->creds); + Unref(); grpc_credentials_metadata_request_destroy(r); } -static bool oauth2_token_fetcher_get_request_metadata( - grpc_call_credentials* creds, grpc_polling_entity* pollent, - grpc_auth_metadata_context context, grpc_credentials_mdelem_array* md_array, - grpc_closure* on_request_metadata, grpc_error** error) { - grpc_oauth2_token_fetcher_credentials* c = - reinterpret_cast(creds); +bool grpc_oauth2_token_fetcher_credentials::get_request_metadata( + grpc_polling_entity* pollent, grpc_auth_metadata_context context, + grpc_credentials_mdelem_array* md_array, grpc_closure* on_request_metadata, + grpc_error** error) { // Check if we can use the cached token. grpc_millis refresh_threshold = GRPC_SECURE_TOKEN_REFRESH_THRESHOLD_SECS * GPR_MS_PER_SEC; grpc_mdelem cached_access_token_md = GRPC_MDNULL; - gpr_mu_lock(&c->mu); - if (!GRPC_MDISNULL(c->access_token_md) && + gpr_mu_lock(&mu_); + if (!GRPC_MDISNULL(access_token_md_) && gpr_time_cmp( - gpr_time_sub(c->token_expiration, gpr_now(GPR_CLOCK_MONOTONIC)), + gpr_time_sub(token_expiration_, gpr_now(GPR_CLOCK_MONOTONIC)), gpr_time_from_seconds(GRPC_SECURE_TOKEN_REFRESH_THRESHOLD_SECS, GPR_TIMESPAN)) > 0) { - cached_access_token_md = GRPC_MDELEM_REF(c->access_token_md); + cached_access_token_md = GRPC_MDELEM_REF(access_token_md_); } if (!GRPC_MDISNULL(cached_access_token_md)) { - gpr_mu_unlock(&c->mu); + gpr_mu_unlock(&mu_); grpc_credentials_mdelem_array_add(md_array, cached_access_token_md); GRPC_MDELEM_UNREF(cached_access_token_md); return true; } // Couldn't get the token from the cache. - // Add request to c->pending_requests and start a new fetch if needed. + // Add request to pending_requests_ and start a new fetch if needed. grpc_oauth2_pending_get_request_metadata* pending_request = static_cast( gpr_malloc(sizeof(*pending_request))); @@ -282,41 +284,37 @@ static bool oauth2_token_fetcher_get_request_metadata( pending_request->on_request_metadata = on_request_metadata; pending_request->pollent = pollent; grpc_polling_entity_add_to_pollset_set( - pollent, grpc_polling_entity_pollset_set(&c->pollent)); - pending_request->next = c->pending_requests; - c->pending_requests = pending_request; + pollent, grpc_polling_entity_pollset_set(&pollent_)); + pending_request->next = pending_requests_; + pending_requests_ = pending_request; bool start_fetch = false; - if (!c->token_fetch_pending) { - c->token_fetch_pending = true; + if (!token_fetch_pending_) { + token_fetch_pending_ = true; start_fetch = true; } - gpr_mu_unlock(&c->mu); + gpr_mu_unlock(&mu_); if (start_fetch) { - grpc_call_credentials_ref(creds); - c->fetch_func(grpc_credentials_metadata_request_create(creds), - &c->httpcli_context, &c->pollent, - on_oauth2_token_fetcher_http_response, - grpc_core::ExecCtx::Get()->Now() + refresh_threshold); + Ref().release(); + fetch_oauth2(grpc_credentials_metadata_request_create(this->Ref()), + &httpcli_context_, &pollent_, + on_oauth2_token_fetcher_http_response, + grpc_core::ExecCtx::Get()->Now() + refresh_threshold); } return false; } -static void oauth2_token_fetcher_cancel_get_request_metadata( - grpc_call_credentials* creds, grpc_credentials_mdelem_array* md_array, - grpc_error* error) { - grpc_oauth2_token_fetcher_credentials* c = - reinterpret_cast(creds); - gpr_mu_lock(&c->mu); +void grpc_oauth2_token_fetcher_credentials::cancel_get_request_metadata( + grpc_credentials_mdelem_array* md_array, grpc_error* error) { + gpr_mu_lock(&mu_); grpc_oauth2_pending_get_request_metadata* prev = nullptr; - grpc_oauth2_pending_get_request_metadata* pending_request = - c->pending_requests; + grpc_oauth2_pending_get_request_metadata* pending_request = pending_requests_; while (pending_request != nullptr) { if (pending_request->md_array == md_array) { // Remove matching pending request from the list. if (prev != nullptr) { prev->next = pending_request->next; } else { - c->pending_requests = pending_request->next; + pending_requests_ = pending_request->next; } // Invoke the callback immediately with an error. GRPC_CLOSURE_SCHED(pending_request->on_request_metadata, @@ -327,96 +325,89 @@ static void oauth2_token_fetcher_cancel_get_request_metadata( prev = pending_request; pending_request = pending_request->next; } - gpr_mu_unlock(&c->mu); + gpr_mu_unlock(&mu_); GRPC_ERROR_UNREF(error); } -static void init_oauth2_token_fetcher(grpc_oauth2_token_fetcher_credentials* c, - grpc_fetch_oauth2_func fetch_func) { - memset(c, 0, sizeof(grpc_oauth2_token_fetcher_credentials)); - c->base.type = GRPC_CALL_CREDENTIALS_TYPE_OAUTH2; - gpr_ref_init(&c->base.refcount, 1); - gpr_mu_init(&c->mu); - c->token_expiration = gpr_inf_past(GPR_CLOCK_MONOTONIC); - c->fetch_func = fetch_func; - c->pollent = - grpc_polling_entity_create_from_pollset_set(grpc_pollset_set_create()); - grpc_httpcli_context_init(&c->httpcli_context); +grpc_oauth2_token_fetcher_credentials::grpc_oauth2_token_fetcher_credentials() + : grpc_call_credentials(GRPC_CALL_CREDENTIALS_TYPE_OAUTH2), + token_expiration_(gpr_inf_past(GPR_CLOCK_MONOTONIC)), + pollent_(grpc_polling_entity_create_from_pollset_set( + grpc_pollset_set_create())) { + gpr_mu_init(&mu_); + grpc_httpcli_context_init(&httpcli_context_); } // // Google Compute Engine credentials. // -static grpc_call_credentials_vtable compute_engine_vtable = { - oauth2_token_fetcher_destruct, oauth2_token_fetcher_get_request_metadata, - oauth2_token_fetcher_cancel_get_request_metadata}; +namespace { -static void compute_engine_fetch_oauth2( - grpc_credentials_metadata_request* metadata_req, - grpc_httpcli_context* httpcli_context, grpc_polling_entity* pollent, - grpc_iomgr_cb_func response_cb, grpc_millis deadline) { - grpc_http_header header = {(char*)"Metadata-Flavor", (char*)"Google"}; - grpc_httpcli_request request; - memset(&request, 0, sizeof(grpc_httpcli_request)); - request.host = (char*)GRPC_COMPUTE_ENGINE_METADATA_HOST; - request.http.path = (char*)GRPC_COMPUTE_ENGINE_METADATA_TOKEN_PATH; - request.http.hdr_count = 1; - request.http.hdrs = &header; - /* TODO(ctiller): Carry the resource_quota in ctx and share it with the host - channel. This would allow us to cancel an authentication query when under - extreme memory pressure. */ - grpc_resource_quota* resource_quota = - grpc_resource_quota_create("oauth2_credentials"); - grpc_httpcli_get( - httpcli_context, pollent, resource_quota, &request, deadline, - GRPC_CLOSURE_CREATE(response_cb, metadata_req, grpc_schedule_on_exec_ctx), - &metadata_req->response); - grpc_resource_quota_unref_internal(resource_quota); -} +class grpc_compute_engine_token_fetcher_credentials + : public grpc_oauth2_token_fetcher_credentials { + public: + grpc_compute_engine_token_fetcher_credentials() = default; + ~grpc_compute_engine_token_fetcher_credentials() override = default; + + protected: + void fetch_oauth2(grpc_credentials_metadata_request* metadata_req, + grpc_httpcli_context* http_context, + grpc_polling_entity* pollent, + grpc_iomgr_cb_func response_cb, + grpc_millis deadline) override { + grpc_http_header header = {(char*)"Metadata-Flavor", (char*)"Google"}; + grpc_httpcli_request request; + memset(&request, 0, sizeof(grpc_httpcli_request)); + request.host = (char*)GRPC_COMPUTE_ENGINE_METADATA_HOST; + request.http.path = (char*)GRPC_COMPUTE_ENGINE_METADATA_TOKEN_PATH; + request.http.hdr_count = 1; + request.http.hdrs = &header; + /* TODO(ctiller): Carry the resource_quota in ctx and share it with the host + channel. This would allow us to cancel an authentication query when under + extreme memory pressure. */ + grpc_resource_quota* resource_quota = + grpc_resource_quota_create("oauth2_credentials"); + grpc_httpcli_get(http_context, pollent, resource_quota, &request, deadline, + GRPC_CLOSURE_CREATE(response_cb, metadata_req, + grpc_schedule_on_exec_ctx), + &metadata_req->response); + grpc_resource_quota_unref_internal(resource_quota); + } +}; + +} // namespace grpc_call_credentials* grpc_google_compute_engine_credentials_create( void* reserved) { - grpc_oauth2_token_fetcher_credentials* c = - static_cast( - gpr_malloc(sizeof(grpc_oauth2_token_fetcher_credentials))); GRPC_API_TRACE("grpc_compute_engine_credentials_create(reserved=%p)", 1, (reserved)); GPR_ASSERT(reserved == nullptr); - init_oauth2_token_fetcher(c, compute_engine_fetch_oauth2); - c->base.vtable = &compute_engine_vtable; - return &c->base; + return grpc_core::MakeRefCounted< + grpc_compute_engine_token_fetcher_credentials>() + .release(); } // // Google Refresh Token credentials. // -static void refresh_token_destruct(grpc_call_credentials* creds) { - grpc_google_refresh_token_credentials* c = - reinterpret_cast(creds); - grpc_auth_refresh_token_destruct(&c->refresh_token); - oauth2_token_fetcher_destruct(&c->base.base); +grpc_google_refresh_token_credentials:: + ~grpc_google_refresh_token_credentials() { + grpc_auth_refresh_token_destruct(&refresh_token_); } -static grpc_call_credentials_vtable refresh_token_vtable = { - refresh_token_destruct, oauth2_token_fetcher_get_request_metadata, - oauth2_token_fetcher_cancel_get_request_metadata}; - -static void refresh_token_fetch_oauth2( +void grpc_google_refresh_token_credentials::fetch_oauth2( grpc_credentials_metadata_request* metadata_req, grpc_httpcli_context* httpcli_context, grpc_polling_entity* pollent, grpc_iomgr_cb_func response_cb, grpc_millis deadline) { - grpc_google_refresh_token_credentials* c = - reinterpret_cast( - metadata_req->creds); grpc_http_header header = {(char*)"Content-Type", (char*)"application/x-www-form-urlencoded"}; grpc_httpcli_request request; char* body = nullptr; gpr_asprintf(&body, GRPC_REFRESH_TOKEN_POST_BODY_FORMAT_STRING, - c->refresh_token.client_id, c->refresh_token.client_secret, - c->refresh_token.refresh_token); + refresh_token_.client_id, refresh_token_.client_secret, + refresh_token_.refresh_token); memset(&request, 0, sizeof(grpc_httpcli_request)); request.host = (char*)GRPC_GOOGLE_OAUTH2_SERVICE_HOST; request.http.path = (char*)GRPC_GOOGLE_OAUTH2_SERVICE_TOKEN_PATH; @@ -437,20 +428,19 @@ static void refresh_token_fetch_oauth2( gpr_free(body); } -grpc_call_credentials* +grpc_google_refresh_token_credentials::grpc_google_refresh_token_credentials( + grpc_auth_refresh_token refresh_token) + : refresh_token_(refresh_token) {} + +grpc_core::RefCountedPtr grpc_refresh_token_credentials_create_from_auth_refresh_token( grpc_auth_refresh_token refresh_token) { - grpc_google_refresh_token_credentials* c; if (!grpc_auth_refresh_token_is_valid(&refresh_token)) { gpr_log(GPR_ERROR, "Invalid input for refresh token credentials creation"); return nullptr; } - c = static_cast( - gpr_zalloc(sizeof(grpc_google_refresh_token_credentials))); - init_oauth2_token_fetcher(&c->base, refresh_token_fetch_oauth2); - c->base.base.vtable = &refresh_token_vtable; - c->refresh_token = refresh_token; - return &c->base.base; + return grpc_core::MakeRefCounted( + refresh_token); } static char* create_loggable_refresh_token(grpc_auth_refresh_token* token) { @@ -469,7 +459,7 @@ grpc_call_credentials* grpc_google_refresh_token_credentials_create( const char* json_refresh_token, void* reserved) { grpc_auth_refresh_token token = grpc_auth_refresh_token_create_from_string(json_refresh_token); - if (grpc_api_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_api_trace)) { char* loggable_token = create_loggable_refresh_token(&token); gpr_log(GPR_INFO, "grpc_refresh_token_credentials_create(json_refresh_token=%s, " @@ -478,59 +468,50 @@ grpc_call_credentials* grpc_google_refresh_token_credentials_create( gpr_free(loggable_token); } GPR_ASSERT(reserved == nullptr); - return grpc_refresh_token_credentials_create_from_auth_refresh_token(token); + return grpc_refresh_token_credentials_create_from_auth_refresh_token(token) + .release(); } // // Oauth2 Access Token credentials. // -static void access_token_destruct(grpc_call_credentials* creds) { - grpc_access_token_credentials* c = - reinterpret_cast(creds); - GRPC_MDELEM_UNREF(c->access_token_md); +grpc_access_token_credentials::~grpc_access_token_credentials() { + GRPC_MDELEM_UNREF(access_token_md_); } -static bool access_token_get_request_metadata( - grpc_call_credentials* creds, grpc_polling_entity* pollent, - grpc_auth_metadata_context context, grpc_credentials_mdelem_array* md_array, - grpc_closure* on_request_metadata, grpc_error** error) { - grpc_access_token_credentials* c = - reinterpret_cast(creds); - grpc_credentials_mdelem_array_add(md_array, c->access_token_md); +bool grpc_access_token_credentials::get_request_metadata( + grpc_polling_entity* pollent, grpc_auth_metadata_context context, + grpc_credentials_mdelem_array* md_array, grpc_closure* on_request_metadata, + grpc_error** error) { + grpc_credentials_mdelem_array_add(md_array, access_token_md_); return true; } -static void access_token_cancel_get_request_metadata( - grpc_call_credentials* c, grpc_credentials_mdelem_array* md_array, - grpc_error* error) { +void grpc_access_token_credentials::cancel_get_request_metadata( + grpc_credentials_mdelem_array* md_array, grpc_error* error) { GRPC_ERROR_UNREF(error); } -static grpc_call_credentials_vtable access_token_vtable = { - access_token_destruct, access_token_get_request_metadata, - access_token_cancel_get_request_metadata}; +grpc_access_token_credentials::grpc_access_token_credentials( + const char* access_token) + : grpc_call_credentials(GRPC_CALL_CREDENTIALS_TYPE_OAUTH2) { + char* token_md_value; + gpr_asprintf(&token_md_value, "Bearer %s", access_token); + grpc_core::ExecCtx exec_ctx; + access_token_md_ = grpc_mdelem_from_slices( + grpc_slice_from_static_string(GRPC_AUTHORIZATION_METADATA_KEY), + grpc_slice_from_copied_string(token_md_value)); + gpr_free(token_md_value); +} grpc_call_credentials* grpc_access_token_credentials_create( const char* access_token, void* reserved) { - grpc_access_token_credentials* c = - static_cast( - gpr_zalloc(sizeof(grpc_access_token_credentials))); GRPC_API_TRACE( "grpc_access_token_credentials_create(access_token=, " "reserved=%p)", 1, (reserved)); GPR_ASSERT(reserved == nullptr); - c->base.type = GRPC_CALL_CREDENTIALS_TYPE_OAUTH2; - c->base.vtable = &access_token_vtable; - gpr_ref_init(&c->base.refcount, 1); - char* token_md_value; - gpr_asprintf(&token_md_value, "Bearer %s", access_token); - grpc_core::ExecCtx exec_ctx; - c->access_token_md = grpc_mdelem_from_slices( - grpc_slice_from_static_string(GRPC_AUTHORIZATION_METADATA_KEY), - grpc_slice_from_copied_string(token_md_value)); - - gpr_free(token_md_value); - return &c->base; + return grpc_core::MakeRefCounted(access_token) + .release(); } diff --git a/src/core/lib/security/credentials/oauth2/oauth2_credentials.h b/src/core/lib/security/credentials/oauth2/oauth2_credentials.h index 12a1d4484fe..510a78b484a 100644 --- a/src/core/lib/security/credentials/oauth2/oauth2_credentials.h +++ b/src/core/lib/security/credentials/oauth2/oauth2_credentials.h @@ -54,46 +54,91 @@ void grpc_auth_refresh_token_destruct(grpc_auth_refresh_token* refresh_token); // This object is a base for credentials that need to acquire an oauth2 token // from an http service. -typedef void (*grpc_fetch_oauth2_func)(grpc_credentials_metadata_request* req, - grpc_httpcli_context* http_context, - grpc_polling_entity* pollent, - grpc_iomgr_cb_func cb, - grpc_millis deadline); - -typedef struct grpc_oauth2_pending_get_request_metadata { +struct grpc_oauth2_pending_get_request_metadata { grpc_credentials_mdelem_array* md_array; grpc_closure* on_request_metadata; grpc_polling_entity* pollent; struct grpc_oauth2_pending_get_request_metadata* next; -} grpc_oauth2_pending_get_request_metadata; +}; -typedef struct { - grpc_call_credentials base; - gpr_mu mu; - grpc_mdelem access_token_md; - gpr_timespec token_expiration; - bool token_fetch_pending; - grpc_oauth2_pending_get_request_metadata* pending_requests; - grpc_httpcli_context httpcli_context; - grpc_fetch_oauth2_func fetch_func; - grpc_polling_entity pollent; -} grpc_oauth2_token_fetcher_credentials; +class grpc_oauth2_token_fetcher_credentials : public grpc_call_credentials { + public: + grpc_oauth2_token_fetcher_credentials(); + ~grpc_oauth2_token_fetcher_credentials() override; + + bool get_request_metadata(grpc_polling_entity* pollent, + grpc_auth_metadata_context context, + grpc_credentials_mdelem_array* md_array, + grpc_closure* on_request_metadata, + grpc_error** error) override; + + void cancel_get_request_metadata(grpc_credentials_mdelem_array* md_array, + grpc_error* error) override; + + void on_http_response(grpc_credentials_metadata_request* r, + grpc_error* error); + + GRPC_ABSTRACT_BASE_CLASS + + protected: + virtual void fetch_oauth2(grpc_credentials_metadata_request* req, + grpc_httpcli_context* httpcli_context, + grpc_polling_entity* pollent, grpc_iomgr_cb_func cb, + grpc_millis deadline) GRPC_ABSTRACT; + + private: + gpr_mu mu_; + grpc_mdelem access_token_md_ = GRPC_MDNULL; + gpr_timespec token_expiration_; + bool token_fetch_pending_ = false; + grpc_oauth2_pending_get_request_metadata* pending_requests_ = nullptr; + grpc_httpcli_context httpcli_context_; + grpc_polling_entity pollent_; +}; // Google refresh token credentials. -typedef struct { - grpc_oauth2_token_fetcher_credentials base; - grpc_auth_refresh_token refresh_token; -} grpc_google_refresh_token_credentials; +class grpc_google_refresh_token_credentials final + : public grpc_oauth2_token_fetcher_credentials { + public: + grpc_google_refresh_token_credentials(grpc_auth_refresh_token refresh_token); + ~grpc_google_refresh_token_credentials() override; + + const grpc_auth_refresh_token& refresh_token() const { + return refresh_token_; + } + + protected: + void fetch_oauth2(grpc_credentials_metadata_request* req, + grpc_httpcli_context* httpcli_context, + grpc_polling_entity* pollent, grpc_iomgr_cb_func cb, + grpc_millis deadline) override; + + private: + grpc_auth_refresh_token refresh_token_; +}; // Access token credentials. -typedef struct { - grpc_call_credentials base; - grpc_mdelem access_token_md; -} grpc_access_token_credentials; +class grpc_access_token_credentials final : public grpc_call_credentials { + public: + grpc_access_token_credentials(const char* access_token); + ~grpc_access_token_credentials() override; + + bool get_request_metadata(grpc_polling_entity* pollent, + grpc_auth_metadata_context context, + grpc_credentials_mdelem_array* md_array, + grpc_closure* on_request_metadata, + grpc_error** error) override; + + void cancel_get_request_metadata(grpc_credentials_mdelem_array* md_array, + grpc_error* error) override; + + private: + grpc_mdelem access_token_md_; +}; // Private constructor for refresh token credentials from an already parsed // refresh token. Takes ownership of the refresh token. -grpc_call_credentials* +grpc_core::RefCountedPtr grpc_refresh_token_credentials_create_from_auth_refresh_token( grpc_auth_refresh_token token); diff --git a/src/core/lib/security/credentials/plugin/plugin_credentials.cc b/src/core/lib/security/credentials/plugin/plugin_credentials.cc index 4015124298b..333366d0f0a 100644 --- a/src/core/lib/security/credentials/plugin/plugin_credentials.cc +++ b/src/core/lib/security/credentials/plugin/plugin_credentials.cc @@ -35,20 +35,17 @@ grpc_core::TraceFlag grpc_plugin_credentials_trace(false, "plugin_credentials"); -static void plugin_destruct(grpc_call_credentials* creds) { - grpc_plugin_credentials* c = - reinterpret_cast(creds); - gpr_mu_destroy(&c->mu); - if (c->plugin.state != nullptr && c->plugin.destroy != nullptr) { - c->plugin.destroy(c->plugin.state); +grpc_plugin_credentials::~grpc_plugin_credentials() { + gpr_mu_destroy(&mu_); + if (plugin_.state != nullptr && plugin_.destroy != nullptr) { + plugin_.destroy(plugin_.state); } } -static void pending_request_remove_locked( - grpc_plugin_credentials* c, - grpc_plugin_credentials_pending_request* pending_request) { +void grpc_plugin_credentials::pending_request_remove_locked( + pending_request* pending_request) { if (pending_request->prev == nullptr) { - c->pending_requests = pending_request->next; + pending_requests_ = pending_request->next; } else { pending_request->prev->next = pending_request->next; } @@ -62,17 +59,17 @@ static void pending_request_remove_locked( // cancelled out from under us. // When this returns, r->cancelled indicates whether the request was // cancelled before completion. -static void pending_request_complete( - grpc_plugin_credentials_pending_request* r) { - gpr_mu_lock(&r->creds->mu); - if (!r->cancelled) pending_request_remove_locked(r->creds, r); - gpr_mu_unlock(&r->creds->mu); +void grpc_plugin_credentials::pending_request_complete(pending_request* r) { + GPR_DEBUG_ASSERT(r->creds == this); + gpr_mu_lock(&mu_); + if (!r->cancelled) pending_request_remove_locked(r); + gpr_mu_unlock(&mu_); // Ref to credentials not needed anymore. - grpc_call_credentials_unref(&r->creds->base); + Unref(); } static grpc_error* process_plugin_result( - grpc_plugin_credentials_pending_request* r, const grpc_metadata* md, + grpc_plugin_credentials::pending_request* r, const grpc_metadata* md, size_t num_md, grpc_status_code status, const char* error_details) { grpc_error* error = GRPC_ERROR_NONE; if (status != GRPC_STATUS_OK) { @@ -117,24 +114,25 @@ static void plugin_md_request_metadata_ready(void* request, grpc_status_code status, const char* error_details) { /* called from application code */ + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; grpc_core::ExecCtx exec_ctx(GRPC_EXEC_CTX_FLAG_IS_FINISHED | GRPC_EXEC_CTX_FLAG_THREAD_RESOURCE_LOOP); - grpc_plugin_credentials_pending_request* r = - static_cast(request); - if (grpc_plugin_credentials_trace.enabled()) { + grpc_plugin_credentials::pending_request* r = + static_cast(request); + if (GRPC_TRACE_FLAG_ENABLED(grpc_plugin_credentials_trace)) { gpr_log(GPR_INFO, "plugin_credentials[%p]: request %p: plugin returned " "asynchronously", r->creds, r); } // Remove request from pending list if not previously cancelled. - pending_request_complete(r); + r->creds->pending_request_complete(r); // If it has not been cancelled, process it. if (!r->cancelled) { grpc_error* error = process_plugin_result(r, md, num_md, status, error_details); GRPC_CLOSURE_SCHED(r->on_request_metadata, error); - } else if (grpc_plugin_credentials_trace.enabled()) { + } else if (GRPC_TRACE_FLAG_ENABLED(grpc_plugin_credentials_trace)) { gpr_log(GPR_INFO, "plugin_credentials[%p]: request %p: plugin was previously " "cancelled", @@ -143,76 +141,70 @@ static void plugin_md_request_metadata_ready(void* request, gpr_free(r); } -static bool plugin_get_request_metadata(grpc_call_credentials* creds, - grpc_polling_entity* pollent, - grpc_auth_metadata_context context, - grpc_credentials_mdelem_array* md_array, - grpc_closure* on_request_metadata, - grpc_error** error) { - grpc_plugin_credentials* c = - reinterpret_cast(creds); +bool grpc_plugin_credentials::get_request_metadata( + grpc_polling_entity* pollent, grpc_auth_metadata_context context, + grpc_credentials_mdelem_array* md_array, grpc_closure* on_request_metadata, + grpc_error** error) { bool retval = true; // Synchronous return. - if (c->plugin.get_metadata != nullptr) { + if (plugin_.get_metadata != nullptr) { // Create pending_request object. - grpc_plugin_credentials_pending_request* pending_request = - static_cast( - gpr_zalloc(sizeof(*pending_request))); - pending_request->creds = c; - pending_request->md_array = md_array; - pending_request->on_request_metadata = on_request_metadata; + pending_request* request = + static_cast(gpr_zalloc(sizeof(*request))); + request->creds = this; + request->md_array = md_array; + request->on_request_metadata = on_request_metadata; // Add it to the pending list. - gpr_mu_lock(&c->mu); - if (c->pending_requests != nullptr) { - c->pending_requests->prev = pending_request; + gpr_mu_lock(&mu_); + if (pending_requests_ != nullptr) { + pending_requests_->prev = request; } - pending_request->next = c->pending_requests; - c->pending_requests = pending_request; - gpr_mu_unlock(&c->mu); + request->next = pending_requests_; + pending_requests_ = request; + gpr_mu_unlock(&mu_); // Invoke the plugin. The callback holds a ref to us. - if (grpc_plugin_credentials_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_plugin_credentials_trace)) { gpr_log(GPR_INFO, "plugin_credentials[%p]: request %p: invoking plugin", - c, pending_request); + this, request); } - grpc_call_credentials_ref(creds); + Ref().release(); grpc_metadata creds_md[GRPC_METADATA_CREDENTIALS_PLUGIN_SYNC_MAX]; size_t num_creds_md = 0; grpc_status_code status = GRPC_STATUS_OK; const char* error_details = nullptr; - if (!c->plugin.get_metadata(c->plugin.state, context, - plugin_md_request_metadata_ready, - pending_request, creds_md, &num_creds_md, - &status, &error_details)) { - if (grpc_plugin_credentials_trace.enabled()) { + if (!plugin_.get_metadata( + plugin_.state, context, plugin_md_request_metadata_ready, request, + creds_md, &num_creds_md, &status, &error_details)) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_plugin_credentials_trace)) { gpr_log(GPR_INFO, "plugin_credentials[%p]: request %p: plugin will return " "asynchronously", - c, pending_request); + this, request); } return false; // Asynchronous return. } // Returned synchronously. // Remove request from pending list if not previously cancelled. - pending_request_complete(pending_request); + request->creds->pending_request_complete(request); // If the request was cancelled, the error will have been returned // asynchronously by plugin_cancel_get_request_metadata(), so return // false. Otherwise, process the result. - if (pending_request->cancelled) { - if (grpc_plugin_credentials_trace.enabled()) { + if (request->cancelled) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_plugin_credentials_trace)) { gpr_log(GPR_INFO, "plugin_credentials[%p]: request %p was cancelled, error " "will be returned asynchronously", - c, pending_request); + this, request); } retval = false; } else { - if (grpc_plugin_credentials_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_plugin_credentials_trace)) { gpr_log(GPR_INFO, "plugin_credentials[%p]: request %p: plugin returned " "synchronously", - c, pending_request); + this, request); } - *error = process_plugin_result(pending_request, creds_md, num_creds_md, - status, error_details); + *error = process_plugin_result(request, creds_md, num_creds_md, status, + error_details); } // Clean up. for (size_t i = 0; i < num_creds_md; ++i) { @@ -220,51 +212,42 @@ static bool plugin_get_request_metadata(grpc_call_credentials* creds, grpc_slice_unref_internal(creds_md[i].value); } gpr_free((void*)error_details); - gpr_free(pending_request); + gpr_free(request); } return retval; } -static void plugin_cancel_get_request_metadata( - grpc_call_credentials* creds, grpc_credentials_mdelem_array* md_array, - grpc_error* error) { - grpc_plugin_credentials* c = - reinterpret_cast(creds); - gpr_mu_lock(&c->mu); - for (grpc_plugin_credentials_pending_request* pending_request = - c->pending_requests; +void grpc_plugin_credentials::cancel_get_request_metadata( + grpc_credentials_mdelem_array* md_array, grpc_error* error) { + gpr_mu_lock(&mu_); + for (pending_request* pending_request = pending_requests_; pending_request != nullptr; pending_request = pending_request->next) { if (pending_request->md_array == md_array) { - if (grpc_plugin_credentials_trace.enabled()) { - gpr_log(GPR_INFO, "plugin_credentials[%p]: cancelling request %p", c, + if (GRPC_TRACE_FLAG_ENABLED(grpc_plugin_credentials_trace)) { + gpr_log(GPR_INFO, "plugin_credentials[%p]: cancelling request %p", this, pending_request); } pending_request->cancelled = true; GRPC_CLOSURE_SCHED(pending_request->on_request_metadata, GRPC_ERROR_REF(error)); - pending_request_remove_locked(c, pending_request); + pending_request_remove_locked(pending_request); break; } } - gpr_mu_unlock(&c->mu); + gpr_mu_unlock(&mu_); GRPC_ERROR_UNREF(error); } -static grpc_call_credentials_vtable plugin_vtable = { - plugin_destruct, plugin_get_request_metadata, - plugin_cancel_get_request_metadata}; +grpc_plugin_credentials::grpc_plugin_credentials( + grpc_metadata_credentials_plugin plugin) + : grpc_call_credentials(plugin.type), plugin_(plugin) { + gpr_mu_init(&mu_); +} grpc_call_credentials* grpc_metadata_credentials_create_from_plugin( grpc_metadata_credentials_plugin plugin, void* reserved) { - grpc_plugin_credentials* c = - static_cast(gpr_zalloc(sizeof(*c))); GRPC_API_TRACE("grpc_metadata_credentials_create_from_plugin(reserved=%p)", 1, (reserved)); GPR_ASSERT(reserved == nullptr); - c->base.type = plugin.type; - c->base.vtable = &plugin_vtable; - gpr_ref_init(&c->base.refcount, 1); - c->plugin = plugin; - gpr_mu_init(&c->mu); - return &c->base; + return grpc_core::New(plugin); } diff --git a/src/core/lib/security/credentials/plugin/plugin_credentials.h b/src/core/lib/security/credentials/plugin/plugin_credentials.h index caf990efa15..77a957e5137 100644 --- a/src/core/lib/security/credentials/plugin/plugin_credentials.h +++ b/src/core/lib/security/credentials/plugin/plugin_credentials.h @@ -25,22 +25,45 @@ extern grpc_core::TraceFlag grpc_plugin_credentials_trace; -struct grpc_plugin_credentials; +// This type is forward declared as a C struct and we cannot define it as a +// class. Otherwise, compiler will complain about type mismatch due to +// -Wmismatched-tags. +struct grpc_plugin_credentials final : public grpc_call_credentials { + public: + struct pending_request { + bool cancelled; + struct grpc_plugin_credentials* creds; + grpc_credentials_mdelem_array* md_array; + grpc_closure* on_request_metadata; + struct pending_request* prev; + struct pending_request* next; + }; -typedef struct grpc_plugin_credentials_pending_request { - bool cancelled; - struct grpc_plugin_credentials* creds; - grpc_credentials_mdelem_array* md_array; - grpc_closure* on_request_metadata; - struct grpc_plugin_credentials_pending_request* prev; - struct grpc_plugin_credentials_pending_request* next; -} grpc_plugin_credentials_pending_request; + explicit grpc_plugin_credentials(grpc_metadata_credentials_plugin plugin); + ~grpc_plugin_credentials() override; -typedef struct grpc_plugin_credentials { - grpc_call_credentials base; - grpc_metadata_credentials_plugin plugin; - gpr_mu mu; - grpc_plugin_credentials_pending_request* pending_requests; -} grpc_plugin_credentials; + bool get_request_metadata(grpc_polling_entity* pollent, + grpc_auth_metadata_context context, + grpc_credentials_mdelem_array* md_array, + grpc_closure* on_request_metadata, + grpc_error** error) override; + + void cancel_get_request_metadata(grpc_credentials_mdelem_array* md_array, + grpc_error* error) override; + + // Checks if the request has been cancelled. + // If not, removes it from the pending list, so that it cannot be + // cancelled out from under us. + // When this returns, r->cancelled indicates whether the request was + // cancelled before completion. + void pending_request_complete(pending_request* r); + + private: + void pending_request_remove_locked(pending_request* pending_request); + + grpc_metadata_credentials_plugin plugin_; + gpr_mu mu_; + pending_request* pending_requests_ = nullptr; +}; #endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_PLUGIN_PLUGIN_CREDENTIALS_H */ diff --git a/src/core/lib/security/credentials/ssl/ssl_credentials.cc b/src/core/lib/security/credentials/ssl/ssl_credentials.cc index 3d6f2f200a3..83db86f1eac 100644 --- a/src/core/lib/security/credentials/ssl/ssl_credentials.cc +++ b/src/core/lib/security/credentials/ssl/ssl_credentials.cc @@ -44,22 +44,27 @@ void grpc_tsi_ssl_pem_key_cert_pairs_destroy(tsi_ssl_pem_key_cert_pair* kp, gpr_free(kp); } -static void ssl_destruct(grpc_channel_credentials* creds) { - grpc_ssl_credentials* c = reinterpret_cast(creds); - gpr_free(c->config.pem_root_certs); - grpc_tsi_ssl_pem_key_cert_pairs_destroy(c->config.pem_key_cert_pair, 1); - if (c->config.verify_options.verify_peer_destruct != nullptr) { - c->config.verify_options.verify_peer_destruct( - c->config.verify_options.verify_peer_callback_userdata); +grpc_ssl_credentials::grpc_ssl_credentials( + const char* pem_root_certs, grpc_ssl_pem_key_cert_pair* pem_key_cert_pair, + const verify_peer_options* verify_options) + : grpc_channel_credentials(GRPC_CHANNEL_CREDENTIALS_TYPE_SSL) { + build_config(pem_root_certs, pem_key_cert_pair, verify_options); +} + +grpc_ssl_credentials::~grpc_ssl_credentials() { + gpr_free(config_.pem_root_certs); + grpc_tsi_ssl_pem_key_cert_pairs_destroy(config_.pem_key_cert_pair, 1); + if (config_.verify_options.verify_peer_destruct != nullptr) { + config_.verify_options.verify_peer_destruct( + config_.verify_options.verify_peer_callback_userdata); } } -static grpc_security_status ssl_create_security_connector( - grpc_channel_credentials* creds, grpc_call_credentials* call_creds, +grpc_core::RefCountedPtr +grpc_ssl_credentials::create_security_connector( + grpc_core::RefCountedPtr call_creds, const char* target, const grpc_channel_args* args, - grpc_channel_security_connector** sc, grpc_channel_args** new_args) { - grpc_ssl_credentials* c = reinterpret_cast(creds); - grpc_security_status status = GRPC_SECURITY_OK; + grpc_channel_args** new_args) { const char* overridden_target_name = nullptr; tsi_ssl_session_cache* ssl_session_cache = nullptr; for (size_t i = 0; args && i < args->num_args; i++) { @@ -74,52 +79,47 @@ static grpc_security_status ssl_create_security_connector( static_cast(arg->value.pointer.p); } } - status = grpc_ssl_channel_security_connector_create( - creds, call_creds, &c->config, target, overridden_target_name, - ssl_session_cache, sc); - if (status != GRPC_SECURITY_OK) { - return status; + grpc_core::RefCountedPtr sc = + grpc_ssl_channel_security_connector_create( + this->Ref(), std::move(call_creds), &config_, target, + overridden_target_name, ssl_session_cache); + if (sc == nullptr) { + return sc; } grpc_arg new_arg = grpc_channel_arg_string_create( (char*)GRPC_ARG_HTTP2_SCHEME, (char*)"https"); *new_args = grpc_channel_args_copy_and_add(args, &new_arg, 1); - return status; + return sc; } -static grpc_channel_credentials_vtable ssl_vtable = { - ssl_destruct, ssl_create_security_connector, nullptr}; - -static void ssl_build_config(const char* pem_root_certs, - grpc_ssl_pem_key_cert_pair* pem_key_cert_pair, - const verify_peer_options* verify_options, - grpc_ssl_config* config) { - if (pem_root_certs != nullptr) { - config->pem_root_certs = gpr_strdup(pem_root_certs); - } +void grpc_ssl_credentials::build_config( + const char* pem_root_certs, grpc_ssl_pem_key_cert_pair* pem_key_cert_pair, + const verify_peer_options* verify_options) { + config_.pem_root_certs = gpr_strdup(pem_root_certs); if (pem_key_cert_pair != nullptr) { GPR_ASSERT(pem_key_cert_pair->private_key != nullptr); GPR_ASSERT(pem_key_cert_pair->cert_chain != nullptr); - config->pem_key_cert_pair = static_cast( + config_.pem_key_cert_pair = static_cast( gpr_zalloc(sizeof(tsi_ssl_pem_key_cert_pair))); - config->pem_key_cert_pair->cert_chain = + config_.pem_key_cert_pair->cert_chain = gpr_strdup(pem_key_cert_pair->cert_chain); - config->pem_key_cert_pair->private_key = + config_.pem_key_cert_pair->private_key = gpr_strdup(pem_key_cert_pair->private_key); + } else { + config_.pem_key_cert_pair = nullptr; } if (verify_options != nullptr) { - memcpy(&config->verify_options, verify_options, + memcpy(&config_.verify_options, verify_options, sizeof(verify_peer_options)); } else { // Otherwise set all options to default values - memset(&config->verify_options, 0, sizeof(verify_peer_options)); + memset(&config_.verify_options, 0, sizeof(verify_peer_options)); } } grpc_channel_credentials* grpc_ssl_credentials_create( const char* pem_root_certs, grpc_ssl_pem_key_cert_pair* pem_key_cert_pair, const verify_peer_options* verify_options, void* reserved) { - grpc_ssl_credentials* c = static_cast( - gpr_zalloc(sizeof(grpc_ssl_credentials))); GRPC_API_TRACE( "grpc_ssl_credentials_create(pem_root_certs=%s, " "pem_key_cert_pair=%p, " @@ -127,12 +127,9 @@ grpc_channel_credentials* grpc_ssl_credentials_create( "reserved=%p)", 4, (pem_root_certs, pem_key_cert_pair, verify_options, reserved)); GPR_ASSERT(reserved == nullptr); - c->base.type = GRPC_CHANNEL_CREDENTIALS_TYPE_SSL; - c->base.vtable = &ssl_vtable; - gpr_ref_init(&c->base.refcount, 1); - ssl_build_config(pem_root_certs, pem_key_cert_pair, verify_options, - &c->config); - return &c->base; + + return grpc_core::New(pem_root_certs, pem_key_cert_pair, + verify_options); } // @@ -145,21 +142,29 @@ struct grpc_ssl_server_credentials_options { grpc_ssl_server_certificate_config_fetcher* certificate_config_fetcher; }; -static void ssl_server_destruct(grpc_server_credentials* creds) { - grpc_ssl_server_credentials* c = - reinterpret_cast(creds); - grpc_tsi_ssl_pem_key_cert_pairs_destroy(c->config.pem_key_cert_pairs, - c->config.num_key_cert_pairs); - gpr_free(c->config.pem_root_certs); +grpc_ssl_server_credentials::grpc_ssl_server_credentials( + const grpc_ssl_server_credentials_options& options) + : grpc_server_credentials(GRPC_CHANNEL_CREDENTIALS_TYPE_SSL) { + if (options.certificate_config_fetcher != nullptr) { + config_.client_certificate_request = options.client_certificate_request; + certificate_config_fetcher_ = *options.certificate_config_fetcher; + } else { + build_config(options.certificate_config->pem_root_certs, + options.certificate_config->pem_key_cert_pairs, + options.certificate_config->num_key_cert_pairs, + options.client_certificate_request); + } } -static grpc_security_status ssl_server_create_security_connector( - grpc_server_credentials* creds, grpc_server_security_connector** sc) { - return grpc_ssl_server_security_connector_create(creds, sc); +grpc_ssl_server_credentials::~grpc_ssl_server_credentials() { + grpc_tsi_ssl_pem_key_cert_pairs_destroy(config_.pem_key_cert_pairs, + config_.num_key_cert_pairs); + gpr_free(config_.pem_root_certs); +} +grpc_core::RefCountedPtr +grpc_ssl_server_credentials::create_security_connector() { + return grpc_ssl_server_security_connector_create(this->Ref()); } - -static grpc_server_credentials_vtable ssl_server_vtable = { - ssl_server_destruct, ssl_server_create_security_connector}; tsi_ssl_pem_key_cert_pair* grpc_convert_grpc_to_tsi_cert_pairs( const grpc_ssl_pem_key_cert_pair* pem_key_cert_pairs, @@ -179,18 +184,15 @@ tsi_ssl_pem_key_cert_pair* grpc_convert_grpc_to_tsi_cert_pairs( return tsi_pairs; } -static void ssl_build_server_config( +void grpc_ssl_server_credentials::build_config( const char* pem_root_certs, grpc_ssl_pem_key_cert_pair* pem_key_cert_pairs, size_t num_key_cert_pairs, - grpc_ssl_client_certificate_request_type client_certificate_request, - grpc_ssl_server_config* config) { - config->client_certificate_request = client_certificate_request; - if (pem_root_certs != nullptr) { - config->pem_root_certs = gpr_strdup(pem_root_certs); - } - config->pem_key_cert_pairs = grpc_convert_grpc_to_tsi_cert_pairs( + grpc_ssl_client_certificate_request_type client_certificate_request) { + config_.client_certificate_request = client_certificate_request; + config_.pem_root_certs = gpr_strdup(pem_root_certs); + config_.pem_key_cert_pairs = grpc_convert_grpc_to_tsi_cert_pairs( pem_key_cert_pairs, num_key_cert_pairs); - config->num_key_cert_pairs = num_key_cert_pairs; + config_.num_key_cert_pairs = num_key_cert_pairs; } grpc_ssl_server_certificate_config* grpc_ssl_server_certificate_config_create( @@ -200,9 +202,7 @@ grpc_ssl_server_certificate_config* grpc_ssl_server_certificate_config_create( grpc_ssl_server_certificate_config* config = static_cast( gpr_zalloc(sizeof(grpc_ssl_server_certificate_config))); - if (pem_root_certs != nullptr) { - config->pem_root_certs = gpr_strdup(pem_root_certs); - } + config->pem_root_certs = gpr_strdup(pem_root_certs); if (num_key_cert_pairs > 0) { GPR_ASSERT(pem_key_cert_pairs != nullptr); config->pem_key_cert_pairs = static_cast( @@ -311,7 +311,6 @@ grpc_server_credentials* grpc_ssl_server_credentials_create_ex( grpc_server_credentials* grpc_ssl_server_credentials_create_with_options( grpc_ssl_server_credentials_options* options) { grpc_server_credentials* retval = nullptr; - grpc_ssl_server_credentials* c = nullptr; if (options == nullptr) { gpr_log(GPR_ERROR, @@ -331,23 +330,7 @@ grpc_server_credentials* grpc_ssl_server_credentials_create_with_options( goto done; } - c = static_cast( - gpr_zalloc(sizeof(grpc_ssl_server_credentials))); - c->base.type = GRPC_CHANNEL_CREDENTIALS_TYPE_SSL; - gpr_ref_init(&c->base.refcount, 1); - c->base.vtable = &ssl_server_vtable; - - if (options->certificate_config_fetcher != nullptr) { - c->config.client_certificate_request = options->client_certificate_request; - c->certificate_config_fetcher = *options->certificate_config_fetcher; - } else { - ssl_build_server_config(options->certificate_config->pem_root_certs, - options->certificate_config->pem_key_cert_pairs, - options->certificate_config->num_key_cert_pairs, - options->client_certificate_request, &c->config); - } - - retval = &c->base; + retval = grpc_core::New(*options); done: grpc_ssl_server_credentials_options_destroy(options); diff --git a/src/core/lib/security/credentials/ssl/ssl_credentials.h b/src/core/lib/security/credentials/ssl/ssl_credentials.h index 0fba413876e..e1174327b30 100644 --- a/src/core/lib/security/credentials/ssl/ssl_credentials.h +++ b/src/core/lib/security/credentials/ssl/ssl_credentials.h @@ -24,27 +24,70 @@ #include "src/core/lib/security/security_connector/ssl/ssl_security_connector.h" -typedef struct { - grpc_channel_credentials base; - grpc_ssl_config config; -} grpc_ssl_credentials; +class grpc_ssl_credentials : public grpc_channel_credentials { + public: + grpc_ssl_credentials(const char* pem_root_certs, + grpc_ssl_pem_key_cert_pair* pem_key_cert_pair, + const verify_peer_options* verify_options); -struct grpc_ssl_server_certificate_config { - grpc_ssl_pem_key_cert_pair* pem_key_cert_pairs; - size_t num_key_cert_pairs; - char* pem_root_certs; + ~grpc_ssl_credentials() override; + + grpc_core::RefCountedPtr + create_security_connector( + grpc_core::RefCountedPtr call_creds, + const char* target, const grpc_channel_args* args, + grpc_channel_args** new_args) override; + + private: + void build_config(const char* pem_root_certs, + grpc_ssl_pem_key_cert_pair* pem_key_cert_pair, + const verify_peer_options* verify_options); + + grpc_ssl_config config_; }; -typedef struct { - grpc_ssl_server_certificate_config_callback cb; - void* user_data; -} grpc_ssl_server_certificate_config_fetcher; +struct grpc_ssl_server_certificate_config { + grpc_ssl_pem_key_cert_pair* pem_key_cert_pairs = nullptr; + size_t num_key_cert_pairs = 0; + char* pem_root_certs = nullptr; +}; -typedef struct { - grpc_server_credentials base; - grpc_ssl_server_config config; - grpc_ssl_server_certificate_config_fetcher certificate_config_fetcher; -} grpc_ssl_server_credentials; +struct grpc_ssl_server_certificate_config_fetcher { + grpc_ssl_server_certificate_config_callback cb = nullptr; + void* user_data; +}; + +class grpc_ssl_server_credentials final : public grpc_server_credentials { + public: + grpc_ssl_server_credentials( + const grpc_ssl_server_credentials_options& options); + ~grpc_ssl_server_credentials() override; + + grpc_core::RefCountedPtr + create_security_connector() override; + + bool has_cert_config_fetcher() const { + return certificate_config_fetcher_.cb != nullptr; + } + + grpc_ssl_certificate_config_reload_status FetchCertConfig( + grpc_ssl_server_certificate_config** config) { + GPR_DEBUG_ASSERT(has_cert_config_fetcher()); + return certificate_config_fetcher_.cb(certificate_config_fetcher_.user_data, + config); + } + + const grpc_ssl_server_config& config() const { return config_; } + + private: + void build_config( + const char* pem_root_certs, + grpc_ssl_pem_key_cert_pair* pem_key_cert_pairs, size_t num_key_cert_pairs, + grpc_ssl_client_certificate_request_type client_certificate_request); + + grpc_ssl_server_config config_; + grpc_ssl_server_certificate_config_fetcher certificate_config_fetcher_; +}; tsi_ssl_pem_key_cert_pair* grpc_convert_grpc_to_tsi_cert_pairs( const grpc_ssl_pem_key_cert_pair* pem_key_cert_pairs, diff --git a/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc b/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc new file mode 100644 index 00000000000..a6169a1b586 --- /dev/null +++ b/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc @@ -0,0 +1,192 @@ +/* + * + * 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 + +#include "src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h" + +#include +#include + +#include +#include +#include + +/** -- gRPC TLS key materials config API implementation. -- **/ +void grpc_tls_key_materials_config::set_key_materials( + grpc_core::UniquePtr pem_root_certs, + PemKeyCertPairList pem_key_cert_pair_list) { + pem_key_cert_pair_list_ = std::move(pem_key_cert_pair_list); + pem_root_certs_ = std::move(pem_root_certs); +} + +/** -- gRPC TLS credential reload config API implementation. -- **/ +grpc_tls_credential_reload_config::grpc_tls_credential_reload_config( + const void* config_user_data, + int (*schedule)(void* config_user_data, + grpc_tls_credential_reload_arg* arg), + void (*cancel)(void* config_user_data, grpc_tls_credential_reload_arg* arg), + void (*destruct)(void* config_user_data)) + : config_user_data_(const_cast(config_user_data)), + schedule_(schedule), + cancel_(cancel), + destruct_(destruct) {} + +grpc_tls_credential_reload_config::~grpc_tls_credential_reload_config() { + if (destruct_ != nullptr) { + destruct_((void*)config_user_data_); + } +} + +/** -- gRPC TLS server authorization check API implementation. -- **/ +grpc_tls_server_authorization_check_config:: + grpc_tls_server_authorization_check_config( + const void* config_user_data, + int (*schedule)(void* config_user_data, + grpc_tls_server_authorization_check_arg* arg), + void (*cancel)(void* config_user_data, + grpc_tls_server_authorization_check_arg* arg), + void (*destruct)(void* config_user_data)) + : config_user_data_(const_cast(config_user_data)), + schedule_(schedule), + cancel_(cancel), + destruct_(destruct) {} + +grpc_tls_server_authorization_check_config:: + ~grpc_tls_server_authorization_check_config() { + if (destruct_ != nullptr) { + destruct_((void*)config_user_data_); + } +} + +/** -- Wrapper APIs declared in grpc_security.h -- **/ +grpc_tls_credentials_options* grpc_tls_credentials_options_create() { + return grpc_core::New(); +} + +int grpc_tls_credentials_options_set_cert_request_type( + grpc_tls_credentials_options* options, + grpc_ssl_client_certificate_request_type type) { + if (options == nullptr) { + gpr_log(GPR_ERROR, + "Invalid nullptr arguments to " + "grpc_tls_credentials_options_set_cert_request_type()"); + return 0; + } + options->set_cert_request_type(type); + return 1; +} + +int grpc_tls_credentials_options_set_key_materials_config( + grpc_tls_credentials_options* options, + grpc_tls_key_materials_config* config) { + if (options == nullptr || config == nullptr) { + gpr_log(GPR_ERROR, + "Invalid nullptr arguments to " + "grpc_tls_credentials_options_set_key_materials_config()"); + return 0; + } + options->set_key_materials_config(config->Ref()); + return 1; +} + +int grpc_tls_credentials_options_set_credential_reload_config( + grpc_tls_credentials_options* options, + grpc_tls_credential_reload_config* config) { + if (options == nullptr || config == nullptr) { + gpr_log(GPR_ERROR, + "Invalid nullptr arguments to " + "grpc_tls_credentials_options_set_credential_reload_config()"); + return 0; + } + options->set_credential_reload_config(config->Ref()); + return 1; +} + +int grpc_tls_credentials_options_set_server_authorization_check_config( + grpc_tls_credentials_options* options, + grpc_tls_server_authorization_check_config* config) { + if (options == nullptr || config == nullptr) { + gpr_log( + GPR_ERROR, + "Invalid nullptr arguments to " + "grpc_tls_credentials_options_set_server_authorization_check_config()"); + return 0; + } + options->set_server_authorization_check_config(config->Ref()); + return 1; +} + +grpc_tls_key_materials_config* grpc_tls_key_materials_config_create() { + return grpc_core::New(); +} + +int grpc_tls_key_materials_config_set_key_materials( + grpc_tls_key_materials_config* config, const char* root_certs, + const grpc_ssl_pem_key_cert_pair** key_cert_pairs, size_t num) { + if (config == nullptr || key_cert_pairs == nullptr || num == 0) { + gpr_log(GPR_ERROR, + "Invalid arguments to " + "grpc_tls_key_materials_config_set_key_materials()"); + return 0; + } + grpc_core::UniquePtr pem_root(const_cast(root_certs)); + grpc_tls_key_materials_config::PemKeyCertPairList cert_pair_list; + for (size_t i = 0; i < num; i++) { + grpc_core::PemKeyCertPair key_cert_pair( + const_cast(key_cert_pairs[i])); + cert_pair_list.emplace_back(std::move(key_cert_pair)); + } + config->set_key_materials(std::move(pem_root), std::move(cert_pair_list)); + gpr_free(key_cert_pairs); + return 1; +} + +grpc_tls_credential_reload_config* grpc_tls_credential_reload_config_create( + const void* config_user_data, + int (*schedule)(void* config_user_data, + grpc_tls_credential_reload_arg* arg), + void (*cancel)(void* config_user_data, grpc_tls_credential_reload_arg* arg), + void (*destruct)(void* config_user_data)) { + if (schedule == nullptr) { + gpr_log( + GPR_ERROR, + "Schedule API is nullptr in creating TLS credential reload config."); + return nullptr; + } + return grpc_core::New( + config_user_data, schedule, cancel, destruct); +} + +grpc_tls_server_authorization_check_config* +grpc_tls_server_authorization_check_config_create( + const void* config_user_data, + int (*schedule)(void* config_user_data, + grpc_tls_server_authorization_check_arg* arg), + void (*cancel)(void* config_user_data, + grpc_tls_server_authorization_check_arg* arg), + void (*destruct)(void* config_user_data)) { + if (schedule == nullptr) { + gpr_log(GPR_ERROR, + "Schedule API is nullptr in creating TLS server authorization " + "check config."); + return nullptr; + } + return grpc_core::New( + config_user_data, schedule, cancel, destruct); +} diff --git a/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h b/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h new file mode 100644 index 00000000000..aee9292acb8 --- /dev/null +++ b/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h @@ -0,0 +1,210 @@ +/* + * + * 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_SECURITY_CREDENTIALS_TLS_GRPC_TLS_CREDENTIALS_OPTIONS_H +#define GRPC_CORE_LIB_SECURITY_CREDENTIALS_TLS_GRPC_TLS_CREDENTIALS_OPTIONS_H + +#include + +#include + +#include "src/core/lib/gprpp/inlined_vector.h" +#include "src/core/lib/gprpp/ref_counted.h" +#include "src/core/lib/security/security_connector/ssl_utils.h" + +/** TLS key materials config. **/ +struct grpc_tls_key_materials_config + : public grpc_core::RefCounted { + public: + typedef grpc_core::InlinedVector + PemKeyCertPairList; + + /** Getters for member fields. **/ + const char* pem_root_certs() const { return pem_root_certs_.get(); } + const PemKeyCertPairList& pem_key_cert_pair_list() const { + return pem_key_cert_pair_list_; + } + + /** Setters for member fields. **/ + void set_key_materials(grpc_core::UniquePtr pem_root_certs, + PemKeyCertPairList pem_key_cert_pair_list); + + private: + PemKeyCertPairList pem_key_cert_pair_list_; + grpc_core::UniquePtr pem_root_certs_; +}; + +/** TLS credential reload config. **/ +struct grpc_tls_credential_reload_config + : public grpc_core::RefCounted { + public: + grpc_tls_credential_reload_config( + const void* config_user_data, + int (*schedule)(void* config_user_data, + grpc_tls_credential_reload_arg* arg), + void (*cancel)(void* config_user_data, + grpc_tls_credential_reload_arg* arg), + void (*destruct)(void* config_user_data)); + ~grpc_tls_credential_reload_config(); + + int Schedule(grpc_tls_credential_reload_arg* arg) const { + return schedule_(config_user_data_, arg); + } + void Cancel(grpc_tls_credential_reload_arg* arg) const { + if (cancel_ == nullptr) { + gpr_log(GPR_ERROR, "cancel API is nullptr."); + return; + } + cancel_(config_user_data_, arg); + } + + private: + /** config-specific, read-only user data that works for all channels created + with a credential using the config. */ + void* config_user_data_; + /** callback function for invoking credential reload API. The implementation + of this method has to be non-blocking, but can be performed synchronously + or asynchronously. + If processing occurs synchronously, it populates \a arg->key_materials, \a + arg->status, and \a arg->error_details and returns zero. + If processing occurs asynchronously, it returns a non-zero value. + Application then invokes \a arg->cb when processing is completed. Note that + \a arg->cb cannot be invoked before \a schedule returns. + */ + int (*schedule_)(void* config_user_data, grpc_tls_credential_reload_arg* arg); + /** callback function for cancelling a credential reload request scheduled via + an asynchronous \a schedule. \a arg is used to pinpoint an exact reloading + request to be cancelled, and the operation may not have any effect if the + request has already been processed. */ + void (*cancel_)(void* config_user_data, grpc_tls_credential_reload_arg* arg); + /** callback function for cleaning up any data associated with credential + reload config. */ + void (*destruct_)(void* config_user_data); +}; + +/** TLS server authorization check config. **/ +struct grpc_tls_server_authorization_check_config + : public grpc_core::RefCounted { + public: + grpc_tls_server_authorization_check_config( + const void* config_user_data, + int (*schedule)(void* config_user_data, + grpc_tls_server_authorization_check_arg* arg), + void (*cancel)(void* config_user_data, + grpc_tls_server_authorization_check_arg* arg), + void (*destruct)(void* config_user_data)); + ~grpc_tls_server_authorization_check_config(); + + int Schedule(grpc_tls_server_authorization_check_arg* arg) const { + return schedule_(config_user_data_, arg); + } + void Cancel(grpc_tls_server_authorization_check_arg* arg) const { + if (cancel_ == nullptr) { + gpr_log(GPR_ERROR, "cancel API is nullptr."); + return; + } + cancel_(config_user_data_, arg); + } + + private: + /** config-specific, read-only user data that works for all channels created + with a Credential using the config. */ + void* config_user_data_; + + /** callback function for invoking server authorization check. The + implementation of this method has to be non-blocking, but can be performed + synchronously or asynchronously. + If processing occurs synchronously, it populates \a arg->result, \a + arg->status, and \a arg->error_details, and returns zero. + If processing occurs asynchronously, it returns a non-zero value. + Application then invokes \a arg->cb when processing is completed. Note that + \a arg->cb cannot be invoked before \a schedule() returns. + */ + int (*schedule_)(void* config_user_data, + grpc_tls_server_authorization_check_arg* arg); + + /** callback function for canceling a server authorization check request. */ + void (*cancel_)(void* config_user_data, + grpc_tls_server_authorization_check_arg* arg); + + /** callback function for cleaning up any data associated with server + authorization check config. */ + void (*destruct_)(void* config_user_data); +}; + +/* TLS credentials options. */ +struct grpc_tls_credentials_options + : public grpc_core::RefCounted { + public: + ~grpc_tls_credentials_options() { + if (key_materials_config_.get() != nullptr) { + key_materials_config_.get()->Unref(); + } + if (credential_reload_config_.get() != nullptr) { + credential_reload_config_.get()->Unref(); + } + if (server_authorization_check_config_.get() != nullptr) { + server_authorization_check_config_.get()->Unref(); + } + } + + /* Getters for member fields. */ + grpc_ssl_client_certificate_request_type cert_request_type() const { + return cert_request_type_; + } + grpc_tls_key_materials_config* key_materials_config() const { + return key_materials_config_.get(); + } + grpc_tls_credential_reload_config* credential_reload_config() const { + return credential_reload_config_.get(); + } + grpc_tls_server_authorization_check_config* + server_authorization_check_config() const { + return server_authorization_check_config_.get(); + } + + /* Setters for member fields. */ + void set_cert_request_type( + const grpc_ssl_client_certificate_request_type type) { + cert_request_type_ = type; + } + void set_key_materials_config( + grpc_core::RefCountedPtr config) { + key_materials_config_ = std::move(config); + } + void set_credential_reload_config( + grpc_core::RefCountedPtr config) { + credential_reload_config_ = std::move(config); + } + void set_server_authorization_check_config( + grpc_core::RefCountedPtr + config) { + server_authorization_check_config_ = std::move(config); + } + + private: + grpc_ssl_client_certificate_request_type cert_request_type_; + grpc_core::RefCountedPtr key_materials_config_; + grpc_core::RefCountedPtr + credential_reload_config_; + grpc_core::RefCountedPtr + server_authorization_check_config_; +}; + +#endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_TLS_GRPC_TLS_CREDENTIALS_OPTIONS_H \ + */ diff --git a/src/core/lib/security/credentials/tls/spiffe_credentials.cc b/src/core/lib/security/credentials/tls/spiffe_credentials.cc new file mode 100644 index 00000000000..da764936c76 --- /dev/null +++ b/src/core/lib/security/credentials/tls/spiffe_credentials.cc @@ -0,0 +1,129 @@ +/* + * + * 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 + +#include "src/core/lib/security/credentials/tls/spiffe_credentials.h" + +#include + +#include +#include +#include +#include + +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/security/security_connector/tls/spiffe_security_connector.h" + +#define GRPC_CREDENTIALS_TYPE_SPIFFE "Spiffe" + +namespace { + +bool CredentialOptionSanityCheck(const grpc_tls_credentials_options* options, + bool is_client) { + if (options == nullptr) { + gpr_log(GPR_ERROR, "SPIFFE TLS credentials options is nullptr."); + return false; + } + if (options->key_materials_config() == nullptr && + options->credential_reload_config() == nullptr) { + gpr_log( + GPR_ERROR, + "SPIFFE TLS credentials options must specify either key materials or " + "credential reload config."); + return false; + } + if (!is_client && options->server_authorization_check_config() != nullptr) { + gpr_log(GPR_INFO, + "Server's credentials options should not contain server " + "authorization check config."); + } + return true; +} + +} // namespace + +SpiffeCredentials::SpiffeCredentials( + grpc_core::RefCountedPtr options) + : grpc_channel_credentials(GRPC_CREDENTIALS_TYPE_SPIFFE), + options_(std::move(options)) {} + +SpiffeCredentials::~SpiffeCredentials() {} + +grpc_core::RefCountedPtr +SpiffeCredentials::create_security_connector( + grpc_core::RefCountedPtr call_creds, + const char* target_name, const grpc_channel_args* args, + grpc_channel_args** new_args) { + const char* overridden_target_name = nullptr; + tsi_ssl_session_cache* ssl_session_cache = nullptr; + for (size_t i = 0; args != nullptr && i < args->num_args; i++) { + grpc_arg* arg = &args->args[i]; + if (strcmp(arg->key, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG) == 0 && + arg->type == GRPC_ARG_STRING) { + overridden_target_name = arg->value.string; + } + if (strcmp(arg->key, GRPC_SSL_SESSION_CACHE_ARG) == 0 && + arg->type == GRPC_ARG_POINTER) { + ssl_session_cache = + static_cast(arg->value.pointer.p); + } + } + grpc_core::RefCountedPtr sc = + SpiffeChannelSecurityConnector::CreateSpiffeChannelSecurityConnector( + this->Ref(), std::move(call_creds), target_name, + overridden_target_name, ssl_session_cache); + if (sc == nullptr) { + return nullptr; + } + grpc_arg new_arg = grpc_channel_arg_string_create( + (char*)GRPC_ARG_HTTP2_SCHEME, (char*)"https"); + *new_args = grpc_channel_args_copy_and_add(args, &new_arg, 1); + return sc; +} + +SpiffeServerCredentials::SpiffeServerCredentials( + grpc_core::RefCountedPtr options) + : grpc_server_credentials(GRPC_CREDENTIALS_TYPE_SPIFFE), + options_(std::move(options)) {} + +SpiffeServerCredentials::~SpiffeServerCredentials() {} + +grpc_core::RefCountedPtr +SpiffeServerCredentials::create_security_connector() { + return SpiffeServerSecurityConnector::CreateSpiffeServerSecurityConnector( + this->Ref()); +} + +grpc_channel_credentials* grpc_tls_spiffe_credentials_create( + grpc_tls_credentials_options* options) { + if (!CredentialOptionSanityCheck(options, true /* is_client */)) { + return nullptr; + } + return grpc_core::New( + grpc_core::RefCountedPtr(options)); +} + +grpc_server_credentials* grpc_tls_spiffe_server_credentials_create( + grpc_tls_credentials_options* options) { + if (!CredentialOptionSanityCheck(options, false /* is_client */)) { + return nullptr; + } + return grpc_core::New( + grpc_core::RefCountedPtr(options)); +} diff --git a/src/core/lib/security/credentials/tls/spiffe_credentials.h b/src/core/lib/security/credentials/tls/spiffe_credentials.h new file mode 100644 index 00000000000..4985fda4a7e --- /dev/null +++ b/src/core/lib/security/credentials/tls/spiffe_credentials.h @@ -0,0 +1,62 @@ +/* + * + * 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_SECURITY_CREDENTIALS_TLS_SPIFFE_CREDENTIALS_H +#define GRPC_CORE_LIB_SECURITY_CREDENTIALS_TLS_SPIFFE_CREDENTIALS_H + +#include + +#include + +#include "src/core/lib/security/credentials/credentials.h" +#include "src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h" + +class SpiffeCredentials final : public grpc_channel_credentials { + public: + explicit SpiffeCredentials( + grpc_core::RefCountedPtr options); + ~SpiffeCredentials() override; + + grpc_core::RefCountedPtr + create_security_connector( + grpc_core::RefCountedPtr call_creds, + const char* target_name, const grpc_channel_args* args, + grpc_channel_args** new_args) override; + + const grpc_tls_credentials_options& options() const { return *options_; } + + private: + grpc_core::RefCountedPtr options_; +}; + +class SpiffeServerCredentials final : public grpc_server_credentials { + public: + explicit SpiffeServerCredentials( + grpc_core::RefCountedPtr options); + ~SpiffeServerCredentials() override; + + grpc_core::RefCountedPtr + create_security_connector() override; + + const grpc_tls_credentials_options& options() const { return *options_; } + + private: + grpc_core::RefCountedPtr options_; +}; + +#endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_TLS_SPIFFE_CREDENTIALS_H */ diff --git a/src/core/lib/security/security_connector/alts/alts_security_connector.cc b/src/core/lib/security/security_connector/alts/alts_security_connector.cc index dd71c8bc606..38b1f856d52 100644 --- a/src/core/lib/security/security_connector/alts/alts_security_connector.cc +++ b/src/core/lib/security/security_connector/alts/alts_security_connector.cc @@ -28,6 +28,7 @@ #include #include +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/security/credentials/alts/alts_credentials.h" #include "src/core/lib/security/transport/security_handshaker.h" #include "src/core/lib/slice/slice_internal.h" @@ -35,64 +36,9 @@ #include "src/core/tsi/alts/handshaker/alts_tsi_handshaker.h" #include "src/core/tsi/transport_security.h" -typedef struct { - grpc_channel_security_connector base; - char* target_name; -} grpc_alts_channel_security_connector; +namespace { -typedef struct { - grpc_server_security_connector base; -} grpc_alts_server_security_connector; - -static void alts_channel_destroy(grpc_security_connector* sc) { - if (sc == nullptr) { - return; - } - auto c = reinterpret_cast(sc); - grpc_call_credentials_unref(c->base.request_metadata_creds); - grpc_channel_credentials_unref(c->base.channel_creds); - gpr_free(c->target_name); - gpr_free(sc); -} - -static void alts_server_destroy(grpc_security_connector* sc) { - if (sc == nullptr) { - return; - } - auto c = reinterpret_cast(sc); - grpc_server_credentials_unref(c->base.server_creds); - gpr_free(sc); -} - -static void alts_channel_add_handshakers( - grpc_channel_security_connector* sc, grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_manager) { - tsi_handshaker* handshaker = nullptr; - auto c = reinterpret_cast(sc); - grpc_alts_credentials* creds = - reinterpret_cast(c->base.channel_creds); - GPR_ASSERT(alts_tsi_handshaker_create( - creds->options, c->target_name, creds->handshaker_service_url, - true, interested_parties, &handshaker) == TSI_OK); - grpc_handshake_manager_add(handshake_manager, grpc_security_handshaker_create( - handshaker, &sc->base)); -} - -static void alts_server_add_handshakers( - grpc_server_security_connector* sc, grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_manager) { - tsi_handshaker* handshaker = nullptr; - auto c = reinterpret_cast(sc); - grpc_alts_server_credentials* creds = - reinterpret_cast(c->base.server_creds); - GPR_ASSERT(alts_tsi_handshaker_create( - creds->options, nullptr, creds->handshaker_service_url, false, - interested_parties, &handshaker) == TSI_OK); - grpc_handshake_manager_add(handshake_manager, grpc_security_handshaker_create( - handshaker, &sc->base)); -} - -static void alts_set_rpc_protocol_versions( +void alts_set_rpc_protocol_versions( grpc_gcp_rpc_protocol_versions* rpc_versions) { grpc_gcp_rpc_protocol_versions_set_max(rpc_versions, GRPC_PROTOCOL_VERSION_MAX_MAJOR, @@ -102,17 +48,133 @@ static void alts_set_rpc_protocol_versions( GRPC_PROTOCOL_VERSION_MIN_MINOR); } +void alts_check_peer(tsi_peer peer, + grpc_core::RefCountedPtr* auth_context, + grpc_closure* on_peer_checked) { + *auth_context = + grpc_core::internal::grpc_alts_auth_context_from_tsi_peer(&peer); + tsi_peer_destruct(&peer); + grpc_error* error = + *auth_context != nullptr + ? GRPC_ERROR_NONE + : GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Could not get ALTS auth context from TSI peer"); + GRPC_CLOSURE_SCHED(on_peer_checked, error); +} + +class grpc_alts_channel_security_connector final + : public grpc_channel_security_connector { + public: + grpc_alts_channel_security_connector( + grpc_core::RefCountedPtr channel_creds, + grpc_core::RefCountedPtr request_metadata_creds, + const char* target_name) + : grpc_channel_security_connector(/*url_scheme=*/nullptr, + std::move(channel_creds), + std::move(request_metadata_creds)), + target_name_(gpr_strdup(target_name)) { + grpc_alts_credentials* creds = + static_cast(mutable_channel_creds()); + alts_set_rpc_protocol_versions(&creds->mutable_options()->rpc_versions); + } + + ~grpc_alts_channel_security_connector() override { gpr_free(target_name_); } + + void add_handshakers( + grpc_pollset_set* interested_parties, + grpc_core::HandshakeManager* handshake_manager) override { + tsi_handshaker* handshaker = nullptr; + const grpc_alts_credentials* creds = + static_cast(channel_creds()); + GPR_ASSERT(alts_tsi_handshaker_create(creds->options(), target_name_, + creds->handshaker_service_url(), true, + interested_parties, + &handshaker) == TSI_OK); + handshake_manager->Add( + grpc_core::SecurityHandshakerCreate(handshaker, this)); + } + + void check_peer(tsi_peer peer, grpc_endpoint* ep, + grpc_core::RefCountedPtr* auth_context, + grpc_closure* on_peer_checked) override { + alts_check_peer(peer, auth_context, on_peer_checked); + } + + int cmp(const grpc_security_connector* other_sc) const override { + auto* other = + reinterpret_cast(other_sc); + int c = channel_security_connector_cmp(other); + if (c != 0) return c; + return strcmp(target_name_, other->target_name_); + } + + bool check_call_host(const char* host, grpc_auth_context* auth_context, + grpc_closure* on_call_host_checked, + grpc_error** error) override { + if (host == nullptr || strcmp(host, target_name_) != 0) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "ALTS call host does not match target name"); + } + return true; + } + + void cancel_check_call_host(grpc_closure* on_call_host_checked, + grpc_error* error) override { + GRPC_ERROR_UNREF(error); + } + + private: + char* target_name_; +}; + +class grpc_alts_server_security_connector final + : public grpc_server_security_connector { + public: + grpc_alts_server_security_connector( + grpc_core::RefCountedPtr server_creds) + : grpc_server_security_connector(/*url_scheme=*/nullptr, + std::move(server_creds)) { + grpc_alts_server_credentials* creds = + reinterpret_cast(mutable_server_creds()); + alts_set_rpc_protocol_versions(&creds->mutable_options()->rpc_versions); + } + ~grpc_alts_server_security_connector() override = default; + + void add_handshakers( + grpc_pollset_set* interested_parties, + grpc_core::HandshakeManager* handshake_manager) override { + tsi_handshaker* handshaker = nullptr; + const grpc_alts_server_credentials* creds = + static_cast(server_creds()); + GPR_ASSERT(alts_tsi_handshaker_create( + creds->options(), nullptr, creds->handshaker_service_url(), + false, interested_parties, &handshaker) == TSI_OK); + handshake_manager->Add( + grpc_core::SecurityHandshakerCreate(handshaker, this)); + } + + void check_peer(tsi_peer peer, grpc_endpoint* ep, + grpc_core::RefCountedPtr* auth_context, + grpc_closure* on_peer_checked) override { + alts_check_peer(peer, auth_context, on_peer_checked); + } + + int cmp(const grpc_security_connector* other) const override { + return server_security_connector_cmp( + static_cast(other)); + } +}; +} // namespace + namespace grpc_core { namespace internal { - -grpc_security_status grpc_alts_auth_context_from_tsi_peer( - const tsi_peer* peer, grpc_auth_context** ctx) { - if (peer == nullptr || ctx == nullptr) { +grpc_core::RefCountedPtr +grpc_alts_auth_context_from_tsi_peer(const tsi_peer* peer) { + if (peer == nullptr) { gpr_log(GPR_ERROR, "Invalid arguments to grpc_alts_auth_context_from_tsi_peer()"); - return GRPC_SECURITY_ERROR; + return nullptr; } - *ctx = nullptr; /* Validate certificate type. */ const tsi_peer_property* cert_type_prop = tsi_peer_get_property_by_name(peer, TSI_CERTIFICATE_TYPE_PEER_PROPERTY); @@ -120,14 +182,14 @@ grpc_security_status grpc_alts_auth_context_from_tsi_peer( strncmp(cert_type_prop->value.data, TSI_ALTS_CERTIFICATE_TYPE, cert_type_prop->value.length) != 0) { gpr_log(GPR_ERROR, "Invalid or missing certificate type property."); - return GRPC_SECURITY_ERROR; + return nullptr; } /* Validate RPC protocol versions. */ const tsi_peer_property* rpc_versions_prop = tsi_peer_get_property_by_name(peer, TSI_ALTS_RPC_VERSIONS); if (rpc_versions_prop == nullptr) { gpr_log(GPR_ERROR, "Missing rpc protocol versions property."); - return GRPC_SECURITY_ERROR; + return nullptr; } grpc_gcp_rpc_protocol_versions local_versions, peer_versions; alts_set_rpc_protocol_versions(&local_versions); @@ -138,19 +200,19 @@ grpc_security_status grpc_alts_auth_context_from_tsi_peer( grpc_slice_unref_internal(slice); if (!decode_result) { gpr_log(GPR_ERROR, "Invalid peer rpc protocol versions."); - return GRPC_SECURITY_ERROR; + return nullptr; } /* TODO: Pass highest common rpc protocol version to grpc caller. */ bool check_result = grpc_gcp_rpc_protocol_versions_check( &local_versions, &peer_versions, nullptr); if (!check_result) { gpr_log(GPR_ERROR, "Mismatch of local and peer rpc protocol versions."); - return GRPC_SECURITY_ERROR; + return nullptr; } /* Create auth context. */ - *ctx = grpc_auth_context_create(nullptr); + auto ctx = grpc_core::MakeRefCounted(nullptr); grpc_auth_context_add_cstring_property( - *ctx, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME, + ctx.get(), GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME, GRPC_ALTS_TRANSPORT_SECURITY_TYPE); size_t i = 0; for (i = 0; i < peer->property_count; i++) { @@ -158,132 +220,47 @@ grpc_security_status grpc_alts_auth_context_from_tsi_peer( /* Add service account to auth context. */ if (strcmp(tsi_prop->name, TSI_ALTS_SERVICE_ACCOUNT_PEER_PROPERTY) == 0) { grpc_auth_context_add_property( - *ctx, TSI_ALTS_SERVICE_ACCOUNT_PEER_PROPERTY, tsi_prop->value.data, - tsi_prop->value.length); + ctx.get(), TSI_ALTS_SERVICE_ACCOUNT_PEER_PROPERTY, + tsi_prop->value.data, tsi_prop->value.length); GPR_ASSERT(grpc_auth_context_set_peer_identity_property_name( - *ctx, TSI_ALTS_SERVICE_ACCOUNT_PEER_PROPERTY) == 1); + ctx.get(), TSI_ALTS_SERVICE_ACCOUNT_PEER_PROPERTY) == 1); } } - if (!grpc_auth_context_peer_is_authenticated(*ctx)) { + if (!grpc_auth_context_peer_is_authenticated(ctx.get())) { gpr_log(GPR_ERROR, "Invalid unauthenticated peer."); - GRPC_AUTH_CONTEXT_UNREF(*ctx, "test"); - *ctx = nullptr; - return GRPC_SECURITY_ERROR; + ctx.reset(DEBUG_LOCATION, "test"); + return nullptr; } - return GRPC_SECURITY_OK; + return ctx; } } // namespace internal } // namespace grpc_core -static void alts_check_peer(grpc_security_connector* sc, tsi_peer peer, - grpc_auth_context** auth_context, - grpc_closure* on_peer_checked) { - grpc_security_status status; - status = grpc_core::internal::grpc_alts_auth_context_from_tsi_peer( - &peer, auth_context); - tsi_peer_destruct(&peer); - grpc_error* error = - status == GRPC_SECURITY_OK - ? GRPC_ERROR_NONE - : GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "Could not get ALTS auth context from TSI peer"); - GRPC_CLOSURE_SCHED(on_peer_checked, error); -} - -static int alts_channel_cmp(grpc_security_connector* sc1, - grpc_security_connector* sc2) { - grpc_alts_channel_security_connector* c1 = - reinterpret_cast(sc1); - grpc_alts_channel_security_connector* c2 = - reinterpret_cast(sc2); - int c = grpc_channel_security_connector_cmp(&c1->base, &c2->base); - if (c != 0) return c; - return strcmp(c1->target_name, c2->target_name); -} - -static int alts_server_cmp(grpc_security_connector* sc1, - grpc_security_connector* sc2) { - grpc_alts_server_security_connector* c1 = - reinterpret_cast(sc1); - grpc_alts_server_security_connector* c2 = - reinterpret_cast(sc2); - return grpc_server_security_connector_cmp(&c1->base, &c2->base); -} - -static grpc_security_connector_vtable alts_channel_vtable = { - alts_channel_destroy, alts_check_peer, alts_channel_cmp}; - -static grpc_security_connector_vtable alts_server_vtable = { - alts_server_destroy, alts_check_peer, alts_server_cmp}; - -static bool alts_check_call_host(grpc_channel_security_connector* sc, - const char* host, - grpc_auth_context* auth_context, - grpc_closure* on_call_host_checked, - grpc_error** error) { - grpc_alts_channel_security_connector* alts_sc = - reinterpret_cast(sc); - if (host == nullptr || alts_sc == nullptr || - strcmp(host, alts_sc->target_name) != 0) { - *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "ALTS call host does not match target name"); - } - return true; -} - -static void alts_cancel_check_call_host(grpc_channel_security_connector* sc, - grpc_closure* on_call_host_checked, - grpc_error* error) { - GRPC_ERROR_UNREF(error); -} - -grpc_security_status grpc_alts_channel_security_connector_create( - grpc_channel_credentials* channel_creds, - grpc_call_credentials* request_metadata_creds, const char* target_name, - grpc_channel_security_connector** sc) { - if (channel_creds == nullptr || sc == nullptr || target_name == nullptr) { +grpc_core::RefCountedPtr +grpc_alts_channel_security_connector_create( + grpc_core::RefCountedPtr channel_creds, + grpc_core::RefCountedPtr request_metadata_creds, + const char* target_name) { + if (channel_creds == nullptr || target_name == nullptr) { gpr_log( GPR_ERROR, "Invalid arguments to grpc_alts_channel_security_connector_create()"); - return GRPC_SECURITY_ERROR; + return nullptr; } - auto c = static_cast( - gpr_zalloc(sizeof(grpc_alts_channel_security_connector))); - gpr_ref_init(&c->base.base.refcount, 1); - c->base.base.vtable = &alts_channel_vtable; - c->base.add_handshakers = alts_channel_add_handshakers; - c->base.channel_creds = grpc_channel_credentials_ref(channel_creds); - c->base.request_metadata_creds = - grpc_call_credentials_ref(request_metadata_creds); - c->base.check_call_host = alts_check_call_host; - c->base.cancel_check_call_host = alts_cancel_check_call_host; - grpc_alts_credentials* creds = - reinterpret_cast(c->base.channel_creds); - alts_set_rpc_protocol_versions(&creds->options->rpc_versions); - c->target_name = gpr_strdup(target_name); - *sc = &c->base; - return GRPC_SECURITY_OK; + return grpc_core::MakeRefCounted( + std::move(channel_creds), std::move(request_metadata_creds), target_name); } -grpc_security_status grpc_alts_server_security_connector_create( - grpc_server_credentials* server_creds, - grpc_server_security_connector** sc) { - if (server_creds == nullptr || sc == nullptr) { +grpc_core::RefCountedPtr +grpc_alts_server_security_connector_create( + grpc_core::RefCountedPtr server_creds) { + if (server_creds == nullptr) { gpr_log( GPR_ERROR, "Invalid arguments to grpc_alts_server_security_connector_create()"); - return GRPC_SECURITY_ERROR; + return nullptr; } - auto c = static_cast( - gpr_zalloc(sizeof(grpc_alts_server_security_connector))); - gpr_ref_init(&c->base.base.refcount, 1); - c->base.base.vtable = &alts_server_vtable; - c->base.server_creds = grpc_server_credentials_ref(server_creds); - c->base.add_handshakers = alts_server_add_handshakers; - grpc_alts_server_credentials* creds = - reinterpret_cast(c->base.server_creds); - alts_set_rpc_protocol_versions(&creds->options->rpc_versions); - *sc = &c->base; - return GRPC_SECURITY_OK; + return grpc_core::MakeRefCounted( + std::move(server_creds)); } diff --git a/src/core/lib/security/security_connector/alts/alts_security_connector.h b/src/core/lib/security/security_connector/alts/alts_security_connector.h index d2e057a76aa..b96dc36b302 100644 --- a/src/core/lib/security/security_connector/alts/alts_security_connector.h +++ b/src/core/lib/security/security_connector/alts/alts_security_connector.h @@ -36,12 +36,13 @@ * - sc: address of ALTS channel security connector instance to be returned from * the method. * - * It returns GRPC_SECURITY_OK on success, and an error stauts code on failure. + * It returns nullptr on failure. */ -grpc_security_status grpc_alts_channel_security_connector_create( - grpc_channel_credentials* channel_creds, - grpc_call_credentials* request_metadata_creds, const char* target_name, - grpc_channel_security_connector** sc); +grpc_core::RefCountedPtr +grpc_alts_channel_security_connector_create( + grpc_core::RefCountedPtr channel_creds, + grpc_core::RefCountedPtr request_metadata_creds, + const char* target_name); /** * This method creates an ALTS server security connector. @@ -50,17 +51,18 @@ grpc_security_status grpc_alts_channel_security_connector_create( * - sc: address of ALTS server security connector instance to be returned from * the method. * - * It returns GRPC_SECURITY_OK on success, and an error status code on failure. + * It returns nullptr on failure. */ -grpc_security_status grpc_alts_server_security_connector_create( - grpc_server_credentials* server_creds, grpc_server_security_connector** sc); +grpc_core::RefCountedPtr +grpc_alts_server_security_connector_create( + grpc_core::RefCountedPtr server_creds); namespace grpc_core { namespace internal { /* Exposed only for testing. */ -grpc_security_status grpc_alts_auth_context_from_tsi_peer( - const tsi_peer* peer, grpc_auth_context** ctx); +grpc_core::RefCountedPtr +grpc_alts_auth_context_from_tsi_peer(const tsi_peer* peer); } // namespace internal } // namespace grpc_core diff --git a/src/core/lib/security/security_connector/fake/fake_security_connector.cc b/src/core/lib/security/security_connector/fake/fake_security_connector.cc index 5c0c89b88f2..c55fd34d0e2 100644 --- a/src/core/lib/security/security_connector/fake/fake_security_connector.cc +++ b/src/core/lib/security/security_connector/fake/fake_security_connector.cc @@ -26,11 +26,14 @@ #include #include +#include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h" +#include "src/core/ext/filters/client_channel/lb_policy/xds/xds.h" #include "src/core/ext/transport/chttp2/alpn/alpn.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/handshaker.h" #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/security/context/security_context.h" #include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/security/credentials/fake/fake_credentials.h" @@ -38,91 +41,184 @@ #include "src/core/lib/security/transport/target_authority_table.h" #include "src/core/tsi/fake_transport_security.h" -typedef struct { - grpc_channel_security_connector base; - 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) { - grpc_fake_channel_security_connector* c = - reinterpret_cast(sc); - 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); -} - -static void fake_server_destroy(grpc_security_connector* sc) { gpr_free(sc); } - -static bool fake_check_target(const char* target_type, const char* target, - const char* set_str) { - GPR_ASSERT(target_type != nullptr); - GPR_ASSERT(target != nullptr); - char** set = nullptr; - size_t set_size = 0; - gpr_string_split(set_str, ",", &set, &set_size); - bool found = false; - for (size_t i = 0; i < set_size; ++i) { - if (set[i] != nullptr && strcmp(target, set[i]) == 0) found = true; +namespace { +class grpc_fake_channel_security_connector final + : public grpc_channel_security_connector { + public: + grpc_fake_channel_security_connector( + grpc_core::RefCountedPtr channel_creds, + grpc_core::RefCountedPtr request_metadata_creds, + const char* target, const grpc_channel_args* args) + : grpc_channel_security_connector(GRPC_FAKE_SECURITY_URL_SCHEME, + std::move(channel_creds), + std::move(request_metadata_creds)), + target_(gpr_strdup(target)), + expected_targets_( + gpr_strdup(grpc_fake_transport_get_expected_targets(args))), + is_lb_channel_( + grpc_channel_args_find( + args, GRPC_ARG_ADDRESS_IS_XDS_LOAD_BALANCER) != nullptr || + grpc_channel_args_find( + args, GRPC_ARG_ADDRESS_IS_GRPCLB_LOAD_BALANCER) != 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) { + target_name_override_ = + gpr_strdup(grpc_channel_arg_get_string(target_name_override_arg)); + } else { + target_name_override_ = nullptr; + } } - for (size_t i = 0; i < set_size; ++i) { - gpr_free(set[i]); - } - gpr_free(set); - return found; -} -static void fake_secure_name_check(const char* target, - const char* expected_targets, - bool is_lb_channel) { - if (expected_targets == nullptr) return; - char** lbs_and_backends = nullptr; - size_t lbs_and_backends_size = 0; - bool success = false; - gpr_string_split(expected_targets, ";", &lbs_and_backends, - &lbs_and_backends_size); - if (lbs_and_backends_size > 2 || lbs_and_backends_size == 0) { - gpr_log(GPR_ERROR, "Invalid expected targets arg value: '%s'", - expected_targets); - goto done; + ~grpc_fake_channel_security_connector() override { + gpr_free(target_); + gpr_free(expected_targets_); + if (target_name_override_ != nullptr) gpr_free(target_name_override_); } - if (is_lb_channel) { - if (lbs_and_backends_size != 2) { - gpr_log(GPR_ERROR, - "Invalid expected targets arg value: '%s'. Expectations for LB " - "channels must be of the form 'be1,be2,be3,...;lb1,lb2,...", - expected_targets); + + void check_peer(tsi_peer peer, grpc_endpoint* ep, + grpc_core::RefCountedPtr* auth_context, + grpc_closure* on_peer_checked) override; + + int cmp(const grpc_security_connector* other_sc) const override { + auto* other = + reinterpret_cast(other_sc); + int c = channel_security_connector_cmp(other); + if (c != 0) return c; + c = strcmp(target_, other->target_); + if (c != 0) return c; + if (expected_targets_ == nullptr || other->expected_targets_ == nullptr) { + c = GPR_ICMP(expected_targets_, other->expected_targets_); + } else { + c = strcmp(expected_targets_, other->expected_targets_); + } + if (c != 0) return c; + return GPR_ICMP(is_lb_channel_, other->is_lb_channel_); + } + + void add_handshakers(grpc_pollset_set* interested_parties, + grpc_core::HandshakeManager* handshake_mgr) override { + handshake_mgr->Add(grpc_core::SecurityHandshakerCreate( + tsi_create_fake_handshaker(/*is_client=*/true), this)); + } + + bool check_call_host(const char* host, grpc_auth_context* auth_context, + grpc_closure* on_call_host_checked, + grpc_error** error) override { + 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(target_, &target_hostname, &target_ignored_port); + if (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(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; + } + + void cancel_check_call_host(grpc_closure* on_call_host_checked, + grpc_error* error) override { + GRPC_ERROR_UNREF(error); + } + + char* target() const { return target_; } + char* expected_targets() const { return expected_targets_; } + bool is_lb_channel() const { return is_lb_channel_; } + char* target_name_override() const { return target_name_override_; } + + private: + bool fake_check_target(const char* target_type, const char* target, + const char* set_str) const { + GPR_ASSERT(target_type != nullptr); + GPR_ASSERT(target != nullptr); + char** set = nullptr; + size_t set_size = 0; + gpr_string_split(set_str, ",", &set, &set_size); + bool found = false; + for (size_t i = 0; i < set_size; ++i) { + if (set[i] != nullptr && strcmp(target, set[i]) == 0) found = true; + } + for (size_t i = 0; i < set_size; ++i) { + gpr_free(set[i]); + } + gpr_free(set); + return found; + } + + void fake_secure_name_check() const { + if (expected_targets_ == nullptr) return; + char** lbs_and_backends = nullptr; + size_t lbs_and_backends_size = 0; + bool success = false; + gpr_string_split(expected_targets_, ";", &lbs_and_backends, + &lbs_and_backends_size); + if (lbs_and_backends_size > 2 || lbs_and_backends_size == 0) { + gpr_log(GPR_ERROR, "Invalid expected targets arg value: '%s'", + expected_targets_); goto done; } - if (!fake_check_target("LB", target, lbs_and_backends[1])) { - gpr_log(GPR_ERROR, "LB target '%s' not found in expected set '%s'", - target, lbs_and_backends[1]); - goto done; + if (is_lb_channel_) { + if (lbs_and_backends_size != 2) { + gpr_log(GPR_ERROR, + "Invalid expected targets arg value: '%s'. Expectations for LB " + "channels must be of the form 'be1,be2,be3,...;lb1,lb2,...", + expected_targets_); + goto done; + } + if (!fake_check_target("LB", target_, lbs_and_backends[1])) { + gpr_log(GPR_ERROR, "LB target '%s' not found in expected set '%s'", + target_, lbs_and_backends[1]); + goto done; + } + success = true; + } else { + if (!fake_check_target("Backend", target_, lbs_and_backends[0])) { + gpr_log(GPR_ERROR, "Backend target '%s' not found in expected set '%s'", + target_, lbs_and_backends[0]); + goto done; + } + success = true; } - success = true; - } else { - if (!fake_check_target("Backend", target, lbs_and_backends[0])) { - gpr_log(GPR_ERROR, "Backend target '%s' not found in expected set '%s'", - target, lbs_and_backends[0]); - goto done; + done: + for (size_t i = 0; i < lbs_and_backends_size; ++i) { + gpr_free(lbs_and_backends[i]); } - success = true; + gpr_free(lbs_and_backends); + if (!success) abort(); } -done: - for (size_t i = 0; i < lbs_and_backends_size; ++i) { - gpr_free(lbs_and_backends[i]); - } - gpr_free(lbs_and_backends); - if (!success) abort(); -} -static void fake_check_peer(grpc_security_connector* sc, tsi_peer peer, - grpc_auth_context** auth_context, - grpc_closure* on_peer_checked) { + char* target_; + char* expected_targets_; + bool is_lb_channel_; + char* target_name_override_; +}; + +static void fake_check_peer( + grpc_security_connector* sc, tsi_peer peer, + grpc_core::RefCountedPtr* auth_context, + grpc_closure* on_peer_checked) { const char* prop_name; grpc_error* error = GRPC_ERROR_NONE; *auth_context = nullptr; @@ -147,164 +243,64 @@ static void fake_check_peer(grpc_security_connector* sc, tsi_peer peer, "Invalid value for cert type property."); goto end; } - *auth_context = grpc_auth_context_create(nullptr); + *auth_context = grpc_core::MakeRefCounted(nullptr); grpc_auth_context_add_cstring_property( - *auth_context, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME, + auth_context->get(), GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME, GRPC_FAKE_TRANSPORT_SECURITY_TYPE); end: GRPC_CLOSURE_SCHED(on_peer_checked, error); tsi_peer_destruct(&peer); } -static void fake_channel_check_peer(grpc_security_connector* sc, tsi_peer peer, - grpc_auth_context** auth_context, - grpc_closure* on_peer_checked) { - fake_check_peer(sc, peer, auth_context, on_peer_checked); - grpc_fake_channel_security_connector* c = - reinterpret_cast(sc); - fake_secure_name_check(c->target, c->expected_targets, c->is_lb_channel); +void grpc_fake_channel_security_connector::check_peer( + tsi_peer peer, grpc_endpoint* ep, + grpc_core::RefCountedPtr* auth_context, + grpc_closure* on_peer_checked) { + fake_check_peer(this, peer, auth_context, on_peer_checked); + fake_secure_name_check(); } -static void fake_server_check_peer(grpc_security_connector* sc, tsi_peer peer, - grpc_auth_context** auth_context, - grpc_closure* on_peer_checked) { - fake_check_peer(sc, peer, auth_context, on_peer_checked); -} +class grpc_fake_server_security_connector + : public grpc_server_security_connector { + public: + grpc_fake_server_security_connector( + grpc_core::RefCountedPtr server_creds) + : grpc_server_security_connector(GRPC_FAKE_SECURITY_URL_SCHEME, + std::move(server_creds)) {} + ~grpc_fake_server_security_connector() override = default; -static int fake_channel_cmp(grpc_security_connector* sc1, - grpc_security_connector* sc2) { - grpc_fake_channel_security_connector* c1 = - reinterpret_cast(sc1); - grpc_fake_channel_security_connector* c2 = - reinterpret_cast(sc2); - int c = grpc_channel_security_connector_cmp(&c1->base, &c2->base); - if (c != 0) return c; - c = strcmp(c1->target, c2->target); - if (c != 0) return c; - if (c1->expected_targets == nullptr || c2->expected_targets == nullptr) { - c = GPR_ICMP(c1->expected_targets, c2->expected_targets); - } else { - c = strcmp(c1->expected_targets, c2->expected_targets); + void check_peer(tsi_peer peer, grpc_endpoint* ep, + grpc_core::RefCountedPtr* auth_context, + grpc_closure* on_peer_checked) override { + fake_check_peer(this, peer, auth_context, on_peer_checked); } - if (c != 0) return c; - return GPR_ICMP(c1->is_lb_channel, c2->is_lb_channel); -} -static int fake_server_cmp(grpc_security_connector* sc1, - grpc_security_connector* sc2) { - return grpc_server_security_connector_cmp( - reinterpret_cast(sc1), - reinterpret_cast(sc2)); -} - -static bool fake_channel_check_call_host(grpc_channel_security_connector* sc, - const char* host, - grpc_auth_context* auth_context, - grpc_closure* on_call_host_checked, - grpc_error** error) { - grpc_fake_channel_security_connector* c = - reinterpret_cast(sc); - 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(); + void add_handshakers(grpc_pollset_set* interested_parties, + grpc_core::HandshakeManager* handshake_mgr) override { + handshake_mgr->Add(grpc_core::SecurityHandshakerCreate( + tsi_create_fake_handshaker(/*=is_client*/ false), this)); } - gpr_free(authority_hostname); - gpr_free(authority_ignored_port); - gpr_free(target_hostname); - gpr_free(target_ignored_port); - return true; -} -static void fake_channel_cancel_check_call_host( - grpc_channel_security_connector* sc, grpc_closure* on_call_host_checked, - grpc_error* error) { - GRPC_ERROR_UNREF(error); -} - -static void fake_channel_add_handshakers( - grpc_channel_security_connector* sc, grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr) { - grpc_handshake_manager_add( - handshake_mgr, - grpc_security_handshaker_create( - tsi_create_fake_handshaker(true /* is_client */), &sc->base)); -} - -static void fake_server_add_handshakers(grpc_server_security_connector* sc, - grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr) { - grpc_handshake_manager_add( - handshake_mgr, - grpc_security_handshaker_create( - tsi_create_fake_handshaker(false /* is_client */), &sc->base)); -} - -static grpc_security_connector_vtable fake_channel_vtable = { - fake_channel_destroy, fake_channel_check_peer, fake_channel_cmp}; - -static grpc_security_connector_vtable fake_server_vtable = { - fake_server_destroy, fake_server_check_peer, fake_server_cmp}; - -grpc_channel_security_connector* grpc_fake_channel_security_connector_create( - grpc_channel_credentials* channel_creds, - grpc_call_credentials* request_metadata_creds, const char* target, - const grpc_channel_args* args) { - grpc_fake_channel_security_connector* c = - static_cast( - gpr_zalloc(sizeof(*c))); - gpr_ref_init(&c->base.base.refcount, 1); - c->base.base.url_scheme = GRPC_FAKE_SECURITY_URL_SCHEME; - c->base.base.vtable = &fake_channel_vtable; - c->base.channel_creds = channel_creds; - c->base.request_metadata_creds = - grpc_call_credentials_ref(request_metadata_creds); - c->base.check_call_host = fake_channel_check_call_host; - c->base.cancel_check_call_host = fake_channel_cancel_check_call_host; - c->base.add_handshakers = fake_channel_add_handshakers; - c->target = gpr_strdup(target); - 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)); + int cmp(const grpc_security_connector* other) const override { + return server_security_connector_cmp( + static_cast(other)); } - return &c->base; +}; +} // namespace + +grpc_core::RefCountedPtr +grpc_fake_channel_security_connector_create( + grpc_core::RefCountedPtr channel_creds, + grpc_core::RefCountedPtr request_metadata_creds, + const char* target, const grpc_channel_args* args) { + return grpc_core::MakeRefCounted( + std::move(channel_creds), std::move(request_metadata_creds), target, + args); } -grpc_server_security_connector* grpc_fake_server_security_connector_create( - grpc_server_credentials* server_creds) { - grpc_server_security_connector* c = - static_cast( - gpr_zalloc(sizeof(grpc_server_security_connector))); - gpr_ref_init(&c->base.refcount, 1); - c->base.vtable = &fake_server_vtable; - c->base.url_scheme = GRPC_FAKE_SECURITY_URL_SCHEME; - c->server_creds = server_creds; - c->add_handshakers = fake_server_add_handshakers; - return c; +grpc_core::RefCountedPtr +grpc_fake_server_security_connector_create( + grpc_core::RefCountedPtr server_creds) { + return grpc_core::MakeRefCounted( + std::move(server_creds)); } diff --git a/src/core/lib/security/security_connector/fake/fake_security_connector.h b/src/core/lib/security/security_connector/fake/fake_security_connector.h index fdfe048c6e7..344a2349a49 100644 --- a/src/core/lib/security/security_connector/fake/fake_security_connector.h +++ b/src/core/lib/security/security_connector/fake/fake_security_connector.h @@ -24,19 +24,22 @@ #include #include "src/core/lib/channel/handshaker.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/security/security_connector/security_connector.h" #define GRPC_FAKE_SECURITY_URL_SCHEME "http+fake_security" /* Creates a fake connector that emulates real channel security. */ -grpc_channel_security_connector* grpc_fake_channel_security_connector_create( - grpc_channel_credentials* channel_creds, - grpc_call_credentials* request_metadata_creds, const char* target, - const grpc_channel_args* args); +grpc_core::RefCountedPtr +grpc_fake_channel_security_connector_create( + grpc_core::RefCountedPtr channel_creds, + grpc_core::RefCountedPtr request_metadata_creds, + const char* target, const grpc_channel_args* args); /* Creates a fake connector that emulates real server security. */ -grpc_server_security_connector* grpc_fake_server_security_connector_create( - grpc_server_credentials* server_creds); +grpc_core::RefCountedPtr +grpc_fake_server_security_connector_create( + grpc_core::RefCountedPtr server_creds); #endif /* GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_FAKE_FAKE_SECURITY_CONNECTOR_H \ */ diff --git a/src/core/lib/security/security_connector/local/local_security_connector.cc b/src/core/lib/security/security_connector/local/local_security_connector.cc index 008a98df281..c1a101d4ab8 100644 --- a/src/core/lib/security/security_connector/local/local_security_connector.cc +++ b/src/core/lib/security/security_connector/local/local_security_connector.cc @@ -30,217 +30,226 @@ #include "src/core/ext/filters/client_channel/client_channel.h" #include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/pollset.h" +#include "src/core/lib/iomgr/resolve_address.h" +#include "src/core/lib/iomgr/sockaddr.h" +#include "src/core/lib/iomgr/sockaddr_utils.h" +#include "src/core/lib/iomgr/socket_utils.h" +#include "src/core/lib/iomgr/unix_sockets_posix.h" #include "src/core/lib/security/credentials/local/local_credentials.h" #include "src/core/lib/security/transport/security_handshaker.h" #include "src/core/tsi/local_transport_security.h" #define GRPC_UDS_URI_PATTERN "unix:" -#define GRPC_UDS_URL_SCHEME "unix" #define GRPC_LOCAL_TRANSPORT_SECURITY_TYPE "local" -typedef struct { - grpc_channel_security_connector base; - char* target_name; -} grpc_local_channel_security_connector; +namespace { -typedef struct { - grpc_server_security_connector base; -} grpc_local_server_security_connector; - -static void local_channel_destroy(grpc_security_connector* sc) { - if (sc == nullptr) { - return; - } - auto c = reinterpret_cast(sc); - grpc_call_credentials_unref(c->base.request_metadata_creds); - grpc_channel_credentials_unref(c->base.channel_creds); - gpr_free(c->target_name); - gpr_free(sc); -} - -static void local_server_destroy(grpc_security_connector* sc) { - if (sc == nullptr) { - return; - } - auto c = reinterpret_cast(sc); - grpc_server_credentials_unref(c->base.server_creds); - gpr_free(sc); -} - -static void local_channel_add_handshakers( - grpc_channel_security_connector* sc, grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_manager) { - tsi_handshaker* handshaker = nullptr; - GPR_ASSERT(local_tsi_handshaker_create(true /* is_client */, &handshaker) == - TSI_OK); - grpc_handshake_manager_add(handshake_manager, grpc_security_handshaker_create( - handshaker, &sc->base)); -} - -static void local_server_add_handshakers( - grpc_server_security_connector* sc, grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_manager) { - tsi_handshaker* handshaker = nullptr; - GPR_ASSERT(local_tsi_handshaker_create(false /* is_client */, &handshaker) == - TSI_OK); - grpc_handshake_manager_add(handshake_manager, grpc_security_handshaker_create( - handshaker, &sc->base)); -} - -static int local_channel_cmp(grpc_security_connector* sc1, - grpc_security_connector* sc2) { - grpc_local_channel_security_connector* c1 = - reinterpret_cast(sc1); - grpc_local_channel_security_connector* c2 = - reinterpret_cast(sc2); - int c = grpc_channel_security_connector_cmp(&c1->base, &c2->base); - if (c != 0) return c; - return strcmp(c1->target_name, c2->target_name); -} - -static int local_server_cmp(grpc_security_connector* sc1, - grpc_security_connector* sc2) { - grpc_local_server_security_connector* c1 = - reinterpret_cast(sc1); - grpc_local_server_security_connector* c2 = - reinterpret_cast(sc2); - return grpc_server_security_connector_cmp(&c1->base, &c2->base); -} - -static grpc_security_status local_auth_context_create(grpc_auth_context** ctx) { - if (ctx == nullptr) { - gpr_log(GPR_ERROR, "Invalid arguments to local_auth_context_create()"); - return GRPC_SECURITY_ERROR; - } +grpc_core::RefCountedPtr local_auth_context_create() { /* Create auth context. */ - *ctx = grpc_auth_context_create(nullptr); + grpc_core::RefCountedPtr ctx = + grpc_core::MakeRefCounted(nullptr); grpc_auth_context_add_cstring_property( - *ctx, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME, + ctx.get(), GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME, GRPC_LOCAL_TRANSPORT_SECURITY_TYPE); GPR_ASSERT(grpc_auth_context_set_peer_identity_property_name( - *ctx, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME) == 1); - return GRPC_SECURITY_OK; + ctx.get(), GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME) == 1); + return ctx; } -static void local_check_peer(grpc_security_connector* sc, tsi_peer peer, - grpc_auth_context** auth_context, - grpc_closure* on_peer_checked) { - grpc_security_status status; +void local_check_peer(grpc_security_connector* sc, tsi_peer peer, + grpc_endpoint* ep, + grpc_core::RefCountedPtr* auth_context, + grpc_closure* on_peer_checked, + grpc_local_connect_type type) { + int fd = grpc_endpoint_get_fd(ep); + grpc_resolved_address resolved_addr; + memset(&resolved_addr, 0, sizeof(resolved_addr)); + resolved_addr.len = GRPC_MAX_SOCKADDR_SIZE; + bool is_endpoint_local = false; + if (getsockname(fd, reinterpret_cast(resolved_addr.addr), + &resolved_addr.len) == 0) { + grpc_resolved_address addr_normalized; + grpc_resolved_address* addr = + grpc_sockaddr_is_v4mapped(&resolved_addr, &addr_normalized) + ? &addr_normalized + : &resolved_addr; + grpc_sockaddr* sock_addr = reinterpret_cast(&addr->addr); + // UDS + if (type == UDS && grpc_is_unix_socket(addr)) { + is_endpoint_local = true; + // IPV4 + } else if (type == LOCAL_TCP && sock_addr->sa_family == GRPC_AF_INET) { + const grpc_sockaddr_in* addr4 = + reinterpret_cast(sock_addr); + if (grpc_htonl(addr4->sin_addr.s_addr) == INADDR_LOOPBACK) { + is_endpoint_local = true; + } + // IPv6 + } else if (type == LOCAL_TCP && sock_addr->sa_family == GRPC_AF_INET6) { + const grpc_sockaddr_in6* addr6 = + reinterpret_cast(addr); + if (memcmp(&addr6->sin6_addr, &in6addr_loopback, + sizeof(in6addr_loopback)) == 0) { + is_endpoint_local = true; + } + } + } + grpc_error* error = GRPC_ERROR_NONE; + if (!is_endpoint_local) { + error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Endpoint is neither UDS or TCP loopback address."); + GRPC_CLOSURE_SCHED(on_peer_checked, error); + return; + } /* Create an auth context which is necessary to pass the santiy check in * {client, server}_auth_filter that verifies if the peer's auth context is * obtained during handshakes. The auth context is only checked for its * existence and not actually used. */ - status = local_auth_context_create(auth_context); - grpc_error* error = status == GRPC_SECURITY_OK - ? GRPC_ERROR_NONE - : GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "Could not create local auth context"); + *auth_context = local_auth_context_create(); + error = *auth_context != nullptr ? GRPC_ERROR_NONE + : GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Could not create local auth context"); GRPC_CLOSURE_SCHED(on_peer_checked, error); } -static grpc_security_connector_vtable local_channel_vtable = { - local_channel_destroy, local_check_peer, local_channel_cmp}; +class grpc_local_channel_security_connector final + : public grpc_channel_security_connector { + public: + grpc_local_channel_security_connector( + grpc_core::RefCountedPtr channel_creds, + grpc_core::RefCountedPtr request_metadata_creds, + const char* target_name) + : grpc_channel_security_connector(nullptr, std::move(channel_creds), + std::move(request_metadata_creds)), + target_name_(gpr_strdup(target_name)) {} -static grpc_security_connector_vtable local_server_vtable = { - local_server_destroy, local_check_peer, local_server_cmp}; + ~grpc_local_channel_security_connector() override { gpr_free(target_name_); } -static bool local_check_call_host(grpc_channel_security_connector* sc, - const char* host, - grpc_auth_context* auth_context, - grpc_closure* on_call_host_checked, - grpc_error** error) { - grpc_local_channel_security_connector* local_sc = - reinterpret_cast(sc); - if (host == nullptr || local_sc == nullptr || - strcmp(host, local_sc->target_name) != 0) { - *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "local call host does not match target name"); + void add_handshakers( + grpc_pollset_set* interested_parties, + grpc_core::HandshakeManager* handshake_manager) override { + tsi_handshaker* handshaker = nullptr; + GPR_ASSERT(local_tsi_handshaker_create(true /* is_client */, &handshaker) == + TSI_OK); + handshake_manager->Add( + grpc_core::SecurityHandshakerCreate(handshaker, this)); } - return true; -} -static void local_cancel_check_call_host(grpc_channel_security_connector* sc, - grpc_closure* on_call_host_checked, - grpc_error* error) { - GRPC_ERROR_UNREF(error); -} + int cmp(const grpc_security_connector* other_sc) const override { + auto* other = + reinterpret_cast( + other_sc); + int c = channel_security_connector_cmp(other); + if (c != 0) return c; + return strcmp(target_name_, other->target_name_); + } -grpc_security_status grpc_local_channel_security_connector_create( - grpc_channel_credentials* channel_creds, - grpc_call_credentials* request_metadata_creds, - const grpc_channel_args* args, const char* target_name, - grpc_channel_security_connector** sc) { - if (channel_creds == nullptr || sc == nullptr || target_name == nullptr) { + void check_peer(tsi_peer peer, grpc_endpoint* ep, + grpc_core::RefCountedPtr* auth_context, + grpc_closure* on_peer_checked) override { + grpc_local_credentials* creds = + reinterpret_cast(mutable_channel_creds()); + local_check_peer(this, peer, ep, auth_context, on_peer_checked, + creds->connect_type()); + } + + bool check_call_host(const char* host, grpc_auth_context* auth_context, + grpc_closure* on_call_host_checked, + grpc_error** error) override { + if (host == nullptr || strcmp(host, target_name_) != 0) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "local call host does not match target name"); + } + return true; + } + + void cancel_check_call_host(grpc_closure* on_call_host_checked, + grpc_error* error) override { + GRPC_ERROR_UNREF(error); + } + + const char* target_name() const { return target_name_; } + + private: + char* target_name_; +}; + +class grpc_local_server_security_connector final + : public grpc_server_security_connector { + public: + grpc_local_server_security_connector( + grpc_core::RefCountedPtr server_creds) + : grpc_server_security_connector(nullptr, std::move(server_creds)) {} + ~grpc_local_server_security_connector() override = default; + + void add_handshakers( + grpc_pollset_set* interested_parties, + grpc_core::HandshakeManager* handshake_manager) override { + tsi_handshaker* handshaker = nullptr; + GPR_ASSERT(local_tsi_handshaker_create(false /* is_client */, + &handshaker) == TSI_OK); + handshake_manager->Add( + grpc_core::SecurityHandshakerCreate(handshaker, this)); + } + + void check_peer(tsi_peer peer, grpc_endpoint* ep, + grpc_core::RefCountedPtr* auth_context, + grpc_closure* on_peer_checked) override { + grpc_local_server_credentials* creds = + static_cast(mutable_server_creds()); + local_check_peer(this, peer, ep, auth_context, on_peer_checked, + creds->connect_type()); + } + + int cmp(const grpc_security_connector* other) const override { + return server_security_connector_cmp( + static_cast(other)); + } +}; +} // namespace + +grpc_core::RefCountedPtr +grpc_local_channel_security_connector_create( + grpc_core::RefCountedPtr channel_creds, + grpc_core::RefCountedPtr request_metadata_creds, + const grpc_channel_args* args, const char* target_name) { + if (channel_creds == nullptr || target_name == nullptr) { gpr_log( GPR_ERROR, "Invalid arguments to grpc_local_channel_security_connector_create()"); - return GRPC_SECURITY_ERROR; + return nullptr; } - // Check if local_connect_type is UDS. Only UDS is supported for now. + // Perform sanity check on UDS address. For TCP local connection, the check + // will be done during check_peer procedure. grpc_local_credentials* creds = - reinterpret_cast(channel_creds); - if (creds->connect_type != UDS) { - gpr_log(GPR_ERROR, - "Invalid local channel type to " - "grpc_local_channel_security_connector_create()"); - return GRPC_SECURITY_ERROR; - } - // Check if target_name is a valid UDS address. + static_cast(channel_creds.get()); 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); - if (strncmp(GRPC_UDS_URI_PATTERN, server_uri_str, + if (creds->connect_type() == UDS && + strncmp(GRPC_UDS_URI_PATTERN, server_uri_str, strlen(GRPC_UDS_URI_PATTERN)) != 0) { gpr_log(GPR_ERROR, - "Invalid target_name to " + "Invalid UDS target name to " "grpc_local_channel_security_connector_create()"); - return GRPC_SECURITY_ERROR; + return nullptr; } - auto c = static_cast( - gpr_zalloc(sizeof(grpc_local_channel_security_connector))); - gpr_ref_init(&c->base.base.refcount, 1); - c->base.base.vtable = &local_channel_vtable; - c->base.add_handshakers = local_channel_add_handshakers; - c->base.channel_creds = grpc_channel_credentials_ref(channel_creds); - c->base.request_metadata_creds = - grpc_call_credentials_ref(request_metadata_creds); - c->base.check_call_host = local_check_call_host; - c->base.cancel_check_call_host = local_cancel_check_call_host; - c->base.base.url_scheme = - creds->connect_type == UDS ? GRPC_UDS_URL_SCHEME : nullptr; - c->target_name = gpr_strdup(target_name); - *sc = &c->base; - return GRPC_SECURITY_OK; + return grpc_core::MakeRefCounted( + channel_creds, request_metadata_creds, target_name); } -grpc_security_status grpc_local_server_security_connector_create( - grpc_server_credentials* server_creds, - grpc_server_security_connector** sc) { - if (server_creds == nullptr || sc == nullptr) { +grpc_core::RefCountedPtr +grpc_local_server_security_connector_create( + grpc_core::RefCountedPtr server_creds) { + if (server_creds == nullptr) { gpr_log( GPR_ERROR, "Invalid arguments to grpc_local_server_security_connector_create()"); - return GRPC_SECURITY_ERROR; + return nullptr; } - // Check if local_connect_type is UDS. Only UDS is supported for now. - grpc_local_server_credentials* creds = - reinterpret_cast(server_creds); - if (creds->connect_type != UDS) { - gpr_log(GPR_ERROR, - "Invalid local server type to " - "grpc_local_server_security_connector_create()"); - return GRPC_SECURITY_ERROR; - } - auto c = static_cast( - gpr_zalloc(sizeof(grpc_local_server_security_connector))); - gpr_ref_init(&c->base.base.refcount, 1); - c->base.base.vtable = &local_server_vtable; - c->base.server_creds = grpc_server_credentials_ref(server_creds); - c->base.base.url_scheme = - creds->connect_type == UDS ? GRPC_UDS_URL_SCHEME : nullptr; - c->base.add_handshakers = local_server_add_handshakers; - *sc = &c->base; - return GRPC_SECURITY_OK; + return grpc_core::MakeRefCounted( + std::move(server_creds)); } diff --git a/src/core/lib/security/security_connector/local/local_security_connector.h b/src/core/lib/security/security_connector/local/local_security_connector.h index 5369a2127aa..6eee0ca9a6c 100644 --- a/src/core/lib/security/security_connector/local/local_security_connector.h +++ b/src/core/lib/security/security_connector/local/local_security_connector.h @@ -34,13 +34,13 @@ * - sc: address of local channel security connector instance to be returned * from the method. * - * It returns GRPC_SECURITY_OK on success, and an error stauts code on failure. + * It returns nullptr on failure. */ -grpc_security_status grpc_local_channel_security_connector_create( - grpc_channel_credentials* channel_creds, - grpc_call_credentials* request_metadata_creds, - const grpc_channel_args* args, const char* target_name, - grpc_channel_security_connector** sc); +grpc_core::RefCountedPtr +grpc_local_channel_security_connector_create( + grpc_core::RefCountedPtr channel_creds, + grpc_core::RefCountedPtr request_metadata_creds, + const grpc_channel_args* args, const char* target_name); /** * This method creates a local server security connector. @@ -49,10 +49,11 @@ grpc_security_status grpc_local_channel_security_connector_create( * - sc: address of local server security connector instance to be returned from * the method. * - * It returns GRPC_SECURITY_OK on success, and an error status code on failure. + * It returns nullptr on failure. */ -grpc_security_status grpc_local_server_security_connector_create( - grpc_server_credentials* server_creds, grpc_server_security_connector** sc); +grpc_core::RefCountedPtr +grpc_local_server_security_connector_create( + grpc_core::RefCountedPtr server_creds); #endif /* GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_LOCAL_LOCAL_SECURITY_CONNECTOR_H \ */ diff --git a/src/core/lib/security/security_connector/security_connector.cc b/src/core/lib/security/security_connector/security_connector.cc index 02cecb0eb1e..96a19605466 100644 --- a/src/core/lib/security/security_connector/security_connector.cc +++ b/src/core/lib/security/security_connector/security_connector.cc @@ -35,150 +35,67 @@ #include "src/core/lib/security/context/security_context.h" #include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/security/security_connector/load_system_roots.h" +#include "src/core/lib/security/security_connector/security_connector.h" #include "src/core/lib/security/transport/security_handshaker.h" grpc_core::DebugOnlyTraceFlag grpc_trace_security_connector_refcount( false, "security_connector_refcount"); -void grpc_channel_security_connector_add_handshakers( - grpc_channel_security_connector* connector, - grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr) { - if (connector != nullptr) { - connector->add_handshakers(connector, interested_parties, handshake_mgr); - } -} +grpc_server_security_connector::grpc_server_security_connector( + const char* url_scheme, + grpc_core::RefCountedPtr server_creds) + : grpc_security_connector(url_scheme), + server_creds_(std::move(server_creds)) {} -void grpc_server_security_connector_add_handshakers( - grpc_server_security_connector* connector, - grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr) { - if (connector != nullptr) { - connector->add_handshakers(connector, interested_parties, handshake_mgr); - } -} +grpc_channel_security_connector::grpc_channel_security_connector( + const char* url_scheme, + grpc_core::RefCountedPtr channel_creds, + grpc_core::RefCountedPtr request_metadata_creds) + : grpc_security_connector(url_scheme), + channel_creds_(std::move(channel_creds)), + request_metadata_creds_(std::move(request_metadata_creds)) {} +grpc_channel_security_connector::~grpc_channel_security_connector() {} -void grpc_security_connector_check_peer(grpc_security_connector* sc, - tsi_peer peer, - grpc_auth_context** auth_context, - grpc_closure* on_peer_checked) { - if (sc == nullptr) { - GRPC_CLOSURE_SCHED(on_peer_checked, - GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "cannot check peer -- no security connector")); - tsi_peer_destruct(&peer); - } else { - sc->vtable->check_peer(sc, peer, auth_context, on_peer_checked); - } -} - -int grpc_security_connector_cmp(grpc_security_connector* sc, - grpc_security_connector* other) { +int grpc_security_connector_cmp(const grpc_security_connector* sc, + const grpc_security_connector* other) { if (sc == nullptr || other == nullptr) return GPR_ICMP(sc, other); - int c = GPR_ICMP(sc->vtable, other->vtable); - if (c != 0) return c; - return sc->vtable->cmp(sc, other); + return sc->cmp(other); } -int grpc_channel_security_connector_cmp(grpc_channel_security_connector* sc1, - grpc_channel_security_connector* sc2) { - GPR_ASSERT(sc1->channel_creds != nullptr); - GPR_ASSERT(sc2->channel_creds != nullptr); - int c = GPR_ICMP(sc1->channel_creds, sc2->channel_creds); +int grpc_channel_security_connector::channel_security_connector_cmp( + const grpc_channel_security_connector* other) const { + const grpc_channel_security_connector* other_sc = + static_cast(other); + GPR_ASSERT(channel_creds() != nullptr); + GPR_ASSERT(other_sc->channel_creds() != nullptr); + int c = GPR_ICMP(channel_creds(), other_sc->channel_creds()); if (c != 0) return c; - c = GPR_ICMP(sc1->request_metadata_creds, sc2->request_metadata_creds); - if (c != 0) return c; - c = GPR_ICMP((void*)sc1->check_call_host, (void*)sc2->check_call_host); - if (c != 0) return c; - c = GPR_ICMP((void*)sc1->cancel_check_call_host, - (void*)sc2->cancel_check_call_host); - if (c != 0) return c; - return GPR_ICMP((void*)sc1->add_handshakers, (void*)sc2->add_handshakers); + return GPR_ICMP(request_metadata_creds(), other_sc->request_metadata_creds()); } -int grpc_server_security_connector_cmp(grpc_server_security_connector* sc1, - grpc_server_security_connector* sc2) { - GPR_ASSERT(sc1->server_creds != nullptr); - GPR_ASSERT(sc2->server_creds != nullptr); - int c = GPR_ICMP(sc1->server_creds, sc2->server_creds); - if (c != 0) return c; - return GPR_ICMP((void*)sc1->add_handshakers, (void*)sc2->add_handshakers); -} - -bool grpc_channel_security_connector_check_call_host( - grpc_channel_security_connector* sc, const char* host, - grpc_auth_context* auth_context, grpc_closure* on_call_host_checked, - grpc_error** error) { - if (sc == nullptr || sc->check_call_host == nullptr) { - *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "cannot check call host -- no security connector"); - return true; - } - return sc->check_call_host(sc, host, auth_context, on_call_host_checked, - error); -} - -void grpc_channel_security_connector_cancel_check_call_host( - grpc_channel_security_connector* sc, grpc_closure* on_call_host_checked, - grpc_error* error) { - if (sc == nullptr || sc->cancel_check_call_host == nullptr) { - GRPC_ERROR_UNREF(error); - return; - } - sc->cancel_check_call_host(sc, on_call_host_checked, error); -} - -#ifndef NDEBUG -grpc_security_connector* grpc_security_connector_ref( - grpc_security_connector* sc, const char* file, int line, - const char* reason) { - if (sc == nullptr) return nullptr; - if (grpc_trace_security_connector_refcount.enabled()) { - gpr_atm val = gpr_atm_no_barrier_load(&sc->refcount.count); - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, - "SECURITY_CONNECTOR:%p ref %" PRIdPTR " -> %" PRIdPTR " %s", sc, - val, val + 1, reason); - } -#else -grpc_security_connector* grpc_security_connector_ref( - grpc_security_connector* sc) { - if (sc == nullptr) return nullptr; -#endif - gpr_ref(&sc->refcount); - return sc; -} - -#ifndef NDEBUG -void grpc_security_connector_unref(grpc_security_connector* sc, - const char* file, int line, - const char* reason) { - if (sc == nullptr) return; - if (grpc_trace_security_connector_refcount.enabled()) { - gpr_atm val = gpr_atm_no_barrier_load(&sc->refcount.count); - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, - "SECURITY_CONNECTOR:%p unref %" PRIdPTR " -> %" PRIdPTR " %s", sc, - val, val - 1, reason); - } -#else -void grpc_security_connector_unref(grpc_security_connector* sc) { - if (sc == nullptr) return; -#endif - if (gpr_unref(&sc->refcount)) sc->vtable->destroy(sc); +int grpc_server_security_connector::server_security_connector_cmp( + const grpc_server_security_connector* other) const { + const grpc_server_security_connector* other_sc = + static_cast(other); + GPR_ASSERT(server_creds() != nullptr); + GPR_ASSERT(other_sc->server_creds() != nullptr); + return GPR_ICMP(server_creds(), other_sc->server_creds()); } static void connector_arg_destroy(void* p) { - GRPC_SECURITY_CONNECTOR_UNREF((grpc_security_connector*)p, - "connector_arg_destroy"); + static_cast(p)->Unref(DEBUG_LOCATION, + "connector_arg_destroy"); } static void* connector_arg_copy(void* p) { - return GRPC_SECURITY_CONNECTOR_REF((grpc_security_connector*)p, - "connector_arg_copy"); + return static_cast(p) + ->Ref(DEBUG_LOCATION, "connector_arg_copy") + .release(); } static int connector_cmp(void* a, void* b) { - return grpc_security_connector_cmp(static_cast(a), - static_cast(b)); + return static_cast(a)->cmp( + static_cast(b)); } static const grpc_arg_pointer_vtable connector_arg_vtable = { diff --git a/src/core/lib/security/security_connector/security_connector.h b/src/core/lib/security/security_connector/security_connector.h index 4c921a87931..f71ee54402d 100644 --- a/src/core/lib/security/security_connector/security_connector.h +++ b/src/core/lib/security/security_connector/security_connector.h @@ -26,6 +26,7 @@ #include #include "src/core/lib/channel/handshaker.h" +#include "src/core/lib/gprpp/ref_counted.h" #include "src/core/lib/iomgr/endpoint.h" #include "src/core/lib/iomgr/pollset.h" #include "src/core/lib/iomgr/tcp_server.h" @@ -34,8 +35,6 @@ extern grpc_core::DebugOnlyTraceFlag grpc_trace_security_connector_refcount; -/* --- status enum. --- */ - typedef enum { GRPC_SECURITY_OK = 0, GRPC_SECURITY_ERROR } grpc_security_status; /* --- security_connector object. --- @@ -43,55 +42,35 @@ typedef enum { GRPC_SECURITY_OK = 0, GRPC_SECURITY_ERROR } grpc_security_status; A security connector object represents away to configure the underlying transport security mechanism and check the resulting trusted peer. */ -typedef struct grpc_security_connector grpc_security_connector; - #define GRPC_ARG_SECURITY_CONNECTOR "grpc.security_connector" -typedef struct { - void (*destroy)(grpc_security_connector* sc); - void (*check_peer)(grpc_security_connector* sc, tsi_peer peer, - grpc_auth_context** auth_context, - grpc_closure* on_peer_checked); - int (*cmp)(grpc_security_connector* sc, grpc_security_connector* other); -} grpc_security_connector_vtable; +class grpc_security_connector + : public grpc_core::RefCounted { + public: + explicit grpc_security_connector(const char* url_scheme) + : grpc_core::RefCounted( + &grpc_trace_security_connector_refcount), + url_scheme_(url_scheme) {} + virtual ~grpc_security_connector() = default; -struct grpc_security_connector { - const grpc_security_connector_vtable* vtable; - gpr_refcount refcount; - const char* url_scheme; + /* Check the peer. Callee takes ownership of the peer object. + When done, sets *auth_context and invokes on_peer_checked. */ + virtual void check_peer( + tsi_peer peer, grpc_endpoint* ep, + grpc_core::RefCountedPtr* auth_context, + grpc_closure* on_peer_checked) GRPC_ABSTRACT; + + /* Compares two security connectors. */ + virtual int cmp(const grpc_security_connector* other) const GRPC_ABSTRACT; + + const char* url_scheme() const { return url_scheme_; } + + GRPC_ABSTRACT_BASE_CLASS + + private: + const char* url_scheme_; }; -/* Refcounting. */ -#ifndef NDEBUG -#define GRPC_SECURITY_CONNECTOR_REF(p, r) \ - grpc_security_connector_ref((p), __FILE__, __LINE__, (r)) -#define GRPC_SECURITY_CONNECTOR_UNREF(p, r) \ - grpc_security_connector_unref((p), __FILE__, __LINE__, (r)) -grpc_security_connector* grpc_security_connector_ref( - grpc_security_connector* policy, const char* file, int line, - const char* reason); -void grpc_security_connector_unref(grpc_security_connector* policy, - const char* file, int line, - const char* reason); -#else -#define GRPC_SECURITY_CONNECTOR_REF(p, r) grpc_security_connector_ref((p)) -#define GRPC_SECURITY_CONNECTOR_UNREF(p, r) grpc_security_connector_unref((p)) -grpc_security_connector* grpc_security_connector_ref( - grpc_security_connector* policy); -void grpc_security_connector_unref(grpc_security_connector* policy); -#endif - -/* Check the peer. Callee takes ownership of the peer object. - When done, sets *auth_context and invokes on_peer_checked. */ -void grpc_security_connector_check_peer(grpc_security_connector* sc, - tsi_peer peer, - grpc_auth_context** auth_context, - grpc_closure* on_peer_checked); - -/* Compares two security connectors. */ -int grpc_security_connector_cmp(grpc_security_connector* sc, - grpc_security_connector* other); - /* Util to encapsulate the connector in a channel arg. */ grpc_arg grpc_security_connector_to_arg(grpc_security_connector* sc); @@ -107,71 +86,89 @@ grpc_security_connector* grpc_security_connector_find_in_args( A channel security connector object represents a way to configure the underlying transport security mechanism on the client side. */ -typedef struct grpc_channel_security_connector grpc_channel_security_connector; +class grpc_channel_security_connector : public grpc_security_connector { + public: + grpc_channel_security_connector( + const char* url_scheme, + grpc_core::RefCountedPtr channel_creds, + grpc_core::RefCountedPtr request_metadata_creds); + ~grpc_channel_security_connector() override; -struct grpc_channel_security_connector { - grpc_security_connector base; - grpc_channel_credentials* channel_creds; - grpc_call_credentials* request_metadata_creds; - bool (*check_call_host)(grpc_channel_security_connector* sc, const char* host, - grpc_auth_context* auth_context, - grpc_closure* on_call_host_checked, - grpc_error** error); - void (*cancel_check_call_host)(grpc_channel_security_connector* sc, - grpc_closure* on_call_host_checked, - grpc_error* error); - void (*add_handshakers)(grpc_channel_security_connector* sc, - grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr); + /// Checks that the host that will be set for a call is acceptable. + /// Returns true if completed synchronously, in which case \a error will + /// be set to indicate the result. Otherwise, \a on_call_host_checked + /// will be invoked when complete. + virtual bool check_call_host(const char* host, + grpc_auth_context* auth_context, + grpc_closure* on_call_host_checked, + grpc_error** error) GRPC_ABSTRACT; + /// Cancels a pending asynchronous call to + /// grpc_channel_security_connector_check_call_host() with + /// \a on_call_host_checked as its callback. + virtual void cancel_check_call_host(grpc_closure* on_call_host_checked, + grpc_error* error) GRPC_ABSTRACT; + /// Registers handshakers with \a handshake_mgr. + virtual void add_handshakers(grpc_pollset_set* interested_parties, + grpc_core::HandshakeManager* handshake_mgr) + GRPC_ABSTRACT; + + const grpc_channel_credentials* channel_creds() const { + return channel_creds_.get(); + } + grpc_channel_credentials* mutable_channel_creds() { + return channel_creds_.get(); + } + const grpc_call_credentials* request_metadata_creds() const { + return request_metadata_creds_.get(); + } + grpc_call_credentials* mutable_request_metadata_creds() { + return request_metadata_creds_.get(); + } + + GRPC_ABSTRACT_BASE_CLASS + + protected: + // Helper methods to be used in subclasses. + int channel_security_connector_cmp( + const grpc_channel_security_connector* other) const; + + private: + grpc_core::RefCountedPtr channel_creds_; + grpc_core::RefCountedPtr request_metadata_creds_; }; -/// A helper function for use in grpc_security_connector_cmp() implementations. -int grpc_channel_security_connector_cmp(grpc_channel_security_connector* sc1, - grpc_channel_security_connector* sc2); - -/// Checks that the host that will be set for a call is acceptable. -/// Returns true if completed synchronously, in which case \a error will -/// be set to indicate the result. Otherwise, \a on_call_host_checked -/// will be invoked when complete. -bool grpc_channel_security_connector_check_call_host( - grpc_channel_security_connector* sc, const char* host, - grpc_auth_context* auth_context, grpc_closure* on_call_host_checked, - grpc_error** error); - -/// Cancels a pending asychronous call to -/// grpc_channel_security_connector_check_call_host() with -/// \a on_call_host_checked as its callback. -void grpc_channel_security_connector_cancel_check_call_host( - grpc_channel_security_connector* sc, grpc_closure* on_call_host_checked, - grpc_error* error); - -/* Registers handshakers with \a handshake_mgr. */ -void grpc_channel_security_connector_add_handshakers( - grpc_channel_security_connector* connector, - grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr); - /* --- server_security_connector object. --- A server security connector object represents a way to configure the underlying transport security mechanism on the server side. */ -typedef struct grpc_server_security_connector grpc_server_security_connector; +class grpc_server_security_connector : public grpc_security_connector { + public: + grpc_server_security_connector( + const char* url_scheme, + grpc_core::RefCountedPtr server_creds); + ~grpc_server_security_connector() override = default; -struct grpc_server_security_connector { - grpc_security_connector base; - grpc_server_credentials* server_creds; - void (*add_handshakers)(grpc_server_security_connector* sc, - grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr); + virtual void add_handshakers(grpc_pollset_set* interested_parties, + grpc_core::HandshakeManager* handshake_mgr) + GRPC_ABSTRACT; + + const grpc_server_credentials* server_creds() const { + return server_creds_.get(); + } + grpc_server_credentials* mutable_server_creds() { + return server_creds_.get(); + } + + GRPC_ABSTRACT_BASE_CLASS + + protected: + // Helper methods to be used in subclasses. + int server_security_connector_cmp( + const grpc_server_security_connector* other) const; + + private: + grpc_core::RefCountedPtr server_creds_; }; -/// A helper function for use in grpc_security_connector_cmp() implementations. -int grpc_server_security_connector_cmp(grpc_server_security_connector* sc1, - grpc_server_security_connector* sc2); - -void grpc_server_security_connector_add_handshakers( - grpc_server_security_connector* sc, grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr); - #endif /* GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_SECURITY_CONNECTOR_H */ diff --git a/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc b/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc index 20a9533dd13..f920dc6046d 100644 --- a/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc +++ b/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc @@ -30,6 +30,7 @@ #include "src/core/lib/channel/handshaker.h" #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/security/context/security_context.h" #include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/security/credentials/ssl/ssl_credentials.h" @@ -39,190 +40,19 @@ #include "src/core/tsi/ssl_transport_security.h" #include "src/core/tsi/transport_security.h" -typedef struct { - grpc_channel_security_connector base; - tsi_ssl_client_handshaker_factory* client_handshaker_factory; - char* target_name; - char* overridden_target_name; - const verify_peer_options* verify_options; -} grpc_ssl_channel_security_connector; - -typedef struct { - grpc_server_security_connector base; - tsi_ssl_server_handshaker_factory* server_handshaker_factory; -} grpc_ssl_server_security_connector; - -static bool server_connector_has_cert_config_fetcher( - grpc_ssl_server_security_connector* c) { - GPR_ASSERT(c != nullptr); - grpc_ssl_server_credentials* server_creds = - reinterpret_cast(c->base.server_creds); - GPR_ASSERT(server_creds != nullptr); - return server_creds->certificate_config_fetcher.cb != nullptr; -} - -static void ssl_channel_destroy(grpc_security_connector* sc) { - grpc_ssl_channel_security_connector* c = - reinterpret_cast(sc); - grpc_channel_credentials_unref(c->base.channel_creds); - grpc_call_credentials_unref(c->base.request_metadata_creds); - tsi_ssl_client_handshaker_factory_unref(c->client_handshaker_factory); - c->client_handshaker_factory = nullptr; - if (c->target_name != nullptr) gpr_free(c->target_name); - if (c->overridden_target_name != nullptr) gpr_free(c->overridden_target_name); - gpr_free(sc); -} - -static void ssl_server_destroy(grpc_security_connector* sc) { - grpc_ssl_server_security_connector* c = - reinterpret_cast(sc); - grpc_server_credentials_unref(c->base.server_creds); - tsi_ssl_server_handshaker_factory_unref(c->server_handshaker_factory); - c->server_handshaker_factory = nullptr; - gpr_free(sc); -} - -static void ssl_channel_add_handshakers(grpc_channel_security_connector* sc, - grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr) { - grpc_ssl_channel_security_connector* c = - reinterpret_cast(sc); - // Instantiate TSI handshaker. - tsi_handshaker* tsi_hs = nullptr; - tsi_result result = tsi_ssl_client_handshaker_factory_create_handshaker( - c->client_handshaker_factory, - c->overridden_target_name != nullptr ? c->overridden_target_name - : c->target_name, - &tsi_hs); - if (result != TSI_OK) { - gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.", - tsi_result_to_string(result)); - return; +namespace { +grpc_error* ssl_check_peer( + const char* peer_name, const tsi_peer* peer, + grpc_core::RefCountedPtr* auth_context) { + grpc_error* error = grpc_ssl_check_alpn(peer); + if (error != GRPC_ERROR_NONE) { + return error; } - // Create handshakers. - grpc_handshake_manager_add( - handshake_mgr, grpc_security_handshaker_create(tsi_hs, &sc->base)); -} - -/* Attempts to replace the server_handshaker_factory with a new factory using - * the provided grpc_ssl_server_certificate_config. Should new factory creation - * fail, the existing factory will not be replaced. Returns true on success (new - * factory created). */ -static bool try_replace_server_handshaker_factory( - grpc_ssl_server_security_connector* sc, - const grpc_ssl_server_certificate_config* config) { - if (config == nullptr) { - gpr_log(GPR_ERROR, - "Server certificate config callback returned invalid (NULL) " - "config."); - return false; - } - gpr_log(GPR_DEBUG, "Using new server certificate config (%p).", config); - - size_t num_alpn_protocols = 0; - const char** alpn_protocol_strings = - grpc_fill_alpn_protocol_strings(&num_alpn_protocols); - tsi_ssl_pem_key_cert_pair* cert_pairs = grpc_convert_grpc_to_tsi_cert_pairs( - config->pem_key_cert_pairs, config->num_key_cert_pairs); - tsi_ssl_server_handshaker_factory* new_handshaker_factory = nullptr; - grpc_ssl_server_credentials* server_creds = - reinterpret_cast(sc->base.server_creds); - tsi_result result = tsi_create_ssl_server_handshaker_factory_ex( - cert_pairs, config->num_key_cert_pairs, config->pem_root_certs, - grpc_get_tsi_client_certificate_request_type( - server_creds->config.client_certificate_request), - grpc_get_ssl_cipher_suites(), alpn_protocol_strings, - static_cast(num_alpn_protocols), &new_handshaker_factory); - gpr_free(cert_pairs); - gpr_free((void*)alpn_protocol_strings); - - if (result != TSI_OK) { - gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.", - tsi_result_to_string(result)); - return false; - } - tsi_ssl_server_handshaker_factory_unref(sc->server_handshaker_factory); - sc->server_handshaker_factory = new_handshaker_factory; - return true; -} - -/* Attempts to fetch the server certificate config if a callback is available. - * Current certificate config will continue to be used if the callback returns - * an error. Returns true if new credentials were sucessfully loaded. */ -static bool try_fetch_ssl_server_credentials( - grpc_ssl_server_security_connector* sc) { - grpc_ssl_server_certificate_config* certificate_config = nullptr; - bool status; - - GPR_ASSERT(sc != nullptr); - if (!server_connector_has_cert_config_fetcher(sc)) return false; - - grpc_ssl_server_credentials* server_creds = - reinterpret_cast(sc->base.server_creds); - grpc_ssl_certificate_config_reload_status cb_result = - server_creds->certificate_config_fetcher.cb( - server_creds->certificate_config_fetcher.user_data, - &certificate_config); - if (cb_result == GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED) { - gpr_log(GPR_DEBUG, "No change in SSL server credentials."); - status = false; - } else if (cb_result == GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW) { - status = try_replace_server_handshaker_factory(sc, certificate_config); - } else { - // Log error, continue using previously-loaded credentials. - gpr_log(GPR_ERROR, - "Failed fetching new server credentials, continuing to " - "use previously-loaded credentials."); - status = false; - } - - if (certificate_config != nullptr) { - grpc_ssl_server_certificate_config_destroy(certificate_config); - } - return status; -} - -static void ssl_server_add_handshakers(grpc_server_security_connector* sc, - grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr) { - grpc_ssl_server_security_connector* c = - reinterpret_cast(sc); - // Instantiate TSI handshaker. - try_fetch_ssl_server_credentials(c); - tsi_handshaker* tsi_hs = nullptr; - tsi_result result = tsi_ssl_server_handshaker_factory_create_handshaker( - c->server_handshaker_factory, &tsi_hs); - if (result != TSI_OK) { - gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.", - tsi_result_to_string(result)); - return; - } - // Create handshakers. - grpc_handshake_manager_add( - handshake_mgr, grpc_security_handshaker_create(tsi_hs, &sc->base)); -} - -static grpc_error* ssl_check_peer(grpc_security_connector* sc, - const char* peer_name, const tsi_peer* peer, - grpc_auth_context** auth_context) { -#if TSI_OPENSSL_ALPN_SUPPORT - /* Check the ALPN if ALPN is supported. */ - const tsi_peer_property* p = - tsi_peer_get_property_by_name(peer, TSI_SSL_ALPN_SELECTED_PROTOCOL); - if (p == nullptr) { - return GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "Cannot check peer: missing selected ALPN property."); - } - if (!grpc_chttp2_is_alpn_version_supported(p->value.data, p->value.length)) { - return GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "Cannot check peer: invalid ALPN value."); - } -#endif /* TSI_OPENSSL_ALPN_SUPPORT */ /* Check the peer name if specified. */ 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); + error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); gpr_free(msg); return error; } @@ -230,245 +60,394 @@ static grpc_error* ssl_check_peer(grpc_security_connector* sc, return GRPC_ERROR_NONE; } -static void ssl_channel_check_peer(grpc_security_connector* sc, tsi_peer peer, - grpc_auth_context** auth_context, - grpc_closure* on_peer_checked) { - grpc_ssl_channel_security_connector* c = - reinterpret_cast(sc); - const char* target_name = c->overridden_target_name != nullptr - ? c->overridden_target_name - : c->target_name; - grpc_error* error = ssl_check_peer(sc, target_name, &peer, auth_context); - if (error == GRPC_ERROR_NONE && - c->verify_options->verify_peer_callback != nullptr) { - const tsi_peer_property* p = - tsi_peer_get_property_by_name(&peer, TSI_X509_PEM_CERT_PROPERTY); - if (p == nullptr) { - error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "Cannot check peer: missing pem cert property."); - } else { - char* peer_pem = static_cast(gpr_malloc(p->value.length + 1)); - memcpy(peer_pem, p->value.data, p->value.length); - peer_pem[p->value.length] = '\0'; - int callback_status = c->verify_options->verify_peer_callback( - target_name, peer_pem, - c->verify_options->verify_peer_callback_userdata); - gpr_free(peer_pem); - if (callback_status) { - char* msg; - gpr_asprintf(&msg, "Verify peer callback returned a failure (%d)", - callback_status); - error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); - gpr_free(msg); - } +class grpc_ssl_channel_security_connector final + : public grpc_channel_security_connector { + public: + grpc_ssl_channel_security_connector( + grpc_core::RefCountedPtr channel_creds, + grpc_core::RefCountedPtr request_metadata_creds, + const grpc_ssl_config* config, const char* target_name, + const char* overridden_target_name) + : grpc_channel_security_connector(GRPC_SSL_URL_SCHEME, + std::move(channel_creds), + std::move(request_metadata_creds)), + overridden_target_name_(overridden_target_name == nullptr + ? nullptr + : gpr_strdup(overridden_target_name)), + verify_options_(&config->verify_options) { + char* port; + gpr_split_host_port(target_name, &target_name_, &port); + gpr_free(port); + } + + ~grpc_ssl_channel_security_connector() override { + tsi_ssl_client_handshaker_factory_unref(client_handshaker_factory_); + if (target_name_ != nullptr) gpr_free(target_name_); + if (overridden_target_name_ != nullptr) gpr_free(overridden_target_name_); + } + + grpc_security_status InitializeHandshakerFactory( + const grpc_ssl_config* config, const char* pem_root_certs, + const tsi_ssl_root_certs_store* root_store, + tsi_ssl_session_cache* ssl_session_cache) { + bool has_key_cert_pair = + config->pem_key_cert_pair != nullptr && + config->pem_key_cert_pair->private_key != nullptr && + config->pem_key_cert_pair->cert_chain != nullptr; + tsi_ssl_client_handshaker_options options; + GPR_DEBUG_ASSERT(pem_root_certs != nullptr); + options.pem_root_certs = pem_root_certs; + options.root_store = root_store; + options.alpn_protocols = + grpc_fill_alpn_protocol_strings(&options.num_alpn_protocols); + if (has_key_cert_pair) { + options.pem_key_cert_pair = config->pem_key_cert_pair; } - } - GRPC_CLOSURE_SCHED(on_peer_checked, error); - tsi_peer_destruct(&peer); -} - -static void ssl_server_check_peer(grpc_security_connector* sc, tsi_peer peer, - grpc_auth_context** auth_context, - grpc_closure* on_peer_checked) { - grpc_error* error = ssl_check_peer(sc, nullptr, &peer, auth_context); - tsi_peer_destruct(&peer); - GRPC_CLOSURE_SCHED(on_peer_checked, error); -} - -static int ssl_channel_cmp(grpc_security_connector* sc1, - grpc_security_connector* sc2) { - grpc_ssl_channel_security_connector* c1 = - reinterpret_cast(sc1); - grpc_ssl_channel_security_connector* c2 = - reinterpret_cast(sc2); - int c = grpc_channel_security_connector_cmp(&c1->base, &c2->base); - if (c != 0) return c; - c = strcmp(c1->target_name, c2->target_name); - if (c != 0) return c; - return (c1->overridden_target_name == nullptr || - c2->overridden_target_name == nullptr) - ? GPR_ICMP(c1->overridden_target_name, c2->overridden_target_name) - : strcmp(c1->overridden_target_name, c2->overridden_target_name); -} - -static int ssl_server_cmp(grpc_security_connector* sc1, - grpc_security_connector* sc2) { - return grpc_server_security_connector_cmp( - reinterpret_cast(sc1), - reinterpret_cast(sc2)); -} - -static bool ssl_channel_check_call_host(grpc_channel_security_connector* sc, - const char* host, - grpc_auth_context* auth_context, - grpc_closure* on_call_host_checked, - grpc_error** error) { - grpc_ssl_channel_security_connector* c = - reinterpret_cast(sc); - grpc_security_status status = GRPC_SECURITY_ERROR; - 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. */ - if (c->overridden_target_name != nullptr && - strcmp(host, c->target_name) == 0) { - status = GRPC_SECURITY_OK; - } - if (status != GRPC_SECURITY_OK) { - *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "call host does not match SSL server name"); - } - grpc_shallow_peer_destruct(&peer); - return true; -} - -static void ssl_channel_cancel_check_call_host( - grpc_channel_security_connector* sc, grpc_closure* on_call_host_checked, - grpc_error* error) { - GRPC_ERROR_UNREF(error); -} - -static grpc_security_connector_vtable ssl_channel_vtable = { - ssl_channel_destroy, ssl_channel_check_peer, ssl_channel_cmp}; - -static grpc_security_connector_vtable ssl_server_vtable = { - ssl_server_destroy, ssl_server_check_peer, ssl_server_cmp}; - -grpc_security_status grpc_ssl_channel_security_connector_create( - grpc_channel_credentials* channel_creds, - grpc_call_credentials* request_metadata_creds, - const grpc_ssl_config* config, const char* target_name, - const char* overridden_target_name, - tsi_ssl_session_cache* ssl_session_cache, - grpc_channel_security_connector** sc) { - tsi_result result = TSI_OK; - grpc_ssl_channel_security_connector* c; - char* port; - bool has_key_cert_pair; - tsi_ssl_client_handshaker_options options; - memset(&options, 0, sizeof(options)); - options.alpn_protocols = - grpc_fill_alpn_protocol_strings(&options.num_alpn_protocols); - - if (config == nullptr || target_name == nullptr) { - gpr_log(GPR_ERROR, "An ssl channel needs a config and a target name."); - goto error; - } - if (config->pem_root_certs == nullptr) { - // Use default root certificates. - options.pem_root_certs = grpc_core::DefaultSslRootStore::GetPemRootCerts(); - options.root_store = grpc_core::DefaultSslRootStore::GetRootStore(); - if (options.pem_root_certs == nullptr) { - gpr_log(GPR_ERROR, "Could not get default pem root certs."); - goto error; - } - } else { - options.pem_root_certs = config->pem_root_certs; - } - c = static_cast( - gpr_zalloc(sizeof(grpc_ssl_channel_security_connector))); - - gpr_ref_init(&c->base.base.refcount, 1); - c->base.base.vtable = &ssl_channel_vtable; - c->base.base.url_scheme = GRPC_SSL_URL_SCHEME; - c->base.channel_creds = grpc_channel_credentials_ref(channel_creds); - c->base.request_metadata_creds = - grpc_call_credentials_ref(request_metadata_creds); - c->base.check_call_host = ssl_channel_check_call_host; - c->base.cancel_check_call_host = ssl_channel_cancel_check_call_host; - c->base.add_handshakers = ssl_channel_add_handshakers; - gpr_split_host_port(target_name, &c->target_name, &port); - gpr_free(port); - if (overridden_target_name != nullptr) { - c->overridden_target_name = gpr_strdup(overridden_target_name); - } - c->verify_options = &config->verify_options; - - has_key_cert_pair = config->pem_key_cert_pair != nullptr && - config->pem_key_cert_pair->private_key != nullptr && - config->pem_key_cert_pair->cert_chain != nullptr; - if (has_key_cert_pair) { - options.pem_key_cert_pair = config->pem_key_cert_pair; - } - options.cipher_suites = grpc_get_ssl_cipher_suites(); - options.session_cache = ssl_session_cache; - result = tsi_create_ssl_client_handshaker_factory_with_options( - &options, &c->client_handshaker_factory); - if (result != TSI_OK) { - gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.", - tsi_result_to_string(result)); - ssl_channel_destroy(&c->base.base); - *sc = nullptr; - goto error; - } - *sc = &c->base; - gpr_free((void*)options.alpn_protocols); - return GRPC_SECURITY_OK; - -error: - gpr_free((void*)options.alpn_protocols); - return GRPC_SECURITY_ERROR; -} - -static grpc_ssl_server_security_connector* -grpc_ssl_server_security_connector_initialize( - grpc_server_credentials* server_creds) { - grpc_ssl_server_security_connector* c = - static_cast( - gpr_zalloc(sizeof(grpc_ssl_server_security_connector))); - gpr_ref_init(&c->base.base.refcount, 1); - c->base.base.url_scheme = GRPC_SSL_URL_SCHEME; - c->base.base.vtable = &ssl_server_vtable; - c->base.add_handshakers = ssl_server_add_handshakers; - c->base.server_creds = grpc_server_credentials_ref(server_creds); - return c; -} - -grpc_security_status grpc_ssl_server_security_connector_create( - grpc_server_credentials* gsc, grpc_server_security_connector** sc) { - tsi_result result = TSI_OK; - grpc_ssl_server_credentials* server_credentials = - reinterpret_cast(gsc); - grpc_security_status retval = GRPC_SECURITY_OK; - - GPR_ASSERT(server_credentials != nullptr); - GPR_ASSERT(sc != nullptr); - - grpc_ssl_server_security_connector* c = - grpc_ssl_server_security_connector_initialize(gsc); - if (server_connector_has_cert_config_fetcher(c)) { - // Load initial credentials from certificate_config_fetcher: - if (!try_fetch_ssl_server_credentials(c)) { - gpr_log(GPR_ERROR, "Failed loading SSL server credentials from fetcher."); - retval = GRPC_SECURITY_ERROR; - } - } else { - size_t num_alpn_protocols = 0; - const char** alpn_protocol_strings = - grpc_fill_alpn_protocol_strings(&num_alpn_protocols); - result = tsi_create_ssl_server_handshaker_factory_ex( - server_credentials->config.pem_key_cert_pairs, - server_credentials->config.num_key_cert_pairs, - server_credentials->config.pem_root_certs, - grpc_get_tsi_client_certificate_request_type( - server_credentials->config.client_certificate_request), - grpc_get_ssl_cipher_suites(), alpn_protocol_strings, - static_cast(num_alpn_protocols), - &c->server_handshaker_factory); - gpr_free((void*)alpn_protocol_strings); + options.cipher_suites = grpc_get_ssl_cipher_suites(); + options.session_cache = ssl_session_cache; + const tsi_result result = + tsi_create_ssl_client_handshaker_factory_with_options( + &options, &client_handshaker_factory_); + gpr_free((void*)options.alpn_protocols); if (result != TSI_OK) { gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.", tsi_result_to_string(result)); - retval = GRPC_SECURITY_ERROR; + return GRPC_SECURITY_ERROR; } + return GRPC_SECURITY_OK; } - if (retval == GRPC_SECURITY_OK) { - *sc = &c->base; - } else { - if (c != nullptr) ssl_server_destroy(&c->base.base); - if (sc != nullptr) *sc = nullptr; + void add_handshakers(grpc_pollset_set* interested_parties, + grpc_core::HandshakeManager* handshake_mgr) override { + // Instantiate TSI handshaker. + tsi_handshaker* tsi_hs = nullptr; + tsi_result result = tsi_ssl_client_handshaker_factory_create_handshaker( + client_handshaker_factory_, + overridden_target_name_ != nullptr ? overridden_target_name_ + : target_name_, + &tsi_hs); + if (result != TSI_OK) { + gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.", + tsi_result_to_string(result)); + return; + } + // Create handshakers. + handshake_mgr->Add(grpc_core::SecurityHandshakerCreate(tsi_hs, this)); } - return retval; + + void check_peer(tsi_peer peer, grpc_endpoint* ep, + grpc_core::RefCountedPtr* auth_context, + grpc_closure* on_peer_checked) override { + const char* target_name = overridden_target_name_ != nullptr + ? overridden_target_name_ + : target_name_; + grpc_error* error = ssl_check_peer(target_name, &peer, auth_context); + if (error == GRPC_ERROR_NONE && + verify_options_->verify_peer_callback != nullptr) { + const tsi_peer_property* p = + tsi_peer_get_property_by_name(&peer, TSI_X509_PEM_CERT_PROPERTY); + if (p == nullptr) { + error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Cannot check peer: missing pem cert property."); + } else { + char* peer_pem = static_cast(gpr_malloc(p->value.length + 1)); + memcpy(peer_pem, p->value.data, p->value.length); + peer_pem[p->value.length] = '\0'; + int callback_status = verify_options_->verify_peer_callback( + target_name, peer_pem, + verify_options_->verify_peer_callback_userdata); + gpr_free(peer_pem); + if (callback_status) { + char* msg; + gpr_asprintf(&msg, "Verify peer callback returned a failure (%d)", + callback_status); + error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); + gpr_free(msg); + } + } + } + GRPC_CLOSURE_SCHED(on_peer_checked, error); + tsi_peer_destruct(&peer); + } + + int cmp(const grpc_security_connector* other_sc) const override { + auto* other = + reinterpret_cast(other_sc); + int c = channel_security_connector_cmp(other); + if (c != 0) return c; + c = strcmp(target_name_, other->target_name_); + if (c != 0) return c; + return (overridden_target_name_ == nullptr || + other->overridden_target_name_ == nullptr) + ? GPR_ICMP(overridden_target_name_, + other->overridden_target_name_) + : strcmp(overridden_target_name_, + other->overridden_target_name_); + } + + bool check_call_host(const char* host, grpc_auth_context* auth_context, + grpc_closure* on_call_host_checked, + grpc_error** error) override { + grpc_security_status status = GRPC_SECURITY_ERROR; + 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. */ + if (overridden_target_name_ != nullptr && strcmp(host, target_name_) == 0) { + status = GRPC_SECURITY_OK; + } + if (status != GRPC_SECURITY_OK) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "call host does not match SSL server name"); + } + grpc_shallow_peer_destruct(&peer); + return true; + } + + void cancel_check_call_host(grpc_closure* on_call_host_checked, + grpc_error* error) override { + GRPC_ERROR_UNREF(error); + } + + private: + tsi_ssl_client_handshaker_factory* client_handshaker_factory_; + char* target_name_; + char* overridden_target_name_; + const verify_peer_options* verify_options_; +}; + +class grpc_ssl_server_security_connector + : public grpc_server_security_connector { + public: + grpc_ssl_server_security_connector( + grpc_core::RefCountedPtr server_creds) + : grpc_server_security_connector(GRPC_SSL_URL_SCHEME, + std::move(server_creds)) {} + + ~grpc_ssl_server_security_connector() override { + tsi_ssl_server_handshaker_factory_unref(server_handshaker_factory_); + } + + bool has_cert_config_fetcher() const { + return static_cast(server_creds()) + ->has_cert_config_fetcher(); + } + + const tsi_ssl_server_handshaker_factory* server_handshaker_factory() const { + return server_handshaker_factory_; + } + + grpc_security_status InitializeHandshakerFactory() { + if (has_cert_config_fetcher()) { + // Load initial credentials from certificate_config_fetcher: + if (!try_fetch_ssl_server_credentials()) { + gpr_log(GPR_ERROR, + "Failed loading SSL server credentials from fetcher."); + return GRPC_SECURITY_ERROR; + } + } else { + auto* server_credentials = + static_cast(server_creds()); + size_t num_alpn_protocols = 0; + const char** alpn_protocol_strings = + grpc_fill_alpn_protocol_strings(&num_alpn_protocols); + tsi_ssl_server_handshaker_options options; + options.pem_key_cert_pairs = + server_credentials->config().pem_key_cert_pairs; + options.num_key_cert_pairs = + server_credentials->config().num_key_cert_pairs; + options.pem_client_root_certs = + server_credentials->config().pem_root_certs; + options.client_certificate_request = + grpc_get_tsi_client_certificate_request_type( + server_credentials->config().client_certificate_request); + options.cipher_suites = grpc_get_ssl_cipher_suites(); + options.alpn_protocols = alpn_protocol_strings; + options.num_alpn_protocols = static_cast(num_alpn_protocols); + const tsi_result result = + tsi_create_ssl_server_handshaker_factory_with_options( + &options, &server_handshaker_factory_); + gpr_free((void*)alpn_protocol_strings); + if (result != TSI_OK) { + gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.", + tsi_result_to_string(result)); + return GRPC_SECURITY_ERROR; + } + } + return GRPC_SECURITY_OK; + } + + void add_handshakers(grpc_pollset_set* interested_parties, + grpc_core::HandshakeManager* handshake_mgr) override { + // Instantiate TSI handshaker. + try_fetch_ssl_server_credentials(); + tsi_handshaker* tsi_hs = nullptr; + tsi_result result = tsi_ssl_server_handshaker_factory_create_handshaker( + server_handshaker_factory_, &tsi_hs); + if (result != TSI_OK) { + gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.", + tsi_result_to_string(result)); + return; + } + // Create handshakers. + handshake_mgr->Add(grpc_core::SecurityHandshakerCreate(tsi_hs, this)); + } + + void check_peer(tsi_peer peer, grpc_endpoint* ep, + grpc_core::RefCountedPtr* auth_context, + grpc_closure* on_peer_checked) override { + grpc_error* error = ssl_check_peer(nullptr, &peer, auth_context); + tsi_peer_destruct(&peer); + GRPC_CLOSURE_SCHED(on_peer_checked, error); + } + + int cmp(const grpc_security_connector* other) const override { + return server_security_connector_cmp( + static_cast(other)); + } + + private: + /* Attempts to fetch the server certificate config if a callback is available. + * Current certificate config will continue to be used if the callback returns + * an error. Returns true if new credentials were successfully loaded. */ + bool try_fetch_ssl_server_credentials() { + grpc_ssl_server_certificate_config* certificate_config = nullptr; + bool status; + if (!has_cert_config_fetcher()) return false; + + grpc_ssl_server_credentials* server_creds = + static_cast(this->mutable_server_creds()); + grpc_ssl_certificate_config_reload_status cb_result = + server_creds->FetchCertConfig(&certificate_config); + if (cb_result == GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED) { + gpr_log(GPR_DEBUG, "No change in SSL server credentials."); + status = false; + } else if (cb_result == GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW) { + status = try_replace_server_handshaker_factory(certificate_config); + } else { + // Log error, continue using previously-loaded credentials. + gpr_log(GPR_ERROR, + "Failed fetching new server credentials, continuing to " + "use previously-loaded credentials."); + status = false; + } + + if (certificate_config != nullptr) { + grpc_ssl_server_certificate_config_destroy(certificate_config); + } + return status; + } + + /* Attempts to replace the server_handshaker_factory with a new factory using + * the provided grpc_ssl_server_certificate_config. Should new factory + * creation fail, the existing factory will not be replaced. Returns true on + * success (new factory created). */ + bool try_replace_server_handshaker_factory( + const grpc_ssl_server_certificate_config* config) { + if (config == nullptr) { + gpr_log(GPR_ERROR, + "Server certificate config callback returned invalid (NULL) " + "config."); + return false; + } + gpr_log(GPR_DEBUG, "Using new server certificate config (%p).", config); + + size_t num_alpn_protocols = 0; + const char** alpn_protocol_strings = + grpc_fill_alpn_protocol_strings(&num_alpn_protocols); + tsi_ssl_server_handshaker_factory* new_handshaker_factory = nullptr; + const grpc_ssl_server_credentials* server_creds = + static_cast(this->server_creds()); + GPR_DEBUG_ASSERT(config->pem_root_certs != nullptr); + tsi_ssl_server_handshaker_options options; + options.pem_key_cert_pairs = grpc_convert_grpc_to_tsi_cert_pairs( + config->pem_key_cert_pairs, config->num_key_cert_pairs); + options.num_key_cert_pairs = config->num_key_cert_pairs; + options.pem_client_root_certs = config->pem_root_certs; + options.client_certificate_request = + grpc_get_tsi_client_certificate_request_type( + server_creds->config().client_certificate_request); + options.cipher_suites = grpc_get_ssl_cipher_suites(); + options.alpn_protocols = alpn_protocol_strings; + options.num_alpn_protocols = static_cast(num_alpn_protocols); + tsi_result result = tsi_create_ssl_server_handshaker_factory_with_options( + &options, &new_handshaker_factory); + grpc_tsi_ssl_pem_key_cert_pairs_destroy( + const_cast(options.pem_key_cert_pairs), + options.num_key_cert_pairs); + gpr_free((void*)alpn_protocol_strings); + + if (result != TSI_OK) { + gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.", + tsi_result_to_string(result)); + return false; + } + set_server_handshaker_factory(new_handshaker_factory); + return true; + } + + void set_server_handshaker_factory( + tsi_ssl_server_handshaker_factory* new_factory) { + if (server_handshaker_factory_) { + tsi_ssl_server_handshaker_factory_unref(server_handshaker_factory_); + } + server_handshaker_factory_ = new_factory; + } + + tsi_ssl_server_handshaker_factory* server_handshaker_factory_ = nullptr; +}; +} // namespace + +grpc_core::RefCountedPtr +grpc_ssl_channel_security_connector_create( + grpc_core::RefCountedPtr channel_creds, + grpc_core::RefCountedPtr request_metadata_creds, + const grpc_ssl_config* config, const char* target_name, + const char* overridden_target_name, + tsi_ssl_session_cache* ssl_session_cache) { + if (config == nullptr || target_name == nullptr) { + gpr_log(GPR_ERROR, "An ssl channel needs a config and a target name."); + return nullptr; + } + + const char* pem_root_certs; + const tsi_ssl_root_certs_store* root_store; + if (config->pem_root_certs == nullptr) { + // Use default root certificates. + pem_root_certs = grpc_core::DefaultSslRootStore::GetPemRootCerts(); + if (pem_root_certs == nullptr) { + gpr_log(GPR_ERROR, "Could not get default pem root certs."); + return nullptr; + } + root_store = grpc_core::DefaultSslRootStore::GetRootStore(); + } else { + pem_root_certs = config->pem_root_certs; + root_store = nullptr; + } + + grpc_core::RefCountedPtr c = + grpc_core::MakeRefCounted( + std::move(channel_creds), std::move(request_metadata_creds), config, + target_name, overridden_target_name); + const grpc_security_status result = c->InitializeHandshakerFactory( + config, pem_root_certs, root_store, ssl_session_cache); + if (result != GRPC_SECURITY_OK) { + return nullptr; + } + return c; +} + +grpc_core::RefCountedPtr +grpc_ssl_server_security_connector_create( + grpc_core::RefCountedPtr server_credentials) { + GPR_ASSERT(server_credentials != nullptr); + grpc_core::RefCountedPtr c = + grpc_core::MakeRefCounted( + std::move(server_credentials)); + const grpc_security_status retval = c->InitializeHandshakerFactory(); + if (retval != GRPC_SECURITY_OK) { + return nullptr; + } + return c; } diff --git a/src/core/lib/security/security_connector/ssl/ssl_security_connector.h b/src/core/lib/security/security_connector/ssl/ssl_security_connector.h index 9b805906061..70e26e338aa 100644 --- a/src/core/lib/security/security_connector/ssl/ssl_security_connector.h +++ b/src/core/lib/security/security_connector/ssl/ssl_security_connector.h @@ -25,6 +25,7 @@ #include "src/core/lib/security/security_connector/security_connector.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/tsi/ssl_transport_security.h" #include "src/core/tsi/transport_security_interface.h" @@ -47,20 +48,21 @@ typedef struct { This function returns GRPC_SECURITY_OK in case of success or a specific error code otherwise. */ -grpc_security_status grpc_ssl_channel_security_connector_create( - grpc_channel_credentials* channel_creds, - grpc_call_credentials* request_metadata_creds, +grpc_core::RefCountedPtr +grpc_ssl_channel_security_connector_create( + grpc_core::RefCountedPtr channel_creds, + grpc_core::RefCountedPtr request_metadata_creds, const grpc_ssl_config* config, const char* target_name, const char* overridden_target_name, - tsi_ssl_session_cache* ssl_session_cache, - grpc_channel_security_connector** sc); + tsi_ssl_session_cache* ssl_session_cache); /* Config for ssl servers. */ typedef struct { - tsi_ssl_pem_key_cert_pair* pem_key_cert_pairs; - size_t num_key_cert_pairs; - char* pem_root_certs; - grpc_ssl_client_certificate_request_type client_certificate_request; + tsi_ssl_pem_key_cert_pair* pem_key_cert_pairs = nullptr; + size_t num_key_cert_pairs = 0; + char* pem_root_certs = nullptr; + grpc_ssl_client_certificate_request_type client_certificate_request = + GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE; } grpc_ssl_server_config; /* Creates an SSL server_security_connector. @@ -69,9 +71,9 @@ typedef struct { This function returns GRPC_SECURITY_OK in case of success or a specific error code otherwise. */ -grpc_security_status grpc_ssl_server_security_connector_create( - grpc_server_credentials* server_credentials, - grpc_server_security_connector** sc); +grpc_core::RefCountedPtr +grpc_ssl_server_security_connector_create( + grpc_core::RefCountedPtr server_credentials); #endif /* GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_SSL_SSL_SECURITY_CONNECTOR_H \ */ diff --git a/src/core/lib/security/security_connector/ssl_utils.cc b/src/core/lib/security/security_connector/ssl_utils.cc index fbf41cfbc7c..1eefff6fe24 100644 --- a/src/core/lib/security/security_connector/ssl_utils.cc +++ b/src/core/lib/security/security_connector/ssl_utils.cc @@ -30,6 +30,8 @@ #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/gprpp/global_config.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/load_file.h" #include "src/core/lib/security/context/security_context.h" #include "src/core/lib/security/security_connector/load_system_roots.h" @@ -46,9 +48,8 @@ static const char* installed_roots_path = /** Environment variable used as a flag to enable/disable loading system root certificates from the OS trust store. */ -#ifndef GRPC_NOT_USE_SYSTEM_SSL_ROOTS_ENV_VAR -#define GRPC_NOT_USE_SYSTEM_SSL_ROOTS_ENV_VAR "GRPC_NOT_USE_SYSTEM_SSL_ROOTS" -#endif +GPR_GLOBAL_CONFIG_DEFINE_BOOL(grpc_not_use_system_ssl_roots, false, + "Disable loading system root certificates."); #ifndef TSI_OPENSSL_ALPN_SUPPORT #define TSI_OPENSSL_ALPN_SUPPORT 1 @@ -111,6 +112,55 @@ grpc_get_tsi_client_certificate_request_type( } } +grpc_error* grpc_ssl_check_alpn(const tsi_peer* peer) { +#if TSI_OPENSSL_ALPN_SUPPORT + /* Check the ALPN if ALPN is supported. */ + const tsi_peer_property* p = + tsi_peer_get_property_by_name(peer, TSI_SSL_ALPN_SELECTED_PROTOCOL); + if (p == nullptr) { + return GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Cannot check peer: missing selected ALPN property."); + } + if (!grpc_chttp2_is_alpn_version_supported(p->value.data, p->value.length)) { + return GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Cannot check peer: invalid ALPN value."); + } +#endif /* TSI_OPENSSL_ALPN_SUPPORT */ + return GRPC_ERROR_NONE; +} + +grpc_error* grpc_ssl_check_peer_name(const char* peer_name, + const tsi_peer* peer) { + /* Check the peer name if specified. */ + 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; + } + return GRPC_ERROR_NONE; +} + +bool grpc_ssl_check_call_host(const char* host, const char* target_name, + const char* overridden_target_name, + grpc_auth_context* auth_context, + grpc_closure* on_call_host_checked, + grpc_error** error) { + grpc_security_status status = GRPC_SECURITY_ERROR; + 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 (overridden_target_name != nullptr && strcmp(host, target_name) == 0) { + status = GRPC_SECURITY_OK; + } + if (status != GRPC_SECURITY_OK) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "call host does not match SSL server name"); + } + grpc_shallow_peer_destruct(&peer); + return true; +} + const char** grpc_fill_alpn_protocol_strings(size_t* num_alpn_protocols) { GPR_ASSERT(num_alpn_protocols != nullptr); *num_alpn_protocols = grpc_chttp2_num_alpn_versions(); @@ -141,16 +191,29 @@ int grpc_ssl_host_matches_name(const tsi_peer* peer, const char* peer_name) { return r; } -grpc_auth_context* grpc_ssl_peer_to_auth_context(const tsi_peer* peer) { +bool grpc_ssl_cmp_target_name(const char* target_name, + const char* other_target_name, + const char* overridden_target_name, + const char* other_overridden_target_name) { + int c = strcmp(target_name, other_target_name); + if (c != 0) return c; + return (overridden_target_name == nullptr || + other_overridden_target_name == nullptr) + ? GPR_ICMP(overridden_target_name, other_overridden_target_name) + : strcmp(overridden_target_name, other_overridden_target_name); +} + +grpc_core::RefCountedPtr 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; /* The caller has checked the certificate type property. */ GPR_ASSERT(peer->property_count >= 1); - ctx = grpc_auth_context_create(nullptr); + grpc_core::RefCountedPtr ctx = + grpc_core::MakeRefCounted(nullptr); grpc_auth_context_add_cstring_property( - ctx, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME, + ctx.get(), GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME, GRPC_SSL_TRANSPORT_SECURITY_TYPE); for (i = 0; i < peer->property_count; i++) { const tsi_peer_property* prop = &peer->properties[i]; @@ -160,24 +223,26 @@ grpc_auth_context* grpc_ssl_peer_to_auth_context(const tsi_peer* peer) { if (peer_identity_property_name == nullptr) { peer_identity_property_name = GRPC_X509_CN_PROPERTY_NAME; } - grpc_auth_context_add_property(ctx, GRPC_X509_CN_PROPERTY_NAME, + grpc_auth_context_add_property(ctx.get(), GRPC_X509_CN_PROPERTY_NAME, prop->value.data, prop->value.length); } else if (strcmp(prop->name, TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY) == 0) { peer_identity_property_name = GRPC_X509_SAN_PROPERTY_NAME; - grpc_auth_context_add_property(ctx, GRPC_X509_SAN_PROPERTY_NAME, + grpc_auth_context_add_property(ctx.get(), GRPC_X509_SAN_PROPERTY_NAME, prop->value.data, prop->value.length); } else if (strcmp(prop->name, TSI_X509_PEM_CERT_PROPERTY) == 0) { - grpc_auth_context_add_property(ctx, GRPC_X509_PEM_CERT_PROPERTY_NAME, + grpc_auth_context_add_property(ctx.get(), + GRPC_X509_PEM_CERT_PROPERTY_NAME, prop->value.data, prop->value.length); } else if (strcmp(prop->name, TSI_SSL_SESSION_REUSED_PEER_PROPERTY) == 0) { - grpc_auth_context_add_property(ctx, GRPC_SSL_SESSION_REUSED_PROPERTY, + grpc_auth_context_add_property(ctx.get(), + GRPC_SSL_SESSION_REUSED_PROPERTY, prop->value.data, prop->value.length); } } if (peer_identity_property_name != nullptr) { GPR_ASSERT(grpc_auth_context_set_peer_identity_property_name( - ctx, peer_identity_property_name) == 1); + ctx.get(), peer_identity_property_name) == 1); } return ctx; } @@ -226,6 +291,79 @@ void grpc_shallow_peer_destruct(tsi_peer* peer) { if (peer->properties != nullptr) gpr_free(peer->properties); } +grpc_security_status grpc_ssl_tsi_client_handshaker_factory_init( + tsi_ssl_pem_key_cert_pair* pem_key_cert_pair, const char* pem_root_certs, + tsi_ssl_session_cache* ssl_session_cache, + tsi_ssl_client_handshaker_factory** handshaker_factory) { + const char* root_certs; + const tsi_ssl_root_certs_store* root_store; + if (pem_root_certs == nullptr) { + // Use default root certificates. + root_certs = grpc_core::DefaultSslRootStore::GetPemRootCerts(); + if (root_certs == nullptr) { + gpr_log(GPR_ERROR, "Could not get default pem root certs."); + return GRPC_SECURITY_ERROR; + } + root_store = grpc_core::DefaultSslRootStore::GetRootStore(); + } else { + root_certs = pem_root_certs; + root_store = nullptr; + } + bool has_key_cert_pair = pem_key_cert_pair != nullptr && + pem_key_cert_pair->private_key != nullptr && + pem_key_cert_pair->cert_chain != nullptr; + tsi_ssl_client_handshaker_options options; + GPR_DEBUG_ASSERT(root_certs != nullptr); + options.pem_root_certs = root_certs; + options.root_store = root_store; + options.alpn_protocols = + grpc_fill_alpn_protocol_strings(&options.num_alpn_protocols); + if (has_key_cert_pair) { + options.pem_key_cert_pair = pem_key_cert_pair; + } + options.cipher_suites = grpc_get_ssl_cipher_suites(); + options.session_cache = ssl_session_cache; + const tsi_result result = + tsi_create_ssl_client_handshaker_factory_with_options(&options, + handshaker_factory); + gpr_free((void*)options.alpn_protocols); + if (result != TSI_OK) { + gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.", + tsi_result_to_string(result)); + return GRPC_SECURITY_ERROR; + } + return GRPC_SECURITY_OK; +} + +grpc_security_status grpc_ssl_tsi_server_handshaker_factory_init( + tsi_ssl_pem_key_cert_pair* pem_key_cert_pairs, size_t num_key_cert_pairs, + const char* pem_root_certs, + grpc_ssl_client_certificate_request_type client_certificate_request, + tsi_ssl_server_handshaker_factory** handshaker_factory) { + size_t num_alpn_protocols = 0; + const char** alpn_protocol_strings = + grpc_fill_alpn_protocol_strings(&num_alpn_protocols); + tsi_ssl_server_handshaker_options options; + options.pem_key_cert_pairs = pem_key_cert_pairs; + options.num_key_cert_pairs = num_key_cert_pairs; + options.pem_client_root_certs = pem_root_certs; + options.client_certificate_request = + grpc_get_tsi_client_certificate_request_type(client_certificate_request); + options.cipher_suites = grpc_get_ssl_cipher_suites(); + options.alpn_protocols = alpn_protocol_strings; + options.num_alpn_protocols = static_cast(num_alpn_protocols); + const tsi_result result = + tsi_create_ssl_server_handshaker_factory_with_options(&options, + handshaker_factory); + gpr_free((void*)alpn_protocol_strings); + if (result != TSI_OK) { + gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.", + tsi_result_to_string(result)); + return GRPC_SECURITY_ERROR; + } + return GRPC_SECURITY_OK; +} + /* --- Ssl cache implementation. --- */ grpc_ssl_session_cache* grpc_ssl_session_cache_create_lru(size_t capacity) { @@ -290,10 +428,8 @@ const char* DefaultSslRootStore::GetPemRootCerts() { grpc_slice DefaultSslRootStore::ComputePemRootCerts() { grpc_slice result = grpc_empty_slice(); - char* not_use_system_roots_env_value = - gpr_getenv(GRPC_NOT_USE_SYSTEM_SSL_ROOTS_ENV_VAR); - const bool not_use_system_roots = gpr_is_true(not_use_system_roots_env_value); - gpr_free(not_use_system_roots_env_value); + const bool not_use_system_roots = + GPR_GLOBAL_CONFIG_GET(grpc_not_use_system_ssl_roots); // First try to load the roots from the environment. char* default_root_certs_path = gpr_getenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR); diff --git a/src/core/lib/security/security_connector/ssl_utils.h b/src/core/lib/security/security_connector/ssl_utils.h index 6f6d473311b..080e277f944 100644 --- a/src/core/lib/security/security_connector/ssl_utils.h +++ b/src/core/lib/security/security_connector/ssl_utils.h @@ -26,7 +26,11 @@ #include #include +#include "src/core/lib/gprpp/ref_counted_ptr.h" +#include "src/core/lib/iomgr/error.h" +#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_interface.h" /* --- Util. --- */ @@ -34,6 +38,23 @@ /* --- URL schemes. --- */ #define GRPC_SSL_URL_SCHEME "https" +/* Check ALPN information returned from SSL handshakes. */ +grpc_error* grpc_ssl_check_alpn(const tsi_peer* peer); + +/* Check peer name information returned from SSL handshakes. */ +grpc_error* grpc_ssl_check_peer_name(const char* peer_name, + const tsi_peer* peer); +/* Compare targer_name information extracted from SSL security connectors. */ +bool grpc_ssl_cmp_target_name(const char* target_name, + const char* other_target_name, + const char* overridden_target_name, + const char* other_overridden_target_name); +/* Check the host that will be set for a call is acceptable.*/ +bool grpc_ssl_check_call_host(const char* host, const char* target_name, + const char* overridden_target_name, + grpc_auth_context* auth_context, + grpc_closure* on_call_host_checked, + grpc_error** error); /* Return HTTP2-compliant cipher suites that gRPC accepts by default. */ const char* grpc_get_ssl_cipher_suites(void); @@ -46,8 +67,21 @@ grpc_get_tsi_client_certificate_request_type( /* Return an array of strings containing alpn protocols. */ const char** grpc_fill_alpn_protocol_strings(size_t* num_alpn_protocols); +/* Initialize TSI SSL server/client handshaker factory. */ +grpc_security_status grpc_ssl_tsi_client_handshaker_factory_init( + tsi_ssl_pem_key_cert_pair* key_cert_pair, const char* pem_root_certs, + tsi_ssl_session_cache* ssl_session_cache, + tsi_ssl_client_handshaker_factory** handshaker_factory); + +grpc_security_status grpc_ssl_tsi_server_handshaker_factory_init( + tsi_ssl_pem_key_cert_pair* key_cert_pairs, size_t num_key_cert_pairs, + const char* pem_root_certs, + grpc_ssl_client_certificate_request_type client_certificate_request, + tsi_ssl_server_handshaker_factory** handshaker_factory); + /* Exposed for testing only. */ -grpc_auth_context* grpc_ssl_peer_to_auth_context(const tsi_peer* peer); +grpc_core::RefCountedPtr 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 grpc_shallow_peer_destruct(tsi_peer* peer); @@ -87,6 +121,39 @@ class DefaultSslRootStore { static grpc_slice default_pem_root_certs_; }; +class PemKeyCertPair { + public: + // Construct from the C struct. We steal its members and then immediately + // free it. + explicit PemKeyCertPair(grpc_ssl_pem_key_cert_pair* pair) + : private_key_(const_cast(pair->private_key)), + cert_chain_(const_cast(pair->cert_chain)) { + gpr_free(pair); + } + + // Movable. + PemKeyCertPair(PemKeyCertPair&& other) { + private_key_ = std::move(other.private_key_); + cert_chain_ = std::move(other.cert_chain_); + } + PemKeyCertPair& operator=(PemKeyCertPair&& other) { + private_key_ = std::move(other.private_key_); + cert_chain_ = std::move(other.cert_chain_); + return *this; + } + + // Not copyable. + PemKeyCertPair(const PemKeyCertPair&) = delete; + PemKeyCertPair& operator=(const PemKeyCertPair&) = delete; + + char* private_key() const { return private_key_.get(); } + char* cert_chain() const { return cert_chain_.get(); } + + private: + grpc_core::UniquePtr private_key_; + grpc_core::UniquePtr cert_chain_; +}; + } // namespace grpc_core #endif /* GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_SSL_UTILS_H \ diff --git a/src/core/lib/security/security_connector/tls/spiffe_security_connector.cc b/src/core/lib/security/security_connector/tls/spiffe_security_connector.cc new file mode 100644 index 00000000000..ebf9c905079 --- /dev/null +++ b/src/core/lib/security/security_connector/tls/spiffe_security_connector.cc @@ -0,0 +1,426 @@ +/* + * + * 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 + +#include "src/core/lib/security/security_connector/tls/spiffe_security_connector.h" + +#include +#include + +#include +#include +#include +#include + +#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/security/credentials/ssl/ssl_credentials.h" +#include "src/core/lib/security/credentials/tls/spiffe_credentials.h" +#include "src/core/lib/security/security_connector/ssl_utils.h" +#include "src/core/lib/security/transport/security_handshaker.h" +#include "src/core/lib/slice/slice_internal.h" +#include "src/core/lib/transport/transport.h" +#include "src/core/tsi/ssl_transport_security.h" +#include "src/core/tsi/transport_security.h" + +namespace { + +tsi_ssl_pem_key_cert_pair* ConvertToTsiPemKeyCertPair( + const grpc_tls_key_materials_config::PemKeyCertPairList& cert_pair_list) { + tsi_ssl_pem_key_cert_pair* tsi_pairs = nullptr; + size_t num_key_cert_pairs = cert_pair_list.size(); + if (num_key_cert_pairs > 0) { + GPR_ASSERT(cert_pair_list.data() != nullptr); + tsi_pairs = static_cast( + gpr_zalloc(num_key_cert_pairs * sizeof(tsi_ssl_pem_key_cert_pair))); + } + for (size_t i = 0; i < num_key_cert_pairs; i++) { + GPR_ASSERT(cert_pair_list[i].private_key() != nullptr); + GPR_ASSERT(cert_pair_list[i].cert_chain() != nullptr); + tsi_pairs[i].cert_chain = gpr_strdup(cert_pair_list[i].cert_chain()); + tsi_pairs[i].private_key = gpr_strdup(cert_pair_list[i].private_key()); + } + return tsi_pairs; +} + +/** -- Util function to populate SPIFFE server/channel credentials. -- */ +grpc_core::RefCountedPtr +PopulateSpiffeCredentials(const grpc_tls_credentials_options& options) { + GPR_ASSERT(options.credential_reload_config() != nullptr || + options.key_materials_config() != nullptr); + grpc_core::RefCountedPtr key_materials_config; + /* Use credential reload config to fetch credentials. */ + if (options.credential_reload_config() != nullptr) { + grpc_tls_credential_reload_arg* arg = + grpc_core::New(); + key_materials_config = grpc_tls_key_materials_config_create()->Ref(); + arg->key_materials_config = key_materials_config.get(); + int result = options.credential_reload_config()->Schedule(arg); + if (result) { + /* Do not support async credential reload. */ + gpr_log(GPR_ERROR, "Async credential reload is unsupported now."); + } else { + grpc_ssl_certificate_config_reload_status status = arg->status; + if (status == GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED) { + gpr_log(GPR_DEBUG, "Credential does not change after reload."); + } else if (status == GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_FAIL) { + gpr_log(GPR_ERROR, "Credential reload failed with an error: %s", + arg->error_details); + } + } + gpr_free((void*)arg->error_details); + grpc_core::Delete(arg); + /* Use existing key materials config. */ + } else { + key_materials_config = options.key_materials_config()->Ref(); + } + return key_materials_config; +} + +} // namespace + +SpiffeChannelSecurityConnector::SpiffeChannelSecurityConnector( + grpc_core::RefCountedPtr channel_creds, + grpc_core::RefCountedPtr request_metadata_creds, + const char* target_name, const char* overridden_target_name) + : grpc_channel_security_connector(GRPC_SSL_URL_SCHEME, + std::move(channel_creds), + std::move(request_metadata_creds)), + overridden_target_name_(overridden_target_name == nullptr + ? nullptr + : gpr_strdup(overridden_target_name)) { + check_arg_ = ServerAuthorizationCheckArgCreate(this); + char* port; + gpr_split_host_port(target_name, &target_name_, &port); + gpr_free(port); +} + +SpiffeChannelSecurityConnector::~SpiffeChannelSecurityConnector() { + if (target_name_ != nullptr) { + gpr_free(target_name_); + } + if (overridden_target_name_ != nullptr) { + gpr_free(overridden_target_name_); + } + if (client_handshaker_factory_ != nullptr) { + tsi_ssl_client_handshaker_factory_unref(client_handshaker_factory_); + } + ServerAuthorizationCheckArgDestroy(check_arg_); +} + +void SpiffeChannelSecurityConnector::add_handshakers( + grpc_pollset_set* interested_parties, + grpc_core::HandshakeManager* handshake_mgr) { + // Instantiate TSI handshaker. + tsi_handshaker* tsi_hs = nullptr; + tsi_result result = tsi_ssl_client_handshaker_factory_create_handshaker( + client_handshaker_factory_, + overridden_target_name_ != nullptr ? overridden_target_name_ + : target_name_, + &tsi_hs); + if (result != TSI_OK) { + gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.", + tsi_result_to_string(result)); + return; + } + // Create handshakers. + handshake_mgr->Add(grpc_core::SecurityHandshakerCreate(tsi_hs, this)); +} + +void SpiffeChannelSecurityConnector::check_peer( + tsi_peer peer, grpc_endpoint* ep, + grpc_core::RefCountedPtr* auth_context, + grpc_closure* on_peer_checked) { + const char* target_name = overridden_target_name_ != nullptr + ? overridden_target_name_ + : target_name_; + grpc_error* error = grpc_ssl_check_alpn(&peer); + if (error != GRPC_ERROR_NONE) { + GRPC_CLOSURE_SCHED(on_peer_checked, error); + tsi_peer_destruct(&peer); + return; + } + *auth_context = grpc_ssl_peer_to_auth_context(&peer); + const SpiffeCredentials* creds = + static_cast(channel_creds()); + const grpc_tls_server_authorization_check_config* config = + creds->options().server_authorization_check_config(); + /* If server authorization config is not null, use it to perform + * server authorization check. */ + if (config != nullptr) { + const tsi_peer_property* p = + tsi_peer_get_property_by_name(&peer, TSI_X509_PEM_CERT_PROPERTY); + if (p == nullptr) { + error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Cannot check peer: missing pem cert property."); + } else { + char* peer_pem = static_cast(gpr_malloc(p->value.length + 1)); + memcpy(peer_pem, p->value.data, p->value.length); + peer_pem[p->value.length] = '\0'; + GPR_ASSERT(check_arg_ != nullptr); + check_arg_->peer_cert = check_arg_->peer_cert == nullptr + ? gpr_strdup(peer_pem) + : check_arg_->peer_cert; + check_arg_->target_name = check_arg_->target_name == nullptr + ? gpr_strdup(target_name) + : check_arg_->target_name; + on_peer_checked_ = on_peer_checked; + gpr_free(peer_pem); + int callback_status = config->Schedule(check_arg_); + /* Server authorization check is handled asynchronously. */ + if (callback_status) { + tsi_peer_destruct(&peer); + return; + } + /* Server authorization check is handled synchronously. */ + error = ProcessServerAuthorizationCheckResult(check_arg_); + } + } + GRPC_CLOSURE_SCHED(on_peer_checked, error); + tsi_peer_destruct(&peer); +} + +int SpiffeChannelSecurityConnector::cmp( + const grpc_security_connector* other_sc) const { + auto* other = + reinterpret_cast(other_sc); + int c = channel_security_connector_cmp(other); + if (c != 0) { + return c; + } + return grpc_ssl_cmp_target_name(target_name_, other->target_name_, + overridden_target_name_, + other->overridden_target_name_); +} + +bool SpiffeChannelSecurityConnector::check_call_host( + const char* host, grpc_auth_context* auth_context, + grpc_closure* on_call_host_checked, grpc_error** error) { + return grpc_ssl_check_call_host(host, target_name_, overridden_target_name_, + auth_context, on_call_host_checked, error); +} + +void SpiffeChannelSecurityConnector::cancel_check_call_host( + grpc_closure* on_call_host_checked, grpc_error* error) { + GRPC_ERROR_UNREF(error); +} + +grpc_core::RefCountedPtr +SpiffeChannelSecurityConnector::CreateSpiffeChannelSecurityConnector( + grpc_core::RefCountedPtr channel_creds, + grpc_core::RefCountedPtr request_metadata_creds, + const char* target_name, const char* overridden_target_name, + tsi_ssl_session_cache* ssl_session_cache) { + if (channel_creds == nullptr) { + gpr_log(GPR_ERROR, + "channel_creds is nullptr in " + "SpiffeChannelSecurityConnectorCreate()"); + return nullptr; + } + if (target_name == nullptr) { + gpr_log(GPR_ERROR, + "target_name is nullptr in " + "SpiffeChannelSecurityConnectorCreate()"); + return nullptr; + } + grpc_core::RefCountedPtr c = + grpc_core::MakeRefCounted( + std::move(channel_creds), std::move(request_metadata_creds), + target_name, overridden_target_name); + if (c->InitializeHandshakerFactory(ssl_session_cache) != GRPC_SECURITY_OK) { + return nullptr; + } + return c; +} + +grpc_security_status +SpiffeChannelSecurityConnector::InitializeHandshakerFactory( + tsi_ssl_session_cache* ssl_session_cache) { + const SpiffeCredentials* creds = + static_cast(channel_creds()); + auto key_materials_config = PopulateSpiffeCredentials(creds->options()); + if (key_materials_config->pem_key_cert_pair_list().empty()) { + key_materials_config->Unref(); + return GRPC_SECURITY_ERROR; + } + tsi_ssl_pem_key_cert_pair* pem_key_cert_pair = ConvertToTsiPemKeyCertPair( + key_materials_config->pem_key_cert_pair_list()); + grpc_security_status status = grpc_ssl_tsi_client_handshaker_factory_init( + pem_key_cert_pair, key_materials_config->pem_root_certs(), + ssl_session_cache, &client_handshaker_factory_); + // Free memory. + key_materials_config->Unref(); + grpc_tsi_ssl_pem_key_cert_pairs_destroy(pem_key_cert_pair, 1); + return status; +} + +void SpiffeChannelSecurityConnector::ServerAuthorizationCheckDone( + grpc_tls_server_authorization_check_arg* arg) { + GPR_ASSERT(arg != nullptr); + grpc_core::ExecCtx exec_ctx; + grpc_error* error = ProcessServerAuthorizationCheckResult(arg); + SpiffeChannelSecurityConnector* connector = + static_cast(arg->cb_user_data); + GRPC_CLOSURE_SCHED(connector->on_peer_checked_, error); +} + +grpc_error* +SpiffeChannelSecurityConnector::ProcessServerAuthorizationCheckResult( + grpc_tls_server_authorization_check_arg* arg) { + grpc_error* error = GRPC_ERROR_NONE; + char* msg = nullptr; + /* Server authorization check is cancelled by caller. */ + if (arg->status == GRPC_STATUS_CANCELLED) { + gpr_asprintf(&msg, + "Server authorization check is cancelled by the caller with " + "error: %s", + arg->error_details); + error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); + } else if (arg->status == GRPC_STATUS_OK) { + /* Server authorization check completed successfully but returned check + * failure. */ + if (!arg->success) { + gpr_asprintf(&msg, "Server authorization check failed with error: %s", + arg->error_details); + error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); + } + /* Server authorization check did not complete correctly. */ + } else { + gpr_asprintf( + &msg, + "Server authorization check did not finish correctly with error: %s", + arg->error_details); + error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); + } + gpr_free(msg); + return error; +} + +grpc_tls_server_authorization_check_arg* +SpiffeChannelSecurityConnector::ServerAuthorizationCheckArgCreate( + void* user_data) { + grpc_tls_server_authorization_check_arg* arg = + grpc_core::New(); + arg->cb = ServerAuthorizationCheckDone; + arg->cb_user_data = user_data; + arg->status = GRPC_STATUS_OK; + return arg; +} + +void SpiffeChannelSecurityConnector::ServerAuthorizationCheckArgDestroy( + grpc_tls_server_authorization_check_arg* arg) { + if (arg == nullptr) { + return; + } + gpr_free((void*)arg->target_name); + gpr_free((void*)arg->peer_cert); + gpr_free((void*)arg->error_details); + grpc_core::Delete(arg); +} + +SpiffeServerSecurityConnector::SpiffeServerSecurityConnector( + grpc_core::RefCountedPtr server_creds) + : grpc_server_security_connector(GRPC_SSL_URL_SCHEME, + std::move(server_creds)) {} + +SpiffeServerSecurityConnector::~SpiffeServerSecurityConnector() { + if (server_handshaker_factory_ != nullptr) { + tsi_ssl_server_handshaker_factory_unref(server_handshaker_factory_); + } +} + +void SpiffeServerSecurityConnector::add_handshakers( + grpc_pollset_set* interested_parties, + grpc_core::HandshakeManager* handshake_mgr) { + /* Create a TLS SPIFFE TSI handshaker for server. */ + RefreshServerHandshakerFactory(); + tsi_handshaker* tsi_hs = nullptr; + tsi_result result = tsi_ssl_server_handshaker_factory_create_handshaker( + server_handshaker_factory_, &tsi_hs); + if (result != TSI_OK) { + gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.", + tsi_result_to_string(result)); + return; + } + handshake_mgr->Add(grpc_core::SecurityHandshakerCreate(tsi_hs, this)); +} + +void SpiffeServerSecurityConnector::check_peer( + tsi_peer peer, grpc_endpoint* ep, + grpc_core::RefCountedPtr* auth_context, + grpc_closure* on_peer_checked) { + grpc_error* error = grpc_ssl_check_alpn(&peer); + *auth_context = grpc_ssl_peer_to_auth_context(&peer); + tsi_peer_destruct(&peer); + GRPC_CLOSURE_SCHED(on_peer_checked, error); +} + +int SpiffeServerSecurityConnector::cmp( + const grpc_security_connector* other) const { + return server_security_connector_cmp( + static_cast(other)); +} + +grpc_core::RefCountedPtr +SpiffeServerSecurityConnector::CreateSpiffeServerSecurityConnector( + grpc_core::RefCountedPtr server_creds) { + if (server_creds == nullptr) { + gpr_log(GPR_ERROR, + "server_creds is nullptr in " + "SpiffeServerSecurityConnectorCreate()"); + return nullptr; + } + grpc_core::RefCountedPtr c = + grpc_core::MakeRefCounted( + std::move(server_creds)); + if (c->RefreshServerHandshakerFactory() != GRPC_SECURITY_OK) { + return nullptr; + } + return c; +} + +grpc_security_status +SpiffeServerSecurityConnector::RefreshServerHandshakerFactory() { + const SpiffeServerCredentials* creds = + static_cast(server_creds()); + auto key_materials_config = PopulateSpiffeCredentials(creds->options()); + /* Credential reload does NOT take effect and we need to keep using + * the existing handshaker factory. */ + if (key_materials_config->pem_key_cert_pair_list().empty()) { + key_materials_config->Unref(); + return GRPC_SECURITY_ERROR; + } + /* Credential reload takes effect and we need to free the existing + * handshaker library. */ + if (server_handshaker_factory_) { + tsi_ssl_server_handshaker_factory_unref(server_handshaker_factory_); + } + tsi_ssl_pem_key_cert_pair* pem_key_cert_pairs = ConvertToTsiPemKeyCertPair( + key_materials_config->pem_key_cert_pair_list()); + size_t num_key_cert_pairs = + key_materials_config->pem_key_cert_pair_list().size(); + grpc_security_status status = grpc_ssl_tsi_server_handshaker_factory_init( + pem_key_cert_pairs, num_key_cert_pairs, + key_materials_config->pem_root_certs(), + creds->options().cert_request_type(), &server_handshaker_factory_); + // Free memory. + key_materials_config->Unref(); + grpc_tsi_ssl_pem_key_cert_pairs_destroy(pem_key_cert_pairs, + num_key_cert_pairs); + return status; +} diff --git a/src/core/lib/security/security_connector/tls/spiffe_security_connector.h b/src/core/lib/security/security_connector/tls/spiffe_security_connector.h new file mode 100644 index 00000000000..56972153e07 --- /dev/null +++ b/src/core/lib/security/security_connector/tls/spiffe_security_connector.h @@ -0,0 +1,122 @@ +/* + * + * 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_SECURITY_SECURITY_CONNECTOR_TLS_SPIFFE_SECURITY_CONNECTOR_H +#define GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_TLS_SPIFFE_SECURITY_CONNECTOR_H + +#include + +#include "src/core/lib/security/context/security_context.h" +#include "src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h" + +#define GRPC_TLS_SPIFFE_TRANSPORT_SECURITY_TYPE "spiffe" + +// Spiffe channel security connector. +class SpiffeChannelSecurityConnector final + : public grpc_channel_security_connector { + public: + // static factory method to create a SPIFFE channel security connector. + static grpc_core::RefCountedPtr + CreateSpiffeChannelSecurityConnector( + grpc_core::RefCountedPtr channel_creds, + grpc_core::RefCountedPtr request_metadata_creds, + const char* target_name, const char* overridden_target_name, + tsi_ssl_session_cache* ssl_session_cache); + + SpiffeChannelSecurityConnector( + grpc_core::RefCountedPtr channel_creds, + grpc_core::RefCountedPtr request_metadata_creds, + const char* target_name, const char* overridden_target_name); + ~SpiffeChannelSecurityConnector() override; + + void add_handshakers(grpc_pollset_set* interested_parties, + grpc_core::HandshakeManager* handshake_mgr) override; + + void check_peer(tsi_peer peer, grpc_endpoint* ep, + grpc_core::RefCountedPtr* auth_context, + grpc_closure* on_peer_checked) override; + + int cmp(const grpc_security_connector* other_sc) const override; + + bool check_call_host(const char* host, grpc_auth_context* auth_context, + grpc_closure* on_call_host_checked, + grpc_error** error) override; + + void cancel_check_call_host(grpc_closure* on_call_host_checked, + grpc_error* error) override; + + private: + // Initialize SSL TSI client handshaker factory. + grpc_security_status InitializeHandshakerFactory( + tsi_ssl_session_cache* ssl_session_cache); + + // gRPC-provided callback executed by application, which servers to bring the + // control back to gRPC core. + static void ServerAuthorizationCheckDone( + grpc_tls_server_authorization_check_arg* arg); + + // A util function to process server authorization check result. + static grpc_error* ProcessServerAuthorizationCheckResult( + grpc_tls_server_authorization_check_arg* arg); + + // A util function to create a server authorization check arg instance. + static grpc_tls_server_authorization_check_arg* + ServerAuthorizationCheckArgCreate(void* user_data); + + // A util function to destroy a server authorization check arg instance. + static void ServerAuthorizationCheckArgDestroy( + grpc_tls_server_authorization_check_arg* arg); + + grpc_closure* on_peer_checked_; + char* target_name_; + char* overridden_target_name_; + tsi_ssl_client_handshaker_factory* client_handshaker_factory_ = nullptr; + grpc_tls_server_authorization_check_arg* check_arg_; +}; + +// Spiffe server security connector. +class SpiffeServerSecurityConnector final + : public grpc_server_security_connector { + public: + // static factory method to create a SPIFFE server security connector. + static grpc_core::RefCountedPtr + CreateSpiffeServerSecurityConnector( + grpc_core::RefCountedPtr server_creds); + + explicit SpiffeServerSecurityConnector( + grpc_core::RefCountedPtr server_creds); + ~SpiffeServerSecurityConnector() override; + + void add_handshakers(grpc_pollset_set* interested_parties, + grpc_core::HandshakeManager* handshake_mgr) override; + + void check_peer(tsi_peer peer, grpc_endpoint* ep, + grpc_core::RefCountedPtr* auth_context, + grpc_closure* on_peer_checked) override; + + int cmp(const grpc_security_connector* other) const override; + + private: + // A util function to refresh SSL TSI server handshaker factory with a valid + // credential. + grpc_security_status RefreshServerHandshakerFactory(); + tsi_ssl_server_handshaker_factory* server_handshaker_factory_ = nullptr; +}; + +#endif /* GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_TLS_SPIFFE_SECURITY_CONNECTOR_H \ + */ diff --git a/src/core/lib/security/transport/auth_filters.h b/src/core/lib/security/transport/auth_filters.h index af2104cfbcd..16a8e58ed9a 100644 --- a/src/core/lib/security/transport/auth_filters.h +++ b/src/core/lib/security/transport/auth_filters.h @@ -28,8 +28,8 @@ extern const grpc_channel_filter grpc_client_auth_filter; extern const grpc_channel_filter grpc_server_auth_filter; void grpc_auth_metadata_context_build( - const char* url_scheme, grpc_slice call_host, grpc_slice call_method, - grpc_auth_context* auth_context, + const char* url_scheme, const grpc_slice& call_host, + const grpc_slice& call_method, grpc_auth_context* auth_context, grpc_auth_metadata_context* auth_md_context); void grpc_auth_metadata_context_reset(grpc_auth_metadata_context* context); diff --git a/src/core/lib/security/transport/client_auth_filter.cc b/src/core/lib/security/transport/client_auth_filter.cc index 6955e8698e2..0c40dd7ff1e 100644 --- a/src/core/lib/security/transport/client_auth_filter.cc +++ b/src/core/lib/security/transport/client_auth_filter.cc @@ -41,12 +41,42 @@ #define MAX_CREDENTIALS_METADATA_COUNT 4 namespace { + +/* We can have a per-channel credentials. */ +struct channel_data { + channel_data(grpc_channel_security_connector* security_connector, + grpc_auth_context* auth_context) + : security_connector( + security_connector->Ref(DEBUG_LOCATION, "client_auth_filter")), + auth_context(auth_context->Ref(DEBUG_LOCATION, "client_auth_filter")) {} + ~channel_data() { + security_connector.reset(DEBUG_LOCATION, "client_auth_filter"); + auth_context.reset(DEBUG_LOCATION, "client_auth_filter"); + } + + grpc_core::RefCountedPtr security_connector; + grpc_core::RefCountedPtr auth_context; +}; + /* We can have a per-call credentials. */ struct call_data { call_data(grpc_call_element* elem, const grpc_call_element_args& args) - : arena(args.arena), - owning_call(args.call_stack), - call_combiner(args.call_combiner) {} + : owning_call(args.call_stack), call_combiner(args.call_combiner) { + channel_data* chand = static_cast(elem->channel_data); + GPR_ASSERT(args.context != nullptr); + if (args.context[GRPC_CONTEXT_SECURITY].value == nullptr) { + args.context[GRPC_CONTEXT_SECURITY].value = + grpc_client_security_context_create(args.arena, /*creds=*/nullptr); + args.context[GRPC_CONTEXT_SECURITY].destroy = + grpc_client_security_context_destroy; + } + grpc_client_security_context* sec_ctx = + static_cast( + args.context[GRPC_CONTEXT_SECURITY].value); + sec_ctx->auth_context.reset(DEBUG_LOCATION, "client_auth_filter"); + sec_ctx->auth_context = + chand->auth_context->Ref(DEBUG_LOCATION, "client_auth_filter"); + } // This method is technically the dtor of this class. However, since // `get_request_metadata_cancel_closure` can run in parallel to @@ -55,16 +85,15 @@ struct call_data { // that the memory is not initialized. void destroy() { grpc_credentials_mdelem_array_destroy(&md_array); - grpc_call_credentials_unref(creds); + creds.reset(); grpc_slice_unref_internal(host); grpc_slice_unref_internal(method); grpc_auth_metadata_context_reset(&auth_md_context); } - gpr_arena* arena; grpc_call_stack* owning_call; - grpc_call_combiner* call_combiner; - grpc_call_credentials* creds = nullptr; + grpc_core::CallCombiner* call_combiner; + grpc_core::RefCountedPtr creds; grpc_slice host = grpc_empty_slice(); grpc_slice method = grpc_empty_slice(); /* pollset{_set} bound to this call; if we need to make external @@ -81,11 +110,6 @@ struct call_data { grpc_closure get_request_metadata_cancel_closure; }; -/* We can have a per-channel credentials. */ -struct channel_data { - grpc_channel_security_connector* security_connector; - grpc_auth_context* auth_context; -}; } // namespace void grpc_auth_metadata_context_reset( @@ -98,10 +122,11 @@ void grpc_auth_metadata_context_reset( gpr_free(const_cast(auth_md_context->method_name)); auth_md_context->method_name = nullptr; } - GRPC_AUTH_CONTEXT_UNREF( - (grpc_auth_context*)auth_md_context->channel_auth_context, - "grpc_auth_metadata_context"); - auth_md_context->channel_auth_context = nullptr; + if (auth_md_context->channel_auth_context != nullptr) { + const_cast(auth_md_context->channel_auth_context) + ->Unref(DEBUG_LOCATION, "grpc_auth_metadata_context"); + auth_md_context->channel_auth_context = nullptr; + } } static void add_error(grpc_error** combined, grpc_error* error) { @@ -144,8 +169,8 @@ static void on_credentials_metadata(void* arg, grpc_error* input_error) { } void grpc_auth_metadata_context_build( - const char* url_scheme, grpc_slice call_host, grpc_slice call_method, - grpc_auth_context* auth_context, + const char* url_scheme, const grpc_slice& call_host, + const grpc_slice& call_method, grpc_auth_context* auth_context, grpc_auth_metadata_context* auth_md_context) { char* service = grpc_slice_to_c_string(call_method); char* last_slash = strrchr(service, '/'); @@ -175,7 +200,10 @@ void grpc_auth_metadata_context_build( auth_md_context->service_url = service_url; auth_md_context->method_name = method_name; auth_md_context->channel_auth_context = - GRPC_AUTH_CONTEXT_REF(auth_context, "grpc_auth_metadata_context"); + auth_context == nullptr + ? nullptr + : auth_context->Ref(DEBUG_LOCATION, "grpc_auth_metadata_context") + .release(); gpr_free(service); gpr_free(host_and_port); } @@ -184,8 +212,8 @@ static void cancel_get_request_metadata(void* arg, grpc_error* error) { grpc_call_element* elem = static_cast(arg); call_data* calld = static_cast(elem->call_data); if (error != GRPC_ERROR_NONE) { - grpc_call_credentials_cancel_get_request_metadata( - calld->creds, &calld->md_array, GRPC_ERROR_REF(error)); + calld->creds->cancel_get_request_metadata(&calld->md_array, + GRPC_ERROR_REF(error)); } } @@ -197,7 +225,7 @@ static void send_security_metadata(grpc_call_element* elem, static_cast( batch->payload->context[GRPC_CONTEXT_SECURITY].value); grpc_call_credentials* channel_call_creds = - chand->security_connector->request_metadata_creds; + chand->security_connector->mutable_request_metadata_creds(); int call_creds_has_md = (ctx != nullptr) && (ctx->creds != nullptr); if (channel_call_creds == nullptr && !call_creds_has_md) { @@ -207,8 +235,9 @@ static void send_security_metadata(grpc_call_element* elem, } if (channel_call_creds != nullptr && call_creds_has_md) { - calld->creds = grpc_composite_call_credentials_create(channel_call_creds, - ctx->creds, nullptr); + calld->creds = grpc_core::RefCountedPtr( + grpc_composite_call_credentials_create(channel_call_creds, + ctx->creds.get(), nullptr)); if (calld->creds == nullptr) { grpc_transport_stream_op_batch_finish_with_failure( batch, @@ -220,32 +249,30 @@ static void send_security_metadata(grpc_call_element* elem, return; } } else { - calld->creds = grpc_call_credentials_ref( - call_creds_has_md ? ctx->creds : channel_call_creds); + calld->creds = + call_creds_has_md ? ctx->creds->Ref() : channel_call_creds->Ref(); } grpc_auth_metadata_context_build( - chand->security_connector->base.url_scheme, calld->host, calld->method, - chand->auth_context, &calld->auth_md_context); + chand->security_connector->url_scheme(), calld->host, calld->method, + chand->auth_context.get(), &calld->auth_md_context); GPR_ASSERT(calld->pollent != nullptr); GRPC_CALL_STACK_REF(calld->owning_call, "get_request_metadata"); GRPC_CLOSURE_INIT(&calld->async_result_closure, on_credentials_metadata, batch, grpc_schedule_on_exec_ctx); grpc_error* error = GRPC_ERROR_NONE; - if (grpc_call_credentials_get_request_metadata( - calld->creds, calld->pollent, calld->auth_md_context, - &calld->md_array, &calld->async_result_closure, &error)) { + if (calld->creds->get_request_metadata( + calld->pollent, calld->auth_md_context, &calld->md_array, + &calld->async_result_closure, &error)) { // Synchronous return; invoke on_credentials_metadata() directly. on_credentials_metadata(batch, error); GRPC_ERROR_UNREF(error); } else { // Async return; register cancellation closure with call combiner. - grpc_call_combiner_set_notify_on_cancel( - calld->call_combiner, - GRPC_CLOSURE_INIT(&calld->get_request_metadata_cancel_closure, - cancel_get_request_metadata, elem, - grpc_schedule_on_exec_ctx)); + calld->call_combiner->SetNotifyOnCancel(GRPC_CLOSURE_INIT( + &calld->get_request_metadata_cancel_closure, + cancel_get_request_metadata, elem, grpc_schedule_on_exec_ctx)); } } @@ -279,9 +306,8 @@ static void cancel_check_call_host(void* arg, grpc_error* error) { call_data* calld = static_cast(elem->call_data); channel_data* chand = static_cast(elem->channel_data); if (error != GRPC_ERROR_NONE) { - grpc_channel_security_connector_cancel_check_call_host( - chand->security_connector, &calld->async_result_closure, - GRPC_ERROR_REF(error)); + chand->security_connector->cancel_check_call_host( + &calld->async_result_closure, GRPC_ERROR_REF(error)); } } @@ -293,24 +319,6 @@ static void auth_start_transport_stream_op_batch( call_data* calld = static_cast(elem->call_data); channel_data* chand = static_cast(elem->channel_data); - if (!batch->cancel_stream) { - // TODO(hcaseyal): move this to init_call_elem once issue #15927 is - // resolved. - GPR_ASSERT(batch->payload->context != nullptr); - if (batch->payload->context[GRPC_CONTEXT_SECURITY].value == nullptr) { - batch->payload->context[GRPC_CONTEXT_SECURITY].value = - grpc_client_security_context_create(calld->arena); - batch->payload->context[GRPC_CONTEXT_SECURITY].destroy = - grpc_client_security_context_destroy; - } - grpc_client_security_context* sec_ctx = - static_cast( - batch->payload->context[GRPC_CONTEXT_SECURITY].value); - GRPC_AUTH_CONTEXT_UNREF(sec_ctx->auth_context, "client auth filter"); - sec_ctx->auth_context = - GRPC_AUTH_CONTEXT_REF(chand->auth_context, "client_auth_filter"); - } - if (batch->send_initial_metadata) { grpc_metadata_batch* metadata = batch->payload->send_initial_metadata.send_initial_metadata; @@ -327,19 +335,17 @@ static void auth_start_transport_stream_op_batch( grpc_schedule_on_exec_ctx); char* call_host = grpc_slice_to_c_string(calld->host); grpc_error* error = GRPC_ERROR_NONE; - if (grpc_channel_security_connector_check_call_host( - chand->security_connector, call_host, chand->auth_context, + if (chand->security_connector->check_call_host( + call_host, chand->auth_context.get(), &calld->async_result_closure, &error)) { // Synchronous return; invoke on_host_checked() directly. on_host_checked(batch, error); GRPC_ERROR_UNREF(error); } else { // Async return; register cancellation closure with call combiner. - grpc_call_combiner_set_notify_on_cancel( - calld->call_combiner, - GRPC_CLOSURE_INIT(&calld->check_call_host_cancel_closure, - cancel_check_call_host, elem, - grpc_schedule_on_exec_ctx)); + calld->call_combiner->SetNotifyOnCancel(GRPC_CLOSURE_INIT( + &calld->check_call_host_cancel_closure, cancel_check_call_host, + elem, grpc_schedule_on_exec_ctx)); } gpr_free(call_host); return; /* early exit */ @@ -374,6 +380,10 @@ static void destroy_call_elem(grpc_call_element* elem, /* Constructor for channel_data */ static grpc_error* init_channel_elem(grpc_channel_element* elem, grpc_channel_element_args* args) { + /* The first and the last filters tend to be implemented differently to + handle the case that there's no 'next' filter to call on the up or down + path */ + GPR_ASSERT(!args->is_last); grpc_security_connector* sc = grpc_security_connector_find_in_args(args->channel_args); if (sc == nullptr) { @@ -386,33 +396,15 @@ static grpc_error* init_channel_elem(grpc_channel_element* elem, return GRPC_ERROR_CREATE_FROM_STATIC_STRING( "Auth context missing from client auth filter args"); } - - /* grab pointers to our data from the channel element */ - channel_data* chand = static_cast(elem->channel_data); - - /* The first and the last filters tend to be implemented differently to - handle the case that there's no 'next' filter to call on the up or down - path */ - GPR_ASSERT(!args->is_last); - - /* initialize members */ - chand->security_connector = - reinterpret_cast( - GRPC_SECURITY_CONNECTOR_REF(sc, "client_auth_filter")); - chand->auth_context = - GRPC_AUTH_CONTEXT_REF(auth_context, "client_auth_filter"); + new (elem->channel_data) channel_data( + static_cast(sc), auth_context); return GRPC_ERROR_NONE; } /* Destructor for channel data */ static void destroy_channel_elem(grpc_channel_element* elem) { - /* grab pointers to our data from the channel element */ channel_data* chand = static_cast(elem->channel_data); - grpc_channel_security_connector* sc = chand->security_connector; - if (sc != nullptr) { - GRPC_SECURITY_CONNECTOR_UNREF(&sc->base, "client_auth_filter"); - } - GRPC_AUTH_CONTEXT_UNREF(chand->auth_context, "client_auth_filter"); + chand->~channel_data(); } const grpc_channel_filter grpc_client_auth_filter = { diff --git a/src/core/lib/security/transport/secure_endpoint.cc b/src/core/lib/security/transport/secure_endpoint.cc index 34d8435907f..0aac7d8d780 100644 --- a/src/core/lib/security/transport/secure_endpoint.cc +++ b/src/core/lib/security/transport/secure_endpoint.cc @@ -113,7 +113,7 @@ static void destroy(secure_endpoint* ep) { grpc_core::Delete(ep); } secure_endpoint_ref((ep), (reason), __FILE__, __LINE__) static void secure_endpoint_unref(secure_endpoint* ep, const char* reason, const char* file, int line) { - if (grpc_trace_secure_endpoint.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_trace_secure_endpoint)) { gpr_atm val = gpr_atm_no_barrier_load(&ep->ref.count); gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "SECENDP unref %p : %s %" PRIdPTR " -> %" PRIdPTR, ep, reason, val, @@ -126,7 +126,7 @@ static void secure_endpoint_unref(secure_endpoint* ep, const char* reason, static void secure_endpoint_ref(secure_endpoint* ep, const char* reason, const char* file, int line) { - if (grpc_trace_secure_endpoint.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_trace_secure_endpoint)) { gpr_atm val = gpr_atm_no_barrier_load(&ep->ref.count); gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "SECENDP ref %p : %s %" PRIdPTR " -> %" PRIdPTR, ep, reason, val, @@ -155,7 +155,7 @@ static void flush_read_staging_buffer(secure_endpoint* ep, uint8_t** cur, } static void call_read_cb(secure_endpoint* ep, grpc_error* error) { - if (grpc_trace_secure_endpoint.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_trace_secure_endpoint)) { size_t i; for (i = 0; i < ep->read_buffer->count; i++) { char* data = grpc_dump_slice(ep->read_buffer->slices[i], @@ -255,7 +255,7 @@ static void on_read(void* user_data, grpc_error* error) { } static void endpoint_read(grpc_endpoint* secure_ep, grpc_slice_buffer* slices, - grpc_closure* cb) { + grpc_closure* cb, bool urgent) { secure_endpoint* ep = reinterpret_cast(secure_ep); ep->read_cb = cb; ep->read_buffer = slices; @@ -269,7 +269,7 @@ static void endpoint_read(grpc_endpoint* secure_ep, grpc_slice_buffer* slices, return; } - grpc_endpoint_read(ep->wrapped_ep, &ep->source_buffer, &ep->on_read); + grpc_endpoint_read(ep->wrapped_ep, &ep->source_buffer, &ep->on_read, urgent); } static void flush_write_staging_buffer(secure_endpoint* ep, uint8_t** cur, @@ -292,7 +292,7 @@ static void endpoint_write(grpc_endpoint* secure_ep, grpc_slice_buffer* slices, grpc_slice_buffer_reset_and_unref_internal(&ep->output_buffer); - if (grpc_trace_secure_endpoint.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_trace_secure_endpoint)) { for (i = 0; i < slices->count; i++) { char* data = grpc_dump_slice(slices->slices[i], GPR_DUMP_HEX | GPR_DUMP_ASCII); @@ -416,6 +416,11 @@ static grpc_resource_user* endpoint_get_resource_user( return grpc_endpoint_get_resource_user(ep->wrapped_ep); } +static bool endpoint_can_track_err(grpc_endpoint* secure_ep) { + secure_endpoint* ep = reinterpret_cast(secure_ep); + return grpc_endpoint_can_track_err(ep->wrapped_ep); +} + static const grpc_endpoint_vtable vtable = {endpoint_read, endpoint_write, endpoint_add_to_pollset, @@ -425,7 +430,8 @@ static const grpc_endpoint_vtable vtable = {endpoint_read, endpoint_destroy, endpoint_get_resource_user, endpoint_get_peer, - endpoint_get_fd}; + endpoint_get_fd, + endpoint_can_track_err}; grpc_endpoint* grpc_secure_endpoint_create( struct tsi_frame_protector* protector, diff --git a/src/core/lib/security/transport/security_handshaker.cc b/src/core/lib/security/transport/security_handshaker.cc index 854a1c4af97..fdc64727b96 100644 --- a/src/core/lib/security/transport/security_handshaker.cc +++ b/src/core/lib/security/transport/security_handshaker.cc @@ -30,6 +30,7 @@ #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/handshaker.h" #include "src/core/lib/channel/handshaker_registry.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/security/context/security_context.h" #include "src/core/lib/security/transport/secure_endpoint.h" #include "src/core/lib/security/transport/tsi_error.h" @@ -38,88 +39,134 @@ #define GRPC_INITIAL_HANDSHAKE_BUFFER_SIZE 256 -typedef struct { - grpc_handshaker base; +namespace grpc_core { + +namespace { + +class SecurityHandshaker : public Handshaker { + public: + SecurityHandshaker(tsi_handshaker* handshaker, + grpc_security_connector* connector); + ~SecurityHandshaker() override; + void Shutdown(grpc_error* why) override; + void DoHandshake(grpc_tcp_server_acceptor* acceptor, + grpc_closure* on_handshake_done, + HandshakerArgs* args) override; + const char* name() const override { return "security"; } + + private: + grpc_error* DoHandshakerNextLocked(const unsigned char* bytes_received, + size_t bytes_received_size); + + grpc_error* OnHandshakeNextDoneLocked( + tsi_result result, const unsigned char* bytes_to_send, + size_t bytes_to_send_size, tsi_handshaker_result* handshaker_result); + void HandshakeFailedLocked(grpc_error* error); + void CleanupArgsForFailureLocked(); + + static void OnHandshakeDataReceivedFromPeerFn(void* arg, grpc_error* error); + static void OnHandshakeDataSentToPeerFn(void* arg, grpc_error* error); + static void OnHandshakeNextDoneGrpcWrapper( + tsi_result result, void* user_data, const unsigned char* bytes_to_send, + size_t bytes_to_send_size, tsi_handshaker_result* handshaker_result); + static void OnPeerCheckedFn(void* arg, grpc_error* error); + void OnPeerCheckedInner(grpc_error* error); + size_t MoveReadBufferIntoHandshakeBuffer(); + grpc_error* CheckPeerLocked(); // State set at creation time. - tsi_handshaker* handshaker; - grpc_security_connector* connector; + tsi_handshaker* handshaker_; + RefCountedPtr connector_; - gpr_mu mu; - gpr_refcount refs; + gpr_mu mu_; - bool shutdown; + bool is_shutdown_ = false; // Endpoint and read buffer to destroy after a shutdown. - grpc_endpoint* endpoint_to_destroy; - grpc_slice_buffer* read_buffer_to_destroy; + grpc_endpoint* endpoint_to_destroy_ = nullptr; + grpc_slice_buffer* read_buffer_to_destroy_ = nullptr; // State saved while performing the handshake. - grpc_handshaker_args* args; - grpc_closure* on_handshake_done; + HandshakerArgs* args_ = nullptr; + grpc_closure* on_handshake_done_ = nullptr; - unsigned char* handshake_buffer; - size_t handshake_buffer_size; - grpc_slice_buffer outgoing; - grpc_closure on_handshake_data_sent_to_peer; - grpc_closure on_handshake_data_received_from_peer; - grpc_closure on_peer_checked; - grpc_auth_context* auth_context; - tsi_handshaker_result* handshaker_result; -} security_handshaker; + size_t handshake_buffer_size_; + unsigned char* handshake_buffer_; + grpc_slice_buffer outgoing_; + grpc_closure on_handshake_data_sent_to_peer_; + grpc_closure on_handshake_data_received_from_peer_; + grpc_closure on_peer_checked_; + RefCountedPtr auth_context_; + tsi_handshaker_result* handshaker_result_ = nullptr; +}; -static size_t move_read_buffer_into_handshake_buffer(security_handshaker* h) { - size_t bytes_in_read_buffer = h->args->read_buffer->length; - if (h->handshake_buffer_size < bytes_in_read_buffer) { - h->handshake_buffer = static_cast( - gpr_realloc(h->handshake_buffer, bytes_in_read_buffer)); - h->handshake_buffer_size = bytes_in_read_buffer; +SecurityHandshaker::SecurityHandshaker(tsi_handshaker* handshaker, + grpc_security_connector* connector) + : handshaker_(handshaker), + connector_(connector->Ref(DEBUG_LOCATION, "handshake")), + handshake_buffer_size_(GRPC_INITIAL_HANDSHAKE_BUFFER_SIZE), + handshake_buffer_( + static_cast(gpr_malloc(handshake_buffer_size_))) { + gpr_mu_init(&mu_); + grpc_slice_buffer_init(&outgoing_); + GRPC_CLOSURE_INIT(&on_handshake_data_sent_to_peer_, + &SecurityHandshaker::OnHandshakeDataSentToPeerFn, this, + grpc_schedule_on_exec_ctx); + GRPC_CLOSURE_INIT(&on_handshake_data_received_from_peer_, + &SecurityHandshaker::OnHandshakeDataReceivedFromPeerFn, + this, grpc_schedule_on_exec_ctx); + GRPC_CLOSURE_INIT(&on_peer_checked_, &SecurityHandshaker::OnPeerCheckedFn, + this, grpc_schedule_on_exec_ctx); +} + +SecurityHandshaker::~SecurityHandshaker() { + gpr_mu_destroy(&mu_); + tsi_handshaker_destroy(handshaker_); + tsi_handshaker_result_destroy(handshaker_result_); + if (endpoint_to_destroy_ != nullptr) { + grpc_endpoint_destroy(endpoint_to_destroy_); + } + if (read_buffer_to_destroy_ != nullptr) { + grpc_slice_buffer_destroy_internal(read_buffer_to_destroy_); + gpr_free(read_buffer_to_destroy_); + } + gpr_free(handshake_buffer_); + grpc_slice_buffer_destroy_internal(&outgoing_); + auth_context_.reset(DEBUG_LOCATION, "handshake"); + connector_.reset(DEBUG_LOCATION, "handshake"); +} + +size_t SecurityHandshaker::MoveReadBufferIntoHandshakeBuffer() { + size_t bytes_in_read_buffer = args_->read_buffer->length; + if (handshake_buffer_size_ < bytes_in_read_buffer) { + handshake_buffer_ = static_cast( + gpr_realloc(handshake_buffer_, bytes_in_read_buffer)); + handshake_buffer_size_ = bytes_in_read_buffer; } size_t offset = 0; - while (h->args->read_buffer->count > 0) { - grpc_slice next_slice = grpc_slice_buffer_take_first(h->args->read_buffer); - memcpy(h->handshake_buffer + offset, GRPC_SLICE_START_PTR(next_slice), - GRPC_SLICE_LENGTH(next_slice)); - offset += GRPC_SLICE_LENGTH(next_slice); - grpc_slice_unref_internal(next_slice); + while (args_->read_buffer->count > 0) { + grpc_slice* next_slice = grpc_slice_buffer_peek_first(args_->read_buffer); + memcpy(handshake_buffer_ + offset, GRPC_SLICE_START_PTR(*next_slice), + GRPC_SLICE_LENGTH(*next_slice)); + offset += GRPC_SLICE_LENGTH(*next_slice); + grpc_slice_buffer_remove_first(args_->read_buffer); } return bytes_in_read_buffer; } -static void security_handshaker_unref(security_handshaker* h) { - if (gpr_unref(&h->refs)) { - gpr_mu_destroy(&h->mu); - tsi_handshaker_destroy(h->handshaker); - tsi_handshaker_result_destroy(h->handshaker_result); - if (h->endpoint_to_destroy != nullptr) { - grpc_endpoint_destroy(h->endpoint_to_destroy); - } - if (h->read_buffer_to_destroy != nullptr) { - grpc_slice_buffer_destroy_internal(h->read_buffer_to_destroy); - gpr_free(h->read_buffer_to_destroy); - } - gpr_free(h->handshake_buffer); - grpc_slice_buffer_destroy_internal(&h->outgoing); - GRPC_AUTH_CONTEXT_UNREF(h->auth_context, "handshake"); - GRPC_SECURITY_CONNECTOR_UNREF(h->connector, "handshake"); - gpr_free(h); - } -} - -// Set args fields to NULL, saving the endpoint and read buffer for +// Set args_ fields to NULL, saving the endpoint and read buffer for // later destruction. -static void cleanup_args_for_failure_locked(security_handshaker* h) { - h->endpoint_to_destroy = h->args->endpoint; - h->args->endpoint = nullptr; - h->read_buffer_to_destroy = h->args->read_buffer; - h->args->read_buffer = nullptr; - grpc_channel_args_destroy(h->args->args); - h->args->args = nullptr; +void SecurityHandshaker::CleanupArgsForFailureLocked() { + endpoint_to_destroy_ = args_->endpoint; + args_->endpoint = nullptr; + read_buffer_to_destroy_ = args_->read_buffer; + args_->read_buffer = nullptr; + grpc_channel_args_destroy(args_->args); + args_->args = nullptr; } // If the handshake failed or we're shutting down, clean up and invoke the // callback with the error. -static void security_handshake_failed_locked(security_handshaker* h, - grpc_error* error) { +void SecurityHandshaker::HandshakeFailedLocked(grpc_error* error) { if (error == GRPC_ERROR_NONE) { // If we were shut down after the handshake succeeded but before an // endpoint callback was invoked, we need to generate our own error. @@ -128,50 +175,51 @@ static void security_handshake_failed_locked(security_handshaker* h, const char* msg = grpc_error_string(error); gpr_log(GPR_DEBUG, "Security handshake failed: %s", msg); - if (!h->shutdown) { + if (!is_shutdown_) { // TODO(ctiller): It is currently necessary to shutdown endpoints // before destroying them, even if we know that there are no // pending read/write callbacks. This should be fixed, at which // point this can be removed. - grpc_endpoint_shutdown(h->args->endpoint, GRPC_ERROR_REF(error)); + grpc_endpoint_shutdown(args_->endpoint, GRPC_ERROR_REF(error)); // Not shutting down, so the write failed. Clean up before // invoking the callback. - cleanup_args_for_failure_locked(h); + CleanupArgsForFailureLocked(); // Set shutdown to true so that subsequent calls to // security_handshaker_shutdown() do nothing. - h->shutdown = true; + is_shutdown_ = true; } // Invoke callback. - GRPC_CLOSURE_SCHED(h->on_handshake_done, error); + GRPC_CLOSURE_SCHED(on_handshake_done_, error); } -static void on_peer_checked_inner(security_handshaker* h, grpc_error* error) { - if (error != GRPC_ERROR_NONE || h->shutdown) { - security_handshake_failed_locked(h, GRPC_ERROR_REF(error)); +void SecurityHandshaker::OnPeerCheckedInner(grpc_error* error) { + MutexLock lock(&mu_); + if (error != GRPC_ERROR_NONE || is_shutdown_) { + HandshakeFailedLocked(GRPC_ERROR_REF(error)); return; } // Create zero-copy frame protector, if implemented. tsi_zero_copy_grpc_protector* zero_copy_protector = nullptr; tsi_result result = tsi_handshaker_result_create_zero_copy_grpc_protector( - h->handshaker_result, nullptr, &zero_copy_protector); + handshaker_result_, nullptr, &zero_copy_protector); if (result != TSI_OK && result != TSI_UNIMPLEMENTED) { error = grpc_set_tsi_error_result( GRPC_ERROR_CREATE_FROM_STATIC_STRING( "Zero-copy frame protector creation failed"), result); - security_handshake_failed_locked(h, error); + HandshakeFailedLocked(error); return; } // Create frame protector if zero-copy frame protector is NULL. tsi_frame_protector* protector = nullptr; if (zero_copy_protector == nullptr) { - result = tsi_handshaker_result_create_frame_protector(h->handshaker_result, + result = tsi_handshaker_result_create_frame_protector(handshaker_result_, nullptr, &protector); if (result != TSI_OK) { error = grpc_set_tsi_error_result(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "Frame protector creation failed"), result); - security_handshake_failed_locked(h, error); + HandshakeFailedLocked(error); return; } } @@ -179,68 +227,63 @@ static void on_peer_checked_inner(security_handshaker* h, grpc_error* error) { const unsigned char* unused_bytes = nullptr; size_t unused_bytes_size = 0; result = tsi_handshaker_result_get_unused_bytes( - h->handshaker_result, &unused_bytes, &unused_bytes_size); + handshaker_result_, &unused_bytes, &unused_bytes_size); // Create secure endpoint. if (unused_bytes_size > 0) { grpc_slice slice = grpc_slice_from_copied_buffer((char*)unused_bytes, unused_bytes_size); - h->args->endpoint = grpc_secure_endpoint_create( - protector, zero_copy_protector, h->args->endpoint, &slice, 1); + args_->endpoint = grpc_secure_endpoint_create( + protector, zero_copy_protector, args_->endpoint, &slice, 1); grpc_slice_unref_internal(slice); } else { - h->args->endpoint = grpc_secure_endpoint_create( - protector, zero_copy_protector, h->args->endpoint, nullptr, 0); + args_->endpoint = grpc_secure_endpoint_create( + protector, zero_copy_protector, args_->endpoint, nullptr, 0); } - tsi_handshaker_result_destroy(h->handshaker_result); - h->handshaker_result = nullptr; + tsi_handshaker_result_destroy(handshaker_result_); + handshaker_result_ = nullptr; // Add auth context to channel args. - grpc_arg auth_context_arg = grpc_auth_context_to_arg(h->auth_context); - grpc_channel_args* tmp_args = h->args->args; - h->args->args = - grpc_channel_args_copy_and_add(tmp_args, &auth_context_arg, 1); + grpc_arg auth_context_arg = grpc_auth_context_to_arg(auth_context_.get()); + grpc_channel_args* tmp_args = args_->args; + args_->args = grpc_channel_args_copy_and_add(tmp_args, &auth_context_arg, 1); grpc_channel_args_destroy(tmp_args); // Invoke callback. - GRPC_CLOSURE_SCHED(h->on_handshake_done, GRPC_ERROR_NONE); + GRPC_CLOSURE_SCHED(on_handshake_done_, GRPC_ERROR_NONE); // Set shutdown to true so that subsequent calls to // security_handshaker_shutdown() do nothing. - h->shutdown = true; + is_shutdown_ = true; } -static void on_peer_checked(void* arg, grpc_error* error) { - security_handshaker* h = static_cast(arg); - gpr_mu_lock(&h->mu); - on_peer_checked_inner(h, error); - gpr_mu_unlock(&h->mu); - security_handshaker_unref(h); +void SecurityHandshaker::OnPeerCheckedFn(void* arg, grpc_error* error) { + RefCountedPtr(static_cast(arg)) + ->OnPeerCheckedInner(error); } -static grpc_error* check_peer_locked(security_handshaker* h) { +grpc_error* SecurityHandshaker::CheckPeerLocked() { tsi_peer peer; tsi_result result = - tsi_handshaker_result_extract_peer(h->handshaker_result, &peer); + tsi_handshaker_result_extract_peer(handshaker_result_, &peer); if (result != TSI_OK) { return grpc_set_tsi_error_result( GRPC_ERROR_CREATE_FROM_STATIC_STRING("Peer extraction failed"), result); } - grpc_security_connector_check_peer(h->connector, peer, &h->auth_context, - &h->on_peer_checked); + connector_->check_peer(peer, args_->endpoint, &auth_context_, + &on_peer_checked_); return GRPC_ERROR_NONE; } -static grpc_error* on_handshake_next_done_locked( - security_handshaker* h, tsi_result result, - const unsigned char* bytes_to_send, size_t bytes_to_send_size, - tsi_handshaker_result* handshaker_result) { +grpc_error* SecurityHandshaker::OnHandshakeNextDoneLocked( + tsi_result result, 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) { + if (is_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); - grpc_endpoint_read(h->args->endpoint, h->args->read_buffer, - &h->on_handshake_data_received_from_peer); + grpc_endpoint_read(args_->endpoint, args_->read_buffer, + &on_handshake_data_received_from_peer_, /*urgent=*/true); return error; } if (result != TSI_OK) { @@ -249,55 +292,52 @@ static grpc_error* on_handshake_next_done_locked( } // Update handshaker result. if (handshaker_result != nullptr) { - GPR_ASSERT(h->handshaker_result == nullptr); - h->handshaker_result = handshaker_result; + GPR_ASSERT(handshaker_result_ == nullptr); + handshaker_result_ = handshaker_result; } if (bytes_to_send_size > 0) { // Send data to peer, if needed. grpc_slice to_send = grpc_slice_from_copied_buffer( reinterpret_cast(bytes_to_send), bytes_to_send_size); - grpc_slice_buffer_reset_and_unref_internal(&h->outgoing); - grpc_slice_buffer_add(&h->outgoing, to_send); - grpc_endpoint_write(h->args->endpoint, &h->outgoing, - &h->on_handshake_data_sent_to_peer, nullptr); + grpc_slice_buffer_reset_and_unref_internal(&outgoing_); + grpc_slice_buffer_add(&outgoing_, to_send); + grpc_endpoint_write(args_->endpoint, &outgoing_, + &on_handshake_data_sent_to_peer_, nullptr); } else if (handshaker_result == nullptr) { // There is nothing to send, but need to read from peer. - grpc_endpoint_read(h->args->endpoint, h->args->read_buffer, - &h->on_handshake_data_received_from_peer); + grpc_endpoint_read(args_->endpoint, args_->read_buffer, + &on_handshake_data_received_from_peer_, /*urgent=*/true); } else { // Handshake has finished, check peer and so on. - error = check_peer_locked(h); + error = CheckPeerLocked(); } return error; } -static void on_handshake_next_done_grpc_wrapper( +void SecurityHandshaker::OnHandshakeNextDoneGrpcWrapper( tsi_result result, void* user_data, const unsigned char* bytes_to_send, size_t bytes_to_send_size, tsi_handshaker_result* handshaker_result) { - security_handshaker* h = static_cast(user_data); - gpr_mu_lock(&h->mu); - grpc_error* error = on_handshake_next_done_locked( - h, result, bytes_to_send, bytes_to_send_size, handshaker_result); + RefCountedPtr h( + static_cast(user_data)); + MutexLock lock(&h->mu_); + grpc_error* error = h->OnHandshakeNextDoneLocked( + result, bytes_to_send, bytes_to_send_size, handshaker_result); if (error != GRPC_ERROR_NONE) { - security_handshake_failed_locked(h, error); - gpr_mu_unlock(&h->mu); - security_handshaker_unref(h); + h->HandshakeFailedLocked(error); } else { - gpr_mu_unlock(&h->mu); + h.release(); // Avoid unref } } -static grpc_error* do_handshaker_next_locked( - security_handshaker* h, const unsigned char* bytes_received, - size_t bytes_received_size) { +grpc_error* SecurityHandshaker::DoHandshakerNextLocked( + const unsigned char* bytes_received, size_t bytes_received_size) { // Invoke TSI handshaker. const unsigned char* bytes_to_send = nullptr; size_t bytes_to_send_size = 0; - tsi_handshaker_result* handshaker_result = nullptr; + tsi_handshaker_result* hs_result = nullptr; tsi_result result = tsi_handshaker_next( - h->handshaker, bytes_received, bytes_received_size, &bytes_to_send, - &bytes_to_send_size, &handshaker_result, - &on_handshake_next_done_grpc_wrapper, h); + handshaker_, bytes_received, bytes_received_size, &bytes_to_send, + &bytes_to_send_size, &hs_result, &OnHandshakeNextDoneGrpcWrapper, this); if (result == TSI_ASYNC) { // Handshaker operating asynchronously. Nothing else to do here; // callback will be invoked in a TSI thread. @@ -305,226 +345,170 @@ static grpc_error* do_handshaker_next_locked( } // Handshaker returned synchronously. Invoke callback directly in // this thread with our existing exec_ctx. - return on_handshake_next_done_locked(h, result, bytes_to_send, - bytes_to_send_size, handshaker_result); + return OnHandshakeNextDoneLocked(result, bytes_to_send, bytes_to_send_size, + hs_result); } -static void on_handshake_data_received_from_peer(void* arg, grpc_error* error) { - security_handshaker* h = static_cast(arg); - gpr_mu_lock(&h->mu); - if (error != GRPC_ERROR_NONE || h->shutdown) { - security_handshake_failed_locked( - h, GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Handshake read failed", &error, 1)); - gpr_mu_unlock(&h->mu); - security_handshaker_unref(h); +void SecurityHandshaker::OnHandshakeDataReceivedFromPeerFn(void* arg, + grpc_error* error) { + RefCountedPtr h(static_cast(arg)); + MutexLock lock(&h->mu_); + if (error != GRPC_ERROR_NONE || h->is_shutdown_) { + h->HandshakeFailedLocked(GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + "Handshake read failed", &error, 1)); return; } // Copy all slices received. - size_t bytes_received_size = move_read_buffer_into_handshake_buffer(h); + size_t bytes_received_size = h->MoveReadBufferIntoHandshakeBuffer(); // Call TSI handshaker. - error = - do_handshaker_next_locked(h, h->handshake_buffer, bytes_received_size); + error = h->DoHandshakerNextLocked(h->handshake_buffer_, bytes_received_size); if (error != GRPC_ERROR_NONE) { - security_handshake_failed_locked(h, error); - gpr_mu_unlock(&h->mu); - security_handshaker_unref(h); + h->HandshakeFailedLocked(error); } else { - gpr_mu_unlock(&h->mu); + h.release(); // Avoid unref } } -static void on_handshake_data_sent_to_peer(void* arg, grpc_error* error) { - security_handshaker* h = static_cast(arg); - gpr_mu_lock(&h->mu); - if (error != GRPC_ERROR_NONE || h->shutdown) { - security_handshake_failed_locked( - h, GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Handshake write failed", &error, 1)); - gpr_mu_unlock(&h->mu); - security_handshaker_unref(h); +void SecurityHandshaker::OnHandshakeDataSentToPeerFn(void* arg, + grpc_error* error) { + RefCountedPtr h(static_cast(arg)); + MutexLock lock(&h->mu_); + if (error != GRPC_ERROR_NONE || h->is_shutdown_) { + h->HandshakeFailedLocked(GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + "Handshake write failed", &error, 1)); return; } // We may be done. - if (h->handshaker_result == nullptr) { - grpc_endpoint_read(h->args->endpoint, h->args->read_buffer, - &h->on_handshake_data_received_from_peer); + if (h->handshaker_result_ == nullptr) { + grpc_endpoint_read(h->args_->endpoint, h->args_->read_buffer, + &h->on_handshake_data_received_from_peer_, + /*urgent=*/true); } else { - error = check_peer_locked(h); + error = h->CheckPeerLocked(); if (error != GRPC_ERROR_NONE) { - security_handshake_failed_locked(h, error); - gpr_mu_unlock(&h->mu); - security_handshaker_unref(h); + h->HandshakeFailedLocked(error); return; } } - gpr_mu_unlock(&h->mu); + h.release(); // Avoid unref } // // public handshaker API // -static void security_handshaker_destroy(grpc_handshaker* handshaker) { - security_handshaker* h = reinterpret_cast(handshaker); - security_handshaker_unref(h); -} - -static void security_handshaker_shutdown(grpc_handshaker* handshaker, - grpc_error* why) { - security_handshaker* h = reinterpret_cast(handshaker); - 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); +void SecurityHandshaker::Shutdown(grpc_error* why) { + MutexLock lock(&mu_); + if (!is_shutdown_) { + is_shutdown_ = true; + tsi_handshaker_shutdown(handshaker_); + grpc_endpoint_shutdown(args_->endpoint, GRPC_ERROR_REF(why)); + CleanupArgsForFailureLocked(); } - gpr_mu_unlock(&h->mu); GRPC_ERROR_UNREF(why); } -static void security_handshaker_do_handshake(grpc_handshaker* handshaker, - grpc_tcp_server_acceptor* acceptor, - grpc_closure* on_handshake_done, - grpc_handshaker_args* args) { - security_handshaker* h = reinterpret_cast(handshaker); - gpr_mu_lock(&h->mu); - h->args = args; - h->on_handshake_done = on_handshake_done; - gpr_ref(&h->refs); - size_t bytes_received_size = move_read_buffer_into_handshake_buffer(h); +void SecurityHandshaker::DoHandshake(grpc_tcp_server_acceptor* acceptor, + grpc_closure* on_handshake_done, + HandshakerArgs* args) { + auto ref = Ref(); + MutexLock lock(&mu_); + args_ = args; + on_handshake_done_ = on_handshake_done; + size_t bytes_received_size = MoveReadBufferIntoHandshakeBuffer(); grpc_error* error = - do_handshaker_next_locked(h, h->handshake_buffer, bytes_received_size); + DoHandshakerNextLocked(handshake_buffer_, bytes_received_size); if (error != GRPC_ERROR_NONE) { - security_handshake_failed_locked(h, error); - gpr_mu_unlock(&h->mu); - security_handshaker_unref(h); - return; + HandshakeFailedLocked(error); + } else { + ref.release(); // Avoid unref } - gpr_mu_unlock(&h->mu); -} - -static const grpc_handshaker_vtable security_handshaker_vtable = { - security_handshaker_destroy, security_handshaker_shutdown, - security_handshaker_do_handshake, "security"}; - -static grpc_handshaker* security_handshaker_create( - tsi_handshaker* handshaker, grpc_security_connector* connector) { - security_handshaker* h = static_cast( - gpr_zalloc(sizeof(security_handshaker))); - grpc_handshaker_init(&security_handshaker_vtable, &h->base); - h->handshaker = handshaker; - h->connector = GRPC_SECURITY_CONNECTOR_REF(connector, "handshake"); - gpr_mu_init(&h->mu); - gpr_ref_init(&h->refs, 1); - h->handshake_buffer_size = GRPC_INITIAL_HANDSHAKE_BUFFER_SIZE; - h->handshake_buffer = - static_cast(gpr_malloc(h->handshake_buffer_size)); - GRPC_CLOSURE_INIT(&h->on_handshake_data_sent_to_peer, - on_handshake_data_sent_to_peer, h, - grpc_schedule_on_exec_ctx); - GRPC_CLOSURE_INIT(&h->on_handshake_data_received_from_peer, - on_handshake_data_received_from_peer, h, - grpc_schedule_on_exec_ctx); - GRPC_CLOSURE_INIT(&h->on_peer_checked, on_peer_checked, h, - grpc_schedule_on_exec_ctx); - grpc_slice_buffer_init(&h->outgoing); - return &h->base; } // -// fail_handshaker +// FailHandshaker // -static void fail_handshaker_destroy(grpc_handshaker* handshaker) { - gpr_free(handshaker); -} +class FailHandshaker : public Handshaker { + public: + const char* name() const override { return "security_fail"; } + void Shutdown(grpc_error* why) override { GRPC_ERROR_UNREF(why); } + void DoHandshake(grpc_tcp_server_acceptor* acceptor, + grpc_closure* on_handshake_done, + HandshakerArgs* args) override { + GRPC_CLOSURE_SCHED(on_handshake_done, + GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Failed to create security handshaker")); + } -static void fail_handshaker_shutdown(grpc_handshaker* handshaker, - grpc_error* why) { - GRPC_ERROR_UNREF(why); -} - -static void fail_handshaker_do_handshake(grpc_handshaker* handshaker, - grpc_tcp_server_acceptor* acceptor, - grpc_closure* on_handshake_done, - grpc_handshaker_args* args) { - GRPC_CLOSURE_SCHED(on_handshake_done, - GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "Failed to create security handshaker")); -} - -static const grpc_handshaker_vtable fail_handshaker_vtable = { - fail_handshaker_destroy, fail_handshaker_shutdown, - fail_handshaker_do_handshake, "security_fail"}; - -static grpc_handshaker* fail_handshaker_create() { - grpc_handshaker* h = static_cast(gpr_malloc(sizeof(*h))); - grpc_handshaker_init(&fail_handshaker_vtable, h); - return h; -} + private: + virtual ~FailHandshaker() = default; +}; // // handshaker factories // -static void client_handshaker_factory_add_handshakers( - grpc_handshaker_factory* handshaker_factory, const grpc_channel_args* args, - grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr) { - grpc_channel_security_connector* security_connector = - reinterpret_cast( - grpc_security_connector_find_in_args(args)); - grpc_channel_security_connector_add_handshakers( - security_connector, interested_parties, handshake_mgr); -} +class ClientSecurityHandshakerFactory : public HandshakerFactory { + public: + void AddHandshakers(const grpc_channel_args* args, + grpc_pollset_set* interested_parties, + HandshakeManager* handshake_mgr) override { + auto* security_connector = + reinterpret_cast( + grpc_security_connector_find_in_args(args)); + if (security_connector) { + security_connector->add_handshakers(interested_parties, handshake_mgr); + } + } + ~ClientSecurityHandshakerFactory() override = default; +}; -static void server_handshaker_factory_add_handshakers( - grpc_handshaker_factory* hf, const grpc_channel_args* args, - grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr) { - grpc_server_security_connector* security_connector = - reinterpret_cast( - grpc_security_connector_find_in_args(args)); - grpc_server_security_connector_add_handshakers( - security_connector, interested_parties, handshake_mgr); -} +class ServerSecurityHandshakerFactory : public HandshakerFactory { + public: + void AddHandshakers(const grpc_channel_args* args, + grpc_pollset_set* interested_parties, + HandshakeManager* handshake_mgr) override { + auto* security_connector = + reinterpret_cast( + grpc_security_connector_find_in_args(args)); + if (security_connector) { + security_connector->add_handshakers(interested_parties, handshake_mgr); + } + } + ~ServerSecurityHandshakerFactory() override = default; +}; -static void handshaker_factory_destroy( - grpc_handshaker_factory* handshaker_factory) {} - -static const grpc_handshaker_factory_vtable client_handshaker_factory_vtable = { - client_handshaker_factory_add_handshakers, handshaker_factory_destroy}; - -static grpc_handshaker_factory client_handshaker_factory = { - &client_handshaker_factory_vtable}; - -static const grpc_handshaker_factory_vtable server_handshaker_factory_vtable = { - server_handshaker_factory_add_handshakers, handshaker_factory_destroy}; - -static grpc_handshaker_factory server_handshaker_factory = { - &server_handshaker_factory_vtable}; +} // namespace // // exported functions // -grpc_handshaker* grpc_security_handshaker_create( +RefCountedPtr SecurityHandshakerCreate( tsi_handshaker* handshaker, grpc_security_connector* connector) { // If no TSI handshaker was created, return a handshaker that always fails. // Otherwise, return a real security handshaker. if (handshaker == nullptr) { - return fail_handshaker_create(); + return MakeRefCounted(); } else { - return security_handshaker_create(handshaker, connector); + return MakeRefCounted(handshaker, connector); } } -void grpc_security_register_handshaker_factories() { - grpc_handshaker_factory_register(false /* at_start */, HANDSHAKER_CLIENT, - &client_handshaker_factory); - grpc_handshaker_factory_register(false /* at_start */, HANDSHAKER_SERVER, - &server_handshaker_factory); +void SecurityRegisterHandshakerFactories() { + HandshakerRegistry::RegisterHandshakerFactory( + false /* at_start */, HANDSHAKER_CLIENT, + UniquePtr(New())); + HandshakerRegistry::RegisterHandshakerFactory( + false /* at_start */, HANDSHAKER_SERVER, + UniquePtr(New())); +} + +} // namespace grpc_core + +grpc_handshaker* grpc_security_handshaker_create( + tsi_handshaker* handshaker, grpc_security_connector* connector) { + return SecurityHandshakerCreate(handshaker, connector).release(); } diff --git a/src/core/lib/security/transport/security_handshaker.h b/src/core/lib/security/transport/security_handshaker.h index 88483b02e74..263fe555967 100644 --- a/src/core/lib/security/transport/security_handshaker.h +++ b/src/core/lib/security/transport/security_handshaker.h @@ -24,11 +24,20 @@ #include "src/core/lib/channel/handshaker.h" #include "src/core/lib/security/security_connector/security_connector.h" +namespace grpc_core { + /// Creates a security handshaker using \a handshaker. -grpc_handshaker* grpc_security_handshaker_create( +RefCountedPtr SecurityHandshakerCreate( tsi_handshaker* handshaker, grpc_security_connector* connector); /// Registers security handshaker factories. -void grpc_security_register_handshaker_factories(); +void SecurityRegisterHandshakerFactories(); + +} // namespace grpc_core + +// TODO(arjunroy): This is transitional to account for the new handshaker API +// and will eventually be removed entirely. +grpc_handshaker* grpc_security_handshaker_create( + tsi_handshaker* handshaker, grpc_security_connector* connector); #endif /* GRPC_CORE_LIB_SECURITY_TRANSPORT_SECURITY_HANDSHAKER_H */ diff --git a/src/core/lib/security/transport/server_auth_filter.cc b/src/core/lib/security/transport/server_auth_filter.cc index 362f49a5843..43509e6c61b 100644 --- a/src/core/lib/security/transport/server_auth_filter.cc +++ b/src/core/lib/security/transport/server_auth_filter.cc @@ -39,8 +39,12 @@ enum async_state { }; struct channel_data { - grpc_auth_context* auth_context; - grpc_server_credentials* creds; + channel_data(grpc_auth_context* auth_context, grpc_server_credentials* creds) + : auth_context(auth_context->Ref()), creds(creds->Ref()) {} + ~channel_data() { auth_context.reset(DEBUG_LOCATION, "server_auth_filter"); } + + grpc_core::RefCountedPtr auth_context; + grpc_core::RefCountedPtr creds; }; struct call_data { @@ -58,7 +62,7 @@ struct call_data { grpc_server_security_context_create(args.arena); channel_data* chand = static_cast(elem->channel_data); server_ctx->auth_context = - GRPC_AUTH_CONTEXT_REF(chand->auth_context, "server_auth_filter"); + chand->auth_context->Ref(DEBUG_LOCATION, "server_auth_filter"); if (args.context[GRPC_CONTEXT_SECURITY].value != nullptr) { args.context[GRPC_CONTEXT_SECURITY].destroy( args.context[GRPC_CONTEXT_SECURITY].value); @@ -70,7 +74,7 @@ struct call_data { ~call_data() { GRPC_ERROR_UNREF(recv_initial_metadata_error); } - grpc_call_combiner* call_combiner; + grpc_core::CallCombiner* call_combiner; grpc_call_stack* owning_call; grpc_transport_stream_op_batch* recv_initial_metadata_batch; grpc_closure* original_recv_initial_metadata_ready; @@ -165,6 +169,7 @@ static void on_md_processing_done( grpc_status_code status, const char* error_details) { grpc_call_element* elem = static_cast(user_data); call_data* calld = static_cast(elem->call_data); + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; grpc_core::ExecCtx exec_ctx; // If the call was not cancelled while we were in flight, process the result. if (gpr_atm_full_cas(&calld->state, static_cast(STATE_INIT), @@ -208,19 +213,20 @@ static void recv_initial_metadata_ready(void* arg, grpc_error* error) { call_data* calld = static_cast(elem->call_data); grpc_transport_stream_op_batch* batch = calld->recv_initial_metadata_batch; if (error == GRPC_ERROR_NONE) { - if (chand->creds != nullptr && chand->creds->processor.process != nullptr) { + if (chand->creds != nullptr && + chand->creds->auth_metadata_processor().process != nullptr) { // We're calling out to the application, so we need to make sure // to drop the call combiner early if we get cancelled. GRPC_CLOSURE_INIT(&calld->cancel_closure, cancel_call, elem, grpc_schedule_on_exec_ctx); - grpc_call_combiner_set_notify_on_cancel(calld->call_combiner, - &calld->cancel_closure); + calld->call_combiner->SetNotifyOnCancel(&calld->cancel_closure); GRPC_CALL_STACK_REF(calld->owning_call, "server_auth_metadata"); calld->md = metadata_batch_to_md_array( batch->payload->recv_initial_metadata.recv_initial_metadata); - chand->creds->processor.process( - chand->creds->processor.state, chand->auth_context, - calld->md.metadata, calld->md.count, on_md_processing_done, elem); + chand->creds->auth_metadata_processor().process( + chand->creds->auth_metadata_processor().state, + chand->auth_context.get(), calld->md.metadata, calld->md.count, + on_md_processing_done, elem); return; } } @@ -290,23 +296,19 @@ static void destroy_call_elem(grpc_call_element* elem, static grpc_error* init_channel_elem(grpc_channel_element* elem, grpc_channel_element_args* args) { GPR_ASSERT(!args->is_last); - channel_data* chand = static_cast(elem->channel_data); grpc_auth_context* auth_context = grpc_find_auth_context_in_args(args->channel_args); GPR_ASSERT(auth_context != nullptr); - chand->auth_context = - GRPC_AUTH_CONTEXT_REF(auth_context, "server_auth_filter"); grpc_server_credentials* creds = grpc_find_server_credentials_in_args(args->channel_args); - chand->creds = grpc_server_credentials_ref(creds); + new (elem->channel_data) channel_data(auth_context, creds); return GRPC_ERROR_NONE; } /* Destructor for channel data */ static void destroy_channel_elem(grpc_channel_element* elem) { channel_data* chand = static_cast(elem->channel_data); - GRPC_AUTH_CONTEXT_UNREF(chand->auth_context, "server_auth_filter"); - grpc_server_credentials_unref(chand->creds); + chand->~channel_data(); } const grpc_channel_filter grpc_server_auth_filter = { diff --git a/src/core/lib/slice/b64.h b/src/core/lib/slice/b64.h index 4475568c25b..88b880a4542 100644 --- a/src/core/lib/slice/b64.h +++ b/src/core/lib/slice/b64.h @@ -23,7 +23,7 @@ #include -/* Encodes data using base64. It is the caller's responsability to free +/* Encodes data using base64. It is the caller's responsibility to free the returned char * using gpr_free. Returns NULL on NULL input. TODO(makdharma) : change the flags to bool from int */ char* grpc_base64_encode(const void* data, size_t data_size, int url_safe, @@ -35,7 +35,7 @@ size_t grpc_base64_estimate_encoded_size(size_t data_size, int url_safe, int multiline); /* Encodes data using base64 and write it to memory pointed to by result. It is - * the caller's responsiblity to allocate enough memory in |result| to fit the + * the caller's responsibility to allocate enough memory in |result| to fit the * encoded data. */ void grpc_base64_encode_core(char* result, const void* vdata, size_t data_size, int url_safe, int multiline); diff --git a/src/core/lib/slice/percent_encoding.cc b/src/core/lib/slice/percent_encoding.cc index 45cd2cc47f4..79a4805bc91 100644 --- a/src/core/lib/slice/percent_encoding.cc +++ b/src/core/lib/slice/percent_encoding.cc @@ -38,7 +38,7 @@ static bool is_unreserved_character(uint8_t c, return ((unreserved_bytes[c / 8] >> (c % 8)) & 1) != 0; } -grpc_slice grpc_percent_encode_slice(grpc_slice slice, +grpc_slice grpc_percent_encode_slice(const grpc_slice& slice, const uint8_t* unreserved_bytes) { static const uint8_t hex[] = "0123456789ABCDEF"; @@ -86,7 +86,7 @@ static uint8_t dehex(uint8_t c) { GPR_UNREACHABLE_CODE(return 255); } -bool grpc_strict_percent_decode_slice(grpc_slice slice_in, +bool grpc_strict_percent_decode_slice(const grpc_slice& slice_in, const uint8_t* unreserved_bytes, grpc_slice* slice_out) { const uint8_t* p = GRPC_SLICE_START_PTR(slice_in); @@ -126,7 +126,7 @@ bool grpc_strict_percent_decode_slice(grpc_slice slice_in, return true; } -grpc_slice grpc_permissive_percent_decode_slice(grpc_slice slice_in) { +grpc_slice grpc_permissive_percent_decode_slice(const grpc_slice& slice_in) { const uint8_t* p = GRPC_SLICE_START_PTR(slice_in); const uint8_t* in_end = GRPC_SLICE_END_PTR(slice_in); size_t out_length = 0; diff --git a/src/core/lib/slice/percent_encoding.h b/src/core/lib/slice/percent_encoding.h index 6b13ffc3fee..43b20f090f0 100644 --- a/src/core/lib/slice/percent_encoding.h +++ b/src/core/lib/slice/percent_encoding.h @@ -46,7 +46,7 @@ extern const uint8_t grpc_compatible_percent_encoding_unreserved_bytes[256 / 8]; /* Percent-encode a slice, returning the new slice (this cannot fail): unreserved_bytes is a bitfield indicating which bytes are considered unreserved and thus do not need percent encoding */ -grpc_slice grpc_percent_encode_slice(grpc_slice slice, +grpc_slice grpc_percent_encode_slice(const grpc_slice& slice, const uint8_t* unreserved_bytes); /* Percent-decode a slice, strictly. If the input is legal (contains no unreserved bytes, and legal % encodings), @@ -54,12 +54,12 @@ grpc_slice grpc_percent_encode_slice(grpc_slice slice, If the input is not legal, returns false and leaves *slice_out untouched. unreserved_bytes is a bitfield indicating which bytes are considered unreserved and thus do not need percent encoding */ -bool grpc_strict_percent_decode_slice(grpc_slice slice_in, +bool grpc_strict_percent_decode_slice(const grpc_slice& slice_in, const uint8_t* unreserved_bytes, grpc_slice* slice_out); /* Percent-decode a slice, permissively. If a % triplet can not be decoded, pass it through verbatim. This cannot fail. */ -grpc_slice grpc_permissive_percent_decode_slice(grpc_slice slice_in); +grpc_slice grpc_permissive_percent_decode_slice(const grpc_slice& slice_in); #endif /* GRPC_CORE_LIB_SLICE_PERCENT_ENCODING_H */ diff --git a/src/core/lib/slice/slice.cc b/src/core/lib/slice/slice.cc index e842d84f11f..75acb28e99c 100644 --- a/src/core/lib/slice/slice.cc +++ b/src/core/lib/slice/slice.cc @@ -26,6 +26,8 @@ #include +#include "src/core/lib/gprpp/memory.h" +#include "src/core/lib/gprpp/ref_counted.h" #include "src/core/lib/iomgr/exec_ctx.h" char* grpc_slice_to_c_string(grpc_slice slice) { @@ -49,19 +51,6 @@ grpc_slice grpc_slice_copy(grpc_slice s) { return out; } -grpc_slice grpc_slice_ref_internal(grpc_slice slice) { - if (slice.refcount) { - slice.refcount->vtable->ref(slice.refcount); - } - return slice; -} - -void grpc_slice_unref_internal(grpc_slice slice) { - if (slice.refcount) { - slice.refcount->vtable->unref(slice.refcount); - } -} - /* Public API */ grpc_slice grpc_slice_ref(grpc_slice slice) { return grpc_slice_ref_internal(slice); @@ -79,17 +68,10 @@ void grpc_slice_unref(grpc_slice slice) { /* grpc_slice_from_static_string support structure - a refcount that does nothing */ -static void noop_ref(void* unused) {} -static void noop_unref(void* unused) {} - -static const grpc_slice_refcount_vtable noop_refcount_vtable = { - noop_ref, noop_unref, grpc_slice_default_eq_impl, - grpc_slice_default_hash_impl}; -static grpc_slice_refcount noop_refcount = {&noop_refcount_vtable, - &noop_refcount}; +static grpc_slice_refcount NoopRefcount; size_t grpc_slice_memory_usage(grpc_slice s) { - if (s.refcount == nullptr || s.refcount == &noop_refcount) { + if (s.refcount == nullptr || s.refcount == &NoopRefcount) { return 0; } else { return s.data.refcounted.length; @@ -98,7 +80,7 @@ size_t grpc_slice_memory_usage(grpc_slice s) { grpc_slice grpc_slice_from_static_buffer(const void* s, size_t len) { grpc_slice slice; - slice.refcount = &noop_refcount; + slice.refcount = &NoopRefcount; slice.data.refcounted.bytes = (uint8_t*)s; slice.data.refcounted.length = len; return slice; @@ -108,45 +90,43 @@ grpc_slice grpc_slice_from_static_string(const char* s) { return grpc_slice_from_static_buffer(s, strlen(s)); } +namespace grpc_core { + /* grpc_slice_new support structures - we create a refcount object extended with the user provided data pointer & destroy function */ -typedef struct new_slice_refcount { - grpc_slice_refcount rc; - gpr_refcount refs; - void (*user_destroy)(void*); - void* user_data; -} new_slice_refcount; - -static void new_slice_ref(void* p) { - new_slice_refcount* r = static_cast(p); - gpr_ref(&r->refs); -} - -static void new_slice_unref(void* p) { - new_slice_refcount* r = static_cast(p); - if (gpr_unref(&r->refs)) { - r->user_destroy(r->user_data); - gpr_free(r); +class NewSliceRefcount { + public: + static void Destroy(void* arg) { + Delete(static_cast(arg)); } -} -static const grpc_slice_refcount_vtable new_slice_vtable = { - new_slice_ref, new_slice_unref, grpc_slice_default_eq_impl, - grpc_slice_default_hash_impl}; + NewSliceRefcount(void (*destroy)(void*), void* user_data) + : rc_(grpc_slice_refcount::Type::REGULAR, &refs_, Destroy, this, &rc_), + user_destroy_(destroy), + user_data_(user_data) {} + + GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE + + grpc_slice_refcount* base_refcount() { return &rc_; } + + private: + ~NewSliceRefcount() { user_destroy_(user_data_); } + + grpc_slice_refcount rc_; + RefCount refs_; + void (*user_destroy_)(void*); + void* user_data_; +}; + +} // namespace grpc_core grpc_slice grpc_slice_new_with_user_data(void* p, size_t len, void (*destroy)(void*), void* user_data) { grpc_slice slice; - new_slice_refcount* rc = - static_cast(gpr_malloc(sizeof(new_slice_refcount))); - gpr_ref_init(&rc->refs, 1); - rc->rc.vtable = &new_slice_vtable; - rc->rc.sub_refcount = &rc->rc; - rc->user_destroy = destroy; - rc->user_data = user_data; - - slice.refcount = &rc->rc; + slice.refcount = + grpc_core::New(destroy, user_data) + ->base_refcount(); slice.data.refcounted.bytes = static_cast(p); slice.data.refcounted.length = len; return slice; @@ -157,46 +137,45 @@ grpc_slice grpc_slice_new(void* p, size_t len, void (*destroy)(void*)) { return grpc_slice_new_with_user_data(p, len, destroy, p); } +namespace grpc_core { /* grpc_slice_new_with_len support structures - we create a refcount object extended with the user provided data pointer & destroy function */ -typedef struct new_with_len_slice_refcount { - grpc_slice_refcount rc; - gpr_refcount refs; - void* user_data; - size_t user_length; - void (*user_destroy)(void*, size_t); -} new_with_len_slice_refcount; -static void new_with_len_ref(void* p) { - new_with_len_slice_refcount* r = static_cast(p); - gpr_ref(&r->refs); -} - -static void new_with_len_unref(void* p) { - new_with_len_slice_refcount* r = static_cast(p); - if (gpr_unref(&r->refs)) { - r->user_destroy(r->user_data, r->user_length); - gpr_free(r); +class NewWithLenSliceRefcount { + public: + static void Destroy(void* arg) { + Delete(static_cast(arg)); } -} -static const grpc_slice_refcount_vtable new_with_len_vtable = { - new_with_len_ref, new_with_len_unref, grpc_slice_default_eq_impl, - grpc_slice_default_hash_impl}; + NewWithLenSliceRefcount(void (*destroy)(void*, size_t), void* user_data, + size_t user_length) + : rc_(grpc_slice_refcount::Type::REGULAR, &refs_, Destroy, this, &rc_), + user_data_(user_data), + user_length_(user_length), + user_destroy_(destroy) {} + + GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE + + grpc_slice_refcount* base_refcount() { return &rc_; } + + private: + ~NewWithLenSliceRefcount() { user_destroy_(user_data_, user_length_); } + + grpc_slice_refcount rc_; + RefCount refs_; + void* user_data_; + size_t user_length_; + void (*user_destroy_)(void*, size_t); +}; + +} // namespace grpc_core grpc_slice grpc_slice_new_with_len(void* p, size_t len, void (*destroy)(void*, size_t)) { grpc_slice slice; - new_with_len_slice_refcount* rc = static_cast( - gpr_malloc(sizeof(new_with_len_slice_refcount))); - gpr_ref_init(&rc->refs, 1); - rc->rc.vtable = &new_with_len_vtable; - rc->rc.sub_refcount = &rc->rc; - rc->user_destroy = destroy; - rc->user_data = p; - rc->user_length = len; - - slice.refcount = &rc->rc; + slice.refcount = + grpc_core::New(destroy, p, len) + ->base_refcount(); slice.data.refcounted.bytes = static_cast(p); slice.data.refcounted.length = len; return slice; @@ -213,26 +192,29 @@ grpc_slice grpc_slice_from_copied_string(const char* source) { return grpc_slice_from_copied_buffer(source, strlen(source)); } -typedef struct { - grpc_slice_refcount base; - gpr_refcount refs; -} malloc_refcount; +namespace { -static void malloc_ref(void* p) { - malloc_refcount* r = static_cast(p); - gpr_ref(&r->refs); -} - -static void malloc_unref(void* p) { - malloc_refcount* r = static_cast(p); - if (gpr_unref(&r->refs)) { +class MallocRefCount { + public: + static void Destroy(void* arg) { + MallocRefCount* r = static_cast(arg); + r->~MallocRefCount(); gpr_free(r); } -} -static const grpc_slice_refcount_vtable malloc_vtable = { - malloc_ref, malloc_unref, grpc_slice_default_eq_impl, - grpc_slice_default_hash_impl}; + MallocRefCount() + : base_(grpc_slice_refcount::Type::REGULAR, &refs_, Destroy, this, + &base_) {} + ~MallocRefCount() = default; + + grpc_slice_refcount* base_refcount() { return &base_; } + + private: + grpc_slice_refcount base_; + grpc_core::RefCount refs_; +}; + +} // namespace grpc_slice grpc_slice_malloc_large(size_t length) { grpc_slice slice; @@ -246,19 +228,16 @@ grpc_slice grpc_slice_malloc_large(size_t length) { refcount is a malloc_refcount bytes is an array of bytes of the requested length Both parts are placed in the same allocation returned from gpr_malloc */ - malloc_refcount* rc = static_cast( - gpr_malloc(sizeof(malloc_refcount) + length)); + auto* rc = + static_cast(gpr_malloc(sizeof(MallocRefCount) + length)); /* Initial refcount on rc is 1 - and it's up to the caller to release this reference. */ - gpr_ref_init(&rc->refs, 1); - - rc->base.vtable = &malloc_vtable; - rc->base.sub_refcount = &rc->base; + new (rc) MallocRefCount(); /* Build up the slice to be returned. */ /* The slices refcount points back to the allocated block. */ - slice.refcount = &rc->base; + slice.refcount = rc->base_refcount(); /* The data bytes are placed immediately after the refcount struct */ slice.data.refcounted.bytes = reinterpret_cast(rc + 1); /* And the length of the block is set to the requested length */ @@ -289,7 +268,7 @@ grpc_slice grpc_slice_sub_no_ref(grpc_slice source, size_t begin, size_t end) { GPR_ASSERT(source.data.refcounted.length >= end); /* Build the result */ - subset.refcount = source.refcount->sub_refcount; + subset.refcount = source.refcount->sub_refcount(); /* Point into the source array */ subset.data.refcounted.bytes = source.data.refcounted.bytes + begin; subset.data.refcounted.length = end - begin; @@ -315,7 +294,7 @@ grpc_slice grpc_slice_sub(grpc_slice source, size_t begin, size_t end) { } else { subset = grpc_slice_sub_no_ref(source, begin, end); /* Bump the refcount */ - subset.refcount->vtable->ref(subset.refcount); + subset.refcount->Ref(); } return subset; } @@ -343,23 +322,23 @@ grpc_slice grpc_slice_split_tail_maybe_ref(grpc_slice* source, size_t split, tail.data.inlined.length = static_cast(tail_length); memcpy(tail.data.inlined.bytes, source->data.refcounted.bytes + split, tail_length); - source->refcount = source->refcount->sub_refcount; + source->refcount = source->refcount->sub_refcount(); } else { /* Build the result */ switch (ref_whom) { case GRPC_SLICE_REF_TAIL: - tail.refcount = source->refcount->sub_refcount; - source->refcount = &noop_refcount; + tail.refcount = source->refcount->sub_refcount(); + source->refcount = &NoopRefcount; break; case GRPC_SLICE_REF_HEAD: - tail.refcount = &noop_refcount; - source->refcount = source->refcount->sub_refcount; + tail.refcount = &NoopRefcount; + source->refcount = source->refcount->sub_refcount(); break; case GRPC_SLICE_REF_BOTH: - tail.refcount = source->refcount->sub_refcount; - source->refcount = source->refcount->sub_refcount; + tail.refcount = source->refcount->sub_refcount(); + source->refcount = source->refcount->sub_refcount(); /* Bump the refcount */ - tail.refcount->vtable->ref(tail.refcount); + tail.refcount->Ref(); break; } /* Point into the source array */ @@ -395,20 +374,20 @@ grpc_slice grpc_slice_split_head(grpc_slice* source, size_t split) { head.refcount = nullptr; head.data.inlined.length = static_cast(split); memcpy(head.data.inlined.bytes, source->data.refcounted.bytes, split); - source->refcount = source->refcount->sub_refcount; + source->refcount = source->refcount->sub_refcount(); source->data.refcounted.bytes += split; source->data.refcounted.length -= split; } else { GPR_ASSERT(source->data.refcounted.length >= split); /* Build the result */ - head.refcount = source->refcount->sub_refcount; + head.refcount = source->refcount->sub_refcount(); /* Bump the refcount */ - head.refcount->vtable->ref(head.refcount); + head.refcount->Ref(); /* Point into the source array */ head.data.refcounted.bytes = source->data.refcounted.bytes; head.data.refcounted.length = split; - source->refcount = source->refcount->sub_refcount; + source->refcount = source->refcount->sub_refcount(); source->data.refcounted.bytes += split; source->data.refcounted.length -= split; } @@ -424,12 +403,38 @@ int grpc_slice_default_eq_impl(grpc_slice a, grpc_slice b) { } int grpc_slice_eq(grpc_slice a, grpc_slice b) { - if (a.refcount && b.refcount && a.refcount->vtable == b.refcount->vtable) { - return a.refcount->vtable->eq(a, b); + if (a.refcount && b.refcount && + a.refcount->GetType() == b.refcount->GetType()) { + return a.refcount->Eq(a, b); } return grpc_slice_default_eq_impl(a, b); } +int grpc_slice_differs_refcounted(const grpc_slice& a, + const grpc_slice& b_not_inline) { + size_t a_len; + const uint8_t* a_ptr; + if (a.refcount) { + a_len = a.data.refcounted.length; + a_ptr = a.data.refcounted.bytes; + } else { + a_len = a.data.inlined.length; + a_ptr = &a.data.inlined.bytes[0]; + } + if (a_len != b_not_inline.data.refcounted.length) { + return true; + } + if (a_len == 0) { + return false; + } + // This check *must* occur after the a_len == 0 check + // to retain compatibility with grpc_slice_eq. + if (a_ptr == nullptr) { + return true; + } + return memcmp(a_ptr, b_not_inline.data.refcounted.bytes, a_len); +} + int grpc_slice_cmp(grpc_slice a, grpc_slice b) { int d = static_cast(GRPC_SLICE_LENGTH(a) - GRPC_SLICE_LENGTH(b)); if (d != 0) return d; diff --git a/src/core/lib/slice/slice_buffer.cc b/src/core/lib/slice/slice_buffer.cc index 1f1c08b1594..e1929250d4a 100644 --- a/src/core/lib/slice/slice_buffer.cc +++ b/src/core/lib/slice/slice_buffer.cc @@ -33,6 +33,10 @@ #define GROW(x) (3 * (x) / 2) static void maybe_embiggen(grpc_slice_buffer* sb) { + if (sb->count == 0) { + sb->slices = sb->base_slices; + } + /* How far away from sb->base_slices is sb->slices pointer */ size_t slice_offset = static_cast(sb->slices - sb->base_slices); size_t slice_count = sb->count + slice_offset; @@ -177,6 +181,7 @@ void grpc_slice_buffer_reset_and_unref_internal(grpc_slice_buffer* sb) { sb->count = 0; sb->length = 0; + sb->slices = sb->base_slices; } void grpc_slice_buffer_reset_and_unref(grpc_slice_buffer* sb) { @@ -370,6 +375,24 @@ grpc_slice grpc_slice_buffer_take_first(grpc_slice_buffer* sb) { return slice; } +void grpc_slice_buffer_remove_first(grpc_slice_buffer* sb) { + GPR_DEBUG_ASSERT(sb->count > 0); + sb->length -= GRPC_SLICE_LENGTH(sb->slices[0]); + grpc_slice_unref_internal(sb->slices[0]); + sb->slices++; + if (--sb->count == 0) { + sb->slices = sb->base_slices; + } +} + +void grpc_slice_buffer_sub_first(grpc_slice_buffer* sb, size_t begin, + size_t end) { + // TODO(soheil): Introduce a ptr version for sub. + sb->length -= GRPC_SLICE_LENGTH(sb->slices[0]); + sb->slices[0] = grpc_slice_sub_no_ref(sb->slices[0], begin, end); + sb->length += end - begin; +} + void grpc_slice_buffer_undo_take_first(grpc_slice_buffer* sb, grpc_slice slice) { sb->slices--; diff --git a/src/core/lib/slice/slice_hash_table.h b/src/core/lib/slice/slice_hash_table.h index 4bbcf88e895..942830a3e9c 100644 --- a/src/core/lib/slice/slice_hash_table.h +++ b/src/core/lib/slice/slice_hash_table.h @@ -88,7 +88,7 @@ class SliceHashTable : public RefCounted> { SliceHashTable(size_t num_entries, Entry* entries, ValueCmp value_cmp); virtual ~SliceHashTable(); - void Add(grpc_slice key, T& value); + void Add(const grpc_slice& key, T& value); // Default value comparison function, if none specified by caller. static int DefaultValueCmp(const T& a, const T& b) { return GPR_ICMP(a, b); } @@ -137,7 +137,7 @@ SliceHashTable::~SliceHashTable() { } template -void SliceHashTable::Add(grpc_slice key, T& value) { +void SliceHashTable::Add(const grpc_slice& key, T& value) { const size_t hash = grpc_slice_hash(key); for (size_t offset = 0; offset < size_; ++offset) { const size_t idx = (hash + offset) % size_; diff --git a/src/core/lib/slice/slice_intern.cc b/src/core/lib/slice/slice_intern.cc index e53c040e1aa..15909d9b96f 100644 --- a/src/core/lib/slice/slice_intern.cc +++ b/src/core/lib/slice/slice_intern.cc @@ -19,6 +19,7 @@ #include #include "src/core/lib/slice/slice_internal.h" +#include "src/core/lib/slice/slice_utils.h" #include #include @@ -27,6 +28,7 @@ #include #include "src/core/lib/gpr/murmur_hash.h" +#include "src/core/lib/gprpp/sync.h" #include "src/core/lib/iomgr/iomgr_internal.h" /* for iomgr_abort_on_leaks() */ #include "src/core/lib/profiling/timers.h" #include "src/core/lib/slice/slice_string_helpers.h" @@ -39,24 +41,17 @@ #define TABLE_IDX(hash, capacity) (((hash) >> LOG2_SHARD_COUNT) % (capacity)) #define SHARD_IDX(hash) ((hash) & ((1 << LOG2_SHARD_COUNT) - 1)) -typedef struct interned_slice_refcount { - grpc_slice_refcount base; - grpc_slice_refcount sub; - size_t length; - gpr_atm refcnt; - uint32_t hash; - struct interned_slice_refcount* bucket_next; -} interned_slice_refcount; +using grpc_core::InternedSliceRefcount; typedef struct slice_shard { gpr_mu mu; - interned_slice_refcount** strs; + InternedSliceRefcount** strs; size_t count; size_t capacity; } slice_shard; /* hash seed: decided at initialization time */ -static uint32_t g_hash_seed; +uint32_t g_hash_seed; static int g_forced_hash_seed = 0; static slice_shard g_shards[SHARD_COUNT]; @@ -69,73 +64,35 @@ typedef struct { static static_metadata_hash_ent static_metadata_hash[4 * GRPC_STATIC_MDSTR_COUNT]; static uint32_t max_static_metadata_hash_probe; -static uint32_t static_metadata_hash_values[GRPC_STATIC_MDSTR_COUNT]; +uint32_t grpc_static_metadata_hash_values[GRPC_STATIC_MDSTR_COUNT]; -static void interned_slice_ref(void* p) { - interned_slice_refcount* s = static_cast(p); - GPR_ASSERT(gpr_atm_no_barrier_fetch_add(&s->refcnt, 1) > 0); -} +namespace grpc_core { -static void interned_slice_destroy(interned_slice_refcount* s) { - slice_shard* shard = &g_shards[SHARD_IDX(s->hash)]; - gpr_mu_lock(&shard->mu); - GPR_ASSERT(0 == gpr_atm_no_barrier_load(&s->refcnt)); - interned_slice_refcount** prev_next; - interned_slice_refcount* cur; - for (prev_next = &shard->strs[TABLE_IDX(s->hash, shard->capacity)], +InternedSliceRefcount::~InternedSliceRefcount() { + slice_shard* shard = &g_shards[SHARD_IDX(this->hash)]; + MutexLock lock(&shard->mu); + InternedSliceRefcount** prev_next; + InternedSliceRefcount* cur; + for (prev_next = &shard->strs[TABLE_IDX(this->hash, shard->capacity)], cur = *prev_next; - cur != s; prev_next = &cur->bucket_next, cur = cur->bucket_next) + cur != this; prev_next = &cur->bucket_next, cur = cur->bucket_next) ; *prev_next = cur->bucket_next; shard->count--; - gpr_free(s); - gpr_mu_unlock(&shard->mu); } -static void interned_slice_unref(void* p) { - interned_slice_refcount* s = static_cast(p); - if (1 == gpr_atm_full_fetch_add(&s->refcnt, -1)) { - interned_slice_destroy(s); - } -} - -static void interned_slice_sub_ref(void* p) { - interned_slice_ref((static_cast(p)) - - offsetof(interned_slice_refcount, sub)); -} - -static void interned_slice_sub_unref(void* p) { - interned_slice_unref((static_cast(p)) - - offsetof(interned_slice_refcount, sub)); -} - -static uint32_t interned_slice_hash(grpc_slice slice) { - interned_slice_refcount* s = - reinterpret_cast(slice.refcount); - return s->hash; -} - -static int interned_slice_eq(grpc_slice a, grpc_slice b) { - return a.refcount == b.refcount; -} - -static const grpc_slice_refcount_vtable interned_slice_vtable = { - interned_slice_ref, interned_slice_unref, interned_slice_eq, - interned_slice_hash}; -static const grpc_slice_refcount_vtable interned_slice_sub_vtable = { - interned_slice_sub_ref, interned_slice_sub_unref, - grpc_slice_default_eq_impl, grpc_slice_default_hash_impl}; +} // namespace grpc_core static void grow_shard(slice_shard* shard) { GPR_TIMER_SCOPE("grow_strtab", 0); size_t capacity = shard->capacity * 2; size_t i; - interned_slice_refcount** strtab; - interned_slice_refcount *s, *next; + InternedSliceRefcount** strtab; + InternedSliceRefcount *s, *next; - strtab = static_cast( - gpr_zalloc(sizeof(interned_slice_refcount*) * capacity)); + strtab = static_cast( + gpr_zalloc(sizeof(InternedSliceRefcount*) * capacity)); for (i = 0; i < shard->capacity; i++) { for (s = shard->strs[i]; s; s = next) { @@ -150,7 +107,7 @@ static void grow_shard(slice_shard* shard) { shard->capacity = capacity; } -static grpc_slice materialize(interned_slice_refcount* s) { +static grpc_slice materialize(InternedSliceRefcount* s) { grpc_slice slice; slice.refcount = &s->base; slice.data.refcounted.bytes = reinterpret_cast(s + 1); @@ -164,7 +121,7 @@ uint32_t grpc_slice_default_hash_impl(grpc_slice s) { } uint32_t grpc_static_slice_hash(grpc_slice s) { - return static_metadata_hash_values[GRPC_STATIC_METADATA_INDEX(s)]; + return grpc_static_metadata_hash_values[GRPC_STATIC_METADATA_INDEX(s)]; } int grpc_static_slice_eq(grpc_slice a, grpc_slice b) { @@ -173,7 +130,7 @@ int grpc_static_slice_eq(grpc_slice a, grpc_slice b) { uint32_t grpc_slice_hash(grpc_slice s) { return s.refcount == nullptr ? grpc_slice_default_hash_impl(s) - : s.refcount->vtable->hash(s); + : s.refcount->Hash(s); } grpc_slice grpc_slice_maybe_static_intern(grpc_slice slice, @@ -187,7 +144,8 @@ grpc_slice grpc_slice_maybe_static_intern(grpc_slice slice, static_metadata_hash_ent ent = static_metadata_hash[(hash + i) % GPR_ARRAY_SIZE(static_metadata_hash)]; if (ent.hash == hash && ent.idx < GRPC_STATIC_MDSTR_COUNT && - grpc_slice_eq(grpc_static_slice_table[ent.idx], slice)) { + grpc_slice_eq_static_interned(slice, + grpc_static_slice_table[ent.idx])) { *returned_slice_is_different = true; return grpc_static_slice_table[ent.idx]; } @@ -196,9 +154,10 @@ grpc_slice grpc_slice_maybe_static_intern(grpc_slice slice, return slice; } -bool grpc_slice_is_interned(grpc_slice slice) { - return (slice.refcount && slice.refcount->vtable == &interned_slice_vtable) || - GRPC_IS_STATIC_METADATA_STRING(slice); +bool grpc_slice_is_interned(const grpc_slice& slice) { + return (slice.refcount && + (slice.refcount->GetType() == grpc_slice_refcount::Type::INTERNED || + GRPC_IS_STATIC_METADATA_STRING(slice))); } grpc_slice grpc_slice_intern(grpc_slice slice) { @@ -208,16 +167,18 @@ grpc_slice grpc_slice_intern(grpc_slice slice) { } uint32_t hash = grpc_slice_hash(slice); + for (uint32_t i = 0; i <= max_static_metadata_hash_probe; i++) { static_metadata_hash_ent ent = static_metadata_hash[(hash + i) % GPR_ARRAY_SIZE(static_metadata_hash)]; if (ent.hash == hash && ent.idx < GRPC_STATIC_MDSTR_COUNT && - grpc_slice_eq(grpc_static_slice_table[ent.idx], slice)) { + grpc_slice_eq_static_interned(slice, + grpc_static_slice_table[ent.idx])) { return grpc_static_slice_table[ent.idx]; } } - interned_slice_refcount* s; + InternedSliceRefcount* s; slice_shard* shard = &g_shards[SHARD_IDX(hash)]; gpr_mu_lock(&shard->mu); @@ -225,15 +186,9 @@ grpc_slice grpc_slice_intern(grpc_slice slice) { /* search for an existing string */ size_t idx = TABLE_IDX(hash, shard->capacity); for (s = shard->strs[idx]; s; s = s->bucket_next) { - if (s->hash == hash && grpc_slice_eq(slice, materialize(s))) { - if (gpr_atm_no_barrier_fetch_add(&s->refcnt, 1) == 0) { - /* If we get here, we've added a ref to something that was about to - * die - drop it immediately. - * The *only* possible path here (given the shard mutex) should be to - * drop from one ref back to zero - assert that with a CAS */ - GPR_ASSERT(gpr_atm_rel_cas(&s->refcnt, 1, 0)); - /* and treat this as if we were never here... sshhh */ - } else { + if (s->hash == hash && + grpc_slice_eq_static_interned(slice, materialize(s))) { + if (s->refcnt.RefIfNonZero()) { gpr_mu_unlock(&shard->mu); return materialize(s); } @@ -242,27 +197,20 @@ grpc_slice grpc_slice_intern(grpc_slice slice) { /* not found: create a new string */ /* string data goes after the internal_string header */ - s = static_cast( + s = static_cast( gpr_malloc(sizeof(*s) + GRPC_SLICE_LENGTH(slice))); - gpr_atm_rel_store(&s->refcnt, 1); - s->length = GRPC_SLICE_LENGTH(slice); - s->hash = hash; - s->base.vtable = &interned_slice_vtable; - s->base.sub_refcount = &s->sub; - s->sub.vtable = &interned_slice_sub_vtable; - s->sub.sub_refcount = &s->sub; - s->bucket_next = shard->strs[idx]; + + new (s) grpc_core::InternedSliceRefcount(GRPC_SLICE_LENGTH(slice), hash, + shard->strs[idx]); + memcpy(reinterpret_cast(s + 1), GRPC_SLICE_START_PTR(slice), + GRPC_SLICE_LENGTH(slice)); shard->strs[idx] = s; - memcpy(s + 1, GRPC_SLICE_START_PTR(slice), GRPC_SLICE_LENGTH(slice)); - shard->count++; - if (shard->count > shard->capacity * 2) { grow_shard(shard); } gpr_mu_unlock(&shard->mu); - return materialize(s); } @@ -280,7 +228,7 @@ void grpc_slice_intern_init(void) { gpr_mu_init(&shard->mu); shard->count = 0; shard->capacity = INITIAL_SHARD_CAPACITY; - shard->strs = static_cast( + shard->strs = static_cast( gpr_zalloc(sizeof(*shard->strs) * shard->capacity)); } for (size_t i = 0; i < GPR_ARRAY_SIZE(static_metadata_hash); i++) { @@ -289,13 +237,13 @@ void grpc_slice_intern_init(void) { } max_static_metadata_hash_probe = 0; for (size_t i = 0; i < GRPC_STATIC_MDSTR_COUNT; i++) { - static_metadata_hash_values[i] = + grpc_static_metadata_hash_values[i] = grpc_slice_default_hash_impl(grpc_static_slice_table[i]); for (size_t j = 0; j < GPR_ARRAY_SIZE(static_metadata_hash); j++) { - size_t slot = (static_metadata_hash_values[i] + j) % + size_t slot = (grpc_static_metadata_hash_values[i] + j) % GPR_ARRAY_SIZE(static_metadata_hash); if (static_metadata_hash[slot].idx == GRPC_STATIC_MDSTR_COUNT) { - static_metadata_hash[slot].hash = static_metadata_hash_values[i]; + static_metadata_hash[slot].hash = grpc_static_metadata_hash_values[i]; static_metadata_hash[slot].idx = static_cast(i); if (j > max_static_metadata_hash_probe) { max_static_metadata_hash_probe = static_cast(j); @@ -315,8 +263,7 @@ void grpc_slice_intern_shutdown(void) { gpr_log(GPR_DEBUG, "WARNING: %" PRIuPTR " metadata strings were leaked", shard->count); for (size_t j = 0; j < shard->capacity; j++) { - for (interned_slice_refcount* s = shard->strs[j]; s; - s = s->bucket_next) { + for (InternedSliceRefcount* s = shard->strs[j]; s; s = s->bucket_next) { char* text = grpc_dump_slice(materialize(s), GPR_DUMP_HEX | GPR_DUMP_ASCII); gpr_log(GPR_DEBUG, "LEAKED: %s", text); diff --git a/src/core/lib/slice/slice_internal.h b/src/core/lib/slice/slice_internal.h index 5b05951522f..e4aba015315 100644 --- a/src/core/lib/slice/slice_internal.h +++ b/src/core/lib/slice/slice_internal.h @@ -21,18 +21,243 @@ #include +#include + #include #include +#include + +#include "src/core/lib/gpr/murmur_hash.h" +#include "src/core/lib/gprpp/ref_counted.h" +#include "src/core/lib/transport/static_metadata.h" + +// Interned slices have specific fast-path operations for hashing. To inline +// these operations, we need to forward declare them here. +extern uint32_t grpc_static_metadata_hash_values[GRPC_STATIC_MDSTR_COUNT]; +extern uint32_t g_hash_seed; + +// grpc_slice_refcount : A reference count for grpc_slice. +// +// Non-inlined grpc_slice objects are refcounted. Historically this was +// implemented via grpc_slice_refcount, a C-style polymorphic class using a +// manually managed vtable of operations. Subclasses would define their own +// vtable; the 'virtual' methods (ref, unref, equals and hash) would simply call +// the function pointers in the vtable as necessary. +// +// Unfortunately, this leads to some inefficiencies in the generated code that +// can be improved upon. For example, equality checking for interned slices is a +// simple equality check on the refcount pointer. With the vtable approach, this +// would translate to roughly the following (high-level) instructions: +// +// grpc_slice_equals(slice1, slice2): +// load vtable->eq -> eq_func +// call eq_func(slice1, slice2) +// +// interned_slice_equals(slice1, slice2) +// load slice1.ref -> r1 +// load slice2.ref -> r2 +// cmp r1, r2 -> retval +// ret retval +// +// This leads to a function call for a function defined in another translation +// unit, which imposes memory barriers, which reduces the compiler's ability to +// optimize (in addition to the added overhead of call/ret). Additionally, it +// may be harder to reason about branch prediction when we're jumping to +// essentially arbitrarily provided function pointers. +// +// In addition, it is arguable that while virtualization was helpful for +// Equals()/Hash() methods, that it was fundamentally unnecessary for +// Ref()/Unref(). +// +// Instead, grpc_slice_refcount provides the same functionality as the C-style +// virtual class, but in a de-virtualized manner - Eq(), Hash(), Ref() and +// Unref() are provided within this header file. Fastpaths for Eq()/Hash() +// (interned and static metadata slices), as well as the Ref() operation, can +// all be inlined without any memory barriers. +// +// It does this by: +// 1. Using grpc_core::RefCount<> (header-only) for Ref/Unref. Two special cases +// need support: No-op ref/unref (eg. static metadata slices) and stream +// slice references (where all the slices share the streamref). This is in +// addition to the normal case of '1 slice, 1 ref'. +// To support these cases, we explicitly track a nullable pointer to the +// underlying RefCount<>. No-op ref/unref is used by checking the pointer for +// null, and doing nothing if it is. Both stream slice refs and 'normal' +// slices use the same path for Ref/Unref (by targeting the non-null +// pointer). +// +// 2. introducing the notion of grpc_slice_refcount::Type. This describes if a +// slice ref is used by a static metadata slice, an interned slice, or other +// slices. We switch on the slice ref type in order to provide fastpaths for +// Equals() and Hash(). +// +// In total, this saves us roughly 1-2% latency for unary calls, with smaller +// calls benefitting. The effect is present, but not as useful, for larger calls +// where the cost of sending the data dominates. +struct grpc_slice_refcount { + public: + enum class Type { + STATIC, // Refcount for a static metadata slice. + INTERNED, // Refcount for an interned slice. + REGULAR // Refcount for non-static-metadata, non-interned slices. + }; + typedef void (*DestroyerFn)(void*); + + grpc_slice_refcount() = default; + + explicit grpc_slice_refcount(grpc_slice_refcount* sub) : sub_refcount_(sub) {} + // Regular constructor for grpc_slice_refcount. + // + // Parameters: + // 1. grpc_slice_refcount::Type type + // Whether we are the refcount for a static + // metadata slice, an interned slice, or any other kind of slice. + // + // 2. RefCount* ref + // The pointer to the actual underlying grpc_core::RefCount. Rather than + // performing struct offset computations as in the original implementation to + // get to the refcount, which requires a virtual method, we devirtualize by + // using a nullable pointer to allow a single pair of Ref/Unref methods. + // + // 3. DestroyerFn destroyer_fn + // Called when the refcount goes to 0, with destroyer_arg as parameter. + // + // 4. void* destroyer_arg + // Argument for the virtualized destructor. + // + // 5. grpc_slice_refcount* sub + // Argument used for interned slices. + grpc_slice_refcount(grpc_slice_refcount::Type type, grpc_core::RefCount* ref, + DestroyerFn destroyer_fn, void* destroyer_arg, + grpc_slice_refcount* sub) + : ref_(ref), + ref_type_(type), + sub_refcount_(sub), + dest_fn_(destroyer_fn), + destroy_fn_arg_(destroyer_arg) {} + // Initializer for static refcounts. + grpc_slice_refcount(grpc_slice_refcount* sub, Type type) + : ref_type_(type), sub_refcount_(sub) {} + + Type GetType() const { return ref_type_; } + + int Eq(const grpc_slice& a, const grpc_slice& b); + + uint32_t Hash(const grpc_slice& slice); + void Ref() { + if (ref_ == nullptr) return; + ref_->RefNonZero(); + } + void Unref() { + if (ref_ == nullptr) return; + if (ref_->Unref()) { + dest_fn_(destroy_fn_arg_); + } + } + + grpc_slice_refcount* sub_refcount() const { return sub_refcount_; } + + private: + grpc_core::RefCount* ref_ = nullptr; + const Type ref_type_ = Type::REGULAR; + grpc_slice_refcount* sub_refcount_ = this; + DestroyerFn dest_fn_ = nullptr; + void* destroy_fn_arg_ = nullptr; +}; + +namespace grpc_core { + +struct InternedSliceRefcount { + static void Destroy(void* arg) { + auto* rc = static_cast(arg); + rc->~InternedSliceRefcount(); + gpr_free(rc); + } + + InternedSliceRefcount(size_t length, uint32_t hash, + InternedSliceRefcount* bucket_next) + : base(grpc_slice_refcount::Type::INTERNED, &refcnt, Destroy, this, &sub), + sub(grpc_slice_refcount::Type::REGULAR, &refcnt, Destroy, this, &sub), + length(length), + hash(hash), + bucket_next(bucket_next) {} + + ~InternedSliceRefcount(); + + grpc_slice_refcount base; + grpc_slice_refcount sub; + const size_t length; + RefCount refcnt; + const uint32_t hash; + InternedSliceRefcount* bucket_next; +}; + +} // namespace grpc_core + +inline int grpc_slice_refcount::Eq(const grpc_slice& a, const grpc_slice& b) { + switch (ref_type_) { + case Type::STATIC: + return GRPC_STATIC_METADATA_INDEX(a) == GRPC_STATIC_METADATA_INDEX(b); + case Type::INTERNED: + return a.refcount == b.refcount; + case Type::REGULAR: + break; + } + if (GRPC_SLICE_LENGTH(a) != GRPC_SLICE_LENGTH(b)) return false; + if (GRPC_SLICE_LENGTH(a) == 0) return true; + return 0 == memcmp(GRPC_SLICE_START_PTR(a), GRPC_SLICE_START_PTR(b), + GRPC_SLICE_LENGTH(a)); +} + +inline uint32_t grpc_slice_refcount::Hash(const grpc_slice& slice) { + switch (ref_type_) { + case Type::STATIC: + return ::grpc_static_metadata_hash_values[GRPC_STATIC_METADATA_INDEX( + slice)]; + case Type::INTERNED: + return reinterpret_cast(slice.refcount) + ->hash; + case Type::REGULAR: + break; + } + return gpr_murmur_hash3(GRPC_SLICE_START_PTR(slice), GRPC_SLICE_LENGTH(slice), + g_hash_seed); +} + +inline const grpc_slice& grpc_slice_ref_internal(const grpc_slice& slice) { + if (slice.refcount) { + slice.refcount->Ref(); + } + return slice; +} + +inline void grpc_slice_unref_internal(const grpc_slice& slice) { + if (slice.refcount) { + slice.refcount->Unref(); + } +} -grpc_slice grpc_slice_ref_internal(grpc_slice slice); -void grpc_slice_unref_internal(grpc_slice slice); void grpc_slice_buffer_reset_and_unref_internal(grpc_slice_buffer* sb); void grpc_slice_buffer_partial_unref_internal(grpc_slice_buffer* sb, size_t idx); void grpc_slice_buffer_destroy_internal(grpc_slice_buffer* sb); +// Returns a pointer to the first slice in the slice buffer without giving +// ownership to or a reference count on that slice. +inline grpc_slice* grpc_slice_buffer_peek_first(grpc_slice_buffer* sb) { + GPR_DEBUG_ASSERT(sb->count > 0); + return &sb->slices[0]; +} + +// Removes the first slice from the slice buffer. +void grpc_slice_buffer_remove_first(grpc_slice_buffer* sb); + +// Calls grpc_slice_sub with the given parameters on the first slice. +void grpc_slice_buffer_sub_first(grpc_slice_buffer* sb, size_t begin, + size_t end); + /* Check if a slice is interned */ -bool grpc_slice_is_interned(grpc_slice slice); +bool grpc_slice_is_interned(const grpc_slice& slice); void grpc_slice_intern_init(void); void grpc_slice_intern_shutdown(void); diff --git a/src/core/lib/slice/slice_traits.h b/src/core/lib/slice/slice_traits.h index ee01916525e..07d13cd8b54 100644 --- a/src/core/lib/slice/slice_traits.h +++ b/src/core/lib/slice/slice_traits.h @@ -24,8 +24,8 @@ #include #include -bool grpc_slice_is_legal_header(grpc_slice s); -bool grpc_slice_is_legal_nonbin_header(grpc_slice s); -bool grpc_slice_is_bin_suffixed(grpc_slice s); +bool grpc_slice_is_legal_header(const grpc_slice& s); +bool grpc_slice_is_legal_nonbin_header(const grpc_slice& s); +bool grpc_slice_is_bin_suffixed(const grpc_slice& s); #endif /* GRPC_CORE_LIB_SLICE_SLICE_TRAITS_H */ diff --git a/src/core/lib/slice/slice_utils.h b/src/core/lib/slice/slice_utils.h new file mode 100644 index 00000000000..7589bf8f0f7 --- /dev/null +++ b/src/core/lib/slice/slice_utils.h @@ -0,0 +1,50 @@ +/* + * + * Copyright 2019 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_SLICE_SLICE_UTILS_H +#define GRPC_CORE_LIB_SLICE_SLICE_UTILS_H + +#include + +#include + +// When we compare two slices, and we know the latter is not inlined, we can +// short circuit our comparison operator. We specifically use differs() +// semantics instead of equals() semantics due to more favourable code +// generation when using differs(). Specifically, we may use the output of +// grpc_slice_differs_refcounted for control flow. If we use differs() +// semantics, we end with a tailcall to memcmp(). If we use equals() semantics, +// we need to invert the result that memcmp provides us, which costs several +// instructions to do so. If we're using the result for control flow (i.e. +// branching based on the output) then we're just performing the extra +// operations to invert the result pointlessly. Concretely, we save 6 ops on +// x86-64/clang with differs(). +int grpc_slice_differs_refcounted(const grpc_slice& a, + const grpc_slice& b_not_inline); +// When we compare two slices, and we *know* that one of them is static or +// interned, we can short circuit our slice equality function. The second slice +// here must be static or interned; slice a can be any slice, inlined or not. +inline bool grpc_slice_eq_static_interned(const grpc_slice& a, + const grpc_slice& b_static_interned) { + if (a.refcount == b_static_interned.refcount) { + return true; + } + return !grpc_slice_differs_refcounted(a, b_static_interned); +} + +#endif /* GRPC_CORE_LIB_SLICE_SLICE_UTILS_H */ diff --git a/src/core/lib/slice/slice_weak_hash_table.h b/src/core/lib/slice/slice_weak_hash_table.h index dc3ccc5dadd..1335c817a39 100644 --- a/src/core/lib/slice/slice_weak_hash_table.h +++ b/src/core/lib/slice/slice_weak_hash_table.h @@ -46,7 +46,7 @@ class SliceWeakHashTable : public RefCounted> { /// Add a mapping from \a key to \a value, taking ownership of \a key. This /// operation will always succeed. It may discard older entries. - void Add(grpc_slice key, T value) { + void Add(const grpc_slice& key, T value) { const size_t idx = grpc_slice_hash(key) % Size; entries_[idx].Set(key, std::move(value)); return; @@ -54,7 +54,7 @@ class SliceWeakHashTable : public RefCounted> { /// Returns the value from the table associated with / \a key or null if not /// found. - const T* Get(const grpc_slice key) const { + const T* Get(const grpc_slice& key) const { const size_t idx = grpc_slice_hash(key) % Size; const auto& entry = entries_[idx]; return grpc_slice_eq(entry.key(), key) ? entry.value() : nullptr; @@ -79,7 +79,7 @@ class SliceWeakHashTable : public RefCounted> { ~Entry() { if (is_set_) grpc_slice_unref_internal(key_); } - grpc_slice key() const { return key_; } + const grpc_slice& key() const { return key_; } /// Return the entry's value, or null if unset. const T* value() const { @@ -88,7 +88,7 @@ class SliceWeakHashTable : public RefCounted> { } /// Set the \a key and \a value (which is moved) for the entry. - void Set(grpc_slice key, T&& value) { + void Set(const grpc_slice& key, T&& value) { if (is_set_) grpc_slice_unref_internal(key_); key_ = key; value_ = std::move(value); diff --git a/src/core/lib/surface/api_trace.h b/src/core/lib/surface/api_trace.h index 72ed830554f..51d1f522230 100644 --- a/src/core/lib/surface/api_trace.h +++ b/src/core/lib/surface/api_trace.h @@ -45,7 +45,7 @@ extern grpc_core::TraceFlag grpc_api_trace; /* Due to the limitations of C89's preprocessor, the arity of the var-arg list 'nargs' must be specified. */ #define GRPC_API_TRACE(fmt, nargs, args) \ - if (grpc_api_trace.enabled()) { \ + if (GRPC_TRACE_FLAG_ENABLED(grpc_api_trace)) { \ gpr_log(GPR_INFO, fmt GRPC_API_TRACE_UNWRAP##nargs args); \ } diff --git a/src/core/lib/surface/byte_buffer_reader.cc b/src/core/lib/surface/byte_buffer_reader.cc index 1debc98ea0c..ed8ecc49590 100644 --- a/src/core/lib/surface/byte_buffer_reader.cc +++ b/src/core/lib/surface/byte_buffer_reader.cc @@ -91,6 +91,23 @@ void grpc_byte_buffer_reader_destroy(grpc_byte_buffer_reader* reader) { } } +int grpc_byte_buffer_reader_peek(grpc_byte_buffer_reader* reader, + grpc_slice** slice) { + switch (reader->buffer_in->type) { + case GRPC_BB_RAW: { + grpc_slice_buffer* slice_buffer; + slice_buffer = &reader->buffer_out->data.raw.slice_buffer; + if (reader->current.index < slice_buffer->count) { + *slice = &slice_buffer->slices[reader->current.index]; + reader->current.index += 1; + return 1; + } + break; + } + } + return 0; +} + int grpc_byte_buffer_reader_next(grpc_byte_buffer_reader* reader, grpc_slice* slice) { switch (reader->buffer_in->type) { diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index 89b3f77822c..254476f47e3 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -35,14 +35,15 @@ #include "src/core/lib/compression/algorithm_metadata.h" #include "src/core/lib/debug/stats.h" #include "src/core/lib/gpr/alloc.h" -#include "src/core/lib/gpr/arena.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/useful.h" +#include "src/core/lib/gprpp/arena.h" #include "src/core/lib/gprpp/manual_constructor.h" +#include "src/core/lib/gprpp/ref_counted.h" #include "src/core/lib/iomgr/timer.h" #include "src/core/lib/profiling/timers.h" -#include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/slice/slice_string_helpers.h" +#include "src/core/lib/slice/slice_utils.h" #include "src/core/lib/surface/api_trace.h" #include "src/core/lib/surface/call.h" #include "src/core/lib/surface/call_test_only.h" @@ -124,14 +125,12 @@ struct child_call { #define RECV_INITIAL_METADATA_FIRST ((gpr_atm)1) struct grpc_call { - grpc_call(gpr_arena* arena, const grpc_call_create_args& args) + grpc_call(grpc_core::Arena* arena, const grpc_call_create_args& args) : arena(arena), cq(args.cq), channel(args.channel), is_client(args.server_transport_data == nullptr), stream_op_payload(context) { - gpr_ref_init(&ext_ref, 1); - grpc_call_combiner_init(&call_combiner); for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { metadata_batch[i][j].deadline = GRPC_MILLIS_INF_FUTURE; @@ -141,12 +140,11 @@ struct grpc_call { ~grpc_call() { gpr_free(static_cast(const_cast(final_info.error_string))); - grpc_call_combiner_destroy(&call_combiner); } - gpr_refcount ext_ref; - gpr_arena* arena; - grpc_call_combiner call_combiner; + grpc_core::RefCount ext_ref; + grpc_core::Arena* arena; + grpc_core::CallCombiner call_combiner; grpc_completion_queue* cq; grpc_polling_entity pollent; grpc_channel* channel; @@ -292,13 +290,13 @@ static void add_init_error(grpc_error** composite, grpc_error* new_err) { } void* grpc_call_arena_alloc(grpc_call* call, size_t size) { - return gpr_arena_alloc(call->arena, size); + return call->arena->Alloc(size); } static parent_call* get_or_create_parent_call(grpc_call* call) { parent_call* p = (parent_call*)gpr_atm_acq_load(&call->parent_call_atm); if (p == nullptr) { - p = new (gpr_arena_alloc(call->arena, sizeof(*p))) parent_call(); + p = call->arena->New(); if (!gpr_atm_rel_cas(&call->parent_call_atm, (gpr_atm) nullptr, (gpr_atm)p)) { p->~parent_call(); @@ -323,16 +321,23 @@ grpc_error* grpc_call_create(const grpc_call_create_args* args, GRPC_CHANNEL_INTERNAL_REF(args->channel, "call"); + grpc_core::Arena* arena; + grpc_call* call; grpc_error* error = GRPC_ERROR_NONE; grpc_channel_stack* channel_stack = grpc_channel_get_channel_stack(args->channel); - grpc_call* call; size_t initial_size = grpc_channel_get_call_size_estimate(args->channel); GRPC_STATS_INC_CALL_INITIAL_SIZE(initial_size); - gpr_arena* arena = gpr_arena_create(initial_size); - call = new (gpr_arena_alloc( - arena, GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_call)) + - channel_stack->call_stack_size)) grpc_call(arena, *args); + size_t call_and_stack_size = + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_call)) + + channel_stack->call_stack_size; + size_t call_alloc_size = + call_and_stack_size + (args->parent ? sizeof(child_call) : 0); + + std::pair arena_with_call = + grpc_core::Arena::CreateWithAlloc(initial_size, call_alloc_size); + arena = arena_with_call.first; + call = new (arena_with_call.second) grpc_call(arena, *args); *out_call = call; grpc_slice path = grpc_empty_slice(); if (call->is_client) { @@ -344,8 +349,8 @@ grpc_error* grpc_call_create(const grpc_call_create_args* args, MAX_SEND_EXTRA_METADATA_COUNT); for (size_t i = 0; i < args->add_initial_metadata_count; i++) { call->send_extra_metadata[i].md = args->add_initial_metadata[i]; - if (grpc_slice_eq(GRPC_MDKEY(args->add_initial_metadata[i]), - GRPC_MDSTR_PATH)) { + if (grpc_slice_eq_static_interned( + GRPC_MDKEY(args->add_initial_metadata[i]), GRPC_MDSTR_PATH)) { path = grpc_slice_ref_internal( GRPC_MDVALUE(args->add_initial_metadata[i])); } @@ -364,8 +369,8 @@ grpc_error* grpc_call_create(const grpc_call_create_args* args, bool immediately_cancel = false; if (args->parent != nullptr) { - call->child = new (gpr_arena_alloc(arena, sizeof(child_call))) - child_call(args->parent); + call->child = new (reinterpret_cast(arena_with_call.second) + + call_and_stack_size) child_call(args->parent); GRPC_CALL_INTERNAL_REF(args->parent, "child"); GPR_ASSERT(call->is_client); @@ -502,9 +507,9 @@ void grpc_call_internal_unref(grpc_call* c REF_ARG) { static void release_call(void* call, grpc_error* error) { grpc_call* c = static_cast(call); grpc_channel* channel = c->channel; - gpr_arena* arena = c->arena; + grpc_core::Arena* arena = c->arena; c->~grpc_call(); - grpc_channel_update_call_size_estimate(channel, gpr_arena_destroy(arena)); + grpc_channel_update_call_size_estimate(channel, arena->Destroy()); GRPC_CHANNEL_INTERNAL_UNREF(channel, "call"); } @@ -548,14 +553,15 @@ static void destroy_call(void* call, grpc_error* error) { grpc_schedule_on_exec_ctx)); } -void grpc_call_ref(grpc_call* c) { gpr_ref(&c->ext_ref); } +void grpc_call_ref(grpc_call* c) { c->ext_ref.Ref(); } void grpc_call_unref(grpc_call* c) { - if (!gpr_unref(&c->ext_ref)) return; + if (GPR_LIKELY(!c->ext_ref.Unref())) return; GPR_TIMER_SCOPE("grpc_call_unref", 0); child_call* cc = c->child; + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; grpc_core::ExecCtx exec_ctx; GRPC_API_TRACE("grpc_call_unref(c=%p)", 1, (c)); @@ -588,7 +594,7 @@ void grpc_call_unref(grpc_call* c) { // holding to the call stack. Also flush the closures on exec_ctx so that // filters that schedule cancel notification closures on exec_ctx do not // need to take a ref of the call stack to guarantee closure liveness. - grpc_call_combiner_set_notify_on_cancel(&c->call_combiner, nullptr); + c->call_combiner.SetNotifyOnCancel(nullptr); grpc_core::ExecCtx::Get()->Flush(); } GRPC_CALL_INTERNAL_UNREF(c, "destroy"); @@ -597,6 +603,7 @@ void grpc_call_unref(grpc_call* c) { grpc_call_error grpc_call_cancel(grpc_call* call, void* reserved) { GRPC_API_TRACE("grpc_call_cancel(call=%p, reserved=%p)", 2, (call, reserved)); GPR_ASSERT(!reserved); + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; grpc_core::ExecCtx exec_ctx; cancel_with_error(call, GRPC_ERROR_CANCELLED); return GRPC_CALL_OK; @@ -646,6 +653,7 @@ grpc_call_error grpc_call_cancel_with_status(grpc_call* c, grpc_status_code status, const char* description, void* reserved) { + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; grpc_core::ExecCtx exec_ctx; GRPC_API_TRACE( "grpc_call_cancel_with_status(" @@ -682,7 +690,7 @@ static void cancel_with_error(grpc_call* c, grpc_error* error) { // any in-flight asynchronous actions that may be holding the call // combiner. This ensures that the cancel_stream batch can be sent // down the filter stack in a timely manner. - grpc_call_combiner_cancel(&c->call_combiner, GRPC_ERROR_REF(error)); + c->call_combiner.Cancel(GRPC_ERROR_REF(error)); cancel_state* state = static_cast(gpr_malloc(sizeof(*state))); state->call = c; GRPC_CLOSURE_INIT(&state->finish_batch, done_termination, state, @@ -715,7 +723,7 @@ static void cancel_with_status(grpc_call* c, grpc_status_code status, } static void set_final_status(grpc_call* call, grpc_error* error) { - if (grpc_call_error_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_call_error_trace)) { gpr_log(GPR_DEBUG, "set_final_status %s", call->is_client ? "CLI" : "SVR"); gpr_log(GPR_DEBUG, "%s", grpc_error_string(error)); } @@ -1032,9 +1040,14 @@ static void recv_trailing_filter(void* args, grpc_metadata_batch* b, grpc_get_status_code_from_metadata(b->idx.named.grpc_status->md); grpc_error* error = GRPC_ERROR_NONE; if (status_code != GRPC_STATUS_OK) { - error = grpc_error_set_int( - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Error received from peer"), - GRPC_ERROR_INT_GRPC_STATUS, static_cast(status_code)); + char* peer_msg = nullptr; + char* peer = grpc_call_get_peer(call); + gpr_asprintf(&peer_msg, "Error received from peer %s", peer); + error = grpc_error_set_int(GRPC_ERROR_CREATE_FROM_COPIED_STRING(peer_msg), + GRPC_ERROR_INT_GRPC_STATUS, + static_cast(status_code)); + gpr_free(peer); + gpr_free(peer_msg); } if (b->idx.named.grpc_message != nullptr) { error = grpc_error_set_str( @@ -1061,7 +1074,7 @@ static void recv_trailing_filter(void* args, grpc_metadata_batch* b, publish_app_metadata(call, b, true); } -gpr_arena* grpc_call_get_arena(grpc_call* call) { return call->arena; } +grpc_core::Arena* grpc_call_get_arena(grpc_call* call) { return call->arena; } grpc_call_stack* grpc_call_get_call_stack(grpc_call* call) { return CALL_STACK_FROM_CALL(call); @@ -1122,8 +1135,7 @@ static batch_control* reuse_or_allocate_batch_control(grpc_call* call, bctl->~batch_control(); bctl->op = {}; } else { - bctl = new (gpr_arena_alloc(call->arena, sizeof(batch_control))) - batch_control(); + bctl = call->arena->New(); *pslot = bctl; } bctl->call = call; @@ -1213,7 +1225,7 @@ static void post_batch_completion(batch_control* bctl) { } static void finish_batch_step(batch_control* bctl) { - if (gpr_unref(&bctl->steps_to_complete)) { + if (GPR_UNLIKELY(gpr_unref(&bctl->steps_to_complete))) { post_batch_completion(bctl); } } @@ -1268,7 +1280,7 @@ static void receiving_slice_ready(void* bctlp, grpc_error* error) { } if (error != GRPC_ERROR_NONE) { - if (grpc_trace_operation_failures.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_trace_operation_failures)) { GRPC_LOG_IF_ERROR("receiving_slice_ready", GRPC_ERROR_REF(error)); } call->receiving_stream.reset(); @@ -1392,7 +1404,7 @@ static void validate_filtered_metadata(batch_control* bctl) { GPR_ASSERT(call->encodings_accepted_by_peer != 0); if (!GPR_BITGET(call->encodings_accepted_by_peer, compression_algorithm)) { - if (grpc_compression_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_compression_trace)) { const char* algo_name = nullptr; grpc_compression_algorithm_name(compression_algorithm, &algo_name); gpr_log(GPR_ERROR, @@ -1551,7 +1563,10 @@ static grpc_call_error call_start_batch(grpc_call* call, const grpc_op* ops, goto done_with_error; } /* process compression level */ - memset(&call->compression_md, 0, sizeof(call->compression_md)); + grpc_metadata& compression_md = call->compression_md; + compression_md.key = grpc_empty_slice(); + compression_md.value = grpc_empty_slice(); + compression_md.flags = 0; size_t additional_metadata_count = 0; grpc_compression_level effective_compression_level = GRPC_COMPRESS_LEVEL_NONE; @@ -1574,8 +1589,8 @@ static grpc_call_error call_start_batch(grpc_call* call, const grpc_op* ops, call, effective_compression_level); /* the following will be picked up by the compress filter and used * as the call's compression algorithm. */ - call->compression_md.key = GRPC_MDSTR_GRPC_INTERNAL_ENCODING_REQUEST; - call->compression_md.value = grpc_compression_algorithm_slice(calgo); + compression_md.key = GRPC_MDSTR_GRPC_INTERNAL_ENCODING_REQUEST; + compression_md.value = grpc_compression_algorithm_slice(calgo); additional_metadata_count++; } @@ -1589,8 +1604,7 @@ static grpc_call_error call_start_batch(grpc_call* call, const grpc_op* ops, if (!prepare_application_metadata( call, static_cast(op->data.send_initial_metadata.count), op->data.send_initial_metadata.metadata, 0, call->is_client, - &call->compression_md, - static_cast(additional_metadata_count))) { + &compression_md, static_cast(additional_metadata_count))) { error = GRPC_CALL_ERROR_INVALID_METADATA; goto done_with_error; } @@ -1894,7 +1908,6 @@ done_with_error: grpc_call_error grpc_call_start_batch(grpc_call* call, const grpc_op* ops, size_t nops, void* tag, void* reserved) { - grpc_core::ExecCtx exec_ctx; grpc_call_error err; GRPC_API_TRACE( @@ -1905,6 +1918,8 @@ grpc_call_error grpc_call_start_batch(grpc_call* call, const grpc_op* ops, if (reserved != nullptr) { err = GRPC_CALL_ERROR; } else { + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; + grpc_core::ExecCtx exec_ctx; err = call_start_batch(call, ops, nops, tag, 0); } diff --git a/src/core/lib/surface/call.h b/src/core/lib/surface/call.h index bd7295fe110..15392fea6dc 100644 --- a/src/core/lib/surface/call.h +++ b/src/core/lib/surface/call.h @@ -23,6 +23,7 @@ #include "src/core/lib/channel/channel_stack.h" #include "src/core/lib/channel/context.h" +#include "src/core/lib/gprpp/arena.h" #include "src/core/lib/surface/api_trace.h" #include @@ -72,7 +73,7 @@ void grpc_call_internal_unref(grpc_call* call); #define GRPC_CALL_INTERNAL_UNREF(call, reason) grpc_call_internal_unref(call) #endif -gpr_arena* grpc_call_get_arena(grpc_call* call); +grpc_core::Arena* grpc_call_get_arena(grpc_call* call); grpc_call_stack* grpc_call_get_call_stack(grpc_call* call); @@ -101,7 +102,11 @@ void grpc_call_context_set(grpc_call* call, grpc_context_index elem, void* grpc_call_context_get(grpc_call* call, grpc_context_index elem); #define GRPC_CALL_LOG_BATCH(sev, call, ops, nops, tag) \ - if (grpc_api_trace.enabled()) grpc_call_log_batch(sev, call, ops, nops, tag) + do { \ + if (GRPC_TRACE_FLAG_ENABLED(grpc_api_trace)) { \ + grpc_call_log_batch(sev, call, ops, nops, tag); \ + } \ + } while (0) uint8_t grpc_call_is_client(grpc_call* call); diff --git a/src/core/lib/surface/call_details.cc b/src/core/lib/surface/call_details.cc index 7f20b1dae74..55e9e3425f2 100644 --- a/src/core/lib/surface/call_details.cc +++ b/src/core/lib/surface/call_details.cc @@ -29,7 +29,6 @@ void grpc_call_details_init(grpc_call_details* cd) { GRPC_API_TRACE("grpc_call_details_init(cd=%p)", 1, (cd)); - memset(cd, 0, sizeof(*cd)); cd->method = grpc_empty_slice(); cd->host = grpc_empty_slice(); } diff --git a/src/core/lib/surface/channel_init.h b/src/core/lib/surface/channel_init.h index f01852473ba..d17a721606d 100644 --- a/src/core/lib/surface/channel_init.h +++ b/src/core/lib/surface/channel_init.h @@ -45,6 +45,11 @@ void grpc_channel_init_init(void); /// registration order (in the case of a tie). /// Stages are registered against one of the pre-determined channel stack /// types. +/// If the channel stack type is GRPC_CLIENT_SUBCHANNEL, the caller should +/// ensure that subchannels with different filter lists will always have +/// different channel args. This requires setting a channel arg in case the +/// registration function relies on some condition other than channel args to +/// decide whether to add a filter or not. void grpc_channel_init_register_stage(grpc_channel_stack_type type, int priority, grpc_channel_init_stage stage_fn, diff --git a/src/core/lib/surface/completion_queue.cc b/src/core/lib/surface/completion_queue.cc index 661022ec5f1..e796071eedc 100644 --- a/src/core/lib/surface/completion_queue.cc +++ b/src/core/lib/surface/completion_queue.cc @@ -33,6 +33,7 @@ #include "src/core/lib/gpr/spinlock.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/tls.h" +#include "src/core/lib/gprpp/atomic.h" #include "src/core/lib/iomgr/pollset.h" #include "src/core/lib/iomgr/timer.h" #include "src/core/lib/profiling/timers.h" @@ -44,6 +45,8 @@ grpc_core::TraceFlag grpc_trace_operation_failures(false, "op_failure"); grpc_core::DebugOnlyTraceFlag grpc_trace_pending_tags(false, "pending_tags"); grpc_core::DebugOnlyTraceFlag grpc_trace_cq_refcount(false, "cq_refcount"); +namespace { + // Specifies a cq thread local cache. // The first event that occurs on a thread // with a cq cache will go into that cache, and @@ -84,24 +87,22 @@ typedef struct { grpc_closure* shutdown; } non_polling_poller; -static size_t non_polling_poller_size(void) { - return sizeof(non_polling_poller); -} +size_t non_polling_poller_size(void) { return sizeof(non_polling_poller); } -static void non_polling_poller_init(grpc_pollset* pollset, gpr_mu** mu) { +void non_polling_poller_init(grpc_pollset* pollset, gpr_mu** mu) { non_polling_poller* npp = reinterpret_cast(pollset); gpr_mu_init(&npp->mu); *mu = &npp->mu; } -static void non_polling_poller_destroy(grpc_pollset* pollset) { +void non_polling_poller_destroy(grpc_pollset* pollset) { non_polling_poller* npp = reinterpret_cast(pollset); gpr_mu_destroy(&npp->mu); } -static grpc_error* non_polling_poller_work(grpc_pollset* pollset, - grpc_pollset_worker** worker, - grpc_millis deadline) { +grpc_error* non_polling_poller_work(grpc_pollset* pollset, + grpc_pollset_worker** worker, + grpc_millis deadline) { non_polling_poller* npp = reinterpret_cast(pollset); if (npp->shutdown) return GRPC_ERROR_NONE; if (npp->kicked_without_poller) { @@ -141,8 +142,8 @@ static grpc_error* non_polling_poller_work(grpc_pollset* pollset, return GRPC_ERROR_NONE; } -static grpc_error* non_polling_poller_kick( - grpc_pollset* pollset, grpc_pollset_worker* specific_worker) { +grpc_error* non_polling_poller_kick(grpc_pollset* pollset, + grpc_pollset_worker* specific_worker) { non_polling_poller* p = reinterpret_cast(pollset); if (specific_worker == nullptr) specific_worker = reinterpret_cast(p->root); @@ -159,8 +160,7 @@ static grpc_error* non_polling_poller_kick( return GRPC_ERROR_NONE; } -static void non_polling_poller_shutdown(grpc_pollset* pollset, - grpc_closure* closure) { +void non_polling_poller_shutdown(grpc_pollset* pollset, grpc_closure* closure) { non_polling_poller* p = reinterpret_cast(pollset); GPR_ASSERT(closure != nullptr); p->shutdown = closure; @@ -175,7 +175,7 @@ static void non_polling_poller_shutdown(grpc_pollset* pollset, } } -static const cq_poller_vtable g_poller_vtable_by_poller_type[] = { +const cq_poller_vtable g_poller_vtable_by_poller_type[] = { /* GRPC_CQ_DEFAULT_POLLING */ {true, true, grpc_pollset_size, grpc_pollset_init, grpc_pollset_kick, grpc_pollset_work, grpc_pollset_shutdown, grpc_pollset_destroy}, @@ -188,7 +188,9 @@ static const cq_poller_vtable g_poller_vtable_by_poller_type[] = { non_polling_poller_shutdown, non_polling_poller_destroy}, }; -typedef struct cq_vtable { +} // namespace + +struct cq_vtable { grpc_cq_completion_type cq_completion_type; size_t data_size; void (*init)(void* data, @@ -203,80 +205,116 @@ typedef struct cq_vtable { void* reserved); grpc_event (*pluck)(grpc_completion_queue* cq, void* tag, gpr_timespec deadline, void* reserved); -} cq_vtable; +}; + +namespace { /* Queue that holds the cq_completion_events. Internally uses gpr_mpscq queue * (a lockfree multiproducer single consumer queue). It uses a queue_lock * to support multiple consumers. * Only used in completion queues whose completion_type is GRPC_CQ_NEXT */ -typedef struct grpc_cq_event_queue { - /* Spinlock to serialize consumers i.e pop() operations */ - gpr_spinlock queue_lock; +class CqEventQueue { + public: + CqEventQueue() { gpr_mpscq_init(&queue_); } + ~CqEventQueue() { gpr_mpscq_destroy(&queue_); } - gpr_mpscq queue; + /* Note: The counter is not incremented/decremented atomically with push/pop. + * The count is only eventually consistent */ + intptr_t num_items() const { + return num_queue_items_.Load(grpc_core::MemoryOrder::RELAXED); + } + + bool Push(grpc_cq_completion* c); + grpc_cq_completion* Pop(); + + private: + /* Spinlock to serialize consumers i.e pop() operations */ + gpr_spinlock queue_lock_ = GPR_SPINLOCK_INITIALIZER; + + gpr_mpscq queue_; /* A lazy counter of number of items in the queue. This is NOT atomically incremented/decremented along with push/pop operations and hence is only eventually consistent */ - gpr_atm num_queue_items; -} grpc_cq_event_queue; + grpc_core::Atomic num_queue_items_{0}; +}; + +struct cq_next_data { + ~cq_next_data() { GPR_ASSERT(queue.num_items() == 0); } -typedef struct cq_next_data { /** Completed events for completion-queues of type GRPC_CQ_NEXT */ - grpc_cq_event_queue queue; + CqEventQueue queue; /** Counter of how many things have ever been queued on this completion queue useful for avoiding locks to check the queue */ - gpr_atm things_queued_ever; + grpc_core::Atomic things_queued_ever{0}; - /* Number of outstanding events (+1 if not shut down) */ - gpr_atm pending_events; + /** Number of outstanding events (+1 if not shut down) + Initial count is dropped by grpc_completion_queue_shutdown */ + grpc_core::Atomic pending_events{1}; /** 0 initially. 1 once we initiated shutdown */ - bool shutdown_called; -} cq_next_data; + bool shutdown_called = false; +}; + +struct cq_pluck_data { + cq_pluck_data() { + completed_tail = &completed_head; + completed_head.next = reinterpret_cast(completed_tail); + } + + ~cq_pluck_data() { + GPR_ASSERT(completed_head.next == + reinterpret_cast(&completed_head)); + } -typedef struct cq_pluck_data { /** Completed events for completion-queues of type GRPC_CQ_PLUCK */ grpc_cq_completion completed_head; grpc_cq_completion* completed_tail; - /** Number of pending events (+1 if we're not shutdown) */ - gpr_atm pending_events; + /** Number of pending events (+1 if we're not shutdown). + Initial count is dropped by grpc_completion_queue_shutdown. */ + grpc_core::Atomic pending_events{1}; /** Counter of how many things have ever been queued on this completion queue useful for avoiding locks to check the queue */ - gpr_atm things_queued_ever; + grpc_core::Atomic things_queued_ever{0}; /** 0 initially. 1 once we completed shutting */ /* TODO: (sreek) This is not needed since (shutdown == 1) if and only if * (pending_events == 0). So consider removing this in future and use * pending_events */ - gpr_atm shutdown; + grpc_core::Atomic shutdown{false}; /** 0 initially. 1 once we initiated shutdown */ - bool shutdown_called; + bool shutdown_called = false; - int num_pluckers; + int num_pluckers = 0; plucker pluckers[GRPC_MAX_COMPLETION_QUEUE_PLUCKERS]; -} cq_pluck_data; +}; -typedef struct cq_callback_data { +struct cq_callback_data { + cq_callback_data( + grpc_experimental_completion_queue_functor* shutdown_callback) + : shutdown_callback(shutdown_callback) {} /** No actual completed events queue, unlike other types */ - /** Number of pending events (+1 if we're not shutdown) */ - gpr_atm pending_events; + /** Number of pending events (+1 if we're not shutdown). + Initial count is dropped by grpc_completion_queue_shutdown. */ + grpc_core::Atomic pending_events{1}; /** Counter of how many things have ever been queued on this completion queue useful for avoiding locks to check the queue */ - gpr_atm things_queued_ever; + grpc_core::Atomic things_queued_ever{0}; /** 0 initially. 1 once we initiated shutdown */ - bool shutdown_called; + bool shutdown_called = false; /** A callback that gets invoked when the CQ completes shutdown */ grpc_experimental_completion_queue_functor* shutdown_callback; -} cq_callback_data; +}; + +} // namespace /* Completion queue structure */ struct grpc_completion_queue { @@ -373,13 +411,16 @@ static const cq_vtable g_cq_vtable[] = { grpc_core::TraceFlag grpc_cq_pluck_trace(false, "queue_pluck"); -#define GRPC_SURFACE_TRACE_RETURNED_EVENT(cq, event) \ - if (grpc_api_trace.enabled() && (grpc_cq_pluck_trace.enabled() || \ - (event)->type != GRPC_QUEUE_TIMEOUT)) { \ - char* _ev = grpc_event_string(event); \ - gpr_log(GPR_INFO, "RETURN_EVENT[%p]: %s", cq, _ev); \ - gpr_free(_ev); \ - } +#define GRPC_SURFACE_TRACE_RETURNED_EVENT(cq, event) \ + do { \ + if (GRPC_TRACE_FLAG_ENABLED(grpc_api_trace) && \ + (GRPC_TRACE_FLAG_ENABLED(grpc_cq_pluck_trace) || \ + (event)->type != GRPC_QUEUE_TIMEOUT)) { \ + char* _ev = grpc_event_string(event); \ + gpr_log(GPR_INFO, "RETURN_EVENT[%p]: %s", cq, _ev); \ + gpr_free(_ev); \ + } \ + } while (0) static void on_pollset_shutdown_done(void* cq, grpc_error* error); @@ -408,7 +449,7 @@ int grpc_completion_queue_thread_local_cache_flush(grpc_completion_queue* cq, storage->done(storage->done_arg, storage); ret = 1; cq_next_data* cqd = static_cast DATA_FROM_CQ(cq); - if (gpr_atm_full_fetch_add(&cqd->pending_events, -1) == 1) { + if (cqd->pending_events.FetchSub(1, grpc_core::MemoryOrder::ACQ_REL) == 1) { GRPC_CQ_INTERNAL_REF(cq, "shutting_down"); gpr_mu_lock(cq->mu); cq_finish_shutdown_next(cq); @@ -422,31 +463,21 @@ int grpc_completion_queue_thread_local_cache_flush(grpc_completion_queue* cq, return ret; } -static void cq_event_queue_init(grpc_cq_event_queue* q) { - gpr_mpscq_init(&q->queue); - q->queue_lock = GPR_SPINLOCK_INITIALIZER; - gpr_atm_no_barrier_store(&q->num_queue_items, 0); +bool CqEventQueue::Push(grpc_cq_completion* c) { + gpr_mpscq_push(&queue_, reinterpret_cast(c)); + return num_queue_items_.FetchAdd(1, grpc_core::MemoryOrder::RELAXED) == 0; } -static void cq_event_queue_destroy(grpc_cq_event_queue* q) { - gpr_mpscq_destroy(&q->queue); -} - -static bool cq_event_queue_push(grpc_cq_event_queue* q, grpc_cq_completion* c) { - gpr_mpscq_push(&q->queue, reinterpret_cast(c)); - return gpr_atm_no_barrier_fetch_add(&q->num_queue_items, 1) == 0; -} - -static grpc_cq_completion* cq_event_queue_pop(grpc_cq_event_queue* q) { +grpc_cq_completion* CqEventQueue::Pop() { grpc_cq_completion* c = nullptr; - if (gpr_spinlock_trylock(&q->queue_lock)) { + if (gpr_spinlock_trylock(&queue_lock_)) { GRPC_STATS_INC_CQ_EV_QUEUE_TRYLOCK_SUCCESSES(); bool is_empty = false; c = reinterpret_cast( - gpr_mpscq_pop_and_check_end(&q->queue, &is_empty)); - gpr_spinlock_unlock(&q->queue_lock); + gpr_mpscq_pop_and_check_end(&queue_, &is_empty)); + gpr_spinlock_unlock(&queue_lock_); if (c == nullptr && !is_empty) { GRPC_STATS_INC_CQ_EV_QUEUE_TRANSIENT_POP_FAILURES(); @@ -456,18 +487,12 @@ static grpc_cq_completion* cq_event_queue_pop(grpc_cq_event_queue* q) { } if (c) { - gpr_atm_no_barrier_fetch_add(&q->num_queue_items, -1); + num_queue_items_.FetchSub(1, grpc_core::MemoryOrder::RELAXED); } return c; } -/* Note: The counter is not incremented/decremented atomically with push/pop. - * The count is only eventually consistent */ -static long cq_event_queue_num_items(grpc_cq_event_queue* q) { - return static_cast(gpr_atm_no_barrier_load(&q->num_queue_items)); -} - grpc_completion_queue* grpc_completion_queue_create_internal( grpc_cq_completion_type completion_type, grpc_cq_polling_type polling_type, grpc_experimental_completion_queue_functor* shutdown_callback) { @@ -507,49 +532,33 @@ grpc_completion_queue* grpc_completion_queue_create_internal( static void cq_init_next( void* data, grpc_experimental_completion_queue_functor* shutdown_callback) { - cq_next_data* cqd = static_cast(data); - /* Initial count is dropped by grpc_completion_queue_shutdown */ - gpr_atm_no_barrier_store(&cqd->pending_events, 1); - cqd->shutdown_called = false; - gpr_atm_no_barrier_store(&cqd->things_queued_ever, 0); - cq_event_queue_init(&cqd->queue); + new (data) cq_next_data(); } static void cq_destroy_next(void* data) { cq_next_data* cqd = static_cast(data); - GPR_ASSERT(cq_event_queue_num_items(&cqd->queue) == 0); - cq_event_queue_destroy(&cqd->queue); + cqd->~cq_next_data(); } static void cq_init_pluck( void* data, grpc_experimental_completion_queue_functor* shutdown_callback) { - cq_pluck_data* cqd = static_cast(data); - /* Initial count is dropped by grpc_completion_queue_shutdown */ - gpr_atm_no_barrier_store(&cqd->pending_events, 1); - cqd->completed_tail = &cqd->completed_head; - cqd->completed_head.next = (uintptr_t)cqd->completed_tail; - gpr_atm_no_barrier_store(&cqd->shutdown, 0); - cqd->shutdown_called = false; - cqd->num_pluckers = 0; - gpr_atm_no_barrier_store(&cqd->things_queued_ever, 0); + new (data) cq_pluck_data(); } static void cq_destroy_pluck(void* data) { cq_pluck_data* cqd = static_cast(data); - GPR_ASSERT(cqd->completed_head.next == (uintptr_t)&cqd->completed_head); + cqd->~cq_pluck_data(); } static void cq_init_callback( void* data, grpc_experimental_completion_queue_functor* shutdown_callback) { - cq_callback_data* cqd = static_cast(data); - /* Initial count is dropped by grpc_completion_queue_shutdown */ - gpr_atm_no_barrier_store(&cqd->pending_events, 1); - cqd->shutdown_called = false; - gpr_atm_no_barrier_store(&cqd->things_queued_ever, 0); - cqd->shutdown_callback = shutdown_callback; + new (data) cq_callback_data(shutdown_callback); } -static void cq_destroy_callback(void* data) {} +static void cq_destroy_callback(void* data) { + cq_callback_data* cqd = static_cast(data); + cqd->~cq_callback_data(); +} grpc_cq_completion_type grpc_get_cq_completion_type(grpc_completion_queue* cq) { return cq->vtable->cq_completion_type; @@ -566,7 +575,7 @@ int grpc_get_cq_poll_num(grpc_completion_queue* cq) { #ifndef NDEBUG void grpc_cq_internal_ref(grpc_completion_queue* cq, const char* reason, const char* file, int line) { - if (grpc_trace_cq_refcount.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_trace_cq_refcount)) { gpr_atm val = gpr_atm_no_barrier_load(&cq->owning_refs.count); gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "CQ:%p ref %" PRIdPTR " -> %" PRIdPTR " %s", cq, val, val + 1, @@ -586,7 +595,7 @@ static void on_pollset_shutdown_done(void* arg, grpc_error* error) { #ifndef NDEBUG void grpc_cq_internal_unref(grpc_completion_queue* cq, const char* reason, const char* file, int line) { - if (grpc_trace_cq_refcount.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_trace_cq_refcount)) { gpr_atm val = gpr_atm_no_barrier_load(&cq->owning_refs.count); gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "CQ:%p unref %" PRIdPTR " -> %" PRIdPTR " %s", cq, val, val - 1, @@ -632,37 +641,19 @@ static void cq_check_tag(grpc_completion_queue* cq, void* tag, bool lock_cq) { static void cq_check_tag(grpc_completion_queue* cq, void* tag, bool lock_cq) {} #endif -/* Atomically increments a counter only if the counter is not zero. Returns - * true if the increment was successful; false if the counter is zero */ -static bool atm_inc_if_nonzero(gpr_atm* counter) { - while (true) { - gpr_atm count = gpr_atm_acq_load(counter); - /* If zero, we are done. If not, we must to a CAS (instead of an atomic - * increment) to maintain the contract: do not increment the counter if it - * is zero. */ - if (count == 0) { - return false; - } else if (gpr_atm_full_cas(counter, count, count + 1)) { - break; - } - } - - return true; -} - static bool cq_begin_op_for_next(grpc_completion_queue* cq, void* tag) { cq_next_data* cqd = static_cast DATA_FROM_CQ(cq); - return atm_inc_if_nonzero(&cqd->pending_events); + return cqd->pending_events.IncrementIfNonzero(); } static bool cq_begin_op_for_pluck(grpc_completion_queue* cq, void* tag) { cq_pluck_data* cqd = static_cast DATA_FROM_CQ(cq); - return atm_inc_if_nonzero(&cqd->pending_events); + return cqd->pending_events.IncrementIfNonzero(); } static bool cq_begin_op_for_callback(grpc_completion_queue* cq, void* tag) { cq_callback_data* cqd = static_cast DATA_FROM_CQ(cq); - return atm_inc_if_nonzero(&cqd->pending_events); + return cqd->pending_events.IncrementIfNonzero(); } bool grpc_cq_begin_op(grpc_completion_queue* cq, void* tag) { @@ -690,14 +681,16 @@ static void cq_end_op_for_next(grpc_completion_queue* cq, void* tag, void* done_arg, grpc_cq_completion* storage) { GPR_TIMER_SCOPE("cq_end_op_for_next", 0); - if (grpc_api_trace.enabled() || - (grpc_trace_operation_failures.enabled() && error != GRPC_ERROR_NONE)) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_api_trace) || + (GRPC_TRACE_FLAG_ENABLED(grpc_trace_operation_failures) && + error != GRPC_ERROR_NONE)) { const char* errmsg = grpc_error_string(error); GRPC_API_TRACE( "cq_end_op_for_next(cq=%p, tag=%p, error=%s, " "done=%p, done_arg=%p, storage=%p)", 6, (cq, tag, errmsg, done, done_arg, storage)); - if (grpc_trace_operation_failures.enabled() && error != GRPC_ERROR_NONE) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_trace_operation_failures) && + error != GRPC_ERROR_NONE) { gpr_log(GPR_ERROR, "Operation failed: tag=%p, error=%s", tag, errmsg); } } @@ -716,17 +709,14 @@ static void cq_end_op_for_next(grpc_completion_queue* cq, void* tag, gpr_tls_set(&g_cached_event, (intptr_t)storage); } else { /* Add the completion to the queue */ - bool is_first = cq_event_queue_push(&cqd->queue, storage); - gpr_atm_no_barrier_fetch_add(&cqd->things_queued_ever, 1); - + bool is_first = cqd->queue.Push(storage); + cqd->things_queued_ever.FetchAdd(1, grpc_core::MemoryOrder::RELAXED); /* Since we do not hold the cq lock here, it is important to do an 'acquire' load here (instead of a 'no_barrier' load) to match with the release store - (done via gpr_atm_full_fetch_add(pending_events, -1)) in cq_shutdown_next + (done via pending_events.FetchSub(1, ACQ_REL)) in cq_shutdown_next */ - bool will_definitely_shutdown = gpr_atm_acq_load(&cqd->pending_events) == 1; - - if (!will_definitely_shutdown) { + if (cqd->pending_events.Load(grpc_core::MemoryOrder::ACQUIRE) != 1) { /* Only kick if this is the first item queued */ if (is_first) { gpr_mu_lock(cq->mu); @@ -740,7 +730,8 @@ static void cq_end_op_for_next(grpc_completion_queue* cq, void* tag, GRPC_ERROR_UNREF(kick_error); } } - if (gpr_atm_full_fetch_add(&cqd->pending_events, -1) == 1) { + if (cqd->pending_events.FetchSub(1, grpc_core::MemoryOrder::ACQ_REL) == + 1) { GRPC_CQ_INTERNAL_REF(cq, "shutting_down"); gpr_mu_lock(cq->mu); cq_finish_shutdown_next(cq); @@ -749,7 +740,7 @@ static void cq_end_op_for_next(grpc_completion_queue* cq, void* tag, } } else { GRPC_CQ_INTERNAL_REF(cq, "shutting_down"); - gpr_atm_rel_store(&cqd->pending_events, 0); + cqd->pending_events.Store(0, grpc_core::MemoryOrder::RELEASE); gpr_mu_lock(cq->mu); cq_finish_shutdown_next(cq); gpr_mu_unlock(cq->mu); @@ -773,14 +764,16 @@ static void cq_end_op_for_pluck(grpc_completion_queue* cq, void* tag, cq_pluck_data* cqd = static_cast DATA_FROM_CQ(cq); int is_success = (error == GRPC_ERROR_NONE); - if (grpc_api_trace.enabled() || - (grpc_trace_operation_failures.enabled() && error != GRPC_ERROR_NONE)) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_api_trace) || + (GRPC_TRACE_FLAG_ENABLED(grpc_trace_operation_failures) && + error != GRPC_ERROR_NONE)) { const char* errmsg = grpc_error_string(error); GRPC_API_TRACE( "cq_end_op_for_pluck(cq=%p, tag=%p, error=%s, " "done=%p, done_arg=%p, storage=%p)", 6, (cq, tag, errmsg, done, done_arg, storage)); - if (grpc_trace_operation_failures.enabled() && error != GRPC_ERROR_NONE) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_trace_operation_failures) && + error != GRPC_ERROR_NONE) { gpr_log(GPR_ERROR, "Operation failed: tag=%p, error=%s", tag, errmsg); } } @@ -795,12 +788,12 @@ static void cq_end_op_for_pluck(grpc_completion_queue* cq, void* tag, cq_check_tag(cq, tag, false); /* Used in debug builds only */ /* Add to the list of completions */ - gpr_atm_no_barrier_fetch_add(&cqd->things_queued_ever, 1); + cqd->things_queued_ever.FetchAdd(1, grpc_core::MemoryOrder::RELAXED); cqd->completed_tail->next = ((uintptr_t)storage) | (1u & cqd->completed_tail->next); cqd->completed_tail = storage; - if (gpr_atm_full_fetch_add(&cqd->pending_events, -1) == 1) { + if (cqd->pending_events.FetchSub(1, grpc_core::MemoryOrder::ACQ_REL) == 1) { cq_finish_shutdown_pluck(cq); gpr_mu_unlock(cq->mu); } else { @@ -838,14 +831,16 @@ static void cq_end_op_for_callback( cq_callback_data* cqd = static_cast DATA_FROM_CQ(cq); bool is_success = (error == GRPC_ERROR_NONE); - if (grpc_api_trace.enabled() || - (grpc_trace_operation_failures.enabled() && error != GRPC_ERROR_NONE)) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_api_trace) || + (GRPC_TRACE_FLAG_ENABLED(grpc_trace_operation_failures) && + error != GRPC_ERROR_NONE)) { const char* errmsg = grpc_error_string(error); GRPC_API_TRACE( "cq_end_op_for_callback(cq=%p, tag=%p, error=%s, " "done=%p, done_arg=%p, storage=%p)", 6, (cq, tag, errmsg, done, done_arg, storage)); - if (grpc_trace_operation_failures.enabled() && error != GRPC_ERROR_NONE) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_trace_operation_failures) && + error != GRPC_ERROR_NONE) { gpr_log(GPR_ERROR, "Operation failed: tag=%p, error=%s", tag, errmsg); } } @@ -854,21 +849,17 @@ static void cq_end_op_for_callback( // for reserved storage. Invoke the done callback right away to release it. done(done_arg, storage); - gpr_mu_lock(cq->mu); - cq_check_tag(cq, tag, false); /* Used in debug builds only */ + cq_check_tag(cq, tag, true); /* Used in debug builds only */ - gpr_atm_no_barrier_fetch_add(&cqd->things_queued_ever, 1); - if (gpr_atm_full_fetch_add(&cqd->pending_events, -1) == 1) { - gpr_mu_unlock(cq->mu); + cqd->things_queued_ever.FetchAdd(1, grpc_core::MemoryOrder::RELAXED); + if (cqd->pending_events.FetchSub(1, grpc_core::MemoryOrder::ACQ_REL) == 1) { cq_finish_shutdown_callback(cq); - } else { - gpr_mu_unlock(cq->mu); } GRPC_ERROR_UNREF(error); auto* functor = static_cast(tag); - (*functor->functor_run)(functor, is_success); + grpc_core::ApplicationCallbackExecCtx::Enqueue(functor, is_success); } void grpc_cq_end_op(grpc_completion_queue* cq, void* tag, grpc_error* error, @@ -897,20 +888,20 @@ class ExecCtxNext : public grpc_core::ExecCtx { cq_next_data* cqd = static_cast DATA_FROM_CQ(cq); GPR_ASSERT(a->stolen_completion == nullptr); - gpr_atm current_last_seen_things_queued_ever = - gpr_atm_no_barrier_load(&cqd->things_queued_ever); + intptr_t current_last_seen_things_queued_ever = + cqd->things_queued_ever.Load(grpc_core::MemoryOrder::RELAXED); if (current_last_seen_things_queued_ever != a->last_seen_things_queued_ever) { a->last_seen_things_queued_ever = - gpr_atm_no_barrier_load(&cqd->things_queued_ever); + cqd->things_queued_ever.Load(grpc_core::MemoryOrder::RELAXED); /* Pop a cq_completion from the queue. Returns NULL if the queue is empty * might return NULL in some cases even if the queue is not empty; but * that * is ok and doesn't affect correctness. Might effect the tail latencies a * bit) */ - a->stolen_completion = cq_event_queue_pop(&cqd->queue); + a->stolen_completion = cqd->queue.Pop(); if (a->stolen_completion != nullptr) { return true; } @@ -924,7 +915,7 @@ class ExecCtxNext : public grpc_core::ExecCtx { #ifndef NDEBUG static void dump_pending_tags(grpc_completion_queue* cq) { - if (!grpc_trace_pending_tags.enabled()) return; + if (!GRPC_TRACE_FLAG_ENABLED(grpc_trace_pending_tags)) return; gpr_strvec v; gpr_strvec_init(&v); @@ -969,7 +960,7 @@ static grpc_event cq_next(grpc_completion_queue* cq, gpr_timespec deadline, grpc_millis deadline_millis = grpc_timespec_to_millis_round_up(deadline); cq_is_finished_arg is_finished_arg = { - gpr_atm_no_barrier_load(&cqd->things_queued_ever), + cqd->things_queued_ever.Load(grpc_core::MemoryOrder::RELAXED), cq, deadline_millis, nullptr, @@ -989,7 +980,7 @@ static grpc_event cq_next(grpc_completion_queue* cq, gpr_timespec deadline, break; } - grpc_cq_completion* c = cq_event_queue_pop(&cqd->queue); + grpc_cq_completion* c = cqd->queue.Pop(); if (c != nullptr) { ret.type = GRPC_OP_COMPLETE; @@ -1003,16 +994,16 @@ static grpc_event cq_next(grpc_completion_queue* cq, gpr_timespec deadline, so that the thread comes back quickly from poll to make a second attempt at popping. Not doing this can potentially deadlock this thread forever (if the deadline is infinity) */ - if (cq_event_queue_num_items(&cqd->queue) > 0) { + if (cqd->queue.num_items() > 0) { iteration_deadline = 0; } } - if (gpr_atm_acq_load(&cqd->pending_events) == 0) { + if (cqd->pending_events.Load(grpc_core::MemoryOrder::ACQUIRE) == 0) { /* Before returning, check if the queue has any items left over (since gpr_mpscq_pop() can sometimes return NULL even if the queue is not empty. If so, keep retrying but do not return GRPC_QUEUE_SHUTDOWN */ - if (cq_event_queue_num_items(&cqd->queue) > 0) { + if (cqd->queue.num_items() > 0) { /* Go to the beginning of the loop. No point doing a poll because (cq->shutdown == true) is only possible when there is no pending work (i.e cq->pending_events == 0) and any outstanding completion @@ -1020,15 +1011,15 @@ static grpc_event cq_next(grpc_completion_queue* cq, gpr_timespec deadline, continue; } - memset(&ret, 0, sizeof(ret)); ret.type = GRPC_QUEUE_SHUTDOWN; + ret.success = 0; break; } if (!is_finished_arg.first_loop && grpc_core::ExecCtx::Get()->Now() >= deadline_millis) { - memset(&ret, 0, sizeof(ret)); ret.type = GRPC_QUEUE_TIMEOUT; + ret.success = 0; dump_pending_tags(cq); break; } @@ -1045,16 +1036,16 @@ static grpc_event cq_next(grpc_completion_queue* cq, gpr_timespec deadline, gpr_log(GPR_ERROR, "Completion queue next failed: %s", msg); GRPC_ERROR_UNREF(err); - memset(&ret, 0, sizeof(ret)); ret.type = GRPC_QUEUE_TIMEOUT; + ret.success = 0; dump_pending_tags(cq); break; } is_finished_arg.first_loop = false; } - if (cq_event_queue_num_items(&cqd->queue) > 0 && - gpr_atm_acq_load(&cqd->pending_events) > 0) { + if (cqd->queue.num_items() > 0 && + cqd->pending_events.Load(grpc_core::MemoryOrder::ACQUIRE) > 0) { gpr_mu_lock(cq->mu); cq->poller_vtable->kick(POLLSET_FROM_CQ(cq), nullptr); gpr_mu_unlock(cq->mu); @@ -1078,7 +1069,7 @@ static void cq_finish_shutdown_next(grpc_completion_queue* cq) { cq_next_data* cqd = static_cast DATA_FROM_CQ(cq); GPR_ASSERT(cqd->shutdown_called); - GPR_ASSERT(gpr_atm_no_barrier_load(&cqd->pending_events) == 0); + GPR_ASSERT(cqd->pending_events.Load(grpc_core::MemoryOrder::RELAXED) == 0); cq->poller_vtable->shutdown(POLLSET_FROM_CQ(cq), &cq->pollset_shutdown_done); } @@ -1100,10 +1091,10 @@ static void cq_shutdown_next(grpc_completion_queue* cq) { return; } cqd->shutdown_called = true; - /* Doing a full_fetch_add (i.e acq/release) here to match with - * cq_begin_op_for_next and and cq_end_op_for_next functions which read/write + /* Doing acq/release FetchSub here to match with + * cq_begin_op_for_next and cq_end_op_for_next functions which read/write * on this counter without necessarily holding a lock on cq */ - if (gpr_atm_full_fetch_add(&cqd->pending_events, -1) == 1) { + if (cqd->pending_events.FetchSub(1, grpc_core::MemoryOrder::ACQ_REL) == 1) { cq_finish_shutdown_next(cq); } gpr_mu_unlock(cq->mu); @@ -1152,12 +1143,12 @@ class ExecCtxPluck : public grpc_core::ExecCtx { GPR_ASSERT(a->stolen_completion == nullptr); gpr_atm current_last_seen_things_queued_ever = - gpr_atm_no_barrier_load(&cqd->things_queued_ever); + cqd->things_queued_ever.Load(grpc_core::MemoryOrder::RELAXED); if (current_last_seen_things_queued_ever != a->last_seen_things_queued_ever) { gpr_mu_lock(cq->mu); a->last_seen_things_queued_ever = - gpr_atm_no_barrier_load(&cqd->things_queued_ever); + cqd->things_queued_ever.Load(grpc_core::MemoryOrder::RELAXED); grpc_cq_completion* c; grpc_cq_completion* prev = &cqd->completed_head; while ((c = (grpc_cq_completion*)(prev->next & @@ -1194,7 +1185,7 @@ static grpc_event cq_pluck(grpc_completion_queue* cq, void* tag, grpc_pollset_worker* worker = nullptr; cq_pluck_data* cqd = static_cast DATA_FROM_CQ(cq); - if (grpc_cq_pluck_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_cq_pluck_trace)) { GRPC_API_TRACE( "grpc_completion_queue_pluck(" "cq=%p, tag=%p, " @@ -1213,7 +1204,7 @@ static grpc_event cq_pluck(grpc_completion_queue* cq, void* tag, gpr_mu_lock(cq->mu); grpc_millis deadline_millis = grpc_timespec_to_millis_round_up(deadline); cq_is_finished_arg is_finished_arg = { - gpr_atm_no_barrier_load(&cqd->things_queued_ever), + cqd->things_queued_ever.Load(grpc_core::MemoryOrder::RELAXED), cq, deadline_millis, nullptr, @@ -1250,10 +1241,10 @@ static grpc_event cq_pluck(grpc_completion_queue* cq, void* tag, } prev = c; } - if (gpr_atm_no_barrier_load(&cqd->shutdown)) { + if (cqd->shutdown.Load(grpc_core::MemoryOrder::RELAXED)) { gpr_mu_unlock(cq->mu); - memset(&ret, 0, sizeof(ret)); ret.type = GRPC_QUEUE_SHUTDOWN; + ret.success = 0; break; } if (!add_plucker(cq, tag, &worker)) { @@ -1262,9 +1253,9 @@ static grpc_event cq_pluck(grpc_completion_queue* cq, void* tag, "is %d", GRPC_MAX_COMPLETION_QUEUE_PLUCKERS); gpr_mu_unlock(cq->mu); - memset(&ret, 0, sizeof(ret)); /* TODO(ctiller): should we use a different result here */ ret.type = GRPC_QUEUE_TIMEOUT; + ret.success = 0; dump_pending_tags(cq); break; } @@ -1272,8 +1263,8 @@ static grpc_event cq_pluck(grpc_completion_queue* cq, void* tag, grpc_core::ExecCtx::Get()->Now() >= deadline_millis) { del_plucker(cq, tag, &worker); gpr_mu_unlock(cq->mu); - memset(&ret, 0, sizeof(ret)); ret.type = GRPC_QUEUE_TIMEOUT; + ret.success = 0; dump_pending_tags(cq); break; } @@ -1287,8 +1278,8 @@ static grpc_event cq_pluck(grpc_completion_queue* cq, void* tag, gpr_log(GPR_ERROR, "Completion queue pluck failed: %s", msg); GRPC_ERROR_UNREF(err); - memset(&ret, 0, sizeof(ret)); ret.type = GRPC_QUEUE_TIMEOUT; + ret.success = 0; dump_pending_tags(cq); break; } @@ -1313,8 +1304,8 @@ static void cq_finish_shutdown_pluck(grpc_completion_queue* cq) { cq_pluck_data* cqd = static_cast DATA_FROM_CQ(cq); GPR_ASSERT(cqd->shutdown_called); - GPR_ASSERT(!gpr_atm_no_barrier_load(&cqd->shutdown)); - gpr_atm_no_barrier_store(&cqd->shutdown, 1); + GPR_ASSERT(!cqd->shutdown.Load(grpc_core::MemoryOrder::RELAXED)); + cqd->shutdown.Store(1, grpc_core::MemoryOrder::RELAXED); cq->poller_vtable->shutdown(POLLSET_FROM_CQ(cq), &cq->pollset_shutdown_done); } @@ -1338,7 +1329,7 @@ static void cq_shutdown_pluck(grpc_completion_queue* cq) { return; } cqd->shutdown_called = true; - if (gpr_atm_full_fetch_add(&cqd->pending_events, -1) == 1) { + if (cqd->pending_events.FetchSub(1, grpc_core::MemoryOrder::ACQ_REL) == 1) { cq_finish_shutdown_pluck(cq); } gpr_mu_unlock(cq->mu); @@ -1352,7 +1343,7 @@ static void cq_finish_shutdown_callback(grpc_completion_queue* cq) { GPR_ASSERT(cqd->shutdown_called); cq->poller_vtable->shutdown(POLLSET_FROM_CQ(cq), &cq->pollset_shutdown_done); - (*callback->functor_run)(callback, true); + grpc_core::ApplicationCallbackExecCtx::Enqueue(callback, true); } static void cq_shutdown_callback(grpc_completion_queue* cq) { @@ -1372,7 +1363,7 @@ static void cq_shutdown_callback(grpc_completion_queue* cq) { return; } cqd->shutdown_called = true; - if (gpr_atm_full_fetch_add(&cqd->pending_events, -1) == 1) { + if (cqd->pending_events.FetchSub(1, grpc_core::MemoryOrder::ACQ_REL) == 1) { gpr_mu_unlock(cq->mu); cq_finish_shutdown_callback(cq); } else { @@ -1385,6 +1376,7 @@ static void cq_shutdown_callback(grpc_completion_queue* cq) { to zero here, then enter shutdown mode and wake up any waiters */ void grpc_completion_queue_shutdown(grpc_completion_queue* cq) { GPR_TIMER_SCOPE("grpc_completion_queue_shutdown", 0); + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; grpc_core::ExecCtx exec_ctx; GRPC_API_TRACE("grpc_completion_queue_shutdown(cq=%p)", 1, (cq)); cq->vtable->shutdown(cq); diff --git a/src/core/lib/surface/init.cc b/src/core/lib/surface/init.cc index c6198b8ae76..1ed1a66b184 100644 --- a/src/core/lib/surface/init.cc +++ b/src/core/lib/surface/init.cc @@ -33,6 +33,7 @@ #include "src/core/lib/debug/stats.h" #include "src/core/lib/debug/trace.h" #include "src/core/lib/gprpp/fork.h" +#include "src/core/lib/gprpp/sync.h" #include "src/core/lib/http/parser.h" #include "src/core/lib/iomgr/call_combiner.h" #include "src/core/lib/iomgr/combiner.h" @@ -61,12 +62,18 @@ extern void grpc_register_built_in_plugins(void); static gpr_once g_basic_init = GPR_ONCE_INIT; static gpr_mu g_init_mu; static int g_initializations; +static gpr_cv* g_shutting_down_cv; +static bool g_shutting_down; static void do_basic_init(void) { gpr_log_verbosity_init(); gpr_mu_init(&g_init_mu); + g_shutting_down_cv = static_cast(malloc(sizeof(gpr_cv))); + gpr_cv_init(g_shutting_down_cv); + g_shutting_down = false; grpc_register_built_in_plugins(); grpc_cq_global_init(); + gpr_time_init(); g_initializations = 0; } @@ -118,22 +125,25 @@ void grpc_init(void) { int i; gpr_once_init(&g_basic_init, do_basic_init); - gpr_mu_lock(&g_init_mu); + grpc_core::MutexLock lock(&g_init_mu); if (++g_initializations == 1) { + if (g_shutting_down) { + g_shutting_down = false; + gpr_cv_broadcast(g_shutting_down_cv); + } grpc_core::Fork::GlobalInit(); grpc_fork_handlers_auto_register(); - gpr_time_init(); - gpr_arena_init(); grpc_stats_init(); grpc_slice_intern_init(); grpc_mdctx_global_init(); grpc_channel_init_init(); grpc_core::channelz::ChannelzRegistry::Init(); grpc_security_pre_init(); + grpc_core::ApplicationCallbackExecCtx::GlobalInit(); grpc_core::ExecCtx::GlobalInit(); grpc_iomgr_init(); gpr_timers_global_init(); - grpc_handshaker_factory_registry_init(); + grpc_core::HandshakerRegistry::Init(); grpc_security_init(); for (i = 0; i < g_number_of_plugins; i++) { if (g_all_of_the_plugins[i].init != nullptr) { @@ -149,48 +159,88 @@ void grpc_init(void) { grpc_channel_init_finalize(); grpc_iomgr_start(); } - gpr_mu_unlock(&g_init_mu); GRPC_API_TRACE("grpc_init(void)", 0, ()); } -void grpc_shutdown(void) { +void grpc_shutdown_internal_locked(void) { int i; - GRPC_API_TRACE("grpc_shutdown(void)", 0, ()); - gpr_mu_lock(&g_init_mu); - if (--g_initializations == 0) { + { + grpc_core::ExecCtx exec_ctx(0); + grpc_iomgr_shutdown_background_closure(); { - grpc_core::ExecCtx exec_ctx(0); - { - grpc_timer_manager_set_threading( - false); // shutdown timer_manager thread - grpc_executor_shutdown(); - for (i = g_number_of_plugins; i >= 0; i--) { - if (g_all_of_the_plugins[i].destroy != nullptr) { - g_all_of_the_plugins[i].destroy(); - } + grpc_timer_manager_set_threading(false); // shutdown timer_manager thread + grpc_core::Executor::ShutdownAll(); + for (i = g_number_of_plugins; i >= 0; i--) { + if (g_all_of_the_plugins[i].destroy != nullptr) { + g_all_of_the_plugins[i].destroy(); } } - grpc_iomgr_shutdown(); - gpr_timers_global_destroy(); - grpc_tracer_shutdown(); - grpc_mdctx_global_shutdown(); - grpc_handshaker_factory_registry_shutdown(); - grpc_slice_intern_shutdown(); - grpc_core::channelz::ChannelzRegistry::Shutdown(); - grpc_stats_shutdown(); - grpc_core::Fork::GlobalShutdown(); } - grpc_core::ExecCtx::GlobalShutdown(); + grpc_iomgr_shutdown(); + gpr_timers_global_destroy(); + grpc_tracer_shutdown(); + grpc_mdctx_global_shutdown(); + grpc_core::HandshakerRegistry::Shutdown(); + grpc_slice_intern_shutdown(); + grpc_core::channelz::ChannelzRegistry::Shutdown(); + grpc_stats_shutdown(); + grpc_core::Fork::GlobalShutdown(); + } + grpc_core::ExecCtx::GlobalShutdown(); + grpc_core::ApplicationCallbackExecCtx::GlobalShutdown(); + g_shutting_down = false; + gpr_cv_broadcast(g_shutting_down_cv); +} + +void grpc_shutdown_internal(void* ignored) { + GRPC_API_TRACE("grpc_shutdown_internal", 0, ()); + grpc_core::MutexLock lock(&g_init_mu); + // We have released lock from the shutdown thread and it is possible that + // another grpc_init has been called, and do nothing if that is the case. + if (--g_initializations != 0) { + return; + } + grpc_shutdown_internal_locked(); +} + +void grpc_shutdown(void) { + GRPC_API_TRACE("grpc_shutdown(void)", 0, ()); + grpc_core::MutexLock lock(&g_init_mu); + if (--g_initializations == 0) { + g_initializations++; + g_shutting_down = true; + // spawn a detached thread to do the actual clean up in case we are + // currently in an executor thread. + grpc_core::Thread cleanup_thread( + "grpc_shutdown", grpc_shutdown_internal, nullptr, nullptr, + grpc_core::Thread::Options().set_joinable(false).set_tracked(false)); + cleanup_thread.Start(); + } +} + +void grpc_shutdown_blocking(void) { + GRPC_API_TRACE("grpc_shutdown_blocking(void)", 0, ()); + grpc_core::MutexLock lock(&g_init_mu); + if (--g_initializations == 0) { + g_shutting_down = true; + grpc_shutdown_internal_locked(); } - gpr_mu_unlock(&g_init_mu); } int grpc_is_initialized(void) { int r; gpr_once_init(&g_basic_init, do_basic_init); - gpr_mu_lock(&g_init_mu); + grpc_core::MutexLock lock(&g_init_mu); r = g_initializations > 0; - gpr_mu_unlock(&g_init_mu); return r; } + +void grpc_maybe_wait_for_async_shutdown(void) { + gpr_once_init(&g_basic_init, do_basic_init); + grpc_core::MutexLock lock(&g_init_mu); + while (g_shutting_down) { + gpr_cv_wait(g_shutting_down_cv, &g_init_mu, + gpr_inf_future(GPR_CLOCK_REALTIME)); + } +} diff --git a/src/core/lib/surface/init.h b/src/core/lib/surface/init.h index 193f51447d9..6eaa488d054 100644 --- a/src/core/lib/surface/init.h +++ b/src/core/lib/surface/init.h @@ -22,5 +22,6 @@ void grpc_register_security_filters(void); void grpc_security_pre_init(void); void grpc_security_init(void); +void grpc_maybe_wait_for_async_shutdown(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 765350cced0..0e83a11a5f0 100644 --- a/src/core/lib/surface/init_secure.cc +++ b/src/core/lib/surface/init_secure.cc @@ -78,4 +78,4 @@ void grpc_register_security_filters(void) { maybe_prepend_server_auth_filter, nullptr); } -void grpc_security_init() { grpc_security_register_handshaker_factories(); } +void grpc_security_init() { grpc_core::SecurityRegisterHandshakerFactories(); } diff --git a/src/core/lib/surface/lame_client.cc b/src/core/lib/surface/lame_client.cc index 5a84428b0ee..dde39b8c681 100644 --- a/src/core/lib/surface/lame_client.cc +++ b/src/core/lib/surface/lame_client.cc @@ -25,10 +25,9 @@ #include #include -#include "src/core/lib/gprpp/atomic.h" - #include "src/core/lib/channel/channel_stack.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/atomic.h" #include "src/core/lib/surface/api_trace.h" #include "src/core/lib/surface/call.h" #include "src/core/lib/surface/channel.h" @@ -40,10 +39,10 @@ namespace grpc_core { namespace { struct CallData { - grpc_call_combiner* call_combiner; + grpc_core::CallCombiner* call_combiner; grpc_linked_mdelem status; grpc_linked_mdelem details; - grpc_core::atomic filled_metadata; + grpc_core::Atomic filled_metadata; }; struct ChannelData { @@ -54,9 +53,8 @@ struct ChannelData { static void fill_metadata(grpc_call_element* elem, grpc_metadata_batch* mdb) { CallData* calld = static_cast(elem->call_data); bool expected = false; - if (!calld->filled_metadata.compare_exchange_strong( - expected, true, grpc_core::memory_order_relaxed, - grpc_core::memory_order_relaxed)) { + if (!calld->filled_metadata.CompareExchangeStrong( + &expected, true, MemoryOrder::RELAXED, MemoryOrder::RELAXED)) { return; } ChannelData* chand = static_cast(elem->channel_data); diff --git a/src/core/lib/surface/server.cc b/src/core/lib/surface/server.cc index 5dc81b29bb7..2377c4d8f23 100644 --- a/src/core/lib/surface/server.cc +++ b/src/core/lib/surface/server.cc @@ -28,6 +28,8 @@ #include #include +#include + #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/connected_channel.h" #include "src/core/lib/debug/stats.h" @@ -109,7 +111,7 @@ struct channel_data { uint32_t registered_method_max_probes; grpc_closure finish_destroy_channel_closure; grpc_closure channel_connectivity_changed; - intptr_t socket_uuid; + grpc_core::RefCountedPtr socket_node; }; typedef struct shutdown_tag { @@ -121,7 +123,7 @@ typedef struct shutdown_tag { typedef enum { /* waiting for metadata */ NOT_STARTED, - /* inital metadata read, not flow controlled in yet */ + /* initial metadata read, not flow controlled in yet */ PENDING, /* flow controlled in, on completion queue */ ACTIVATED, @@ -188,7 +190,7 @@ struct call_data { grpc_closure publish; call_data* pending_next = nullptr; - grpc_call_combiner* call_combiner; + grpc_core::CallCombiner* call_combiner; }; struct request_matcher { @@ -345,8 +347,8 @@ static void channel_broadcaster_shutdown(channel_broadcaster* cb, */ static void request_matcher_init(request_matcher* rm, grpc_server* server) { - memset(rm, 0, sizeof(*rm)); rm->server = server; + rm->pending_head = rm->pending_tail = nullptr; rm->requests_per_cq = static_cast( gpr_malloc(sizeof(*rm->requests_per_cq) * server->cq_count)); for (size_t i = 0; i < server->cq_count; i++) { @@ -462,7 +464,8 @@ static void destroy_channel(channel_data* chand, grpc_error* error) { GRPC_CLOSURE_INIT(&chand->finish_destroy_channel_closure, finish_destroy_channel, chand, grpc_schedule_on_exec_ctx); - if (grpc_server_channel_trace.enabled() && error != GRPC_ERROR_NONE) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_server_channel_trace) && + error != GRPC_ERROR_NONE) { const char* msg = grpc_error_string(error); gpr_log(GPR_INFO, "Disconnected client: %s", msg); } @@ -599,8 +602,9 @@ static void finish_start_new_rpc( break; case GRPC_SRM_PAYLOAD_READ_INITIAL_BYTE_BUFFER: { grpc_op op; - memset(&op, 0, sizeof(op)); op.op = GRPC_OP_RECV_MESSAGE; + op.flags = 0; + op.reserved = nullptr; op.data.recv_message.recv_message = &calld->payload; GRPC_CLOSURE_INIT(&calld->publish, publish_new_rpc, elem, grpc_schedule_on_exec_ctx); @@ -937,6 +941,7 @@ static grpc_error* init_channel_elem(grpc_channel_element* elem, static void destroy_channel_elem(grpc_channel_element* elem) { size_t i; channel_data* chand = static_cast(elem->channel_data); + chand->socket_node.reset(); if (chand->registered_methods) { for (i = 0; i < chand->registered_method_slots; i++) { grpc_slice_unref_internal(chand->registered_methods[i].method); @@ -994,10 +999,12 @@ void grpc_server_register_completion_queue(grpc_server* server, "grpc_server_register_completion_queue(server=%p, cq=%p, reserved=%p)", 3, (server, cq, reserved)); - if (grpc_get_cq_completion_type(cq) != GRPC_CQ_NEXT) { + auto cq_type = grpc_get_cq_completion_type(cq); + if (cq_type != GRPC_CQ_NEXT && cq_type != GRPC_CQ_CALLBACK) { gpr_log(GPR_INFO, - "Completion queue which is not of type GRPC_CQ_NEXT is being " - "registered as a server-completion-queue"); + "Completion queue of type %d is being registered as a " + "server-completion-queue", + static_cast(cq_type)); /* Ideally we should log an error and abort but ruby-wrapped-language API calls grpc_completion_queue_pluck() on server completion queues */ } @@ -1093,20 +1100,6 @@ void* grpc_server_register_method( return m; } -static void start_listeners(void* s, grpc_error* error) { - grpc_server* server = static_cast(s); - for (listener* l = server->listeners; l; l = l->next) { - l->start(server, l->arg, server->pollsets, server->pollset_count); - } - - gpr_mu_lock(&server->mu_global); - server->starting = false; - gpr_cv_signal(&server->starting_cv); - gpr_mu_unlock(&server->mu_global); - - server_unref(server); -} - void grpc_server_start(grpc_server* server) { size_t i; grpc_core::ExecCtx exec_ctx; @@ -1128,12 +1121,18 @@ void grpc_server_start(grpc_server* server) { request_matcher_init(&rm->matcher, server); } - server_ref(server); + gpr_mu_lock(&server->mu_global); server->starting = true; - GRPC_CLOSURE_SCHED( - GRPC_CLOSURE_CREATE(start_listeners, server, - grpc_executor_scheduler(GRPC_EXECUTOR_SHORT)), - GRPC_ERROR_NONE); + gpr_mu_unlock(&server->mu_global); + + for (listener* l = server->listeners; l; l = l->next) { + l->start(server, l->arg, server->pollsets, server->pollset_count); + } + + gpr_mu_lock(&server->mu_global); + server->starting = false; + gpr_cv_signal(&server->starting_cv); + gpr_mu_unlock(&server->mu_global); } void grpc_server_get_pollsets(grpc_server* server, grpc_pollset*** pollsets, @@ -1142,11 +1141,11 @@ void grpc_server_get_pollsets(grpc_server* server, grpc_pollset*** pollsets, *pollsets = server->pollsets; } -void grpc_server_setup_transport(grpc_server* s, grpc_transport* transport, - grpc_pollset* accepting_pollset, - const grpc_channel_args* args, - intptr_t socket_uuid, - grpc_resource_user* resource_user) { +void grpc_server_setup_transport( + grpc_server* s, grpc_transport* transport, grpc_pollset* accepting_pollset, + const grpc_channel_args* args, + grpc_core::RefCountedPtr socket_node, + grpc_resource_user* resource_user) { size_t num_registered_methods; size_t alloc; registered_method* rm; @@ -1167,7 +1166,7 @@ void grpc_server_setup_transport(grpc_server* s, grpc_transport* transport, chand->server = s; server_ref(s); chand->channel = channel; - chand->socket_uuid = socket_uuid; + chand->socket_node = std::move(socket_node); size_t cq_idx; for (cq_idx = 0; cq_idx < s->cq_count; cq_idx++) { @@ -1243,14 +1242,13 @@ void grpc_server_setup_transport(grpc_server* s, grpc_transport* transport, } void grpc_server_populate_server_sockets( - grpc_server* s, grpc_core::channelz::ChildRefsList* server_sockets, + grpc_server* s, grpc_core::channelz::ChildSocketsList* server_sockets, intptr_t start_idx) { gpr_mu_lock(&s->mu_global); channel_data* c = nullptr; for (c = s->root_channel_data.next; c != &s->root_channel_data; c = c->next) { - intptr_t socket_uuid = c->socket_uuid; - if (socket_uuid >= start_idx) { - server_sockets->push_back(socket_uuid); + if (c->socket_node != nullptr && c->socket_node->uuid() >= start_idx) { + server_sockets->push_back(c->socket_node.get()); } } gpr_mu_unlock(&s->mu_global); @@ -1299,6 +1297,7 @@ void grpc_server_shutdown_and_notify(grpc_server* server, listener* l; shutdown_tag* sdt; channel_broadcaster broadcaster; + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; grpc_core::ExecCtx exec_ctx; GRPC_API_TRACE("grpc_server_shutdown_and_notify(server=%p, cq=%p, tag=%p)", 3, @@ -1366,6 +1365,7 @@ void grpc_server_shutdown_and_notify(grpc_server* server, void grpc_server_cancel_all_calls(grpc_server* server) { channel_broadcaster broadcaster; + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; grpc_core::ExecCtx exec_ctx; GRPC_API_TRACE("grpc_server_cancel_all_calls(server=%p)", 1, (server)); @@ -1381,6 +1381,7 @@ void grpc_server_cancel_all_calls(grpc_server* server) { void grpc_server_destroy(grpc_server* server) { listener* l; + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; grpc_core::ExecCtx exec_ctx; GRPC_API_TRACE("grpc_server_destroy(server=%p)", 1, (server)); @@ -1466,6 +1467,7 @@ grpc_call_error grpc_server_request_call( grpc_completion_queue* cq_bound_to_call, grpc_completion_queue* cq_for_notification, void* tag) { grpc_call_error error; + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; grpc_core::ExecCtx exec_ctx; requested_call* rc = static_cast(gpr_malloc(sizeof(*rc))); GRPC_STATS_INC_SERVER_REQUESTED_CALLS(); @@ -1512,11 +1514,11 @@ grpc_call_error grpc_server_request_registered_call( grpc_metadata_array* initial_metadata, grpc_byte_buffer** optional_payload, grpc_completion_queue* cq_bound_to_call, grpc_completion_queue* cq_for_notification, void* tag) { - grpc_call_error error; + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; grpc_core::ExecCtx exec_ctx; + GRPC_STATS_INC_SERVER_REQUESTED_CALLS(); requested_call* rc = static_cast(gpr_malloc(sizeof(*rc))); registered_method* rm = static_cast(rmp); - GRPC_STATS_INC_SERVER_REQUESTED_CALLS(); GRPC_API_TRACE( "grpc_server_request_registered_call(" "server=%p, rmp=%p, call=%p, deadline=%p, initial_metadata=%p, " @@ -1534,19 +1536,17 @@ grpc_call_error grpc_server_request_registered_call( } if (cq_idx == server->cq_count) { gpr_free(rc); - error = GRPC_CALL_ERROR_NOT_SERVER_COMPLETION_QUEUE; - goto done; + return GRPC_CALL_ERROR_NOT_SERVER_COMPLETION_QUEUE; } if ((optional_payload == nullptr) != (rm->payload_handling == GRPC_SRM_PAYLOAD_NONE)) { gpr_free(rc); - error = GRPC_CALL_ERROR_PAYLOAD_TYPE_MISMATCH; - goto done; + return GRPC_CALL_ERROR_PAYLOAD_TYPE_MISMATCH; } + if (grpc_cq_begin_op(cq_for_notification, tag) == false) { gpr_free(rc); - error = GRPC_CALL_ERROR_COMPLETION_QUEUE_SHUTDOWN; - goto done; + return GRPC_CALL_ERROR_COMPLETION_QUEUE_SHUTDOWN; } rc->cq_idx = cq_idx; rc->type = REGISTERED_CALL; @@ -1558,10 +1558,7 @@ grpc_call_error grpc_server_request_registered_call( rc->data.registered.deadline = deadline; rc->initial_metadata = initial_metadata; rc->data.registered.optional_payload = optional_payload; - error = queue_call_request(server, cq_idx, rc); -done: - - return error; + return queue_call_request(server, cq_idx, rc); } static void fail_call(grpc_server* server, size_t cq_idx, requested_call* rc, diff --git a/src/core/lib/surface/server.h b/src/core/lib/surface/server.h index 27038fdb7a6..393bb242148 100644 --- a/src/core/lib/surface/server.h +++ b/src/core/lib/surface/server.h @@ -44,15 +44,15 @@ void grpc_server_add_listener(grpc_server* server, void* listener, /* Setup a transport - creates a channel stack, binds the transport to the server */ -void grpc_server_setup_transport(grpc_server* server, grpc_transport* transport, - grpc_pollset* accepting_pollset, - const grpc_channel_args* args, - intptr_t socket_uuid, - grpc_resource_user* resource_user = nullptr); +void grpc_server_setup_transport( + grpc_server* server, grpc_transport* transport, + grpc_pollset* accepting_pollset, const grpc_channel_args* args, + grpc_core::RefCountedPtr socket_node, + grpc_resource_user* resource_user = nullptr); /* fills in the uuids of all sockets used for connections on this server */ void grpc_server_populate_server_sockets( - grpc_server* server, grpc_core::channelz::ChildRefsList* server_sockets, + grpc_server* server, grpc_core::channelz::ChildSocketsList* server_sockets, intptr_t start_idx); /* fills in the uuids of all listen sockets on this server */ diff --git a/src/core/lib/surface/version.cc b/src/core/lib/surface/version.cc index 66890ce65ac..7d9d49bc2aa 100644 --- a/src/core/lib/surface/version.cc +++ b/src/core/lib/surface/version.cc @@ -23,6 +23,6 @@ #include -const char* grpc_version_string(void) { return "7.0.0-dev"; } +const char* grpc_version_string(void) { return "7.0.0"; } -const char* grpc_g_stands_for(void) { return "gizmo"; } +const char* grpc_g_stands_for(void) { return "gale"; } diff --git a/src/core/lib/transport/bdp_estimator.cc b/src/core/lib/transport/bdp_estimator.cc index 8e71f869894..8835e32bcff 100644 --- a/src/core/lib/transport/bdp_estimator.cc +++ b/src/core/lib/transport/bdp_estimator.cc @@ -46,7 +46,7 @@ grpc_millis BdpEstimator::CompletePing() { 1e-9 * static_cast(dt_ts.tv_nsec); double bw = dt > 0 ? (static_cast(accumulator_) / dt) : 0; int start_inter_ping_delay = inter_ping_delay_; - if (grpc_bdp_estimator_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_bdp_estimator_trace)) { gpr_log(GPR_INFO, "bdp[%s]:complete acc=%" PRId64 " est=%" PRId64 " dt=%lf bw=%lfMbs bw_est=%lfMbs", @@ -57,7 +57,7 @@ grpc_millis BdpEstimator::CompletePing() { if (accumulator_ > 2 * estimate_ / 3 && bw > bw_est_) { estimate_ = GPR_MAX(accumulator_, estimate_ * 2); bw_est_ = bw; - if (grpc_bdp_estimator_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_bdp_estimator_trace)) { gpr_log(GPR_INFO, "bdp[%s]: estimate increased to %" PRId64, name_, estimate_); } @@ -74,7 +74,7 @@ grpc_millis BdpEstimator::CompletePing() { } if (start_inter_ping_delay != inter_ping_delay_) { stable_estimate_count_ = 0; - if (grpc_bdp_estimator_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_bdp_estimator_trace)) { 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 ab13ae4be4c..6dc4d6bb05e 100644 --- a/src/core/lib/transport/bdp_estimator.h +++ b/src/core/lib/transport/bdp_estimator.h @@ -49,7 +49,7 @@ class BdpEstimator { // grpc_bdp_estimator_add_incoming_bytes once a ping has been scheduled by a // transport (but not necessarily started) void SchedulePing() { - if (grpc_bdp_estimator_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_bdp_estimator_trace)) { gpr_log(GPR_INFO, "bdp[%s]:sched acc=%" PRId64 " est=%" PRId64, name_, accumulator_, estimate_); } @@ -62,7 +62,7 @@ class BdpEstimator { // once // the ping is on the wire void StartPing() { - if (grpc_bdp_estimator_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_bdp_estimator_trace)) { gpr_log(GPR_INFO, "bdp[%s]:start acc=%" PRId64 " est=%" PRId64, name_, accumulator_, estimate_); } diff --git a/src/core/lib/transport/connectivity_state.cc b/src/core/lib/transport/connectivity_state.cc index db6b6c04440..bf35fd09def 100644 --- a/src/core/lib/transport/connectivity_state.cc +++ b/src/core/lib/transport/connectivity_state.cc @@ -48,7 +48,6 @@ void grpc_connectivity_state_init(grpc_connectivity_state_tracker* tracker, grpc_connectivity_state init_state, const char* name) { gpr_atm_no_barrier_store(&tracker->current_state_atm, init_state); - tracker->current_error = GRPC_ERROR_NONE; tracker->watchers = nullptr; tracker->name = gpr_strdup(name); } @@ -69,7 +68,6 @@ void grpc_connectivity_state_destroy(grpc_connectivity_state_tracker* tracker) { GRPC_CLOSURE_SCHED(w->notify, error); gpr_free(w); } - GRPC_ERROR_UNREF(tracker->current_error); gpr_free(tracker->name); } @@ -77,27 +75,13 @@ grpc_connectivity_state grpc_connectivity_state_check( grpc_connectivity_state_tracker* tracker) { grpc_connectivity_state cur = static_cast( gpr_atm_no_barrier_load(&tracker->current_state_atm)); - if (grpc_connectivity_state_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_connectivity_state_trace)) { gpr_log(GPR_INFO, "CONWATCH: %p %s: get %s", tracker, tracker->name, grpc_connectivity_state_name(cur)); } return cur; } -grpc_connectivity_state grpc_connectivity_state_get( - grpc_connectivity_state_tracker* tracker, grpc_error** error) { - grpc_connectivity_state cur = static_cast( - gpr_atm_no_barrier_load(&tracker->current_state_atm)); - if (grpc_connectivity_state_trace.enabled()) { - gpr_log(GPR_INFO, "CONWATCH: %p %s: get %s", tracker, tracker->name, - grpc_connectivity_state_name(cur)); - } - if (error != nullptr) { - *error = GRPC_ERROR_REF(tracker->current_error); - } - return cur; -} - bool grpc_connectivity_state_has_watchers( grpc_connectivity_state_tracker* connectivity_state) { return connectivity_state->watchers != nullptr; @@ -108,7 +92,7 @@ bool grpc_connectivity_state_notify_on_state_change( grpc_closure* notify) { grpc_connectivity_state cur = static_cast( gpr_atm_no_barrier_load(&tracker->current_state_atm)); - if (grpc_connectivity_state_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_connectivity_state_trace)) { if (current == nullptr) { gpr_log(GPR_INFO, "CONWATCH: %p %s: unsubscribe notify=%p", tracker, tracker->name, notify); @@ -140,7 +124,7 @@ bool grpc_connectivity_state_notify_on_state_change( } else { if (cur != *current) { *current = cur; - GRPC_CLOSURE_SCHED(notify, GRPC_ERROR_REF(tracker->current_error)); + GRPC_CLOSURE_SCHED(notify, GRPC_ERROR_NONE); } else { grpc_connectivity_state_watcher* w = static_cast(gpr_malloc(sizeof(*w))); @@ -155,29 +139,15 @@ bool grpc_connectivity_state_notify_on_state_change( void grpc_connectivity_state_set(grpc_connectivity_state_tracker* tracker, grpc_connectivity_state state, - grpc_error* error, const char* reason) { + const char* reason) { grpc_connectivity_state cur = static_cast( gpr_atm_no_barrier_load(&tracker->current_state_atm)); grpc_connectivity_state_watcher* w; - if (grpc_connectivity_state_trace.enabled()) { - const char* error_string = grpc_error_string(error); - 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); + if (GRPC_TRACE_FLAG_ENABLED(grpc_connectivity_state_trace)) { + gpr_log(GPR_INFO, "SET: %p %s: %s --> %s [%s]", tracker, tracker->name, + grpc_connectivity_state_name(cur), + grpc_connectivity_state_name(state), reason); } - switch (state) { - case GRPC_CHANNEL_CONNECTING: - case GRPC_CHANNEL_IDLE: - case GRPC_CHANNEL_READY: - GPR_ASSERT(error == GRPC_ERROR_NONE); - break; - case GRPC_CHANNEL_SHUTDOWN: - case GRPC_CHANNEL_TRANSIENT_FAILURE: - GPR_ASSERT(error != GRPC_ERROR_NONE); - break; - } - GRPC_ERROR_UNREF(tracker->current_error); - tracker->current_error = error; if (cur == state) { return; } @@ -186,10 +156,10 @@ void grpc_connectivity_state_set(grpc_connectivity_state_tracker* tracker, while ((w = tracker->watchers) != nullptr) { *w->current = state; tracker->watchers = w->next; - if (grpc_connectivity_state_trace.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_connectivity_state_trace)) { gpr_log(GPR_INFO, "NOTIFY: %p %s: %p", tracker, tracker->name, w->notify); } - GRPC_CLOSURE_SCHED(w->notify, GRPC_ERROR_REF(tracker->current_error)); + GRPC_CLOSURE_SCHED(w->notify, GRPC_ERROR_NONE); gpr_free(w); } } diff --git a/src/core/lib/transport/connectivity_state.h b/src/core/lib/transport/connectivity_state.h index ecb083cfc2f..0ff1432cb9d 100644 --- a/src/core/lib/transport/connectivity_state.h +++ b/src/core/lib/transport/connectivity_state.h @@ -37,8 +37,6 @@ typedef struct grpc_connectivity_state_watcher { typedef struct { /** current grpc_connectivity_state */ gpr_atm current_state_atm; - /** error associated with state */ - grpc_error* current_error; /** all our watchers */ grpc_connectivity_state_watcher* watchers; /** a name to help debugging */ @@ -59,7 +57,6 @@ void grpc_connectivity_state_destroy(grpc_connectivity_state_tracker* tracker); * external lock */ void grpc_connectivity_state_set(grpc_connectivity_state_tracker* tracker, grpc_connectivity_state state, - grpc_error* associated_error, const char* reason); /** Return true if this connectivity state has watchers. @@ -71,11 +68,6 @@ bool grpc_connectivity_state_has_watchers( grpc_connectivity_state grpc_connectivity_state_check( grpc_connectivity_state_tracker* tracker); -/** Return the last seen connectivity state, and the associated error. - Access must be serialized with an external lock. */ -grpc_connectivity_state grpc_connectivity_state_get( - grpc_connectivity_state_tracker* tracker, grpc_error** error); - /** Return 1 if the channel should start connecting, 0 otherwise. If current==NULL cancel notify if it is already queued (success==0 in that case). diff --git a/src/core/lib/transport/error_utils.cc b/src/core/lib/transport/error_utils.cc index 558f1d494cd..eb4e8c3a282 100644 --- a/src/core/lib/transport/error_utils.cc +++ b/src/core/lib/transport/error_utils.cc @@ -48,6 +48,18 @@ void grpc_error_get_status(grpc_error* error, grpc_millis deadline, grpc_status_code* code, grpc_slice* slice, grpc_http2_error_code* http_error, const char** error_string) { + // Fast path: We expect no error. + if (GPR_LIKELY(error == GRPC_ERROR_NONE)) { + if (code != nullptr) *code = GRPC_STATUS_OK; + if (slice != nullptr) { + grpc_error_get_str(error, GRPC_ERROR_STR_GRPC_MESSAGE, slice); + } + if (http_error != nullptr) { + *http_error = GRPC_HTTP2_NO_ERROR; + } + return; + } + // Start with the parent error and recurse through the tree of children // until we find the first one that has a status code. grpc_error* found_error = diff --git a/src/core/lib/transport/metadata.cc b/src/core/lib/transport/metadata.cc index 60af22393ef..4609eb42cdc 100644 --- a/src/core/lib/transport/metadata.cc +++ b/src/core/lib/transport/metadata.cc @@ -41,6 +41,10 @@ #include "src/core/lib/slice/slice_string_helpers.h" #include "src/core/lib/transport/static_metadata.h" +using grpc_core::AllocatedMetadata; +using grpc_core::InternedMetadata; +using grpc_core::UserData; + /* There are two kinds of mdelem and mdstr instances. * Static instances are declared in static_metadata.{h,c} and * are initialized by grpc_mdctx_global_init(). @@ -54,13 +58,40 @@ grpc_core::DebugOnlyTraceFlag grpc_trace_metadata(false, "metadata"); #ifndef NDEBUG #define DEBUG_ARGS , const char *file, int line -#define FWD_DEBUG_ARGS , file, line -#define REF_MD_LOCKED(shard, s) ref_md_locked((shard), (s), __FILE__, __LINE__) -#else +#define FWD_DEBUG_ARGS file, line + +void grpc_mdelem_trace_ref(void* md, const grpc_slice& key, + const grpc_slice& value, intptr_t refcnt, + const char* file, int line) { + if (grpc_trace_metadata.enabled()) { + char* key_str = grpc_slice_to_c_string(key); + char* value_str = grpc_slice_to_c_string(value); + gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, + "ELM REF:%p:%" PRIdPTR "->%" PRIdPTR ": '%s' = '%s'", md, refcnt, + refcnt + 1, key_str, value_str); + gpr_free(key_str); + gpr_free(value_str); + } +} + +void grpc_mdelem_trace_unref(void* md, const grpc_slice& key, + const grpc_slice& value, intptr_t refcnt, + const char* file, int line) { + if (grpc_trace_metadata.enabled()) { + char* key_str = grpc_slice_to_c_string(key); + char* value_str = grpc_slice_to_c_string(value); + gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, + "ELM UNREF:%p:%" PRIdPTR "->%" PRIdPTR ": '%s' = '%s'", md, + refcnt, refcnt - 1, key_str, value_str); + gpr_free(key_str); + gpr_free(value_str); + } +} + +#else // ifndef NDEBUG #define DEBUG_ARGS #define FWD_DEBUG_ARGS -#define REF_MD_LOCKED(shard, s) ref_md_locked((shard), (s)) -#endif +#endif // ifndef NDEBUG #define INITIAL_SHARD_CAPACITY 8 #define LOG2_SHARD_COUNT 4 @@ -69,37 +100,87 @@ grpc_core::DebugOnlyTraceFlag grpc_trace_metadata(false, "metadata"); #define TABLE_IDX(hash, capacity) (((hash) >> (LOG2_SHARD_COUNT)) % (capacity)) #define SHARD_IDX(hash) ((hash) & ((1 << (LOG2_SHARD_COUNT)) - 1)) -typedef void (*destroy_user_data_func)(void* user_data); +AllocatedMetadata::AllocatedMetadata(const grpc_slice& key, + const grpc_slice& value) + : key_(grpc_slice_ref_internal(key)), + value_(grpc_slice_ref_internal(value)), + refcnt_(1) { +#ifndef NDEBUG + if (grpc_trace_metadata.enabled()) { + char* key_str = grpc_slice_to_c_string(key_); + char* value_str = grpc_slice_to_c_string(value_); + gpr_log(GPR_DEBUG, "ELM ALLOC:%p:%" PRIdPTR ": '%s' = '%s'", this, + RefValue(), key_str, value_str); + gpr_free(key_str); + gpr_free(value_str); + } +#endif +} -/* Shadow structure for grpc_mdelem_data for interned elements */ -typedef struct interned_metadata { - /* must be byte compatible with grpc_mdelem_data */ - grpc_slice key; - grpc_slice value; +AllocatedMetadata::~AllocatedMetadata() { + grpc_slice_unref_internal(key_); + grpc_slice_unref_internal(value_); + void* user_data = user_data_.data.Load(grpc_core::MemoryOrder::RELAXED); + if (user_data) { + destroy_user_data_func destroy_user_data = + user_data_.destroy_user_data.Load(grpc_core::MemoryOrder::RELAXED); + destroy_user_data(user_data); + } +} - /* private only data */ - gpr_atm refcnt; +InternedMetadata::InternedMetadata(const grpc_slice& key, + const grpc_slice& value, uint32_t hash, + InternedMetadata* next) + : key_(grpc_slice_ref_internal(key)), + value_(grpc_slice_ref_internal(value)), + refcnt_(1), + hash_(hash), + link_(next) { +#ifndef NDEBUG + if (grpc_trace_metadata.enabled()) { + char* key_str = grpc_slice_to_c_string(key_); + char* value_str = grpc_slice_to_c_string(value_); + gpr_log(GPR_DEBUG, "ELM NEW:%p:%" PRIdPTR ": '%s' = '%s'", this, + RefValue(), key_str, value_str); + gpr_free(key_str); + gpr_free(value_str); + } +#endif +} - gpr_mu mu_user_data; - gpr_atm destroy_user_data; - gpr_atm user_data; +InternedMetadata::~InternedMetadata() { + grpc_slice_unref_internal(key_); + grpc_slice_unref_internal(value_); + void* user_data = user_data_.data.Load(grpc_core::MemoryOrder::RELAXED); + if (user_data) { + destroy_user_data_func destroy_user_data = + user_data_.destroy_user_data.Load(grpc_core::MemoryOrder::RELAXED); + destroy_user_data(user_data); + } +} - struct interned_metadata* bucket_next; -} interned_metadata; +size_t InternedMetadata::CleanupLinkedMetadata( + InternedMetadata::BucketLink* head) { + size_t num_freed = 0; + InternedMetadata::BucketLink* prev_next = head; + InternedMetadata *md, *next; -/* Shadow structure for grpc_mdelem_data for allocated elements */ -typedef struct allocated_metadata { - /* must be byte compatible with grpc_mdelem_data */ - grpc_slice key; - grpc_slice value; - - /* private only data */ - gpr_atm refcnt; -} allocated_metadata; + for (md = head->next; md; md = next) { + next = md->link_.next; + if (md->AllRefsDropped()) { + prev_next->next = next; + grpc_core::Delete(md); + num_freed++; + } else { + prev_next = &md->link_; + } + } + return num_freed; +} typedef struct mdtab_shard { gpr_mu mu; - interned_metadata** elems; + InternedMetadata::BucketLink* elems; size_t count; size_t capacity; /** Estimate of the number of unreferenced mdelems in the hash table. @@ -120,7 +201,7 @@ void grpc_mdctx_global_init(void) { shard->count = 0; gpr_atm_no_barrier_store(&shard->free_estimate, 0); shard->capacity = INITIAL_SHARD_CAPACITY; - shard->elems = static_cast( + shard->elems = static_cast( gpr_zalloc(sizeof(*shard->elems) * shard->capacity)); } } @@ -130,7 +211,6 @@ void grpc_mdctx_global_shutdown() { mdtab_shard* shard = &g_shards[i]; gpr_mu_destroy(&shard->mu); gc_mdtab(shard); - /* TODO(ctiller): GPR_ASSERT(shard->count == 0); */ if (shard->count != 0) { gpr_log(GPR_DEBUG, "WARNING: %" PRIuPTR " metadata elements were leaked", shard->count); @@ -138,6 +218,7 @@ void grpc_mdctx_global_shutdown() { abort(); } } + GPR_DEBUG_ASSERT(shard->count == 0); gpr_free(shard->elems); } } @@ -148,55 +229,34 @@ static int is_mdelem_static(grpc_mdelem e) { &grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT]; } -static void ref_md_locked(mdtab_shard* shard, - interned_metadata* md DEBUG_ARGS) { +void InternedMetadata::RefWithShardLocked(mdtab_shard* shard) { #ifndef NDEBUG if (grpc_trace_metadata.enabled()) { - char* key_str = grpc_slice_to_c_string(md->key); - char* value_str = grpc_slice_to_c_string(md->value); - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, - "ELM REF:%p:%" PRIdPTR "->%" PRIdPTR ": '%s' = '%s'", (void*)md, - gpr_atm_no_barrier_load(&md->refcnt), - gpr_atm_no_barrier_load(&md->refcnt) + 1, key_str, value_str); + char* key_str = grpc_slice_to_c_string(key_); + char* value_str = grpc_slice_to_c_string(value_); + intptr_t value = RefValue(); + gpr_log(__FILE__, __LINE__, GPR_LOG_SEVERITY_DEBUG, + "ELM REF:%p:%" PRIdPTR "->%" PRIdPTR ": '%s' = '%s'", this, value, + value + 1, key_str, value_str); gpr_free(key_str); gpr_free(value_str); } #endif - if (0 == gpr_atm_no_barrier_fetch_add(&md->refcnt, 1)) { + if (FirstRef()) { gpr_atm_no_barrier_fetch_add(&shard->free_estimate, -1); } } static void gc_mdtab(mdtab_shard* shard) { GPR_TIMER_SCOPE("gc_mdtab", 0); - - size_t i; - interned_metadata** prev_next; - interned_metadata *md, *next; - gpr_atm num_freed = 0; - - for (i = 0; i < shard->capacity; i++) { - prev_next = &shard->elems[i]; - for (md = shard->elems[i]; md; md = next) { - void* user_data = (void*)gpr_atm_no_barrier_load(&md->user_data); - next = md->bucket_next; - if (gpr_atm_acq_load(&md->refcnt) == 0) { - grpc_slice_unref_internal(md->key); - grpc_slice_unref_internal(md->value); - if (md->user_data) { - ((destroy_user_data_func)gpr_atm_no_barrier_load( - &md->destroy_user_data))(user_data); - } - gpr_free(md); - *prev_next = next; - num_freed++; - shard->count--; - } else { - prev_next = &md->bucket_next; - } - } + size_t num_freed = 0; + for (size_t i = 0; i < shard->capacity; ++i) { + intptr_t freed = InternedMetadata::CleanupLinkedMetadata(&shard->elems[i]); + num_freed += freed; + shard->count -= freed; } - gpr_atm_no_barrier_fetch_add(&shard->free_estimate, -num_freed); + gpr_atm_no_barrier_fetch_add(&shard->free_estimate, + -static_cast(num_freed)); } static void grow_mdtab(mdtab_shard* shard) { @@ -204,22 +264,21 @@ static void grow_mdtab(mdtab_shard* shard) { size_t capacity = shard->capacity * 2; size_t i; - interned_metadata** mdtab; - interned_metadata *md, *next; + InternedMetadata::BucketLink* mdtab; + InternedMetadata *md, *next; uint32_t hash; - mdtab = static_cast( - gpr_zalloc(sizeof(interned_metadata*) * capacity)); + mdtab = static_cast( + gpr_zalloc(sizeof(InternedMetadata::BucketLink) * capacity)); for (i = 0; i < shard->capacity; i++) { - for (md = shard->elems[i]; md; md = next) { + for (md = shard->elems[i].next; md; md = next) { size_t idx; - hash = GRPC_MDSTR_KV_HASH(grpc_slice_hash(md->key), - grpc_slice_hash(md->value)); - next = md->bucket_next; + hash = md->hash(); + next = md->bucket_next(); idx = TABLE_IDX(hash, capacity); - md->bucket_next = mdtab[idx]; - mdtab[idx] = md; + md->set_bucket_next(mdtab[idx].next); + mdtab[idx].next = md; } } gpr_free(shard->elems); @@ -239,31 +298,22 @@ static void rehash_mdtab(mdtab_shard* shard) { grpc_mdelem grpc_mdelem_create( const grpc_slice& key, const grpc_slice& value, grpc_mdelem_data* compatible_external_backing_store) { + // External storage if either slice is not interned and the caller already + // created a backing store. If no backing store, we allocate one. if (!grpc_slice_is_interned(key) || !grpc_slice_is_interned(value)) { if (compatible_external_backing_store != nullptr) { + // Caller provided backing store. return GRPC_MAKE_MDELEM(compatible_external_backing_store, GRPC_MDELEM_STORAGE_EXTERNAL); + } else { + // We allocate backing store. + return GRPC_MAKE_MDELEM(grpc_core::New(key, value), + GRPC_MDELEM_STORAGE_ALLOCATED); } - - allocated_metadata* allocated = - static_cast(gpr_malloc(sizeof(*allocated))); - allocated->key = grpc_slice_ref_internal(key); - allocated->value = grpc_slice_ref_internal(value); - gpr_atm_rel_store(&allocated->refcnt, 1); -#ifndef NDEBUG - if (grpc_trace_metadata.enabled()) { - char* key_str = grpc_slice_to_c_string(allocated->key); - char* value_str = grpc_slice_to_c_string(allocated->value); - gpr_log(GPR_DEBUG, "ELM ALLOC:%p:%" PRIdPTR ": '%s' = '%s'", - (void*)allocated, gpr_atm_no_barrier_load(&allocated->refcnt), - key_str, value_str); - gpr_free(key_str); - gpr_free(value_str); - } -#endif - return GRPC_MAKE_MDELEM(allocated, GRPC_MDELEM_STORAGE_ALLOCATED); } + // Not all static slice input yields a statically stored metadata element. + // It may be worth documenting why. if (GRPC_IS_STATIC_METADATA_STRING(key) && GRPC_IS_STATIC_METADATA_STRING(value)) { grpc_mdelem static_elem = grpc_static_mdelem_for_static_strings( @@ -275,7 +325,7 @@ grpc_mdelem grpc_mdelem_create( uint32_t hash = GRPC_MDSTR_KV_HASH(grpc_slice_hash(key), grpc_slice_hash(value)); - interned_metadata* md; + InternedMetadata* md; mdtab_shard* shard = &g_shards[SHARD_IDX(hash)]; size_t idx; @@ -285,34 +335,18 @@ grpc_mdelem grpc_mdelem_create( idx = TABLE_IDX(hash, shard->capacity); /* search for an existing pair */ - for (md = shard->elems[idx]; md; md = md->bucket_next) { - if (grpc_slice_eq(key, md->key) && grpc_slice_eq(value, md->value)) { - REF_MD_LOCKED(shard, md); + for (md = shard->elems[idx].next; md; md = md->bucket_next()) { + if (grpc_slice_eq(key, md->key()) && grpc_slice_eq(value, md->value())) { + md->RefWithShardLocked(shard); gpr_mu_unlock(&shard->mu); return GRPC_MAKE_MDELEM(md, GRPC_MDELEM_STORAGE_INTERNED); } } /* not found: create a new pair */ - md = static_cast(gpr_malloc(sizeof(interned_metadata))); - gpr_atm_rel_store(&md->refcnt, 1); - md->key = grpc_slice_ref_internal(key); - md->value = grpc_slice_ref_internal(value); - md->user_data = 0; - md->destroy_user_data = 0; - md->bucket_next = shard->elems[idx]; - shard->elems[idx] = md; - gpr_mu_init(&md->mu_user_data); -#ifndef NDEBUG - if (grpc_trace_metadata.enabled()) { - char* key_str = grpc_slice_to_c_string(md->key); - char* value_str = grpc_slice_to_c_string(md->value); - gpr_log(GPR_DEBUG, "ELM NEW:%p:%" PRIdPTR ": '%s' = '%s'", (void*)md, - gpr_atm_no_barrier_load(&md->refcnt), key_str, value_str); - gpr_free(key_str); - gpr_free(value_str); - } -#endif + md = grpc_core::New(key, value, hash, + shard->elems[idx].next); + shard->elems[idx].next = md; shard->count++; if (shard->count > shard->capacity * 2) { @@ -343,171 +377,69 @@ grpc_mdelem grpc_mdelem_from_grpc_metadata(grpc_metadata* metadata) { changed ? nullptr : reinterpret_cast(metadata)); } -grpc_mdelem grpc_mdelem_ref(grpc_mdelem gmd DEBUG_ARGS) { - switch (GRPC_MDELEM_STORAGE(gmd)) { - case GRPC_MDELEM_STORAGE_EXTERNAL: - case GRPC_MDELEM_STORAGE_STATIC: - break; - case GRPC_MDELEM_STORAGE_INTERNED: { - interned_metadata* md = - reinterpret_cast GRPC_MDELEM_DATA(gmd); -#ifndef NDEBUG - if (grpc_trace_metadata.enabled()) { - char* key_str = grpc_slice_to_c_string(md->key); - char* value_str = grpc_slice_to_c_string(md->value); - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, - "ELM REF:%p:%" PRIdPTR "->%" PRIdPTR ": '%s' = '%s'", - (void*)md, gpr_atm_no_barrier_load(&md->refcnt), - gpr_atm_no_barrier_load(&md->refcnt) + 1, key_str, value_str); - gpr_free(key_str); - gpr_free(value_str); - } -#endif - /* we can assume the ref count is >= 1 as the application is calling - this function - meaning that no adjustment to mdtab_free is necessary, - simplifying the logic here to be just an atomic increment */ - /* use C assert to have this removed in opt builds */ - GPR_ASSERT(gpr_atm_no_barrier_load(&md->refcnt) >= 1); - gpr_atm_no_barrier_fetch_add(&md->refcnt, 1); - break; - } - case GRPC_MDELEM_STORAGE_ALLOCATED: { - allocated_metadata* md = - reinterpret_cast GRPC_MDELEM_DATA(gmd); -#ifndef NDEBUG - if (grpc_trace_metadata.enabled()) { - char* key_str = grpc_slice_to_c_string(md->key); - char* value_str = grpc_slice_to_c_string(md->value); - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, - "ELM REF:%p:%" PRIdPTR "->%" PRIdPTR ": '%s' = '%s'", - (void*)md, gpr_atm_no_barrier_load(&md->refcnt), - gpr_atm_no_barrier_load(&md->refcnt) + 1, key_str, value_str); - gpr_free(key_str); - gpr_free(value_str); - } -#endif - /* we can assume the ref count is >= 1 as the application is calling - this function - meaning that no adjustment to mdtab_free is necessary, - simplifying the logic here to be just an atomic increment */ - /* use C assert to have this removed in opt builds */ - gpr_atm_no_barrier_fetch_add(&md->refcnt, 1); - break; - } - } - return gmd; -} - -void grpc_mdelem_unref(grpc_mdelem gmd DEBUG_ARGS) { - switch (GRPC_MDELEM_STORAGE(gmd)) { - case GRPC_MDELEM_STORAGE_EXTERNAL: - case GRPC_MDELEM_STORAGE_STATIC: - break; - case GRPC_MDELEM_STORAGE_INTERNED: { - interned_metadata* md = - reinterpret_cast GRPC_MDELEM_DATA(gmd); -#ifndef NDEBUG - if (grpc_trace_metadata.enabled()) { - char* key_str = grpc_slice_to_c_string(md->key); - char* value_str = grpc_slice_to_c_string(md->value); - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, - "ELM UNREF:%p:%" PRIdPTR "->%" PRIdPTR ": '%s' = '%s'", - (void*)md, gpr_atm_no_barrier_load(&md->refcnt), - gpr_atm_no_barrier_load(&md->refcnt) - 1, key_str, value_str); - gpr_free(key_str); - gpr_free(value_str); - } -#endif - uint32_t hash = GRPC_MDSTR_KV_HASH(grpc_slice_hash(md->key), - grpc_slice_hash(md->value)); - const gpr_atm prev_refcount = gpr_atm_full_fetch_add(&md->refcnt, -1); - GPR_ASSERT(prev_refcount >= 1); - if (1 == prev_refcount) { - /* once the refcount hits zero, some other thread can come along and - free md at any time: it's unsafe from this point on to access it */ - mdtab_shard* shard = &g_shards[SHARD_IDX(hash)]; - gpr_atm_no_barrier_fetch_add(&shard->free_estimate, 1); - } - break; - } - case GRPC_MDELEM_STORAGE_ALLOCATED: { - allocated_metadata* md = - reinterpret_cast GRPC_MDELEM_DATA(gmd); -#ifndef NDEBUG - if (grpc_trace_metadata.enabled()) { - char* key_str = grpc_slice_to_c_string(md->key); - char* value_str = grpc_slice_to_c_string(md->value); - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, - "ELM UNREF:%p:%" PRIdPTR "->%" PRIdPTR ": '%s' = '%s'", - (void*)md, gpr_atm_no_barrier_load(&md->refcnt), - gpr_atm_no_barrier_load(&md->refcnt) - 1, key_str, value_str); - gpr_free(key_str); - gpr_free(value_str); - } -#endif - const gpr_atm prev_refcount = gpr_atm_full_fetch_add(&md->refcnt, -1); - GPR_ASSERT(prev_refcount >= 1); - if (1 == prev_refcount) { - grpc_slice_unref_internal(md->key); - grpc_slice_unref_internal(md->value); - gpr_free(md); - } - break; - } +static void* get_user_data(UserData* user_data, void (*destroy_func)(void*)) { + if (user_data->destroy_user_data.Load(grpc_core::MemoryOrder::ACQUIRE) == + destroy_func) { + return user_data->data.Load(grpc_core::MemoryOrder::RELAXED); + } else { + return nullptr; } } void* grpc_mdelem_get_user_data(grpc_mdelem md, void (*destroy_func)(void*)) { switch (GRPC_MDELEM_STORAGE(md)) { case GRPC_MDELEM_STORAGE_EXTERNAL: - case GRPC_MDELEM_STORAGE_ALLOCATED: return nullptr; case GRPC_MDELEM_STORAGE_STATIC: return (void*)grpc_static_mdelem_user_data[GRPC_MDELEM_DATA(md) - grpc_static_mdelem_table]; + case GRPC_MDELEM_STORAGE_ALLOCATED: { + auto* am = reinterpret_cast(GRPC_MDELEM_DATA(md)); + return get_user_data(am->user_data(), destroy_func); + } case GRPC_MDELEM_STORAGE_INTERNED: { - interned_metadata* im = - reinterpret_cast GRPC_MDELEM_DATA(md); - void* result; - if (gpr_atm_acq_load(&im->destroy_user_data) == (gpr_atm)destroy_func) { - return (void*)gpr_atm_no_barrier_load(&im->user_data); - } else { - return nullptr; - } - return result; + auto* im = reinterpret_cast GRPC_MDELEM_DATA(md); + return get_user_data(im->user_data(), destroy_func); } } GPR_UNREACHABLE_CODE(return nullptr); } +static void* set_user_data(UserData* ud, void (*destroy_func)(void*), + void* data) { + GPR_ASSERT((data == nullptr) == (destroy_func == nullptr)); + grpc_core::ReleasableMutexLock lock(&ud->mu_user_data); + if (ud->destroy_user_data.Load(grpc_core::MemoryOrder::RELAXED)) { + /* user data can only be set once */ + lock.Unlock(); + if (destroy_func != nullptr) { + destroy_func(data); + } + return ud->data.Load(grpc_core::MemoryOrder::RELAXED); + } + ud->data.Store(data, grpc_core::MemoryOrder::RELAXED); + ud->destroy_user_data.Store(destroy_func, grpc_core::MemoryOrder::RELEASE); + return data; +} + void* grpc_mdelem_set_user_data(grpc_mdelem md, void (*destroy_func)(void*), - void* user_data) { + void* data) { switch (GRPC_MDELEM_STORAGE(md)) { case GRPC_MDELEM_STORAGE_EXTERNAL: - case GRPC_MDELEM_STORAGE_ALLOCATED: - destroy_func(user_data); + destroy_func(data); return nullptr; case GRPC_MDELEM_STORAGE_STATIC: - destroy_func(user_data); + destroy_func(data); return (void*)grpc_static_mdelem_user_data[GRPC_MDELEM_DATA(md) - grpc_static_mdelem_table]; + case GRPC_MDELEM_STORAGE_ALLOCATED: { + auto* am = reinterpret_cast(GRPC_MDELEM_DATA(md)); + return set_user_data(am->user_data(), destroy_func, data); + } case GRPC_MDELEM_STORAGE_INTERNED: { - interned_metadata* im = - reinterpret_cast GRPC_MDELEM_DATA(md); + auto* im = reinterpret_cast GRPC_MDELEM_DATA(md); GPR_ASSERT(!is_mdelem_static(md)); - GPR_ASSERT((user_data == nullptr) == (destroy_func == nullptr)); - gpr_mu_lock(&im->mu_user_data); - if (gpr_atm_no_barrier_load(&im->destroy_user_data)) { - /* user data can only be set once */ - gpr_mu_unlock(&im->mu_user_data); - if (destroy_func != nullptr) { - destroy_func(user_data); - } - return (void*)gpr_atm_no_barrier_load(&im->user_data); - } - gpr_atm_no_barrier_store(&im->user_data, (gpr_atm)user_data); - gpr_atm_rel_store(&im->destroy_user_data, (gpr_atm)destroy_func); - gpr_mu_unlock(&im->mu_user_data); - return user_data; + return set_user_data(im->user_data(), destroy_func, data); } } GPR_UNREACHABLE_CODE(return nullptr); @@ -520,3 +452,33 @@ bool grpc_mdelem_eq(grpc_mdelem a, grpc_mdelem b) { return grpc_slice_eq(GRPC_MDKEY(a), GRPC_MDKEY(b)) && grpc_slice_eq(GRPC_MDVALUE(a), GRPC_MDVALUE(b)); } + +static void note_disposed_interned_metadata(uint32_t hash) { + mdtab_shard* shard = &g_shards[SHARD_IDX(hash)]; + gpr_atm_no_barrier_fetch_add(&shard->free_estimate, 1); +} + +void grpc_mdelem_do_unref(grpc_mdelem gmd DEBUG_ARGS) { + switch (GRPC_MDELEM_STORAGE(gmd)) { + case GRPC_MDELEM_STORAGE_EXTERNAL: + case GRPC_MDELEM_STORAGE_STATIC: + return; + case GRPC_MDELEM_STORAGE_INTERNED: { + auto* md = reinterpret_cast GRPC_MDELEM_DATA(gmd); + uint32_t hash = md->hash(); + if (GPR_UNLIKELY(md->Unref(FWD_DEBUG_ARGS))) { + /* once the refcount hits zero, some other thread can come along and + free md at any time: it's unsafe from this point on to access it */ + note_disposed_interned_metadata(hash); + } + break; + } + case GRPC_MDELEM_STORAGE_ALLOCATED: { + auto* md = reinterpret_cast GRPC_MDELEM_DATA(gmd); + if (GPR_UNLIKELY(md->Unref(FWD_DEBUG_ARGS))) { + grpc_core::Delete(md); + } + break; + } + } +} diff --git a/src/core/lib/transport/metadata.h b/src/core/lib/transport/metadata.h index 989c7544c1f..3ff5a35dd2d 100644 --- a/src/core/lib/transport/metadata.h +++ b/src/core/lib/transport/metadata.h @@ -21,11 +21,16 @@ #include +#include "include/grpc/impl/codegen/log.h" + #include #include #include "src/core/lib/debug/trace.h" #include "src/core/lib/gpr/useful.h" +#include "src/core/lib/gprpp/atomic.h" +#include "src/core/lib/gprpp/sync.h" +#include "src/core/lib/slice/slice_utils.h" extern grpc_core::DebugOnlyTraceFlag grpc_trace_metadata; @@ -63,7 +68,7 @@ extern grpc_core::DebugOnlyTraceFlag grpc_trace_metadata; typedef struct grpc_mdelem grpc_mdelem; /* if changing this, make identical changes in: - - interned_metadata, allocated_metadata in metadata.c + - grpc_core::{InternedMetadata, AllocatedMetadata} - grpc_metadata in grpc_types.h */ typedef struct grpc_mdelem_data { const grpc_slice key; @@ -124,28 +129,219 @@ grpc_mdelem grpc_mdelem_create( const grpc_slice& key, const grpc_slice& value, grpc_mdelem_data* compatible_external_backing_store); +#define GRPC_MDKEY(md) (GRPC_MDELEM_DATA(md)->key) +#define GRPC_MDVALUE(md) (GRPC_MDELEM_DATA(md)->value) + bool grpc_mdelem_eq(grpc_mdelem a, grpc_mdelem b); +/* Often we compare metadata where we know a-priori that the second parameter is + * static, and that the keys match. This most commonly happens when processing + * metadata batch callouts in initial/trailing filters. In this case, fastpath + * grpc_mdelem_eq and remove unnecessary checks. */ +inline bool grpc_mdelem_static_value_eq(grpc_mdelem a, grpc_mdelem b_static) { + if (a.payload == b_static.payload) return true; + return grpc_slice_eq_static_interned(GRPC_MDVALUE(a), GRPC_MDVALUE(b_static)); +} /* Mutator and accessor for grpc_mdelem user data. The destructor function is used as a type tag and is checked during user_data fetch. */ void* grpc_mdelem_get_user_data(grpc_mdelem md, void (*if_destroy_func)(void*)); void* grpc_mdelem_set_user_data(grpc_mdelem md, void (*destroy_func)(void*), - void* user_data); + void* data); + +// Defined in metadata.cc. +struct mdtab_shard; + +#ifndef NDEBUG +void grpc_mdelem_trace_ref(void* md, const grpc_slice& key, + const grpc_slice& value, intptr_t refcnt, + const char* file, int line); +void grpc_mdelem_trace_unref(void* md, const grpc_slice& key, + const grpc_slice& value, intptr_t refcnt, + const char* file, int line); +#endif +namespace grpc_core { + +typedef void (*destroy_user_data_func)(void* data); + +struct UserData { + Mutex mu_user_data; + grpc_core::Atomic destroy_user_data; + grpc_core::Atomic data; +}; + +class InternedMetadata { + public: + struct BucketLink { + explicit BucketLink(InternedMetadata* md) : next(md) {} + + InternedMetadata* next = nullptr; + }; + + InternedMetadata(const grpc_slice& key, const grpc_slice& value, + uint32_t hash, InternedMetadata* next); + ~InternedMetadata(); + +#ifndef NDEBUG + void Ref(const char* file, int line) { + grpc_mdelem_trace_ref(this, key_, value_, RefValue(), file, line); + const intptr_t prior = refcnt_.FetchAdd(1, MemoryOrder::RELAXED); + GPR_ASSERT(prior > 0); + } + bool Unref(const char* file, int line) { + grpc_mdelem_trace_unref(this, key_, value_, RefValue(), file, line); + return Unref(); + } +#else + // We define a naked Ref() in the else-clause to make sure we don't + // inadvertently skip the assert on debug builds. + void Ref() { + /* we can assume the ref count is >= 1 as the application is calling + this function - meaning that no adjustment to mdtab_free is necessary, + simplifying the logic here to be just an atomic increment */ + refcnt_.FetchAdd(1, MemoryOrder::RELAXED); + } +#endif // ifndef NDEBUG + bool Unref() { + const intptr_t prior = refcnt_.FetchSub(1, MemoryOrder::ACQ_REL); + GPR_DEBUG_ASSERT(prior > 0); + return prior == 1; + } + + void RefWithShardLocked(mdtab_shard* shard); + const grpc_slice& key() const { return key_; } + const grpc_slice& value() const { return value_; } + UserData* user_data() { return &user_data_; } + uint32_t hash() { return hash_; } + InternedMetadata* bucket_next() { return link_.next; } + void set_bucket_next(InternedMetadata* md) { link_.next = md; } + + static size_t CleanupLinkedMetadata(BucketLink* head); + + private: + bool AllRefsDropped() { return refcnt_.Load(MemoryOrder::ACQUIRE) == 0; } + bool FirstRef() { return refcnt_.FetchAdd(1, MemoryOrder::RELAXED) == 0; } + intptr_t RefValue() { return refcnt_.Load(MemoryOrder::RELAXED); } + + /* must be byte compatible with grpc_mdelem_data */ + grpc_slice key_; + grpc_slice value_; + + /* private only data */ + grpc_core::Atomic refcnt_; + uint32_t hash_; + + UserData user_data_; + + BucketLink link_; +}; + +/* Shadow structure for grpc_mdelem_data for allocated elements */ +class AllocatedMetadata { + public: + AllocatedMetadata(const grpc_slice& key, const grpc_slice& value); + ~AllocatedMetadata(); + + const grpc_slice& key() const { return key_; } + const grpc_slice& value() const { return value_; } + UserData* user_data() { return &user_data_; } + +#ifndef NDEBUG + void Ref(const char* file, int line) { + grpc_mdelem_trace_ref(this, key_, value_, RefValue(), file, line); + Ref(); + } + bool Unref(const char* file, int line) { + grpc_mdelem_trace_unref(this, key_, value_, RefValue(), file, line); + return Unref(); + } +#endif // ifndef NDEBUG + void Ref() { + /* we can assume the ref count is >= 1 as the application is calling + this function - meaning that no adjustment to mdtab_free is necessary, + simplifying the logic here to be just an atomic increment */ + refcnt_.FetchAdd(1, MemoryOrder::RELAXED); + } + bool Unref() { + const intptr_t prior = refcnt_.FetchSub(1, MemoryOrder::ACQ_REL); + GPR_DEBUG_ASSERT(prior > 0); + return prior == 1; + } + + private: + intptr_t RefValue() { return refcnt_.Load(MemoryOrder::RELAXED); } + + /* must be byte compatible with grpc_mdelem_data */ + grpc_slice key_; + grpc_slice value_; + + /* private only data */ + grpc_core::Atomic refcnt_; + + UserData user_data_; +}; + +} // namespace grpc_core #ifndef NDEBUG #define GRPC_MDELEM_REF(s) grpc_mdelem_ref((s), __FILE__, __LINE__) -#define GRPC_MDELEM_UNREF(s) grpc_mdelem_unref((s), __FILE__, __LINE__) -grpc_mdelem grpc_mdelem_ref(grpc_mdelem md, const char* file, int line); -void grpc_mdelem_unref(grpc_mdelem md, const char* file, int line); -#else +inline grpc_mdelem grpc_mdelem_ref(grpc_mdelem gmd, const char* file, + int line) { +#else // ifndef NDEBUG #define GRPC_MDELEM_REF(s) grpc_mdelem_ref((s)) -#define GRPC_MDELEM_UNREF(s) grpc_mdelem_unref((s)) -grpc_mdelem grpc_mdelem_ref(grpc_mdelem md); -void grpc_mdelem_unref(grpc_mdelem md); +inline grpc_mdelem grpc_mdelem_ref(grpc_mdelem gmd) { +#endif // ifndef NDEBUG + switch (GRPC_MDELEM_STORAGE(gmd)) { + case GRPC_MDELEM_STORAGE_EXTERNAL: + case GRPC_MDELEM_STORAGE_STATIC: + break; + case GRPC_MDELEM_STORAGE_INTERNED: { + auto* md = + reinterpret_cast GRPC_MDELEM_DATA(gmd); + /* use C assert to have this removed in opt builds */ +#ifndef NDEBUG + md->Ref(file, line); +#else + md->Ref(); #endif + break; + } + case GRPC_MDELEM_STORAGE_ALLOCATED: { + auto* md = + reinterpret_cast GRPC_MDELEM_DATA(gmd); +#ifndef NDEBUG + md->Ref(file, line); +#else + md->Ref(); +#endif + break; + } + } + return gmd; +} -#define GRPC_MDKEY(md) (GRPC_MDELEM_DATA(md)->key) -#define GRPC_MDVALUE(md) (GRPC_MDELEM_DATA(md)->value) +#ifndef NDEBUG +#define GRPC_MDELEM_UNREF(s) grpc_mdelem_unref((s), __FILE__, __LINE__) +void grpc_mdelem_do_unref(grpc_mdelem gmd, const char* file, int line); +inline void grpc_mdelem_unref(grpc_mdelem gmd, const char* file, int line) { +#else +#define GRPC_MDELEM_UNREF(s) grpc_mdelem_unref((s)) +void grpc_mdelem_do_unref(grpc_mdelem gmd); +inline void grpc_mdelem_unref(grpc_mdelem gmd) { +#endif + switch (GRPC_MDELEM_STORAGE(gmd)) { + case GRPC_MDELEM_STORAGE_EXTERNAL: + case GRPC_MDELEM_STORAGE_STATIC: + return; + case GRPC_MDELEM_STORAGE_INTERNED: + case GRPC_MDELEM_STORAGE_ALLOCATED: +#ifndef NDEBUG + grpc_mdelem_do_unref(gmd, file, line); +#else + grpc_mdelem_do_unref(gmd); +#endif + return; + } +} #define GRPC_MDNULL GRPC_MAKE_MDELEM(NULL, GRPC_MDELEM_STORAGE_EXTERNAL) #define GRPC_MDISNULL(md) (GRPC_MDELEM_DATA(md) == NULL) diff --git a/src/core/lib/transport/metadata_batch.cc b/src/core/lib/transport/metadata_batch.cc index 928ed73cdad..49a56e709d5 100644 --- a/src/core/lib/transport/metadata_batch.cc +++ b/src/core/lib/transport/metadata_batch.cc @@ -227,7 +227,7 @@ void grpc_metadata_batch_remove(grpc_metadata_batch* batch, } void grpc_metadata_batch_set_value(grpc_linked_mdelem* storage, - grpc_slice value) { + const grpc_slice& value) { grpc_mdelem old_mdelem = storage->md; grpc_mdelem new_mdelem = grpc_mdelem_from_slices( grpc_slice_ref_internal(GRPC_MDKEY(old_mdelem)), value); diff --git a/src/core/lib/transport/metadata_batch.h b/src/core/lib/transport/metadata_batch.h index f6e8bbf2052..d87a8b0886d 100644 --- a/src/core/lib/transport/metadata_batch.h +++ b/src/core/lib/transport/metadata_batch.h @@ -74,7 +74,7 @@ grpc_error* grpc_metadata_batch_substitute(grpc_metadata_batch* batch, grpc_mdelem new_value); void grpc_metadata_batch_set_value(grpc_linked_mdelem* storage, - grpc_slice value); + const grpc_slice& value); /** Add \a storage to the beginning of \a batch. storage->md is assumed to be valid. diff --git a/src/core/lib/transport/service_config.cc b/src/core/lib/transport/service_config.cc deleted file mode 100644 index 405e3360287..00000000000 --- a/src/core/lib/transport/service_config.cc +++ /dev/null @@ -1,106 +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 - -#include "src/core/lib/transport/service_config.h" - -#include - -#include -#include -#include -#include - -#include "src/core/lib/gpr/string.h" -#include "src/core/lib/json/json.h" -#include "src/core/lib/slice/slice_hash_table.h" -#include "src/core/lib/slice/slice_internal.h" -#include "src/core/lib/slice/slice_string_helpers.h" - -namespace grpc_core { - -UniquePtr ServiceConfig::Create(const char* json) { - UniquePtr json_string(gpr_strdup(json)); - grpc_json* json_tree = grpc_json_parse_string(json_string.get()); - if (json_tree == nullptr) { - gpr_log(GPR_INFO, "failed to parse JSON for service config"); - return nullptr; - } - return MakeUnique(std::move(json_string), json_tree); -} - -ServiceConfig::ServiceConfig(UniquePtr json_string, grpc_json* json_tree) - : json_string_(std::move(json_string)), json_tree_(json_tree) {} - -ServiceConfig::~ServiceConfig() { grpc_json_destroy(json_tree_); } - -const char* ServiceConfig::GetLoadBalancingPolicyName() const { - if (json_tree_->type != GRPC_JSON_OBJECT || json_tree_->key != nullptr) { - return nullptr; - } - const char* lb_policy_name = nullptr; - for (grpc_json* field = json_tree_->child; field != nullptr; - field = field->next) { - if (field->key == nullptr) return nullptr; - if (strcmp(field->key, "loadBalancingPolicy") == 0) { - if (lb_policy_name != nullptr) return nullptr; // Duplicate. - if (field->type != GRPC_JSON_STRING) return nullptr; - lb_policy_name = field->value; - } - } - return lb_policy_name; -} - -int ServiceConfig::CountNamesInMethodConfig(grpc_json* json) { - int num_names = 0; - for (grpc_json* field = json->child; field != nullptr; field = field->next) { - if (field->key != nullptr && strcmp(field->key, "name") == 0) { - if (field->type != GRPC_JSON_ARRAY) return -1; - for (grpc_json* name = field->child; name != nullptr; name = name->next) { - if (name->type != GRPC_JSON_OBJECT) return -1; - ++num_names; - } - } - } - return num_names; -} - -UniquePtr ServiceConfig::ParseJsonMethodName(grpc_json* json) { - if (json->type != GRPC_JSON_OBJECT) return nullptr; - const char* service_name = nullptr; - const char* method_name = nullptr; - for (grpc_json* child = json->child; child != nullptr; child = child->next) { - if (child->key == nullptr) return nullptr; - if (child->type != GRPC_JSON_STRING) return nullptr; - if (strcmp(child->key, "service") == 0) { - if (service_name != nullptr) return nullptr; // Duplicate. - if (child->value == nullptr) return nullptr; - service_name = child->value; - } else if (strcmp(child->key, "method") == 0) { - if (method_name != nullptr) return nullptr; // Duplicate. - if (child->value == nullptr) return nullptr; - method_name = child->value; - } - } - if (service_name == nullptr) return nullptr; // Required field. - char* path; - gpr_asprintf(&path, "/%s/%s", service_name, - method_name == nullptr ? "*" : method_name); - return UniquePtr(path); -} - -} // namespace grpc_core diff --git a/src/core/lib/transport/service_config.h b/src/core/lib/transport/service_config.h deleted file mode 100644 index 2c0dd758453..00000000000 --- a/src/core/lib/transport/service_config.h +++ /dev/null @@ -1,249 +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. -// - -#ifndef GRPC_CORE_LIB_TRANSPORT_SERVICE_CONFIG_H -#define GRPC_CORE_LIB_TRANSPORT_SERVICE_CONFIG_H - -#include - -#include -#include - -#include "src/core/lib/gprpp/inlined_vector.h" -#include "src/core/lib/gprpp/ref_counted_ptr.h" -#include "src/core/lib/json/json.h" -#include "src/core/lib/slice/slice_hash_table.h" - -// The main purpose of the code here is to parse the service config in -// JSON form, which will look like this: -// -// { -// "loadBalancingPolicy": "string", // optional -// "methodConfig": [ // array of one or more method_config objects -// { -// "name": [ // array of one or more name objects -// { -// "service": "string", // required -// "method": "string", // optional -// } -// ], -// // remaining fields are optional. -// // see -// https://developers.google.com/protocol-buffers/docs/proto3#json -// // for format details. -// "waitForReady": bool, -// "timeout": "duration_string", -// "maxRequestMessageBytes": "int64_string", -// "maxResponseMessageBytes": "int64_string", -// } -// ] -// } - -namespace grpc_core { - -class ServiceConfig { - public: - /// Creates a new service config from parsing \a json_string. - /// Returns null on parse error. - static UniquePtr Create(const char* json); - - ~ServiceConfig(); - - /// Invokes \a process_json() for each global parameter in the service - /// config. \a arg is passed as the second argument to \a process_json(). - template - using ProcessJson = void (*)(const grpc_json*, T*); - template - void ParseGlobalParams(ProcessJson process_json, T* arg) const; - - /// Gets the LB policy name from \a service_config. - /// Returns NULL if no LB policy name was specified. - /// Caller does NOT take ownership. - const char* GetLoadBalancingPolicyName() const; - - /// Creates a method config table based on the data in \a json. - /// The table's keys are request paths. The table's value type is - /// returned by \a create_value(), based on data parsed from the JSON tree. - /// Returns null on error. - template - using CreateValue = RefCountedPtr (*)(const grpc_json* method_config_json); - template - RefCountedPtr>> CreateMethodConfigTable( - CreateValue create_value); - - /// A helper function for looking up values in the table returned by - /// \a CreateMethodConfigTable(). - /// Gets the method config for the specified \a path, which should be of - /// the form "/service/method". - /// Returns null if the method has no config. - /// Caller does NOT own a reference to the result. - template - static RefCountedPtr MethodConfigTableLookup( - const SliceHashTable>& table, grpc_slice path); - - private: - // So New() can call our private ctor. - template - friend T* New(Args&&... args); - - // Takes ownership of \a json_tree. - ServiceConfig(UniquePtr json_string, grpc_json* json_tree); - - // Returns the number of names specified in the method config \a json. - static int CountNamesInMethodConfig(grpc_json* json); - - // Returns a path string for the JSON name object specified by \a json. - // Returns null on error. - static UniquePtr ParseJsonMethodName(grpc_json* json); - - // Parses the method config from \a json. Adds an entry to \a entries for - // each name found, incrementing \a idx for each entry added. - // Returns false on error. - template - static bool ParseJsonMethodConfig( - grpc_json* json, CreateValue create_value, - typename SliceHashTable>::Entry* entries, size_t* idx); - - UniquePtr json_string_; // Underlying storage for json_tree. - grpc_json* json_tree_; -}; - -// -// implementation -- no user-serviceable parts below -// - -template -void ServiceConfig::ParseGlobalParams(ProcessJson process_json, - T* arg) const { - if (json_tree_->type != GRPC_JSON_OBJECT || json_tree_->key != nullptr) { - return; - } - for (grpc_json* field = json_tree_->child; field != nullptr; - field = field->next) { - if (field->key == nullptr) return; - if (strcmp(field->key, "methodConfig") == 0) continue; - process_json(field, arg); - } -} - -template -bool ServiceConfig::ParseJsonMethodConfig( - grpc_json* json, CreateValue create_value, - typename SliceHashTable>::Entry* entries, size_t* idx) { - // Construct value. - RefCountedPtr method_config = create_value(json); - if (method_config == nullptr) return false; - // Construct list of paths. - InlinedVector, 10> paths; - for (grpc_json* child = json->child; child != nullptr; child = child->next) { - if (child->key == nullptr) continue; - if (strcmp(child->key, "name") == 0) { - if (child->type != GRPC_JSON_ARRAY) return false; - for (grpc_json* name = child->child; name != nullptr; name = name->next) { - UniquePtr path = ParseJsonMethodName(name); - if (path == nullptr) return false; - paths.push_back(std::move(path)); - } - } - } - if (paths.size() == 0) return false; // No names specified. - // Add entry for each path. - for (size_t i = 0; i < paths.size(); ++i) { - entries[*idx].key = grpc_slice_from_copied_string(paths[i].get()); - entries[*idx].value = method_config; // Takes a new ref. - ++*idx; - } - // Success. - return true; -} - -template -RefCountedPtr>> -ServiceConfig::CreateMethodConfigTable(CreateValue create_value) { - // Traverse parsed JSON tree. - if (json_tree_->type != GRPC_JSON_OBJECT || json_tree_->key != nullptr) { - return nullptr; - } - size_t num_entries = 0; - typename SliceHashTable>::Entry* entries = nullptr; - for (grpc_json* field = json_tree_->child; field != nullptr; - field = field->next) { - if (field->key == nullptr) return nullptr; - if (strcmp(field->key, "methodConfig") == 0) { - if (entries != nullptr) return nullptr; // Duplicate. - if (field->type != GRPC_JSON_ARRAY) return nullptr; - // Find number of entries. - for (grpc_json* method = field->child; method != nullptr; - method = method->next) { - int count = CountNamesInMethodConfig(method); - if (count <= 0) return nullptr; - num_entries += static_cast(count); - } - // Populate method config table entries. - entries = static_cast>::Entry*>( - gpr_zalloc(num_entries * - sizeof(typename SliceHashTable>::Entry))); - size_t idx = 0; - for (grpc_json* method = field->child; method != nullptr; - method = method->next) { - if (!ParseJsonMethodConfig(method, create_value, entries, &idx)) { - for (size_t i = 0; i < idx; ++i) { - grpc_slice_unref_internal(entries[i].key); - entries[i].value.reset(); - } - gpr_free(entries); - return nullptr; - } - } - GPR_ASSERT(idx == num_entries); - } - } - // Instantiate method config table. - RefCountedPtr>> method_config_table; - if (entries != nullptr) { - method_config_table = - SliceHashTable>::Create(num_entries, entries, nullptr); - gpr_free(entries); - } - return method_config_table; -} - -template -RefCountedPtr ServiceConfig::MethodConfigTableLookup( - const SliceHashTable>& table, grpc_slice path) { - const RefCountedPtr* value = table.Get(path); - // If we didn't find a match for the path, try looking for a wildcard - // entry (i.e., change "/service/method" to "/service/*"). - if (value == nullptr) { - char* path_str = grpc_slice_to_c_string(path); - const char* sep = strrchr(path_str, '/') + 1; - const size_t len = (size_t)(sep - path_str); - char* buf = (char*)gpr_malloc(len + 2); // '*' and NUL - memcpy(buf, path_str, len); - buf[len] = '*'; - buf[len + 1] = '\0'; - grpc_slice wildcard_path = grpc_slice_from_copied_string(buf); - gpr_free(buf); - value = table.Get(wildcard_path); - grpc_slice_unref_internal(wildcard_path); - gpr_free(path_str); - } - return RefCountedPtr(*value); -} - -} // namespace grpc_core - -#endif /* GRPC_CORE_LIB_TRANSPORT_SERVICE_CONFIG_H */ diff --git a/src/core/lib/transport/static_metadata.cc b/src/core/lib/transport/static_metadata.cc index 4ebe73f82a0..61ee1d46f77 100644 --- a/src/core/lib/transport/static_metadata.cc +++ b/src/core/lib/transport/static_metadata.cc @@ -65,277 +65,276 @@ static uint8_t g_bytes[] = { 97, 110, 99, 101, 114, 47, 66, 97, 108, 97, 110, 99, 101, 76, 111, 97, 100, 47, 103, 114, 112, 99, 46, 104, 101, 97, 108, 116, 104, 46, 118, 49, 46, 72, 101, 97, 108, 116, 104, 47, 87, 97, 116, 99, 104, - 100, 101, 102, 108, 97, 116, 101, 103, 122, 105, 112, 115, 116, 114, 101, - 97, 109, 47, 103, 122, 105, 112, 71, 69, 84, 80, 79, 83, 84, 47, - 47, 105, 110, 100, 101, 120, 46, 104, 116, 109, 108, 104, 116, 116, 112, - 104, 116, 116, 112, 115, 50, 48, 48, 50, 48, 52, 50, 48, 54, 51, - 48, 52, 52, 48, 48, 52, 48, 52, 53, 48, 48, 97, 99, 99, 101, - 112, 116, 45, 99, 104, 97, 114, 115, 101, 116, 103, 122, 105, 112, 44, - 32, 100, 101, 102, 108, 97, 116, 101, 97, 99, 99, 101, 112, 116, 45, - 108, 97, 110, 103, 117, 97, 103, 101, 97, 99, 99, 101, 112, 116, 45, - 114, 97, 110, 103, 101, 115, 97, 99, 99, 101, 112, 116, 97, 99, 99, - 101, 115, 115, 45, 99, 111, 110, 116, 114, 111, 108, 45, 97, 108, 108, - 111, 119, 45, 111, 114, 105, 103, 105, 110, 97, 103, 101, 97, 108, 108, - 111, 119, 97, 117, 116, 104, 111, 114, 105, 122, 97, 116, 105, 111, 110, - 99, 97, 99, 104, 101, 45, 99, 111, 110, 116, 114, 111, 108, 99, 111, - 110, 116, 101, 110, 116, 45, 100, 105, 115, 112, 111, 115, 105, 116, 105, - 111, 110, 99, 111, 110, 116, 101, 110, 116, 45, 108, 97, 110, 103, 117, - 97, 103, 101, 99, 111, 110, 116, 101, 110, 116, 45, 108, 101, 110, 103, - 116, 104, 99, 111, 110, 116, 101, 110, 116, 45, 108, 111, 99, 97, 116, - 105, 111, 110, 99, 111, 110, 116, 101, 110, 116, 45, 114, 97, 110, 103, - 101, 99, 111, 111, 107, 105, 101, 100, 97, 116, 101, 101, 116, 97, 103, - 101, 120, 112, 101, 99, 116, 101, 120, 112, 105, 114, 101, 115, 102, 114, - 111, 109, 105, 102, 45, 109, 97, 116, 99, 104, 105, 102, 45, 109, 111, - 100, 105, 102, 105, 101, 100, 45, 115, 105, 110, 99, 101, 105, 102, 45, - 110, 111, 110, 101, 45, 109, 97, 116, 99, 104, 105, 102, 45, 114, 97, - 110, 103, 101, 105, 102, 45, 117, 110, 109, 111, 100, 105, 102, 105, 101, - 100, 45, 115, 105, 110, 99, 101, 108, 97, 115, 116, 45, 109, 111, 100, - 105, 102, 105, 101, 100, 108, 105, 110, 107, 108, 111, 99, 97, 116, 105, - 111, 110, 109, 97, 120, 45, 102, 111, 114, 119, 97, 114, 100, 115, 112, - 114, 111, 120, 121, 45, 97, 117, 116, 104, 101, 110, 116, 105, 99, 97, - 116, 101, 112, 114, 111, 120, 121, 45, 97, 117, 116, 104, 111, 114, 105, - 122, 97, 116, 105, 111, 110, 114, 97, 110, 103, 101, 114, 101, 102, 101, - 114, 101, 114, 114, 101, 102, 114, 101, 115, 104, 114, 101, 116, 114, 121, - 45, 97, 102, 116, 101, 114, 115, 101, 114, 118, 101, 114, 115, 101, 116, - 45, 99, 111, 111, 107, 105, 101, 115, 116, 114, 105, 99, 116, 45, 116, - 114, 97, 110, 115, 112, 111, 114, 116, 45, 115, 101, 99, 117, 114, 105, - 116, 121, 116, 114, 97, 110, 115, 102, 101, 114, 45, 101, 110, 99, 111, - 100, 105, 110, 103, 118, 97, 114, 121, 118, 105, 97, 119, 119, 119, 45, - 97, 117, 116, 104, 101, 110, 116, 105, 99, 97, 116, 101, 48, 105, 100, - 101, 110, 116, 105, 116, 121, 116, 114, 97, 105, 108, 101, 114, 115, 97, - 112, 112, 108, 105, 99, 97, 116, 105, 111, 110, 47, 103, 114, 112, 99, - 103, 114, 112, 99, 80, 85, 84, 108, 98, 45, 99, 111, 115, 116, 45, - 98, 105, 110, 105, 100, 101, 110, 116, 105, 116, 121, 44, 100, 101, 102, - 108, 97, 116, 101, 105, 100, 101, 110, 116, 105, 116, 121, 44, 103, 122, - 105, 112, 100, 101, 102, 108, 97, 116, 101, 44, 103, 122, 105, 112, 105, - 100, 101, 110, 116, 105, 116, 121, 44, 100, 101, 102, 108, 97, 116, 101, - 44, 103, 122, 105, 112}; + 47, 101, 110, 118, 111, 121, 46, 115, 101, 114, 118, 105, 99, 101, 46, + 100, 105, 115, 99, 111, 118, 101, 114, 121, 46, 118, 50, 46, 65, 103, + 103, 114, 101, 103, 97, 116, 101, 100, 68, 105, 115, 99, 111, 118, 101, + 114, 121, 83, 101, 114, 118, 105, 99, 101, 47, 83, 116, 114, 101, 97, + 109, 65, 103, 103, 114, 101, 103, 97, 116, 101, 100, 82, 101, 115, 111, + 117, 114, 99, 101, 115, 100, 101, 102, 108, 97, 116, 101, 103, 122, 105, + 112, 115, 116, 114, 101, 97, 109, 47, 103, 122, 105, 112, 71, 69, 84, + 80, 79, 83, 84, 47, 47, 105, 110, 100, 101, 120, 46, 104, 116, 109, + 108, 104, 116, 116, 112, 104, 116, 116, 112, 115, 50, 48, 48, 50, 48, + 52, 50, 48, 54, 51, 48, 52, 52, 48, 48, 52, 48, 52, 53, 48, + 48, 97, 99, 99, 101, 112, 116, 45, 99, 104, 97, 114, 115, 101, 116, + 103, 122, 105, 112, 44, 32, 100, 101, 102, 108, 97, 116, 101, 97, 99, + 99, 101, 112, 116, 45, 108, 97, 110, 103, 117, 97, 103, 101, 97, 99, + 99, 101, 112, 116, 45, 114, 97, 110, 103, 101, 115, 97, 99, 99, 101, + 112, 116, 97, 99, 99, 101, 115, 115, 45, 99, 111, 110, 116, 114, 111, + 108, 45, 97, 108, 108, 111, 119, 45, 111, 114, 105, 103, 105, 110, 97, + 103, 101, 97, 108, 108, 111, 119, 97, 117, 116, 104, 111, 114, 105, 122, + 97, 116, 105, 111, 110, 99, 97, 99, 104, 101, 45, 99, 111, 110, 116, + 114, 111, 108, 99, 111, 110, 116, 101, 110, 116, 45, 100, 105, 115, 112, + 111, 115, 105, 116, 105, 111, 110, 99, 111, 110, 116, 101, 110, 116, 45, + 108, 97, 110, 103, 117, 97, 103, 101, 99, 111, 110, 116, 101, 110, 116, + 45, 108, 101, 110, 103, 116, 104, 99, 111, 110, 116, 101, 110, 116, 45, + 108, 111, 99, 97, 116, 105, 111, 110, 99, 111, 110, 116, 101, 110, 116, + 45, 114, 97, 110, 103, 101, 99, 111, 111, 107, 105, 101, 100, 97, 116, + 101, 101, 116, 97, 103, 101, 120, 112, 101, 99, 116, 101, 120, 112, 105, + 114, 101, 115, 102, 114, 111, 109, 105, 102, 45, 109, 97, 116, 99, 104, + 105, 102, 45, 109, 111, 100, 105, 102, 105, 101, 100, 45, 115, 105, 110, + 99, 101, 105, 102, 45, 110, 111, 110, 101, 45, 109, 97, 116, 99, 104, + 105, 102, 45, 114, 97, 110, 103, 101, 105, 102, 45, 117, 110, 109, 111, + 100, 105, 102, 105, 101, 100, 45, 115, 105, 110, 99, 101, 108, 97, 115, + 116, 45, 109, 111, 100, 105, 102, 105, 101, 100, 108, 105, 110, 107, 108, + 111, 99, 97, 116, 105, 111, 110, 109, 97, 120, 45, 102, 111, 114, 119, + 97, 114, 100, 115, 112, 114, 111, 120, 121, 45, 97, 117, 116, 104, 101, + 110, 116, 105, 99, 97, 116, 101, 112, 114, 111, 120, 121, 45, 97, 117, + 116, 104, 111, 114, 105, 122, 97, 116, 105, 111, 110, 114, 97, 110, 103, + 101, 114, 101, 102, 101, 114, 101, 114, 114, 101, 102, 114, 101, 115, 104, + 114, 101, 116, 114, 121, 45, 97, 102, 116, 101, 114, 115, 101, 114, 118, + 101, 114, 115, 101, 116, 45, 99, 111, 111, 107, 105, 101, 115, 116, 114, + 105, 99, 116, 45, 116, 114, 97, 110, 115, 112, 111, 114, 116, 45, 115, + 101, 99, 117, 114, 105, 116, 121, 116, 114, 97, 110, 115, 102, 101, 114, + 45, 101, 110, 99, 111, 100, 105, 110, 103, 118, 97, 114, 121, 118, 105, + 97, 119, 119, 119, 45, 97, 117, 116, 104, 101, 110, 116, 105, 99, 97, + 116, 101, 48, 105, 100, 101, 110, 116, 105, 116, 121, 116, 114, 97, 105, + 108, 101, 114, 115, 97, 112, 112, 108, 105, 99, 97, 116, 105, 111, 110, + 47, 103, 114, 112, 99, 103, 114, 112, 99, 80, 85, 84, 108, 98, 45, + 99, 111, 115, 116, 45, 98, 105, 110, 105, 100, 101, 110, 116, 105, 116, + 121, 44, 100, 101, 102, 108, 97, 116, 101, 105, 100, 101, 110, 116, 105, + 116, 121, 44, 103, 122, 105, 112, 100, 101, 102, 108, 97, 116, 101, 44, + 103, 122, 105, 112, 105, 100, 101, 110, 116, 105, 116, 121, 44, 100, 101, + 102, 108, 97, 116, 101, 44, 103, 122, 105, 112}; -static void static_ref(void* unused) {} -static void static_unref(void* unused) {} -static const grpc_slice_refcount_vtable static_sub_vtable = { - static_ref, static_unref, grpc_slice_default_eq_impl, - grpc_slice_default_hash_impl}; -const grpc_slice_refcount_vtable grpc_static_metadata_vtable = { - static_ref, static_unref, grpc_static_slice_eq, grpc_static_slice_hash}; -static grpc_slice_refcount static_sub_refcnt = {&static_sub_vtable, - &static_sub_refcnt}; +static grpc_slice_refcount static_sub_refcnt; grpc_slice_refcount grpc_static_metadata_refcounts[GRPC_STATIC_MDSTR_COUNT] = { - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, - {&grpc_static_metadata_vtable, &static_sub_refcnt}, + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), + grpc_slice_refcount(&static_sub_refcnt, grpc_slice_refcount::Type::STATIC), }; const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT] = { - {&grpc_static_metadata_refcounts[0], {{g_bytes + 0, 5}}}, - {&grpc_static_metadata_refcounts[1], {{g_bytes + 5, 7}}}, - {&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[3], {{g_bytes + 19, 10}}}, - {&grpc_static_metadata_refcounts[4], {{g_bytes + 29, 7}}}, - {&grpc_static_metadata_refcounts[5], {{g_bytes + 36, 2}}}, - {&grpc_static_metadata_refcounts[6], {{g_bytes + 38, 12}}}, - {&grpc_static_metadata_refcounts[7], {{g_bytes + 50, 11}}}, - {&grpc_static_metadata_refcounts[8], {{g_bytes + 61, 16}}}, - {&grpc_static_metadata_refcounts[9], {{g_bytes + 77, 13}}}, - {&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, - {&grpc_static_metadata_refcounts[11], {{g_bytes + 110, 21}}}, - {&grpc_static_metadata_refcounts[12], {{g_bytes + 131, 13}}}, - {&grpc_static_metadata_refcounts[13], {{g_bytes + 144, 14}}}, - {&grpc_static_metadata_refcounts[14], {{g_bytes + 158, 12}}}, - {&grpc_static_metadata_refcounts[15], {{g_bytes + 170, 16}}}, - {&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}}, - {&grpc_static_metadata_refcounts[17], {{g_bytes + 201, 30}}}, - {&grpc_static_metadata_refcounts[18], {{g_bytes + 231, 37}}}, - {&grpc_static_metadata_refcounts[19], {{g_bytes + 268, 10}}}, - {&grpc_static_metadata_refcounts[20], {{g_bytes + 278, 4}}}, - {&grpc_static_metadata_refcounts[21], {{g_bytes + 282, 8}}}, - {&grpc_static_metadata_refcounts[22], {{g_bytes + 290, 26}}}, - {&grpc_static_metadata_refcounts[23], {{g_bytes + 316, 22}}}, - {&grpc_static_metadata_refcounts[24], {{g_bytes + 338, 12}}}, - {&grpc_static_metadata_refcounts[25], {{g_bytes + 350, 1}}}, - {&grpc_static_metadata_refcounts[26], {{g_bytes + 351, 1}}}, - {&grpc_static_metadata_refcounts[27], {{g_bytes + 352, 1}}}, - {&grpc_static_metadata_refcounts[28], {{g_bytes + 353, 1}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}, - {&grpc_static_metadata_refcounts[30], {{g_bytes + 354, 19}}}, - {&grpc_static_metadata_refcounts[31], {{g_bytes + 373, 12}}}, - {&grpc_static_metadata_refcounts[32], {{g_bytes + 385, 30}}}, - {&grpc_static_metadata_refcounts[33], {{g_bytes + 415, 31}}}, - {&grpc_static_metadata_refcounts[34], {{g_bytes + 446, 36}}}, - {&grpc_static_metadata_refcounts[35], {{g_bytes + 482, 28}}}, - {&grpc_static_metadata_refcounts[36], {{g_bytes + 510, 7}}}, - {&grpc_static_metadata_refcounts[37], {{g_bytes + 517, 4}}}, - {&grpc_static_metadata_refcounts[38], {{g_bytes + 521, 11}}}, - {&grpc_static_metadata_refcounts[39], {{g_bytes + 532, 3}}}, - {&grpc_static_metadata_refcounts[40], {{g_bytes + 535, 4}}}, - {&grpc_static_metadata_refcounts[41], {{g_bytes + 539, 1}}}, - {&grpc_static_metadata_refcounts[42], {{g_bytes + 540, 11}}}, - {&grpc_static_metadata_refcounts[43], {{g_bytes + 551, 4}}}, - {&grpc_static_metadata_refcounts[44], {{g_bytes + 555, 5}}}, - {&grpc_static_metadata_refcounts[45], {{g_bytes + 560, 3}}}, - {&grpc_static_metadata_refcounts[46], {{g_bytes + 563, 3}}}, - {&grpc_static_metadata_refcounts[47], {{g_bytes + 566, 3}}}, - {&grpc_static_metadata_refcounts[48], {{g_bytes + 569, 3}}}, - {&grpc_static_metadata_refcounts[49], {{g_bytes + 572, 3}}}, - {&grpc_static_metadata_refcounts[50], {{g_bytes + 575, 3}}}, - {&grpc_static_metadata_refcounts[51], {{g_bytes + 578, 3}}}, - {&grpc_static_metadata_refcounts[52], {{g_bytes + 581, 14}}}, - {&grpc_static_metadata_refcounts[53], {{g_bytes + 595, 13}}}, - {&grpc_static_metadata_refcounts[54], {{g_bytes + 608, 15}}}, - {&grpc_static_metadata_refcounts[55], {{g_bytes + 623, 13}}}, - {&grpc_static_metadata_refcounts[56], {{g_bytes + 636, 6}}}, - {&grpc_static_metadata_refcounts[57], {{g_bytes + 642, 27}}}, - {&grpc_static_metadata_refcounts[58], {{g_bytes + 669, 3}}}, - {&grpc_static_metadata_refcounts[59], {{g_bytes + 672, 5}}}, - {&grpc_static_metadata_refcounts[60], {{g_bytes + 677, 13}}}, - {&grpc_static_metadata_refcounts[61], {{g_bytes + 690, 13}}}, - {&grpc_static_metadata_refcounts[62], {{g_bytes + 703, 19}}}, - {&grpc_static_metadata_refcounts[63], {{g_bytes + 722, 16}}}, - {&grpc_static_metadata_refcounts[64], {{g_bytes + 738, 14}}}, - {&grpc_static_metadata_refcounts[65], {{g_bytes + 752, 16}}}, - {&grpc_static_metadata_refcounts[66], {{g_bytes + 768, 13}}}, - {&grpc_static_metadata_refcounts[67], {{g_bytes + 781, 6}}}, - {&grpc_static_metadata_refcounts[68], {{g_bytes + 787, 4}}}, - {&grpc_static_metadata_refcounts[69], {{g_bytes + 791, 4}}}, - {&grpc_static_metadata_refcounts[70], {{g_bytes + 795, 6}}}, - {&grpc_static_metadata_refcounts[71], {{g_bytes + 801, 7}}}, - {&grpc_static_metadata_refcounts[72], {{g_bytes + 808, 4}}}, - {&grpc_static_metadata_refcounts[73], {{g_bytes + 812, 8}}}, - {&grpc_static_metadata_refcounts[74], {{g_bytes + 820, 17}}}, - {&grpc_static_metadata_refcounts[75], {{g_bytes + 837, 13}}}, - {&grpc_static_metadata_refcounts[76], {{g_bytes + 850, 8}}}, - {&grpc_static_metadata_refcounts[77], {{g_bytes + 858, 19}}}, - {&grpc_static_metadata_refcounts[78], {{g_bytes + 877, 13}}}, - {&grpc_static_metadata_refcounts[79], {{g_bytes + 890, 4}}}, - {&grpc_static_metadata_refcounts[80], {{g_bytes + 894, 8}}}, - {&grpc_static_metadata_refcounts[81], {{g_bytes + 902, 12}}}, - {&grpc_static_metadata_refcounts[82], {{g_bytes + 914, 18}}}, - {&grpc_static_metadata_refcounts[83], {{g_bytes + 932, 19}}}, - {&grpc_static_metadata_refcounts[84], {{g_bytes + 951, 5}}}, - {&grpc_static_metadata_refcounts[85], {{g_bytes + 956, 7}}}, - {&grpc_static_metadata_refcounts[86], {{g_bytes + 963, 7}}}, - {&grpc_static_metadata_refcounts[87], {{g_bytes + 970, 11}}}, - {&grpc_static_metadata_refcounts[88], {{g_bytes + 981, 6}}}, - {&grpc_static_metadata_refcounts[89], {{g_bytes + 987, 10}}}, - {&grpc_static_metadata_refcounts[90], {{g_bytes + 997, 25}}}, - {&grpc_static_metadata_refcounts[91], {{g_bytes + 1022, 17}}}, - {&grpc_static_metadata_refcounts[92], {{g_bytes + 1039, 4}}}, - {&grpc_static_metadata_refcounts[93], {{g_bytes + 1043, 3}}}, - {&grpc_static_metadata_refcounts[94], {{g_bytes + 1046, 16}}}, - {&grpc_static_metadata_refcounts[95], {{g_bytes + 1062, 1}}}, - {&grpc_static_metadata_refcounts[96], {{g_bytes + 1063, 8}}}, - {&grpc_static_metadata_refcounts[97], {{g_bytes + 1071, 8}}}, - {&grpc_static_metadata_refcounts[98], {{g_bytes + 1079, 16}}}, - {&grpc_static_metadata_refcounts[99], {{g_bytes + 1095, 4}}}, - {&grpc_static_metadata_refcounts[100], {{g_bytes + 1099, 3}}}, - {&grpc_static_metadata_refcounts[101], {{g_bytes + 1102, 11}}}, - {&grpc_static_metadata_refcounts[102], {{g_bytes + 1113, 16}}}, - {&grpc_static_metadata_refcounts[103], {{g_bytes + 1129, 13}}}, - {&grpc_static_metadata_refcounts[104], {{g_bytes + 1142, 12}}}, - {&grpc_static_metadata_refcounts[105], {{g_bytes + 1154, 21}}}, + {&grpc_static_metadata_refcounts[0], {{5, g_bytes + 0}}}, + {&grpc_static_metadata_refcounts[1], {{7, g_bytes + 5}}}, + {&grpc_static_metadata_refcounts[2], {{7, g_bytes + 12}}}, + {&grpc_static_metadata_refcounts[3], {{10, g_bytes + 19}}}, + {&grpc_static_metadata_refcounts[4], {{7, g_bytes + 29}}}, + {&grpc_static_metadata_refcounts[5], {{2, g_bytes + 36}}}, + {&grpc_static_metadata_refcounts[6], {{12, g_bytes + 38}}}, + {&grpc_static_metadata_refcounts[7], {{11, g_bytes + 50}}}, + {&grpc_static_metadata_refcounts[8], {{16, g_bytes + 61}}}, + {&grpc_static_metadata_refcounts[9], {{13, g_bytes + 77}}}, + {&grpc_static_metadata_refcounts[10], {{20, g_bytes + 90}}}, + {&grpc_static_metadata_refcounts[11], {{21, g_bytes + 110}}}, + {&grpc_static_metadata_refcounts[12], {{13, g_bytes + 131}}}, + {&grpc_static_metadata_refcounts[13], {{14, g_bytes + 144}}}, + {&grpc_static_metadata_refcounts[14], {{12, g_bytes + 158}}}, + {&grpc_static_metadata_refcounts[15], {{16, g_bytes + 170}}}, + {&grpc_static_metadata_refcounts[16], {{15, g_bytes + 186}}}, + {&grpc_static_metadata_refcounts[17], {{30, g_bytes + 201}}}, + {&grpc_static_metadata_refcounts[18], {{37, g_bytes + 231}}}, + {&grpc_static_metadata_refcounts[19], {{10, g_bytes + 268}}}, + {&grpc_static_metadata_refcounts[20], {{4, g_bytes + 278}}}, + {&grpc_static_metadata_refcounts[21], {{8, g_bytes + 282}}}, + {&grpc_static_metadata_refcounts[22], {{26, g_bytes + 290}}}, + {&grpc_static_metadata_refcounts[23], {{22, g_bytes + 316}}}, + {&grpc_static_metadata_refcounts[24], {{12, g_bytes + 338}}}, + {&grpc_static_metadata_refcounts[25], {{1, g_bytes + 350}}}, + {&grpc_static_metadata_refcounts[26], {{1, g_bytes + 351}}}, + {&grpc_static_metadata_refcounts[27], {{1, g_bytes + 352}}}, + {&grpc_static_metadata_refcounts[28], {{1, g_bytes + 353}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, + {&grpc_static_metadata_refcounts[30], {{19, g_bytes + 354}}}, + {&grpc_static_metadata_refcounts[31], {{12, g_bytes + 373}}}, + {&grpc_static_metadata_refcounts[32], {{30, g_bytes + 385}}}, + {&grpc_static_metadata_refcounts[33], {{31, g_bytes + 415}}}, + {&grpc_static_metadata_refcounts[34], {{36, g_bytes + 446}}}, + {&grpc_static_metadata_refcounts[35], {{28, g_bytes + 482}}}, + {&grpc_static_metadata_refcounts[36], {{80, g_bytes + 510}}}, + {&grpc_static_metadata_refcounts[37], {{7, g_bytes + 590}}}, + {&grpc_static_metadata_refcounts[38], {{4, g_bytes + 597}}}, + {&grpc_static_metadata_refcounts[39], {{11, g_bytes + 601}}}, + {&grpc_static_metadata_refcounts[40], {{3, g_bytes + 612}}}, + {&grpc_static_metadata_refcounts[41], {{4, g_bytes + 615}}}, + {&grpc_static_metadata_refcounts[42], {{1, g_bytes + 619}}}, + {&grpc_static_metadata_refcounts[43], {{11, g_bytes + 620}}}, + {&grpc_static_metadata_refcounts[44], {{4, g_bytes + 631}}}, + {&grpc_static_metadata_refcounts[45], {{5, g_bytes + 635}}}, + {&grpc_static_metadata_refcounts[46], {{3, g_bytes + 640}}}, + {&grpc_static_metadata_refcounts[47], {{3, g_bytes + 643}}}, + {&grpc_static_metadata_refcounts[48], {{3, g_bytes + 646}}}, + {&grpc_static_metadata_refcounts[49], {{3, g_bytes + 649}}}, + {&grpc_static_metadata_refcounts[50], {{3, g_bytes + 652}}}, + {&grpc_static_metadata_refcounts[51], {{3, g_bytes + 655}}}, + {&grpc_static_metadata_refcounts[52], {{3, g_bytes + 658}}}, + {&grpc_static_metadata_refcounts[53], {{14, g_bytes + 661}}}, + {&grpc_static_metadata_refcounts[54], {{13, g_bytes + 675}}}, + {&grpc_static_metadata_refcounts[55], {{15, g_bytes + 688}}}, + {&grpc_static_metadata_refcounts[56], {{13, g_bytes + 703}}}, + {&grpc_static_metadata_refcounts[57], {{6, g_bytes + 716}}}, + {&grpc_static_metadata_refcounts[58], {{27, g_bytes + 722}}}, + {&grpc_static_metadata_refcounts[59], {{3, g_bytes + 749}}}, + {&grpc_static_metadata_refcounts[60], {{5, g_bytes + 752}}}, + {&grpc_static_metadata_refcounts[61], {{13, g_bytes + 757}}}, + {&grpc_static_metadata_refcounts[62], {{13, g_bytes + 770}}}, + {&grpc_static_metadata_refcounts[63], {{19, g_bytes + 783}}}, + {&grpc_static_metadata_refcounts[64], {{16, g_bytes + 802}}}, + {&grpc_static_metadata_refcounts[65], {{14, g_bytes + 818}}}, + {&grpc_static_metadata_refcounts[66], {{16, g_bytes + 832}}}, + {&grpc_static_metadata_refcounts[67], {{13, g_bytes + 848}}}, + {&grpc_static_metadata_refcounts[68], {{6, g_bytes + 861}}}, + {&grpc_static_metadata_refcounts[69], {{4, g_bytes + 867}}}, + {&grpc_static_metadata_refcounts[70], {{4, g_bytes + 871}}}, + {&grpc_static_metadata_refcounts[71], {{6, g_bytes + 875}}}, + {&grpc_static_metadata_refcounts[72], {{7, g_bytes + 881}}}, + {&grpc_static_metadata_refcounts[73], {{4, g_bytes + 888}}}, + {&grpc_static_metadata_refcounts[74], {{8, g_bytes + 892}}}, + {&grpc_static_metadata_refcounts[75], {{17, g_bytes + 900}}}, + {&grpc_static_metadata_refcounts[76], {{13, g_bytes + 917}}}, + {&grpc_static_metadata_refcounts[77], {{8, g_bytes + 930}}}, + {&grpc_static_metadata_refcounts[78], {{19, g_bytes + 938}}}, + {&grpc_static_metadata_refcounts[79], {{13, g_bytes + 957}}}, + {&grpc_static_metadata_refcounts[80], {{4, g_bytes + 970}}}, + {&grpc_static_metadata_refcounts[81], {{8, g_bytes + 974}}}, + {&grpc_static_metadata_refcounts[82], {{12, g_bytes + 982}}}, + {&grpc_static_metadata_refcounts[83], {{18, g_bytes + 994}}}, + {&grpc_static_metadata_refcounts[84], {{19, g_bytes + 1012}}}, + {&grpc_static_metadata_refcounts[85], {{5, g_bytes + 1031}}}, + {&grpc_static_metadata_refcounts[86], {{7, g_bytes + 1036}}}, + {&grpc_static_metadata_refcounts[87], {{7, g_bytes + 1043}}}, + {&grpc_static_metadata_refcounts[88], {{11, g_bytes + 1050}}}, + {&grpc_static_metadata_refcounts[89], {{6, g_bytes + 1061}}}, + {&grpc_static_metadata_refcounts[90], {{10, g_bytes + 1067}}}, + {&grpc_static_metadata_refcounts[91], {{25, g_bytes + 1077}}}, + {&grpc_static_metadata_refcounts[92], {{17, g_bytes + 1102}}}, + {&grpc_static_metadata_refcounts[93], {{4, g_bytes + 1119}}}, + {&grpc_static_metadata_refcounts[94], {{3, g_bytes + 1123}}}, + {&grpc_static_metadata_refcounts[95], {{16, g_bytes + 1126}}}, + {&grpc_static_metadata_refcounts[96], {{1, g_bytes + 1142}}}, + {&grpc_static_metadata_refcounts[97], {{8, g_bytes + 1143}}}, + {&grpc_static_metadata_refcounts[98], {{8, g_bytes + 1151}}}, + {&grpc_static_metadata_refcounts[99], {{16, g_bytes + 1159}}}, + {&grpc_static_metadata_refcounts[100], {{4, g_bytes + 1175}}}, + {&grpc_static_metadata_refcounts[101], {{3, g_bytes + 1179}}}, + {&grpc_static_metadata_refcounts[102], {{11, g_bytes + 1182}}}, + {&grpc_static_metadata_refcounts[103], {{16, g_bytes + 1193}}}, + {&grpc_static_metadata_refcounts[104], {{13, g_bytes + 1209}}}, + {&grpc_static_metadata_refcounts[105], {{12, g_bytes + 1222}}}, + {&grpc_static_metadata_refcounts[106], {{21, g_bytes + 1234}}}, }; uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT] = { @@ -345,17 +344,17 @@ uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 4, 6, 6, 8, 8, 2, 4, 4}; static const int8_t elems_r[] = { - 16, 11, -8, 0, 3, -42, -81, -43, 0, 6, -8, 0, 0, 0, -7, - -3, -10, 0, 0, 0, -1, -2, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -63, 0, -47, -68, -69, -70, 0, 33, - 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 20, - 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, - 4, 4, 4, 3, 10, 9, 0, 0, 0, 0, 0, 0, -3, 0}; + 15, 10, -8, 0, 2, -42, -81, -43, 0, 6, -8, 0, 0, 0, 2, + -3, -10, 0, 0, 1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -64, 0, -67, -68, -69, -70, 0, + 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, + 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, + 5, 4, 5, 4, 4, 8, 8, 0, 0, 0, 0, 0, 0, -5, 0}; static uint32_t elems_phash(uint32_t i) { - i -= 41; - uint32_t x = i % 104; - uint32_t y = i / 104; + i -= 42; + uint32_t x = i % 105; + uint32_t y = i / 105; uint32_t h = x; if (y < GPR_ARRAY_SIZE(elems_r)) { uint32_t delta = (uint32_t)elems_r[y]; @@ -365,29 +364,29 @@ static uint32_t elems_phash(uint32_t i) { } static const uint16_t elem_keys[] = { - 257, 258, 259, 260, 261, 262, 263, 1096, 1097, 1513, 1725, 145, - 146, 467, 468, 1619, 41, 42, 1733, 990, 991, 767, 768, 1627, - 627, 837, 2043, 2149, 2255, 5541, 5859, 5965, 6071, 6177, 1749, 6283, - 6389, 6495, 6601, 6707, 6813, 6919, 7025, 7131, 7237, 7343, 7449, 7555, - 7661, 5753, 7767, 7873, 7979, 8085, 8191, 8297, 8403, 8509, 8615, 8721, - 8827, 8933, 9039, 9145, 9251, 9357, 9463, 1156, 9569, 523, 9675, 9781, - 206, 1162, 1163, 1164, 1165, 1792, 1582, 1050, 9887, 9993, 1686, 10735, - 1799, 0, 0, 0, 0, 0, 347, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0}; + 260, 261, 262, 263, 264, 265, 266, 1107, 1108, 1741, 147, 148, + 472, 473, 1634, 42, 43, 1527, 1750, 1000, 1001, 774, 775, 1643, + 633, 845, 2062, 2169, 2276, 5700, 5914, 6021, 6128, 6235, 1766, 6342, + 6449, 6556, 6663, 6770, 6877, 6984, 7091, 7198, 7305, 7412, 7519, 7626, + 7733, 7840, 7947, 8054, 8161, 8268, 8375, 8482, 8589, 8696, 8803, 8910, + 9017, 9124, 9231, 9338, 9445, 9552, 9659, 1167, 528, 9766, 9873, 208, + 9980, 1173, 1174, 1175, 1176, 1809, 10087, 1060, 10194, 10943, 1702, 0, + 1816, 0, 0, 1597, 0, 0, 350, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0}; static const uint8_t elem_idxs[] = { - 7, 8, 9, 10, 11, 12, 13, 77, 79, 30, 71, 1, 2, 5, 6, 25, - 3, 4, 84, 66, 65, 62, 63, 73, 67, 61, 57, 37, 74, 14, 17, 18, - 19, 20, 15, 21, 22, 23, 24, 26, 27, 28, 29, 31, 32, 33, 34, 35, - 36, 16, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, - 52, 53, 54, 76, 55, 69, 56, 58, 70, 78, 80, 81, 82, 83, 68, 64, - 59, 60, 72, 75, 85, 255, 255, 255, 255, 255, 0}; + 7, 8, 9, 10, 11, 12, 13, 77, 79, 71, 1, 2, 5, 6, 25, 3, + 4, 30, 84, 66, 65, 62, 63, 73, 67, 61, 57, 37, 74, 14, 16, 17, + 18, 19, 15, 20, 21, 22, 23, 24, 26, 27, 28, 29, 31, 32, 33, 34, + 35, 36, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 76, 69, 55, 56, 70, 58, 78, 80, 81, 82, 83, 59, 64, + 60, 75, 72, 255, 85, 255, 255, 68, 255, 255, 0}; -grpc_mdelem grpc_static_mdelem_for_static_strings(int a, int b) { +grpc_mdelem grpc_static_mdelem_for_static_strings(intptr_t a, intptr_t b) { if (a == -1 || b == -1) return GRPC_MDNULL; - uint32_t k = (uint32_t)(a * 106 + b); + uint32_t k = static_cast(a * 107 + b); uint32_t h = elems_phash(k); return h < GPR_ARRAY_SIZE(elem_keys) && elem_keys[h] == k && elem_idxs[h] != 255 @@ -397,178 +396,178 @@ grpc_mdelem grpc_static_mdelem_for_static_strings(int a, int b) { } grpc_mdelem_data grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT] = { - {{&grpc_static_metadata_refcounts[3], {{g_bytes + 19, 10}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[1], {{g_bytes + 5, 7}}}, - {&grpc_static_metadata_refcounts[39], {{g_bytes + 532, 3}}}}, - {{&grpc_static_metadata_refcounts[1], {{g_bytes + 5, 7}}}, - {&grpc_static_metadata_refcounts[40], {{g_bytes + 535, 4}}}}, - {{&grpc_static_metadata_refcounts[0], {{g_bytes + 0, 5}}}, - {&grpc_static_metadata_refcounts[41], {{g_bytes + 539, 1}}}}, - {{&grpc_static_metadata_refcounts[0], {{g_bytes + 0, 5}}}, - {&grpc_static_metadata_refcounts[42], {{g_bytes + 540, 11}}}}, - {{&grpc_static_metadata_refcounts[4], {{g_bytes + 29, 7}}}, - {&grpc_static_metadata_refcounts[43], {{g_bytes + 551, 4}}}}, - {{&grpc_static_metadata_refcounts[4], {{g_bytes + 29, 7}}}, - {&grpc_static_metadata_refcounts[44], {{g_bytes + 555, 5}}}}, - {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[45], {{g_bytes + 560, 3}}}}, - {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[46], {{g_bytes + 563, 3}}}}, - {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[47], {{g_bytes + 566, 3}}}}, - {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[48], {{g_bytes + 569, 3}}}}, - {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[49], {{g_bytes + 572, 3}}}}, - {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[50], {{g_bytes + 575, 3}}}}, - {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[51], {{g_bytes + 578, 3}}}}, - {{&grpc_static_metadata_refcounts[52], {{g_bytes + 581, 14}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}}, - {&grpc_static_metadata_refcounts[53], {{g_bytes + 595, 13}}}}, - {{&grpc_static_metadata_refcounts[54], {{g_bytes + 608, 15}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[55], {{g_bytes + 623, 13}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[56], {{g_bytes + 636, 6}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[57], {{g_bytes + 642, 27}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[58], {{g_bytes + 669, 3}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[59], {{g_bytes + 672, 5}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[60], {{g_bytes + 677, 13}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[61], {{g_bytes + 690, 13}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[62], {{g_bytes + 703, 19}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[15], {{g_bytes + 170, 16}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[63], {{g_bytes + 722, 16}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[64], {{g_bytes + 738, 14}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[65], {{g_bytes + 752, 16}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[66], {{g_bytes + 768, 13}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[14], {{g_bytes + 158, 12}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[67], {{g_bytes + 781, 6}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[68], {{g_bytes + 787, 4}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[69], {{g_bytes + 791, 4}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[70], {{g_bytes + 795, 6}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[71], {{g_bytes + 801, 7}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[72], {{g_bytes + 808, 4}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[20], {{g_bytes + 278, 4}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[73], {{g_bytes + 812, 8}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[74], {{g_bytes + 820, 17}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[75], {{g_bytes + 837, 13}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[76], {{g_bytes + 850, 8}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[77], {{g_bytes + 858, 19}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[78], {{g_bytes + 877, 13}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[79], {{g_bytes + 890, 4}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[80], {{g_bytes + 894, 8}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[81], {{g_bytes + 902, 12}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[82], {{g_bytes + 914, 18}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[83], {{g_bytes + 932, 19}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[84], {{g_bytes + 951, 5}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[85], {{g_bytes + 956, 7}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[86], {{g_bytes + 963, 7}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[87], {{g_bytes + 970, 11}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[88], {{g_bytes + 981, 6}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[89], {{g_bytes + 987, 10}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[90], {{g_bytes + 997, 25}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[91], {{g_bytes + 1022, 17}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[19], {{g_bytes + 268, 10}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[92], {{g_bytes + 1039, 4}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[93], {{g_bytes + 1043, 3}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[94], {{g_bytes + 1046, 16}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[7], {{g_bytes + 50, 11}}}, - {&grpc_static_metadata_refcounts[95], {{g_bytes + 1062, 1}}}}, - {{&grpc_static_metadata_refcounts[7], {{g_bytes + 50, 11}}}, - {&grpc_static_metadata_refcounts[25], {{g_bytes + 350, 1}}}}, - {{&grpc_static_metadata_refcounts[7], {{g_bytes + 50, 11}}}, - {&grpc_static_metadata_refcounts[26], {{g_bytes + 351, 1}}}}, - {{&grpc_static_metadata_refcounts[9], {{g_bytes + 77, 13}}}, - {&grpc_static_metadata_refcounts[96], {{g_bytes + 1063, 8}}}}, - {{&grpc_static_metadata_refcounts[9], {{g_bytes + 77, 13}}}, - {&grpc_static_metadata_refcounts[37], {{g_bytes + 517, 4}}}}, - {{&grpc_static_metadata_refcounts[9], {{g_bytes + 77, 13}}}, - {&grpc_static_metadata_refcounts[36], {{g_bytes + 510, 7}}}}, - {{&grpc_static_metadata_refcounts[5], {{g_bytes + 36, 2}}}, - {&grpc_static_metadata_refcounts[97], {{g_bytes + 1071, 8}}}}, - {{&grpc_static_metadata_refcounts[14], {{g_bytes + 158, 12}}}, - {&grpc_static_metadata_refcounts[98], {{g_bytes + 1079, 16}}}}, - {{&grpc_static_metadata_refcounts[4], {{g_bytes + 29, 7}}}, - {&grpc_static_metadata_refcounts[99], {{g_bytes + 1095, 4}}}}, - {{&grpc_static_metadata_refcounts[1], {{g_bytes + 5, 7}}}, - {&grpc_static_metadata_refcounts[100], {{g_bytes + 1099, 3}}}}, - {{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[15], {{g_bytes + 170, 16}}}, - {&grpc_static_metadata_refcounts[96], {{g_bytes + 1063, 8}}}}, - {{&grpc_static_metadata_refcounts[15], {{g_bytes + 170, 16}}}, - {&grpc_static_metadata_refcounts[37], {{g_bytes + 517, 4}}}}, - {{&grpc_static_metadata_refcounts[21], {{g_bytes + 282, 8}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[101], {{g_bytes + 1102, 11}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, - {&grpc_static_metadata_refcounts[96], {{g_bytes + 1063, 8}}}}, - {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, - {&grpc_static_metadata_refcounts[36], {{g_bytes + 510, 7}}}}, - {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, - {&grpc_static_metadata_refcounts[102], {{g_bytes + 1113, 16}}}}, - {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, - {&grpc_static_metadata_refcounts[37], {{g_bytes + 517, 4}}}}, - {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, - {&grpc_static_metadata_refcounts[103], {{g_bytes + 1129, 13}}}}, - {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, - {&grpc_static_metadata_refcounts[104], {{g_bytes + 1142, 12}}}}, - {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, - {&grpc_static_metadata_refcounts[105], {{g_bytes + 1154, 21}}}}, - {{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}}, - {&grpc_static_metadata_refcounts[96], {{g_bytes + 1063, 8}}}}, - {{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}}, - {&grpc_static_metadata_refcounts[37], {{g_bytes + 517, 4}}}}, - {{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}}, - {&grpc_static_metadata_refcounts[103], {{g_bytes + 1129, 13}}}}, + {{&grpc_static_metadata_refcounts[3], {{10, g_bytes + 19}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[1], {{7, g_bytes + 5}}}, + {&grpc_static_metadata_refcounts[40], {{3, g_bytes + 612}}}}, + {{&grpc_static_metadata_refcounts[1], {{7, g_bytes + 5}}}, + {&grpc_static_metadata_refcounts[41], {{4, g_bytes + 615}}}}, + {{&grpc_static_metadata_refcounts[0], {{5, g_bytes + 0}}}, + {&grpc_static_metadata_refcounts[42], {{1, g_bytes + 619}}}}, + {{&grpc_static_metadata_refcounts[0], {{5, g_bytes + 0}}}, + {&grpc_static_metadata_refcounts[43], {{11, g_bytes + 620}}}}, + {{&grpc_static_metadata_refcounts[4], {{7, g_bytes + 29}}}, + {&grpc_static_metadata_refcounts[44], {{4, g_bytes + 631}}}}, + {{&grpc_static_metadata_refcounts[4], {{7, g_bytes + 29}}}, + {&grpc_static_metadata_refcounts[45], {{5, g_bytes + 635}}}}, + {{&grpc_static_metadata_refcounts[2], {{7, g_bytes + 12}}}, + {&grpc_static_metadata_refcounts[46], {{3, g_bytes + 640}}}}, + {{&grpc_static_metadata_refcounts[2], {{7, g_bytes + 12}}}, + {&grpc_static_metadata_refcounts[47], {{3, g_bytes + 643}}}}, + {{&grpc_static_metadata_refcounts[2], {{7, g_bytes + 12}}}, + {&grpc_static_metadata_refcounts[48], {{3, g_bytes + 646}}}}, + {{&grpc_static_metadata_refcounts[2], {{7, g_bytes + 12}}}, + {&grpc_static_metadata_refcounts[49], {{3, g_bytes + 649}}}}, + {{&grpc_static_metadata_refcounts[2], {{7, g_bytes + 12}}}, + {&grpc_static_metadata_refcounts[50], {{3, g_bytes + 652}}}}, + {{&grpc_static_metadata_refcounts[2], {{7, g_bytes + 12}}}, + {&grpc_static_metadata_refcounts[51], {{3, g_bytes + 655}}}}, + {{&grpc_static_metadata_refcounts[2], {{7, g_bytes + 12}}}, + {&grpc_static_metadata_refcounts[52], {{3, g_bytes + 658}}}}, + {{&grpc_static_metadata_refcounts[53], {{14, g_bytes + 661}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[16], {{15, g_bytes + 186}}}, + {&grpc_static_metadata_refcounts[54], {{13, g_bytes + 675}}}}, + {{&grpc_static_metadata_refcounts[55], {{15, g_bytes + 688}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[56], {{13, g_bytes + 703}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[57], {{6, g_bytes + 716}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[58], {{27, g_bytes + 722}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[59], {{3, g_bytes + 749}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[60], {{5, g_bytes + 752}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[61], {{13, g_bytes + 757}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[62], {{13, g_bytes + 770}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[63], {{19, g_bytes + 783}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[15], {{16, g_bytes + 170}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[64], {{16, g_bytes + 802}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[65], {{14, g_bytes + 818}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[66], {{16, g_bytes + 832}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[67], {{13, g_bytes + 848}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[14], {{12, g_bytes + 158}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[68], {{6, g_bytes + 861}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[69], {{4, g_bytes + 867}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[70], {{4, g_bytes + 871}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[71], {{6, g_bytes + 875}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[72], {{7, g_bytes + 881}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[73], {{4, g_bytes + 888}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[20], {{4, g_bytes + 278}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[74], {{8, g_bytes + 892}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[75], {{17, g_bytes + 900}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[76], {{13, g_bytes + 917}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[77], {{8, g_bytes + 930}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[78], {{19, g_bytes + 938}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[79], {{13, g_bytes + 957}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[80], {{4, g_bytes + 970}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[81], {{8, g_bytes + 974}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[82], {{12, g_bytes + 982}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[83], {{18, g_bytes + 994}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[84], {{19, g_bytes + 1012}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[85], {{5, g_bytes + 1031}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[86], {{7, g_bytes + 1036}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[87], {{7, g_bytes + 1043}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[88], {{11, g_bytes + 1050}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[89], {{6, g_bytes + 1061}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[90], {{10, g_bytes + 1067}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[91], {{25, g_bytes + 1077}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[92], {{17, g_bytes + 1102}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[19], {{10, g_bytes + 268}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[93], {{4, g_bytes + 1119}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[94], {{3, g_bytes + 1123}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[95], {{16, g_bytes + 1126}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[7], {{11, g_bytes + 50}}}, + {&grpc_static_metadata_refcounts[96], {{1, g_bytes + 1142}}}}, + {{&grpc_static_metadata_refcounts[7], {{11, g_bytes + 50}}}, + {&grpc_static_metadata_refcounts[25], {{1, g_bytes + 350}}}}, + {{&grpc_static_metadata_refcounts[7], {{11, g_bytes + 50}}}, + {&grpc_static_metadata_refcounts[26], {{1, g_bytes + 351}}}}, + {{&grpc_static_metadata_refcounts[9], {{13, g_bytes + 77}}}, + {&grpc_static_metadata_refcounts[97], {{8, g_bytes + 1143}}}}, + {{&grpc_static_metadata_refcounts[9], {{13, g_bytes + 77}}}, + {&grpc_static_metadata_refcounts[38], {{4, g_bytes + 597}}}}, + {{&grpc_static_metadata_refcounts[9], {{13, g_bytes + 77}}}, + {&grpc_static_metadata_refcounts[37], {{7, g_bytes + 590}}}}, + {{&grpc_static_metadata_refcounts[5], {{2, g_bytes + 36}}}, + {&grpc_static_metadata_refcounts[98], {{8, g_bytes + 1151}}}}, + {{&grpc_static_metadata_refcounts[14], {{12, g_bytes + 158}}}, + {&grpc_static_metadata_refcounts[99], {{16, g_bytes + 1159}}}}, + {{&grpc_static_metadata_refcounts[4], {{7, g_bytes + 29}}}, + {&grpc_static_metadata_refcounts[100], {{4, g_bytes + 1175}}}}, + {{&grpc_static_metadata_refcounts[1], {{7, g_bytes + 5}}}, + {&grpc_static_metadata_refcounts[101], {{3, g_bytes + 1179}}}}, + {{&grpc_static_metadata_refcounts[16], {{15, g_bytes + 186}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[15], {{16, g_bytes + 170}}}, + {&grpc_static_metadata_refcounts[97], {{8, g_bytes + 1143}}}}, + {{&grpc_static_metadata_refcounts[15], {{16, g_bytes + 170}}}, + {&grpc_static_metadata_refcounts[38], {{4, g_bytes + 597}}}}, + {{&grpc_static_metadata_refcounts[21], {{8, g_bytes + 282}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[102], {{11, g_bytes + 1182}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[10], {{20, g_bytes + 90}}}, + {&grpc_static_metadata_refcounts[97], {{8, g_bytes + 1143}}}}, + {{&grpc_static_metadata_refcounts[10], {{20, g_bytes + 90}}}, + {&grpc_static_metadata_refcounts[37], {{7, g_bytes + 590}}}}, + {{&grpc_static_metadata_refcounts[10], {{20, g_bytes + 90}}}, + {&grpc_static_metadata_refcounts[103], {{16, g_bytes + 1193}}}}, + {{&grpc_static_metadata_refcounts[10], {{20, g_bytes + 90}}}, + {&grpc_static_metadata_refcounts[38], {{4, g_bytes + 597}}}}, + {{&grpc_static_metadata_refcounts[10], {{20, g_bytes + 90}}}, + {&grpc_static_metadata_refcounts[104], {{13, g_bytes + 1209}}}}, + {{&grpc_static_metadata_refcounts[10], {{20, g_bytes + 90}}}, + {&grpc_static_metadata_refcounts[105], {{12, g_bytes + 1222}}}}, + {{&grpc_static_metadata_refcounts[10], {{20, g_bytes + 90}}}, + {&grpc_static_metadata_refcounts[106], {{21, g_bytes + 1234}}}}, + {{&grpc_static_metadata_refcounts[16], {{15, g_bytes + 186}}}, + {&grpc_static_metadata_refcounts[97], {{8, g_bytes + 1143}}}}, + {{&grpc_static_metadata_refcounts[16], {{15, g_bytes + 186}}}, + {&grpc_static_metadata_refcounts[38], {{4, g_bytes + 597}}}}, + {{&grpc_static_metadata_refcounts[16], {{15, g_bytes + 186}}}, + {&grpc_static_metadata_refcounts[104], {{13, g_bytes + 1209}}}}, }; const uint8_t grpc_static_accept_encoding_metadata[8] = {0, 76, 77, 78, 79, 80, 81, 82}; diff --git a/src/core/lib/transport/static_metadata.h b/src/core/lib/transport/static_metadata.h index 2bb9f728380..a3f23de0953 100644 --- a/src/core/lib/transport/static_metadata.h +++ b/src/core/lib/transport/static_metadata.h @@ -29,9 +29,11 @@ #include +#include + #include "src/core/lib/transport/metadata.h" -#define GRPC_STATIC_MDSTR_COUNT 106 +#define GRPC_STATIC_MDSTR_COUNT 107 extern const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT]; /* ":path" */ #define GRPC_MDSTR_PATH (grpc_static_slice_table[0]) @@ -110,157 +112,161 @@ extern const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT]; /* "/grpc.health.v1.Health/Watch" */ #define GRPC_MDSTR_SLASH_GRPC_DOT_HEALTH_DOT_V1_DOT_HEALTH_SLASH_WATCH \ (grpc_static_slice_table[35]) +/* "/envoy.service.discovery.v2.AggregatedDiscoveryService/StreamAggregatedResources" + */ +#define GRPC_MDSTR_SLASH_ENVOY_DOT_SERVICE_DOT_DISCOVERY_DOT_V2_DOT_AGGREGATEDDISCOVERYSERVICE_SLASH_STREAMAGGREGATEDRESOURCES \ + (grpc_static_slice_table[36]) /* "deflate" */ -#define GRPC_MDSTR_DEFLATE (grpc_static_slice_table[36]) +#define GRPC_MDSTR_DEFLATE (grpc_static_slice_table[37]) /* "gzip" */ -#define GRPC_MDSTR_GZIP (grpc_static_slice_table[37]) +#define GRPC_MDSTR_GZIP (grpc_static_slice_table[38]) /* "stream/gzip" */ -#define GRPC_MDSTR_STREAM_SLASH_GZIP (grpc_static_slice_table[38]) +#define GRPC_MDSTR_STREAM_SLASH_GZIP (grpc_static_slice_table[39]) /* "GET" */ -#define GRPC_MDSTR_GET (grpc_static_slice_table[39]) +#define GRPC_MDSTR_GET (grpc_static_slice_table[40]) /* "POST" */ -#define GRPC_MDSTR_POST (grpc_static_slice_table[40]) +#define GRPC_MDSTR_POST (grpc_static_slice_table[41]) /* "/" */ -#define GRPC_MDSTR_SLASH (grpc_static_slice_table[41]) +#define GRPC_MDSTR_SLASH (grpc_static_slice_table[42]) /* "/index.html" */ -#define GRPC_MDSTR_SLASH_INDEX_DOT_HTML (grpc_static_slice_table[42]) +#define GRPC_MDSTR_SLASH_INDEX_DOT_HTML (grpc_static_slice_table[43]) /* "http" */ -#define GRPC_MDSTR_HTTP (grpc_static_slice_table[43]) +#define GRPC_MDSTR_HTTP (grpc_static_slice_table[44]) /* "https" */ -#define GRPC_MDSTR_HTTPS (grpc_static_slice_table[44]) +#define GRPC_MDSTR_HTTPS (grpc_static_slice_table[45]) /* "200" */ -#define GRPC_MDSTR_200 (grpc_static_slice_table[45]) +#define GRPC_MDSTR_200 (grpc_static_slice_table[46]) /* "204" */ -#define GRPC_MDSTR_204 (grpc_static_slice_table[46]) +#define GRPC_MDSTR_204 (grpc_static_slice_table[47]) /* "206" */ -#define GRPC_MDSTR_206 (grpc_static_slice_table[47]) +#define GRPC_MDSTR_206 (grpc_static_slice_table[48]) /* "304" */ -#define GRPC_MDSTR_304 (grpc_static_slice_table[48]) +#define GRPC_MDSTR_304 (grpc_static_slice_table[49]) /* "400" */ -#define GRPC_MDSTR_400 (grpc_static_slice_table[49]) +#define GRPC_MDSTR_400 (grpc_static_slice_table[50]) /* "404" */ -#define GRPC_MDSTR_404 (grpc_static_slice_table[50]) +#define GRPC_MDSTR_404 (grpc_static_slice_table[51]) /* "500" */ -#define GRPC_MDSTR_500 (grpc_static_slice_table[51]) +#define GRPC_MDSTR_500 (grpc_static_slice_table[52]) /* "accept-charset" */ -#define GRPC_MDSTR_ACCEPT_CHARSET (grpc_static_slice_table[52]) +#define GRPC_MDSTR_ACCEPT_CHARSET (grpc_static_slice_table[53]) /* "gzip, deflate" */ -#define GRPC_MDSTR_GZIP_COMMA_DEFLATE (grpc_static_slice_table[53]) +#define GRPC_MDSTR_GZIP_COMMA_DEFLATE (grpc_static_slice_table[54]) /* "accept-language" */ -#define GRPC_MDSTR_ACCEPT_LANGUAGE (grpc_static_slice_table[54]) +#define GRPC_MDSTR_ACCEPT_LANGUAGE (grpc_static_slice_table[55]) /* "accept-ranges" */ -#define GRPC_MDSTR_ACCEPT_RANGES (grpc_static_slice_table[55]) +#define GRPC_MDSTR_ACCEPT_RANGES (grpc_static_slice_table[56]) /* "accept" */ -#define GRPC_MDSTR_ACCEPT (grpc_static_slice_table[56]) +#define GRPC_MDSTR_ACCEPT (grpc_static_slice_table[57]) /* "access-control-allow-origin" */ -#define GRPC_MDSTR_ACCESS_CONTROL_ALLOW_ORIGIN (grpc_static_slice_table[57]) +#define GRPC_MDSTR_ACCESS_CONTROL_ALLOW_ORIGIN (grpc_static_slice_table[58]) /* "age" */ -#define GRPC_MDSTR_AGE (grpc_static_slice_table[58]) +#define GRPC_MDSTR_AGE (grpc_static_slice_table[59]) /* "allow" */ -#define GRPC_MDSTR_ALLOW (grpc_static_slice_table[59]) +#define GRPC_MDSTR_ALLOW (grpc_static_slice_table[60]) /* "authorization" */ -#define GRPC_MDSTR_AUTHORIZATION (grpc_static_slice_table[60]) +#define GRPC_MDSTR_AUTHORIZATION (grpc_static_slice_table[61]) /* "cache-control" */ -#define GRPC_MDSTR_CACHE_CONTROL (grpc_static_slice_table[61]) +#define GRPC_MDSTR_CACHE_CONTROL (grpc_static_slice_table[62]) /* "content-disposition" */ -#define GRPC_MDSTR_CONTENT_DISPOSITION (grpc_static_slice_table[62]) +#define GRPC_MDSTR_CONTENT_DISPOSITION (grpc_static_slice_table[63]) /* "content-language" */ -#define GRPC_MDSTR_CONTENT_LANGUAGE (grpc_static_slice_table[63]) +#define GRPC_MDSTR_CONTENT_LANGUAGE (grpc_static_slice_table[64]) /* "content-length" */ -#define GRPC_MDSTR_CONTENT_LENGTH (grpc_static_slice_table[64]) +#define GRPC_MDSTR_CONTENT_LENGTH (grpc_static_slice_table[65]) /* "content-location" */ -#define GRPC_MDSTR_CONTENT_LOCATION (grpc_static_slice_table[65]) +#define GRPC_MDSTR_CONTENT_LOCATION (grpc_static_slice_table[66]) /* "content-range" */ -#define GRPC_MDSTR_CONTENT_RANGE (grpc_static_slice_table[66]) +#define GRPC_MDSTR_CONTENT_RANGE (grpc_static_slice_table[67]) /* "cookie" */ -#define GRPC_MDSTR_COOKIE (grpc_static_slice_table[67]) +#define GRPC_MDSTR_COOKIE (grpc_static_slice_table[68]) /* "date" */ -#define GRPC_MDSTR_DATE (grpc_static_slice_table[68]) +#define GRPC_MDSTR_DATE (grpc_static_slice_table[69]) /* "etag" */ -#define GRPC_MDSTR_ETAG (grpc_static_slice_table[69]) +#define GRPC_MDSTR_ETAG (grpc_static_slice_table[70]) /* "expect" */ -#define GRPC_MDSTR_EXPECT (grpc_static_slice_table[70]) +#define GRPC_MDSTR_EXPECT (grpc_static_slice_table[71]) /* "expires" */ -#define GRPC_MDSTR_EXPIRES (grpc_static_slice_table[71]) +#define GRPC_MDSTR_EXPIRES (grpc_static_slice_table[72]) /* "from" */ -#define GRPC_MDSTR_FROM (grpc_static_slice_table[72]) +#define GRPC_MDSTR_FROM (grpc_static_slice_table[73]) /* "if-match" */ -#define GRPC_MDSTR_IF_MATCH (grpc_static_slice_table[73]) +#define GRPC_MDSTR_IF_MATCH (grpc_static_slice_table[74]) /* "if-modified-since" */ -#define GRPC_MDSTR_IF_MODIFIED_SINCE (grpc_static_slice_table[74]) +#define GRPC_MDSTR_IF_MODIFIED_SINCE (grpc_static_slice_table[75]) /* "if-none-match" */ -#define GRPC_MDSTR_IF_NONE_MATCH (grpc_static_slice_table[75]) +#define GRPC_MDSTR_IF_NONE_MATCH (grpc_static_slice_table[76]) /* "if-range" */ -#define GRPC_MDSTR_IF_RANGE (grpc_static_slice_table[76]) +#define GRPC_MDSTR_IF_RANGE (grpc_static_slice_table[77]) /* "if-unmodified-since" */ -#define GRPC_MDSTR_IF_UNMODIFIED_SINCE (grpc_static_slice_table[77]) +#define GRPC_MDSTR_IF_UNMODIFIED_SINCE (grpc_static_slice_table[78]) /* "last-modified" */ -#define GRPC_MDSTR_LAST_MODIFIED (grpc_static_slice_table[78]) +#define GRPC_MDSTR_LAST_MODIFIED (grpc_static_slice_table[79]) /* "link" */ -#define GRPC_MDSTR_LINK (grpc_static_slice_table[79]) +#define GRPC_MDSTR_LINK (grpc_static_slice_table[80]) /* "location" */ -#define GRPC_MDSTR_LOCATION (grpc_static_slice_table[80]) +#define GRPC_MDSTR_LOCATION (grpc_static_slice_table[81]) /* "max-forwards" */ -#define GRPC_MDSTR_MAX_FORWARDS (grpc_static_slice_table[81]) +#define GRPC_MDSTR_MAX_FORWARDS (grpc_static_slice_table[82]) /* "proxy-authenticate" */ -#define GRPC_MDSTR_PROXY_AUTHENTICATE (grpc_static_slice_table[82]) +#define GRPC_MDSTR_PROXY_AUTHENTICATE (grpc_static_slice_table[83]) /* "proxy-authorization" */ -#define GRPC_MDSTR_PROXY_AUTHORIZATION (grpc_static_slice_table[83]) +#define GRPC_MDSTR_PROXY_AUTHORIZATION (grpc_static_slice_table[84]) /* "range" */ -#define GRPC_MDSTR_RANGE (grpc_static_slice_table[84]) +#define GRPC_MDSTR_RANGE (grpc_static_slice_table[85]) /* "referer" */ -#define GRPC_MDSTR_REFERER (grpc_static_slice_table[85]) +#define GRPC_MDSTR_REFERER (grpc_static_slice_table[86]) /* "refresh" */ -#define GRPC_MDSTR_REFRESH (grpc_static_slice_table[86]) +#define GRPC_MDSTR_REFRESH (grpc_static_slice_table[87]) /* "retry-after" */ -#define GRPC_MDSTR_RETRY_AFTER (grpc_static_slice_table[87]) +#define GRPC_MDSTR_RETRY_AFTER (grpc_static_slice_table[88]) /* "server" */ -#define GRPC_MDSTR_SERVER (grpc_static_slice_table[88]) +#define GRPC_MDSTR_SERVER (grpc_static_slice_table[89]) /* "set-cookie" */ -#define GRPC_MDSTR_SET_COOKIE (grpc_static_slice_table[89]) +#define GRPC_MDSTR_SET_COOKIE (grpc_static_slice_table[90]) /* "strict-transport-security" */ -#define GRPC_MDSTR_STRICT_TRANSPORT_SECURITY (grpc_static_slice_table[90]) +#define GRPC_MDSTR_STRICT_TRANSPORT_SECURITY (grpc_static_slice_table[91]) /* "transfer-encoding" */ -#define GRPC_MDSTR_TRANSFER_ENCODING (grpc_static_slice_table[91]) +#define GRPC_MDSTR_TRANSFER_ENCODING (grpc_static_slice_table[92]) /* "vary" */ -#define GRPC_MDSTR_VARY (grpc_static_slice_table[92]) +#define GRPC_MDSTR_VARY (grpc_static_slice_table[93]) /* "via" */ -#define GRPC_MDSTR_VIA (grpc_static_slice_table[93]) +#define GRPC_MDSTR_VIA (grpc_static_slice_table[94]) /* "www-authenticate" */ -#define GRPC_MDSTR_WWW_AUTHENTICATE (grpc_static_slice_table[94]) +#define GRPC_MDSTR_WWW_AUTHENTICATE (grpc_static_slice_table[95]) /* "0" */ -#define GRPC_MDSTR_0 (grpc_static_slice_table[95]) +#define GRPC_MDSTR_0 (grpc_static_slice_table[96]) /* "identity" */ -#define GRPC_MDSTR_IDENTITY (grpc_static_slice_table[96]) +#define GRPC_MDSTR_IDENTITY (grpc_static_slice_table[97]) /* "trailers" */ -#define GRPC_MDSTR_TRAILERS (grpc_static_slice_table[97]) +#define GRPC_MDSTR_TRAILERS (grpc_static_slice_table[98]) /* "application/grpc" */ -#define GRPC_MDSTR_APPLICATION_SLASH_GRPC (grpc_static_slice_table[98]) +#define GRPC_MDSTR_APPLICATION_SLASH_GRPC (grpc_static_slice_table[99]) /* "grpc" */ -#define GRPC_MDSTR_GRPC (grpc_static_slice_table[99]) +#define GRPC_MDSTR_GRPC (grpc_static_slice_table[100]) /* "PUT" */ -#define GRPC_MDSTR_PUT (grpc_static_slice_table[100]) +#define GRPC_MDSTR_PUT (grpc_static_slice_table[101]) /* "lb-cost-bin" */ -#define GRPC_MDSTR_LB_COST_BIN (grpc_static_slice_table[101]) +#define GRPC_MDSTR_LB_COST_BIN (grpc_static_slice_table[102]) /* "identity,deflate" */ -#define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE (grpc_static_slice_table[102]) +#define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE (grpc_static_slice_table[103]) /* "identity,gzip" */ -#define GRPC_MDSTR_IDENTITY_COMMA_GZIP (grpc_static_slice_table[103]) +#define GRPC_MDSTR_IDENTITY_COMMA_GZIP (grpc_static_slice_table[104]) /* "deflate,gzip" */ -#define GRPC_MDSTR_DEFLATE_COMMA_GZIP (grpc_static_slice_table[104]) +#define GRPC_MDSTR_DEFLATE_COMMA_GZIP (grpc_static_slice_table[105]) /* "identity,deflate,gzip" */ #define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE_COMMA_GZIP \ - (grpc_static_slice_table[105]) + (grpc_static_slice_table[106]) -extern const grpc_slice_refcount_vtable grpc_static_metadata_vtable; extern grpc_slice_refcount grpc_static_metadata_refcounts[GRPC_STATIC_MDSTR_COUNT]; #define GRPC_IS_STATIC_METADATA_STRING(slice) \ ((slice).refcount != NULL && \ - (slice).refcount->vtable == &grpc_static_metadata_vtable) + (slice).refcount->GetType() == grpc_slice_refcount::Type::STATIC) #define GRPC_STATIC_METADATA_INDEX(static_slice) \ - ((int)((static_slice).refcount - grpc_static_metadata_refcounts)) + (static_cast( \ + ((static_slice).refcount - grpc_static_metadata_refcounts))) #define GRPC_STATIC_MDELEM_COUNT 86 extern grpc_mdelem_data grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT]; @@ -524,7 +530,7 @@ extern uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT]; #define GRPC_MDELEM_ACCEPT_ENCODING_IDENTITY_COMMA_GZIP \ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[85], GRPC_MDELEM_STORAGE_STATIC)) -grpc_mdelem grpc_static_mdelem_for_static_strings(int a, int b); +grpc_mdelem grpc_static_mdelem_for_static_strings(intptr_t a, intptr_t b); typedef enum { GRPC_BATCH_PATH, GRPC_BATCH_METHOD, @@ -583,11 +589,11 @@ typedef union { } named; } grpc_metadata_batch_callouts; -#define GRPC_BATCH_INDEX_OF(slice) \ - (GRPC_IS_STATIC_METADATA_STRING((slice)) \ - ? (grpc_metadata_batch_callouts_index)GPR_CLAMP( \ - GRPC_STATIC_METADATA_INDEX((slice)), 0, \ - GRPC_BATCH_CALLOUTS_COUNT) \ +#define GRPC_BATCH_INDEX_OF(slice) \ + (GRPC_IS_STATIC_METADATA_STRING((slice)) \ + ? static_cast( \ + GPR_CLAMP(GRPC_STATIC_METADATA_INDEX((slice)), 0, \ + static_cast(GRPC_BATCH_CALLOUTS_COUNT))) \ : GRPC_BATCH_CALLOUTS_COUNT) extern const uint8_t grpc_static_accept_encoding_metadata[8]; diff --git a/src/core/lib/transport/status_metadata.cc b/src/core/lib/transport/status_metadata.cc index f896053e4da..8ef96821c3d 100644 --- a/src/core/lib/transport/status_metadata.cc +++ b/src/core/lib/transport/status_metadata.cc @@ -31,13 +31,13 @@ static void destroy_status(void* ignored) {} grpc_status_code grpc_get_status_code_from_metadata(grpc_mdelem md) { - if (grpc_mdelem_eq(md, GRPC_MDELEM_GRPC_STATUS_0)) { + if (grpc_mdelem_static_value_eq(md, GRPC_MDELEM_GRPC_STATUS_0)) { return GRPC_STATUS_OK; } - if (grpc_mdelem_eq(md, GRPC_MDELEM_GRPC_STATUS_1)) { + if (grpc_mdelem_static_value_eq(md, GRPC_MDELEM_GRPC_STATUS_1)) { return GRPC_STATUS_CANCELLED; } - if (grpc_mdelem_eq(md, GRPC_MDELEM_GRPC_STATUS_2)) { + if (grpc_mdelem_static_value_eq(md, GRPC_MDELEM_GRPC_STATUS_2)) { return GRPC_STATUS_UNKNOWN; } void* user_data = grpc_mdelem_get_user_data(md, destroy_status); diff --git a/src/core/lib/transport/timeout_encoding.cc b/src/core/lib/transport/timeout_encoding.cc index c37249920bd..fe22c15fa6d 100644 --- a/src/core/lib/transport/timeout_encoding.cc +++ b/src/core/lib/transport/timeout_encoding.cc @@ -89,7 +89,7 @@ static int is_all_whitespace(const char* p, const char* end) { return p == end; } -int grpc_http2_decode_timeout(grpc_slice text, grpc_millis* timeout) { +int grpc_http2_decode_timeout(const grpc_slice& text, grpc_millis* timeout) { grpc_millis x = 0; const uint8_t* p = GRPC_SLICE_START_PTR(text); const uint8_t* end = GRPC_SLICE_END_PTR(text); diff --git a/src/core/lib/transport/timeout_encoding.h b/src/core/lib/transport/timeout_encoding.h index 8505e32ff09..cc0d37452fd 100644 --- a/src/core/lib/transport/timeout_encoding.h +++ b/src/core/lib/transport/timeout_encoding.h @@ -32,6 +32,6 @@ /* Encode/decode timeouts to the GRPC over HTTP/2 format; encoding may round up arbitrarily */ void grpc_http2_encode_timeout(grpc_millis timeout, char* buffer); -int grpc_http2_decode_timeout(grpc_slice text, grpc_millis* timeout); +int grpc_http2_decode_timeout(const grpc_slice& text, grpc_millis* timeout); #endif /* GRPC_CORE_LIB_TRANSPORT_TIMEOUT_ENCODING_H */ diff --git a/src/core/lib/transport/transport.cc b/src/core/lib/transport/transport.cc index cbdb77c8441..29c1e561891 100644 --- a/src/core/lib/transport/transport.cc +++ b/src/core/lib/transport/transport.cc @@ -27,8 +27,11 @@ #include #include +#include "src/core/lib/gpr/alloc.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/memory.h" #include "src/core/lib/iomgr/executor.h" +#include "src/core/lib/iomgr/iomgr.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/slice/slice_string_helpers.h" #include "src/core/lib/transport/transport_impl.h" @@ -36,71 +39,39 @@ grpc_core::DebugOnlyTraceFlag grpc_trace_stream_refcount(false, "stream_refcount"); -#ifndef NDEBUG -void grpc_stream_ref(grpc_stream_refcount* refcount, const char* reason) { - if (grpc_trace_stream_refcount.enabled()) { - gpr_atm val = gpr_atm_no_barrier_load(&refcount->refs.count); - gpr_log(GPR_DEBUG, "%s %p:%p REF %" PRIdPTR "->%" PRIdPTR " %s", - refcount->object_type, refcount, refcount->destroy.cb_arg, val, - val + 1, reason); +void grpc_stream_destroy(grpc_stream_refcount* refcount) { + if (!grpc_iomgr_is_any_background_poller_thread() && + (grpc_core::ExecCtx::Get()->flags() & + GRPC_EXEC_CTX_FLAG_THREAD_RESOURCE_LOOP)) { + /* Ick. + The thread we're running on MAY be owned (indirectly) by a call-stack. + If that's the case, destroying the call-stack MAY try to destroy the + thread, which is a tangled mess that we just don't want to ever have to + cope with. + Throw this over to the executor (on a core-owned thread) and process it + there. */ + refcount->destroy.scheduler = + grpc_core::Executor::Scheduler(grpc_core::ExecutorJobType::SHORT); } -#else -void grpc_stream_ref(grpc_stream_refcount* refcount) { -#endif - gpr_ref_non_zero(&refcount->refs); + GRPC_CLOSURE_SCHED(&refcount->destroy, GRPC_ERROR_NONE); } -#ifndef NDEBUG -void grpc_stream_unref(grpc_stream_refcount* refcount, const char* reason) { - if (grpc_trace_stream_refcount.enabled()) { - gpr_atm val = gpr_atm_no_barrier_load(&refcount->refs.count); - gpr_log(GPR_DEBUG, "%s %p:%p UNREF %" PRIdPTR "->%" PRIdPTR " %s", - refcount->object_type, refcount, refcount->destroy.cb_arg, val, - val - 1, reason); - } -#else -void grpc_stream_unref(grpc_stream_refcount* refcount) { -#endif - if (gpr_unref(&refcount->refs)) { - if (grpc_core::ExecCtx::Get()->flags() & - GRPC_EXEC_CTX_FLAG_THREAD_RESOURCE_LOOP) { - /* Ick. - The thread we're running on MAY be owned (indirectly) by a call-stack. - If that's the case, destroying the call-stack MAY try to destroy the - thread, which is a tangled mess that we just don't want to ever have to - cope with. - Throw this over to the executor (on a core-owned thread) and process it - there. */ - refcount->destroy.scheduler = - grpc_executor_scheduler(GRPC_EXECUTOR_SHORT); - } - GRPC_CLOSURE_SCHED(&refcount->destroy, GRPC_ERROR_NONE); - } +void slice_stream_destroy(void* arg) { + grpc_stream_destroy(static_cast(arg)); } #define STREAM_REF_FROM_SLICE_REF(p) \ ((grpc_stream_refcount*)(((uint8_t*)p) - \ offsetof(grpc_stream_refcount, slice_refcount))) -static void slice_stream_ref(void* p) { -#ifndef NDEBUG - grpc_stream_ref(STREAM_REF_FROM_SLICE_REF(p), "slice"); -#else - grpc_stream_ref(STREAM_REF_FROM_SLICE_REF(p)); -#endif -} - -static void slice_stream_unref(void* p) { -#ifndef NDEBUG - grpc_stream_unref(STREAM_REF_FROM_SLICE_REF(p), "slice"); -#else - grpc_stream_unref(STREAM_REF_FROM_SLICE_REF(p)); -#endif -} - grpc_slice grpc_slice_from_stream_owned_buffer(grpc_stream_refcount* refcount, void* buffer, size_t length) { - slice_stream_ref(&refcount->slice_refcount); +#ifndef NDEBUG + grpc_stream_ref(STREAM_REF_FROM_SLICE_REF(&refcount->slice_refcount), + "slice"); +#else + grpc_stream_ref(STREAM_REF_FROM_SLICE_REF(&refcount->slice_refcount)); +#endif grpc_slice res; res.refcount = &refcount->slice_refcount; res.data.refcounted.bytes = static_cast(buffer); @@ -108,13 +79,6 @@ grpc_slice grpc_slice_from_stream_owned_buffer(grpc_stream_refcount* refcount, return res; } -static const grpc_slice_refcount_vtable stream_ref_slice_vtable = { - slice_stream_ref, /* ref */ - slice_stream_unref, /* unref */ - grpc_slice_default_eq_impl, /* eq */ - grpc_slice_default_hash_impl /* hash */ -}; - #ifndef NDEBUG void grpc_stream_ref_init(grpc_stream_refcount* refcount, int initial_refs, grpc_iomgr_cb_func cb, void* cb_arg, @@ -124,10 +88,12 @@ void grpc_stream_ref_init(grpc_stream_refcount* refcount, int initial_refs, void grpc_stream_ref_init(grpc_stream_refcount* refcount, int initial_refs, grpc_iomgr_cb_func cb, void* cb_arg) { #endif - gpr_ref_init(&refcount->refs, initial_refs); GRPC_CLOSURE_INIT(&refcount->destroy, cb, cb_arg, grpc_schedule_on_exec_ctx); - refcount->slice_refcount.vtable = &stream_ref_slice_vtable; - refcount->slice_refcount.sub_refcount = &refcount->slice_refcount; + + new (&refcount->refs) grpc_core::RefCount(); + new (&refcount->slice_refcount) grpc_slice_refcount( + grpc_slice_refcount::Type::REGULAR, &refcount->refs, slice_stream_destroy, + refcount, &refcount->slice_refcount); } static void move64(uint64_t* from, uint64_t* to) { @@ -149,7 +115,7 @@ void grpc_transport_move_stats(grpc_transport_stream_stats* from, } size_t grpc_transport_stream_size(grpc_transport* transport) { - return transport->vtable->sizeof_stream; + return GPR_ROUND_UP_TO_ALIGNMENT_SIZE(transport->vtable->sizeof_stream); } void grpc_transport_destroy(grpc_transport* transport) { @@ -158,7 +124,8 @@ void grpc_transport_destroy(grpc_transport* transport) { int grpc_transport_init_stream(grpc_transport* transport, grpc_stream* stream, grpc_stream_refcount* refcount, - const void* server_data, gpr_arena* arena) { + const void* server_data, + grpc_core::Arena* arena) { return transport->vtable->init_stream(transport, stream, refcount, server_data, arena); } @@ -208,7 +175,7 @@ grpc_endpoint* grpc_transport_get_endpoint(grpc_transport* transport) { // it's grpc_transport_stream_op_batch_finish_with_failure void grpc_transport_stream_op_batch_finish_with_failure( grpc_transport_stream_op_batch* batch, grpc_error* error, - grpc_call_combiner* call_combiner) { + grpc_core::CallCombiner* call_combiner) { if (batch->send_message) { batch->payload->send_message.send_message.reset(); } @@ -240,25 +207,26 @@ void grpc_transport_stream_op_batch_finish_with_failure( GRPC_ERROR_UNREF(error); } -typedef struct { +struct made_transport_op { grpc_closure outer_on_complete; - grpc_closure* inner_on_complete; + grpc_closure* inner_on_complete = nullptr; grpc_transport_op op; -} made_transport_op; + made_transport_op() { + memset(&outer_on_complete, 0, sizeof(outer_on_complete)); + } +}; static void destroy_made_transport_op(void* arg, grpc_error* error) { made_transport_op* op = static_cast(arg); GRPC_CLOSURE_SCHED(op->inner_on_complete, GRPC_ERROR_REF(error)); - gpr_free(op); + grpc_core::Delete(op); } grpc_transport_op* grpc_make_transport_op(grpc_closure* on_complete) { - made_transport_op* op = - static_cast(gpr_malloc(sizeof(*op))); + made_transport_op* op = grpc_core::New(); GRPC_CLOSURE_INIT(&op->outer_on_complete, destroy_made_transport_op, op, grpc_schedule_on_exec_ctx); op->inner_on_complete = on_complete; - memset(&op->op, 0, sizeof(op->op)); op->op.on_consumed = &op->outer_on_complete; return &op->op; } diff --git a/src/core/lib/transport/transport.h b/src/core/lib/transport/transport.h index edfa7030d13..a6a6e904f08 100644 --- a/src/core/lib/transport/transport.h +++ b/src/core/lib/transport/transport.h @@ -24,12 +24,13 @@ #include #include "src/core/lib/channel/context.h" -#include "src/core/lib/gpr/arena.h" +#include "src/core/lib/gprpp/arena.h" #include "src/core/lib/iomgr/call_combiner.h" #include "src/core/lib/iomgr/endpoint.h" #include "src/core/lib/iomgr/polling_entity.h" #include "src/core/lib/iomgr/pollset.h" #include "src/core/lib/iomgr/pollset_set.h" +#include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/transport/byte_stream.h" #include "src/core/lib/transport/metadata_batch.h" @@ -51,7 +52,7 @@ typedef struct grpc_stream grpc_stream; extern grpc_core::DebugOnlyTraceFlag grpc_trace_stream_refcount; typedef struct grpc_stream_refcount { - gpr_refcount refs; + grpc_core::RefCount refs; grpc_closure destroy; #ifndef NDEBUG const char* object_type; @@ -63,19 +64,45 @@ typedef struct grpc_stream_refcount { void grpc_stream_ref_init(grpc_stream_refcount* refcount, int initial_refs, grpc_iomgr_cb_func cb, void* cb_arg, const char* object_type); -void grpc_stream_ref(grpc_stream_refcount* refcount, const char* reason); -void grpc_stream_unref(grpc_stream_refcount* refcount, const char* reason); #define GRPC_STREAM_REF_INIT(rc, ir, cb, cb_arg, objtype) \ grpc_stream_ref_init(rc, ir, cb, cb_arg, objtype) #else void grpc_stream_ref_init(grpc_stream_refcount* refcount, int initial_refs, grpc_iomgr_cb_func cb, void* cb_arg); -void grpc_stream_ref(grpc_stream_refcount* refcount); -void grpc_stream_unref(grpc_stream_refcount* refcount); #define GRPC_STREAM_REF_INIT(rc, ir, cb, cb_arg, objtype) \ grpc_stream_ref_init(rc, ir, cb, cb_arg) #endif +#ifndef NDEBUG +inline void grpc_stream_ref(grpc_stream_refcount* refcount, + const char* reason) { + if (grpc_trace_stream_refcount.enabled()) { + gpr_log(GPR_DEBUG, "%s %p:%p REF %s", refcount->object_type, refcount, + refcount->destroy.cb_arg, reason); + } +#else +inline void grpc_stream_ref(grpc_stream_refcount* refcount) { +#endif + refcount->refs.RefNonZero(); +} + +void grpc_stream_destroy(grpc_stream_refcount* refcount); + +#ifndef NDEBUG +inline void grpc_stream_unref(grpc_stream_refcount* refcount, + const char* reason) { + if (grpc_trace_stream_refcount.enabled()) { + gpr_log(GPR_DEBUG, "%s %p:%p UNREF %s", refcount->object_type, refcount, + refcount->destroy.cb_arg, reason); + } +#else +inline void grpc_stream_unref(grpc_stream_refcount* refcount) { +#endif + if (GPR_UNLIKELY(refcount->refs.Unref())) { + grpc_stream_destroy(refcount); + } +} + /* Wrap a buffer that is owned by some stream object into a slice that shares the same refcount */ grpc_slice grpc_slice_from_stream_owned_buffer(grpc_stream_refcount* refcount, @@ -111,10 +138,11 @@ void grpc_transport_move_stats(grpc_transport_stream_stats* from, // currently handling the batch). Once a filter or transport passes control // of the batch to the next handler, it cannot depend on the contents of // this struct anymore, because the next handler may reuse it. -typedef struct { - void* extra_arg; +struct grpc_handler_private_op_data { + void* extra_arg = nullptr; grpc_closure closure; -} grpc_handler_private_op_data; + grpc_handler_private_op_data() { memset(&closure, 0, sizeof(closure)); } +}; typedef struct grpc_transport_stream_op_batch_payload grpc_transport_stream_op_batch_payload; @@ -129,7 +157,8 @@ struct grpc_transport_stream_op_batch { recv_initial_metadata(false), recv_message(false), recv_trailing_metadata(false), - cancel_stream(false) {} + cancel_stream(false), + is_traced(false) {} /** Should be scheduled when all of the non-recv operations in the batch are complete. @@ -167,6 +196,9 @@ struct grpc_transport_stream_op_batch { /** Cancel this stream with the provided error */ bool cancel_stream : 1; + /** Is this stream traced */ + bool is_traced : 1; + /*************************************************************************** * remaining fields are initialized and used at the discretion of the * current handler of the op */ @@ -268,40 +300,40 @@ struct grpc_transport_stream_op_batch_payload { /** Transport op: a set of operations to perform on a transport as a whole */ typedef struct grpc_transport_op { /** Called when processing of this op is done. */ - grpc_closure* on_consumed; + grpc_closure* on_consumed = nullptr; /** connectivity monitoring - set connectivity_state to NULL to unsubscribe */ - grpc_closure* on_connectivity_state_change; - grpc_connectivity_state* connectivity_state; + grpc_closure* on_connectivity_state_change = nullptr; + grpc_connectivity_state* connectivity_state = nullptr; /** should the transport be disconnected * Error contract: the transport that gets this op must cause * disconnect_with_error to be unref'ed after processing it */ - grpc_error* disconnect_with_error; + grpc_error* disconnect_with_error = nullptr; /** what should the goaway contain? * Error contract: the transport that gets this op must cause * goaway_error to be unref'ed after processing it */ - grpc_error* goaway_error; + grpc_error* goaway_error = nullptr; /** set the callback for accepting new streams; this is a permanent callback, unlike the other one-shot closures. If true, the callback is set to set_accept_stream_fn, with its user_data argument set to set_accept_stream_user_data */ - bool set_accept_stream; + bool set_accept_stream = false; void (*set_accept_stream_fn)(void* user_data, grpc_transport* transport, - const void* server_data); - void* set_accept_stream_user_data; + const void* server_data) = nullptr; + void* set_accept_stream_user_data = nullptr; /** add this transport to a pollset */ - grpc_pollset* bind_pollset; + grpc_pollset* bind_pollset = nullptr; /** add this transport to a pollset_set */ - grpc_pollset_set* bind_pollset_set; + grpc_pollset_set* bind_pollset_set = nullptr; /** send a ping, if either on_initiate or on_ack is not NULL */ struct { /** Ping may be delayed by the transport, on_initiate callback will be called when the ping is actually being sent. */ - grpc_closure* on_initiate; + grpc_closure* on_initiate = nullptr; /** Called when the ping ack is received */ - grpc_closure* on_ack; + grpc_closure* on_ack = nullptr; } send_ping; // If true, will reset the channel's connection backoff. - bool reset_connect_backoff; + bool reset_connect_backoff = false; /*************************************************************************** * remaining fields are initialized and used at the discretion of the @@ -326,7 +358,8 @@ size_t grpc_transport_stream_size(grpc_transport* transport); supplied from the accept_stream callback function */ int grpc_transport_init_stream(grpc_transport* transport, grpc_stream* stream, grpc_stream_refcount* refcount, - const void* server_data, gpr_arena* arena); + const void* server_data, + grpc_core::Arena* arena); void grpc_transport_set_pops(grpc_transport* transport, grpc_stream* stream, grpc_polling_entity* pollent); @@ -347,7 +380,7 @@ void grpc_transport_destroy_stream(grpc_transport* transport, void grpc_transport_stream_op_batch_finish_with_failure( grpc_transport_stream_op_batch* op, grpc_error* error, - grpc_call_combiner* call_combiner); + grpc_core::CallCombiner* call_combiner); char* grpc_transport_stream_op_batch_string(grpc_transport_stream_op_batch* op); char* grpc_transport_op_string(grpc_transport_op* op); diff --git a/src/core/lib/transport/transport_impl.h b/src/core/lib/transport/transport_impl.h index ba5e05df0af..526cc1b1bac 100644 --- a/src/core/lib/transport/transport_impl.h +++ b/src/core/lib/transport/transport_impl.h @@ -34,7 +34,7 @@ typedef struct grpc_transport_vtable { /* implementation of grpc_transport_init_stream */ int (*init_stream)(grpc_transport* self, grpc_stream* stream, grpc_stream_refcount* refcount, const void* server_data, - gpr_arena* arena); + grpc_core::Arena* arena); /* implementation of grpc_transport_set_pollset */ void (*set_pollset)(grpc_transport* self, grpc_stream* stream, diff --git a/src/core/tsi/alts/handshaker/alts_handshaker_client.cc b/src/core/tsi/alts/handshaker/alts_handshaker_client.cc index 1de6264183a..464de9e00d0 100644 --- a/src/core/tsi/alts/handshaker/alts_handshaker_client.cc +++ b/src/core/tsi/alts/handshaker/alts_handshaker_client.cc @@ -116,12 +116,13 @@ void alts_handshaker_client_handle_response(alts_handshaker_client* c, "cb is nullptr in alts_tsi_handshaker_handle_response()"); return; } - if (handshaker == nullptr || recv_buffer == nullptr) { + if (handshaker == nullptr) { gpr_log(GPR_ERROR, - "Invalid arguments to alts_tsi_handshaker_handle_response()"); + "handshaker is nullptr in alts_tsi_handshaker_handle_response()"); cb(TSI_INTERNAL_ERROR, user_data, nullptr, 0, nullptr); return; } + /* TSI handshake has been shutdown. */ if (alts_tsi_handshaker_has_shutdown(handshaker)) { gpr_log(GPR_ERROR, "TSI handshake shutdown"); cb(TSI_HANDSHAKE_SHUTDOWN, user_data, nullptr, 0, nullptr); @@ -133,6 +134,12 @@ void alts_handshaker_client_handle_response(alts_handshaker_client* c, cb(TSI_INTERNAL_ERROR, user_data, nullptr, 0, nullptr); return; } + if (recv_buffer == nullptr) { + gpr_log(GPR_ERROR, + "recv_buffer is nullptr in alts_tsi_handshaker_handle_response()"); + cb(TSI_INTERNAL_ERROR, user_data, nullptr, 0, nullptr); + return; + } grpc_gcp_handshaker_resp* resp = alts_tsi_utils_deserialize_response(recv_buffer); grpc_byte_buffer_destroy(client->recv_buffer); @@ -356,7 +363,7 @@ static tsi_result handshaker_client_next(alts_handshaker_client* c, alts_grpc_handshaker_client* client = reinterpret_cast(c); grpc_slice_unref_internal(client->recv_bytes); - client->recv_bytes = grpc_slice_ref(*bytes_received); + client->recv_bytes = grpc_slice_ref_internal(*bytes_received); grpc_byte_buffer* buffer = get_serialized_next(bytes_received); if (buffer == nullptr) { gpr_log(GPR_ERROR, "get_serialized_next() failed"); @@ -399,7 +406,7 @@ static const alts_handshaker_client_vtable vtable = { alts_handshaker_client* alts_grpc_handshaker_client_create( alts_tsi_handshaker* handshaker, grpc_channel* channel, const char* handshaker_service_url, grpc_pollset_set* interested_parties, - grpc_alts_credentials_options* options, grpc_slice target_name, + grpc_alts_credentials_options* options, const grpc_slice& target_name, grpc_iomgr_cb_func grpc_cb, tsi_handshaker_on_next_done_cb cb, void* user_data, alts_handshaker_client_vtable* vtable_for_testing, bool is_client) { @@ -480,7 +487,7 @@ void alts_handshaker_client_set_recv_bytes_for_testing( GPR_ASSERT(c != nullptr); alts_grpc_handshaker_client* client = reinterpret_cast(c); - client->recv_bytes = grpc_slice_ref(*recv_bytes); + client->recv_bytes = grpc_slice_ref_internal(*recv_bytes); } void alts_handshaker_client_set_fields_for_testing( diff --git a/src/core/tsi/alts/handshaker/alts_handshaker_client.h b/src/core/tsi/alts/handshaker/alts_handshaker_client.h index 4b489875f3c..319a23c88c7 100644 --- a/src/core/tsi/alts/handshaker/alts_handshaker_client.h +++ b/src/core/tsi/alts/handshaker/alts_handshaker_client.h @@ -138,7 +138,7 @@ void alts_handshaker_client_destroy(alts_handshaker_client* client); alts_handshaker_client* alts_grpc_handshaker_client_create( alts_tsi_handshaker* handshaker, grpc_channel* channel, const char* handshaker_service_url, grpc_pollset_set* interested_parties, - grpc_alts_credentials_options* options, grpc_slice target_name, + grpc_alts_credentials_options* options, const grpc_slice& target_name, grpc_iomgr_cb_func grpc_cb, tsi_handshaker_on_next_done_cb cb, void* user_data, alts_handshaker_client_vtable* vtable_for_testing, bool is_client); diff --git a/src/core/tsi/alts/handshaker/alts_shared_resource.h b/src/core/tsi/alts/handshaker/alts_shared_resource.h index 8ae0089a11c..d8638e7df69 100644 --- a/src/core/tsi/alts/handshaker/alts_shared_resource.h +++ b/src/core/tsi/alts/handshaker/alts_shared_resource.h @@ -48,7 +48,7 @@ alts_shared_resource_dedicated* grpc_alts_get_shared_resource_dedicated(void); /** * This method destroys the alts_shared_resource_dedicated object - * shared by all TSI handshakes. The applicaiton is responsible for + * shared by all TSI handshakes. The application is responsible for * invoking the API before calling grpc_shutdown(). */ void grpc_alts_shared_resource_dedicated_shutdown(); diff --git a/src/core/tsi/alts/handshaker/transport_security_common_api.cc b/src/core/tsi/alts/handshaker/transport_security_common_api.cc index 8a7edb53d4f..6c518c1ff31 100644 --- a/src/core/tsi/alts/handshaker/transport_security_common_api.cc +++ b/src/core/tsi/alts/handshaker/transport_security_common_api.cc @@ -106,15 +106,16 @@ bool grpc_gcp_rpc_protocol_versions_encode( } bool grpc_gcp_rpc_protocol_versions_decode( - grpc_slice slice, grpc_gcp_rpc_protocol_versions* versions) { + const grpc_slice& slice, grpc_gcp_rpc_protocol_versions* versions) { if (versions == nullptr) { gpr_log(GPR_ERROR, "version is nullptr in " "grpc_gcp_rpc_protocol_versions_decode()."); return false; } - pb_istream_t stream = pb_istream_from_buffer(GRPC_SLICE_START_PTR(slice), - GRPC_SLICE_LENGTH(slice)); + pb_istream_t stream = + pb_istream_from_buffer(const_cast(GRPC_SLICE_START_PTR(slice)), + GRPC_SLICE_LENGTH(slice)); if (!pb_decode(&stream, grpc_gcp_RpcProtocolVersions_fields, versions)) { gpr_log(GPR_ERROR, "nanopb error: %s", PB_GET_ERROR(&stream)); return false; diff --git a/src/core/tsi/alts/handshaker/transport_security_common_api.h b/src/core/tsi/alts/handshaker/transport_security_common_api.h index ec2a0b4b5e3..27942c8ae4c 100644 --- a/src/core/tsi/alts/handshaker/transport_security_common_api.h +++ b/src/core/tsi/alts/handshaker/transport_security_common_api.h @@ -112,7 +112,7 @@ bool grpc_gcp_rpc_protocol_versions_encode( * The method returns true on success and false otherwise. */ bool grpc_gcp_rpc_protocol_versions_decode( - grpc_slice slice, grpc_gcp_rpc_protocol_versions* versions); + const grpc_slice& slice, grpc_gcp_rpc_protocol_versions* versions); /** * This method performs a deep copy operation on rpc protocol versions diff --git a/src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc b/src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc index 58aba9b747e..fc40aaa698c 100644 --- a/src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc +++ b/src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc @@ -105,7 +105,7 @@ static bool read_frame_size(const grpc_slice_buffer* sb, * Creates an alts_grpc_record_protocol object, given key, key size, and flags * to indicate whether the record_protocol object uses the rekeying AEAD, * whether the object is for client or server, whether the object is for - * integrity-only or privacy-integrity mode, and whether the object is is used + * integrity-only or privacy-integrity mode, and whether the object is used * for protect or unprotect. */ static tsi_result create_alts_grpc_record_protocol( diff --git a/src/core/tsi/fake_transport_security.cc b/src/core/tsi/fake_transport_security.cc index 4d4c4950451..fde88dd819b 100644 --- a/src/core/tsi/fake_transport_security.cc +++ b/src/core/tsi/fake_transport_security.cc @@ -585,7 +585,7 @@ static tsi_result fake_handshaker_get_bytes_to_send_to_peer( if (next_message_to_send > TSI_FAKE_HANDSHAKE_MESSAGE_MAX) { next_message_to_send = TSI_FAKE_HANDSHAKE_MESSAGE_MAX; } - if (tsi_tracing_enabled.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(tsi_tracing_enabled)) { gpr_log(GPR_INFO, "%s prepared %s.", impl->is_client ? "Client" : "Server", tsi_fake_handshake_message_to_string(impl->next_message_to_send)); @@ -597,7 +597,7 @@ static tsi_result fake_handshaker_get_bytes_to_send_to_peer( if (!impl->is_client && impl->next_message_to_send == TSI_FAKE_HANDSHAKE_MESSAGE_MAX) { /* We're done. */ - if (tsi_tracing_enabled.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(tsi_tracing_enabled)) { gpr_log(GPR_INFO, "Server is done."); } impl->result = TSI_OK; @@ -636,7 +636,7 @@ static tsi_result fake_handshaker_process_bytes_from_peer( tsi_fake_handshake_message_to_string(received_msg), tsi_fake_handshake_message_to_string(expected_msg)); } - if (tsi_tracing_enabled.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(tsi_tracing_enabled)) { gpr_log(GPR_INFO, "%s received %s.", impl->is_client ? "Client" : "Server", tsi_fake_handshake_message_to_string(received_msg)); } @@ -644,7 +644,7 @@ static tsi_result fake_handshaker_process_bytes_from_peer( impl->needs_incoming_message = 0; if (impl->next_message_to_send == TSI_FAKE_HANDSHAKE_MESSAGE_MAX) { /* We're done. */ - if (tsi_tracing_enabled.enabled()) { + if (GRPC_TRACE_FLAG_ENABLED(tsi_tracing_enabled)) { gpr_log(GPR_INFO, "%s is done.", impl->is_client ? "Client" : "Server"); } impl->result = TSI_OK; diff --git a/src/core/tsi/ssl/session_cache/ssl_session_cache.cc b/src/core/tsi/ssl/session_cache/ssl_session_cache.cc index f9184bcc34f..ba0745a2359 100644 --- a/src/core/tsi/ssl/session_cache/ssl_session_cache.cc +++ b/src/core/tsi/ssl/session_cache/ssl_session_cache.cc @@ -18,7 +18,7 @@ #include -#include "src/core/lib/gprpp/mutex_lock.h" +#include "src/core/lib/gprpp/sync.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/tsi/ssl/session_cache/ssl_session.h" #include "src/core/tsi/ssl/session_cache/ssl_session_cache.h" diff --git a/src/core/tsi/ssl_transport_security.cc b/src/core/tsi/ssl_transport_security.cc index d6a72ada0d8..25ae2cee285 100644 --- a/src/core/tsi/ssl_transport_security.cc +++ b/src/core/tsi/ssl_transport_security.cc @@ -156,9 +156,13 @@ static unsigned long openssl_thread_id_cb(void) { #endif static void init_openssl(void) { +#if OPENSSL_API_COMPAT >= 0x10100000L + OPENSSL_init_ssl(0, NULL); +#else SSL_library_init(); SSL_load_error_strings(); OpenSSL_add_all_algorithms(); +#endif #if OPENSSL_VERSION_NUMBER < 0x10100000 if (!CRYPTO_get_locking_callback()) { int num_locks = CRYPTO_num_locks(); @@ -209,7 +213,7 @@ static const char* ssl_error_string(int error) { /* TODO(jboeuf): Remove when we are past the debugging phase with this code. */ static void ssl_log_where_info(const SSL* ssl, int where, int flag, const char* msg) { - if ((where & flag) && tsi_tracing_enabled.enabled()) { + if ((where & flag) && GRPC_TRACE_FLAG_ENABLED(tsi_tracing_enabled)) { gpr_log(GPR_INFO, "%20.20s - %30.30s - %5.10s", msg, SSL_state_string_long(ssl), SSL_state_string(ssl)); } @@ -615,15 +619,19 @@ static tsi_result x509_store_load_certs(X509_STORE* cert_store, sk_X509_NAME_push(*root_names, root_name); root_name = nullptr; } + ERR_clear_error(); if (!X509_STORE_add_cert(cert_store, root)) { - gpr_log(GPR_ERROR, "Could not add root certificate to ssl context."); - result = TSI_INTERNAL_ERROR; - break; + unsigned long error = ERR_get_error(); + if (ERR_GET_LIB(error) != ERR_LIB_X509 || + ERR_GET_REASON(error) != X509_R_CERT_ALREADY_IN_HASH_TABLE) { + gpr_log(GPR_ERROR, "Could not add root certificate to ssl context."); + result = TSI_INTERNAL_ERROR; + break; + } } X509_free(root); num_roots++; } - if (num_roots == 0) { gpr_log(GPR_ERROR, "Could not load any root certificate."); result = TSI_INVALID_ARGUMENT; @@ -647,6 +655,8 @@ static tsi_result ssl_ctx_load_verification_certs(SSL_CTX* context, STACK_OF(X509_NAME) * *root_name) { X509_STORE* cert_store = SSL_CTX_get_cert_store(context); + X509_STORE_set_flags(cert_store, + X509_V_FLAG_PARTIAL_CHAIN | X509_V_FLAG_TRUSTED_FIRST); return x509_store_load_certs(cert_store, pem_roots, pem_roots_size, root_name); } @@ -1007,7 +1017,6 @@ static void tsi_ssl_handshaker_factory_init( } /* --- tsi_handshaker_result methods implementation. ---*/ - static tsi_result ssl_handshaker_result_extract_peer( const tsi_handshaker_result* self, tsi_peer* peer) { tsi_result result = TSI_OK; @@ -1015,6 +1024,7 @@ static tsi_result ssl_handshaker_result_extract_peer( unsigned int alpn_selected_len; const tsi_ssl_handshaker_result* impl = reinterpret_cast(self); + // TODO(yihuazhang): Return a full certificate chain as a peer property. X509* peer_cert = SSL_get_peer_certificate(impl->ssl); if (peer_cert != nullptr) { result = peer_from_x509(peer_cert, 1, peer); @@ -1056,7 +1066,6 @@ static tsi_result ssl_handshaker_result_extract_peer( &peer->properties[peer->property_count]); if (result != TSI_OK) return result; peer->property_count++; - return result; } @@ -1390,7 +1399,6 @@ static tsi_result create_tsi_ssl_handshaker(SSL_CTX* ctx, int is_client, static_cast(gpr_zalloc(impl->outgoing_bytes_buffer_size)); impl->base.vtable = &handshaker_vtable; impl->factory_ref = tsi_ssl_handshaker_factory_ref(factory); - *handshaker = &impl->base; return TSI_OK; } @@ -1624,7 +1632,6 @@ tsi_result tsi_create_ssl_client_handshaker_factory( const char** alpn_protocols, uint16_t num_alpn_protocols, tsi_ssl_client_handshaker_factory** factory) { tsi_ssl_client_handshaker_options options; - memset(&options, 0, sizeof(options)); options.pem_key_cert_pair = pem_key_cert_pair; options.pem_root_certs = pem_root_certs; options.cipher_suites = cipher_suites; @@ -1649,7 +1656,11 @@ tsi_result tsi_create_ssl_client_handshaker_factory_with_options( return TSI_INVALID_ARGUMENT; } +#if defined(OPENSSL_NO_TLS1_2_METHOD) || OPENSSL_API_COMPAT >= 0x10100000L + ssl_context = SSL_CTX_new(TLS_method()); +#else ssl_context = SSL_CTX_new(TLSv1_2_method()); +#endif if (ssl_context == nullptr) { gpr_log(GPR_ERROR, "Could not create ssl context."); return TSI_INVALID_ARGUMENT; @@ -1750,7 +1761,6 @@ tsi_result tsi_create_ssl_server_handshaker_factory_ex( const char* cipher_suites, const char** alpn_protocols, uint16_t num_alpn_protocols, tsi_ssl_server_handshaker_factory** factory) { tsi_ssl_server_handshaker_options options; - memset(&options, 0, sizeof(options)); options.pem_key_cert_pairs = pem_key_cert_pairs; options.num_key_cert_pairs = num_key_cert_pairs; options.pem_client_root_certs = pem_client_root_certs; @@ -1806,7 +1816,11 @@ tsi_result tsi_create_ssl_server_handshaker_factory_with_options( for (i = 0; i < options->num_key_cert_pairs; i++) { do { +#if defined(OPENSSL_NO_TLS1_2_METHOD) || OPENSSL_API_COMPAT >= 0x10100000L + impl->ssl_contexts[i] = SSL_CTX_new(TLS_method()); +#else impl->ssl_contexts[i] = SSL_CTX_new(TLSv1_2_method()); +#endif if (impl->ssl_contexts[i] == nullptr) { gpr_log(GPR_ERROR, "Could not create ssl context."); result = TSI_OUT_OF_RESOURCES; @@ -1850,31 +1864,30 @@ tsi_result tsi_create_ssl_server_handshaker_factory_with_options( break; } SSL_CTX_set_client_CA_list(impl->ssl_contexts[i], root_names); - switch (options->client_certificate_request) { - case TSI_DONT_REQUEST_CLIENT_CERTIFICATE: - SSL_CTX_set_verify(impl->ssl_contexts[i], SSL_VERIFY_NONE, nullptr); - break; - case TSI_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY: - SSL_CTX_set_verify(impl->ssl_contexts[i], SSL_VERIFY_PEER, - NullVerifyCallback); - break; - case TSI_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY: - SSL_CTX_set_verify(impl->ssl_contexts[i], SSL_VERIFY_PEER, nullptr); - break; - case TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY: - SSL_CTX_set_verify( - impl->ssl_contexts[i], - SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, - NullVerifyCallback); - break; - case TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY: - SSL_CTX_set_verify( - impl->ssl_contexts[i], - SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr); - break; - } - /* TODO(jboeuf): Add revocation verification. */ } + switch (options->client_certificate_request) { + case TSI_DONT_REQUEST_CLIENT_CERTIFICATE: + SSL_CTX_set_verify(impl->ssl_contexts[i], SSL_VERIFY_NONE, nullptr); + break; + case TSI_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY: + SSL_CTX_set_verify(impl->ssl_contexts[i], SSL_VERIFY_PEER, + NullVerifyCallback); + break; + case TSI_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY: + SSL_CTX_set_verify(impl->ssl_contexts[i], SSL_VERIFY_PEER, nullptr); + break; + case TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY: + SSL_CTX_set_verify(impl->ssl_contexts[i], + SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, + NullVerifyCallback); + break; + case TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY: + SSL_CTX_set_verify(impl->ssl_contexts[i], + SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, + nullptr); + break; + } + /* TODO(jboeuf): Add revocation verification. */ result = extract_x509_subject_names_from_pem_cert( options->pem_key_cert_pairs[i].cert_chain, diff --git a/src/core/tsi/ssl_transport_security.h b/src/core/tsi/ssl_transport_security.h index cabf5830980..769949e4aad 100644 --- a/src/core/tsi/ssl_transport_security.h +++ b/src/core/tsi/ssl_transport_security.h @@ -111,7 +111,7 @@ tsi_result tsi_create_ssl_client_handshaker_factory( const char** alpn_protocols, uint16_t num_alpn_protocols, tsi_ssl_client_handshaker_factory** factory); -typedef struct { +struct tsi_ssl_client_handshaker_options { /* pem_key_cert_pair is a pointer to the object containing client's private key and certificate chain. This parameter can be NULL if the client does not have such a key/cert pair. */ @@ -140,7 +140,16 @@ typedef struct { size_t num_alpn_protocols; /* ssl_session_cache is a cache for reusable client-side sessions. */ tsi_ssl_session_cache* session_cache; -} tsi_ssl_client_handshaker_options; + + tsi_ssl_client_handshaker_options() + : pem_key_cert_pair(nullptr), + pem_root_certs(nullptr), + root_store(nullptr), + cipher_suites(nullptr), + alpn_protocols(nullptr), + num_alpn_protocols(0), + session_cache(nullptr) {} +}; /* Creates a client handshaker factory. - options is the options used to create a factory. @@ -221,7 +230,7 @@ tsi_result tsi_create_ssl_server_handshaker_factory_ex( const char* cipher_suites, const char** alpn_protocols, uint16_t num_alpn_protocols, tsi_ssl_server_handshaker_factory** factory); -typedef struct { +struct tsi_ssl_server_handshaker_options { /* pem_key_cert_pairs is an array private key / certificate chains of the server. */ const tsi_ssl_pem_key_cert_pair* pem_key_cert_pairs; @@ -255,7 +264,18 @@ typedef struct { const char* session_ticket_key; /* session_ticket_key_size is a size of session ticket encryption key. */ size_t session_ticket_key_size; -} tsi_ssl_server_handshaker_options; + + tsi_ssl_server_handshaker_options() + : pem_key_cert_pairs(nullptr), + num_key_cert_pairs(0), + pem_client_root_certs(nullptr), + client_certificate_request(TSI_DONT_REQUEST_CLIENT_CERTIFICATE), + cipher_suites(nullptr), + alpn_protocols(nullptr), + num_alpn_protocols(0), + session_ticket_key(nullptr), + session_ticket_key_size(0) {} +}; /* Creates a server handshaker factory. - options is the options used to create a factory. diff --git a/src/cpp/README.md b/src/cpp/README.md old mode 100644 new mode 100755 index 4ec9133c598..da5c5e69453 --- a/src/cpp/README.md +++ b/src/cpp/README.md @@ -52,7 +52,7 @@ support for crosscompiling and can be used for targeting Android platform. If your project is using cmake, there are several ways to add gRPC dependency. - install gRPC via cmake first and then locate it with `find_package(gRPC CONFIG)`. [Example](../../examples/cpp/helloworld/CMakeLists.txt) - via cmake's `ExternalProject_Add` using a technique called "superbuild". [Example](../../examples/cpp/helloworld/cmake_externalproject/CMakeLists.txt) -- add gRPC source tree to your project (preferrably as a git submodule) and add it to your cmake project with `add_subdirectory`. [Example](../../examples/cpp/helloworld/CMakeLists.txt) +- add gRPC source tree to your project (preferably as a git submodule) and add it to your cmake project with `add_subdirectory`. [Example](../../examples/cpp/helloworld/CMakeLists.txt) ## Packaging systems diff --git a/src/cpp/client/channel_cc.cc b/src/cpp/client/channel_cc.cc index d1c55319f7c..58f012d8c82 100644 --- a/src/cpp/client/channel_cc.cc +++ b/src/cpp/client/channel_cc.cc @@ -18,8 +18,6 @@ #include -#include -#include #include #include #include @@ -41,22 +39,21 @@ #include #include #include -#include -#include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/string.h" -#include "src/core/lib/gprpp/memory.h" -#include "src/core/lib/gprpp/thd.h" -#include "src/core/lib/profiling/timers.h" #include "src/core/lib/surface/completion_queue.h" -namespace grpc { +void grpc::experimental::ChannelResetConnectionBackoff( + ::grpc::Channel* channel) { + grpc_impl::experimental::ChannelResetConnectionBackoff(channel); +} -static internal::GrpcLibraryInitializer g_gli_initializer; -Channel::Channel( - const grpc::string& host, grpc_channel* channel, - std::vector< - std::unique_ptr> - interceptor_creators) +namespace grpc_impl { + +static ::grpc::internal::GrpcLibraryInitializer g_gli_initializer; +Channel::Channel(const grpc::string& host, grpc_channel* channel, + std::vector> + interceptor_creators) : host_(host), c_channel_(channel) { interceptor_creators_ = std::move(interceptor_creators); g_gli_initializer.summon(); @@ -72,7 +69,8 @@ Channel::~Channel() { namespace { inline grpc_slice SliceFromArray(const char* arr, size_t len) { - return g_core_codegen_interface->grpc_slice_from_copied_buffer(arr, len); + return ::grpc::g_core_codegen_interface->grpc_slice_from_copied_buffer(arr, + len); } grpc::string GetChannelInfoField(grpc_channel* channel, @@ -110,10 +108,9 @@ void ChannelResetConnectionBackoff(Channel* channel) { } // namespace experimental -internal::Call Channel::CreateCallInternal(const internal::RpcMethod& method, - ClientContext* context, - CompletionQueue* cq, - size_t interceptor_pos) { +::grpc::internal::Call Channel::CreateCallInternal( + const ::grpc::internal::RpcMethod& method, ::grpc::ClientContext* context, + ::grpc::CompletionQueue* cq, size_t interceptor_pos) { const bool kRegistered = method.channel_tag() && context->authority().empty(); grpc_call* c_call = nullptr; if (kRegistered) { @@ -122,7 +119,7 @@ internal::Call Channel::CreateCallInternal(const internal::RpcMethod& method, context->propagation_options_.c_bitmask(), cq->cq(), method.channel_tag(), context->raw_deadline(), nullptr); } else { - const string* host_str = nullptr; + const ::grpc::string* host_str = nullptr; if (!context->authority_.empty()) { host_str = &context->authority_; } else if (!host_.empty()) { @@ -132,7 +129,7 @@ internal::Call Channel::CreateCallInternal(const internal::RpcMethod& method, SliceFromArray(method.name(), strlen(method.name())); grpc_slice host_slice; if (host_str != nullptr) { - host_slice = SliceFromCopiedString(*host_str); + host_slice = ::grpc::SliceFromCopiedString(*host_str); } c_call = grpc_channel_create_call( c_channel_, context->propagate_from_call_, @@ -149,21 +146,22 @@ internal::Call Channel::CreateCallInternal(const internal::RpcMethod& method, // ClientRpcInfo should be set before call because set_call also checks // whether the call has been cancelled, and if the call was cancelled, we // should notify the interceptors too/ - auto* info = context->set_client_rpc_info( - method.name(), this, interceptor_creators_, interceptor_pos); + auto* info = + context->set_client_rpc_info(method.name(), method.method_type(), this, + interceptor_creators_, interceptor_pos); context->set_call(c_call, shared_from_this()); - return internal::Call(c_call, this, cq, info); + return ::grpc::internal::Call(c_call, this, cq, info); } -internal::Call Channel::CreateCall(const internal::RpcMethod& method, - ClientContext* context, - CompletionQueue* cq) { +::grpc::internal::Call Channel::CreateCall( + const ::grpc::internal::RpcMethod& method, ::grpc::ClientContext* context, + ::grpc::CompletionQueue* cq) { return CreateCallInternal(method, context, cq, 0); } -void Channel::PerformOpsOnCall(internal::CallOpSetInterface* ops, - internal::Call* call) { +void Channel::PerformOpsOnCall(::grpc::internal::CallOpSetInterface* ops, + ::grpc::internal::Call* call) { ops->FillOps( call); // Make a copy of call. It's fine since Call just has pointers } @@ -179,7 +177,7 @@ grpc_connectivity_state Channel::GetState(bool try_to_connect) { namespace { -class TagSaver final : public internal::CompletionQueueTag { +class TagSaver final : public ::grpc::internal::CompletionQueueTag { public: explicit TagSaver(void* tag) : tag_(tag) {} ~TagSaver() override {} @@ -197,7 +195,7 @@ class TagSaver final : public internal::CompletionQueueTag { void Channel::NotifyOnStateChangeImpl(grpc_connectivity_state last_observed, gpr_timespec deadline, - CompletionQueue* cq, void* tag) { + ::grpc::CompletionQueue* cq, void* tag) { TagSaver* tag_saver = new TagSaver(tag); grpc_channel_watch_connectivity_state(c_channel_, last_observed, deadline, cq->cq(), tag_saver); @@ -205,7 +203,7 @@ void Channel::NotifyOnStateChangeImpl(grpc_connectivity_state last_observed, bool Channel::WaitForStateChangeImpl(grpc_connectivity_state last_observed, gpr_timespec deadline) { - CompletionQueue cq; + ::grpc::CompletionQueue cq; bool ok = false; void* tag = nullptr; NotifyOnStateChangeImpl(last_observed, deadline, &cq, nullptr); @@ -220,7 +218,7 @@ class ShutdownCallback : public grpc_experimental_completion_queue_functor { ShutdownCallback() { functor_run = &ShutdownCallback::Run; } // TakeCQ takes ownership of the cq into the shutdown callback // so that the shutdown callback will be responsible for destroying it - void TakeCQ(CompletionQueue* cq) { cq_ = cq; } + void TakeCQ(::grpc::CompletionQueue* cq) { cq_ = cq; } // The Run function will get invoked by the completion queue library // when the shutdown is actually complete @@ -231,17 +229,17 @@ class ShutdownCallback : public grpc_experimental_completion_queue_functor { } private: - CompletionQueue* cq_ = nullptr; + ::grpc::CompletionQueue* cq_ = nullptr; }; } // namespace -CompletionQueue* Channel::CallbackCQ() { +::grpc::CompletionQueue* Channel::CallbackCQ() { // TODO(vjpai): Consider using a single global CQ for the default CQ // if there is no explicit per-channel CQ registered - std::lock_guard l(mu_); + grpc::internal::MutexLock l(&mu_); if (callback_cq_ == nullptr) { auto* shutdown_callback = new ShutdownCallback; - callback_cq_ = new CompletionQueue(grpc_completion_queue_attributes{ + callback_cq_ = new ::grpc::CompletionQueue(grpc_completion_queue_attributes{ GRPC_CQ_CURRENT_VERSION, GRPC_CQ_CALLBACK, GRPC_CQ_DEFAULT_POLLING, shutdown_callback}); @@ -251,4 +249,4 @@ CompletionQueue* Channel::CallbackCQ() { return callback_cq_; } -} // namespace grpc +} // namespace grpc_impl diff --git a/src/cpp/client/client_context.cc b/src/cpp/client/client_context.cc index 50da75f09c1..0ae1ecbf4ba 100644 --- a/src/cpp/client/client_context.cc +++ b/src/cpp/client/client_context.cc @@ -25,11 +25,17 @@ #include #include +#include #include #include #include #include +namespace grpc_impl { + +class Channel; +} + namespace grpc { class DefaultGlobalClientCallbacks final @@ -41,9 +47,10 @@ class DefaultGlobalClientCallbacks final }; static internal::GrpcLibraryInitializer g_gli_initializer; -static DefaultGlobalClientCallbacks g_default_client_callbacks; +static DefaultGlobalClientCallbacks* g_default_client_callbacks = + new DefaultGlobalClientCallbacks(); static ClientContext::GlobalCallbacks* g_client_callbacks = - &g_default_client_callbacks; + g_default_client_callbacks; ClientContext::ClientContext() : initial_metadata_received_(false), @@ -56,6 +63,7 @@ ClientContext::ClientContext() deadline_(gpr_inf_future(GPR_CLOCK_REALTIME)), census_context_(nullptr), propagate_from_call_(nullptr), + compression_algorithm_(GRPC_COMPRESS_NONE), initial_metadata_corked_(false) { g_client_callbacks->DefaultConstructor(this); } @@ -80,9 +88,9 @@ void ClientContext::AddMetadata(const grpc::string& meta_key, send_initial_metadata_.insert(std::make_pair(meta_key, meta_value)); } -void ClientContext::set_call(grpc_call* call, - const std::shared_ptr& channel) { - std::unique_lock lock(mu_); +void ClientContext::set_call( + grpc_call* call, const std::shared_ptr<::grpc_impl::Channel>& channel) { + grpc::internal::MutexLock lock(&mu_); GPR_ASSERT(call_ == nullptr); call_ = call; channel_ = channel; @@ -112,7 +120,7 @@ void ClientContext::set_compression_algorithm( } void ClientContext::TryCancel() { - std::unique_lock lock(mu_); + grpc::internal::MutexLock lock(&mu_); if (call_) { SendCancelToInterceptors(); grpc_call_cancel(call_, nullptr); @@ -139,9 +147,9 @@ grpc::string ClientContext::peer() const { } void ClientContext::SetGlobalCallbacks(GlobalCallbacks* client_callbacks) { - GPR_ASSERT(g_client_callbacks == &g_default_client_callbacks); + GPR_ASSERT(g_client_callbacks == g_default_client_callbacks); GPR_ASSERT(client_callbacks != nullptr); - GPR_ASSERT(client_callbacks != &g_default_client_callbacks); + GPR_ASSERT(client_callbacks != g_default_client_callbacks); g_client_callbacks = client_callbacks; } diff --git a/src/cpp/client/client_interceptor.cc b/src/cpp/client/client_interceptor.cc index 3a5cac9830f..a91950cae2d 100644 --- a/src/cpp/client/client_interceptor.cc +++ b/src/cpp/client/client_interceptor.cc @@ -28,7 +28,17 @@ experimental::ClientInterceptorFactoryInterface* namespace experimental { void RegisterGlobalClientInterceptorFactory( ClientInterceptorFactoryInterface* factory) { + if (internal::g_global_client_interceptor_factory != nullptr) { + GPR_ASSERT(false && + "It is illegal to call RegisterGlobalClientInterceptorFactory " + "multiple times."); + } internal::g_global_client_interceptor_factory = factory; } + +// For testing purposes only. +void TestOnlyResetGlobalClientInterceptorFactory() { + internal::g_global_client_interceptor_factory = nullptr; +} } // namespace experimental } // namespace grpc diff --git a/src/cpp/client/create_channel.cc b/src/cpp/client/create_channel.cc index 457daa674c7..3318ded7268 100644 --- a/src/cpp/client/create_channel.cc +++ b/src/cpp/client/create_channel.cc @@ -21,32 +21,33 @@ #include #include #include +#include #include #include "src/cpp/client/create_channel_internal.h" -namespace grpc { -class ChannelArguments; - -std::shared_ptr CreateChannel( +namespace grpc_impl { +std::shared_ptr CreateChannelImpl( const grpc::string& target, - const std::shared_ptr& creds) { - return CreateCustomChannel(target, creds, ChannelArguments()); + const std::shared_ptr& creds) { + return CreateCustomChannelImpl(target, creds, grpc::ChannelArguments()); } -std::shared_ptr CreateCustomChannel( +std::shared_ptr CreateCustomChannelImpl( const grpc::string& target, - const std::shared_ptr& creds, - const ChannelArguments& args) { - GrpcLibraryCodegen init_lib; // We need to call init in case of a bad creds. - return creds ? creds->CreateChannel(target, args) - : CreateChannelInternal( + const std::shared_ptr& creds, + const grpc::ChannelArguments& args) { + grpc::GrpcLibraryCodegen + init_lib; // We need to call init in case of a bad creds. + return creds ? creds->CreateChannelImpl(target, args) + : grpc::CreateChannelInternal( "", grpc_lame_client_channel_create( nullptr, GRPC_STATUS_INVALID_ARGUMENT, "Invalid credentials."), std::vector>()); + grpc::experimental:: + ClientInterceptorFactoryInterface>>()); } namespace experimental { @@ -61,23 +62,22 @@ namespace experimental { /// hold an object or is invalid, a lame channel (one on which all operations /// fail) is returned. /// \param args Options for channel creation. -std::shared_ptr CreateCustomChannelWithInterceptors( +std::shared_ptr CreateCustomChannelWithInterceptors( const grpc::string& target, - const std::shared_ptr& creds, - const ChannelArguments& args, + const std::shared_ptr& creds, + const grpc::ChannelArguments& args, std::vector< - std::unique_ptr> + std::unique_ptr> interceptor_creators) { return creds ? creds->CreateChannelWithInterceptors( target, args, std::move(interceptor_creators)) - : CreateChannelInternal( + : ::grpc::CreateChannelInternal( "", grpc_lame_client_channel_create( nullptr, GRPC_STATUS_INVALID_ARGUMENT, "Invalid credentials."), - std::vector>()); + std::move(interceptor_creators)); } } // namespace experimental -} // namespace grpc +} // namespace grpc_impl diff --git a/src/cpp/client/create_channel_internal.cc b/src/cpp/client/create_channel_internal.cc index a0efb97f7ef..63e1d14eb34 100644 --- a/src/cpp/client/create_channel_internal.cc +++ b/src/cpp/client/create_channel_internal.cc @@ -26,10 +26,11 @@ namespace grpc { std::shared_ptr CreateChannelInternal( const grpc::string& host, grpc_channel* c_channel, - std::vector< - std::unique_ptr> + std::vector> interceptor_creators) { return std::shared_ptr( new Channel(host, c_channel, std::move(interceptor_creators))); } + } // namespace grpc diff --git a/src/cpp/client/create_channel_internal.h b/src/cpp/client/create_channel_internal.h index a90c92c518d..3b201afb5a7 100644 --- a/src/cpp/client/create_channel_internal.h +++ b/src/cpp/client/create_channel_internal.h @@ -27,12 +27,11 @@ struct grpc_channel; namespace grpc { -class Channel; std::shared_ptr CreateChannelInternal( const grpc::string& host, grpc_channel* c_channel, - std::vector< - std::unique_ptr> + std::vector> interceptor_creators); } // namespace grpc diff --git a/src/cpp/client/create_channel_posix.cc b/src/cpp/client/create_channel_posix.cc index 3affc1ef391..ca26c3f0a9f 100644 --- a/src/cpp/client/create_channel_posix.cc +++ b/src/cpp/client/create_channel_posix.cc @@ -19,50 +19,53 @@ #include #include #include -#include #include +#include #include "src/cpp/client/create_channel_internal.h" -namespace grpc { +namespace grpc_impl { + +class ChannelArguments; #ifdef GPR_SUPPORT_CHANNELS_FROM_FD -std::shared_ptr CreateInsecureChannelFromFd(const grpc::string& target, - int fd) { - internal::GrpcLibrary init_lib; +std::shared_ptr CreateInsecureChannelFromFd( + const grpc::string& target, int fd) { + grpc::internal::GrpcLibrary init_lib; init_lib.init(); - return CreateChannelInternal( + return ::grpc::CreateChannelInternal( "", grpc_insecure_channel_create_from_fd(target.c_str(), fd, nullptr), - std::vector< - std::unique_ptr>()); + std::vector>()); } -std::shared_ptr CreateCustomInsecureChannelFromFd( - const grpc::string& target, int fd, const ChannelArguments& args) { - internal::GrpcLibrary init_lib; +std::shared_ptr CreateCustomInsecureChannelFromFd( + const grpc::string& target, int fd, const grpc::ChannelArguments& args) { + grpc::internal::GrpcLibrary init_lib; init_lib.init(); grpc_channel_args channel_args; args.SetChannelArgs(&channel_args); - return CreateChannelInternal( + return ::grpc::CreateChannelInternal( "", grpc_insecure_channel_create_from_fd(target.c_str(), fd, &channel_args), - std::vector< - std::unique_ptr>()); + std::vector>()); } namespace experimental { -std::shared_ptr CreateCustomInsecureChannelWithInterceptorsFromFd( - const grpc::string& target, int fd, const ChannelArguments& args, +std::shared_ptr +CreateCustomInsecureChannelWithInterceptorsFromFd( + const grpc::string& target, int fd, const grpc::ChannelArguments& args, std::vector< - std::unique_ptr> + std::unique_ptr> interceptor_creators) { - internal::GrpcLibrary init_lib; + grpc::internal::GrpcLibrary init_lib; init_lib.init(); grpc_channel_args channel_args; args.SetChannelArgs(&channel_args); - return CreateChannelInternal( + return ::grpc::CreateChannelInternal( "", grpc_insecure_channel_create_from_fd(target.c_str(), fd, &channel_args), std::move(interceptor_creators)); @@ -72,4 +75,4 @@ std::shared_ptr CreateCustomInsecureChannelWithInterceptorsFromFd( #endif // GPR_SUPPORT_CHANNELS_FROM_FD -} // namespace grpc +} // namespace grpc_impl diff --git a/src/cpp/client/credentials_cc.cc b/src/cpp/client/credentials_cc.cc index 2a0f06f424e..62334bd9eba 100644 --- a/src/cpp/client/credentials_cc.cc +++ b/src/cpp/client/credentials_cc.cc @@ -19,9 +19,9 @@ #include #include -namespace grpc { +namespace grpc_impl { -static internal::GrpcLibraryInitializer g_gli_initializer; +static grpc::internal::GrpcLibraryInitializer g_gli_initializer; ChannelCredentials::ChannelCredentials() { g_gli_initializer.summon(); } ChannelCredentials::~ChannelCredentials() {} @@ -30,4 +30,4 @@ CallCredentials::CallCredentials() { g_gli_initializer.summon(); } CallCredentials::~CallCredentials() {} -} // namespace grpc +} // namespace grpc_impl diff --git a/src/cpp/client/cronet_credentials.cc b/src/cpp/client/cronet_credentials.cc index b2801764f20..f4ead14cde8 100644 --- a/src/cpp/client/cronet_credentials.cc +++ b/src/cpp/client/cronet_credentials.cc @@ -29,7 +29,7 @@ class CronetChannelCredentialsImpl final : public ChannelCredentials { public: CronetChannelCredentialsImpl(void* engine) : engine_(engine) {} - std::shared_ptr CreateChannel( + std::shared_ptr CreateChannelImpl( const string& target, const grpc::ChannelArguments& args) override { return CreateChannelWithInterceptors( target, args, @@ -55,10 +55,10 @@ class CronetChannelCredentialsImpl final : public ChannelCredentials { } void* engine_; }; - +} // namespace grpc +namespace grpc_impl { std::shared_ptr CronetChannelCredentials(void* engine) { return std::shared_ptr( - new CronetChannelCredentialsImpl(engine)); + new grpc::CronetChannelCredentialsImpl(engine)); } - -} // namespace grpc +} // namespace grpc_impl diff --git a/src/cpp/client/generic_stub.cc b/src/cpp/client/generic_stub.cc index 87902b26f0e..41631c794f2 100644 --- a/src/cpp/client/generic_stub.cc +++ b/src/cpp/client/generic_stub.cc @@ -22,54 +22,75 @@ #include #include -namespace grpc { +namespace grpc_impl { namespace { -std::unique_ptr CallInternal( - ChannelInterface* channel, ClientContext* context, - const grpc::string& method, CompletionQueue* cq, bool start, void* tag) { - return std::unique_ptr( - internal::ClientAsyncReaderWriterFactory::Create( - channel, cq, - internal::RpcMethod(method.c_str(), - internal::RpcMethod::BIDI_STREAMING), - context, start, tag)); +std::unique_ptr CallInternal( + grpc::ChannelInterface* channel, grpc::ClientContext* context, + const grpc::string& method, grpc::CompletionQueue* cq, bool start, + void* tag) { + return std::unique_ptr( + grpc::internal::ClientAsyncReaderWriterFactory:: + Create(channel, cq, + grpc::internal::RpcMethod( + method.c_str(), grpc::internal::RpcMethod::BIDI_STREAMING), + context, start, tag)); } } // namespace // begin a call to a named method -std::unique_ptr GenericStub::Call( - ClientContext* context, const grpc::string& method, CompletionQueue* cq, - void* tag) { +std::unique_ptr GenericStub::Call( + grpc::ClientContext* context, const grpc::string& method, + grpc::CompletionQueue* cq, void* tag) { return CallInternal(channel_.get(), context, method, cq, true, tag); } // setup a call to a named method -std::unique_ptr GenericStub::PrepareCall( - ClientContext* context, const grpc::string& method, CompletionQueue* cq) { +std::unique_ptr GenericStub::PrepareCall( + grpc::ClientContext* context, const grpc::string& method, + grpc::CompletionQueue* cq) { return CallInternal(channel_.get(), context, method, cq, false, nullptr); } // setup a unary call to a named method -std::unique_ptr GenericStub::PrepareUnaryCall( - ClientContext* context, const grpc::string& method, - const ByteBuffer& request, CompletionQueue* cq) { - return std::unique_ptr( - internal::ClientAsyncResponseReaderFactory::Create( - channel_.get(), cq, - internal::RpcMethod(method.c_str(), internal::RpcMethod::NORMAL_RPC), - context, request, false)); +std::unique_ptr +GenericStub::PrepareUnaryCall(grpc::ClientContext* context, + const grpc::string& method, + const grpc::ByteBuffer& request, + grpc::CompletionQueue* cq) { + return std::unique_ptr( + grpc::internal::ClientAsyncResponseReaderFactory< + grpc::ByteBuffer>::Create(channel_.get(), cq, + grpc::internal::RpcMethod( + method.c_str(), + grpc::internal::RpcMethod::NORMAL_RPC), + context, request, false)); } void GenericStub::experimental_type::UnaryCall( - ClientContext* context, const grpc::string& method, - const ByteBuffer* request, ByteBuffer* response, - std::function on_completion) { - internal::CallbackUnaryCall( + grpc::ClientContext* context, const grpc::string& method, + const grpc::ByteBuffer* request, grpc::ByteBuffer* response, + std::function on_completion) { + grpc::internal::CallbackUnaryCall( stub_->channel_.get(), - internal::RpcMethod(method.c_str(), internal::RpcMethod::NORMAL_RPC), + grpc::internal::RpcMethod(method.c_str(), + grpc::internal::RpcMethod::NORMAL_RPC), context, request, response, std::move(on_completion)); } -} // namespace grpc +void GenericStub::experimental_type::PrepareBidiStreamingCall( + grpc::ClientContext* context, const grpc::string& method, + grpc::experimental::ClientBidiReactor* + reactor) { + grpc::internal::ClientCallbackReaderWriterFactory< + grpc::ByteBuffer, + grpc::ByteBuffer>::Create(stub_->channel_.get(), + grpc::internal::RpcMethod( + method.c_str(), + grpc::internal::RpcMethod::BIDI_STREAMING), + context, reactor); +} + +} // namespace grpc_impl diff --git a/src/cpp/client/insecure_credentials.cc b/src/cpp/client/insecure_credentials.cc index 241ce918034..dcbb56dccda 100644 --- a/src/cpp/client/insecure_credentials.cc +++ b/src/cpp/client/insecure_credentials.cc @@ -21,31 +21,32 @@ #include #include #include +#include #include #include #include "src/cpp/client/create_channel_internal.h" -namespace grpc { +namespace grpc_impl { namespace { class InsecureChannelCredentialsImpl final : public ChannelCredentials { public: - std::shared_ptr CreateChannel( - const string& target, const grpc::ChannelArguments& args) override { + std::shared_ptr<::grpc::Channel> CreateChannelImpl( + const grpc::string& target, const grpc::ChannelArguments& args) override { return CreateChannelWithInterceptors( target, args, std::vector>()); + grpc::experimental::ClientInterceptorFactoryInterface>>()); } - std::shared_ptr CreateChannelWithInterceptors( - const string& target, const grpc::ChannelArguments& args, - std::vector< - std::unique_ptr> + std::shared_ptr<::grpc::Channel> CreateChannelWithInterceptors( + const grpc::string& target, const grpc::ChannelArguments& args, + std::vector> interceptor_creators) override { grpc_channel_args channel_args; args.SetChannelArgs(&channel_args); - return CreateChannelInternal( + return ::grpc::CreateChannelInternal( "", grpc_insecure_channel_create(target.c_str(), &channel_args, nullptr), std::move(interceptor_creators)); @@ -60,4 +61,4 @@ std::shared_ptr InsecureChannelCredentials() { new InsecureChannelCredentialsImpl()); } -} // namespace grpc +} // namespace grpc_impl diff --git a/src/cpp/client/secure_credentials.cc b/src/cpp/client/secure_credentials.cc index d0abe441a6a..724a43a9709 100644 --- a/src/cpp/client/secure_credentials.cc +++ b/src/cpp/client/secure_credentials.cc @@ -25,32 +25,32 @@ #include "src/cpp/client/create_channel_internal.h" #include "src/cpp/common/secure_auth_context.h" -namespace grpc { +namespace grpc_impl { -static internal::GrpcLibraryInitializer g_gli_initializer; +static grpc::internal::GrpcLibraryInitializer g_gli_initializer; SecureChannelCredentials::SecureChannelCredentials( grpc_channel_credentials* c_creds) : c_creds_(c_creds) { g_gli_initializer.summon(); } -std::shared_ptr SecureChannelCredentials::CreateChannel( - const string& target, const grpc::ChannelArguments& args) { +std::shared_ptr SecureChannelCredentials::CreateChannelImpl( + const grpc::string& target, const grpc::ChannelArguments& args) { return CreateChannelWithInterceptors( target, args, - std::vector< - std::unique_ptr>()); + std::vector>()); } std::shared_ptr SecureChannelCredentials::CreateChannelWithInterceptors( - const string& target, const grpc::ChannelArguments& args, + const grpc::string& target, const grpc::ChannelArguments& args, std::vector< - std::unique_ptr> + std::unique_ptr> interceptor_creators) { grpc_channel_args channel_args; args.SetChannelArgs(&channel_args); - return CreateChannelInternal( + return ::grpc::CreateChannelInternal( args.GetSslTargetNameOverride(), grpc_secure_channel_create(c_creds_, target.c_str(), &channel_args, nullptr), @@ -83,14 +83,14 @@ std::shared_ptr WrapCallCredentials( } // namespace std::shared_ptr GoogleDefaultCredentials() { - GrpcLibraryCodegen init; // To call grpc_init(). + grpc::GrpcLibraryCodegen init; // To call grpc_init(). return WrapChannelCredentials(grpc_google_default_credentials_create()); } // Builds SSL Credentials given SSL specific options std::shared_ptr SslCredentials( const SslCredentialsOptions& options) { - GrpcLibraryCodegen init; // To call grpc_init(). + grpc::GrpcLibraryCodegen init; // To call grpc_init(). grpc_ssl_pem_key_cert_pair pem_key_cert_pair = { options.pem_private_key.c_str(), options.pem_cert_chain.c_str()}; @@ -106,7 +106,7 @@ namespace experimental { // Builds ALTS Credentials given ALTS specific options std::shared_ptr AltsCredentials( const AltsCredentialsOptions& options) { - GrpcLibraryCodegen init; // To call grpc_init(). + grpc::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(); @@ -123,7 +123,7 @@ std::shared_ptr AltsCredentials( // Builds Local Credentials std::shared_ptr LocalCredentials( grpc_local_connect_type type) { - GrpcLibraryCodegen init; // To call grpc_init(). + grpc::GrpcLibraryCodegen init; // To call grpc_init(). return WrapChannelCredentials(grpc_local_credentials_create(type)); } @@ -131,7 +131,7 @@ std::shared_ptr LocalCredentials( // Builds credentials for use when running in GCE std::shared_ptr GoogleComputeEngineCredentials() { - GrpcLibraryCodegen init; // To call grpc_init(). + grpc::GrpcLibraryCodegen init; // To call grpc_init(). return WrapCallCredentials( grpc_google_compute_engine_credentials_create(nullptr)); } @@ -139,7 +139,7 @@ std::shared_ptr GoogleComputeEngineCredentials() { // Builds JWT credentials. std::shared_ptr ServiceAccountJWTAccessCredentials( const grpc::string& json_key, long token_lifetime_seconds) { - GrpcLibraryCodegen init; // To call grpc_init(). + grpc::GrpcLibraryCodegen init; // To call grpc_init(). if (token_lifetime_seconds <= 0) { gpr_log(GPR_ERROR, "Trying to create JWTCredentials with non-positive lifetime"); @@ -154,7 +154,7 @@ std::shared_ptr ServiceAccountJWTAccessCredentials( // Builds refresh token credentials. std::shared_ptr GoogleRefreshTokenCredentials( const grpc::string& json_refresh_token) { - GrpcLibraryCodegen init; // To call grpc_init(). + grpc::GrpcLibraryCodegen init; // To call grpc_init(). return WrapCallCredentials(grpc_google_refresh_token_credentials_create( json_refresh_token.c_str(), nullptr)); } @@ -162,7 +162,7 @@ std::shared_ptr GoogleRefreshTokenCredentials( // Builds access token credentials. std::shared_ptr AccessTokenCredentials( const grpc::string& access_token) { - GrpcLibraryCodegen init; // To call grpc_init(). + grpc::GrpcLibraryCodegen init; // To call grpc_init(). return WrapCallCredentials( grpc_access_token_credentials_create(access_token.c_str(), nullptr)); } @@ -171,7 +171,7 @@ std::shared_ptr AccessTokenCredentials( std::shared_ptr GoogleIAMCredentials( const grpc::string& authorization_token, const grpc::string& authority_selector) { - GrpcLibraryCodegen init; // To call grpc_init(). + grpc::GrpcLibraryCodegen init; // To call grpc_init(). return WrapCallCredentials(grpc_google_iam_credentials_create( authorization_token.c_str(), authority_selector.c_str(), nullptr)); } @@ -207,6 +207,23 @@ std::shared_ptr CompositeCallCredentials( return nullptr; } +std::shared_ptr MetadataCredentialsFromPlugin( + std::unique_ptr plugin) { + grpc::GrpcLibraryCodegen init; // To call grpc_init(). + const char* type = plugin->GetType(); + grpc::MetadataCredentialsPluginWrapper* wrapper = + new grpc::MetadataCredentialsPluginWrapper(std::move(plugin)); + grpc_metadata_credentials_plugin c_plugin = { + grpc::MetadataCredentialsPluginWrapper::GetMetadata, + grpc::MetadataCredentialsPluginWrapper::Destroy, wrapper, type}; + return WrapCallCredentials( + grpc_metadata_credentials_create_from_plugin(c_plugin, nullptr)); +} + +} // namespace grpc_impl + +namespace grpc { + void MetadataCredentialsPluginWrapper::Destroy(void* wrapper) { if (wrapper == nullptr) return; MetadataCredentialsPluginWrapper* w = @@ -261,10 +278,10 @@ void MetadataCredentialsPluginWrapper::InvokePlugin( grpc_status_code* status_code, const char** error_details) { std::multimap metadata; - // const_cast is safe since the SecureAuthContext does not take owndership and - // the object is passed as a const ref to plugin_->GetMetadata. + // const_cast is safe since the SecureAuthContext only inc/dec the refcount + // and the object is passed as a const ref to plugin_->GetMetadata. SecureAuthContext cpp_channel_auth_context( - const_cast(context.channel_auth_context), false); + const_cast(context.channel_auth_context)); Status status = plugin_->GetMetadata(context.service_url, context.method_name, cpp_channel_auth_context, &metadata); @@ -308,17 +325,4 @@ MetadataCredentialsPluginWrapper::MetadataCredentialsPluginWrapper( std::unique_ptr plugin) : thread_pool_(CreateDefaultThreadPool()), plugin_(std::move(plugin)) {} -std::shared_ptr MetadataCredentialsFromPlugin( - std::unique_ptr plugin) { - GrpcLibraryCodegen init; // To call grpc_init(). - const char* type = plugin->GetType(); - MetadataCredentialsPluginWrapper* wrapper = - new MetadataCredentialsPluginWrapper(std::move(plugin)); - grpc_metadata_credentials_plugin c_plugin = { - MetadataCredentialsPluginWrapper::GetMetadata, - MetadataCredentialsPluginWrapper::Destroy, wrapper, type}; - return WrapCallCredentials( - grpc_metadata_credentials_create_from_plugin(c_plugin, nullptr)); -} - } // namespace grpc diff --git a/src/cpp/client/secure_credentials.h b/src/cpp/client/secure_credentials.h index 613f1d6dc2c..c4eef6c746d 100644 --- a/src/cpp/client/secure_credentials.h +++ b/src/cpp/client/secure_credentials.h @@ -24,26 +24,31 @@ #include #include +#include "src/core/lib/security/credentials/credentials.h" #include "src/cpp/server/thread_pool_interface.h" -namespace grpc { +namespace grpc_impl { + +class Channel; class SecureChannelCredentials final : public ChannelCredentials { public: explicit SecureChannelCredentials(grpc_channel_credentials* c_creds); - ~SecureChannelCredentials() { grpc_channel_credentials_release(c_creds_); } + ~SecureChannelCredentials() { + if (c_creds_ != nullptr) c_creds_->Unref(); + } grpc_channel_credentials* GetRawCreds() { return c_creds_; } - std::shared_ptr CreateChannel( - const string& target, const grpc::ChannelArguments& args) override; + std::shared_ptr<::grpc::Channel> CreateChannelImpl( + const grpc::string& target, const grpc::ChannelArguments& args) override; SecureChannelCredentials* AsSecureCredentials() override { return this; } private: - std::shared_ptr CreateChannelWithInterceptors( - const string& target, const grpc::ChannelArguments& args, - std::vector< - std::unique_ptr> + std::shared_ptr<::grpc::Channel> CreateChannelWithInterceptors( + const grpc::string& target, const grpc::ChannelArguments& args, + std::vector> interceptor_creators) override; grpc_channel_credentials* const c_creds_; }; @@ -51,7 +56,9 @@ class SecureChannelCredentials final : public ChannelCredentials { class SecureCallCredentials final : public CallCredentials { public: explicit SecureCallCredentials(grpc_call_credentials* c_creds); - ~SecureCallCredentials() { grpc_call_credentials_release(c_creds_); } + ~SecureCallCredentials() { + if (c_creds_ != nullptr) c_creds_->Unref(); + } grpc_call_credentials* GetRawCreds() { return c_creds_; } bool ApplyToCall(grpc_call* call) override; @@ -61,6 +68,10 @@ class SecureCallCredentials final : public CallCredentials { grpc_call_credentials* const c_creds_; }; +} // namespace grpc_impl + +namespace grpc { + class MetadataCredentialsPluginWrapper final : private GrpcLibraryCodegen { public: static void Destroy(void* wrapper); diff --git a/src/cpp/codegen/codegen_init.cc b/src/cpp/codegen/codegen_init.cc index 684d7218b93..e1e47cbb17b 100644 --- a/src/cpp/codegen/codegen_init.cc +++ b/src/cpp/codegen/codegen_init.cc @@ -20,7 +20,7 @@ #include /// Null-initializes the global gRPC variables for the codegen library. These -/// stay null in the absence of of grpc++ library. In this case, no gRPC +/// stay null in the absence of grpc++ library. In this case, no gRPC /// features such as the ability to perform calls will be available. Trying to /// perform them would result in a segmentation fault when trying to deference /// the following nulled globals. These should be associated with actual diff --git a/src/cpp/common/alarm.cc b/src/cpp/common/alarm.cc index 5819a4210bd..dbec80cde4f 100644 --- a/src/cpp/common/alarm.cc +++ b/src/cpp/common/alarm.cc @@ -31,27 +31,23 @@ #include #include "src/core/lib/debug/trace.h" -namespace grpc { +namespace grpc_impl { namespace internal { -class AlarmImpl : public CompletionQueueTag { +class AlarmImpl : public ::grpc::internal::CompletionQueueTag { public: AlarmImpl() : cq_(nullptr), tag_(nullptr) { gpr_ref_init(&refs_, 1); grpc_timer_init_unset(&timer_); } - ~AlarmImpl() { - grpc_core::ExecCtx exec_ctx; - if (cq_ != nullptr) { - GRPC_CQ_INTERNAL_UNREF(cq_, "alarm"); - } - } + ~AlarmImpl() {} bool FinalizeResult(void** tag, bool* status) override { *tag = tag_; Unref(); return true; } - void Set(CompletionQueue* cq, gpr_timespec deadline, void* tag) { + void Set(::grpc::CompletionQueue* cq, gpr_timespec deadline, void* tag) { + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; grpc_core::ExecCtx exec_ctx; GRPC_CQ_INTERNAL_REF(cq->cq(), "alarm"); cq_ = cq->cq(); @@ -62,16 +58,22 @@ class AlarmImpl : public CompletionQueueTag { // queue the op on the completion queue AlarmImpl* alarm = static_cast(arg); alarm->Ref(); + // Preserve the cq and reset the cq_ so that the alarm + // can be reset when the alarm tag is delivered. + grpc_completion_queue* cq = alarm->cq_; + alarm->cq_ = nullptr; grpc_cq_end_op( - alarm->cq_, alarm, error, + cq, alarm, error, [](void* arg, grpc_cq_completion* completion) {}, arg, &alarm->completion_); + GRPC_CQ_INTERNAL_UNREF(cq, "alarm"); }, this, grpc_schedule_on_exec_ctx); grpc_timer_init(&timer_, grpc_timespec_to_millis_round_up(deadline), &on_alarm_); } void Set(gpr_timespec deadline, std::function f) { + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; grpc_core::ExecCtx exec_ctx; // Don't use any CQ at all. Instead just use the timer to fire the function callback_ = std::move(f); @@ -87,6 +89,7 @@ class AlarmImpl : public CompletionQueueTag { &on_alarm_); } void Cancel() { + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; grpc_core::ExecCtx exec_ctx; grpc_timer_cancel(&timer_); } @@ -114,13 +117,14 @@ class AlarmImpl : public CompletionQueueTag { }; } // namespace internal -static internal::GrpcLibraryInitializer g_gli_initializer; +static ::grpc::internal::GrpcLibraryInitializer g_gli_initializer; Alarm::Alarm() : alarm_(new internal::AlarmImpl()) { g_gli_initializer.summon(); } -void Alarm::SetInternal(CompletionQueue* cq, gpr_timespec deadline, void* tag) { +void Alarm::SetInternal(::grpc::CompletionQueue* cq, gpr_timespec deadline, + void* tag) { // Note that we know that alarm_ is actually an internal::AlarmImpl // but we declared it as the base pointer to avoid a forward declaration // or exposing core data structures in the C++ public headers. @@ -145,4 +149,4 @@ Alarm::~Alarm() { } void Alarm::Cancel() { static_cast(alarm_)->Cancel(); } -} // namespace grpc +} // namespace grpc_impl diff --git a/src/cpp/common/channel_arguments.cc b/src/cpp/common/channel_arguments.cc index 50ee9d871f0..932139890fe 100644 --- a/src/cpp/common/channel_arguments.cc +++ b/src/cpp/common/channel_arguments.cc @@ -27,11 +27,11 @@ #include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/iomgr/socket_mutator.h" -namespace grpc { +namespace grpc_impl { ChannelArguments::ChannelArguments() { // This will be ignored if used on the server side. - SetString(GRPC_ARG_PRIMARY_USER_AGENT_STRING, "grpc-c++/" + Version()); + SetString(GRPC_ARG_PRIMARY_USER_AGENT_STRING, "grpc-c++/" + grpc::Version()); } ChannelArguments::ChannelArguments(const ChannelArguments& other) @@ -106,7 +106,9 @@ void ChannelArguments::SetSocketMutator(grpc_socket_mutator* mutator) { } if (!replaced) { + strings_.push_back(grpc::string(mutator_arg.key)); args_.push_back(mutator_arg); + args_.back().key = const_cast(strings_.back().c_str()); } } @@ -141,7 +143,7 @@ void ChannelArguments::SetUserAgentPrefix( } void ChannelArguments::SetResourceQuota( - const grpc::ResourceQuota& resource_quota) { + const grpc_impl::ResourceQuota& resource_quota) { SetPointerWithVtable(GRPC_ARG_RESOURCE_QUOTA, resource_quota.c_resource_quota(), grpc_resource_quota_arg_vtable()); @@ -213,4 +215,4 @@ void ChannelArguments::SetChannelArgs(grpc_channel_args* channel_args) const { } } -} // namespace grpc +} // namespace grpc_impl diff --git a/src/cpp/common/channel_filter.h b/src/cpp/common/channel_filter.h index 5e569c97e68..1a3295fc80f 100644 --- a/src/cpp/common/channel_filter.h +++ b/src/cpp/common/channel_filter.h @@ -366,6 +366,11 @@ void ChannelFilterPluginShutdown(); /// The \a include_filter argument specifies a function that will be called /// to determine at run-time whether or not to add the filter. If the /// value is nullptr, the filter will be added unconditionally. +/// If the channel stack type is GRPC_CLIENT_SUBCHANNEL, the caller should +/// ensure that subchannels with different filter lists will always have +/// different channel args. This requires setting a channel arg in case the +/// registration function relies on some condition other than channel args to +/// decide whether to add a filter or not. template void RegisterChannelFilter( const char* name, grpc_channel_stack_type stack_type, int priority, diff --git a/src/cpp/common/completion_queue_cc.cc b/src/cpp/common/completion_queue_cc.cc index d93a54aed71..43c2eee96f8 100644 --- a/src/cpp/common/completion_queue_cc.cc +++ b/src/cpp/common/completion_queue_cc.cc @@ -24,9 +24,9 @@ #include #include -namespace grpc { +namespace grpc_impl { -static internal::GrpcLibraryInitializer g_gli_initializer; +static ::grpc::internal::GrpcLibraryInitializer g_gli_initializer; // 'CompletionQueue' constructor can safely call GrpcLibraryCodegen(false) here // i.e not have GrpcLibraryCodegen call grpc_init(). This is because, to create @@ -42,14 +42,6 @@ void CompletionQueue::Shutdown() { CompleteAvalanching(); } -void CompletionQueue::CompleteAvalanching() { - // Check if this was the last avalanching operation - if (gpr_atm_no_barrier_fetch_add(&avalanches_in_flight_, - static_cast(-1)) == 1) { - grpc_completion_queue_shutdown(cq_); - } -} - CompletionQueue::NextStatus CompletionQueue::AsyncNextInternal( void** tag, bool* ok, gpr_timespec deadline) { for (;;) { @@ -60,7 +52,8 @@ CompletionQueue::NextStatus CompletionQueue::AsyncNextInternal( case GRPC_QUEUE_SHUTDOWN: return SHUTDOWN; case GRPC_OP_COMPLETE: - auto core_cq_tag = static_cast(ev.tag); + auto core_cq_tag = + static_cast<::grpc::internal::CompletionQueueTag*>(ev.tag); *ok = ev.success != 0; *tag = core_cq_tag; if (core_cq_tag->FinalizeResult(tag, ok)) { @@ -87,7 +80,8 @@ bool CompletionQueue::CompletionQueueTLSCache::Flush(void** tag, bool* ok) { flushed_ = true; if (grpc_completion_queue_thread_local_cache_flush(cq_->cq_, &res_tag, &res)) { - auto core_cq_tag = static_cast(res_tag); + auto core_cq_tag = + static_cast<::grpc::internal::CompletionQueueTag*>(res_tag); *ok = res == 1; if (core_cq_tag->FinalizeResult(tag, ok)) { return true; @@ -96,4 +90,4 @@ bool CompletionQueue::CompletionQueueTLSCache::Flush(void** tag, bool* ok) { return false; } -} // namespace grpc +} // namespace grpc_impl diff --git a/src/cpp/common/core_codegen.cc b/src/cpp/common/core_codegen.cc index cfaa2e7b193..665305ca0a5 100644 --- a/src/cpp/common/core_codegen.cc +++ b/src/cpp/common/core_codegen.cc @@ -59,6 +59,10 @@ grpc_completion_queue* CoreCodegen::grpc_completion_queue_create_for_pluck( return ::grpc_completion_queue_create_for_pluck(reserved); } +void CoreCodegen::grpc_completion_queue_shutdown(grpc_completion_queue* cq) { + ::grpc_completion_queue_shutdown(cq); +} + void CoreCodegen::grpc_completion_queue_destroy(grpc_completion_queue* cq) { ::grpc_completion_queue_destroy(cq); } @@ -77,7 +81,7 @@ void CoreCodegen::gpr_free(void* p) { return ::gpr_free(p); } void CoreCodegen::grpc_init() { ::grpc_init(); } void CoreCodegen::grpc_shutdown() { ::grpc_shutdown(); } -void CoreCodegen::gpr_mu_init(gpr_mu* mu) { ::gpr_mu_init(mu); }; +void CoreCodegen::gpr_mu_init(gpr_mu* mu) { ::gpr_mu_init(mu); } void CoreCodegen::gpr_mu_destroy(gpr_mu* mu) { ::gpr_mu_destroy(mu); } void CoreCodegen::gpr_mu_lock(gpr_mu* mu) { ::gpr_mu_lock(mu); } void CoreCodegen::gpr_mu_unlock(gpr_mu* mu) { ::gpr_mu_unlock(mu); } @@ -135,6 +139,11 @@ int CoreCodegen::grpc_byte_buffer_reader_next(grpc_byte_buffer_reader* reader, return ::grpc_byte_buffer_reader_next(reader, slice); } +int CoreCodegen::grpc_byte_buffer_reader_peek(grpc_byte_buffer_reader* reader, + grpc_slice** slice) { + return ::grpc_byte_buffer_reader_peek(reader, slice); +} + grpc_byte_buffer* CoreCodegen::grpc_raw_byte_buffer_create(grpc_slice* slice, size_t nslices) { return ::grpc_raw_byte_buffer_create(slice, nslices); diff --git a/src/cpp/common/resource_quota_cc.cc b/src/cpp/common/resource_quota_cc.cc index 276e5f79548..4fab2975d89 100644 --- a/src/cpp/common/resource_quota_cc.cc +++ b/src/cpp/common/resource_quota_cc.cc @@ -19,7 +19,7 @@ #include #include -namespace grpc { +namespace grpc_impl { ResourceQuota::ResourceQuota() : impl_(grpc_resource_quota_create(nullptr)) {} @@ -37,4 +37,4 @@ ResourceQuota& ResourceQuota::SetMaxThreads(int new_max_threads) { grpc_resource_quota_set_max_threads(impl_, new_max_threads); return *this; } -} // namespace grpc +} // namespace grpc_impl diff --git a/src/cpp/common/secure_auth_context.cc b/src/cpp/common/secure_auth_context.cc index 1d66dd3d1f1..7a2b5afed69 100644 --- a/src/cpp/common/secure_auth_context.cc +++ b/src/cpp/common/secure_auth_context.cc @@ -22,19 +22,12 @@ namespace grpc { -SecureAuthContext::SecureAuthContext(grpc_auth_context* ctx, - bool take_ownership) - : ctx_(ctx), take_ownership_(take_ownership) {} - -SecureAuthContext::~SecureAuthContext() { - if (take_ownership_) grpc_auth_context_release(ctx_); -} - std::vector SecureAuthContext::GetPeerIdentity() const { - if (!ctx_) { + if (ctx_ == nullptr) { return std::vector(); } - grpc_auth_property_iterator iter = grpc_auth_context_peer_identity(ctx_); + grpc_auth_property_iterator iter = + grpc_auth_context_peer_identity(ctx_.get()); std::vector identity; const grpc_auth_property* property = nullptr; while ((property = grpc_auth_property_iterator_next(&iter))) { @@ -45,20 +38,20 @@ std::vector SecureAuthContext::GetPeerIdentity() const { } grpc::string SecureAuthContext::GetPeerIdentityPropertyName() const { - if (!ctx_) { + if (ctx_ == nullptr) { return ""; } - const char* name = grpc_auth_context_peer_identity_property_name(ctx_); + const char* name = grpc_auth_context_peer_identity_property_name(ctx_.get()); return name == nullptr ? "" : name; } std::vector SecureAuthContext::FindPropertyValues( const grpc::string& name) const { - if (!ctx_) { + if (ctx_ == nullptr) { return std::vector(); } grpc_auth_property_iterator iter = - grpc_auth_context_find_properties_by_name(ctx_, name.c_str()); + grpc_auth_context_find_properties_by_name(ctx_.get(), name.c_str()); const grpc_auth_property* property = nullptr; std::vector values; while ((property = grpc_auth_property_iterator_next(&iter))) { @@ -68,9 +61,9 @@ std::vector SecureAuthContext::FindPropertyValues( } AuthPropertyIterator SecureAuthContext::begin() const { - if (ctx_) { + if (ctx_ != nullptr) { grpc_auth_property_iterator iter = - grpc_auth_context_property_iterator(ctx_); + grpc_auth_context_property_iterator(ctx_.get()); const grpc_auth_property* property = grpc_auth_property_iterator_next(&iter); return AuthPropertyIterator(property, &iter); @@ -85,19 +78,20 @@ AuthPropertyIterator SecureAuthContext::end() const { void SecureAuthContext::AddProperty(const grpc::string& key, const grpc::string_ref& value) { - if (!ctx_) return; - grpc_auth_context_add_property(ctx_, key.c_str(), value.data(), value.size()); + if (ctx_ == nullptr) return; + grpc_auth_context_add_property(ctx_.get(), key.c_str(), value.data(), + value.size()); } bool SecureAuthContext::SetPeerIdentityPropertyName(const grpc::string& name) { - if (!ctx_) return false; - return grpc_auth_context_set_peer_identity_property_name(ctx_, + if (ctx_ == nullptr) return false; + return grpc_auth_context_set_peer_identity_property_name(ctx_.get(), name.c_str()) != 0; } bool SecureAuthContext::IsPeerAuthenticated() const { - if (!ctx_) return false; - return grpc_auth_context_peer_is_authenticated(ctx_) != 0; + if (ctx_ == nullptr) return false; + return grpc_auth_context_peer_is_authenticated(ctx_.get()) != 0; } } // namespace grpc diff --git a/src/cpp/common/secure_auth_context.h b/src/cpp/common/secure_auth_context.h index 142617959cb..2e8f7937211 100644 --- a/src/cpp/common/secure_auth_context.h +++ b/src/cpp/common/secure_auth_context.h @@ -21,15 +21,17 @@ #include -struct grpc_auth_context; +#include "src/core/lib/gprpp/ref_counted_ptr.h" +#include "src/core/lib/security/context/security_context.h" namespace grpc { class SecureAuthContext final : public AuthContext { public: - SecureAuthContext(grpc_auth_context* ctx, bool take_ownership); + explicit SecureAuthContext(grpc_auth_context* ctx) + : ctx_(ctx != nullptr ? ctx->Ref() : nullptr) {} - ~SecureAuthContext() override; + ~SecureAuthContext() override = default; bool IsPeerAuthenticated() const override; @@ -50,8 +52,7 @@ class SecureAuthContext final : public AuthContext { virtual bool SetPeerIdentityPropertyName(const grpc::string& name) override; private: - grpc_auth_context* ctx_; - bool take_ownership_; + grpc_core::RefCountedPtr ctx_; }; } // namespace grpc diff --git a/src/cpp/common/secure_channel_arguments.cc b/src/cpp/common/secure_channel_arguments.cc index 2fb8ea44fbc..e5d03cd2378 100644 --- a/src/cpp/common/secure_channel_arguments.cc +++ b/src/cpp/common/secure_channel_arguments.cc @@ -21,7 +21,7 @@ #include #include "src/core/lib/channel/channel_args.h" -namespace grpc { +namespace grpc_impl { void ChannelArguments::SetSslTargetNameOverride(const grpc::string& name) { SetString(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG, name); @@ -36,4 +36,4 @@ grpc::string ChannelArguments::GetSslTargetNameOverride() const { return ""; } -} // namespace grpc +} // namespace grpc_impl diff --git a/src/cpp/common/secure_create_auth_context.cc b/src/cpp/common/secure_create_auth_context.cc index bc1387c8d75..908c46629e6 100644 --- a/src/cpp/common/secure_create_auth_context.cc +++ b/src/cpp/common/secure_create_auth_context.cc @@ -20,6 +20,7 @@ #include #include #include +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/cpp/common/secure_auth_context.h" namespace grpc { @@ -28,8 +29,8 @@ std::shared_ptr CreateAuthContext(grpc_call* call) { if (call == nullptr) { return std::shared_ptr(); } - return std::shared_ptr( - new SecureAuthContext(grpc_call_auth_context(call), true)); + grpc_core::RefCountedPtr ctx(grpc_call_auth_context(call)); + return std::make_shared(ctx.get()); } } // namespace grpc diff --git a/src/cpp/common/version_cc.cc b/src/cpp/common/version_cc.cc index 8abd45efb77..76e2773e938 100644 --- a/src/cpp/common/version_cc.cc +++ b/src/cpp/common/version_cc.cc @@ -22,5 +22,5 @@ #include namespace grpc { -grpc::string Version() { return "1.17.0-dev"; } +grpc::string Version() { return "1.22.0-dev"; } } // namespace grpc diff --git a/src/cpp/ext/filters/census/context.cc b/src/cpp/ext/filters/census/context.cc index 78fc69a8054..160590353a7 100644 --- a/src/cpp/ext/filters/census/context.cc +++ b/src/cpp/ext/filters/census/context.cc @@ -28,6 +28,9 @@ using ::opencensus::trace::SpanContext; void GenerateServerContext(absl::string_view tracing, absl::string_view stats, absl::string_view primary_role, absl::string_view method, CensusContext* context) { + // Destruct the current CensusContext to free the Span memory before + // overwriting it below. + context->~CensusContext(); GrpcTraceContext trace_ctxt; if (TraceContextEncoding::Decode(tracing, &trace_ctxt) != TraceContextEncoding::kEncodeDecodeFailure) { @@ -42,6 +45,9 @@ void GenerateServerContext(absl::string_view tracing, absl::string_view stats, void GenerateClientContext(absl::string_view method, CensusContext* ctxt, CensusContext* parent_ctxt) { + // Destruct the current CensusContext to free the Span memory before + // overwriting it below. + ctxt->~CensusContext(); if (parent_ctxt != nullptr) { SpanContext span_ctxt = parent_ctxt->Context(); Span span = parent_ctxt->Span(); diff --git a/src/cpp/ext/filters/census/grpc_plugin.cc b/src/cpp/ext/filters/census/grpc_plugin.cc index f978ed3bf51..c5018f0673a 100644 --- a/src/cpp/ext/filters/census/grpc_plugin.cc +++ b/src/cpp/ext/filters/census/grpc_plugin.cc @@ -30,35 +30,6 @@ namespace grpc { -void RegisterOpenCensusPlugin() { - RegisterChannelFilter( - "opencensus_client", GRPC_CLIENT_CHANNEL, INT_MAX /* priority */, - nullptr /* condition function */); - RegisterChannelFilter( - "opencensus_server", GRPC_SERVER_CHANNEL, INT_MAX /* priority */, - nullptr /* condition function */); - - // Access measures to ensure they are initialized. Otherwise, creating a view - // before the first RPC would cause an error. - RpcClientSentBytesPerRpc(); - RpcClientReceivedBytesPerRpc(); - RpcClientRoundtripLatency(); - RpcClientServerLatency(); - RpcClientSentMessagesPerRpc(); - RpcClientReceivedMessagesPerRpc(); - - RpcServerSentBytesPerRpc(); - RpcServerReceivedBytesPerRpc(); - RpcServerServerLatency(); - RpcServerSentMessagesPerRpc(); - RpcServerReceivedMessagesPerRpc(); -} - -::opencensus::trace::Span GetSpanFromServerContext(ServerContext* context) { - return reinterpret_cast(context->census_context()) - ->Span(); -} - // These measure definitions should be kept in sync across opencensus // implementations--see // https://github.com/census-instrumentation/opencensus-java/blob/master/contrib/grpc_metrics/src/main/java/io/opencensus/contrib/grpc/metrics/RpcMeasureConstants.java. @@ -126,5 +97,39 @@ ABSL_CONST_INIT const absl::string_view ABSL_CONST_INIT const absl::string_view kRpcServerServerLatencyMeasureName = "grpc.io/server/server_latency"; - } // namespace grpc +namespace grpc_impl { + +void RegisterOpenCensusPlugin() { + grpc::RegisterChannelFilter( + "opencensus_client", GRPC_CLIENT_CHANNEL, INT_MAX /* priority */, + nullptr /* condition function */); + grpc::RegisterChannelFilter( + "opencensus_server", GRPC_SERVER_CHANNEL, INT_MAX /* priority */, + nullptr /* condition function */); + + // Access measures to ensure they are initialized. Otherwise, creating a view + // before the first RPC would cause an error. + grpc::RpcClientSentBytesPerRpc(); + grpc::RpcClientReceivedBytesPerRpc(); + grpc::RpcClientRoundtripLatency(); + grpc::RpcClientServerLatency(); + grpc::RpcClientSentMessagesPerRpc(); + grpc::RpcClientReceivedMessagesPerRpc(); + + grpc::RpcServerSentBytesPerRpc(); + grpc::RpcServerReceivedBytesPerRpc(); + grpc::RpcServerServerLatency(); + grpc::RpcServerSentMessagesPerRpc(); + grpc::RpcServerReceivedMessagesPerRpc(); +} + +::opencensus::trace::Span GetSpanFromServerContext( + grpc::ServerContext* context) { + return reinterpret_cast(context->census_context()) + ->Span(); +} + +} // namespace grpc_impl diff --git a/src/cpp/ext/filters/census/grpc_plugin.h b/src/cpp/ext/filters/census/grpc_plugin.h index 9e319cb994e..993faae0a94 100644 --- a/src/cpp/ext/filters/census/grpc_plugin.h +++ b/src/cpp/ext/filters/census/grpc_plugin.h @@ -26,7 +26,6 @@ #include "opencensus/stats/stats.h" namespace grpc { - class ServerContext; // The tag keys set when recording RPC stats. diff --git a/src/cpp/ext/filters/census/views.cc b/src/cpp/ext/filters/census/views.cc index 2c0c5f72950..d7e3c81a955 100644 --- a/src/cpp/ext/filters/census/views.cc +++ b/src/cpp/ext/filters/census/views.cc @@ -25,6 +25,23 @@ #include "opencensus/stats/internal/set_aggregation_window.h" #include "opencensus/stats/stats.h" +namespace grpc_impl { + +void RegisterOpenCensusViewsForExport() { + grpc::ClientSentMessagesPerRpcCumulative().RegisterForExport(); + grpc::ClientSentBytesPerRpcCumulative().RegisterForExport(); + grpc::ClientReceivedMessagesPerRpcCumulative().RegisterForExport(); + grpc::ClientReceivedBytesPerRpcCumulative().RegisterForExport(); + grpc::ClientRoundtripLatencyCumulative().RegisterForExport(); + grpc::ClientServerLatencyCumulative().RegisterForExport(); + + grpc::ServerSentMessagesPerRpcCumulative().RegisterForExport(); + grpc::ServerSentBytesPerRpcCumulative().RegisterForExport(); + grpc::ServerReceivedMessagesPerRpcCumulative().RegisterForExport(); + grpc::ServerReceivedBytesPerRpcCumulative().RegisterForExport(); + grpc::ServerServerLatencyCumulative().RegisterForExport(); +} +} // namespace grpc_impl namespace grpc { using ::opencensus::stats::Aggregation; @@ -71,21 +88,6 @@ ViewDescriptor HourDescriptor() { } // namespace -void RegisterOpenCensusViewsForExport() { - ClientSentMessagesPerRpcCumulative().RegisterForExport(); - ClientSentBytesPerRpcCumulative().RegisterForExport(); - ClientReceivedMessagesPerRpcCumulative().RegisterForExport(); - ClientReceivedBytesPerRpcCumulative().RegisterForExport(); - ClientRoundtripLatencyCumulative().RegisterForExport(); - ClientServerLatencyCumulative().RegisterForExport(); - - ServerSentMessagesPerRpcCumulative().RegisterForExport(); - ServerSentBytesPerRpcCumulative().RegisterForExport(); - ServerReceivedMessagesPerRpcCumulative().RegisterForExport(); - ServerReceivedBytesPerRpcCumulative().RegisterForExport(); - ServerServerLatencyCumulative().RegisterForExport(); -} - // client cumulative const ViewDescriptor& ClientSentBytesPerRpcCumulative() { const static ViewDescriptor descriptor = diff --git a/src/cpp/ext/proto_server_reflection_plugin.cc b/src/cpp/ext/proto_server_reflection_plugin.cc index ee3ac3fee88..0ac4cb80c64 100644 --- a/src/cpp/ext/proto_server_reflection_plugin.cc +++ b/src/cpp/ext/proto_server_reflection_plugin.cc @@ -23,7 +23,7 @@ #include "src/cpp/ext/proto_server_reflection.h" -namespace grpc { +namespace grpc_impl { namespace reflection { ProtoServerReflectionPlugin::ProtoServerReflectionPlugin() @@ -79,4 +79,4 @@ struct StaticProtoReflectionPluginInitializer { } static_proto_reflection_plugin_initializer; } // namespace reflection -} // namespace grpc +} // namespace grpc_impl diff --git a/src/cpp/server/channelz/channelz_service.cc b/src/cpp/server/channelz/channelz_service.cc index 9ecb9de7e4b..0409991fe67 100644 --- a/src/cpp/server/channelz/channelz_service.cc +++ b/src/cpp/server/channelz/channelz_service.cc @@ -24,6 +24,12 @@ #include namespace grpc { +grpc::protobuf::util::Status ParseJson(const char* json_str, + grpc::protobuf::Message* message) { + grpc::protobuf::json::JsonParseOptions options; + options.case_insensitive_enum_parsing = true; + return grpc::protobuf::json::JsonStringToMessage(json_str, message, options); +} Status ChannelzService::GetTopChannels( ServerContext* unused, const channelz::v1::GetTopChannelsRequest* request, @@ -33,8 +39,7 @@ Status ChannelzService::GetTopChannels( return Status(StatusCode::INTERNAL, "grpc_channelz_get_top_channels returned null"); } - grpc::protobuf::util::Status s = - grpc::protobuf::json::JsonStringToMessage(json_str, response); + grpc::protobuf::util::Status s = ParseJson(json_str, response); gpr_free(json_str); if (!s.ok()) { return Status(StatusCode::INTERNAL, s.ToString()); @@ -50,8 +55,7 @@ Status ChannelzService::GetServers( return Status(StatusCode::INTERNAL, "grpc_channelz_get_servers returned null"); } - grpc::protobuf::util::Status s = - grpc::protobuf::json::JsonStringToMessage(json_str, response); + grpc::protobuf::util::Status s = ParseJson(json_str, response); gpr_free(json_str); if (!s.ok()) { return Status(StatusCode::INTERNAL, s.ToString()); @@ -67,8 +71,7 @@ Status ChannelzService::GetServer(ServerContext* unused, return Status(StatusCode::INTERNAL, "grpc_channelz_get_server returned null"); } - grpc::protobuf::util::Status s = - grpc::protobuf::json::JsonStringToMessage(json_str, response); + grpc::protobuf::util::Status s = ParseJson(json_str, response); gpr_free(json_str); if (!s.ok()) { return Status(StatusCode::INTERNAL, s.ToString()); @@ -79,14 +82,13 @@ Status ChannelzService::GetServer(ServerContext* unused, Status ChannelzService::GetServerSockets( ServerContext* unused, const channelz::v1::GetServerSocketsRequest* request, channelz::v1::GetServerSocketsResponse* response) { - char* json_str = grpc_channelz_get_server_sockets(request->server_id(), - request->start_socket_id()); + char* json_str = grpc_channelz_get_server_sockets( + request->server_id(), request->start_socket_id(), request->max_results()); if (json_str == nullptr) { return Status(StatusCode::INTERNAL, "grpc_channelz_get_server_sockets returned null"); } - grpc::protobuf::util::Status s = - grpc::protobuf::json::JsonStringToMessage(json_str, response); + grpc::protobuf::util::Status s = ParseJson(json_str, response); gpr_free(json_str); if (!s.ok()) { return Status(StatusCode::INTERNAL, s.ToString()); @@ -101,8 +103,7 @@ Status ChannelzService::GetChannel( if (json_str == nullptr) { return Status(StatusCode::NOT_FOUND, "No object found for that ChannelId"); } - grpc::protobuf::util::Status s = - grpc::protobuf::json::JsonStringToMessage(json_str, response); + grpc::protobuf::util::Status s = ParseJson(json_str, response); gpr_free(json_str); if (!s.ok()) { return Status(StatusCode::INTERNAL, s.ToString()); @@ -118,8 +119,7 @@ Status ChannelzService::GetSubchannel( return Status(StatusCode::NOT_FOUND, "No object found for that SubchannelId"); } - grpc::protobuf::util::Status s = - grpc::protobuf::json::JsonStringToMessage(json_str, response); + grpc::protobuf::util::Status s = ParseJson(json_str, response); gpr_free(json_str); if (!s.ok()) { return Status(StatusCode::INTERNAL, s.ToString()); @@ -134,8 +134,7 @@ Status ChannelzService::GetSocket(ServerContext* unused, if (json_str == nullptr) { return Status(StatusCode::NOT_FOUND, "No object found for that SocketId"); } - grpc::protobuf::util::Status s = - grpc::protobuf::json::JsonStringToMessage(json_str, response); + grpc::protobuf::util::Status s = ParseJson(json_str, response); gpr_free(json_str); if (!s.ok()) { return Status(StatusCode::INTERNAL, s.ToString()); diff --git a/src/cpp/server/channelz/channelz_service_plugin.cc b/src/cpp/server/channelz/channelz_service_plugin.cc index b93e5b551e1..04c6411d5a3 100644 --- a/src/cpp/server/channelz/channelz_service_plugin.cc +++ b/src/cpp/server/channelz/channelz_service_plugin.cc @@ -67,13 +67,21 @@ CreateChannelzServicePlugin() { new ChannelzServicePlugin()); } +} // namespace experimental +} // namespace channelz +} // namespace grpc +namespace grpc_impl { +namespace channelz { +namespace experimental { + void InitChannelzService() { static bool already_here = false; if (already_here) return; already_here = true; - ::grpc::ServerBuilder::InternalAddPluginFactory(&CreateChannelzServicePlugin); + ::grpc::ServerBuilder::InternalAddPluginFactory( + &grpc::channelz::experimental::CreateChannelzServicePlugin); } } // namespace experimental } // namespace channelz -} // namespace grpc +} // namespace grpc_impl diff --git a/src/cpp/server/dynamic_thread_pool.cc b/src/cpp/server/dynamic_thread_pool.cc index ef99d6459f7..c8bdbdea7e6 100644 --- a/src/cpp/server/dynamic_thread_pool.cc +++ b/src/cpp/server/dynamic_thread_pool.cc @@ -21,6 +21,7 @@ #include #include +#include #include "src/core/lib/gprpp/thd.h" @@ -40,27 +41,27 @@ DynamicThreadPool::DynamicThread::~DynamicThread() { thd_.Join(); } void DynamicThreadPool::DynamicThread::ThreadFunc() { pool_->ThreadFunc(); // Now that we have killed ourselves, we should reduce the thread count - std::unique_lock lock(pool_->mu_); + grpc_core::MutexLock lock(&pool_->mu_); pool_->nthreads_--; // Move ourselves to dead list pool_->dead_threads_.push_back(this); if ((pool_->shutdown_) && (pool_->nthreads_ == 0)) { - pool_->shutdown_cv_.notify_one(); + pool_->shutdown_cv_.Signal(); } } void DynamicThreadPool::ThreadFunc() { for (;;) { // Wait until work is available or we are shutting down. - std::unique_lock lock(mu_); + grpc_core::ReleasableMutexLock lock(&mu_); if (!shutdown_ && callbacks_.empty()) { // If there are too many threads waiting, then quit this thread if (threads_waiting_ >= reserve_threads_) { break; } threads_waiting_++; - cv_.wait(lock); + cv_.Wait(&mu_); threads_waiting_--; } // Drain callbacks before considering shutdown to ensure all work @@ -68,7 +69,7 @@ void DynamicThreadPool::ThreadFunc() { if (!callbacks_.empty()) { auto cb = callbacks_.front(); callbacks_.pop(); - lock.unlock(); + lock.Unlock(); cb(); } else if (shutdown_) { break; @@ -82,7 +83,7 @@ DynamicThreadPool::DynamicThreadPool(int reserve_threads) nthreads_(0), threads_waiting_(0) { for (int i = 0; i < reserve_threads_; i++) { - std::lock_guard lock(mu_); + grpc_core::MutexLock lock(&mu_); nthreads_++; new DynamicThread(this); } @@ -95,17 +96,17 @@ void DynamicThreadPool::ReapThreads(std::list* tlist) { } DynamicThreadPool::~DynamicThreadPool() { - std::unique_lock lock(mu_); + grpc_core::MutexLock lock(&mu_); shutdown_ = true; - cv_.notify_all(); + cv_.Broadcast(); while (nthreads_ != 0) { - shutdown_cv_.wait(lock); + shutdown_cv_.Wait(&mu_); } ReapThreads(&dead_threads_); } void DynamicThreadPool::Add(const std::function& callback) { - std::lock_guard lock(mu_); + grpc_core::MutexLock lock(&mu_); // Add works to the callbacks list callbacks_.push(callback); // Increase pool size or notify as needed @@ -114,7 +115,7 @@ void DynamicThreadPool::Add(const std::function& callback) { nthreads_++; new DynamicThread(this); } else { - cv_.notify_one(); + cv_.Signal(); } // Also use this chance to harvest dead threads if (!dead_threads_.empty()) { diff --git a/src/cpp/server/dynamic_thread_pool.h b/src/cpp/server/dynamic_thread_pool.h index 5df8cf2b043..4ae0257d40b 100644 --- a/src/cpp/server/dynamic_thread_pool.h +++ b/src/cpp/server/dynamic_thread_pool.h @@ -27,6 +27,7 @@ #include +#include "src/core/lib/gprpp/sync.h" #include "src/core/lib/gprpp/thd.h" #include "src/cpp/server/thread_pool_interface.h" @@ -50,9 +51,9 @@ class DynamicThreadPool final : public ThreadPoolInterface { grpc_core::Thread thd_; void ThreadFunc(); }; - std::mutex mu_; - std::condition_variable cv_; - std::condition_variable shutdown_cv_; + grpc_core::Mutex mu_; + grpc_core::CondVar cv_; + grpc_core::CondVar shutdown_cv_; bool shutdown_; std::queue> callbacks_; int reserve_threads_; diff --git a/src/cpp/server/health/default_health_check_service.cc b/src/cpp/server/health/default_health_check_service.cc index c951c69d513..01bc51aa213 100644 --- a/src/cpp/server/health/default_health_check_service.cc +++ b/src/cpp/server/health/default_health_check_service.cc @@ -41,23 +41,42 @@ DefaultHealthCheckService::DefaultHealthCheckService() { void DefaultHealthCheckService::SetServingStatus( const grpc::string& service_name, bool serving) { - std::unique_lock lock(mu_); + grpc_core::MutexLock lock(&mu_); + if (shutdown_) { + // Set to NOT_SERVING in case service_name is not in the map. + serving = false; + } services_map_[service_name].SetServingStatus(serving ? SERVING : NOT_SERVING); } void DefaultHealthCheckService::SetServingStatus(bool serving) { const ServingStatus status = serving ? SERVING : NOT_SERVING; - std::unique_lock lock(mu_); + grpc_core::MutexLock lock(&mu_); + if (shutdown_) { + return; + } for (auto& p : services_map_) { ServiceData& service_data = p.second; service_data.SetServingStatus(status); } } +void DefaultHealthCheckService::Shutdown() { + grpc_core::MutexLock lock(&mu_); + if (shutdown_) { + return; + } + shutdown_ = true; + for (auto& p : services_map_) { + ServiceData& service_data = p.second; + service_data.SetServingStatus(NOT_SERVING); + } +} + DefaultHealthCheckService::ServingStatus DefaultHealthCheckService::GetServingStatus( const grpc::string& service_name) const { - std::lock_guard lock(mu_); + grpc_core::MutexLock lock(&mu_); auto it = services_map_.find(service_name); if (it == services_map_.end()) { return NOT_FOUND; @@ -69,7 +88,7 @@ DefaultHealthCheckService::GetServingStatus( void DefaultHealthCheckService::RegisterCallHandler( const grpc::string& service_name, std::shared_ptr handler) { - std::unique_lock lock(mu_); + grpc_core::MutexLock lock(&mu_); ServiceData& service_data = services_map_[service_name]; service_data.AddCallHandler(handler /* copies ref */); HealthCheckServiceImpl::CallHandler* h = handler.get(); @@ -79,7 +98,7 @@ void DefaultHealthCheckService::RegisterCallHandler( void DefaultHealthCheckService::UnregisterCallHandler( const grpc::string& service_name, const std::shared_ptr& handler) { - std::unique_lock lock(mu_); + grpc_core::MutexLock lock(&mu_); auto it = services_map_.find(service_name); if (it == services_map_.end()) return; ServiceData& service_data = it->second; @@ -147,7 +166,7 @@ DefaultHealthCheckService::HealthCheckServiceImpl::~HealthCheckServiceImpl() { // We will reach here after the server starts shutting down. shutdown_ = true; { - std::unique_lock lock(cq_shutdown_mu_); + grpc_core::MutexLock lock(&cq_shutdown_mu_); cq_->Shutdown(); } thread_->Join(); @@ -247,7 +266,7 @@ void DefaultHealthCheckService::HealthCheckServiceImpl::CheckCallHandler:: std::make_shared(cq, database, service); CheckCallHandler* handler = static_cast(self.get()); { - std::unique_lock lock(service->cq_shutdown_mu_); + grpc_core::MutexLock lock(&service->cq_shutdown_mu_); if (service->shutdown_) return; // Request a Check() call. handler->next_ = @@ -292,7 +311,7 @@ void DefaultHealthCheckService::HealthCheckServiceImpl::CheckCallHandler:: } // Send response. { - std::unique_lock lock(service_->cq_shutdown_mu_); + grpc_core::MutexLock lock(&service_->cq_shutdown_mu_); if (!service_->shutdown_) { next_ = CallableTag(std::bind(&CheckCallHandler::OnFinishDone, this, @@ -328,7 +347,7 @@ void DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: std::make_shared(cq, database, service); WatchCallHandler* handler = static_cast(self.get()); { - std::unique_lock lock(service->cq_shutdown_mu_); + grpc_core::MutexLock lock(&service->cq_shutdown_mu_); if (service->shutdown_) return; // Request AsyncNotifyWhenDone(). handler->on_done_notified_ = @@ -383,7 +402,7 @@ void DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: void DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: SendHealth(std::shared_ptr self, ServingStatus status) { - std::unique_lock lock(send_mu_); + grpc_core::MutexLock lock(&send_mu_); // If there's already a send in flight, cache the new status, and // we'll start a new send for it when the one in flight completes. if (send_in_flight_) { @@ -401,7 +420,7 @@ void DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: ByteBuffer response; bool success = service_->EncodeResponse(status, &response); // Grab shutdown lock and send response. - std::unique_lock cq_lock(service_->cq_shutdown_mu_); + grpc_core::MutexLock cq_lock(&service_->cq_shutdown_mu_); if (service_->shutdown_) { SendFinishLocked(std::move(self), Status::CANCELLED); return; @@ -423,7 +442,7 @@ void DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: SendFinish(std::move(self), Status::CANCELLED); return; } - std::unique_lock lock(send_mu_); + grpc_core::MutexLock lock(&send_mu_); send_in_flight_ = false; // If we got a new status since we started the last send, start a // new send for it. @@ -437,7 +456,7 @@ void DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: void DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: SendFinish(std::shared_ptr self, const Status& status) { if (finish_called_) return; - std::unique_lock cq_lock(service_->cq_shutdown_mu_); + grpc_core::MutexLock cq_lock(&service_->cq_shutdown_mu_); if (service_->shutdown_) return; SendFinishLocked(std::move(self), status); } diff --git a/src/cpp/server/health/default_health_check_service.h b/src/cpp/server/health/default_health_check_service.h index 450bd543f55..4b926efdfe8 100644 --- a/src/cpp/server/health/default_health_check_service.h +++ b/src/cpp/server/health/default_health_check_service.h @@ -31,6 +31,7 @@ #include #include +#include "src/core/lib/gprpp/sync.h" #include "src/core/lib/gprpp/thd.h" namespace grpc { @@ -197,7 +198,7 @@ class DefaultHealthCheckService final : public HealthCheckServiceInterface { GenericServerAsyncWriter stream_; ServerContext ctx_; - std::mutex send_mu_; + grpc_core::Mutex send_mu_; bool send_in_flight_ = false; // Guarded by mu_. ServingStatus pending_status_ = NOT_FOUND; // Guarded by mu_. @@ -226,7 +227,7 @@ class DefaultHealthCheckService final : public HealthCheckServiceInterface { // To synchronize the operations related to shutdown state of cq_, so that // we don't enqueue new tags into cq_ after it is already shut down. - std::mutex cq_shutdown_mu_; + grpc_core::Mutex cq_shutdown_mu_; std::atomic_bool shutdown_{false}; std::unique_ptr<::grpc_core::Thread> thread_; }; @@ -237,6 +238,8 @@ class DefaultHealthCheckService final : public HealthCheckServiceInterface { bool serving) override; void SetServingStatus(bool serving) override; + void Shutdown() override; + ServingStatus GetServingStatus(const grpc::string& service_name) const; HealthCheckServiceImpl* GetHealthCheckService( @@ -271,7 +274,8 @@ class DefaultHealthCheckService final : public HealthCheckServiceInterface { const grpc::string& service_name, const std::shared_ptr& handler); - mutable std::mutex mu_; + mutable grpc_core::Mutex mu_; + bool shutdown_ = false; // Guarded by mu_. std::map services_map_; // Guarded by mu_. std::unique_ptr impl_; }; diff --git a/src/cpp/server/health/health_check_service.cc b/src/cpp/server/health/health_check_service.cc index a0fa2d62f58..ca0b49a1ae8 100644 --- a/src/cpp/server/health/health_check_service.cc +++ b/src/cpp/server/health/health_check_service.cc @@ -16,9 +16,9 @@ * */ -#include +#include -namespace grpc { +namespace grpc_impl { namespace { bool g_grpc_default_health_check_service_enabled = false; } // namespace @@ -31,4 +31,4 @@ void EnableDefaultHealthCheckService(bool enable) { g_grpc_default_health_check_service_enabled = enable; } -} // namespace grpc +} // namespace grpc_impl diff --git a/src/cpp/server/insecure_server_credentials.cc b/src/cpp/server/insecure_server_credentials.cc index 7d749ddca4d..e4623ececef 100644 --- a/src/cpp/server/insecure_server_credentials.cc +++ b/src/cpp/server/insecure_server_credentials.cc @@ -21,7 +21,7 @@ #include #include -namespace grpc { +namespace grpc_impl { namespace { class InsecureServerCredentialsImpl final : public ServerCredentials { public: @@ -29,7 +29,7 @@ class InsecureServerCredentialsImpl final : public ServerCredentials { return grpc_server_add_insecure_http2_port(server, addr.c_str()); } void SetAuthMetadataProcessor( - const std::shared_ptr& processor) override { + const std::shared_ptr& processor) override { (void)processor; GPR_ASSERT(0); // Should not be called on InsecureServerCredentials. } @@ -41,4 +41,4 @@ std::shared_ptr InsecureServerCredentials() { new InsecureServerCredentialsImpl()); } -} // namespace grpc +} // namespace grpc_impl diff --git a/src/cpp/server/load_reporter/get_cpu_stats_linux.cc b/src/cpp/server/load_reporter/get_cpu_stats_linux.cc index 9c1fd0cd0b8..561d4f50482 100644 --- a/src/cpp/server/load_reporter/get_cpu_stats_linux.cc +++ b/src/cpp/server/load_reporter/get_cpu_stats_linux.cc @@ -32,7 +32,10 @@ std::pair GetCpuStatsImpl() { FILE* fp; fp = fopen("/proc/stat", "r"); uint64_t user, nice, system, idle; - fscanf(fp, "cpu %lu %lu %lu %lu", &user, &nice, &system, &idle); + if (fscanf(fp, "cpu %lu %lu %lu %lu", &user, &nice, &system, &idle) != 4) { + // Something bad happened with the information, so assume it's all invalid + user = nice = system = idle = 0; + } fclose(fp); busy = user + nice + system; total = busy + idle; diff --git a/src/cpp/server/load_reporter/load_reporter.cc b/src/cpp/server/load_reporter/load_reporter.cc index 464063a13ff..422ea62efd5 100644 --- a/src/cpp/server/load_reporter/load_reporter.cc +++ b/src/cpp/server/load_reporter/load_reporter.cc @@ -239,7 +239,7 @@ grpc::string LoadReporter::GenerateLbId() { ::grpc::lb::v1::LoadBalancingFeedback LoadReporter::GenerateLoadBalancingFeedback() { - std::unique_lock lock(feedback_mu_); + grpc_core::ReleasableMutexLock lock(&feedback_mu_); auto now = std::chrono::system_clock::now(); // Discard records outside the window until there is only one record // outside the window, which is used as the base for difference. @@ -277,7 +277,7 @@ LoadReporter::GenerateLoadBalancingFeedback() { double cpu_limit = newest->cpu_limit - oldest->cpu_limit; std::chrono::duration duration_seconds = newest->end_time - oldest->end_time; - lock.unlock(); + lock.Unlock(); ::grpc::lb::v1::LoadBalancingFeedback feedback; feedback.set_server_utilization(static_cast(cpu_usage / cpu_limit)); feedback.set_calls_per_second( @@ -290,7 +290,7 @@ LoadReporter::GenerateLoadBalancingFeedback() { ::google::protobuf::RepeatedPtrField<::grpc::lb::v1::Load> LoadReporter::GenerateLoads(const grpc::string& hostname, const grpc::string& lb_id) { - std::lock_guard lock(store_mu_); + grpc_core::MutexLock lock(&store_mu_); auto assigned_stores = load_data_store_.GetAssignedStores(hostname, lb_id); GPR_ASSERT(assigned_stores != nullptr); GPR_ASSERT(!assigned_stores->empty()); @@ -371,7 +371,7 @@ void LoadReporter::AppendNewFeedbackRecord(uint64_t rpcs, uint64_t errors) { // This will make the load balancing feedback generation a no-op. cpu_stats = {0, 0}; } - std::unique_lock lock(feedback_mu_); + grpc_core::MutexLock lock(&feedback_mu_); feedback_records_.emplace_back(std::chrono::system_clock::now(), rpcs, errors, cpu_stats.first, cpu_stats.second); } @@ -379,7 +379,7 @@ void LoadReporter::AppendNewFeedbackRecord(uint64_t rpcs, uint64_t errors) { void LoadReporter::ReportStreamCreated(const grpc::string& hostname, const grpc::string& lb_id, const grpc::string& load_key) { - std::lock_guard lock(store_mu_); + grpc_core::MutexLock lock(&store_mu_); load_data_store_.ReportStreamCreated(hostname, lb_id, load_key); gpr_log(GPR_INFO, "[LR %p] Report stream created (host: %s, LB ID: %s, load key: %s).", @@ -388,7 +388,7 @@ void LoadReporter::ReportStreamCreated(const grpc::string& hostname, void LoadReporter::ReportStreamClosed(const grpc::string& hostname, const grpc::string& lb_id) { - std::lock_guard lock(store_mu_); + grpc_core::MutexLock lock(&store_mu_); load_data_store_.ReportStreamClosed(hostname, lb_id); gpr_log(GPR_INFO, "[LR %p] Report stream closed (host: %s, LB ID: %s).", this, hostname.c_str(), lb_id.c_str()); @@ -407,7 +407,7 @@ void LoadReporter::ProcessViewDataCallStart( LoadRecordKey key(client_ip_and_token, user_id); LoadRecordValue value = LoadRecordValue(start_count); { - std::unique_lock lock(store_mu_); + grpc_core::MutexLock lock(&store_mu_); load_data_store_.MergeRow(host, key, value); } } @@ -459,7 +459,7 @@ void LoadReporter::ProcessViewDataCallEnd( LoadRecordValue value = LoadRecordValue( 0, ok_count, error_count, bytes_sent, bytes_received, latency_ms); { - std::unique_lock lock(store_mu_); + grpc_core::MutexLock lock(&store_mu_); load_data_store_.MergeRow(host, key, value); } } @@ -486,7 +486,7 @@ void LoadReporter::ProcessViewDataOtherCallMetrics( LoadRecordValue value = LoadRecordValue( metric_name, static_cast(num_calls), total_metric_value); { - std::unique_lock lock(store_mu_); + grpc_core::MutexLock lock(&store_mu_); load_data_store_.MergeRow(host, key, value); } } diff --git a/src/cpp/server/load_reporter/load_reporter.h b/src/cpp/server/load_reporter/load_reporter.h index b2254d56016..766e02a407a 100644 --- a/src/cpp/server/load_reporter/load_reporter.h +++ b/src/cpp/server/load_reporter/load_reporter.h @@ -29,6 +29,7 @@ #include #include +#include "src/core/lib/gprpp/sync.h" #include "src/cpp/server/load_reporter/load_data_store.h" #include "src/proto/grpc/lb/v1/load_reporter.grpc.pb.h" @@ -212,11 +213,11 @@ class LoadReporter { std::atomic next_lb_id_{0}; const std::chrono::seconds feedback_sample_window_seconds_; - std::mutex feedback_mu_; + grpc_core::Mutex feedback_mu_; std::deque feedback_records_; // TODO(juanlishen): Lock in finer grain. Locking the whole store may be // too expensive. - std::mutex store_mu_; + grpc_core::Mutex store_mu_; LoadDataStore load_data_store_; std::unique_ptr census_view_provider_; std::unique_ptr cpu_stats_provider_; diff --git a/src/cpp/server/load_reporter/load_reporter_async_service_impl.cc b/src/cpp/server/load_reporter/load_reporter_async_service_impl.cc index d001199b8c5..9eaab5d6366 100644 --- a/src/cpp/server/load_reporter/load_reporter_async_service_impl.cc +++ b/src/cpp/server/load_reporter/load_reporter_async_service_impl.cc @@ -48,7 +48,7 @@ LoadReporterAsyncServiceImpl::~LoadReporterAsyncServiceImpl() { // We will reach here after the server starts shutting down. shutdown_ = true; { - std::unique_lock lock(cq_shutdown_mu_); + grpc_core::MutexLock lock(&cq_shutdown_mu_); cq_->Shutdown(); } if (next_fetch_and_sample_alarm_ != nullptr) @@ -62,7 +62,7 @@ void LoadReporterAsyncServiceImpl::ScheduleNextFetchAndSample() { gpr_time_from_millis(kFetchAndSampleIntervalSeconds * 1000, GPR_TIMESPAN)); { - std::unique_lock lock(cq_shutdown_mu_); + grpc_core::MutexLock lock(&cq_shutdown_mu_); if (shutdown_) return; // TODO(juanlishen): Improve the Alarm implementation to reuse a single // instance for multiple events. @@ -119,7 +119,7 @@ void LoadReporterAsyncServiceImpl::ReportLoadHandler::CreateAndStart( std::make_shared(cq, service, load_reporter); ReportLoadHandler* p = handler.get(); { - std::unique_lock lock(service->cq_shutdown_mu_); + grpc_core::MutexLock lock(&service->cq_shutdown_mu_); if (service->shutdown_) return; p->on_done_notified_ = CallableTag(std::bind(&ReportLoadHandler::OnDoneNotified, p, @@ -164,9 +164,9 @@ void LoadReporterAsyncServiceImpl::ReportLoadHandler::OnRequestDelivered( // instance will deallocate itself when it's done. CreateAndStart(cq_, service_, load_reporter_); { - std::unique_lock lock(service_->cq_shutdown_mu_); + grpc_core::ReleasableMutexLock lock(&service_->cq_shutdown_mu_); if (service_->shutdown_) { - lock.release()->unlock(); + lock.Unlock(); Shutdown(std::move(self), "OnRequestDelivered"); return; } @@ -211,8 +211,8 @@ void LoadReporterAsyncServiceImpl::ReportLoadHandler::OnReadDone( load_key_); const auto& load_report_interval = initial_request.load_report_interval(); load_report_interval_ms_ = - static_cast(load_report_interval.seconds() * 1000 + - load_report_interval.nanos() / 1000); + static_cast(load_report_interval.seconds() * 1000 + + load_report_interval.nanos() / 1000); gpr_log( GPR_INFO, "[LRS %p] Initial request received. Start load reporting (load " @@ -222,9 +222,9 @@ void LoadReporterAsyncServiceImpl::ReportLoadHandler::OnReadDone( SendReport(self, true /* ok */); // Expect this read to fail. { - std::unique_lock lock(service_->cq_shutdown_mu_); + grpc_core::ReleasableMutexLock lock(&service_->cq_shutdown_mu_); if (service_->shutdown_) { - lock.release()->unlock(); + lock.Unlock(); Shutdown(std::move(self), "OnReadDone"); return; } @@ -254,9 +254,9 @@ void LoadReporterAsyncServiceImpl::ReportLoadHandler::ScheduleNextReport( gpr_now(GPR_CLOCK_MONOTONIC), gpr_time_from_millis(load_report_interval_ms_, GPR_TIMESPAN)); { - std::unique_lock lock(service_->cq_shutdown_mu_); + grpc_core::ReleasableMutexLock lock(&service_->cq_shutdown_mu_); if (service_->shutdown_) { - lock.release()->unlock(); + lock.Unlock(); Shutdown(std::move(self), "ScheduleNextReport"); return; } @@ -294,9 +294,9 @@ void LoadReporterAsyncServiceImpl::ReportLoadHandler::SendReport( call_status_ = INITIAL_RESPONSE_SENT; } { - std::unique_lock lock(service_->cq_shutdown_mu_); + grpc_core::ReleasableMutexLock lock(&service_->cq_shutdown_mu_); if (service_->shutdown_) { - lock.release()->unlock(); + lock.Unlock(); Shutdown(std::move(self), "SendReport"); return; } @@ -342,7 +342,7 @@ void LoadReporterAsyncServiceImpl::ReportLoadHandler::Shutdown( // OnRequestDelivered() may be called after OnDoneNotified(), so we need to // try to Finish() every time we are in Shutdown(). if (call_status_ >= DELIVERED && call_status_ < FINISH_CALLED) { - std::unique_lock lock(service_->cq_shutdown_mu_); + grpc_core::MutexLock lock(&service_->cq_shutdown_mu_); if (!service_->shutdown_) { on_finish_done_ = CallableTag(std::bind(&ReportLoadHandler::OnFinishDone, this, diff --git a/src/cpp/server/load_reporter/load_reporter_async_service_impl.h b/src/cpp/server/load_reporter/load_reporter_async_service_impl.h index 6fc577ff493..3087cbfc04d 100644 --- a/src/cpp/server/load_reporter/load_reporter_async_service_impl.h +++ b/src/cpp/server/load_reporter/load_reporter_async_service_impl.h @@ -25,6 +25,7 @@ #include #include +#include "src/core/lib/gprpp/sync.h" #include "src/core/lib/gprpp/thd.h" #include "src/cpp/server/load_reporter/load_reporter.h" @@ -181,7 +182,7 @@ class LoadReporterAsyncServiceImpl std::unique_ptr cq_; // To synchronize the operations related to shutdown state of cq_, so that we // don't enqueue new tags into cq_ after it is already shut down. - std::mutex cq_shutdown_mu_; + grpc_core::Mutex cq_shutdown_mu_; std::atomic_bool shutdown_{false}; std::unique_ptr<::grpc_core::Thread> thread_; std::unique_ptr load_reporter_; diff --git a/src/cpp/server/load_reporter/load_reporting_service_server_builder_option.cc b/src/cpp/server/load_reporter/load_reporting_service_server_builder_option.cc index 81cf6ac562d..ab63bebb792 100644 --- a/src/cpp/server/load_reporter/load_reporting_service_server_builder_option.cc +++ b/src/cpp/server/load_reporter/load_reporting_service_server_builder_option.cc @@ -22,7 +22,7 @@ #include "src/cpp/server/load_reporter/load_reporting_service_server_builder_plugin.h" -namespace grpc { +namespace grpc_impl { namespace load_reporter { namespace experimental { @@ -33,9 +33,10 @@ void LoadReportingServiceServerBuilderOption::UpdateArguments( void LoadReportingServiceServerBuilderOption::UpdatePlugins( std::vector>* plugins) { - plugins->emplace_back(new LoadReportingServiceServerBuilderPlugin()); + plugins->emplace_back( + new grpc::load_reporter::LoadReportingServiceServerBuilderPlugin()); } } // namespace experimental } // namespace load_reporter -} // namespace grpc +} // namespace grpc_impl diff --git a/src/cpp/server/load_reporter/load_reporting_service_server_builder_plugin.h b/src/cpp/server/load_reporter/load_reporting_service_server_builder_plugin.h index 1f098591d4d..c80802b2638 100644 --- a/src/cpp/server/load_reporter/load_reporting_service_server_builder_plugin.h +++ b/src/cpp/server/load_reporter/load_reporting_service_server_builder_plugin.h @@ -36,13 +36,13 @@ class LoadReportingServiceServerBuilderPlugin : public ServerBuilderPlugin { grpc::string name() override { return "load_reporting_service"; } // Creates a load reporting service. - void UpdateServerBuilder(grpc::ServerBuilder* builder) override; + void UpdateServerBuilder(ServerBuilder* builder) override; // Registers the load reporter service. - void InitServer(grpc::ServerInitializer* si) override; + void InitServer(grpc_impl::ServerInitializer* si) override; // Starts the load reporter service. - void Finish(grpc::ServerInitializer* si) override; + void Finish(grpc_impl::ServerInitializer* si) override; void ChangeArguments(const grpc::string& name, void* value) override {} void UpdateChannelArguments(grpc::ChannelArguments* args) override {} diff --git a/src/cpp/server/load_reporter/util.cc b/src/cpp/server/load_reporter/util.cc index 89bdf57049c..b69705a6994 100644 --- a/src/cpp/server/load_reporter/util.cc +++ b/src/cpp/server/load_reporter/util.cc @@ -24,7 +24,7 @@ #include -namespace grpc { +namespace grpc_impl { namespace load_reporter { namespace experimental { @@ -44,4 +44,4 @@ void AddLoadReportingCost(grpc::ServerContext* ctx, } // namespace experimental } // namespace load_reporter -} // namespace grpc +} // namespace grpc_impl diff --git a/src/cpp/server/secure_server_credentials.cc b/src/cpp/server/secure_server_credentials.cc index ebb17def32b..93dc10f14ea 100644 --- a/src/cpp/server/secure_server_credentials.cc +++ b/src/cpp/server/secure_server_credentials.cc @@ -61,7 +61,7 @@ void AuthMetadataProcessorAyncWrapper::InvokeProcessor( metadata.insert(std::make_pair(StringRefFromSlice(&md[i].key), StringRefFromSlice(&md[i].value))); } - SecureAuthContext context(ctx, false); + SecureAuthContext context(ctx); AuthMetadataProcessor::OutputMetadata consumed_metadata; AuthMetadataProcessor::OutputMetadata response_metadata; @@ -93,21 +93,25 @@ void AuthMetadataProcessorAyncWrapper::InvokeProcessor( status.error_message().c_str()); } +} // namespace grpc + +namespace grpc_impl { + int SecureServerCredentials::AddPortToServer(const grpc::string& addr, grpc_server* server) { return grpc_server_add_secure_http2_port(server, addr.c_str(), creds_); } void SecureServerCredentials::SetAuthMetadataProcessor( - const std::shared_ptr& processor) { - auto* wrapper = new AuthMetadataProcessorAyncWrapper(processor); + const std::shared_ptr& processor) { + auto* wrapper = new grpc::AuthMetadataProcessorAyncWrapper(processor); grpc_server_credentials_set_auth_metadata_processor( - creds_, {AuthMetadataProcessorAyncWrapper::Process, - AuthMetadataProcessorAyncWrapper::Destroy, wrapper}); + creds_, {grpc::AuthMetadataProcessorAyncWrapper::Process, + grpc::AuthMetadataProcessorAyncWrapper::Destroy, wrapper}); } std::shared_ptr SslServerCredentials( - const SslServerCredentialsOptions& options) { + const grpc::SslServerCredentialsOptions& options) { std::vector pem_key_cert_pairs; for (auto key_cert_pair = options.pem_key_cert_pairs.begin(); key_cert_pair != options.pem_key_cert_pairs.end(); key_cert_pair++) { @@ -147,4 +151,4 @@ std::shared_ptr LocalServerCredentials( } } // namespace experimental -} // namespace grpc +} // namespace grpc_impl diff --git a/src/cpp/server/secure_server_credentials.h b/src/cpp/server/secure_server_credentials.h index 8a81af2f591..24b133cf7f0 100644 --- a/src/cpp/server/secure_server_credentials.h +++ b/src/cpp/server/secure_server_credentials.h @@ -27,8 +27,15 @@ #include "src/cpp/server/thread_pool_interface.h" +namespace grpc_impl { + +class SecureServerCredentials; +} // namespace grpc_impl + namespace grpc { +typedef ::grpc_impl::SecureServerCredentials SecureServerCredentials; + class AuthMetadataProcessorAyncWrapper final { public: static void Destroy(void* wrapper); @@ -49,6 +56,10 @@ class AuthMetadataProcessorAyncWrapper final { std::shared_ptr processor_; }; +} // namespace grpc + +namespace grpc_impl { + class SecureServerCredentials final : public ServerCredentials { public: explicit SecureServerCredentials(grpc_server_credentials* creds) @@ -60,13 +71,13 @@ class SecureServerCredentials final : public ServerCredentials { int AddPortToServer(const grpc::string& addr, grpc_server* server) override; void SetAuthMetadataProcessor( - const std::shared_ptr& processor) override; + const std::shared_ptr& processor) override; private: grpc_server_credentials* creds_; - std::unique_ptr processor_; + std::unique_ptr processor_; }; -} // namespace grpc +} // namespace grpc_impl #endif // GRPC_INTERNAL_CPP_SERVER_SECURE_SERVER_CREDENTIALS_H diff --git a/src/cpp/server/server_builder.cc b/src/cpp/server/server_builder.cc index 0dc03b68768..af76ffbe9b5 100644 --- a/src/cpp/server/server_builder.cc +++ b/src/cpp/server/server_builder.cc @@ -29,23 +29,22 @@ #include "src/core/lib/gpr/useful.h" #include "src/cpp/server/thread_pool_interface.h" -namespace grpc { +namespace grpc_impl { -static std::vector (*)()>* +static std::vector (*)()>* g_plugin_factory_list; static gpr_once once_init_plugin_list = GPR_ONCE_INIT; static void do_plugin_list_init(void) { g_plugin_factory_list = - new std::vector (*)()>(); + new std::vector (*)()>(); } ServerBuilder::ServerBuilder() : max_receive_message_size_(INT_MIN), max_send_message_size_(INT_MIN), sync_server_settings_(SyncServerSettings()), - resource_quota_(nullptr), - generic_service_(nullptr) { + resource_quota_(nullptr) { gpr_once_init(&once_init_plugin_list, do_plugin_list_init); for (auto it = g_plugin_factory_list->begin(); it != g_plugin_factory_list->end(); it++) { @@ -68,32 +67,32 @@ ServerBuilder::~ServerBuilder() { } } -std::unique_ptr ServerBuilder::AddCompletionQueue( +std::unique_ptr ServerBuilder::AddCompletionQueue( bool is_frequently_polled) { - ServerCompletionQueue* cq = new ServerCompletionQueue( + grpc::ServerCompletionQueue* cq = new grpc::ServerCompletionQueue( GRPC_CQ_NEXT, is_frequently_polled ? GRPC_CQ_DEFAULT_POLLING : GRPC_CQ_NON_LISTENING, nullptr); cqs_.push_back(cq); - return std::unique_ptr(cq); + return std::unique_ptr(cq); } -ServerBuilder& ServerBuilder::RegisterService(Service* service) { +ServerBuilder& ServerBuilder::RegisterService(grpc::Service* service) { services_.emplace_back(new NamedService(service)); return *this; } ServerBuilder& ServerBuilder::RegisterService(const grpc::string& addr, - Service* service) { + grpc::Service* service) { services_.emplace_back(new NamedService(addr, service)); return *this; } ServerBuilder& ServerBuilder::RegisterAsyncGenericService( - AsyncGenericService* service) { - if (generic_service_) { + grpc::AsyncGenericService* service) { + if (generic_service_ || callback_generic_service_) { gpr_log(GPR_ERROR, - "Adding multiple AsyncGenericService is unsupported for now. " + "Adding multiple generic services is unsupported for now. " "Dropping the service %p", (void*)service); } else { @@ -102,8 +101,21 @@ ServerBuilder& ServerBuilder::RegisterAsyncGenericService( return *this; } +ServerBuilder& ServerBuilder::experimental_type::RegisterCallbackGenericService( + grpc::experimental::CallbackGenericService* service) { + if (builder_->generic_service_ || builder_->callback_generic_service_) { + gpr_log(GPR_ERROR, + "Adding multiple generic services is unsupported for now. " + "Dropping the service %p", + (void*)service); + } else { + builder_->callback_generic_service_ = service; + } + return *builder_; +} + ServerBuilder& ServerBuilder::SetOption( - std::unique_ptr option) { + std::unique_ptr option) { options_.push_back(std::move(option)); return *this; } @@ -139,6 +151,7 @@ ServerBuilder& ServerBuilder::SetCompressionAlgorithmSupportStatus( ServerBuilder& ServerBuilder::SetDefaultCompressionLevel( grpc_compression_level level) { + maybe_default_compression_level_.is_set = true; maybe_default_compression_level_.level = level; return *this; } @@ -151,7 +164,7 @@ ServerBuilder& ServerBuilder::SetDefaultCompressionAlgorithm( } ServerBuilder& ServerBuilder::SetResourceQuota( - const grpc::ResourceQuota& resource_quota) { + const grpc_impl::ResourceQuota& resource_quota) { if (resource_quota_ != nullptr) { grpc_resource_quota_unref(resource_quota_); } @@ -161,8 +174,8 @@ ServerBuilder& ServerBuilder::SetResourceQuota( } ServerBuilder& ServerBuilder::AddListeningPort( - const grpc::string& addr_uri, std::shared_ptr creds, - int* selected_port) { + const grpc::string& addr_uri, + std::shared_ptr creds, int* selected_port) { const grpc::string uri_scheme = "dns:"; grpc::string addr = addr_uri; if (addr_uri.compare(0, uri_scheme.size(), uri_scheme) == 0) { @@ -175,8 +188,8 @@ ServerBuilder& ServerBuilder::AddListeningPort( return *this; } -std::unique_ptr ServerBuilder::BuildAndStart() { - ChannelArguments args; +std::unique_ptr ServerBuilder::BuildAndStart() { + grpc::ChannelArguments args; for (auto option = options_.begin(); option != options_.end(); ++option) { (*option)->UpdateArguments(&args); (*option)->UpdatePlugins(&plugins_); @@ -238,28 +251,16 @@ std::unique_ptr ServerBuilder::BuildAndStart() { // This is different from the completion queues added to the server via // ServerBuilder's AddCompletionQueue() method (those completion queues // are in 'cqs_' member variable of ServerBuilder object) - std::shared_ptr>> - sync_server_cqs(std::make_shared< - std::vector>>()); + std::shared_ptr>> + sync_server_cqs( + std::make_shared< + std::vector>>()); - int num_frequently_polled_cqs = 0; + bool has_frequently_polled_cqs = false; for (auto it = cqs_.begin(); it != cqs_.end(); ++it) { if ((*it)->IsFrequentlyPolled()) { - num_frequently_polled_cqs++; - } - } - - const bool is_hybrid_server = - has_sync_methods && num_frequently_polled_cqs > 0; - - if (has_sync_methods) { - grpc_cq_polling_type polling_type = - is_hybrid_server ? GRPC_CQ_NON_POLLING : GRPC_CQ_DEFAULT_POLLING; - - // Create completion queues to listen to incoming rpc requests - for (int i = 0; i < sync_server_settings_.num_cqs; i++) { - sync_server_cqs->emplace_back( - new ServerCompletionQueue(GRPC_CQ_NEXT, polling_type, nullptr)); + has_frequently_polled_cqs = true; + break; } } @@ -268,10 +269,24 @@ std::unique_ptr ServerBuilder::BuildAndStart() { for (auto it = services_.begin(); it != services_.end(); ++it) { if ((*it)->service->has_callback_methods()) { has_callback_methods = true; + has_frequently_polled_cqs = true; break; } } + const bool is_hybrid_server = has_sync_methods && has_frequently_polled_cqs; + + if (has_sync_methods) { + grpc_cq_polling_type polling_type = + is_hybrid_server ? GRPC_CQ_NON_POLLING : GRPC_CQ_DEFAULT_POLLING; + + // Create completion queues to listen to incoming rpc requests + for (int i = 0; i < sync_server_settings_.num_cqs; i++) { + sync_server_cqs->emplace_back( + new grpc::ServerCompletionQueue(GRPC_CQ_NEXT, polling_type, nullptr)); + } + } + // TODO(vjpai): Add a section here for plugins once they can support callback // methods @@ -289,13 +304,13 @@ std::unique_ptr ServerBuilder::BuildAndStart() { gpr_log(GPR_INFO, "Callback server."); } - std::unique_ptr server(new Server( + std::unique_ptr server(new grpc::Server( max_receive_message_size_, &args, sync_server_cqs, sync_server_settings_.min_pollers, sync_server_settings_.max_pollers, sync_server_settings_.cq_timeout_msec, resource_quota_, std::move(interceptor_creators_))); - ServerInitializer* initializer = server->initializer(); + grpc_impl::ServerInitializer* initializer = server->initializer(); // Register all the completion queues with the server. i.e // 1. sync_server_cqs: internal completion queues created IF this is a sync @@ -305,13 +320,12 @@ std::unique_ptr ServerBuilder::BuildAndStart() { for (auto it = sync_server_cqs->begin(); it != sync_server_cqs->end(); ++it) { grpc_server_register_completion_queue(server->server_, (*it)->cq(), nullptr); - num_frequently_polled_cqs++; + has_frequently_polled_cqs = true; } - if (has_callback_methods) { + if (has_callback_methods || callback_generic_service_ != nullptr) { auto* cq = server->CallbackCQ(); grpc_server_register_completion_queue(server->server_, cq->cq(), nullptr); - num_frequently_polled_cqs++; } // cqs_ contains the completion queue added by calling the ServerBuilder's @@ -324,7 +338,7 @@ std::unique_ptr ServerBuilder::BuildAndStart() { nullptr); } - if (num_frequently_polled_cqs == 0) { + if (!has_frequently_polled_cqs) { gpr_log(GPR_ERROR, "At least one of the completion queues must be frequently polled"); return nullptr; @@ -343,6 +357,8 @@ std::unique_ptr ServerBuilder::BuildAndStart() { if (generic_service_) { server->RegisterAsyncGenericService(generic_service_); + } else if (callback_generic_service_) { + server->RegisterCallbackGenericService(callback_generic_service_); } else { for (auto it = services_.begin(); it != services_.end(); ++it) { if ((*it)->service->has_generic_methods()) { @@ -378,7 +394,7 @@ std::unique_ptr ServerBuilder::BuildAndStart() { } void ServerBuilder::InternalAddPluginFactory( - std::unique_ptr (*CreatePlugin)()) { + std::unique_ptr (*CreatePlugin)()) { gpr_once_init(&once_init_plugin_list, do_plugin_list_init); (*g_plugin_factory_list).push_back(CreatePlugin); } @@ -393,4 +409,4 @@ ServerBuilder& ServerBuilder::EnableWorkaround(grpc_workaround_list id) { } } -} // namespace grpc +} // namespace grpc_impl diff --git a/src/cpp/server/server_cc.cc b/src/cpp/server/server_cc.cc index 72d005f23d3..9c2b1ee13fc 100644 --- a/src/cpp/server/server_cc.cc +++ b/src/cpp/server/server_cc.cc @@ -19,6 +19,7 @@ #include #include +#include #include #include @@ -59,7 +60,15 @@ namespace { #define DEFAULT_MAX_SYNC_SERVER_THREADS INT_MAX // How many callback requests of each method should we pre-register at start -#define DEFAULT_CALLBACK_REQS_PER_METHOD 32 +#define DEFAULT_CALLBACK_REQS_PER_METHOD 512 + +// What is the (soft) limit for outstanding requests in the server +#define SOFT_MAXIMUM_CALLBACK_REQS_OUTSTANDING 30000 + +// If the number of unmatched requests for a method drops below this amount, try +// to allocate extra unless it pushes the total number of callbacks above the +// soft maximum +#define SOFT_MINIMUM_SPARE_CALLBACK_REQS_PER_METHOD 128 class DefaultGlobalCallbacks final : public Server::GlobalCallbacks { public: @@ -84,10 +93,7 @@ class ShutdownTag : public internal::CompletionQueueTag { class DummyTag : public internal::CompletionQueueTag { public: - bool FinalizeResult(void** tag, bool* status) { - *status = true; - return true; - } + bool FinalizeResult(void** tag, bool* status) { return true; } }; class UnimplementedAsyncRequestContext { @@ -100,865 +106,6 @@ class UnimplementedAsyncRequestContext { } // namespace -/// Use private inheritance rather than composition only to establish order -/// of construction, since the public base class should be constructed after the -/// elements belonging to the private base class are constructed. This is not -/// possible using true composition. -class Server::UnimplementedAsyncRequest final - : private UnimplementedAsyncRequestContext, - public GenericAsyncRequest { - public: - UnimplementedAsyncRequest(Server* server, ServerCompletionQueue* cq) - : GenericAsyncRequest(server, &server_context_, &generic_stream_, cq, cq, - nullptr, false), - server_(server), - cq_(cq) {} - - bool FinalizeResult(void** tag, bool* status) override; - - ServerContext* context() { return &server_context_; } - GenericServerAsyncReaderWriter* stream() { return &generic_stream_; } - - private: - Server* const server_; - ServerCompletionQueue* const cq_; -}; - -/// UnimplementedAsyncResponse should not post user-visible completions to the -/// C++ completion queue, but is generated as a CQ event by the core -class Server::UnimplementedAsyncResponse final - : public internal::CallOpSet { - public: - UnimplementedAsyncResponse(UnimplementedAsyncRequest* request); - ~UnimplementedAsyncResponse() { delete request_; } - - bool FinalizeResult(void** tag, bool* status) override { - if (internal::CallOpSet< - internal::CallOpSendInitialMetadata, - internal::CallOpServerSendStatus>::FinalizeResult(tag, status)) { - delete this; - } else { - // The tag was swallowed due to interception. We will see it again. - } - return false; - } - - private: - UnimplementedAsyncRequest* const request_; -}; - -class Server::SyncRequest final : public internal::CompletionQueueTag { - public: - SyncRequest(internal::RpcServiceMethod* method, void* method_tag) - : method_(method), - method_tag_(method_tag), - in_flight_(false), - has_request_payload_( - method->method_type() == internal::RpcMethod::NORMAL_RPC || - method->method_type() == internal::RpcMethod::SERVER_STREAMING), - call_details_(nullptr), - cq_(nullptr) { - grpc_metadata_array_init(&request_metadata_); - } - - ~SyncRequest() { - if (call_details_) { - delete call_details_; - } - grpc_metadata_array_destroy(&request_metadata_); - } - - void SetupRequest() { cq_ = grpc_completion_queue_create_for_pluck(nullptr); } - - void TeardownRequest() { - grpc_completion_queue_destroy(cq_); - cq_ = nullptr; - } - - void Request(grpc_server* server, grpc_completion_queue* notify_cq) { - GPR_ASSERT(cq_ && !in_flight_); - in_flight_ = true; - if (method_tag_) { - if (GRPC_CALL_OK != - grpc_server_request_registered_call( - server, method_tag_, &call_, &deadline_, &request_metadata_, - has_request_payload_ ? &request_payload_ : nullptr, cq_, - notify_cq, this)) { - TeardownRequest(); - return; - } - } else { - if (!call_details_) { - call_details_ = new grpc_call_details; - grpc_call_details_init(call_details_); - } - if (grpc_server_request_call(server, &call_, call_details_, - &request_metadata_, cq_, notify_cq, - this) != GRPC_CALL_OK) { - TeardownRequest(); - return; - } - } - } - - void PostShutdownCleanup() { - if (call_) { - grpc_call_unref(call_); - call_ = nullptr; - } - if (cq_) { - grpc_completion_queue_destroy(cq_); - cq_ = nullptr; - } - } - - bool FinalizeResult(void** tag, bool* status) override { - if (!*status) { - grpc_completion_queue_destroy(cq_); - cq_ = nullptr; - } - if (call_details_) { - deadline_ = call_details_->deadline; - grpc_call_details_destroy(call_details_); - grpc_call_details_init(call_details_); - } - return true; - } - - // The CallData class represents a call that is "active" as opposed - // to just being requested. It wraps and takes ownership of the cq from - // the call request - class CallData final { - public: - explicit CallData(Server* server, SyncRequest* mrd) - : cq_(mrd->cq_), - ctx_(mrd->deadline_, &mrd->request_metadata_), - has_request_payload_(mrd->has_request_payload_), - request_payload_(has_request_payload_ ? mrd->request_payload_ - : nullptr), - request_(nullptr), - method_(mrd->method_), - call_(mrd->call_, server, &cq_, server->max_receive_message_size(), - ctx_.set_server_rpc_info(method_->name(), - server->interceptor_creators_)), - server_(server), - global_callbacks_(nullptr), - resources_(false) { - ctx_.set_call(mrd->call_); - ctx_.cq_ = &cq_; - GPR_ASSERT(mrd->in_flight_); - mrd->in_flight_ = false; - mrd->request_metadata_.count = 0; - } - - ~CallData() { - if (has_request_payload_ && request_payload_) { - grpc_byte_buffer_destroy(request_payload_); - } - } - - void Run(const std::shared_ptr& global_callbacks, - bool resources) { - global_callbacks_ = global_callbacks; - resources_ = resources; - - interceptor_methods_.SetCall(&call_); - interceptor_methods_.SetReverse(); - // Set interception point for RECV INITIAL METADATA - interceptor_methods_.AddInterceptionHookPoint( - experimental::InterceptionHookPoints::POST_RECV_INITIAL_METADATA); - interceptor_methods_.SetRecvInitialMetadata(&ctx_.client_metadata_); - - if (has_request_payload_) { - // Set interception point for RECV MESSAGE - auto* handler = resources_ ? method_->handler() - : server_->resource_exhausted_handler_.get(); - request_ = handler->Deserialize(call_.call(), request_payload_, - &request_status_); - - request_payload_ = nullptr; - interceptor_methods_.AddInterceptionHookPoint( - experimental::InterceptionHookPoints::POST_RECV_MESSAGE); - interceptor_methods_.SetRecvMessage(request_); - } - - if (interceptor_methods_.RunInterceptors( - [this]() { ContinueRunAfterInterception(); })) { - ContinueRunAfterInterception(); - } else { - // There were interceptors to be run, so ContinueRunAfterInterception - // will be run when interceptors are done. - } - } - - void ContinueRunAfterInterception() { - { - ctx_.BeginCompletionOp(&call_, false); - global_callbacks_->PreSynchronousRequest(&ctx_); - auto* handler = resources_ ? method_->handler() - : server_->resource_exhausted_handler_.get(); - handler->RunHandler(internal::MethodHandler::HandlerParameter( - &call_, &ctx_, request_, request_status_, nullptr)); - request_ = nullptr; - global_callbacks_->PostSynchronousRequest(&ctx_); - - cq_.Shutdown(); - - internal::CompletionQueueTag* op_tag = ctx_.GetCompletionOpTag(); - cq_.TryPluck(op_tag, gpr_inf_future(GPR_CLOCK_REALTIME)); - - /* Ensure the cq_ is shutdown */ - DummyTag ignored_tag; - GPR_ASSERT(cq_.Pluck(&ignored_tag) == false); - } - delete this; - } - - private: - CompletionQueue cq_; - ServerContext ctx_; - const bool has_request_payload_; - grpc_byte_buffer* request_payload_; - void* request_; - Status request_status_; - internal::RpcServiceMethod* const method_; - internal::Call call_; - Server* server_; - std::shared_ptr global_callbacks_; - bool resources_; - internal::InterceptorBatchMethodsImpl interceptor_methods_; - }; - - private: - internal::RpcServiceMethod* const method_; - void* const method_tag_; - bool in_flight_; - const bool has_request_payload_; - grpc_call* call_; - grpc_call_details* call_details_; - gpr_timespec deadline_; - grpc_metadata_array request_metadata_; - grpc_byte_buffer* request_payload_; - grpc_completion_queue* cq_; -}; - -class Server::CallbackRequest final : public internal::CompletionQueueTag { - public: - CallbackRequest(Server* server, internal::RpcServiceMethod* method, - void* method_tag) - : server_(server), - method_(method), - method_tag_(method_tag), - has_request_payload_( - method->method_type() == internal::RpcMethod::NORMAL_RPC || - method->method_type() == internal::RpcMethod::SERVER_STREAMING), - cq_(server->CallbackCQ()), - tag_(this) { - Setup(); - } - - ~CallbackRequest() { Clear(); } - - void Request() { - if (method_tag_) { - if (GRPC_CALL_OK != - grpc_server_request_registered_call( - server_->c_server(), method_tag_, &call_, &deadline_, - &request_metadata_, - has_request_payload_ ? &request_payload_ : nullptr, cq_->cq(), - cq_->cq(), static_cast(&tag_))) { - return; - } - } else { - if (!call_details_) { - call_details_ = new grpc_call_details; - grpc_call_details_init(call_details_); - } - if (grpc_server_request_call(server_->c_server(), &call_, call_details_, - &request_metadata_, cq_->cq(), cq_->cq(), - static_cast(&tag_)) != GRPC_CALL_OK) { - return; - } - } - } - - bool FinalizeResult(void** tag, bool* status) override { return false; } - - private: - class CallbackCallTag : public grpc_experimental_completion_queue_functor { - public: - CallbackCallTag(Server::CallbackRequest* req) : req_(req) { - functor_run = &CallbackCallTag::StaticRun; - } - - // force_run can not be performed on a tag if operations using this tag - // have been sent to PerformOpsOnCall. It is intended for error conditions - // that are detected before the operations are internally processed. - void force_run(bool ok) { Run(ok); } - - private: - Server::CallbackRequest* req_; - internal::Call* call_; - - static void StaticRun(grpc_experimental_completion_queue_functor* cb, - int ok) { - static_cast(cb)->Run(static_cast(ok)); - } - void Run(bool ok) { - void* ignored = req_; - bool new_ok = ok; - GPR_ASSERT(!req_->FinalizeResult(&ignored, &new_ok)); - GPR_ASSERT(ignored == req_); - - if (!ok) { - // The call has been shutdown - req_->Clear(); - return; - } - - // Bind the call, deadline, and metadata from what we got - req_->ctx_.set_call(req_->call_); - req_->ctx_.cq_ = req_->cq_; - req_->ctx_.BindDeadlineAndMetadata(req_->deadline_, - &req_->request_metadata_); - req_->request_metadata_.count = 0; - - // Create a C++ Call to control the underlying core call - call_ = new (grpc_call_arena_alloc(req_->call_, sizeof(internal::Call))) - internal::Call( - req_->call_, req_->server_, req_->cq_, - req_->server_->max_receive_message_size(), - req_->ctx_.set_server_rpc_info( - req_->method_->name(), req_->server_->interceptor_creators_)); - - req_->interceptor_methods_.SetCall(call_); - req_->interceptor_methods_.SetReverse(); - // Set interception point for RECV INITIAL METADATA - req_->interceptor_methods_.AddInterceptionHookPoint( - experimental::InterceptionHookPoints::POST_RECV_INITIAL_METADATA); - req_->interceptor_methods_.SetRecvInitialMetadata( - &req_->ctx_.client_metadata_); - - if (req_->has_request_payload_) { - // Set interception point for RECV MESSAGE - req_->request_ = req_->method_->handler()->Deserialize( - req_->call_, req_->request_payload_, &req_->request_status_); - req_->request_payload_ = nullptr; - req_->interceptor_methods_.AddInterceptionHookPoint( - experimental::InterceptionHookPoints::POST_RECV_MESSAGE); - req_->interceptor_methods_.SetRecvMessage(req_->request_); - } - - if (req_->interceptor_methods_.RunInterceptors( - [this] { ContinueRunAfterInterception(); })) { - ContinueRunAfterInterception(); - } else { - // There were interceptors to be run, so ContinueRunAfterInterception - // will be run when interceptors are done. - } - } - void ContinueRunAfterInterception() { - req_->ctx_.BeginCompletionOp(call_, true); - req_->method_->handler()->RunHandler( - internal::MethodHandler::HandlerParameter( - call_, &req_->ctx_, req_->request_, req_->request_status_, - [this] { - req_->Reset(); - req_->Request(); - })); - } - }; - - void Reset() { - Clear(); - Setup(); - } - - void Clear() { - if (call_details_) { - delete call_details_; - call_details_ = nullptr; - } - grpc_metadata_array_destroy(&request_metadata_); - if (has_request_payload_ && request_payload_) { - grpc_byte_buffer_destroy(request_payload_); - } - ctx_.Clear(); - interceptor_methods_.ClearState(); - } - - void Setup() { - grpc_metadata_array_init(&request_metadata_); - ctx_.Setup(gpr_inf_future(GPR_CLOCK_REALTIME)); - request_payload_ = nullptr; - request_ = nullptr; - request_status_ = Status(); - } - - Server* const server_; - internal::RpcServiceMethod* const method_; - void* const method_tag_; - const bool has_request_payload_; - grpc_byte_buffer* request_payload_; - void* request_; - Status request_status_; - grpc_call_details* call_details_ = nullptr; - grpc_call* call_; - gpr_timespec deadline_; - grpc_metadata_array request_metadata_; - CompletionQueue* cq_; - CallbackCallTag tag_; - ServerContext ctx_; - internal::InterceptorBatchMethodsImpl interceptor_methods_; -}; - -// Implementation of ThreadManager. Each instance of SyncRequestThreadManager -// manages a pool of threads that poll for incoming Sync RPCs and call the -// appropriate RPC handlers -class Server::SyncRequestThreadManager : public ThreadManager { - public: - SyncRequestThreadManager(Server* server, CompletionQueue* server_cq, - std::shared_ptr global_callbacks, - grpc_resource_quota* rq, int min_pollers, - int max_pollers, int cq_timeout_msec) - : ThreadManager("SyncServer", rq, min_pollers, max_pollers), - server_(server), - server_cq_(server_cq), - cq_timeout_msec_(cq_timeout_msec), - global_callbacks_(std::move(global_callbacks)) {} - - WorkStatus PollForWork(void** tag, bool* ok) override { - *tag = nullptr; - // TODO(ctiller): workaround for GPR_TIMESPAN based deadlines not working - // right now - gpr_timespec deadline = - gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), - gpr_time_from_millis(cq_timeout_msec_, GPR_TIMESPAN)); - - switch (server_cq_->AsyncNext(tag, ok, deadline)) { - case CompletionQueue::TIMEOUT: - return TIMEOUT; - case CompletionQueue::SHUTDOWN: - return SHUTDOWN; - case CompletionQueue::GOT_EVENT: - return WORK_FOUND; - } - - GPR_UNREACHABLE_CODE(return TIMEOUT); - } - - void DoWork(void* tag, bool ok, bool resources) override { - SyncRequest* sync_req = static_cast(tag); - - if (!sync_req) { - // No tag. Nothing to work on. This is an unlikley scenario and possibly a - // bug in RPC Manager implementation. - gpr_log(GPR_ERROR, "Sync server. DoWork() was called with NULL tag"); - return; - } - - if (ok) { - // Calldata takes ownership of the completion queue and interceptors - // inside sync_req - auto* cd = new SyncRequest::CallData(server_, sync_req); - // Prepare for the next request - if (!IsShutdown()) { - sync_req->SetupRequest(); // Create new completion queue for sync_req - sync_req->Request(server_->c_server(), server_cq_->cq()); - } - - GPR_TIMER_SCOPE("cd.Run()", 0); - cd->Run(global_callbacks_, resources); - } - // TODO (sreek) If ok is false here (which it isn't in case of - // grpc_request_registered_call), we should still re-queue the request - // object - } - - void AddSyncMethod(internal::RpcServiceMethod* method, void* tag) { - sync_requests_.emplace_back(new SyncRequest(method, tag)); - } - - void AddUnknownSyncMethod() { - if (!sync_requests_.empty()) { - unknown_method_.reset(new internal::RpcServiceMethod( - "unknown", internal::RpcMethod::BIDI_STREAMING, - new internal::UnknownMethodHandler)); - sync_requests_.emplace_back( - new SyncRequest(unknown_method_.get(), nullptr)); - } - } - - void Shutdown() override { - ThreadManager::Shutdown(); - server_cq_->Shutdown(); - } - - void Wait() override { - ThreadManager::Wait(); - // Drain any pending items from the queue - void* tag; - bool ok; - while (server_cq_->Next(&tag, &ok)) { - if (ok) { - // If a request was pulled off the queue, it means that the thread - // handling the request added it to the completion queue after shutdown - // was called - because the thread had already started and checked the - // shutdown flag before shutdown was called. In this case, we simply - // clean it up here, *after* calling wait on all the worker threads, at - // which point we are certain no in-flight requests will add more to the - // queue. This fixes an intermittent memory leak on shutdown. - SyncRequest* sync_req = static_cast(tag); - sync_req->PostShutdownCleanup(); - } - } - } - - void Start() { - if (!sync_requests_.empty()) { - for (auto m = sync_requests_.begin(); m != sync_requests_.end(); m++) { - (*m)->SetupRequest(); - (*m)->Request(server_->c_server(), server_cq_->cq()); - } - - Initialize(); // ThreadManager's Initialize() - } - } - - private: - Server* server_; - CompletionQueue* server_cq_; - int cq_timeout_msec_; - std::vector> sync_requests_; - std::unique_ptr unknown_method_; - std::shared_ptr global_callbacks_; -}; - -static internal::GrpcLibraryInitializer g_gli_initializer; -Server::Server( - int max_receive_message_size, ChannelArguments* args, - std::shared_ptr>> - sync_server_cqs, - int min_pollers, int max_pollers, int sync_cq_timeout_msec, - grpc_resource_quota* server_rq, - std::vector< - std::unique_ptr> - interceptor_creators) - : interceptor_creators_(std::move(interceptor_creators)), - max_receive_message_size_(max_receive_message_size), - sync_server_cqs_(std::move(sync_server_cqs)), - started_(false), - shutdown_(false), - shutdown_notified_(false), - has_generic_service_(false), - server_(nullptr), - server_initializer_(new ServerInitializer(this)), - health_check_service_disabled_(false) { - g_gli_initializer.summon(); - gpr_once_init(&g_once_init_callbacks, InitGlobalCallbacks); - global_callbacks_ = g_callbacks; - global_callbacks_->UpdateArguments(args); - - if (sync_server_cqs_ != nullptr) { - bool default_rq_created = false; - if (server_rq == nullptr) { - server_rq = grpc_resource_quota_create("SyncServer-default-rq"); - grpc_resource_quota_set_max_threads(server_rq, - DEFAULT_MAX_SYNC_SERVER_THREADS); - default_rq_created = true; - } - - for (const auto& it : *sync_server_cqs_) { - sync_req_mgrs_.emplace_back(new SyncRequestThreadManager( - this, it.get(), global_callbacks_, server_rq, min_pollers, - max_pollers, sync_cq_timeout_msec)); - } - - if (default_rq_created) { - grpc_resource_quota_unref(server_rq); - } - } - - grpc_channel_args channel_args; - args->SetChannelArgs(&channel_args); - - for (size_t i = 0; i < channel_args.num_args; i++) { - if (0 == - strcmp(channel_args.args[i].key, kHealthCheckServiceInterfaceArg)) { - if (channel_args.args[i].value.pointer.p == nullptr) { - health_check_service_disabled_ = true; - } else { - health_check_service_.reset(static_cast( - channel_args.args[i].value.pointer.p)); - } - break; - } - } - - server_ = grpc_server_create(&channel_args, nullptr); -} - -Server::~Server() { - { - std::unique_lock lock(mu_); - if (callback_cq_ != nullptr) { - callback_cq_->Shutdown(); - } - if (started_ && !shutdown_) { - lock.unlock(); - Shutdown(); - } else if (!started_) { - // Shutdown the completion queues - for (auto it = sync_req_mgrs_.begin(); it != sync_req_mgrs_.end(); it++) { - (*it)->Shutdown(); - } - } - } - - grpc_server_destroy(server_); -} - -void Server::SetGlobalCallbacks(GlobalCallbacks* callbacks) { - GPR_ASSERT(!g_callbacks); - GPR_ASSERT(callbacks); - g_callbacks.reset(callbacks); -} - -grpc_server* Server::c_server() { return server_; } - -std::shared_ptr Server::InProcessChannel( - const ChannelArguments& args) { - grpc_channel_args channel_args = args.c_channel_args(); - return CreateChannelInternal( - "inproc", grpc_inproc_channel_create(server_, &channel_args, nullptr), - std::vector< - std::unique_ptr>()); -} - -std::shared_ptr -Server::experimental_type::InProcessChannelWithInterceptors( - const ChannelArguments& args, - std::vector< - std::unique_ptr> - interceptor_creators) { - grpc_channel_args channel_args = args.c_channel_args(); - return CreateChannelInternal( - "inproc", - grpc_inproc_channel_create(server_->server_, &channel_args, nullptr), - std::move(interceptor_creators)); -} - -static grpc_server_register_method_payload_handling PayloadHandlingForMethod( - internal::RpcServiceMethod* method) { - switch (method->method_type()) { - case internal::RpcMethod::NORMAL_RPC: - case internal::RpcMethod::SERVER_STREAMING: - return GRPC_SRM_PAYLOAD_READ_INITIAL_BYTE_BUFFER; - case internal::RpcMethod::CLIENT_STREAMING: - case internal::RpcMethod::BIDI_STREAMING: - return GRPC_SRM_PAYLOAD_NONE; - } - GPR_UNREACHABLE_CODE(return GRPC_SRM_PAYLOAD_NONE;); -} - -bool Server::RegisterService(const grpc::string* host, Service* service) { - bool has_async_methods = service->has_async_methods(); - if (has_async_methods) { - GPR_ASSERT(service->server_ == nullptr && - "Can only register an asynchronous service against one server."); - service->server_ = this; - } - - const char* method_name = nullptr; - for (auto it = service->methods_.begin(); it != service->methods_.end(); - ++it) { - if (it->get() == nullptr) { // Handled by generic service if any. - continue; - } - - internal::RpcServiceMethod* method = it->get(); - void* method_registration_tag = grpc_server_register_method( - server_, method->name(), host ? host->c_str() : nullptr, - PayloadHandlingForMethod(method), 0); - if (method_registration_tag == nullptr) { - gpr_log(GPR_DEBUG, "Attempt to register %s multiple times", - method->name()); - return false; - } - - if (method->handler() == nullptr) { // Async method without handler - method->set_server_tag(method_registration_tag); - } else if (method->api_type() == - internal::RpcServiceMethod::ApiType::SYNC) { - for (auto it = sync_req_mgrs_.begin(); it != sync_req_mgrs_.end(); it++) { - (*it)->AddSyncMethod(method, method_registration_tag); - } - } else { - // a callback method. Register at least some callback requests - // TODO(vjpai): Register these dynamically based on need - for (int i = 0; i < DEFAULT_CALLBACK_REQS_PER_METHOD; i++) { - auto* req = new CallbackRequest(this, method, method_registration_tag); - callback_reqs_.emplace_back(req); - } - // Enqueue it so that it will be Request'ed later once - // all request matchers are created at core server startup - } - - method_name = method->name(); - } - - // Parse service name. - if (method_name != nullptr) { - std::stringstream ss(method_name); - grpc::string service_name; - if (std::getline(ss, service_name, '/') && - std::getline(ss, service_name, '/')) { - services_.push_back(service_name); - } - } - return true; -} - -void Server::RegisterAsyncGenericService(AsyncGenericService* service) { - GPR_ASSERT(service->server_ == nullptr && - "Can only register an async generic service against one server."); - service->server_ = this; - has_generic_service_ = true; -} - -int Server::AddListeningPort(const grpc::string& addr, - ServerCredentials* creds) { - GPR_ASSERT(!started_); - int port = creds->AddPortToServer(addr, server_); - global_callbacks_->AddPort(this, addr, creds, port); - return port; -} - -void Server::Start(ServerCompletionQueue** cqs, size_t num_cqs) { - GPR_ASSERT(!started_); - global_callbacks_->PreServerStart(this); - started_ = true; - - // Only create default health check service when user did not provide an - // explicit one. - ServerCompletionQueue* health_check_cq = nullptr; - DefaultHealthCheckService::HealthCheckServiceImpl* - default_health_check_service_impl = nullptr; - if (health_check_service_ == nullptr && !health_check_service_disabled_ && - DefaultHealthCheckServiceEnabled()) { - auto* default_hc_service = new DefaultHealthCheckService; - health_check_service_.reset(default_hc_service); - // We create a non-polling CQ to avoid impacting application - // performance. This ensures that we don't introduce thread hops - // for application requests that wind up on this CQ, which is polled - // in its own thread. - health_check_cq = - new ServerCompletionQueue(GRPC_CQ_NEXT, GRPC_CQ_NON_POLLING, nullptr); - grpc_server_register_completion_queue(server_, health_check_cq->cq(), - nullptr); - default_health_check_service_impl = - default_hc_service->GetHealthCheckService( - std::unique_ptr(health_check_cq)); - RegisterService(nullptr, default_health_check_service_impl); - } - - grpc_server_start(server_); - - if (!has_generic_service_) { - for (auto it = sync_req_mgrs_.begin(); it != sync_req_mgrs_.end(); it++) { - (*it)->AddUnknownSyncMethod(); - } - - for (size_t i = 0; i < num_cqs; i++) { - if (cqs[i]->IsFrequentlyPolled()) { - new UnimplementedAsyncRequest(this, cqs[i]); - } - } - if (health_check_cq != nullptr) { - new UnimplementedAsyncRequest(this, health_check_cq); - } - } - - // If this server has any support for synchronous methods (has any sync - // server CQs), make sure that we have a ResourceExhausted handler - // to deal with the case of thread exhaustion - if (sync_server_cqs_ != nullptr && !sync_server_cqs_->empty()) { - resource_exhausted_handler_.reset(new internal::ResourceExhaustedHandler); - } - - for (auto it = sync_req_mgrs_.begin(); it != sync_req_mgrs_.end(); it++) { - (*it)->Start(); - } - - for (auto& cbreq : callback_reqs_) { - cbreq->Request(); - } - - if (default_health_check_service_impl != nullptr) { - default_health_check_service_impl->StartServingThread(); - } -} - -void Server::ShutdownInternal(gpr_timespec deadline) { - std::unique_lock lock(mu_); - if (!shutdown_) { - shutdown_ = true; - - /// The completion queue to use for server shutdown completion notification - CompletionQueue shutdown_cq; - ShutdownTag shutdown_tag; // Dummy shutdown tag - grpc_server_shutdown_and_notify(server_, shutdown_cq.cq(), &shutdown_tag); - - shutdown_cq.Shutdown(); - - void* tag; - bool ok; - CompletionQueue::NextStatus status = - shutdown_cq.AsyncNext(&tag, &ok, deadline); - - // If this timed out, it means we are done with the grace period for a clean - // shutdown. We should force a shutdown now by cancelling all inflight calls - if (status == CompletionQueue::NextStatus::TIMEOUT) { - grpc_server_cancel_all_calls(server_); - } - // Else in case of SHUTDOWN or GOT_EVENT, it means that the server has - // successfully shutdown - - // Shutdown all ThreadManagers. This will try to gracefully stop all the - // threads in the ThreadManagers (once they process any inflight requests) - for (auto it = sync_req_mgrs_.begin(); it != sync_req_mgrs_.end(); it++) { - (*it)->Shutdown(); // ThreadManager's Shutdown() - } - - // Wait for threads in all ThreadManagers to terminate - for (auto it = sync_req_mgrs_.begin(); it != sync_req_mgrs_.end(); it++) { - (*it)->Wait(); - } - - // Drain the shutdown queue (if the previous call to AsyncNext() timed out - // and we didn't remove the tag from the queue yet) - while (shutdown_cq.Next(&tag, &ok)) { - // Nothing to be done here. Just ignore ok and tag values - } - - shutdown_notified_ = true; - shutdown_cv_.notify_all(); - } -} - -void Server::Wait() { - std::unique_lock lock(mu_); - while (started_ && !shutdown_notified_) { - shutdown_cv_.wait(lock); - } -} - -void Server::PerformOpsOnCall(internal::CallOpSetInterface* ops, - internal::Call* call) { - ops->FillOps(call); -} - ServerInterface::BaseAsyncRequest::BaseAsyncRequest( ServerInterface* server, ServerContext* context, internal::ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq, @@ -1021,7 +168,7 @@ bool ServerInterface::BaseAsyncRequest::FinalizeResult(void** tag, } } if (*status && call_) { - context_->BeginCompletionOp(&call_wrapper_, false); + context_->BeginCompletionOp(&call_wrapper_, nullptr, nullptr); } *tag = tag_; if (delete_on_finalize_) { @@ -1032,7 +179,7 @@ bool ServerInterface::BaseAsyncRequest::FinalizeResult(void** tag, void ServerInterface::BaseAsyncRequest:: ContinueFinalizeResultAfterInterception() { - context_->BeginCompletionOp(&call_wrapper_, false); + context_->BeginCompletionOp(&call_wrapper_, nullptr, nullptr); // Queue a tag which will be returned immediately grpc_core::ExecCtx exec_ctx; grpc_cq_begin_op(notification_cq_->cq(), this); @@ -1045,10 +192,12 @@ void ServerInterface::BaseAsyncRequest:: ServerInterface::RegisteredAsyncRequest::RegisteredAsyncRequest( ServerInterface* server, ServerContext* context, internal::ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq, - ServerCompletionQueue* notification_cq, void* tag, const char* name) + ServerCompletionQueue* notification_cq, void* tag, const char* name, + internal::RpcMethod::RpcType type) : BaseAsyncRequest(server, context, stream, call_cq, notification_cq, tag, true), - name_(name) {} + name_(name), + type_(type) {} void ServerInterface::RegisteredAsyncRequest::IssueRequest( void* registered_method, grpc_byte_buffer** payload, @@ -1095,36 +244,11 @@ bool ServerInterface::GenericAsyncRequest::FinalizeResult(void** tag, call_, server_, call_cq_, server_->max_receive_message_size(), context_->set_server_rpc_info( static_cast(context_)->method_.c_str(), + internal::RpcMethod::BIDI_STREAMING, *server_->interceptor_creators())); return BaseAsyncRequest::FinalizeResult(tag, status); } -bool Server::UnimplementedAsyncRequest::FinalizeResult(void** tag, - bool* status) { - if (GenericAsyncRequest::FinalizeResult(tag, status)) { - // We either had no interceptors run or we are done intercepting - if (*status) { - new UnimplementedAsyncRequest(server_, cq_); - new UnimplementedAsyncResponse(this); - } else { - delete this; - } - } else { - // The tag was swallowed due to interception. We will see it again. - } - return false; -} - -Server::UnimplementedAsyncResponse::UnimplementedAsyncResponse( - UnimplementedAsyncRequest* request) - : request_(request) { - Status status(StatusCode::UNIMPLEMENTED, ""); - internal::UnknownMethodHandler::FillOps(request_->context(), this); - request_->stream()->call_.PerformOps(this); -} - -ServerInitializer* Server::initializer() { return server_initializer_.get(); } - namespace { class ShutdownCallback : public grpc_experimental_completion_queue_functor { public: @@ -1146,13 +270,1086 @@ class ShutdownCallback : public grpc_experimental_completion_queue_functor { }; } // namespace -CompletionQueue* Server::CallbackCQ() { +} // namespace grpc + +namespace grpc_impl { + +/// Use private inheritance rather than composition only to establish order +/// of construction, since the public base class should be constructed after the +/// elements belonging to the private base class are constructed. This is not +/// possible using true composition. +class Server::UnimplementedAsyncRequest final + : private grpc::UnimplementedAsyncRequestContext, + public GenericAsyncRequest { + public: + UnimplementedAsyncRequest(Server* server, grpc::ServerCompletionQueue* cq) + : GenericAsyncRequest(server, &server_context_, &generic_stream_, cq, cq, + nullptr, false), + server_(server), + cq_(cq) {} + + bool FinalizeResult(void** tag, bool* status) override; + + grpc::ServerContext* context() { return &server_context_; } + grpc::GenericServerAsyncReaderWriter* stream() { return &generic_stream_; } + + private: + Server* const server_; + grpc::ServerCompletionQueue* const cq_; +}; + +/// UnimplementedAsyncResponse should not post user-visible completions to the +/// C++ completion queue, but is generated as a CQ event by the core +class Server::UnimplementedAsyncResponse final + : public grpc::internal::CallOpSet< + grpc::internal::CallOpSendInitialMetadata, + grpc::internal::CallOpServerSendStatus> { + public: + UnimplementedAsyncResponse(UnimplementedAsyncRequest* request); + ~UnimplementedAsyncResponse() { delete request_; } + + bool FinalizeResult(void** tag, bool* status) override { + if (grpc::internal::CallOpSet< + grpc::internal::CallOpSendInitialMetadata, + grpc::internal::CallOpServerSendStatus>::FinalizeResult(tag, + status)) { + delete this; + } else { + // The tag was swallowed due to interception. We will see it again. + } + return false; + } + + private: + UnimplementedAsyncRequest* const request_; +}; + +class Server::SyncRequest final : public grpc::internal::CompletionQueueTag { + public: + SyncRequest(grpc::internal::RpcServiceMethod* method, void* method_tag) + : method_(method), + method_tag_(method_tag), + in_flight_(false), + has_request_payload_(method->method_type() == + grpc::internal::RpcMethod::NORMAL_RPC || + method->method_type() == + grpc::internal::RpcMethod::SERVER_STREAMING), + call_details_(nullptr), + cq_(nullptr) { + grpc_metadata_array_init(&request_metadata_); + } + + ~SyncRequest() { + if (call_details_) { + delete call_details_; + } + grpc_metadata_array_destroy(&request_metadata_); + } + + void SetupRequest() { cq_ = grpc_completion_queue_create_for_pluck(nullptr); } + + void TeardownRequest() { + grpc_completion_queue_destroy(cq_); + cq_ = nullptr; + } + + void Request(grpc_server* server, grpc_completion_queue* notify_cq) { + GPR_ASSERT(cq_ && !in_flight_); + in_flight_ = true; + if (method_tag_) { + if (grpc_server_request_registered_call( + server, method_tag_, &call_, &deadline_, &request_metadata_, + has_request_payload_ ? &request_payload_ : nullptr, cq_, + notify_cq, this) != GRPC_CALL_OK) { + TeardownRequest(); + return; + } + } else { + if (!call_details_) { + call_details_ = new grpc_call_details; + grpc_call_details_init(call_details_); + } + if (grpc_server_request_call(server, &call_, call_details_, + &request_metadata_, cq_, notify_cq, + this) != GRPC_CALL_OK) { + TeardownRequest(); + return; + } + } + } + + void PostShutdownCleanup() { + if (call_) { + grpc_call_unref(call_); + call_ = nullptr; + } + if (cq_) { + grpc_completion_queue_destroy(cq_); + cq_ = nullptr; + } + } + + bool FinalizeResult(void** tag, bool* status) override { + if (!*status) { + grpc_completion_queue_destroy(cq_); + cq_ = nullptr; + } + if (call_details_) { + deadline_ = call_details_->deadline; + grpc_call_details_destroy(call_details_); + grpc_call_details_init(call_details_); + } + return true; + } + + // The CallData class represents a call that is "active" as opposed + // to just being requested. It wraps and takes ownership of the cq from + // the call request + class CallData final { + public: + explicit CallData(Server* server, SyncRequest* mrd) + : cq_(mrd->cq_), + ctx_(mrd->deadline_, &mrd->request_metadata_), + has_request_payload_(mrd->has_request_payload_), + request_payload_(has_request_payload_ ? mrd->request_payload_ + : nullptr), + request_(nullptr), + method_(mrd->method_), + call_( + mrd->call_, server, &cq_, server->max_receive_message_size(), + ctx_.set_server_rpc_info(method_->name(), method_->method_type(), + server->interceptor_creators_)), + server_(server), + global_callbacks_(nullptr), + resources_(false) { + ctx_.set_call(mrd->call_); + ctx_.cq_ = &cq_; + GPR_ASSERT(mrd->in_flight_); + mrd->in_flight_ = false; + mrd->request_metadata_.count = 0; + } + + ~CallData() { + if (has_request_payload_ && request_payload_) { + grpc_byte_buffer_destroy(request_payload_); + } + } + + void Run(const std::shared_ptr& global_callbacks, + bool resources) { + global_callbacks_ = global_callbacks; + resources_ = resources; + + interceptor_methods_.SetCall(&call_); + interceptor_methods_.SetReverse(); + // Set interception point for RECV INITIAL METADATA + interceptor_methods_.AddInterceptionHookPoint( + grpc::experimental::InterceptionHookPoints:: + POST_RECV_INITIAL_METADATA); + interceptor_methods_.SetRecvInitialMetadata(&ctx_.client_metadata_); + + if (has_request_payload_) { + // Set interception point for RECV MESSAGE + auto* handler = resources_ ? method_->handler() + : server_->resource_exhausted_handler_.get(); + request_ = handler->Deserialize(call_.call(), request_payload_, + &request_status_, nullptr); + + request_payload_ = nullptr; + interceptor_methods_.AddInterceptionHookPoint( + grpc::experimental::InterceptionHookPoints::POST_RECV_MESSAGE); + interceptor_methods_.SetRecvMessage(request_, nullptr); + } + + if (interceptor_methods_.RunInterceptors( + [this]() { ContinueRunAfterInterception(); })) { + ContinueRunAfterInterception(); + } else { + // There were interceptors to be run, so ContinueRunAfterInterception + // will be run when interceptors are done. + } + } + + void ContinueRunAfterInterception() { + { + ctx_.BeginCompletionOp(&call_, nullptr, nullptr); + global_callbacks_->PreSynchronousRequest(&ctx_); + auto* handler = resources_ ? method_->handler() + : server_->resource_exhausted_handler_.get(); + handler->RunHandler(grpc::internal::MethodHandler::HandlerParameter( + &call_, &ctx_, request_, request_status_, nullptr, nullptr)); + request_ = nullptr; + global_callbacks_->PostSynchronousRequest(&ctx_); + + cq_.Shutdown(); + + grpc::internal::CompletionQueueTag* op_tag = ctx_.GetCompletionOpTag(); + cq_.TryPluck(op_tag, gpr_inf_future(GPR_CLOCK_REALTIME)); + + /* Ensure the cq_ is shutdown */ + grpc::DummyTag ignored_tag; + GPR_ASSERT(cq_.Pluck(&ignored_tag) == false); + } + delete this; + } + + private: + grpc::CompletionQueue cq_; + grpc::ServerContext ctx_; + const bool has_request_payload_; + grpc_byte_buffer* request_payload_; + void* request_; + grpc::Status request_status_; + grpc::internal::RpcServiceMethod* const method_; + grpc::internal::Call call_; + Server* server_; + std::shared_ptr global_callbacks_; + bool resources_; + grpc::internal::InterceptorBatchMethodsImpl interceptor_methods_; + }; + + private: + grpc::internal::RpcServiceMethod* const method_; + void* const method_tag_; + bool in_flight_; + const bool has_request_payload_; + grpc_call* call_; + grpc_call_details* call_details_; + gpr_timespec deadline_; + grpc_metadata_array request_metadata_; + grpc_byte_buffer* request_payload_; + grpc_completion_queue* cq_; +}; + +class Server::CallbackRequestBase : public grpc::internal::CompletionQueueTag { + public: + virtual ~CallbackRequestBase() {} + virtual bool Request() = 0; +}; + +template +class Server::CallbackRequest final : public Server::CallbackRequestBase { + public: + static_assert(std::is_base_of::value, + "ServerContextType must be derived from ServerContext"); + + // The constructor needs to know the server for this callback request and its + // index in the server's request count array to allow for proper dynamic + // requesting of incoming RPCs. For codegen services, the values of method and + // method_tag represent the defined characteristics of the method being + // requested. For generic services, method and method_tag are nullptr since + // these services don't have pre-defined methods or method registration tags. + CallbackRequest(Server* server, size_t method_idx, + grpc::internal::RpcServiceMethod* method, void* method_tag) + : server_(server), + method_index_(method_idx), + method_(method), + method_tag_(method_tag), + has_request_payload_( + method_ != nullptr && + (method->method_type() == grpc::internal::RpcMethod::NORMAL_RPC || + method->method_type() == + grpc::internal::RpcMethod::SERVER_STREAMING)), + cq_(server->CallbackCQ()), + tag_(this) { + server_->callback_reqs_outstanding_++; + Setup(); + } + + ~CallbackRequest() { + Clear(); + + // The counter of outstanding requests must be decremented + // under a lock in case it causes the server shutdown. + grpc::internal::MutexLock l(&server_->callback_reqs_mu_); + if (--server_->callback_reqs_outstanding_ == 0) { + server_->callback_reqs_done_cv_.Signal(); + } + } + + bool Request() override { + if (method_tag_) { + if (GRPC_CALL_OK != + grpc_server_request_registered_call( + server_->c_server(), method_tag_, &call_, &deadline_, + &request_metadata_, + has_request_payload_ ? &request_payload_ : nullptr, cq_->cq(), + cq_->cq(), static_cast(&tag_))) { + return false; + } + } else { + if (!call_details_) { + call_details_ = new grpc_call_details; + grpc_call_details_init(call_details_); + } + if (grpc_server_request_call(server_->c_server(), &call_, call_details_, + &request_metadata_, cq_->cq(), cq_->cq(), + static_cast(&tag_)) != GRPC_CALL_OK) { + return false; + } + } + return true; + } + + // Needs specialization to account for different processing of metadata + // in generic API + bool FinalizeResult(void** tag, bool* status) override; + + private: + // method_name needs to be specialized between named method and generic + const char* method_name() const; + + class CallbackCallTag : public grpc_experimental_completion_queue_functor { + public: + CallbackCallTag(Server::CallbackRequest* req) + : req_(req) { + functor_run = &CallbackCallTag::StaticRun; + } + + // force_run can not be performed on a tag if operations using this tag + // have been sent to PerformOpsOnCall. It is intended for error conditions + // that are detected before the operations are internally processed. + void force_run(bool ok) { Run(ok); } + + private: + Server::CallbackRequest* req_; + grpc::internal::Call* call_; + + static void StaticRun(grpc_experimental_completion_queue_functor* cb, + int ok) { + static_cast(cb)->Run(static_cast(ok)); + } + void Run(bool ok) { + void* ignored = req_; + bool new_ok = ok; + GPR_ASSERT(!req_->FinalizeResult(&ignored, &new_ok)); + GPR_ASSERT(ignored == req_); + + int count = + static_cast(gpr_atm_no_barrier_fetch_add( + &req_->server_ + ->callback_unmatched_reqs_count_[req_->method_index_], + -1)) - + 1; + if (!ok) { + // The call has been shutdown. + // Delete its contents to free up the request. + delete req_; + return; + } + + // If this was the last request in the list or it is below the soft + // minimum and there are spare requests available, set up a new one. + if (count == 0 || (count < SOFT_MINIMUM_SPARE_CALLBACK_REQS_PER_METHOD && + req_->server_->callback_reqs_outstanding_ < + SOFT_MAXIMUM_CALLBACK_REQS_OUTSTANDING)) { + auto* new_req = new CallbackRequest( + req_->server_, req_->method_index_, req_->method_, + req_->method_tag_); + if (!new_req->Request()) { + // The server must have just decided to shutdown. + gpr_atm_no_barrier_fetch_add( + &new_req->server_ + ->callback_unmatched_reqs_count_[new_req->method_index_], + -1); + delete new_req; + } + } + + // Bind the call, deadline, and metadata from what we got + req_->ctx_.set_call(req_->call_); + req_->ctx_.cq_ = req_->cq_; + req_->ctx_.BindDeadlineAndMetadata(req_->deadline_, + &req_->request_metadata_); + req_->request_metadata_.count = 0; + + // Create a C++ Call to control the underlying core call + call_ = + new (grpc_call_arena_alloc(req_->call_, sizeof(grpc::internal::Call))) + grpc::internal::Call( + req_->call_, req_->server_, req_->cq_, + req_->server_->max_receive_message_size(), + req_->ctx_.set_server_rpc_info( + req_->method_name(), + (req_->method_ != nullptr) + ? req_->method_->method_type() + : grpc::internal::RpcMethod::BIDI_STREAMING, + req_->server_->interceptor_creators_)); + + req_->interceptor_methods_.SetCall(call_); + req_->interceptor_methods_.SetReverse(); + // Set interception point for RECV INITIAL METADATA + req_->interceptor_methods_.AddInterceptionHookPoint( + grpc::experimental::InterceptionHookPoints:: + POST_RECV_INITIAL_METADATA); + req_->interceptor_methods_.SetRecvInitialMetadata( + &req_->ctx_.client_metadata_); + + if (req_->has_request_payload_) { + // Set interception point for RECV MESSAGE + req_->request_ = req_->method_->handler()->Deserialize( + req_->call_, req_->request_payload_, &req_->request_status_, + &req_->handler_data_); + req_->request_payload_ = nullptr; + req_->interceptor_methods_.AddInterceptionHookPoint( + grpc::experimental::InterceptionHookPoints::POST_RECV_MESSAGE); + req_->interceptor_methods_.SetRecvMessage(req_->request_, nullptr); + } + + if (req_->interceptor_methods_.RunInterceptors( + [this] { ContinueRunAfterInterception(); })) { + ContinueRunAfterInterception(); + } else { + // There were interceptors to be run, so ContinueRunAfterInterception + // will be run when interceptors are done. + } + } + void ContinueRunAfterInterception() { + auto* handler = (req_->method_ != nullptr) + ? req_->method_->handler() + : req_->server_->generic_handler_.get(); + handler->RunHandler(grpc::internal::MethodHandler::HandlerParameter( + call_, &req_->ctx_, req_->request_, req_->request_status_, + req_->handler_data_, [this] { + // Recycle this request if there aren't too many outstanding. + // Note that we don't have to worry about a case where there + // are no requests waiting to match for this method since that + // is already taken care of when binding a request to a call. + // TODO(vjpai): Also don't recycle this request if the dynamic + // load no longer justifies it. Consider measuring + // dynamic load and setting a target accordingly. + if (req_->server_->callback_reqs_outstanding_ < + SOFT_MAXIMUM_CALLBACK_REQS_OUTSTANDING) { + req_->Clear(); + req_->Setup(); + } else { + // We can free up this request because there are too many + delete req_; + return; + } + if (!req_->Request()) { + // The server must have just decided to shutdown. + delete req_; + } + })); + } + }; + + void Clear() { + if (call_details_) { + delete call_details_; + call_details_ = nullptr; + } + grpc_metadata_array_destroy(&request_metadata_); + if (has_request_payload_ && request_payload_) { + grpc_byte_buffer_destroy(request_payload_); + } + ctx_.Clear(); + interceptor_methods_.ClearState(); + } + + void Setup() { + gpr_atm_no_barrier_fetch_add( + &server_->callback_unmatched_reqs_count_[method_index_], 1); + grpc_metadata_array_init(&request_metadata_); + ctx_.Setup(gpr_inf_future(GPR_CLOCK_REALTIME)); + request_payload_ = nullptr; + request_ = nullptr; + handler_data_ = nullptr; + request_status_ = grpc::Status(); + } + + Server* const server_; + const size_t method_index_; + grpc::internal::RpcServiceMethod* const method_; + void* const method_tag_; + const bool has_request_payload_; + grpc_byte_buffer* request_payload_; + void* request_; + void* handler_data_; + grpc::Status request_status_; + grpc_call_details* call_details_ = nullptr; + grpc_call* call_; + gpr_timespec deadline_; + grpc_metadata_array request_metadata_; + grpc::CompletionQueue* cq_; + CallbackCallTag tag_; + ServerContextType ctx_; + grpc::internal::InterceptorBatchMethodsImpl interceptor_methods_; +}; + +template <> +bool Server::CallbackRequest::FinalizeResult( + void** tag, bool* status) { + return false; +} + +template <> +bool Server::CallbackRequest::FinalizeResult( + void** tag, bool* status) { + if (*status) { + // TODO(yangg) remove the copy here + ctx_.method_ = grpc::StringFromCopiedSlice(call_details_->method); + ctx_.host_ = grpc::StringFromCopiedSlice(call_details_->host); + } + grpc_slice_unref(call_details_->method); + grpc_slice_unref(call_details_->host); + return false; +} + +template <> +const char* Server::CallbackRequest::method_name() const { + return method_->name(); +} + +template <> +const char* Server::CallbackRequest::method_name() + const { + return ctx_.method().c_str(); +} + +// Implementation of ThreadManager. Each instance of SyncRequestThreadManager +// manages a pool of threads that poll for incoming Sync RPCs and call the +// appropriate RPC handlers +class Server::SyncRequestThreadManager : public grpc::ThreadManager { + public: + SyncRequestThreadManager(Server* server, grpc::CompletionQueue* server_cq, + std::shared_ptr global_callbacks, + grpc_resource_quota* rq, int min_pollers, + int max_pollers, int cq_timeout_msec) + : ThreadManager("SyncServer", rq, min_pollers, max_pollers), + server_(server), + server_cq_(server_cq), + cq_timeout_msec_(cq_timeout_msec), + global_callbacks_(std::move(global_callbacks)) {} + + WorkStatus PollForWork(void** tag, bool* ok) override { + *tag = nullptr; + // TODO(ctiller): workaround for GPR_TIMESPAN based deadlines not working + // right now + gpr_timespec deadline = + gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), + gpr_time_from_millis(cq_timeout_msec_, GPR_TIMESPAN)); + + switch (server_cq_->AsyncNext(tag, ok, deadline)) { + case grpc::CompletionQueue::TIMEOUT: + return TIMEOUT; + case grpc::CompletionQueue::SHUTDOWN: + return SHUTDOWN; + case grpc::CompletionQueue::GOT_EVENT: + return WORK_FOUND; + } + + GPR_UNREACHABLE_CODE(return TIMEOUT); + } + + void DoWork(void* tag, bool ok, bool resources) override { + SyncRequest* sync_req = static_cast(tag); + + if (!sync_req) { + // No tag. Nothing to work on. This is an unlikley scenario and possibly a + // bug in RPC Manager implementation. + gpr_log(GPR_ERROR, "Sync server. DoWork() was called with NULL tag"); + return; + } + + if (ok) { + // Calldata takes ownership of the completion queue and interceptors + // inside sync_req + auto* cd = new SyncRequest::CallData(server_, sync_req); + // Prepare for the next request + if (!IsShutdown()) { + sync_req->SetupRequest(); // Create new completion queue for sync_req + sync_req->Request(server_->c_server(), server_cq_->cq()); + } + + GPR_TIMER_SCOPE("cd.Run()", 0); + cd->Run(global_callbacks_, resources); + } + // TODO (sreek) If ok is false here (which it isn't in case of + // grpc_request_registered_call), we should still re-queue the request + // object + } + + void AddSyncMethod(grpc::internal::RpcServiceMethod* method, void* tag) { + sync_requests_.emplace_back(new SyncRequest(method, tag)); + } + + void AddUnknownSyncMethod() { + if (!sync_requests_.empty()) { + unknown_method_.reset(new grpc::internal::RpcServiceMethod( + "unknown", grpc::internal::RpcMethod::BIDI_STREAMING, + new grpc::internal::UnknownMethodHandler)); + sync_requests_.emplace_back( + new SyncRequest(unknown_method_.get(), nullptr)); + } + } + + void Shutdown() override { + ThreadManager::Shutdown(); + server_cq_->Shutdown(); + } + + void Wait() override { + ThreadManager::Wait(); + // Drain any pending items from the queue + void* tag; + bool ok; + while (server_cq_->Next(&tag, &ok)) { + if (ok) { + // If a request was pulled off the queue, it means that the thread + // handling the request added it to the completion queue after shutdown + // was called - because the thread had already started and checked the + // shutdown flag before shutdown was called. In this case, we simply + // clean it up here, *after* calling wait on all the worker threads, at + // which point we are certain no in-flight requests will add more to the + // queue. This fixes an intermittent memory leak on shutdown. + SyncRequest* sync_req = static_cast(tag); + sync_req->PostShutdownCleanup(); + } + } + } + + void Start() { + if (!sync_requests_.empty()) { + for (auto m = sync_requests_.begin(); m != sync_requests_.end(); m++) { + (*m)->SetupRequest(); + (*m)->Request(server_->c_server(), server_cq_->cq()); + } + + Initialize(); // ThreadManager's Initialize() + } + } + + private: + Server* server_; + grpc::CompletionQueue* server_cq_; + int cq_timeout_msec_; + std::vector> sync_requests_; + std::unique_ptr unknown_method_; + std::shared_ptr global_callbacks_; +}; + +static grpc::internal::GrpcLibraryInitializer g_gli_initializer; +Server::Server( + int max_receive_message_size, grpc::ChannelArguments* args, + std::shared_ptr>> + sync_server_cqs, + int min_pollers, int max_pollers, int sync_cq_timeout_msec, + grpc_resource_quota* server_rq, + std::vector< + std::unique_ptr> + interceptor_creators) + : interceptor_creators_(std::move(interceptor_creators)), + max_receive_message_size_(max_receive_message_size), + sync_server_cqs_(std::move(sync_server_cqs)), + started_(false), + shutdown_(false), + shutdown_notified_(false), + server_(nullptr), + server_initializer_(new grpc_impl::ServerInitializer(this)), + health_check_service_disabled_(false) { + g_gli_initializer.summon(); + gpr_once_init(&grpc::g_once_init_callbacks, grpc::InitGlobalCallbacks); + global_callbacks_ = grpc::g_callbacks; + global_callbacks_->UpdateArguments(args); + + if (sync_server_cqs_ != nullptr) { + bool default_rq_created = false; + if (server_rq == nullptr) { + server_rq = grpc_resource_quota_create("SyncServer-default-rq"); + grpc_resource_quota_set_max_threads(server_rq, + DEFAULT_MAX_SYNC_SERVER_THREADS); + default_rq_created = true; + } + + for (const auto& it : *sync_server_cqs_) { + sync_req_mgrs_.emplace_back(new SyncRequestThreadManager( + this, it.get(), global_callbacks_, server_rq, min_pollers, + max_pollers, sync_cq_timeout_msec)); + } + + if (default_rq_created) { + grpc_resource_quota_unref(server_rq); + } + } + + grpc_channel_args channel_args; + args->SetChannelArgs(&channel_args); + + for (size_t i = 0; i < channel_args.num_args; i++) { + if (0 == strcmp(channel_args.args[i].key, + grpc::kHealthCheckServiceInterfaceArg)) { + if (channel_args.args[i].value.pointer.p == nullptr) { + health_check_service_disabled_ = true; + } else { + health_check_service_.reset( + static_cast( + channel_args.args[i].value.pointer.p)); + } + break; + } + } + + server_ = grpc_server_create(&channel_args, nullptr); +} + +Server::~Server() { + { + grpc::internal::ReleasableMutexLock lock(&mu_); + if (callback_cq_ != nullptr) { + callback_cq_->Shutdown(); + } + if (started_ && !shutdown_) { + lock.Unlock(); + Shutdown(); + } else if (!started_) { + // Shutdown the completion queues + for (auto it = sync_req_mgrs_.begin(); it != sync_req_mgrs_.end(); it++) { + (*it)->Shutdown(); + } + } + } + + grpc_server_destroy(server_); + for (auto& per_method_count : callback_unmatched_reqs_count_) { + // There should be no more unmatched callbacks for any method + // as each request is failed by Shutdown. Check that this actually + // happened + GPR_ASSERT(static_cast(gpr_atm_no_barrier_load(&per_method_count)) == + 0); + } +} + +void Server::SetGlobalCallbacks(GlobalCallbacks* callbacks) { + GPR_ASSERT(!grpc::g_callbacks); + GPR_ASSERT(callbacks); + grpc::g_callbacks.reset(callbacks); +} + +grpc_server* Server::c_server() { return server_; } + +std::shared_ptr Server::InProcessChannel( + const grpc::ChannelArguments& args) { + grpc_channel_args channel_args = args.c_channel_args(); + return grpc::CreateChannelInternal( + "inproc", grpc_inproc_channel_create(server_, &channel_args, nullptr), + std::vector>()); +} + +std::shared_ptr +Server::experimental_type::InProcessChannelWithInterceptors( + const grpc::ChannelArguments& args, + std::vector< + std::unique_ptr> + interceptor_creators) { + grpc_channel_args channel_args = args.c_channel_args(); + return grpc::CreateChannelInternal( + "inproc", + grpc_inproc_channel_create(server_->server_, &channel_args, nullptr), + std::move(interceptor_creators)); +} + +static grpc_server_register_method_payload_handling PayloadHandlingForMethod( + grpc::internal::RpcServiceMethod* method) { + switch (method->method_type()) { + case grpc::internal::RpcMethod::NORMAL_RPC: + case grpc::internal::RpcMethod::SERVER_STREAMING: + return GRPC_SRM_PAYLOAD_READ_INITIAL_BYTE_BUFFER; + case grpc::internal::RpcMethod::CLIENT_STREAMING: + case grpc::internal::RpcMethod::BIDI_STREAMING: + return GRPC_SRM_PAYLOAD_NONE; + } + GPR_UNREACHABLE_CODE(return GRPC_SRM_PAYLOAD_NONE;); +} + +bool Server::RegisterService(const grpc::string* host, grpc::Service* service) { + bool has_async_methods = service->has_async_methods(); + if (has_async_methods) { + GPR_ASSERT(service->server_ == nullptr && + "Can only register an asynchronous service against one server."); + service->server_ = this; + } + + const char* method_name = nullptr; + + for (auto it = service->methods_.begin(); it != service->methods_.end(); + ++it) { + if (it->get() == nullptr) { // Handled by generic service if any. + continue; + } + + grpc::internal::RpcServiceMethod* method = it->get(); + void* method_registration_tag = grpc_server_register_method( + server_, method->name(), host ? host->c_str() : nullptr, + PayloadHandlingForMethod(method), 0); + if (method_registration_tag == nullptr) { + gpr_log(GPR_DEBUG, "Attempt to register %s multiple times", + method->name()); + return false; + } + + if (method->handler() == nullptr) { // Async method without handler + method->set_server_tag(method_registration_tag); + } else if (method->api_type() == + grpc::internal::RpcServiceMethod::ApiType::SYNC) { + for (auto it = sync_req_mgrs_.begin(); it != sync_req_mgrs_.end(); it++) { + (*it)->AddSyncMethod(method, method_registration_tag); + } + } else { + // a callback method. Register at least some callback requests + callback_unmatched_reqs_count_.push_back(0); + auto method_index = callback_unmatched_reqs_count_.size() - 1; + // TODO(vjpai): Register these dynamically based on need + for (int i = 0; i < DEFAULT_CALLBACK_REQS_PER_METHOD; i++) { + callback_reqs_to_start_.push_back( + new CallbackRequest(this, method_index, method, + method_registration_tag)); + } + // Enqueue it so that it will be Request'ed later after all request + // matchers are created at core server startup + } + + method_name = method->name(); + } + + // Parse service name. + if (method_name != nullptr) { + std::stringstream ss(method_name); + grpc::string service_name; + if (std::getline(ss, service_name, '/') && + std::getline(ss, service_name, '/')) { + services_.push_back(service_name); + } + } + return true; +} + +void Server::RegisterAsyncGenericService(grpc::AsyncGenericService* service) { + GPR_ASSERT(service->server_ == nullptr && + "Can only register an async generic service against one server."); + service->server_ = this; + has_async_generic_service_ = true; +} + +void Server::RegisterCallbackGenericService( + grpc::experimental::CallbackGenericService* service) { + GPR_ASSERT( + service->server_ == nullptr && + "Can only register a callback generic service against one server."); + service->server_ = this; + has_callback_generic_service_ = true; + generic_handler_.reset(service->Handler()); + + callback_unmatched_reqs_count_.push_back(0); + auto method_index = callback_unmatched_reqs_count_.size() - 1; + // TODO(vjpai): Register these dynamically based on need + for (int i = 0; i < DEFAULT_CALLBACK_REQS_PER_METHOD; i++) { + callback_reqs_to_start_.push_back( + new CallbackRequest(this, method_index, + nullptr, nullptr)); + } +} + +int Server::AddListeningPort(const grpc::string& addr, + grpc::ServerCredentials* creds) { + GPR_ASSERT(!started_); + int port = creds->AddPortToServer(addr, server_); + global_callbacks_->AddPort(this, addr, creds, port); + return port; +} + +void Server::Start(grpc::ServerCompletionQueue** cqs, size_t num_cqs) { + GPR_ASSERT(!started_); + global_callbacks_->PreServerStart(this); + started_ = true; + + // Only create default health check service when user did not provide an + // explicit one. + grpc::ServerCompletionQueue* health_check_cq = nullptr; + grpc::DefaultHealthCheckService::HealthCheckServiceImpl* + default_health_check_service_impl = nullptr; + if (health_check_service_ == nullptr && !health_check_service_disabled_ && + grpc::DefaultHealthCheckServiceEnabled()) { + auto* default_hc_service = new grpc::DefaultHealthCheckService; + health_check_service_.reset(default_hc_service); + // We create a non-polling CQ to avoid impacting application + // performance. This ensures that we don't introduce thread hops + // for application requests that wind up on this CQ, which is polled + // in its own thread. + health_check_cq = new grpc::ServerCompletionQueue( + GRPC_CQ_NEXT, GRPC_CQ_NON_POLLING, nullptr); + grpc_server_register_completion_queue(server_, health_check_cq->cq(), + nullptr); + default_health_check_service_impl = + default_hc_service->GetHealthCheckService( + std::unique_ptr(health_check_cq)); + RegisterService(nullptr, default_health_check_service_impl); + } + + // If this server uses callback methods, then create a callback generic + // service to handle any unimplemented methods using the default reactor + // creator + if (!callback_reqs_to_start_.empty() && !has_callback_generic_service_) { + unimplemented_service_.reset( + new grpc::experimental::CallbackGenericService); + RegisterCallbackGenericService(unimplemented_service_.get()); + } + + grpc_server_start(server_); + + if (!has_async_generic_service_ && !has_callback_generic_service_) { + for (auto it = sync_req_mgrs_.begin(); it != sync_req_mgrs_.end(); it++) { + (*it)->AddUnknownSyncMethod(); + } + + for (size_t i = 0; i < num_cqs; i++) { + if (cqs[i]->IsFrequentlyPolled()) { + new UnimplementedAsyncRequest(this, cqs[i]); + } + } + if (health_check_cq != nullptr) { + new UnimplementedAsyncRequest(this, health_check_cq); + } + } + + // If this server has any support for synchronous methods (has any sync + // server CQs), make sure that we have a ResourceExhausted handler + // to deal with the case of thread exhaustion + if (sync_server_cqs_ != nullptr && !sync_server_cqs_->empty()) { + resource_exhausted_handler_.reset( + new grpc::internal::ResourceExhaustedHandler); + } + + for (auto it = sync_req_mgrs_.begin(); it != sync_req_mgrs_.end(); it++) { + (*it)->Start(); + } + + for (auto* cbreq : callback_reqs_to_start_) { + GPR_ASSERT(cbreq->Request()); + } + callback_reqs_to_start_.clear(); + + if (default_health_check_service_impl != nullptr) { + default_health_check_service_impl->StartServingThread(); + } +} + +void Server::ShutdownInternal(gpr_timespec deadline) { + grpc::internal::MutexLock lock(&mu_); + if (shutdown_) { + return; + } + + shutdown_ = true; + + /// The completion queue to use for server shutdown completion notification + grpc::CompletionQueue shutdown_cq; + grpc::ShutdownTag shutdown_tag; // Dummy shutdown tag + grpc_server_shutdown_and_notify(server_, shutdown_cq.cq(), &shutdown_tag); + + shutdown_cq.Shutdown(); + + void* tag; + bool ok; + grpc::CompletionQueue::NextStatus status = + shutdown_cq.AsyncNext(&tag, &ok, deadline); + + // If this timed out, it means we are done with the grace period for a clean + // shutdown. We should force a shutdown now by cancelling all inflight calls + if (status == grpc::CompletionQueue::NextStatus::TIMEOUT) { + grpc_server_cancel_all_calls(server_); + } + // Else in case of SHUTDOWN or GOT_EVENT, it means that the server has + // successfully shutdown + + // Shutdown all ThreadManagers. This will try to gracefully stop all the + // threads in the ThreadManagers (once they process any inflight requests) + for (auto it = sync_req_mgrs_.begin(); it != sync_req_mgrs_.end(); it++) { + (*it)->Shutdown(); // ThreadManager's Shutdown() + } + + // Wait for threads in all ThreadManagers to terminate + for (auto it = sync_req_mgrs_.begin(); it != sync_req_mgrs_.end(); it++) { + (*it)->Wait(); + } + + // Wait for all outstanding callback requests to complete + // (whether waiting for a match or already active). + // We know that no new requests will be created after this point + // because they are only created at server startup time or when + // we have a successful match on a request. During the shutdown phase, + // requests that have not yet matched will be failed rather than + // allowed to succeed, which will cause the server to delete the + // request and decrement the count. Possibly a request will match before + // the shutdown but then find that shutdown has already started by the + // time it tries to register a new request. In that case, the registration + // will report a failure, indicating a shutdown and again we won't end + // up incrementing the counter. + { + grpc::internal::MutexLock cblock(&callback_reqs_mu_); + callback_reqs_done_cv_.WaitUntil( + &callback_reqs_mu_, [this] { return callback_reqs_outstanding_ == 0; }); + } + + // Drain the shutdown queue (if the previous call to AsyncNext() timed out + // and we didn't remove the tag from the queue yet) + while (shutdown_cq.Next(&tag, &ok)) { + // Nothing to be done here. Just ignore ok and tag values + } + + shutdown_notified_ = true; + shutdown_cv_.Broadcast(); +} + +void Server::Wait() { + grpc::internal::MutexLock lock(&mu_); + while (started_ && !shutdown_notified_) { + shutdown_cv_.Wait(&mu_); + } +} + +void Server::PerformOpsOnCall(grpc::internal::CallOpSetInterface* ops, + grpc::internal::Call* call) { + ops->FillOps(call); +} + +bool Server::UnimplementedAsyncRequest::FinalizeResult(void** tag, + bool* status) { + if (GenericAsyncRequest::FinalizeResult(tag, status)) { + // We either had no interceptors run or we are done intercepting + if (*status) { + new UnimplementedAsyncRequest(server_, cq_); + new UnimplementedAsyncResponse(this); + } else { + delete this; + } + } else { + // The tag was swallowed due to interception. We will see it again. + } + return false; +} + +Server::UnimplementedAsyncResponse::UnimplementedAsyncResponse( + UnimplementedAsyncRequest* request) + : request_(request) { + grpc::Status status(grpc::StatusCode::UNIMPLEMENTED, ""); + grpc::internal::UnknownMethodHandler::FillOps(request_->context(), this); + request_->stream()->call_.PerformOps(this); +} + +grpc::ServerInitializer* Server::initializer() { + return server_initializer_.get(); +} + +grpc::CompletionQueue* Server::CallbackCQ() { // TODO(vjpai): Consider using a single global CQ for the default CQ // if there is no explicit per-server CQ registered - std::lock_guard l(mu_); + grpc::internal::MutexLock l(&mu_); if (callback_cq_ == nullptr) { - auto* shutdown_callback = new ShutdownCallback; - callback_cq_ = new CompletionQueue(grpc_completion_queue_attributes{ + auto* shutdown_callback = new grpc::ShutdownCallback; + callback_cq_ = new grpc::CompletionQueue(grpc_completion_queue_attributes{ GRPC_CQ_CURRENT_VERSION, GRPC_CQ_CALLBACK, GRPC_CQ_DEFAULT_POLLING, shutdown_callback}); @@ -1160,6 +1357,6 @@ CompletionQueue* Server::CallbackCQ() { shutdown_callback->TakeCQ(callback_cq_); } return callback_cq_; -}; +} -} // namespace grpc +} // namespace grpc_impl diff --git a/src/cpp/server/server_context.cc b/src/cpp/server/server_context.cc index 9c01f896e6c..eced89d1a79 100644 --- a/src/cpp/server/server_context.cc +++ b/src/cpp/server/server_context.cc @@ -17,6 +17,7 @@ */ #include +#include #include #include @@ -31,6 +32,8 @@ #include #include +#include "src/core/lib/gprpp/ref_counted.h" +#include "src/core/lib/gprpp/sync.h" #include "src/core/lib/surface/call.h" namespace grpc { @@ -41,8 +44,9 @@ class ServerContext::CompletionOp final : public internal::CallOpSetInterface { public: // initial refs: one in the server context, one in the cq // must ref the call before calling constructor and after deleting this - CompletionOp(internal::Call* call) + CompletionOp(internal::Call* call, internal::ServerReactor* reactor) : call_(*call), + reactor_(reactor), has_tag_(false), tag_(nullptr), core_cq_tag_(this), @@ -92,6 +96,22 @@ class ServerContext::CompletionOp final : public internal::CallOpSetInterface { tag_ = tag; } + void SetCancelCallback(std::function callback) { + grpc_core::MutexLock lock(&mu_); + + if (finalized_ && (cancelled_ != 0)) { + callback(); + return; + } + + cancel_callback_ = std::move(callback); + } + + void ClearCancelCallback() { + grpc_core::MutexLock g(&mu_); + cancel_callback_ = nullptr; + } + void set_core_cq_tag(void* core_cq_tag) { core_cq_tag_ = core_cq_tag; } void* core_cq_tag() override { return core_cq_tag_; } @@ -114,43 +134,37 @@ class ServerContext::CompletionOp final : public internal::CallOpSetInterface { done_intercepting_ = true; if (!has_tag_) { /* We don't have a tag to return. */ - std::unique_lock lock(mu_); - if (--refs_ == 0) { - lock.unlock(); - grpc_call* call = call_.call(); - delete this; - grpc_call_unref(call); - } + Unref(); return; } /* Start a dummy op so that we can return the tag */ - GPR_CODEGEN_ASSERT(GRPC_CALL_OK == - g_core_codegen_interface->grpc_call_start_batch( - call_.call(), nullptr, 0, this, nullptr)); + GPR_CODEGEN_ASSERT( + GRPC_CALL_OK == + grpc_call_start_batch(call_.call(), nullptr, 0, core_cq_tag_, nullptr)); } private: bool CheckCancelledNoPluck() { - std::lock_guard g(mu_); + grpc_core::MutexLock lock(&mu_); return finalized_ ? (cancelled_ != 0) : false; } internal::Call call_; + internal::ServerReactor* const reactor_; bool has_tag_; void* tag_; void* core_cq_tag_; - std::mutex mu_; - int refs_; + grpc_core::RefCount refs_; + grpc_core::Mutex mu_; bool finalized_; - int cancelled_; + int cancelled_; // This is an int (not bool) because it is passed to core + std::function cancel_callback_; bool done_intercepting_; internal::InterceptorBatchMethodsImpl interceptor_methods_; }; void ServerContext::CompletionOp::Unref() { - std::unique_lock lock(mu_); - if (--refs_ == 0) { - lock.unlock(); + if (refs_.Unref()) { grpc_call* call = call_.call(); delete this; grpc_call_unref(call); @@ -173,27 +187,44 @@ void ServerContext::CompletionOp::FillOps(internal::Call* call) { bool ServerContext::CompletionOp::FinalizeResult(void** tag, bool* status) { bool ret = false; - std::unique_lock lock(mu_); + grpc_core::ReleasableMutexLock lock(&mu_); if (done_intercepting_) { /* We are done intercepting. */ if (has_tag_) { *tag = tag_; ret = true; } - if (--refs_ == 0) { - lock.unlock(); - grpc_call* call = call_.call(); - delete this; - grpc_call_unref(call); - } + Unref(); return ret; } finalized_ = true; - if (!*status) cancelled_ = 1; - /* Release the lock since we are going to be running through interceptors now - */ - lock.unlock(); + // If for some reason the incoming status is false, mark that as a + // cancellation. + // TODO(vjpai): does this ever happen? + if (!*status) { + cancelled_ = 1; + } + + // Decide whether to call the cancel callback before releasing the lock + bool call_cancel = (cancelled_ != 0); + + // If it's a unary cancel callback, call it under the lock so that it doesn't + // race with ClearCancelCallback. Although we don't normally call callbacks + // under a lock, this is a special case since the user needs a guarantee that + // the callback won't issue or run after ClearCancelCallback has returned. + // This requirement imposes certain restrictions on the callback, documented + // in the API comments of SetCancelCallback. + if (cancel_callback_) { + cancel_callback_(); + } + + // Release the lock since we may call a callback and interceptors now. + lock.Unlock(); + + if (call_cancel && reactor_ != nullptr) { + reactor_->MaybeCallOnCancel(); + } /* Add interception point and run through interceptors */ interceptor_methods_.AddInterceptionHookPoint( experimental::InterceptionHookPoints::POST_RECV_CLOSE); @@ -203,13 +234,7 @@ bool ServerContext::CompletionOp::FinalizeResult(void** tag, bool* status) { *tag = tag_; ret = true; } - lock.lock(); - if (--refs_ == 0) { - lock.unlock(); - grpc_call* call = call_.call(); - delete this; - grpc_call_unref(call); - } + Unref(); return ret; } /* There are interceptors to be run. Return false for now */ @@ -251,21 +276,25 @@ void ServerContext::Clear() { initial_metadata_.clear(); trailing_metadata_.clear(); client_metadata_.Reset(); - if (call_) { - grpc_call_unref(call_); - } if (completion_op_) { completion_op_->Unref(); + completion_op_ = nullptr; completion_tag_.Clear(); } if (rpc_info_) { rpc_info_->Unref(); + rpc_info_ = nullptr; + } + if (call_) { + auto* call = call_; + call_ = nullptr; + grpc_call_unref(call); } - // Don't need to clear out call_, completion_op_, or rpc_info_ because this is - // either called from destructor or just before Setup } -void ServerContext::BeginCompletionOp(internal::Call* call, bool callback) { +void ServerContext::BeginCompletionOp(internal::Call* call, + std::function callback, + internal::ServerReactor* reactor) { GPR_ASSERT(!completion_op_); if (rpc_info_) { rpc_info_->Ref(); @@ -273,10 +302,11 @@ void ServerContext::BeginCompletionOp(internal::Call* call, bool callback) { grpc_call_ref(call->call()); completion_op_ = new (grpc_call_arena_alloc(call->call(), sizeof(CompletionOp))) - CompletionOp(call); - if (callback) { - completion_tag_.Set(call->call(), nullptr, completion_op_); + CompletionOp(call, reactor); + if (callback != nullptr) { + completion_tag_.Set(call->call(), std::move(callback), completion_op_); completion_op_->set_core_cq_tag(&completion_tag_); + completion_op_->set_tag(completion_op_); } else if (has_notify_when_done_tag_) { completion_op_->set_tag(async_notify_when_done_tag_); } @@ -311,6 +341,14 @@ void ServerContext::TryCancel() const { } } +void ServerContext::SetCancelCallback(std::function callback) { + completion_op_->SetCancelCallback(std::move(callback)); +} + +void ServerContext::ClearCancelCallback() { + completion_op_->ClearCancelCallback(); +} + bool ServerContext::IsCancelled() const { if (completion_tag_) { // When using callback API, this result is always valid. diff --git a/src/cpp/server/server_credentials.cc b/src/cpp/server/server_credentials.cc index c3b3a8b3793..8b85264f9d7 100644 --- a/src/cpp/server/server_credentials.cc +++ b/src/cpp/server/server_credentials.cc @@ -16,10 +16,10 @@ * */ -#include +#include -namespace grpc { +namespace grpc_impl { ServerCredentials::~ServerCredentials() {} -} // namespace grpc +} // namespace grpc_impl diff --git a/src/cpp/server/server_posix.cc b/src/cpp/server/server_posix.cc index 7c221ed036a..7b77e24bc0e 100644 --- a/src/cpp/server/server_posix.cc +++ b/src/cpp/server/server_posix.cc @@ -20,14 +20,14 @@ #include -namespace grpc { +namespace grpc_impl { #ifdef GPR_SUPPORT_CHANNELS_FROM_FD -void AddInsecureChannelFromFd(Server* server, int fd) { +void AddInsecureChannelFromFd(grpc::Server* server, int fd) { grpc_server_add_insecure_channel_from_fd(server->c_server(), nullptr, fd); } #endif // GPR_SUPPORT_CHANNELS_FROM_FD -} // namespace grpc +} // namespace grpc_impl diff --git a/src/cpp/thread_manager/thread_manager.cc b/src/cpp/thread_manager/thread_manager.cc index 3e8606a76fd..2b65352f797 100644 --- a/src/cpp/thread_manager/thread_manager.cc +++ b/src/cpp/thread_manager/thread_manager.cc @@ -62,7 +62,7 @@ ThreadManager::ThreadManager(const char* name, ThreadManager::~ThreadManager() { { - std::lock_guard lock(mu_); + grpc_core::MutexLock lock(&mu_); GPR_ASSERT(num_threads_ == 0); } @@ -72,38 +72,38 @@ ThreadManager::~ThreadManager() { } void ThreadManager::Wait() { - std::unique_lock lock(mu_); + grpc_core::MutexLock lock(&mu_); while (num_threads_ != 0) { - shutdown_cv_.wait(lock); + shutdown_cv_.Wait(&mu_); } } void ThreadManager::Shutdown() { - std::lock_guard lock(mu_); + grpc_core::MutexLock lock(&mu_); shutdown_ = true; } bool ThreadManager::IsShutdown() { - std::lock_guard lock(mu_); + grpc_core::MutexLock lock(&mu_); return shutdown_; } int ThreadManager::GetMaxActiveThreadsSoFar() { - std::lock_guard list_lock(list_mu_); + grpc_core::MutexLock list_lock(&list_mu_); return max_active_threads_sofar_; } void ThreadManager::MarkAsCompleted(WorkerThread* thd) { { - std::lock_guard list_lock(list_mu_); + grpc_core::MutexLock list_lock(&list_mu_); completed_threads_.push_back(thd); } { - std::lock_guard lock(mu_); + grpc_core::MutexLock lock(&mu_); num_threads_--; if (num_threads_ == 0) { - shutdown_cv_.notify_one(); + shutdown_cv_.Signal(); } } @@ -116,7 +116,7 @@ void ThreadManager::CleanupCompletedThreads() { { // swap out the completed threads list: allows other threads to clean up // more quickly - std::unique_lock lock(list_mu_); + grpc_core::MutexLock lock(&list_mu_); completed_threads.swap(completed_threads_); } for (auto thd : completed_threads) delete thd; @@ -132,7 +132,7 @@ void ThreadManager::Initialize() { } { - std::unique_lock lock(mu_); + grpc_core::MutexLock lock(&mu_); num_pollers_ = min_pollers_; num_threads_ = min_pollers_; max_active_threads_sofar_ = min_pollers_; @@ -149,7 +149,7 @@ void ThreadManager::MainWorkLoop() { bool ok; WorkStatus work_status = PollForWork(&tag, &ok); - std::unique_lock lock(mu_); + grpc_core::ReleasableMutexLock lock(&mu_); // Reduce the number of pollers by 1 and check what happened with the poll num_pollers_--; bool done = false; @@ -176,30 +176,30 @@ void ThreadManager::MainWorkLoop() { max_active_threads_sofar_ = num_threads_; } // Drop lock before spawning thread to avoid contention - lock.unlock(); + lock.Unlock(); new WorkerThread(this); } else if (num_pollers_ > 0) { // There is still at least some thread polling, so we can go on // even though we are below the number of pollers that we would // like to have (min_pollers_) - lock.unlock(); + lock.Unlock(); } else { // There are no pollers to spare and we couldn't allocate // a new thread, so resources are exhausted! - lock.unlock(); + lock.Unlock(); resource_exhausted = true; } } else { // There are a sufficient number of pollers available so we can do // the work and continue polling with our existing poller threads - lock.unlock(); + lock.Unlock(); } // Lock is always released at this point - do the application work // or return resource exhausted if there is new work but we couldn't // get a thread in which to do it. DoWork(tag, ok, !resource_exhausted); // Take the lock again to check post conditions - lock.lock(); + lock.Lock(); // If we're shutdown, we should finish at this point. if (shutdown_) done = true; break; diff --git a/src/cpp/thread_manager/thread_manager.h b/src/cpp/thread_manager/thread_manager.h index 6f0bd17c5fe..2fbf309d421 100644 --- a/src/cpp/thread_manager/thread_manager.h +++ b/src/cpp/thread_manager/thread_manager.h @@ -26,6 +26,7 @@ #include +#include "src/core/lib/gprpp/sync.h" #include "src/core/lib/gprpp/thd.h" #include "src/core/lib/iomgr/resource_quota.h" @@ -140,10 +141,10 @@ class ThreadManager { // Protects shutdown_, num_pollers_, num_threads_ and // max_active_threads_sofar_ - std::mutex mu_; + grpc_core::Mutex mu_; bool shutdown_; - std::condition_variable shutdown_cv_; + grpc_core::CondVar shutdown_cv_; // The resource user object to use when requesting quota to create threads // @@ -169,7 +170,7 @@ class ThreadManager { // ever set so far int max_active_threads_sofar_; - std::mutex list_mu_; + grpc_core::Mutex list_mu_; std::list completed_threads_; }; diff --git a/src/cpp/util/byte_buffer_cc.cc b/src/cpp/util/byte_buffer_cc.cc index a7e16454352..fb705906455 100644 --- a/src/cpp/util/byte_buffer_cc.cc +++ b/src/cpp/util/byte_buffer_cc.cc @@ -43,18 +43,4 @@ Status ByteBuffer::Dump(std::vector* slices) const { return Status::OK; } -ByteBuffer::ByteBuffer(const ByteBuffer& buf) : buffer_(nullptr) { - operator=(buf); -} - -ByteBuffer& ByteBuffer::operator=(const ByteBuffer& buf) { - if (this != &buf) { - Clear(); // first remove existing data - } - if (buf.buffer_) { - buffer_ = grpc_byte_buffer_copy(buf.buffer_); // then copy - } - return *this; -} - } // namespace grpc diff --git a/src/cpp/util/error_details.cc b/src/cpp/util/error_details.cc index 42c887aed73..a1aafcbdc6e 100644 --- a/src/cpp/util/error_details.cc +++ b/src/cpp/util/error_details.cc @@ -20,29 +20,31 @@ #include "src/proto/grpc/status/status.pb.h" -namespace grpc { +namespace grpc_impl { -Status ExtractErrorDetails(const Status& from, ::google::rpc::Status* to) { +grpc::Status ExtractErrorDetails(const grpc::Status& from, + ::google::rpc::Status* to) { if (to == nullptr) { - return Status(StatusCode::FAILED_PRECONDITION, ""); + return grpc::Status(grpc::StatusCode::FAILED_PRECONDITION, ""); } if (!to->ParseFromString(from.error_details())) { - return Status(StatusCode::INVALID_ARGUMENT, ""); + return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, ""); } - return Status::OK; + return grpc::Status::OK; } -Status SetErrorDetails(const ::google::rpc::Status& from, Status* to) { +grpc::Status SetErrorDetails(const ::google::rpc::Status& from, + grpc::Status* to) { if (to == nullptr) { - return Status(StatusCode::FAILED_PRECONDITION, ""); + return grpc::Status(grpc::StatusCode::FAILED_PRECONDITION, ""); } - StatusCode code = StatusCode::UNKNOWN; - if (from.code() >= StatusCode::OK && - from.code() <= StatusCode::UNAUTHENTICATED) { - code = static_cast(from.code()); + grpc::StatusCode code = grpc::StatusCode::UNKNOWN; + if (from.code() >= grpc::StatusCode::OK && + from.code() <= grpc::StatusCode::UNAUTHENTICATED) { + code = static_cast(from.code()); } - *to = Status(code, from.message(), from.SerializeAsString()); - return Status::OK; + *to = grpc::Status(code, from.message(), from.SerializeAsString()); + return grpc::Status::OK; } -} // namespace grpc +} // namespace grpc_impl diff --git a/src/csharp/Directory.Build.props b/src/csharp/Directory.Build.props new file mode 100644 index 00000000000..7127cc4d509 --- /dev/null +++ b/src/csharp/Directory.Build.props @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/csharp/Grpc.Auth/Grpc.Auth.csproj b/src/csharp/Grpc.Auth/Grpc.Auth.csproj index 5bbff389487..298b721409e 100755 --- a/src/csharp/Grpc.Auth/Grpc.Auth.csproj +++ b/src/csharp/Grpc.Auth/Grpc.Auth.csproj @@ -1,20 +1,21 @@  - - Copyright 2015, Google Inc. - gRPC C# Auth - $(GrpcCsharpVersion) - Google Inc. - net45;netstandard1.5 - $(DefineConstants);SIGNED - Grpc.Auth - Grpc.Auth - gRPC RPC Protocol HTTP/2 Auth OAuth2 + The gRPC Authors + Copyright 2015 The gRPC Authors + gRPC C# Authentication Library + https://github.com/grpc/grpc.github.io/raw/master/img/grpc_square_reverse_4x.png + Apache-2.0 https://github.com/grpc/grpc - https://github.com/grpc/grpc/blob/master/LICENSE + gRPC RPC HTTP/2 Auth OAuth2 + $(GrpcCsharpVersion) + + + + net45;netstandard1.5;netstandard2.0 + $(DefineConstants);SIGNED true true @@ -22,7 +23,7 @@ - + diff --git a/src/csharp/Grpc.Core.Api/.gitignore b/src/csharp/Grpc.Core.Api/.gitignore new file mode 100644 index 00000000000..1746e3269ed --- /dev/null +++ b/src/csharp/Grpc.Core.Api/.gitignore @@ -0,0 +1,2 @@ +bin +obj diff --git a/src/csharp/Grpc.Core/AsyncAuthInterceptor.cs b/src/csharp/Grpc.Core.Api/AsyncAuthInterceptor.cs similarity index 100% rename from src/csharp/Grpc.Core/AsyncAuthInterceptor.cs rename to src/csharp/Grpc.Core.Api/AsyncAuthInterceptor.cs diff --git a/src/csharp/Grpc.Core/AsyncClientStreamingCall.cs b/src/csharp/Grpc.Core.Api/AsyncClientStreamingCall.cs similarity index 100% rename from src/csharp/Grpc.Core/AsyncClientStreamingCall.cs rename to src/csharp/Grpc.Core.Api/AsyncClientStreamingCall.cs diff --git a/src/csharp/Grpc.Core/AsyncDuplexStreamingCall.cs b/src/csharp/Grpc.Core.Api/AsyncDuplexStreamingCall.cs similarity index 100% rename from src/csharp/Grpc.Core/AsyncDuplexStreamingCall.cs rename to src/csharp/Grpc.Core.Api/AsyncDuplexStreamingCall.cs diff --git a/src/csharp/Grpc.Core/AsyncServerStreamingCall.cs b/src/csharp/Grpc.Core.Api/AsyncServerStreamingCall.cs similarity index 100% rename from src/csharp/Grpc.Core/AsyncServerStreamingCall.cs rename to src/csharp/Grpc.Core.Api/AsyncServerStreamingCall.cs diff --git a/src/csharp/Grpc.Core/AsyncUnaryCall.cs b/src/csharp/Grpc.Core.Api/AsyncUnaryCall.cs similarity index 100% rename from src/csharp/Grpc.Core/AsyncUnaryCall.cs rename to src/csharp/Grpc.Core.Api/AsyncUnaryCall.cs diff --git a/src/csharp/Grpc.Core/AuthContext.cs b/src/csharp/Grpc.Core.Api/AuthContext.cs similarity index 96% rename from src/csharp/Grpc.Core/AuthContext.cs rename to src/csharp/Grpc.Core.Api/AuthContext.cs index f2354310486..fbec5001f6d 100644 --- a/src/csharp/Grpc.Core/AuthContext.cs +++ b/src/csharp/Grpc.Core.Api/AuthContext.cs @@ -19,7 +19,6 @@ using System; using System.Collections.Generic; using System.Linq; -using Grpc.Core.Internal; using Grpc.Core.Utils; namespace Grpc.Core @@ -40,7 +39,7 @@ namespace Grpc.Core /// /// Peer identity property name. /// Multimap of auth properties by name. - internal AuthContext(string peerIdentityPropertyName, Dictionary> properties) + public AuthContext(string peerIdentityPropertyName, Dictionary> properties) { this.peerIdentityPropertyName = peerIdentityPropertyName; this.properties = GrpcPreconditions.CheckNotNull(properties); diff --git a/src/csharp/Grpc.Core/AuthProperty.cs b/src/csharp/Grpc.Core.Api/AuthProperty.cs similarity index 94% rename from src/csharp/Grpc.Core/AuthProperty.cs rename to src/csharp/Grpc.Core.Api/AuthProperty.cs index 49765da6396..0907edba84d 100644 --- a/src/csharp/Grpc.Core/AuthProperty.cs +++ b/src/csharp/Grpc.Core.Api/AuthProperty.cs @@ -19,7 +19,7 @@ using System; using System.Collections.Generic; using System.Linq; -using Grpc.Core.Internal; +using System.Text; using Grpc.Core.Utils; namespace Grpc.Core @@ -30,6 +30,7 @@ namespace Grpc.Core /// public class AuthProperty { + static readonly Encoding EncodingUTF8 = System.Text.Encoding.UTF8; string name; byte[] valueBytes; Lazy value; @@ -38,7 +39,7 @@ namespace Grpc.Core { this.name = GrpcPreconditions.CheckNotNull(name); this.valueBytes = GrpcPreconditions.CheckNotNull(valueBytes); - this.value = new Lazy(() => MarshalUtils.GetStringUTF8(this.valueBytes)); + this.value = new Lazy(() => EncodingUTF8.GetString(this.valueBytes)); } /// diff --git a/src/csharp/Grpc.Core.Api/BindServiceMethodAttribute.cs b/src/csharp/Grpc.Core.Api/BindServiceMethodAttribute.cs new file mode 100644 index 00000000000..2ee0abe1d0a --- /dev/null +++ b/src/csharp/Grpc.Core.Api/BindServiceMethodAttribute.cs @@ -0,0 +1,53 @@ +#region Copyright notice and license +// Copyright 2019 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. +// 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; + +namespace Grpc.Core +{ + /// + /// Specifies the location of the service bind method for a gRPC service. + /// The bind method is typically generated code and is used to register a service's + /// methods with the server on startup. + /// + /// The bind method signature takes a and an optional + /// instance of the service base class, e.g. static void BindService(ServiceBinderBase, GreeterService). + /// + [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)] + public class BindServiceMethodAttribute : Attribute + { + /// + /// Initializes a new instance of the class. + /// + /// The type the service bind method is defined on. + /// The name of the service bind method. + public BindServiceMethodAttribute(Type bindType, string bindMethodName) + { + BindType = bindType; + BindMethodName = bindMethodName; + } + + /// + /// Gets the type the service bind method is defined on. + /// + public Type BindType { get; } + + /// + /// Gets the name of the service bind method. + /// + public string BindMethodName { get; } + } +} diff --git a/src/csharp/Grpc.Core.Api/CallCredentials.cs b/src/csharp/Grpc.Core.Api/CallCredentials.cs new file mode 100644 index 00000000000..6344a881070 --- /dev/null +++ b/src/csharp/Grpc.Core.Api/CallCredentials.cs @@ -0,0 +1,90 @@ +#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.Collections.Generic; +using System.Collections.ObjectModel; + +using Grpc.Core.Internal; +using Grpc.Core.Utils; + +namespace Grpc.Core +{ + /// + /// Client-side call credentials. Provide authorization with per-call granularity. + /// + public abstract class CallCredentials + { + /// + /// Composes multiple multiple CallCredentials objects into + /// a single CallCredentials object. + /// + /// credentials to compose + /// The new CompositeCallCredentials + public static CallCredentials Compose(params CallCredentials[] credentials) + { + return new CompositeCallCredentials(credentials); + } + + /// + /// Creates a new instance of CallCredentials class from an + /// interceptor that can attach metadata to outgoing calls. + /// + /// authentication interceptor + public static CallCredentials FromInterceptor(AsyncAuthInterceptor interceptor) + { + return new AsyncAuthInterceptorCredentials(interceptor); + } + + /// + /// Populates this call credential instances. + /// You never need to invoke this, part of internal implementation. + /// + public abstract void InternalPopulateConfiguration(CallCredentialsConfiguratorBase configurator, object state); + + private class CompositeCallCredentials : CallCredentials + { + readonly IReadOnlyList credentials; + + public CompositeCallCredentials(CallCredentials[] credentials) + { + GrpcPreconditions.CheckArgument(credentials.Length >= 2, "Composite credentials object can only be created from 2 or more credentials."); + this.credentials = new List(credentials).AsReadOnly(); + } + + public override void InternalPopulateConfiguration(CallCredentialsConfiguratorBase configurator, object state) + { + configurator.SetCompositeCredentials(state, credentials); + } + } + + private class AsyncAuthInterceptorCredentials : CallCredentials + { + readonly AsyncAuthInterceptor interceptor; + + public AsyncAuthInterceptorCredentials(AsyncAuthInterceptor interceptor) + { + this.interceptor = GrpcPreconditions.CheckNotNull(interceptor); + } + + public override void InternalPopulateConfiguration(CallCredentialsConfiguratorBase configurator, object state) + { + configurator.SetAsyncAuthInterceptorCredentials(state, interceptor); + } + } + } +} diff --git a/src/csharp/Grpc.Core.Api/CallCredentialsConfiguratorBase.cs b/src/csharp/Grpc.Core.Api/CallCredentialsConfiguratorBase.cs new file mode 100644 index 00000000000..51f8d729a11 --- /dev/null +++ b/src/csharp/Grpc.Core.Api/CallCredentialsConfiguratorBase.cs @@ -0,0 +1,39 @@ +#region Copyright notice and license + +// Copyright 2019 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. +// 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.Collections.Generic; + +namespace Grpc.Core +{ + /// + /// Base class for objects that can consume configuration from CallCredentials objects. + /// Note: experimental API that can change or be removed without any prior notice. + /// + public abstract class CallCredentialsConfiguratorBase + { + /// + /// Consumes configuration for composite call credentials. + /// + public abstract void SetCompositeCredentials(object state, IReadOnlyList credentials); + + /// + /// Consumes configuration for call credentials created from AsyncAuthInterceptor + /// + public abstract void SetAsyncAuthInterceptorCredentials(object state, AsyncAuthInterceptor interceptor); + } +} diff --git a/src/csharp/Grpc.Core/Internal/CallFlags.cs b/src/csharp/Grpc.Core.Api/CallFlags.cs similarity index 100% rename from src/csharp/Grpc.Core/Internal/CallFlags.cs rename to src/csharp/Grpc.Core.Api/CallFlags.cs diff --git a/src/csharp/Grpc.Core/CallInvoker.cs b/src/csharp/Grpc.Core.Api/CallInvoker.cs similarity index 98% rename from src/csharp/Grpc.Core/CallInvoker.cs rename to src/csharp/Grpc.Core.Api/CallInvoker.cs index 09fbf0b1e8d..8a84a5215ce 100644 --- a/src/csharp/Grpc.Core/CallInvoker.cs +++ b/src/csharp/Grpc.Core.Api/CallInvoker.cs @@ -17,14 +17,12 @@ #endregion using System.Threading.Tasks; -using Grpc.Core.Internal; namespace Grpc.Core { /// /// Abstraction of client-side RPC invocation. /// - /// public abstract class CallInvoker { /// diff --git a/src/csharp/Grpc.Core/CallOptions.cs b/src/csharp/Grpc.Core.Api/CallOptions.cs similarity index 85% rename from src/csharp/Grpc.Core/CallOptions.cs rename to src/csharp/Grpc.Core.Api/CallOptions.cs index 75d8906a691..c0b732a1005 100644 --- a/src/csharp/Grpc.Core/CallOptions.cs +++ b/src/csharp/Grpc.Core.Api/CallOptions.cs @@ -20,7 +20,6 @@ using System; using System.Threading; using Grpc.Core.Internal; -using Grpc.Core.Utils; namespace Grpc.Core { @@ -227,34 +226,5 @@ namespace Grpc.Core newOptions.flags = flags; return newOptions; } - - /// - /// Returns a new instance of with - /// all previously unset values set to their defaults and deadline and cancellation - /// token propagated when appropriate. - /// - internal CallOptions Normalize() - { - var newOptions = this; - if (propagationToken != null) - { - if (propagationToken.Options.IsPropagateDeadline) - { - GrpcPreconditions.CheckArgument(!newOptions.deadline.HasValue, - "Cannot propagate deadline from parent call. The deadline has already been set explicitly."); - newOptions.deadline = propagationToken.ParentDeadline; - } - if (propagationToken.Options.IsPropagateCancellation) - { - GrpcPreconditions.CheckArgument(!newOptions.cancellationToken.CanBeCanceled, - "Cannot propagate cancellation token from parent call. The cancellation token has already been set to a non-default value."); - newOptions.cancellationToken = propagationToken.ParentCancellationToken; - } - } - - newOptions.headers = newOptions.headers ?? Metadata.Empty; - newOptions.deadline = newOptions.deadline ?? DateTime.MaxValue; - return newOptions; - } } } diff --git a/src/csharp/Grpc.Core.Api/ContextPropagationOptions.cs b/src/csharp/Grpc.Core.Api/ContextPropagationOptions.cs new file mode 100644 index 00000000000..160d10dc82c --- /dev/null +++ b/src/csharp/Grpc.Core.Api/ContextPropagationOptions.cs @@ -0,0 +1,59 @@ +#region Copyright notice and license + +// Copyright 2019 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. +// 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; + +namespace Grpc.Core +{ + /// + /// Options for . + /// + public class ContextPropagationOptions + { + /// + /// The context propagation options that will be used by default. + /// + public static readonly ContextPropagationOptions Default = new ContextPropagationOptions(); + + bool propagateDeadline; + bool propagateCancellation; + + /// + /// Creates new context propagation options. + /// + /// If set to true parent call's deadline will be propagated to the child call. + /// If set to true parent call's cancellation token will be propagated to the child call. + public ContextPropagationOptions(bool propagateDeadline = true, bool propagateCancellation = true) + { + this.propagateDeadline = propagateDeadline; + this.propagateCancellation = propagateCancellation; + } + + /// true if parent call's deadline should be propagated to the child call. + public bool IsPropagateDeadline + { + get { return this.propagateDeadline; } + } + + /// true if parent call's cancellation token should be propagated to the child call. + public bool IsPropagateCancellation + { + get { return this.propagateCancellation; } + } + } +} diff --git a/src/csharp/Grpc.Core.Api/ContextPropagationToken.cs b/src/csharp/Grpc.Core.Api/ContextPropagationToken.cs new file mode 100644 index 00000000000..60e407dc781 --- /dev/null +++ b/src/csharp/Grpc.Core.Api/ContextPropagationToken.cs @@ -0,0 +1,35 @@ +#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 + +namespace Grpc.Core +{ + /// + /// Token for propagating context of server side handlers to child calls. + /// In situations when a backend is making calls to another backend, + /// it makes sense to propagate properties like deadline and cancellation + /// token of the server call to the child call. + /// Underlying gRPC implementation may provide other "opaque" contexts (like tracing context) that + /// are not explicitly accesible via the public C# API, but this token still allows propagating them. + /// + public abstract class ContextPropagationToken + { + internal ContextPropagationToken() + { + } + } +} diff --git a/src/csharp/Grpc.Core/DeserializationContext.cs b/src/csharp/Grpc.Core.Api/DeserializationContext.cs similarity index 64% rename from src/csharp/Grpc.Core/DeserializationContext.cs rename to src/csharp/Grpc.Core.Api/DeserializationContext.cs index d69e0db5bdf..966bcfa8c8e 100644 --- a/src/csharp/Grpc.Core/DeserializationContext.cs +++ b/src/csharp/Grpc.Core.Api/DeserializationContext.cs @@ -39,7 +39,7 @@ namespace Grpc.Core /// Also, allocating a new buffer each time can put excessive pressure on GC, especially if /// the payload is more than 86700 bytes large (which means the newly allocated buffer will be placed in LOH, /// and LOH object can only be garbage collected via a full ("stop the world") GC run). - /// NOTE: Deserializers are expected not to call this method more than once per received message + /// NOTE: Deserializers are expected not to call this method (or other payload accessor methods) more than once per received message /// (as there is no practical reason for doing so) and DeserializationContext implementations are free to assume so. /// /// byte array containing the entire payload. @@ -47,5 +47,22 @@ namespace Grpc.Core { throw new NotImplementedException(); } + +#if GRPC_CSHARP_SUPPORT_SYSTEM_MEMORY + /// + /// Gets the entire payload as a ReadOnlySequence. + /// The ReadOnlySequence is only valid for the duration of the deserializer routine and the caller must not access it after the deserializer returns. + /// Using the read only sequence is the most efficient way to access the message payload. Where possible it allows directly + /// accessing the received payload without needing to perform any buffer copying or buffer allocations. + /// NOTE: This method is only available in the netstandard2.0 build of the library. + /// NOTE: Deserializers are expected not to call this method (or other payload accessor methods) more than once per received message + /// (as there is no practical reason for doing so) and DeserializationContext implementations are free to assume so. + /// + /// read only sequence containing the entire payload. + public virtual System.Buffers.ReadOnlySequence PayloadAsReadOnlySequence() + { + throw new NotImplementedException(); + } +#endif } } diff --git a/src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj b/src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj new file mode 100755 index 00000000000..8a32bc757df --- /dev/null +++ b/src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj @@ -0,0 +1,41 @@ + + + + + + The gRPC Authors + Copyright 2019 The gRPC Authors + gRPC C# Surface API + https://github.com/grpc/grpc.github.io/raw/master/img/grpc_square_reverse_4x.png + Apache-2.0 + https://github.com/grpc/grpc + gRPC RPC HTTP/2 + $(GrpcCsharpVersion) + + + + net45;netstandard1.5;netstandard2.0 + true + true + + + + $(DefineConstants);GRPC_CSHARP_SUPPORT_SYSTEM_MEMORY + + + + + + + + + + + + + + + + + + diff --git a/src/csharp/Grpc.Core/IAsyncStreamReader.cs b/src/csharp/Grpc.Core.Api/IAsyncStreamReader.cs similarity index 100% rename from src/csharp/Grpc.Core/IAsyncStreamReader.cs rename to src/csharp/Grpc.Core.Api/IAsyncStreamReader.cs diff --git a/src/csharp/Grpc.Core/IAsyncStreamWriter.cs b/src/csharp/Grpc.Core.Api/IAsyncStreamWriter.cs similarity index 100% rename from src/csharp/Grpc.Core/IAsyncStreamWriter.cs rename to src/csharp/Grpc.Core.Api/IAsyncStreamWriter.cs diff --git a/src/csharp/Grpc.Core/IClientStreamWriter.cs b/src/csharp/Grpc.Core.Api/IClientStreamWriter.cs similarity index 100% rename from src/csharp/Grpc.Core/IClientStreamWriter.cs rename to src/csharp/Grpc.Core.Api/IClientStreamWriter.cs diff --git a/src/csharp/Grpc.Core/IServerStreamWriter.cs b/src/csharp/Grpc.Core.Api/IServerStreamWriter.cs similarity index 100% rename from src/csharp/Grpc.Core/IServerStreamWriter.cs rename to src/csharp/Grpc.Core.Api/IServerStreamWriter.cs diff --git a/src/csharp/Grpc.Core/Interceptors/ClientInterceptorContext.cs b/src/csharp/Grpc.Core.Api/Interceptors/ClientInterceptorContext.cs similarity index 100% rename from src/csharp/Grpc.Core/Interceptors/ClientInterceptorContext.cs rename to src/csharp/Grpc.Core.Api/Interceptors/ClientInterceptorContext.cs diff --git a/src/csharp/Grpc.Core/Interceptors/Interceptor.cs b/src/csharp/Grpc.Core.Api/Interceptors/Interceptor.cs similarity index 100% rename from src/csharp/Grpc.Core/Interceptors/Interceptor.cs rename to src/csharp/Grpc.Core.Api/Interceptors/Interceptor.cs diff --git a/src/csharp/Grpc.Core/Marshaller.cs b/src/csharp/Grpc.Core.Api/Marshaller.cs similarity index 100% rename from src/csharp/Grpc.Core/Marshaller.cs rename to src/csharp/Grpc.Core.Api/Marshaller.cs diff --git a/src/csharp/Grpc.Core/Metadata.cs b/src/csharp/Grpc.Core.Api/Metadata.cs similarity index 97% rename from src/csharp/Grpc.Core/Metadata.cs rename to src/csharp/Grpc.Core.Api/Metadata.cs index bc263c34696..27e72fbfa8b 100644 --- a/src/csharp/Grpc.Core/Metadata.cs +++ b/src/csharp/Grpc.Core.Api/Metadata.cs @@ -20,7 +20,6 @@ using System.Collections.Generic; using System.Text; using System.Text.RegularExpressions; -using Grpc.Core.Internal; using Grpc.Core.Utils; namespace Grpc.Core @@ -52,6 +51,7 @@ namespace Grpc.Core /// feature and is not part of public API. /// internal const string CompressionRequestAlgorithmMetadataKey = "grpc-internal-encoding-request"; + static readonly Encoding EncodingASCII = System.Text.Encoding.ASCII; readonly List entries; bool readOnly; @@ -286,7 +286,7 @@ namespace Grpc.Core { if (valueBytes == null) { - return MarshalUtils.GetBytesASCII(value); + return EncodingASCII.GetBytes(value); } // defensive copy to guarantee immutability @@ -304,7 +304,7 @@ namespace Grpc.Core get { GrpcPreconditions.CheckState(!IsBinary, "Cannot access string value of a binary metadata entry"); - return value ?? MarshalUtils.GetStringASCII(valueBytes); + return value ?? EncodingASCII.GetString(valueBytes); } } @@ -328,7 +328,7 @@ namespace Grpc.Core { return string.Format("[Entry: key={0}, valueBytes={1}]", key, valueBytes); } - + return string.Format("[Entry: key={0}, value={1}]", key, value); } @@ -338,7 +338,7 @@ namespace Grpc.Core /// internal byte[] GetSerializedValueUnsafe() { - return valueBytes ?? MarshalUtils.GetBytesASCII(value); + return valueBytes ?? EncodingASCII.GetBytes(value); } /// @@ -351,21 +351,21 @@ namespace Grpc.Core { return new Entry(key, null, valueBytes); } - return new Entry(key, MarshalUtils.GetStringASCII(valueBytes), null); + return new Entry(key, EncodingASCII.GetString(valueBytes), null); } private static string NormalizeKey(string key) { GrpcPreconditions.CheckNotNull(key, "key"); - GrpcPreconditions.CheckArgument(IsValidKey(key, out bool isLowercase), + GrpcPreconditions.CheckArgument(IsValidKey(key, out bool isLowercase), "Metadata entry key not valid. Keys can only contain lowercase alphanumeric characters, underscores, hyphens and dots."); if (isLowercase) { // save allocation of a new string if already lowercase return key; } - + return key.ToLowerInvariant(); } @@ -378,7 +378,7 @@ namespace Grpc.Core if ('a' <= c && c <= 'z' || '0' <= c && c <= '9' || c == '.' || - c == '_' || + c == '_' || c == '-' ) continue; diff --git a/src/csharp/Grpc.Core/Method.cs b/src/csharp/Grpc.Core.Api/Method.cs similarity index 100% rename from src/csharp/Grpc.Core/Method.cs rename to src/csharp/Grpc.Core.Api/Method.cs diff --git a/src/csharp/Grpc.Core.Api/Properties/AssemblyInfo.cs b/src/csharp/Grpc.Core.Api/Properties/AssemblyInfo.cs new file mode 100644 index 00000000000..ad38569908e --- /dev/null +++ b/src/csharp/Grpc.Core.Api/Properties/AssemblyInfo.cs @@ -0,0 +1,63 @@ +#region Copyright notice and license + +// Copyright 2019 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. +// 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.Reflection; +using System.Runtime.CompilerServices; + +[assembly: AssemblyTitle("Grpc.Core.Api")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("Google Inc. All rights reserved.")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +#if SIGNED +[assembly: InternalsVisibleTo("Grpc.Core,PublicKey=" + + "00240000048000009400000006020000002400005253413100040000010001002f5797a92c6fcde81bd4098f43" + + "0442bb8e12768722de0b0cb1b15e955b32a11352740ee59f2c94c48edc8e177d1052536b8ac651bce11ce5da3a" + + "27fc95aff3dc604a6971417453f9483c7b5e836756d5b271bf8f2403fe186e31956148c03d804487cf642f8cc0" + + "71394ee9672dfe5b55ea0f95dfd5a7f77d22c962ccf51320d3")] +[assembly: InternalsVisibleTo("Grpc.Core.Tests,PublicKey=" + + "00240000048000009400000006020000002400005253413100040000010001002f5797a92c6fcde81bd4098f43" + + "0442bb8e12768722de0b0cb1b15e955b32a11352740ee59f2c94c48edc8e177d1052536b8ac651bce11ce5da3a" + + "27fc95aff3dc604a6971417453f9483c7b5e836756d5b271bf8f2403fe186e31956148c03d804487cf642f8cc0" + + "71394ee9672dfe5b55ea0f95dfd5a7f77d22c962ccf51320d3")] +[assembly: InternalsVisibleTo("Grpc.Core.Testing,PublicKey=" + + "00240000048000009400000006020000002400005253413100040000010001002f5797a92c6fcde81bd4098f43" + + "0442bb8e12768722de0b0cb1b15e955b32a11352740ee59f2c94c48edc8e177d1052536b8ac651bce11ce5da3a" + + "27fc95aff3dc604a6971417453f9483c7b5e836756d5b271bf8f2403fe186e31956148c03d804487cf642f8cc0" + + "71394ee9672dfe5b55ea0f95dfd5a7f77d22c962ccf51320d3")] +[assembly: InternalsVisibleTo("Grpc.IntegrationTesting,PublicKey=" + + "00240000048000009400000006020000002400005253413100040000010001002f5797a92c6fcde81bd4098f43" + + "0442bb8e12768722de0b0cb1b15e955b32a11352740ee59f2c94c48edc8e177d1052536b8ac651bce11ce5da3a" + + "27fc95aff3dc604a6971417453f9483c7b5e836756d5b271bf8f2403fe186e31956148c03d804487cf642f8cc0" + + "71394ee9672dfe5b55ea0f95dfd5a7f77d22c962ccf51320d3")] +[assembly: InternalsVisibleTo("Grpc.Microbenchmarks,PublicKey=" + + "00240000048000009400000006020000002400005253413100040000010001002f5797a92c6fcde81bd4098f43" + + "0442bb8e12768722de0b0cb1b15e955b32a11352740ee59f2c94c48edc8e177d1052536b8ac651bce11ce5da3a" + + "27fc95aff3dc604a6971417453f9483c7b5e836756d5b271bf8f2403fe186e31956148c03d804487cf642f8cc0" + + "71394ee9672dfe5b55ea0f95dfd5a7f77d22c962ccf51320d3")] +#else +[assembly: InternalsVisibleTo("Grpc.Core")] +[assembly: InternalsVisibleTo("Grpc.Core.Tests")] +[assembly: InternalsVisibleTo("Grpc.Core.Testing")] +[assembly: InternalsVisibleTo("Grpc.IntegrationTesting")] +[assembly: InternalsVisibleTo("Grpc.Microbenchmarks")] +#endif diff --git a/src/csharp/Grpc.Core/RpcException.cs b/src/csharp/Grpc.Core.Api/RpcException.cs similarity index 100% rename from src/csharp/Grpc.Core/RpcException.cs rename to src/csharp/Grpc.Core.Api/RpcException.cs diff --git a/src/csharp/Grpc.Core/SerializationContext.cs b/src/csharp/Grpc.Core.Api/SerializationContext.cs similarity index 100% rename from src/csharp/Grpc.Core/SerializationContext.cs rename to src/csharp/Grpc.Core.Api/SerializationContext.cs diff --git a/src/csharp/Grpc.Core.Api/ServerCallContext.cs b/src/csharp/Grpc.Core.Api/ServerCallContext.cs new file mode 100644 index 00000000000..8d7dbf544d6 --- /dev/null +++ b/src/csharp/Grpc.Core.Api/ServerCallContext.cs @@ -0,0 +1,163 @@ +#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.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace Grpc.Core +{ + /// + /// Context for a server-side call. + /// + public abstract class ServerCallContext + { + private Dictionary userState; + + /// + /// Creates a new instance of ServerCallContext. + /// + protected ServerCallContext() + { + } + + /// + /// Asynchronously sends response headers for the current call to the client. This method may only be invoked once for each call and needs to be invoked + /// before any response messages are written. Writing the first response message implicitly sends empty response headers if WriteResponseHeadersAsync haven't + /// been called yet. + /// + /// The response headers to send. + /// The task that finished once response headers have been written. + public Task WriteResponseHeadersAsync(Metadata responseHeaders) + { + return WriteResponseHeadersAsyncCore(responseHeaders); + } + + /// + /// Creates a propagation token to be used to propagate call context to a child call. + /// + public ContextPropagationToken CreatePropagationToken(ContextPropagationOptions options = null) + { + return CreatePropagationTokenCore(options); + } + + /// Name of method called in this RPC. + public string Method => MethodCore; + + /// Name of host called in this RPC. + public string Host => HostCore; + + /// Address of the remote endpoint in URI format. + public string Peer => PeerCore; + + /// Deadline for this RPC. + public DateTime Deadline => DeadlineCore; + + /// Initial metadata sent by client. + public Metadata RequestHeaders => RequestHeadersCore; + + /// Cancellation token signals when call is cancelled. + public CancellationToken CancellationToken => CancellationTokenCore; + + /// Trailers to send back to client after RPC finishes. + public Metadata ResponseTrailers => ResponseTrailersCore; + + /// Status to send back to client after RPC finishes. + public Status Status + { + get + { + return StatusCore; + } + + set + { + StatusCore = value; + } + } + + /// + /// Allows setting write options for the following write. + /// For streaming response calls, this property is also exposed as on IServerStreamWriter for convenience. + /// Both properties are backed by the same underlying value. + /// + public WriteOptions WriteOptions + { + get + { + return WriteOptionsCore; + } + + set + { + WriteOptionsCore = value; + } + } + + /// + /// Gets the AuthContext associated with this call. + /// Note: Access to AuthContext is an experimental API that can change without any prior notice. + /// + public AuthContext AuthContext => AuthContextCore; + + /// + /// Gets a dictionary that can be used by the various interceptors and handlers of this + /// call to store arbitrary state. + /// + public IDictionary UserState => UserStateCore; + + /// Provides implementation of a non-virtual public member. + protected abstract Task WriteResponseHeadersAsyncCore(Metadata responseHeaders); + /// Provides implementation of a non-virtual public member. + protected abstract ContextPropagationToken CreatePropagationTokenCore(ContextPropagationOptions options); + /// Provides implementation of a non-virtual public member. + protected abstract string MethodCore { get; } + /// Provides implementation of a non-virtual public member. + protected abstract string HostCore { get; } + /// Provides implementation of a non-virtual public member. + protected abstract string PeerCore { get; } + /// Provides implementation of a non-virtual public member. + protected abstract DateTime DeadlineCore { get; } + /// Provides implementation of a non-virtual public member. + protected abstract Metadata RequestHeadersCore { get; } + /// Provides implementation of a non-virtual public member. + protected abstract CancellationToken CancellationTokenCore { get; } + /// Provides implementation of a non-virtual public member. + protected abstract Metadata ResponseTrailersCore { get; } + /// Provides implementation of a non-virtual public member. + protected abstract Status StatusCore { get; set; } + /// Provides implementation of a non-virtual public member. + protected abstract WriteOptions WriteOptionsCore { get; set; } + /// Provides implementation of a non-virtual public member. + protected abstract AuthContext AuthContextCore { get; } + /// Provides implementation of a non-virtual public member. + protected virtual IDictionary UserStateCore + { + get + { + if (userState == null) + { + userState = new Dictionary(); + } + + return userState; + } + } + } +} diff --git a/src/csharp/Grpc.Core/ServerMethods.cs b/src/csharp/Grpc.Core.Api/ServerMethods.cs similarity index 100% rename from src/csharp/Grpc.Core/ServerMethods.cs rename to src/csharp/Grpc.Core.Api/ServerMethods.cs diff --git a/src/csharp/Grpc.Core/ServerServiceDefinition.cs b/src/csharp/Grpc.Core.Api/ServerServiceDefinition.cs similarity index 74% rename from src/csharp/Grpc.Core/ServerServiceDefinition.cs rename to src/csharp/Grpc.Core.Api/ServerServiceDefinition.cs index b040ab379c8..8c76f0bcc97 100644 --- a/src/csharp/Grpc.Core/ServerServiceDefinition.cs +++ b/src/csharp/Grpc.Core.Api/ServerServiceDefinition.cs @@ -18,33 +18,31 @@ using System; using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Linq; -using Grpc.Core.Interceptors; -using Grpc.Core.Internal; -using Grpc.Core.Utils; namespace Grpc.Core { /// - /// Mapping of method names to server call handlers. + /// Stores mapping of methods to server call handlers. /// Normally, the ServerServiceDefinition objects will be created by the BindService factory method /// that is part of the autogenerated code for a protocol buffers service definition. /// public class ServerServiceDefinition { - readonly ReadOnlyDictionary callHandlers; + readonly IReadOnlyList> addMethodActions; - internal ServerServiceDefinition(Dictionary callHandlers) + internal ServerServiceDefinition(List> addMethodActions) { - this.callHandlers = new ReadOnlyDictionary(callHandlers); + this.addMethodActions = addMethodActions.AsReadOnly(); } - internal IDictionary CallHandlers + /// + /// Forwards all the previously stored AddMethod calls to the service binder. + /// + internal void BindService(ServiceBinderBase serviceBinder) { - get + foreach (var addMethodAction in addMethodActions) { - return this.callHandlers; + addMethodAction(serviceBinder); } } @@ -62,7 +60,10 @@ namespace Grpc.Core /// public class Builder { - readonly Dictionary callHandlers = new Dictionary(); + // to maintain legacy behavior, we need to detect duplicate keys and throw the same exception as before + readonly Dictionary duplicateDetector = new Dictionary(); + // for each AddMethod call, we store an action that will later register the method and handler with ServiceBinderBase + readonly List> addMethodActions = new List>(); /// /// Creates a new instance of builder. @@ -85,7 +86,8 @@ namespace Grpc.Core where TRequest : class where TResponse : class { - callHandlers.Add(method.FullName, ServerCalls.UnaryCall(method, handler)); + duplicateDetector.Add(method.FullName, null); + addMethodActions.Add((serviceBinder) => serviceBinder.AddMethod(method, handler)); return this; } @@ -103,7 +105,8 @@ namespace Grpc.Core where TRequest : class where TResponse : class { - callHandlers.Add(method.FullName, ServerCalls.ClientStreamingCall(method, handler)); + duplicateDetector.Add(method.FullName, null); + addMethodActions.Add((serviceBinder) => serviceBinder.AddMethod(method, handler)); return this; } @@ -121,7 +124,8 @@ namespace Grpc.Core where TRequest : class where TResponse : class { - callHandlers.Add(method.FullName, ServerCalls.ServerStreamingCall(method, handler)); + duplicateDetector.Add(method.FullName, null); + addMethodActions.Add((serviceBinder) => serviceBinder.AddMethod(method, handler)); return this; } @@ -139,7 +143,8 @@ namespace Grpc.Core where TRequest : class where TResponse : class { - callHandlers.Add(method.FullName, ServerCalls.DuplexStreamingCall(method, handler)); + duplicateDetector.Add(method.FullName, null); + addMethodActions.Add((serviceBinder) => serviceBinder.AddMethod(method, handler)); return this; } @@ -149,7 +154,7 @@ namespace Grpc.Core /// The ServerServiceDefinition object. public ServerServiceDefinition Build() { - return new ServerServiceDefinition(callHandlers); + return new ServerServiceDefinition(addMethodActions); } } } diff --git a/src/csharp/Grpc.Core/ServiceBinderBase.cs b/src/csharp/Grpc.Core.Api/ServiceBinderBase.cs similarity index 97% rename from src/csharp/Grpc.Core/ServiceBinderBase.cs rename to src/csharp/Grpc.Core.Api/ServiceBinderBase.cs index d4909f4a269..074bfae1ea0 100644 --- a/src/csharp/Grpc.Core/ServiceBinderBase.cs +++ b/src/csharp/Grpc.Core.Api/ServiceBinderBase.cs @@ -20,8 +20,6 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; -using Grpc.Core.Interceptors; -using Grpc.Core.Internal; using Grpc.Core.Utils; namespace Grpc.Core @@ -30,7 +28,6 @@ namespace Grpc.Core /// Allows binding server-side method implementations in alternative serving stacks. /// Instances of this class are usually populated by the BindService method /// that is part of the autogenerated code for a protocol buffers service definition. - /// /// public class ServiceBinderBase { diff --git a/src/csharp/Grpc.Core/Status.cs b/src/csharp/Grpc.Core.Api/Status.cs similarity index 97% rename from src/csharp/Grpc.Core/Status.cs rename to src/csharp/Grpc.Core.Api/Status.cs index 170a5b68c3e..b1a030b2d1f 100644 --- a/src/csharp/Grpc.Core/Status.cs +++ b/src/csharp/Grpc.Core.Api/Status.cs @@ -14,12 +14,10 @@ // limitations under the License. #endregion -using Grpc.Core.Utils; - namespace Grpc.Core { /// - /// Represents RPC result, which consists of and an optional detail string. + /// Represents RPC result, which consists of and an optional detail string. /// public struct Status { diff --git a/src/csharp/Grpc.Core/StatusCode.cs b/src/csharp/Grpc.Core.Api/StatusCode.cs similarity index 97% rename from src/csharp/Grpc.Core/StatusCode.cs rename to src/csharp/Grpc.Core.Api/StatusCode.cs index 57fe538e815..8493f375adb 100644 --- a/src/csharp/Grpc.Core/StatusCode.cs +++ b/src/csharp/Grpc.Core.Api/StatusCode.cs @@ -114,7 +114,8 @@ namespace Grpc.Core /// /// The service is currently unavailable. This is a most likely a /// transient condition and may be corrected by retrying with - /// a backoff. + /// a backoff. Note that it is not always safe to retry + /// non-idempotent operations. /// Unavailable = 14, diff --git a/src/csharp/Grpc.Core/Utils/GrpcPreconditions.cs b/src/csharp/Grpc.Core.Api/Utils/GrpcPreconditions.cs similarity index 100% rename from src/csharp/Grpc.Core/Utils/GrpcPreconditions.cs rename to src/csharp/Grpc.Core.Api/Utils/GrpcPreconditions.cs diff --git a/src/csharp/Grpc.Core/Version.cs b/src/csharp/Grpc.Core.Api/Version.cs similarity index 100% rename from src/csharp/Grpc.Core/Version.cs rename to src/csharp/Grpc.Core.Api/Version.cs diff --git a/src/csharp/Grpc.Core/VersionInfo.cs b/src/csharp/Grpc.Core.Api/VersionInfo.cs similarity index 91% rename from src/csharp/Grpc.Core/VersionInfo.cs rename to src/csharp/Grpc.Core.Api/VersionInfo.cs index 14714c8c4ae..fb67fe622b5 100644 --- a/src/csharp/Grpc.Core/VersionInfo.cs +++ b/src/csharp/Grpc.Core.Api/VersionInfo.cs @@ -33,11 +33,11 @@ namespace Grpc.Core /// /// Current AssemblyFileVersion of gRPC C# assemblies /// - public const string CurrentAssemblyFileVersion = "1.17.0.0"; + public const string CurrentAssemblyFileVersion = "1.22.0.0"; /// /// Current version of gRPC C# /// - public const string CurrentVersion = "1.17.0-dev"; + public const string CurrentVersion = "1.22.0-dev"; } } diff --git a/src/csharp/Grpc.Core/WriteOptions.cs b/src/csharp/Grpc.Core.Api/WriteOptions.cs similarity index 99% rename from src/csharp/Grpc.Core/WriteOptions.cs rename to src/csharp/Grpc.Core.Api/WriteOptions.cs index f99a6a0631e..cbb866b0a90 100644 --- a/src/csharp/Grpc.Core/WriteOptions.cs +++ b/src/csharp/Grpc.Core.Api/WriteOptions.cs @@ -48,7 +48,7 @@ namespace Grpc.Core /// Default write options. /// public static readonly WriteOptions Default = new WriteOptions(); - + private readonly WriteFlags flags; /// diff --git a/src/csharp/Grpc.Core.NativeDebug.nuspec b/src/csharp/Grpc.Core.NativeDebug.nuspec deleted file mode 100644 index d4bb8ad2237..00000000000 --- a/src/csharp/Grpc.Core.NativeDebug.nuspec +++ /dev/null @@ -1,25 +0,0 @@ - - - - Grpc.Core.NativeDebug - Grpc.Core: Native Debug Symbols - Debug symbols for the native library contained in Grpc.Core - Currently contains grpc_csharp_ext.pdb - $version$ - Google Inc. - grpc-packages - https://github.com/grpc/grpc/blob/master/LICENSE - https://github.com/grpc/grpc - false - Release $version$ - Copyright 2015, Google Inc. - gRPC RPC Protocol HTTP/2 - - - - - - - - - diff --git a/src/csharp/Grpc.Core.NativeDebug/.gitignore b/src/csharp/Grpc.Core.NativeDebug/.gitignore new file mode 100644 index 00000000000..1746e3269ed --- /dev/null +++ b/src/csharp/Grpc.Core.NativeDebug/.gitignore @@ -0,0 +1,2 @@ +bin +obj diff --git a/src/csharp/Grpc.Core.NativeDebug/Grpc.Core.NativeDebug.csproj b/src/csharp/Grpc.Core.NativeDebug/Grpc.Core.NativeDebug.csproj new file mode 100644 index 00000000000..a8b13030ee6 --- /dev/null +++ b/src/csharp/Grpc.Core.NativeDebug/Grpc.Core.NativeDebug.csproj @@ -0,0 +1,41 @@ + + + + + + The gRPC Authors + Copyright 2015 The gRPC Authors + Debug symbols for the native library contained in Grpc.Core + https://github.com/grpc/grpc.github.io/raw/master/img/grpc_square_reverse_4x.png + Apache-2.0 + https://github.com/grpc/grpc + gRPC RPC HTTP/2 + $(GrpcCsharpVersion) + + + + net45;netstandard1.5;netstandard2.0 + + false + true + + + + + runtimes/win/native/grpc_csharp_ext.x86.dll + true + + + runtimes/win/native/grpc_csharp_ext.x86.pdb + true + + + runtimes/win/native/grpc_csharp_ext.x64.dll + true + + + runtimes/win/native/grpc_csharp_ext.x64.pdb + true + + + diff --git a/src/csharp/Grpc.Core.Testing/Grpc.Core.Testing.csproj b/src/csharp/Grpc.Core.Testing/Grpc.Core.Testing.csproj index 40840d4da3e..3cd36d45008 100755 --- a/src/csharp/Grpc.Core.Testing/Grpc.Core.Testing.csproj +++ b/src/csharp/Grpc.Core.Testing/Grpc.Core.Testing.csproj @@ -1,20 +1,20 @@  - - Copyright 2017, Google Inc. - gRPC C# Core Testing - $(GrpcCsharpVersion) - Google Inc. - net45;netstandard1.5 - true - Grpc.Core.Testing - Grpc.Core.Testing - gRPC test testing + The gRPC Authors + Miscellaneous code for testing Grpc.Core + Copyright 2017 The gRPC Authors + https://github.com/grpc/grpc.github.io/raw/master/img/grpc_square_reverse_4x.png + Apache-2.0 https://github.com/grpc/grpc - https://github.com/grpc/grpc/blob/master/LICENSE + gRPC test testing + $(GrpcCsharpVersion) + + + + net45;netstandard1.5;netstandard2.0 true true @@ -22,7 +22,7 @@ - + diff --git a/src/csharp/Grpc.Core.Testing/TestServerCallContext.cs b/src/csharp/Grpc.Core.Testing/TestServerCallContext.cs index 5418417d7ed..e6297e61226 100644 --- a/src/csharp/Grpc.Core.Testing/TestServerCallContext.cs +++ b/src/csharp/Grpc.Core.Testing/TestServerCallContext.cs @@ -19,7 +19,6 @@ using System; using System.Threading; using System.Threading.Tasks; -using Grpc.Core; namespace Grpc.Core.Testing { @@ -36,23 +35,73 @@ namespace Grpc.Core.Testing string peer, AuthContext authContext, ContextPropagationToken contextPropagationToken, Func writeHeadersFunc, Func writeOptionsGetter, Action writeOptionsSetter) { - return new ServerCallContext(null, method, host, deadline, requestHeaders, cancellationToken, - writeHeadersFunc, new WriteOptionsHolder(writeOptionsGetter, writeOptionsSetter), - () => peer, () => authContext, () => contextPropagationToken); + return new TestingServerCallContext(method, host, deadline, requestHeaders, cancellationToken, peer, + authContext, contextPropagationToken, writeHeadersFunc, writeOptionsGetter, writeOptionsSetter); } - private class WriteOptionsHolder : IHasWriteOptions + private class TestingServerCallContext : ServerCallContext { - Func writeOptionsGetter; - Action writeOptionsSetter; + private readonly string method; + private readonly string host; + private readonly DateTime deadline; + private readonly Metadata requestHeaders; + private readonly CancellationToken cancellationToken; + private readonly Metadata responseTrailers = new Metadata(); + private Status status; + private readonly string peer; + private readonly AuthContext authContext; + private readonly ContextPropagationToken contextPropagationToken; + private readonly Func writeHeadersFunc; + private readonly Func writeOptionsGetter; + private readonly Action writeOptionsSetter; - public WriteOptionsHolder(Func writeOptionsGetter, Action writeOptionsSetter) + public TestingServerCallContext(string method, string host, DateTime deadline, Metadata requestHeaders, CancellationToken cancellationToken, + string peer, AuthContext authContext, ContextPropagationToken contextPropagationToken, + Func writeHeadersFunc, Func writeOptionsGetter, Action writeOptionsSetter) { + this.method = method; + this.host = host; + this.deadline = deadline; + this.requestHeaders = requestHeaders; + this.cancellationToken = cancellationToken; + this.responseTrailers = new Metadata(); + this.status = Status.DefaultSuccess; + this.peer = peer; + this.authContext = authContext; + this.contextPropagationToken = contextPropagationToken; + this.writeHeadersFunc = writeHeadersFunc; this.writeOptionsGetter = writeOptionsGetter; this.writeOptionsSetter = writeOptionsSetter; } - public WriteOptions WriteOptions { get => writeOptionsGetter(); set => writeOptionsSetter(value); } + protected override string MethodCore => method; + + protected override string HostCore => host; + + protected override string PeerCore => peer; + + protected override DateTime DeadlineCore => deadline; + + protected override Metadata RequestHeadersCore => requestHeaders; + + protected override CancellationToken CancellationTokenCore => cancellationToken; + + protected override Metadata ResponseTrailersCore => responseTrailers; + + protected override Status StatusCore { get => status; set => status = value; } + protected override WriteOptions WriteOptionsCore { get => writeOptionsGetter(); set => writeOptionsSetter(value); } + + protected override AuthContext AuthContextCore => authContext; + + protected override ContextPropagationToken CreatePropagationTokenCore(ContextPropagationOptions options) + { + return contextPropagationToken; + } + + protected override Task WriteResponseHeadersAsyncCore(Metadata responseHeaders) + { + return writeHeadersFunc(responseHeaders); + } } } } diff --git a/src/csharp/Grpc.Core.Tests/AppDomainUnloadTest.cs b/src/csharp/Grpc.Core.Tests/AppDomainUnloadTest.cs index 3a161763fd0..b10d7a10451 100644 --- a/src/csharp/Grpc.Core.Tests/AppDomainUnloadTest.cs +++ b/src/csharp/Grpc.Core.Tests/AppDomainUnloadTest.cs @@ -25,7 +25,7 @@ namespace Grpc.Core.Tests { public class AppDomainUnloadTest { -#if NETCOREAPP1_0 +#if NETCOREAPP1_1 || NETCOREAPP2_1 [Test] [Ignore("Not supported for CoreCLR")] public void AppDomainUnloadHookCanCleanupAbandonedCall() diff --git a/src/csharp/Grpc.Core.Tests/CallOptionsTest.cs b/src/csharp/Grpc.Core.Tests/CallOptionsTest.cs index 8e5c411cadd..1fd48812b54 100644 --- a/src/csharp/Grpc.Core.Tests/CallOptionsTest.cs +++ b/src/csharp/Grpc.Core.Tests/CallOptionsTest.cs @@ -45,7 +45,7 @@ namespace Grpc.Core.Tests var writeOptions = new WriteOptions(); Assert.AreSame(writeOptions, options.WithWriteOptions(writeOptions).WriteOptions); - var propagationToken = new ContextPropagationToken(CallSafeHandle.NullInstance, DateTime.UtcNow, + var propagationToken = new ContextPropagationTokenImpl(CallSafeHandle.NullInstance, DateTime.UtcNow, CancellationToken.None, ContextPropagationOptions.Default); Assert.AreSame(propagationToken, options.WithPropagationToken(propagationToken).PropagationToken); @@ -72,13 +72,13 @@ namespace Grpc.Core.Tests Assert.AreEqual(DateTime.MaxValue, new CallOptions().Normalize().Deadline.Value); var deadline = DateTime.UtcNow; - var propagationToken1 = new ContextPropagationToken(CallSafeHandle.NullInstance, deadline, CancellationToken.None, + var propagationToken1 = new ContextPropagationTokenImpl(CallSafeHandle.NullInstance, deadline, CancellationToken.None, new ContextPropagationOptions(propagateDeadline: true, propagateCancellation: false)); Assert.AreEqual(deadline, new CallOptions(propagationToken: propagationToken1).Normalize().Deadline.Value); Assert.Throws(typeof(ArgumentException), () => new CallOptions(deadline: deadline, propagationToken: propagationToken1).Normalize()); var token = new CancellationTokenSource().Token; - var propagationToken2 = new ContextPropagationToken(CallSafeHandle.NullInstance, deadline, token, + var propagationToken2 = new ContextPropagationTokenImpl(CallSafeHandle.NullInstance, deadline, token, new ContextPropagationOptions(propagateDeadline: false, propagateCancellation: true)); Assert.AreEqual(token, new CallOptions(propagationToken: propagationToken2).Normalize().CancellationToken); Assert.Throws(typeof(ArgumentException), () => new CallOptions(cancellationToken: token, propagationToken: propagationToken2).Normalize()); diff --git a/src/csharp/Grpc.Core.Tests/ContextPropagationTest.cs b/src/csharp/Grpc.Core.Tests/ContextPropagationTest.cs index c8bc372202d..4158579194f 100644 --- a/src/csharp/Grpc.Core.Tests/ContextPropagationTest.cs +++ b/src/csharp/Grpc.Core.Tests/ContextPropagationTest.cs @@ -72,7 +72,7 @@ namespace Grpc.Core.Tests helper.ClientStreamingHandler = new ClientStreamingServerMethod(async (requestStream, context) => { var propagationToken = context.CreatePropagationToken(); - Assert.IsNotNull(propagationToken.ParentCall); + Assert.IsNotNull(propagationToken.AsImplOrNull().ParentCall); var callOptions = new CallOptions(propagationToken: propagationToken); try @@ -154,5 +154,28 @@ namespace Grpc.Core.Tests await call.RequestStream.CompleteAsync(); Assert.AreEqual("PASS", await call); } + + [Test] + public void ForeignPropagationTokenInterpretedAsNull() + { + Assert.IsNull(new ForeignContextPropagationToken().AsImplOrNull()); + } + + [Test] + public async Task ForeignPropagationTokenIsIgnored() + { + helper.UnaryHandler = new UnaryServerMethod((request, context) => + { + return Task.FromResult("PASS"); + }); + + var callOptions = new CallOptions(propagationToken: new ForeignContextPropagationToken()); + await Calls.AsyncUnaryCall(helper.CreateUnaryCall(callOptions), "xyz"); + } + + // For testing, represents context propagation token that's not generated by Grpc.Core + private class ForeignContextPropagationToken : ContextPropagationToken + { + } } } diff --git a/src/csharp/Grpc.Core.Tests/FakeCredentials.cs b/src/csharp/Grpc.Core.Tests/FakeCredentials.cs index f23c9e97574..59587b9a510 100644 --- a/src/csharp/Grpc.Core.Tests/FakeCredentials.cs +++ b/src/csharp/Grpc.Core.Tests/FakeCredentials.cs @@ -42,9 +42,9 @@ namespace Grpc.Core.Tests internal class FakeCallCredentials : CallCredentials { - internal override CallCredentialsSafeHandle ToNativeCredentials() + public override void InternalPopulateConfiguration(CallCredentialsConfiguratorBase configurator, object state) { - return null; + // not invoking the configurator on purpose } } } diff --git a/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj b/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj index d58f0468244..7fef2c77091 100755 --- a/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj +++ b/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj @@ -1,16 +1,17 @@  - - net45;netcoreapp1.0 - Grpc.Core.Tests + net45;netcoreapp2.1 Exe - Grpc.Core.Tests true + + $(DefineConstants);GRPC_CSHARP_SUPPORT_SYSTEM_MEMORY + + @@ -29,7 +30,7 @@ - + diff --git a/src/csharp/Grpc.Core.Tests/Interceptors/ServerInterceptorTest.cs b/src/csharp/Grpc.Core.Tests/Interceptors/ServerInterceptorTest.cs index e76f21d0985..66990832124 100644 --- a/src/csharp/Grpc.Core.Tests/Interceptors/ServerInterceptorTest.cs +++ b/src/csharp/Grpc.Core.Tests/Interceptors/ServerInterceptorTest.cs @@ -77,6 +77,53 @@ namespace Grpc.Core.Interceptors.Tests Assert.AreEqual("CB1B2B3A", stringBuilder.ToString()); } + [Test] + public void UserStateVisibleToAllInterceptors() + { + object key1 = new object(); + object value1 = new object(); + const string key2 = "Interceptor #2"; + const string value2 = "Important state"; + + var interceptor1 = new ServerCallContextInterceptor(ctx => { + // state starts off empty + Assert.AreEqual(0, ctx.UserState.Count); + + ctx.UserState.Add(key1, value1); + }); + + var interceptor2 = new ServerCallContextInterceptor(ctx => { + // second interceptor can see state set by the first + bool found = ctx.UserState.TryGetValue(key1, out object storedValue1); + Assert.IsTrue(found); + Assert.AreEqual(value1, storedValue1); + + ctx.UserState.Add(key2, value2); + }); + + var helper = new MockServiceHelper(Host); + helper.UnaryHandler = new UnaryServerMethod((request, context) => { + // call handler can see all the state + bool found = context.UserState.TryGetValue(key1, out object storedValue1); + Assert.IsTrue(found); + Assert.AreEqual(value1, storedValue1); + + found = context.UserState.TryGetValue(key2, out object storedValue2); + Assert.IsTrue(found); + Assert.AreEqual(value2, storedValue2); + + return Task.FromResult("PASS"); + }); + helper.ServiceDefinition = helper.ServiceDefinition + .Intercept(interceptor2) + .Intercept(interceptor1); + + var server = helper.GetServer(); + server.Start(); + var channel = helper.GetChannel(); + Assert.AreEqual("PASS", Calls.BlockingUnaryCall(helper.CreateUnaryCall(), "")); + } + [Test] public void CheckNullInterceptorRegistrationFails() { diff --git a/src/csharp/Grpc.Core.Tests/Internal/AsyncCallServerTest.cs b/src/csharp/Grpc.Core.Tests/Internal/AsyncCallServerTest.cs index 5c7d48f786c..fd221613c04 100644 --- a/src/csharp/Grpc.Core.Tests/Internal/AsyncCallServerTest.cs +++ b/src/csharp/Grpc.Core.Tests/Internal/AsyncCallServerTest.cs @@ -35,6 +35,7 @@ namespace Grpc.Core.Internal.Tests Server server; FakeNativeCall fakeCall; AsyncCallServer asyncCallServer; + FakeBufferReaderManager fakeBufferReaderManager; [SetUp] public void Init() @@ -52,11 +53,13 @@ namespace Grpc.Core.Internal.Tests Marshallers.StringMarshaller.ContextualSerializer, Marshallers.StringMarshaller.ContextualDeserializer, server); asyncCallServer.InitializeForTesting(fakeCall); + fakeBufferReaderManager = new FakeBufferReaderManager(); } [TearDown] public void Cleanup() { + fakeBufferReaderManager.Dispose(); server.ShutdownAsync().Wait(); } @@ -77,7 +80,7 @@ namespace Grpc.Core.Internal.Tests var moveNextTask = requestStream.MoveNext(); fakeCall.ReceivedCloseOnServerCallback.OnReceivedCloseOnServer(true, cancelled: true); - fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, null); + fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, CreateNullResponse()); Assert.IsFalse(moveNextTask.Result); AssertFinished(asyncCallServer, fakeCall, finishedTask); @@ -107,7 +110,7 @@ namespace Grpc.Core.Internal.Tests // if a read completion's success==false, the request stream will silently finish // and we rely on C core cancelling the call. var moveNextTask = requestStream.MoveNext(); - fakeCall.ReceivedMessageCallback.OnReceivedMessage(false, null); + fakeCall.ReceivedMessageCallback.OnReceivedMessage(false, CreateNullResponse()); Assert.IsFalse(moveNextTask.Result); fakeCall.ReceivedCloseOnServerCallback.OnReceivedCloseOnServer(true, cancelled: true); @@ -182,5 +185,10 @@ namespace Grpc.Core.Internal.Tests Assert.IsTrue(finishedTask.IsCompleted); Assert.DoesNotThrow(() => finishedTask.Wait()); } + + IBufferReader CreateNullResponse() + { + return fakeBufferReaderManager.CreateNullPayloadBufferReader(); + } } } diff --git a/src/csharp/Grpc.Core.Tests/Internal/AsyncCallTest.cs b/src/csharp/Grpc.Core.Tests/Internal/AsyncCallTest.cs index 775849d89b6..78c7f3ad5bb 100644 --- a/src/csharp/Grpc.Core.Tests/Internal/AsyncCallTest.cs +++ b/src/csharp/Grpc.Core.Tests/Internal/AsyncCallTest.cs @@ -21,6 +21,7 @@ using System.Collections.Generic; using System.Threading.Tasks; using Grpc.Core.Internal; +using Grpc.Core.Utils; using NUnit.Framework; namespace Grpc.Core.Internal.Tests @@ -33,6 +34,7 @@ namespace Grpc.Core.Internal.Tests Channel channel; FakeNativeCall fakeCall; AsyncCall asyncCall; + FakeBufferReaderManager fakeBufferReaderManager; [SetUp] public void Init() @@ -43,12 +45,14 @@ namespace Grpc.Core.Internal.Tests var callDetails = new CallInvocationDetails(channel, "someMethod", null, Marshallers.StringMarshaller, Marshallers.StringMarshaller, new CallOptions()); asyncCall = new AsyncCall(callDetails, fakeCall); + fakeBufferReaderManager = new FakeBufferReaderManager(); } [TearDown] public void Cleanup() { channel.ShutdownAsync().Wait(); + fakeBufferReaderManager.Dispose(); } [Test] @@ -87,7 +91,7 @@ namespace Grpc.Core.Internal.Tests var resultTask = asyncCall.UnaryCallAsync("request1"); fakeCall.UnaryResponseClientCallback.OnUnaryResponseClient(true, CreateClientSideStatus(StatusCode.InvalidArgument), - null, + CreateNullResponse(), new Metadata()); AssertUnaryResponseError(asyncCall, fakeCall, resultTask, StatusCode.InvalidArgument); @@ -168,7 +172,7 @@ namespace Grpc.Core.Internal.Tests var resultTask = asyncCall.ClientStreamingCallAsync(); fakeCall.UnaryResponseClientCallback.OnUnaryResponseClient(true, CreateClientSideStatus(StatusCode.InvalidArgument), - null, + CreateNullResponse(), new Metadata()); AssertUnaryResponseError(asyncCall, fakeCall, resultTask, StatusCode.InvalidArgument); @@ -214,7 +218,7 @@ namespace Grpc.Core.Internal.Tests fakeCall.UnaryResponseClientCallback.OnUnaryResponseClient(true, CreateClientSideStatus(StatusCode.Internal), - null, + CreateNullResponse(), new Metadata()); var ex = Assert.ThrowsAsync(async () => await writeTask); @@ -233,7 +237,7 @@ namespace Grpc.Core.Internal.Tests fakeCall.UnaryResponseClientCallback.OnUnaryResponseClient(true, CreateClientSideStatus(StatusCode.Internal), - null, + CreateNullResponse(), new Metadata()); fakeCall.SendCompletionCallback.OnSendCompletion(false); @@ -259,7 +263,7 @@ namespace Grpc.Core.Internal.Tests fakeCall.UnaryResponseClientCallback.OnUnaryResponseClient(true, CreateClientSideStatus(StatusCode.Internal), - null, + CreateNullResponse(), new Metadata()); var ex = Assert.ThrowsAsync(async () => await writeTask); @@ -357,7 +361,7 @@ namespace Grpc.Core.Internal.Tests fakeCall.UnaryResponseClientCallback.OnUnaryResponseClient(true, CreateClientSideStatus(StatusCode.Cancelled), - null, + CreateNullResponse(), new Metadata()); AssertUnaryResponseError(asyncCall, fakeCall, resultTask, StatusCode.Cancelled); @@ -390,7 +394,7 @@ namespace Grpc.Core.Internal.Tests fakeCall.ReceivedResponseHeadersCallback.OnReceivedResponseHeaders(true, new Metadata()); Assert.AreEqual(0, asyncCall.ResponseHeadersAsync.Result.Count); - fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, null); + fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, CreateNullResponse()); fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, new ClientSideStatus(Status.DefaultSuccess, new Metadata())); AssertStreamingResponseSuccess(asyncCall, fakeCall, readTask); @@ -405,7 +409,7 @@ namespace Grpc.Core.Internal.Tests // try alternative order of completions fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, new ClientSideStatus(Status.DefaultSuccess, new Metadata())); - fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, null); + fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, CreateNullResponse()); AssertStreamingResponseSuccess(asyncCall, fakeCall, readTask); } @@ -417,7 +421,7 @@ namespace Grpc.Core.Internal.Tests var responseStream = new ClientResponseStream(asyncCall); var readTask = responseStream.MoveNext(); - fakeCall.ReceivedMessageCallback.OnReceivedMessage(false, null); // after a failed read, we rely on C core to deliver appropriate status code. + fakeCall.ReceivedMessageCallback.OnReceivedMessage(false, CreateNullResponse()); // after a failed read, we rely on C core to deliver appropriate status code. fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, CreateClientSideStatus(StatusCode.Internal)); AssertStreamingResponseError(asyncCall, fakeCall, readTask, StatusCode.Internal); @@ -441,7 +445,7 @@ namespace Grpc.Core.Internal.Tests var readTask3 = responseStream.MoveNext(); fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, new ClientSideStatus(Status.DefaultSuccess, new Metadata())); - fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, null); + fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, CreateNullResponse()); AssertStreamingResponseSuccess(asyncCall, fakeCall, readTask3); } @@ -479,7 +483,7 @@ namespace Grpc.Core.Internal.Tests Assert.DoesNotThrowAsync(async () => await writeTask1); var readTask = responseStream.MoveNext(); - fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, null); + fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, CreateNullResponse()); fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, new ClientSideStatus(Status.DefaultSuccess, new Metadata())); AssertStreamingResponseSuccess(asyncCall, fakeCall, readTask); @@ -493,7 +497,7 @@ namespace Grpc.Core.Internal.Tests var responseStream = new ClientResponseStream(asyncCall); var readTask = responseStream.MoveNext(); - fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, null); + fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, CreateNullResponse()); fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, new ClientSideStatus(Status.DefaultSuccess, new Metadata())); AssertStreamingResponseSuccess(asyncCall, fakeCall, readTask); @@ -511,7 +515,7 @@ namespace Grpc.Core.Internal.Tests var responseStream = new ClientResponseStream(asyncCall); var readTask = responseStream.MoveNext(); - fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, null); + fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, CreateNullResponse()); fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, new ClientSideStatus(Status.DefaultSuccess, new Metadata())); AssertStreamingResponseSuccess(asyncCall, fakeCall, readTask); @@ -533,7 +537,7 @@ namespace Grpc.Core.Internal.Tests Assert.IsFalse(writeTask.IsCompleted); var readTask = responseStream.MoveNext(); - fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, null); + fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, CreateNullResponse()); fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, CreateClientSideStatus(StatusCode.PermissionDenied)); var ex = Assert.ThrowsAsync(async () => await writeTask); @@ -552,7 +556,7 @@ namespace Grpc.Core.Internal.Tests var writeTask = requestStream.WriteAsync("request1"); var readTask = responseStream.MoveNext(); - fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, null); + fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, CreateNullResponse()); fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, CreateClientSideStatus(StatusCode.PermissionDenied)); fakeCall.SendCompletionCallback.OnSendCompletion(false); @@ -576,7 +580,7 @@ namespace Grpc.Core.Internal.Tests Assert.ThrowsAsync(typeof(TaskCanceledException), async () => await writeTask); var readTask = responseStream.MoveNext(); - fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, null); + fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, CreateNullResponse()); fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, CreateClientSideStatus(StatusCode.Cancelled)); AssertStreamingResponseError(asyncCall, fakeCall, readTask, StatusCode.Cancelled); @@ -597,7 +601,7 @@ namespace Grpc.Core.Internal.Tests Assert.AreEqual("response1", responseStream.Current); var readTask2 = responseStream.MoveNext(); - fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, null); + fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, CreateNullResponse()); fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, CreateClientSideStatus(StatusCode.Cancelled)); AssertStreamingResponseError(asyncCall, fakeCall, readTask2, StatusCode.Cancelled); @@ -618,7 +622,7 @@ namespace Grpc.Core.Internal.Tests Assert.AreEqual("response1", responseStream.Current); var readTask2 = responseStream.MoveNext(); - fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, null); + fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, CreateNullResponse()); fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, CreateClientSideStatus(StatusCode.Cancelled)); AssertStreamingResponseError(asyncCall, fakeCall, readTask2, StatusCode.Cancelled); @@ -638,9 +642,14 @@ namespace Grpc.Core.Internal.Tests return new ClientSideStatus(new Status(statusCode, ""), new Metadata()); } - byte[] CreateResponsePayload() + IBufferReader CreateResponsePayload() { - return Marshallers.StringMarshaller.Serializer("response1"); + return fakeBufferReaderManager.CreateSingleSegmentBufferReader(Marshallers.StringMarshaller.Serializer("response1")); + } + + IBufferReader CreateNullResponse() + { + return fakeBufferReaderManager.CreateNullPayloadBufferReader(); } static void AssertUnaryResponseSuccess(AsyncCall asyncCall, FakeNativeCall fakeCall, Task resultTask) diff --git a/src/csharp/Grpc.Core.Tests/Internal/CompletionQueueSafeHandleTest.cs b/src/csharp/Grpc.Core.Tests/Internal/CompletionQueueSafeHandleTest.cs index 7e4e2975c16..a0ea1cc4278 100644 --- a/src/csharp/Grpc.Core.Tests/Internal/CompletionQueueSafeHandleTest.cs +++ b/src/csharp/Grpc.Core.Tests/Internal/CompletionQueueSafeHandleTest.cs @@ -47,7 +47,6 @@ namespace Grpc.Core.Internal.Tests GrpcEnvironment.ReleaseAsync().Wait(); Assert.AreEqual(CompletionQueueEvent.CompletionType.Shutdown, ev.type); Assert.AreNotEqual(IntPtr.Zero, ev.success); - Assert.AreEqual(IntPtr.Zero, ev.tag); } } } diff --git a/src/csharp/Grpc.Core.Tests/Internal/DefaultDeserializationContextTest.cs b/src/csharp/Grpc.Core.Tests/Internal/DefaultDeserializationContextTest.cs new file mode 100644 index 00000000000..63baab31624 --- /dev/null +++ b/src/csharp/Grpc.Core.Tests/Internal/DefaultDeserializationContextTest.cs @@ -0,0 +1,240 @@ +#region Copyright notice and license + +// Copyright 2019 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. +// 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.Collections.Generic; +using Grpc.Core; +using Grpc.Core.Internal; +using Grpc.Core.Utils; +using NUnit.Framework; + +using System.Runtime.InteropServices; + +#if GRPC_CSHARP_SUPPORT_SYSTEM_MEMORY +using System.Buffers; +#endif + +namespace Grpc.Core.Internal.Tests +{ + public class DefaultDeserializationContextTest + { + FakeBufferReaderManager fakeBufferReaderManager; + + [SetUp] + public void Init() + { + fakeBufferReaderManager = new FakeBufferReaderManager(); + } + + [TearDown] + public void Cleanup() + { + fakeBufferReaderManager.Dispose(); + } + +#if GRPC_CSHARP_SUPPORT_SYSTEM_MEMORY + [TestCase] + public void PayloadAsReadOnlySequence_ZeroSegmentPayload() + { + var context = new DefaultDeserializationContext(); + context.Initialize(fakeBufferReaderManager.CreateMultiSegmentBufferReader(new List {})); + + Assert.AreEqual(0, context.PayloadLength); + + var sequence = context.PayloadAsReadOnlySequence(); + + Assert.AreEqual(ReadOnlySequence.Empty, sequence); + Assert.IsTrue(sequence.IsEmpty); + Assert.IsTrue(sequence.IsSingleSegment); + } + + [TestCase(0)] + [TestCase(1)] + [TestCase(10)] + [TestCase(100)] + [TestCase(1000)] + public void PayloadAsReadOnlySequence_SingleSegmentPayload(int segmentLength) + { + var origBuffer = GetTestBuffer(segmentLength); + var context = new DefaultDeserializationContext(); + context.Initialize(fakeBufferReaderManager.CreateSingleSegmentBufferReader(origBuffer)); + + Assert.AreEqual(origBuffer.Length, context.PayloadLength); + + var sequence = context.PayloadAsReadOnlySequence(); + + Assert.AreEqual(origBuffer.Length, sequence.Length); + Assert.AreEqual(origBuffer.Length, sequence.First.Length); + Assert.IsTrue(sequence.IsSingleSegment); + CollectionAssert.AreEqual(origBuffer, sequence.First.ToArray()); + } + + [TestCase(0, 5, 10)] + [TestCase(1, 1, 1)] + [TestCase(10, 100, 1000)] + [TestCase(100, 100, 10)] + [TestCase(1000, 1000, 1000)] + public void PayloadAsReadOnlySequence_MultiSegmentPayload(int segmentLen1, int segmentLen2, int segmentLen3) + { + var origBuffer1 = GetTestBuffer(segmentLen1); + var origBuffer2 = GetTestBuffer(segmentLen2); + var origBuffer3 = GetTestBuffer(segmentLen3); + int totalLen = origBuffer1.Length + origBuffer2.Length + origBuffer3.Length; + + var context = new DefaultDeserializationContext(); + context.Initialize(fakeBufferReaderManager.CreateMultiSegmentBufferReader(new List { origBuffer1, origBuffer2, origBuffer3 })); + + Assert.AreEqual(totalLen, context.PayloadLength); + + var sequence = context.PayloadAsReadOnlySequence(); + + Assert.AreEqual(totalLen, sequence.Length); + + var segmentEnumerator = sequence.GetEnumerator(); + + Assert.IsTrue(segmentEnumerator.MoveNext()); + CollectionAssert.AreEqual(origBuffer1, segmentEnumerator.Current.ToArray()); + + Assert.IsTrue(segmentEnumerator.MoveNext()); + CollectionAssert.AreEqual(origBuffer2, segmentEnumerator.Current.ToArray()); + + Assert.IsTrue(segmentEnumerator.MoveNext()); + CollectionAssert.AreEqual(origBuffer3, segmentEnumerator.Current.ToArray()); + + Assert.IsFalse(segmentEnumerator.MoveNext()); + } +#endif + + [TestCase] + public void NullPayloadNotAllowed() + { + var context = new DefaultDeserializationContext(); + Assert.Throws(typeof(InvalidOperationException), () => context.Initialize(fakeBufferReaderManager.CreateNullPayloadBufferReader())); + } + + [TestCase] + public void PayloadAsNewByteBuffer_ZeroSegmentPayload() + { + var context = new DefaultDeserializationContext(); + context.Initialize(fakeBufferReaderManager.CreateMultiSegmentBufferReader(new List {})); + + Assert.AreEqual(0, context.PayloadLength); + + var payload = context.PayloadAsNewBuffer(); + Assert.AreEqual(0, payload.Length); + } + + [TestCase(0)] + [TestCase(1)] + [TestCase(10)] + [TestCase(100)] + [TestCase(1000)] + public void PayloadAsNewByteBuffer_SingleSegmentPayload(int segmentLength) + { + var origBuffer = GetTestBuffer(segmentLength); + var context = new DefaultDeserializationContext(); + context.Initialize(fakeBufferReaderManager.CreateSingleSegmentBufferReader(origBuffer)); + + Assert.AreEqual(origBuffer.Length, context.PayloadLength); + + var payload = context.PayloadAsNewBuffer(); + CollectionAssert.AreEqual(origBuffer, payload); + } + + [TestCase(0, 5, 10)] + [TestCase(1, 1, 1)] + [TestCase(10, 100, 1000)] + [TestCase(100, 100, 10)] + [TestCase(1000, 1000, 1000)] + public void PayloadAsNewByteBuffer_MultiSegmentPayload(int segmentLen1, int segmentLen2, int segmentLen3) + { + var origBuffer1 = GetTestBuffer(segmentLen1); + var origBuffer2 = GetTestBuffer(segmentLen2); + var origBuffer3 = GetTestBuffer(segmentLen3); + + var context = new DefaultDeserializationContext(); + context.Initialize(fakeBufferReaderManager.CreateMultiSegmentBufferReader(new List { origBuffer1, origBuffer2, origBuffer3 })); + + var payload = context.PayloadAsNewBuffer(); + + var concatenatedOrigBuffers = new List(); + concatenatedOrigBuffers.AddRange(origBuffer1); + concatenatedOrigBuffers.AddRange(origBuffer2); + concatenatedOrigBuffers.AddRange(origBuffer3); + + Assert.AreEqual(concatenatedOrigBuffers.Count, context.PayloadLength); + Assert.AreEqual(concatenatedOrigBuffers.Count, payload.Length); + CollectionAssert.AreEqual(concatenatedOrigBuffers, payload); + } + + [TestCase] + public void GetPayloadMultipleTimesIsIllegal() + { + var origBuffer = GetTestBuffer(100); + var context = new DefaultDeserializationContext(); + context.Initialize(fakeBufferReaderManager.CreateSingleSegmentBufferReader(origBuffer)); + + Assert.AreEqual(origBuffer.Length, context.PayloadLength); + + var payload = context.PayloadAsNewBuffer(); + CollectionAssert.AreEqual(origBuffer, payload); + + // Getting payload multiple times is illegal + Assert.Throws(typeof(InvalidOperationException), () => context.PayloadAsNewBuffer()); +#if GRPC_CSHARP_SUPPORT_SYSTEM_MEMORY + Assert.Throws(typeof(InvalidOperationException), () => context.PayloadAsReadOnlySequence()); +#endif + } + + [TestCase] + public void ResetContextAndReinitialize() + { + var origBuffer = GetTestBuffer(100); + var context = new DefaultDeserializationContext(); + context.Initialize(fakeBufferReaderManager.CreateSingleSegmentBufferReader(origBuffer)); + + Assert.AreEqual(origBuffer.Length, context.PayloadLength); + + // Reset invalidates context + context.Reset(); + + Assert.AreEqual(0, context.PayloadLength); + Assert.Throws(typeof(NullReferenceException), () => context.PayloadAsNewBuffer()); +#if GRPC_CSHARP_SUPPORT_SYSTEM_MEMORY + Assert.Throws(typeof(NullReferenceException), () => context.PayloadAsReadOnlySequence()); +#endif + + // Previously reset context can be initialized again + var origBuffer2 = GetTestBuffer(50); + context.Initialize(fakeBufferReaderManager.CreateSingleSegmentBufferReader(origBuffer2)); + + Assert.AreEqual(origBuffer2.Length, context.PayloadLength); + CollectionAssert.AreEqual(origBuffer2, context.PayloadAsNewBuffer()); + } + + private byte[] GetTestBuffer(int length) + { + var testBuffer = new byte[length]; + for (int i = 0; i < testBuffer.Length; i++) + { + testBuffer[i] = (byte) i; + } + return testBuffer; + } + } +} diff --git a/src/csharp/Grpc.Core.Tests/Internal/FakeBufferReaderManager.cs b/src/csharp/Grpc.Core.Tests/Internal/FakeBufferReaderManager.cs new file mode 100644 index 00000000000..d8d0c0a6354 --- /dev/null +++ b/src/csharp/Grpc.Core.Tests/Internal/FakeBufferReaderManager.cs @@ -0,0 +1,118 @@ +#region Copyright notice and license + +// Copyright 2018 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. +// 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.Collections.Generic; +using System.Runtime.InteropServices; +using System.Threading.Tasks; + +using Grpc.Core.Internal; +using Grpc.Core.Utils; + +namespace Grpc.Core.Internal.Tests +{ + // Creates instances of fake IBufferReader. All created instances will become invalid once Dispose is called. + internal class FakeBufferReaderManager : IDisposable + { + List pinnedHandles = new List(); + bool disposed = false; + public IBufferReader CreateSingleSegmentBufferReader(byte[] data) + { + return CreateMultiSegmentBufferReader(new List { data }); + } + + public IBufferReader CreateMultiSegmentBufferReader(IEnumerable dataSegments) + { + GrpcPreconditions.CheckState(!disposed); + GrpcPreconditions.CheckNotNull(dataSegments); + var segments = new List(); + foreach (var data in dataSegments) + { + GrpcPreconditions.CheckNotNull(data); + segments.Add(GCHandle.Alloc(data, GCHandleType.Pinned)); + } + pinnedHandles.AddRange(segments); // all the allocated GCHandles will be freed on Dispose() + return new FakeBufferReader(segments); + } + + public IBufferReader CreateNullPayloadBufferReader() + { + GrpcPreconditions.CheckState(!disposed); + return new FakeBufferReader(null); + } + + public void Dispose() + { + if (!disposed) + { + disposed = true; + for (int i = 0; i < pinnedHandles.Count; i++) + { + pinnedHandles[i].Free(); + } + } + } + + private class FakeBufferReader : IBufferReader + { + readonly List bufferSegments; + readonly int? totalLength; + readonly IEnumerator segmentEnumerator; + + public FakeBufferReader(List bufferSegments) + { + this.bufferSegments = bufferSegments; + this.totalLength = ComputeTotalLength(bufferSegments); + this.segmentEnumerator = bufferSegments?.GetEnumerator(); + } + + public int? TotalLength => totalLength; + + public bool TryGetNextSlice(out Slice slice) + { + GrpcPreconditions.CheckNotNull(bufferSegments); + if (!segmentEnumerator.MoveNext()) + { + slice = default(Slice); + return false; + } + + var segment = segmentEnumerator.Current; + int sliceLen = ((byte[]) segment.Target).Length; + slice = new Slice(segment.AddrOfPinnedObject(), sliceLen); + return true; + } + + static int? ComputeTotalLength(List bufferSegments) + { + if (bufferSegments == null) + { + return null; + } + + int sum = 0; + foreach (var segment in bufferSegments) + { + var data = (byte[]) segment.Target; + sum += data.Length; + } + return sum; + } + } + } +} diff --git a/src/csharp/Grpc.Core.Tests/Internal/FakeBufferReaderManagerTest.cs b/src/csharp/Grpc.Core.Tests/Internal/FakeBufferReaderManagerTest.cs new file mode 100644 index 00000000000..7c4ff652bd3 --- /dev/null +++ b/src/csharp/Grpc.Core.Tests/Internal/FakeBufferReaderManagerTest.cs @@ -0,0 +1,121 @@ +#region Copyright notice and license + +// Copyright 2018 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. +// 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.Collections.Generic; +using Grpc.Core; +using Grpc.Core.Internal; +using Grpc.Core.Utils; +using NUnit.Framework; + +namespace Grpc.Core.Internal.Tests +{ + public class FakeBufferReaderManagerTest + { + FakeBufferReaderManager fakeBufferReaderManager; + + [SetUp] + public void Init() + { + fakeBufferReaderManager = new FakeBufferReaderManager(); + } + + [TearDown] + public void Cleanup() + { + fakeBufferReaderManager.Dispose(); + } + + [TestCase] + public void NullPayload() + { + var fakeBufferReader = fakeBufferReaderManager.CreateNullPayloadBufferReader(); + Assert.IsFalse(fakeBufferReader.TotalLength.HasValue); + Assert.Throws(typeof(ArgumentNullException), () => fakeBufferReader.TryGetNextSlice(out Slice slice)); + } + [TestCase] + public void ZeroSegmentPayload() + { + var fakeBufferReader = fakeBufferReaderManager.CreateMultiSegmentBufferReader(new List {}); + Assert.AreEqual(0, fakeBufferReader.TotalLength.Value); + Assert.IsFalse(fakeBufferReader.TryGetNextSlice(out Slice slice)); + } + + [TestCase(0)] + [TestCase(1)] + [TestCase(10)] + [TestCase(30)] + [TestCase(100)] + [TestCase(1000)] + public void SingleSegmentPayload(int bufferLen) + { + var origBuffer = GetTestBuffer(bufferLen); + var fakeBufferReader = fakeBufferReaderManager.CreateSingleSegmentBufferReader(origBuffer); + Assert.AreEqual(origBuffer.Length, fakeBufferReader.TotalLength.Value); + + Assert.IsTrue(fakeBufferReader.TryGetNextSlice(out Slice slice)); + AssertSliceDataEqual(origBuffer, slice); + + Assert.IsFalse(fakeBufferReader.TryGetNextSlice(out Slice slice2)); + } + + [TestCase(0, 5, 10)] + [TestCase(1, 1, 1)] + [TestCase(10, 100, 1000)] + [TestCase(100, 100, 10)] + [TestCase(1000, 1000, 1000)] + public void MultiSegmentPayload(int segmentLen1, int segmentLen2, int segmentLen3) + { + var origBuffer1 = GetTestBuffer(segmentLen1); + var origBuffer2 = GetTestBuffer(segmentLen2); + var origBuffer3 = GetTestBuffer(segmentLen3); + var fakeBufferReader = fakeBufferReaderManager.CreateMultiSegmentBufferReader(new List { origBuffer1, origBuffer2, origBuffer3 }); + + Assert.AreEqual(origBuffer1.Length + origBuffer2.Length + origBuffer3.Length, fakeBufferReader.TotalLength.Value); + + Assert.IsTrue(fakeBufferReader.TryGetNextSlice(out Slice slice1)); + AssertSliceDataEqual(origBuffer1, slice1); + + Assert.IsTrue(fakeBufferReader.TryGetNextSlice(out Slice slice2)); + AssertSliceDataEqual(origBuffer2, slice2); + + Assert.IsTrue(fakeBufferReader.TryGetNextSlice(out Slice slice3)); + AssertSliceDataEqual(origBuffer3, slice3); + + Assert.IsFalse(fakeBufferReader.TryGetNextSlice(out Slice slice4)); + } + + private void AssertSliceDataEqual(byte[] expected, Slice actual) + { + var actualSliceData = new byte[actual.Length]; + actual.CopyTo(new ArraySegment(actualSliceData)); + CollectionAssert.AreEqual(expected, actualSliceData); + } + + // create a buffer of given size and fill it with some data + private byte[] GetTestBuffer(int length) + { + var testBuffer = new byte[length]; + for (int i = 0; i < testBuffer.Length; i++) + { + testBuffer[i] = (byte) i; + } + return testBuffer; + } + } +} diff --git a/src/csharp/Grpc.Core.Tests/Internal/ReusableSliceBufferTest.cs b/src/csharp/Grpc.Core.Tests/Internal/ReusableSliceBufferTest.cs new file mode 100644 index 00000000000..7630785aef4 --- /dev/null +++ b/src/csharp/Grpc.Core.Tests/Internal/ReusableSliceBufferTest.cs @@ -0,0 +1,151 @@ +#region Copyright notice and license + +// Copyright 2018 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. +// 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.Collections.Generic; +using System.Linq; +using Grpc.Core; +using Grpc.Core.Internal; +using Grpc.Core.Utils; +using NUnit.Framework; + +using System.Runtime.InteropServices; + +#if GRPC_CSHARP_SUPPORT_SYSTEM_MEMORY +using System.Buffers; +#endif + +namespace Grpc.Core.Internal.Tests +{ + // Converts IBufferReader into instances of ReadOnlySequence + // Objects representing the sequence segments are cached to decrease GC load. + public class ReusableSliceBufferTest + { + FakeBufferReaderManager fakeBufferReaderManager; + + [SetUp] + public void Init() + { + fakeBufferReaderManager = new FakeBufferReaderManager(); + } + + [TearDown] + public void Cleanup() + { + fakeBufferReaderManager.Dispose(); + } + +#if GRPC_CSHARP_SUPPORT_SYSTEM_MEMORY + [TestCase] + public void NullPayload() + { + var sliceBuffer = new ReusableSliceBuffer(); + Assert.Throws(typeof(ArgumentNullException), () => sliceBuffer.PopulateFrom(fakeBufferReaderManager.CreateNullPayloadBufferReader())); + } + + [TestCase] + public void ZeroSegmentPayload() + { + var sliceBuffer = new ReusableSliceBuffer(); + var sequence = sliceBuffer.PopulateFrom(fakeBufferReaderManager.CreateMultiSegmentBufferReader(new List {})); + + Assert.AreEqual(ReadOnlySequence.Empty, sequence); + Assert.IsTrue(sequence.IsEmpty); + Assert.IsTrue(sequence.IsSingleSegment); + } + + [TestCase] + public void SegmentsAreCached() + { + var bufferSegments1 = Enumerable.Range(0, 100).Select((_) => GetTestBuffer(50)).ToList(); + var bufferSegments2 = Enumerable.Range(0, 100).Select((_) => GetTestBuffer(50)).ToList(); + + var sliceBuffer = new ReusableSliceBuffer(); + + var sequence1 = sliceBuffer.PopulateFrom(fakeBufferReaderManager.CreateMultiSegmentBufferReader(bufferSegments1)); + var memoryManagers1 = GetMemoryManagersForSequenceSegments(sequence1); + + sliceBuffer.Invalidate(); + + var sequence2 = sliceBuffer.PopulateFrom(fakeBufferReaderManager.CreateMultiSegmentBufferReader(bufferSegments2)); + var memoryManagers2 = GetMemoryManagersForSequenceSegments(sequence2); + + // check memory managers are identical objects (i.e. they've been reused) + CollectionAssert.AreEquivalent(memoryManagers1, memoryManagers2); + } + + [TestCase] + public void MultiSegmentPayload_LotsOfSegments() + { + var bufferSegments = Enumerable.Range(0, ReusableSliceBuffer.MaxCachedSegments + 100).Select((_) => GetTestBuffer(10)).ToList(); + + var sliceBuffer = new ReusableSliceBuffer(); + var sequence = sliceBuffer.PopulateFrom(fakeBufferReaderManager.CreateMultiSegmentBufferReader(bufferSegments)); + + int index = 0; + foreach (var memory in sequence) + { + CollectionAssert.AreEqual(bufferSegments[index], memory.ToArray()); + index ++; + } + } + + [TestCase] + public void InvalidateMakesSequenceUnusable() + { + var origBuffer = GetTestBuffer(100); + + var sliceBuffer = new ReusableSliceBuffer(); + var sequence = sliceBuffer.PopulateFrom(fakeBufferReaderManager.CreateMultiSegmentBufferReader(new List { origBuffer })); + + Assert.AreEqual(origBuffer.Length, sequence.Length); + + sliceBuffer.Invalidate(); + + // Invalidate with make the returned sequence completely unusable and broken, users must not use it beyond the deserializer functions. + Assert.Throws(typeof(ArgumentOutOfRangeException), () => { var first = sequence.First; }); + } + + private List> GetMemoryManagersForSequenceSegments(ReadOnlySequence sequence) + { + var result = new List>(); + foreach (var memory in sequence) + { + Assert.IsTrue(MemoryMarshal.TryGetMemoryManager(memory, out MemoryManager memoryManager)); + result.Add(memoryManager); + } + return result; + } +#else + [TestCase] + public void OnlySupportedOnNetCore() + { + // Test case needs to exist to make C# sanity test happy. + } +#endif + private byte[] GetTestBuffer(int length) + { + var testBuffer = new byte[length]; + for (int i = 0; i < testBuffer.Length; i++) + { + testBuffer[i] = (byte) i; + } + return testBuffer; + } + } +} diff --git a/src/csharp/Grpc.Core.Tests/Internal/SliceTest.cs b/src/csharp/Grpc.Core.Tests/Internal/SliceTest.cs new file mode 100644 index 00000000000..eb090bbfa50 --- /dev/null +++ b/src/csharp/Grpc.Core.Tests/Internal/SliceTest.cs @@ -0,0 +1,83 @@ +#region Copyright notice and license + +// Copyright 2018 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. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#endregion + +using System; +using Grpc.Core; +using Grpc.Core.Internal; +using Grpc.Core.Utils; +using NUnit.Framework; + +using System.Runtime.InteropServices; + +namespace Grpc.Core.Internal.Tests +{ + public class SliceTest + { + [TestCase(0)] + [TestCase(1)] + [TestCase(10)] + [TestCase(100)] + [TestCase(1000)] + public void SliceFromNativePtr_CopyToArraySegment(int bufferLength) + { + var origBuffer = GetTestBuffer(bufferLength); + var gcHandle = GCHandle.Alloc(origBuffer, GCHandleType.Pinned); + try + { + var slice = new Slice(gcHandle.AddrOfPinnedObject(), origBuffer.Length); + Assert.AreEqual(bufferLength, slice.Length); + + var newBuffer = new byte[bufferLength]; + slice.CopyTo(new ArraySegment(newBuffer)); + CollectionAssert.AreEqual(origBuffer, newBuffer); + } + finally + { + gcHandle.Free(); + } + } + + [TestCase] + public void SliceFromNativePtr_CopyToArraySegmentTooSmall() + { + var origBuffer = GetTestBuffer(100); + var gcHandle = GCHandle.Alloc(origBuffer, GCHandleType.Pinned); + try + { + var slice = new Slice(gcHandle.AddrOfPinnedObject(), origBuffer.Length); + var tooSmall = new byte[origBuffer.Length - 1]; + Assert.Catch(typeof(ArgumentException), () => slice.CopyTo(new ArraySegment(tooSmall))); + } + finally + { + gcHandle.Free(); + } + } + + // create a buffer of given size and fill it with some data + private byte[] GetTestBuffer(int length) + { + var testBuffer = new byte[length]; + for (int i = 0; i < testBuffer.Length; i++) + { + testBuffer[i] = (byte) i; + } + return testBuffer; + } + } +} diff --git a/src/csharp/Grpc.Core.Tests/NUnitMain.cs b/src/csharp/Grpc.Core.Tests/NUnitMain.cs index 49cb8cd3b99..3b206603f14 100644 --- a/src/csharp/Grpc.Core.Tests/NUnitMain.cs +++ b/src/csharp/Grpc.Core.Tests/NUnitMain.cs @@ -34,11 +34,7 @@ namespace Grpc.Core.Tests { // Make logger immune to NUnit capturing stdout and stderr to workaround https://github.com/nunit/nunit/issues/1406. GrpcEnvironment.SetLogger(new ConsoleLogger()); -#if NETCOREAPP1_0 - return new AutoRun(typeof(NUnitMain).GetTypeInfo().Assembly).Execute(args, new ExtendedTextWrapper(Console.Out), Console.In); -#else - return new AutoRun().Execute(args); -#endif + return new AutoRun(typeof(NUnitMain).GetTypeInfo().Assembly).Execute(args); } } } diff --git a/src/csharp/Grpc.Core.Tests/SanityTest.cs b/src/csharp/Grpc.Core.Tests/SanityTest.cs index 0904453b6e9..f785f70f4ce 100644 --- a/src/csharp/Grpc.Core.Tests/SanityTest.cs +++ b/src/csharp/Grpc.Core.Tests/SanityTest.cs @@ -31,7 +31,7 @@ namespace Grpc.Core.Tests public class SanityTest { // TODO: make sanity test work for CoreCLR as well -#if !NETCOREAPP1_0 +#if !NETCOREAPP1_1 && !NETCOREAPP2_1 /// /// Because we depend on a native library, sometimes when things go wrong, the /// entire NUnit test process crashes. To be able to track down problems better, @@ -44,7 +44,7 @@ namespace Grpc.Core.Tests public void TestsJsonUpToDate() { var discoveredTests = DiscoverAllTestClasses(); - var testsFromFile + var testsFromFile = JsonConvert.DeserializeObject>>(ReadTestsJson()); Assert.AreEqual(discoveredTests, testsFromFile); diff --git a/src/csharp/Grpc.Core/CallCredentials.cs b/src/csharp/Grpc.Core/CallCredentials.cs deleted file mode 100644 index c1bd95b9e22..00000000000 --- a/src/csharp/Grpc.Core/CallCredentials.cs +++ /dev/null @@ -1,129 +0,0 @@ -#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.Collections.Generic; -using System.Threading.Tasks; - -using Grpc.Core.Internal; -using Grpc.Core.Utils; - -namespace Grpc.Core -{ - /// - /// Client-side call credentials. Provide authorization with per-call granularity. - /// - public abstract class CallCredentials - { - /// - /// Composes multiple multiple CallCredentials objects into - /// a single CallCredentials object. - /// - /// credentials to compose - /// The new CompositeCallCredentials - public static CallCredentials Compose(params CallCredentials[] credentials) - { - return new CompositeCallCredentials(credentials); - } - - /// - /// Creates a new instance of CallCredentials class from an - /// interceptor that can attach metadata to outgoing calls. - /// - /// authentication interceptor - public static CallCredentials FromInterceptor(AsyncAuthInterceptor interceptor) - { - return new MetadataCredentials(interceptor); - } - - /// - /// Creates native object for the credentials. - /// - /// The native credentials. - internal abstract CallCredentialsSafeHandle ToNativeCredentials(); - } - - /// - /// Client-side credentials that delegate metadata based auth to an interceptor. - /// The interceptor is automatically invoked for each remote call that uses MetadataCredentials. - /// - internal sealed class MetadataCredentials : CallCredentials - { - readonly AsyncAuthInterceptor interceptor; - - /// - /// Initializes a new instance of MetadataCredentials class. - /// - /// authentication interceptor - public MetadataCredentials(AsyncAuthInterceptor interceptor) - { - this.interceptor = GrpcPreconditions.CheckNotNull(interceptor); - } - - internal override CallCredentialsSafeHandle ToNativeCredentials() - { - NativeMetadataCredentialsPlugin plugin = new NativeMetadataCredentialsPlugin(interceptor); - return plugin.Credentials; - } - } - - /// - /// Credentials that allow composing multiple credentials objects into one object. - /// - internal sealed class CompositeCallCredentials : CallCredentials - { - readonly List credentials; - - /// - /// Initializes a new instance of CompositeCallCredentials class. - /// The resulting credentials object will be composite of all the credentials specified as parameters. - /// - /// credentials to compose - public CompositeCallCredentials(params CallCredentials[] credentials) - { - GrpcPreconditions.CheckArgument(credentials.Length >= 2, "Composite credentials object can only be created from 2 or more credentials."); - this.credentials = new List(credentials); - } - - internal override CallCredentialsSafeHandle ToNativeCredentials() - { - return ToNativeRecursive(0); - } - - // Recursive descent makes managing lifetime of intermediate CredentialSafeHandle instances easier. - // In practice, we won't usually see composites from more than two credentials anyway. - private CallCredentialsSafeHandle ToNativeRecursive(int startIndex) - { - if (startIndex == credentials.Count - 1) - { - return credentials[startIndex].ToNativeCredentials(); - } - - using (var cred1 = credentials[startIndex].ToNativeCredentials()) - using (var cred2 = ToNativeRecursive(startIndex + 1)) - { - var nativeComposite = CallCredentialsSafeHandle.CreateComposite(cred1, cred2); - if (nativeComposite.IsInvalid) - { - throw new ArgumentException("Error creating native composite credentials. Likely, this is because you are trying to compose incompatible credentials."); - } - return nativeComposite; - } - } - } -} diff --git a/src/csharp/Grpc.Core/Channel.cs b/src/csharp/Grpc.Core/Channel.cs index 7ce929dfa31..97f79b0fb4f 100644 --- a/src/csharp/Grpc.Core/Channel.cs +++ b/src/csharp/Grpc.Core/Channel.cs @@ -59,7 +59,7 @@ namespace Grpc.Core /// /// Creates a channel that connects to a specific host. - /// Port will default to 80 for an unsecure channel and to 443 for a secure channel. + /// Port will default to 80 for an unsecure channel or to 443 for a secure channel. /// /// Target of the channel. /// Credentials to secure the channel. @@ -112,7 +112,7 @@ namespace Grpc.Core /// /// Gets current connectivity state of this channel. - /// After channel is has been shutdown, ChannelState.Shutdown will be returned. + /// After channel has been shutdown, ChannelState.Shutdown will be returned. /// public ChannelState State { @@ -132,7 +132,7 @@ namespace Grpc.Core /// /// Returned tasks completes once channel state has become different from /// given lastObservedState. - /// If deadline is reached or and error occurs, returned task is cancelled. + /// If deadline is reached or an error occurs, returned task is cancelled. /// public async Task WaitForStateChangedAsync(ChannelState lastObservedState, DateTime? deadline = null) { diff --git a/src/csharp/Grpc.Core/ChannelCredentials.cs b/src/csharp/Grpc.Core/ChannelCredentials.cs index 3ce32f31b76..dcbe9f3599b 100644 --- a/src/csharp/Grpc.Core/ChannelCredentials.cs +++ b/src/csharp/Grpc.Core/ChannelCredentials.cs @@ -18,9 +18,11 @@ using System; using System.Collections.Generic; +using System.Runtime.InteropServices; using System.Threading.Tasks; using Grpc.Core.Internal; +using Grpc.Core.Logging; using Grpc.Core.Utils; namespace Grpc.Core @@ -104,20 +106,38 @@ namespace Grpc.Core } } + /// + /// Callback invoked with the expected targetHost and the peer's certificate. + /// If false is returned by this callback then it is treated as a + /// verification failure and the attempted connection will fail. + /// Invocation of the callback is blocking, so any + /// implementation should be light-weight. + /// Note that the callback can potentially be invoked multiple times, + /// concurrently from different threads (e.g. when multiple connections + /// are being created for the same credentials). + /// + /// The associated with the callback + /// true if verification succeeded, false otherwise. + /// Note: experimental API that can change or be removed without any prior notice. + public delegate bool VerifyPeerCallback(VerifyPeerContext context); + /// /// Client-side SSL credentials. /// public sealed class SslCredentials : ChannelCredentials { + static readonly ILogger Logger = GrpcEnvironment.Logger.ForType(); + readonly string rootCertificates; readonly KeyCertificatePair keyCertificatePair; + readonly VerifyPeerCallback verifyPeerCallback; /// /// Creates client-side SSL credentials loaded from /// disk file pointed to by the GRPC_DEFAULT_SSL_ROOTS_FILE_PATH environment variable. /// If that fails, gets the roots certificates from a well known place on disk. /// - public SslCredentials() : this(null, null) + public SslCredentials() : this(null, null, null) { } @@ -125,19 +145,32 @@ namespace Grpc.Core /// Creates client-side SSL credentials from /// a string containing PEM encoded root certificates. /// - public SslCredentials(string rootCertificates) : this(rootCertificates, null) + public SslCredentials(string rootCertificates) : this(rootCertificates, null, null) { } - + /// /// Creates client-side SSL credentials. /// /// string containing PEM encoded server root certificates. /// a key certificate pair. - public SslCredentials(string rootCertificates, KeyCertificatePair keyCertificatePair) + public SslCredentials(string rootCertificates, KeyCertificatePair keyCertificatePair) : + this(rootCertificates, keyCertificatePair, null) + { + } + + /// + /// Creates client-side SSL credentials. + /// + /// string containing PEM encoded server root certificates. + /// a key certificate pair. + /// a callback to verify peer's target name and certificate. + /// Note: experimental API that can change or be removed without any prior notice. + public SslCredentials(string rootCertificates, KeyCertificatePair keyCertificatePair, VerifyPeerCallback verifyPeerCallback) { this.rootCertificates = rootCertificates; this.keyCertificatePair = keyCertificatePair; + this.verifyPeerCallback = verifyPeerCallback; } /// @@ -171,7 +204,54 @@ namespace Grpc.Core internal override ChannelCredentialsSafeHandle CreateNativeCredentials() { - return ChannelCredentialsSafeHandle.CreateSslCredentials(rootCertificates, keyCertificatePair); + IntPtr verifyPeerCallbackTag = IntPtr.Zero; + if (verifyPeerCallback != null) + { + verifyPeerCallbackTag = new VerifyPeerCallbackRegistration(verifyPeerCallback).CallbackRegistration.Tag; + } + return ChannelCredentialsSafeHandle.CreateSslCredentials(rootCertificates, keyCertificatePair, verifyPeerCallbackTag); + } + + private class VerifyPeerCallbackRegistration + { + readonly VerifyPeerCallback verifyPeerCallback; + readonly NativeCallbackRegistration callbackRegistration; + + public VerifyPeerCallbackRegistration(VerifyPeerCallback verifyPeerCallback) + { + this.verifyPeerCallback = verifyPeerCallback; + this.callbackRegistration = NativeCallbackDispatcher.RegisterCallback(HandleUniversalCallback); + } + + public NativeCallbackRegistration CallbackRegistration => callbackRegistration; + + private int HandleUniversalCallback(IntPtr arg0, IntPtr arg1, IntPtr arg2, IntPtr arg3, IntPtr arg4, IntPtr arg5) + { + return VerifyPeerCallbackHandler(arg0, arg1, arg2 != IntPtr.Zero); + } + + private int VerifyPeerCallbackHandler(IntPtr targetName, IntPtr peerPem, bool isDestroy) + { + if (isDestroy) + { + this.callbackRegistration.Dispose(); + return 0; + } + + try + { + var context = new VerifyPeerContext(Marshal.PtrToStringAnsi(targetName), Marshal.PtrToStringAnsi(peerPem)); + + return this.verifyPeerCallback(context) ? 0 : 1; + } + catch (Exception e) + { + // eat the exception, we must not throw when inside callback from native code. + Logger.Error(e, "Exception occurred while invoking verify peer callback handler."); + // Return validation failure in case of exception. + return 1; + } + } } } diff --git a/src/csharp/Grpc.Core/ForwardedTypes.cs b/src/csharp/Grpc.Core/ForwardedTypes.cs new file mode 100644 index 00000000000..ab5f5a87c67 --- /dev/null +++ b/src/csharp/Grpc.Core/ForwardedTypes.cs @@ -0,0 +1,68 @@ +#region Copyright notice and license + +// Copyright 2019 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. +// 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.Runtime.CompilerServices; +using Grpc.Core; +using Grpc.Core.Interceptors; +using Grpc.Core.Internal; +using Grpc.Core.Utils; + +// API types that used to be in Grpc.Core package, but were moved to Grpc.Core.Api +// https://docs.microsoft.com/en-us/dotnet/framework/app-domains/type-forwarding-in-the-common-language-runtime + +[assembly:TypeForwardedToAttribute(typeof(GrpcPreconditions))] +[assembly:TypeForwardedToAttribute(typeof(AsyncClientStreamingCall<,>))] +[assembly:TypeForwardedToAttribute(typeof(AsyncDuplexStreamingCall<,>))] +[assembly:TypeForwardedToAttribute(typeof(AsyncServerStreamingCall<>))] +[assembly:TypeForwardedToAttribute(typeof(AsyncUnaryCall<>))] +[assembly:TypeForwardedToAttribute(typeof(AuthContext))] +[assembly:TypeForwardedToAttribute(typeof(AsyncAuthInterceptor))] +[assembly:TypeForwardedToAttribute(typeof(AuthInterceptorContext))] +[assembly:TypeForwardedToAttribute(typeof(CallCredentials))] +[assembly:TypeForwardedToAttribute(typeof(CallFlags))] +[assembly:TypeForwardedToAttribute(typeof(CallInvoker))] +[assembly:TypeForwardedToAttribute(typeof(CallOptions))] +[assembly:TypeForwardedToAttribute(typeof(ClientInterceptorContext<,>))] +[assembly:TypeForwardedToAttribute(typeof(ContextPropagationOptions))] +[assembly:TypeForwardedToAttribute(typeof(ContextPropagationToken))] +[assembly:TypeForwardedToAttribute(typeof(DeserializationContext))] +[assembly:TypeForwardedToAttribute(typeof(IAsyncStreamReader<>))] +[assembly:TypeForwardedToAttribute(typeof(IAsyncStreamWriter<>))] +[assembly:TypeForwardedToAttribute(typeof(IClientStreamWriter<>))] +[assembly:TypeForwardedToAttribute(typeof(Interceptor))] +[assembly:TypeForwardedToAttribute(typeof(IServerStreamWriter<>))] +[assembly:TypeForwardedToAttribute(typeof(Marshaller<>))] +[assembly:TypeForwardedToAttribute(typeof(Marshallers))] +[assembly:TypeForwardedToAttribute(typeof(Metadata))] +[assembly:TypeForwardedToAttribute(typeof(MethodType))] +[assembly:TypeForwardedToAttribute(typeof(IMethod))] +[assembly:TypeForwardedToAttribute(typeof(Method<,>))] +[assembly:TypeForwardedToAttribute(typeof(RpcException))] +[assembly:TypeForwardedToAttribute(typeof(SerializationContext))] +[assembly:TypeForwardedToAttribute(typeof(ServerCallContext))] +[assembly:TypeForwardedToAttribute(typeof(UnaryServerMethod<,>))] +[assembly:TypeForwardedToAttribute(typeof(ClientStreamingServerMethod<,>))] +[assembly:TypeForwardedToAttribute(typeof(ServerStreamingServerMethod<,>))] +[assembly:TypeForwardedToAttribute(typeof(DuplexStreamingServerMethod<,>))] +[assembly:TypeForwardedToAttribute(typeof(ServerServiceDefinition))] +[assembly:TypeForwardedToAttribute(typeof(ServiceBinderBase))] +[assembly:TypeForwardedToAttribute(typeof(Status))] +[assembly:TypeForwardedToAttribute(typeof(StatusCode))] +[assembly:TypeForwardedToAttribute(typeof(VersionInfo))] +[assembly:TypeForwardedToAttribute(typeof(WriteOptions))] +[assembly:TypeForwardedToAttribute(typeof(WriteFlags))] diff --git a/src/csharp/Grpc.Core/Grpc.Core.csproj b/src/csharp/Grpc.Core/Grpc.Core.csproj index dc5683c9753..afd60e73a21 100755 --- a/src/csharp/Grpc.Core/Grpc.Core.csproj +++ b/src/csharp/Grpc.Core/Grpc.Core.csproj @@ -1,23 +1,37 @@  - - Copyright 2015, Google Inc. - gRPC C# Core - $(GrpcCsharpVersion) - Google Inc. - net45;netstandard1.5 - Grpc.Core - Grpc.Core - gRPC RPC Protocol HTTP/2 + The gRPC Authors + Copyright 2015 The gRPC Authors + C# implementation of gRPC based on native gRPC C-core library. + https://github.com/grpc/grpc.github.io/raw/master/img/grpc_square_reverse_4x.png + Apache-2.0 https://github.com/grpc/grpc - https://github.com/grpc/grpc/blob/master/LICENSE + gRPC RPC HTTP/2 + $(GrpcCsharpVersion) + + + + net45;netstandard1.5;netstandard2.0 true true + + true + + + + 7.2 + $(DefineConstants);GRPC_CSHARP_SUPPORT_SYSTEM_MEMORY + + + + + + @@ -81,7 +95,11 @@ - + + + + + diff --git a/src/csharp/Grpc.Core/GrpcEnvironment.cs b/src/csharp/Grpc.Core/GrpcEnvironment.cs index 6ca694e0e46..3c83b03cc1f 100644 --- a/src/csharp/Grpc.Core/GrpcEnvironment.cs +++ b/src/csharp/Grpc.Core/GrpcEnvironment.cs @@ -448,7 +448,7 @@ namespace Grpc.Core // the gRPC channels and servers before the application exits. The following // hooks provide some extra handling for cases when this is not the case, // in the effort to achieve a reasonable behavior on shutdown. -#if NETSTANDARD1_5 +#if NETSTANDARD1_5 || NETSTANDARD2_0 // No action required at shutdown on .NET Core // - In-progress P/Invoke calls (such as grpc_completion_queue_next) don't seem // to prevent a .NET core application from terminating, so no special handling diff --git a/src/csharp/Grpc.Core/Interceptors/ServerServiceDefinitionExtensions.cs b/src/csharp/Grpc.Core/Interceptors/ServerServiceDefinitionExtensions.cs index 8987544f7f4..321cf080faa 100644 --- a/src/csharp/Grpc.Core/Interceptors/ServerServiceDefinitionExtensions.cs +++ b/src/csharp/Grpc.Core/Interceptors/ServerServiceDefinitionExtensions.cs @@ -44,7 +44,10 @@ namespace Grpc.Core.Interceptors { GrpcPreconditions.CheckNotNull(serverServiceDefinition, nameof(serverServiceDefinition)); GrpcPreconditions.CheckNotNull(interceptor, nameof(interceptor)); - return new ServerServiceDefinition(serverServiceDefinition.CallHandlers.ToDictionary(x => x.Key, x => x.Value.Intercept(interceptor))); + + var binder = new InterceptingServiceBinder(interceptor); + serverServiceDefinition.BindService(binder); + return binder.GetInterceptedServerServiceDefinition(); } /// @@ -75,5 +78,52 @@ namespace Grpc.Core.Interceptors return serverServiceDefinition; } + + /// + /// Helper for creating ServerServiceDefinition with intercepted handlers. + /// + private class InterceptingServiceBinder : ServiceBinderBase + { + readonly ServerServiceDefinition.Builder builder = ServerServiceDefinition.CreateBuilder(); + readonly Interceptor interceptor; + + public InterceptingServiceBinder(Interceptor interceptor) + { + this.interceptor = GrpcPreconditions.CheckNotNull(interceptor, nameof(interceptor)); + } + + internal ServerServiceDefinition GetInterceptedServerServiceDefinition() + { + return builder.Build(); + } + + public override void AddMethod( + Method method, + UnaryServerMethod handler) + { + builder.AddMethod(method, (request, context) => interceptor.UnaryServerHandler(request, context, handler)); + } + + public override void AddMethod( + Method method, + ClientStreamingServerMethod handler) + { + builder.AddMethod(method, (requestStream, context) => interceptor.ClientStreamingServerHandler(requestStream, context, handler)); + } + + public override void AddMethod( + Method method, + ServerStreamingServerMethod handler) + { + builder.AddMethod(method, (request, responseStream, context) => interceptor.ServerStreamingServerHandler(request, responseStream, context, handler)); + } + + public override void AddMethod( + Method method, + DuplexStreamingServerMethod handler) + { + builder.AddMethod(method, (requestStream, responseStream, context) => interceptor.DuplexStreamingServerHandler(requestStream, responseStream, context, handler)); + } + } } -} \ No newline at end of file +} diff --git a/src/csharp/Grpc.Core/Internal/AsyncCall.cs b/src/csharp/Grpc.Core/Internal/AsyncCall.cs index b6d687f71e7..a1c688140d1 100644 --- a/src/csharp/Grpc.Core/Internal/AsyncCall.cs +++ b/src/csharp/Grpc.Core/Internal/AsyncCall.cs @@ -111,7 +111,7 @@ namespace Grpc.Core.Internal { using (profiler.NewScope("AsyncCall.UnaryCall.HandleBatch")) { - HandleUnaryResponse(success, ctx.GetReceivedStatusOnClient(), ctx.GetReceivedMessage(), ctx.GetReceivedInitialMetadata()); + HandleUnaryResponse(success, ctx.GetReceivedStatusOnClient(), ctx.GetReceivedMessageReader(), ctx.GetReceivedInitialMetadata()); } } catch (Exception e) @@ -494,13 +494,13 @@ namespace Grpc.Core.Internal return injectedNativeCall; // allows injecting a mock INativeCall in tests. } - var parentCall = details.Options.PropagationToken != null ? details.Options.PropagationToken.ParentCall : CallSafeHandle.NullInstance; + var parentCall = details.Options.PropagationToken.AsImplOrNull()?.ParentCall ?? CallSafeHandle.NullInstance; var credentials = details.Options.Credentials; using (var nativeCredentials = credentials != null ? credentials.ToNativeCredentials() : null) { var result = details.Channel.Handle.CreateCall( - parentCall, ContextPropagationToken.DefaultMask, cq, + parentCall, ContextPropagationTokenImpl.DefaultMask, cq, details.Method, details.Host, Timespec.FromDateTime(details.Options.Deadline.Value), nativeCredentials); return result; } @@ -537,14 +537,14 @@ namespace Grpc.Core.Internal /// /// Handler for unary response completion. /// - private void HandleUnaryResponse(bool success, ClientSideStatus receivedStatus, byte[] receivedMessage, Metadata responseHeaders) + private void HandleUnaryResponse(bool success, ClientSideStatus receivedStatus, IBufferReader receivedMessageReader, Metadata responseHeaders) { // NOTE: because this event is a result of batch containing GRPC_OP_RECV_STATUS_ON_CLIENT, // success will be always set to true. TaskCompletionSource delayedStreamingWriteTcs = null; TResponse msg = default(TResponse); - var deserializeException = TryDeserialize(receivedMessage, out msg); + var deserializeException = TryDeserialize(receivedMessageReader, out msg); bool releasedResources; lock (myLock) @@ -634,9 +634,9 @@ namespace Grpc.Core.Internal IUnaryResponseClientCallback UnaryResponseClientCallback => this; - void IUnaryResponseClientCallback.OnUnaryResponseClient(bool success, ClientSideStatus receivedStatus, byte[] receivedMessage, Metadata responseHeaders) + void IUnaryResponseClientCallback.OnUnaryResponseClient(bool success, ClientSideStatus receivedStatus, IBufferReader receivedMessageReader, Metadata responseHeaders) { - HandleUnaryResponse(success, receivedStatus, receivedMessage, responseHeaders); + HandleUnaryResponse(success, receivedStatus, receivedMessageReader, responseHeaders); } IReceivedStatusOnClientCallback ReceivedStatusOnClientCallback => this; diff --git a/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs b/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs index 39c9f7c6160..0b99aaf3e21 100644 --- a/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs +++ b/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs @@ -228,12 +228,12 @@ namespace Grpc.Core.Internal } } - protected Exception TryDeserialize(byte[] payload, out TRead msg) + protected Exception TryDeserialize(IBufferReader reader, out TRead msg) { DefaultDeserializationContext context = null; try { - context = DefaultDeserializationContext.GetInitializedThreadLocal(payload); + context = DefaultDeserializationContext.GetInitializedThreadLocal(reader); msg = deserializer(context); return null; } @@ -245,7 +245,6 @@ namespace Grpc.Core.Internal finally { context?.Reset(); - } } @@ -333,21 +332,21 @@ namespace Grpc.Core.Internal /// /// Handles streaming read completion. /// - protected void HandleReadFinished(bool success, byte[] receivedMessage) + protected void HandleReadFinished(bool success, IBufferReader receivedMessageReader) { - // if success == false, received message will be null. It that case we will + // if success == false, the message reader will report null payload. It that case we will // treat this completion as the last read an rely on C core to handle the failed // read (e.g. deliver approriate statusCode on the clientside). TRead msg = default(TRead); - var deserializeException = (success && receivedMessage != null) ? TryDeserialize(receivedMessage, out msg) : null; + var deserializeException = (success && receivedMessageReader.TotalLength.HasValue) ? TryDeserialize(receivedMessageReader, out msg) : null; TaskCompletionSource origTcs = null; bool releasedResources; lock (myLock) { origTcs = streamingReadTcs; - if (receivedMessage == null) + if (!receivedMessageReader.TotalLength.HasValue) { // This was the last read. readingDone = true; @@ -391,9 +390,9 @@ namespace Grpc.Core.Internal IReceivedMessageCallback ReceivedMessageCallback => this; - void IReceivedMessageCallback.OnReceivedMessage(bool success, byte[] receivedMessage) + void IReceivedMessageCallback.OnReceivedMessage(bool success, IBufferReader receivedMessageReader) { - HandleReadFinished(success, receivedMessage); + HandleReadFinished(success, receivedMessageReader); } } } diff --git a/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs b/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs index 085e7faf595..50a626842dd 100644 --- a/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs +++ b/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs @@ -30,10 +30,17 @@ namespace Grpc.Core.Internal void OnComplete(bool success); } + internal interface IBufferReader + { + int? TotalLength { get; } + + bool TryGetNextSlice(out Slice slice); + } + /// /// grpcsharp_batch_context /// - internal class BatchContextSafeHandle : SafeHandleZeroIsInvalid, IOpCompletionCallback, IPooledObject + internal class BatchContextSafeHandle : SafeHandleZeroIsInvalid, IOpCompletionCallback, IPooledObject, IBufferReader { static readonly NativeMethods Native = NativeMethods.Get(); static readonly ILogger Logger = GrpcEnvironment.Logger.ForType(); @@ -93,17 +100,9 @@ namespace Grpc.Core.Internal return new ClientSideStatus(status, metadata); } - // Gets data of recv_message completion. - public byte[] GetReceivedMessage() + public IBufferReader GetReceivedMessageReader() { - IntPtr len = Native.grpcsharp_batch_context_recv_message_length(this); - if (len == new IntPtr(-1)) - { - return null; - } - byte[] data = new byte[(int)len]; - Native.grpcsharp_batch_context_recv_message_to_buffer(this, data, new UIntPtr((ulong)data.Length)); - return data; + return this; } // Gets data of receive_close_on_server completion. @@ -153,6 +152,29 @@ namespace Grpc.Core.Internal } } + int? IBufferReader.TotalLength + { + get + { + var len = Native.grpcsharp_batch_context_recv_message_length(this); + return len != new IntPtr(-1) ? (int?) len : null; + } + } + + bool IBufferReader.TryGetNextSlice(out Slice slice) + { + UIntPtr sliceLen; + IntPtr sliceDataPtr; + + if (0 == Native.grpcsharp_batch_context_recv_message_next_slice_peek(this, out sliceLen, out sliceDataPtr)) + { + slice = default(Slice); + return false; + } + slice = new Slice(sliceDataPtr, (int) sliceLen); + return true; + } + struct CompletionCallbackData { public CompletionCallbackData(BatchCompletionDelegate callback, object state) diff --git a/src/csharp/Grpc.Core/Internal/CallOptionsExtensions.cs b/src/csharp/Grpc.Core/Internal/CallOptionsExtensions.cs new file mode 100644 index 00000000000..b58b041297f --- /dev/null +++ b/src/csharp/Grpc.Core/Internal/CallOptionsExtensions.cs @@ -0,0 +1,57 @@ +#region Copyright notice and license + +// Copyright 2019 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. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#endregion + +using System; +using Grpc.Core.Utils; + +namespace Grpc.Core.Internal +{ + internal static class CallOptionsExtensions + { + /// + /// Returns a new instance of with + /// all previously unset values set to their defaults and deadline and cancellation + /// token propagated when appropriate. + /// + internal static CallOptions Normalize(this CallOptions options) + { + var newOptions = options; + // silently ignore the context propagation token if it wasn't produced by "us" + var propagationTokenImpl = options.PropagationToken.AsImplOrNull(); + if (propagationTokenImpl != null) + { + if (propagationTokenImpl.Options.IsPropagateDeadline) + { + GrpcPreconditions.CheckArgument(!newOptions.Deadline.HasValue, + "Cannot propagate deadline from parent call. The deadline has already been set explicitly."); + newOptions = newOptions.WithDeadline(propagationTokenImpl.ParentDeadline); + } + if (propagationTokenImpl.Options.IsPropagateCancellation) + { + GrpcPreconditions.CheckArgument(!newOptions.CancellationToken.CanBeCanceled, + "Cannot propagate cancellation token from parent call. The cancellation token has already been set to a non-default value."); + newOptions = newOptions.WithCancellationToken(propagationTokenImpl.ParentCancellationToken); + } + } + + newOptions = newOptions.WithHeaders(newOptions.Headers ?? Metadata.Empty); + newOptions = newOptions.WithDeadline(newOptions.Deadline ?? DateTime.MaxValue); + return newOptions; + } + } +} diff --git a/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs b/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs index a3ef3e61ee1..858d2a69605 100644 --- a/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs +++ b/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs @@ -35,11 +35,11 @@ namespace Grpc.Core.Internal // Completion handlers are pre-allocated to avoid unneccessary delegate allocations. // The "state" field is used to store the actual callback to invoke. static readonly BatchCompletionDelegate CompletionHandler_IUnaryResponseClientCallback = - (success, context, state) => ((IUnaryResponseClientCallback)state).OnUnaryResponseClient(success, context.GetReceivedStatusOnClient(), context.GetReceivedMessage(), context.GetReceivedInitialMetadata()); + (success, context, state) => ((IUnaryResponseClientCallback)state).OnUnaryResponseClient(success, context.GetReceivedStatusOnClient(), context.GetReceivedMessageReader(), context.GetReceivedInitialMetadata()); static readonly BatchCompletionDelegate CompletionHandler_IReceivedStatusOnClientCallback = (success, context, state) => ((IReceivedStatusOnClientCallback)state).OnReceivedStatusOnClient(success, context.GetReceivedStatusOnClient()); static readonly BatchCompletionDelegate CompletionHandler_IReceivedMessageCallback = - (success, context, state) => ((IReceivedMessageCallback)state).OnReceivedMessage(success, context.GetReceivedMessage()); + (success, context, state) => ((IReceivedMessageCallback)state).OnReceivedMessage(success, context.GetReceivedMessageReader()); static readonly BatchCompletionDelegate CompletionHandler_IReceivedResponseHeadersCallback = (success, context, state) => ((IReceivedResponseHeadersCallback)state).OnReceivedResponseHeaders(success, context.GetReceivedInitialMetadata()); static readonly BatchCompletionDelegate CompletionHandler_ISendCompletionCallback = diff --git a/src/csharp/Grpc.Core/Internal/ChannelCredentialsSafeHandle.cs b/src/csharp/Grpc.Core/Internal/ChannelCredentialsSafeHandle.cs index 11b5d2cc3f6..d4f50344b23 100644 --- a/src/csharp/Grpc.Core/Internal/ChannelCredentialsSafeHandle.cs +++ b/src/csharp/Grpc.Core/Internal/ChannelCredentialsSafeHandle.cs @@ -38,15 +38,15 @@ namespace Grpc.Core.Internal return creds; } - public static ChannelCredentialsSafeHandle CreateSslCredentials(string pemRootCerts, KeyCertificatePair keyCertPair) + public static ChannelCredentialsSafeHandle CreateSslCredentials(string pemRootCerts, KeyCertificatePair keyCertPair, IntPtr verifyPeerCallbackTag) { if (keyCertPair != null) { - return Native.grpcsharp_ssl_credentials_create(pemRootCerts, keyCertPair.CertificateChain, keyCertPair.PrivateKey); + return Native.grpcsharp_ssl_credentials_create(pemRootCerts, keyCertPair.CertificateChain, keyCertPair.PrivateKey, verifyPeerCallbackTag); } else { - return Native.grpcsharp_ssl_credentials_create(pemRootCerts, null, null); + return Native.grpcsharp_ssl_credentials_create(pemRootCerts, null, null, verifyPeerCallbackTag); } } diff --git a/src/csharp/Grpc.Core/Internal/ContextPropagationFlags.cs b/src/csharp/Grpc.Core/Internal/ContextPropagationFlags.cs new file mode 100644 index 00000000000..11a9c93a67d --- /dev/null +++ b/src/csharp/Grpc.Core/Internal/ContextPropagationFlags.cs @@ -0,0 +1,34 @@ +#region Copyright notice and license + +// Copyright 2019 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. +// 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; + +namespace Grpc.Core.Internal +{ + /// + /// Context propagation flags from grpc/grpc.h. + /// + [Flags] + internal enum ContextPropagationFlags + { + Deadline = 1, + CensusStatsContext = 2, + CensusTracingContext = 4, + Cancellation = 8 + } +} diff --git a/src/csharp/Grpc.Core/ContextPropagationToken.cs b/src/csharp/Grpc.Core/Internal/ContextPropagationTokenImpl.cs similarity index 51% rename from src/csharp/Grpc.Core/ContextPropagationToken.cs rename to src/csharp/Grpc.Core/Internal/ContextPropagationTokenImpl.cs index fe5c8a5c99a..e2528e84cff 100644 --- a/src/csharp/Grpc.Core/ContextPropagationToken.cs +++ b/src/csharp/Grpc.Core/Internal/ContextPropagationTokenImpl.cs @@ -1,6 +1,6 @@ #region Copyright notice and license -// Copyright 2015 gRPC authors. +// Copyright 2019 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. @@ -19,20 +19,18 @@ using System; using System.Threading; -using Grpc.Core.Internal; using Grpc.Core.Utils; -namespace Grpc.Core +namespace Grpc.Core.Internal { /// - /// Token for propagating context of server side handlers to child calls. - /// In situations when a backend is making calls to another backend, - /// it makes sense to propagate properties like deadline and cancellation - /// token of the server call to the child call. - /// The gRPC native layer provides some other contexts (like tracing context) that - /// are not accessible to explicitly C# layer, but this token still allows propagating them. + /// Implementation of ContextPropagationToken that carries + /// all fields needed for context propagation by C-core based implementation of gRPC. + /// Instances of ContextPropagationToken that are not of this + /// type will be recognized as "foreign" and will be silently ignored + /// (treated as if null). /// - public class ContextPropagationToken + internal class ContextPropagationTokenImpl : ContextPropagationToken { /// /// Default propagation mask used by C core. @@ -41,7 +39,8 @@ namespace Grpc.Core /// /// Default propagation mask used by C# - we want to propagate deadline - /// and cancellation token by our own means. + /// and cancellation token by our own means, everything else will be propagated + /// by C core automatically (according to DefaultCoreMask). /// internal const ContextPropagationFlags DefaultMask = DefaultCoreMask & ~ContextPropagationFlags.Deadline & ~ContextPropagationFlags.Cancellation; @@ -51,7 +50,7 @@ namespace Grpc.Core readonly CancellationToken cancellationToken; readonly ContextPropagationOptions options; - internal ContextPropagationToken(CallSafeHandle parentCall, DateTime deadline, CancellationToken cancellationToken, ContextPropagationOptions options) + internal ContextPropagationTokenImpl(CallSafeHandle parentCall, DateTime deadline, CancellationToken cancellationToken, ContextPropagationOptions options) { this.parentCall = GrpcPreconditions.CheckNotNull(parentCall); this.deadline = deadline; @@ -104,52 +103,17 @@ namespace Grpc.Core } } - /// - /// Options for . - /// - public class ContextPropagationOptions + internal static class ContextPropagationTokenExtensions { /// - /// The context propagation options that will be used by default. + /// Converts given ContextPropagationToken to ContextPropagationTokenImpl + /// if possible or returns null. + /// Being able to convert means that the context propagation token is recognized as + /// "ours" (was created by this implementation). /// - public static readonly ContextPropagationOptions Default = new ContextPropagationOptions(); - - bool propagateDeadline; - bool propagateCancellation; - - /// - /// Creates new context propagation options. - /// - /// If set to true parent call's deadline will be propagated to the child call. - /// If set to true parent call's cancellation token will be propagated to the child call. - public ContextPropagationOptions(bool propagateDeadline = true, bool propagateCancellation = true) + public static ContextPropagationTokenImpl AsImplOrNull(this ContextPropagationToken instanceOrNull) { - this.propagateDeadline = propagateDeadline; - this.propagateCancellation = propagateCancellation; + return instanceOrNull as ContextPropagationTokenImpl; } - - /// true if parent call's deadline should be propagated to the child call. - public bool IsPropagateDeadline - { - get { return this.propagateDeadline; } - } - - /// true if parent call's cancellation token should be propagated to the child call. - public bool IsPropagateCancellation - { - get { return this.propagateCancellation; } - } - } - - /// - /// Context propagation flags from grpc/grpc.h. - /// - [Flags] - internal enum ContextPropagationFlags - { - Deadline = 1, - CensusStatsContext = 2, - CensusTracingContext = 4, - Cancellation = 8 } } diff --git a/src/csharp/Grpc.Core/Internal/DefaultCallCredentialsConfigurator.cs b/src/csharp/Grpc.Core/Internal/DefaultCallCredentialsConfigurator.cs new file mode 100644 index 00000000000..a2c53a173c5 --- /dev/null +++ b/src/csharp/Grpc.Core/Internal/DefaultCallCredentialsConfigurator.cs @@ -0,0 +1,85 @@ +#region Copyright notice and license + +// Copyright 2019 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. +// 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.Collections.Generic; +using Grpc.Core.Utils; + +namespace Grpc.Core.Internal +{ + /// + /// Creates native call credential objects from instances of CallCredentials. + /// + internal class DefaultCallCredentialsConfigurator : CallCredentialsConfiguratorBase + { + CallCredentialsSafeHandle nativeCredentials; + + public CallCredentialsSafeHandle NativeCredentials => nativeCredentials; + + public override void SetAsyncAuthInterceptorCredentials(object state, AsyncAuthInterceptor interceptor) + { + GrpcPreconditions.CheckState(nativeCredentials == null); + + var plugin = new NativeMetadataCredentialsPlugin(interceptor); + nativeCredentials = plugin.Credentials; + } + + public override void SetCompositeCredentials(object state, IReadOnlyList credentials) + { + GrpcPreconditions.CheckState(nativeCredentials == null); + + GrpcPreconditions.CheckArgument(credentials.Count >= 2); + nativeCredentials = CompositeToNativeRecursive(credentials, 0); + } + + // Recursive descent makes managing lifetime of intermediate CredentialSafeHandle instances easier. + // In practice, we won't usually see composites from more than two credentials anyway. + private CallCredentialsSafeHandle CompositeToNativeRecursive(IReadOnlyList credentials, int startIndex) + { + if (startIndex == credentials.Count - 1) + { + return credentials[startIndex].ToNativeCredentials(); + } + + using (var cred1 = credentials[startIndex].ToNativeCredentials()) + using (var cred2 = CompositeToNativeRecursive(credentials, startIndex + 1)) + { + var nativeComposite = CallCredentialsSafeHandle.CreateComposite(cred1, cred2); + if (nativeComposite.IsInvalid) + { + throw new ArgumentException("Error creating native composite credentials. Likely, this is because you are trying to compose incompatible credentials."); + } + return nativeComposite; + } + } + } + + internal static class CallCredentialsExtensions + { + /// + /// Creates native object for the credentials. + /// + /// The native credentials. + public static CallCredentialsSafeHandle ToNativeCredentials(this CallCredentials credentials) + { + var configurator = new DefaultCallCredentialsConfigurator(); + credentials.InternalPopulateConfiguration(configurator, credentials); + return configurator.NativeCredentials; + } + } +} diff --git a/src/csharp/Grpc.Core/Internal/DefaultDeserializationContext.cs b/src/csharp/Grpc.Core/Internal/DefaultDeserializationContext.cs index 7ace80e8d53..946c37de190 100644 --- a/src/csharp/Grpc.Core/Internal/DefaultDeserializationContext.cs +++ b/src/csharp/Grpc.Core/Internal/DefaultDeserializationContext.cs @@ -20,6 +20,10 @@ using Grpc.Core.Utils; using System; using System.Threading; +#if GRPC_CSHARP_SUPPORT_SYSTEM_MEMORY +using System.Buffers; +#endif + namespace Grpc.Core.Internal { internal class DefaultDeserializationContext : DeserializationContext @@ -27,40 +31,71 @@ namespace Grpc.Core.Internal static readonly ThreadLocal threadLocalInstance = new ThreadLocal(() => new DefaultDeserializationContext(), false); - byte[] payload; - bool alreadyCalledPayloadAsNewBuffer; + IBufferReader bufferReader; + int payloadLength; +#if GRPC_CSHARP_SUPPORT_SYSTEM_MEMORY + ReusableSliceBuffer cachedSliceBuffer = new ReusableSliceBuffer(); +#endif public DefaultDeserializationContext() { Reset(); } - public override int PayloadLength => payload.Length; + public override int PayloadLength => payloadLength; public override byte[] PayloadAsNewBuffer() { - GrpcPreconditions.CheckState(!alreadyCalledPayloadAsNewBuffer); - alreadyCalledPayloadAsNewBuffer = true; - return payload; + var buffer = new byte[payloadLength]; + FillContinguousBuffer(bufferReader, buffer); + return buffer; } - public void Initialize(byte[] payload) +#if GRPC_CSHARP_SUPPORT_SYSTEM_MEMORY + public override ReadOnlySequence PayloadAsReadOnlySequence() { - this.payload = GrpcPreconditions.CheckNotNull(payload); - this.alreadyCalledPayloadAsNewBuffer = false; + var sequence = cachedSliceBuffer.PopulateFrom(bufferReader); + GrpcPreconditions.CheckState(sequence.Length == payloadLength); + return sequence; + } +#endif + + public void Initialize(IBufferReader bufferReader) + { + this.bufferReader = GrpcPreconditions.CheckNotNull(bufferReader); + this.payloadLength = bufferReader.TotalLength.Value; // payload must not be null } public void Reset() { - this.payload = null; - this.alreadyCalledPayloadAsNewBuffer = true; // mark payload as read + this.bufferReader = null; + this.payloadLength = 0; +#if GRPC_CSHARP_SUPPORT_SYSTEM_MEMORY + this.cachedSliceBuffer.Invalidate(); +#endif } - public static DefaultDeserializationContext GetInitializedThreadLocal(byte[] payload) + public static DefaultDeserializationContext GetInitializedThreadLocal(IBufferReader bufferReader) { var instance = threadLocalInstance.Value; - instance.Initialize(payload); + instance.Initialize(bufferReader); return instance; } + + private void FillContinguousBuffer(IBufferReader reader, byte[] destination) + { +#if GRPC_CSHARP_SUPPORT_SYSTEM_MEMORY + PayloadAsReadOnlySequence().CopyTo(new Span(destination)); +#else + int offset = 0; + while (reader.TryGetNextSlice(out Slice slice)) + { + slice.CopyTo(new ArraySegment(destination, offset, (int)slice.Length)); + offset += (int)slice.Length; + } + // check that we filled the entire destination + GrpcPreconditions.CheckState(offset == payloadLength); +#endif + } } } diff --git a/src/csharp/Grpc.Core/Internal/DefaultServerCallContext.cs b/src/csharp/Grpc.Core/Internal/DefaultServerCallContext.cs new file mode 100644 index 00000000000..b33cb631e26 --- /dev/null +++ b/src/csharp/Grpc.Core/Internal/DefaultServerCallContext.cs @@ -0,0 +1,110 @@ +#region Copyright notice and license + +// Copyright 2019 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. +// 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.Internal; + +namespace Grpc.Core +{ + /// + /// Default implementation of ServerCallContext. + /// + internal class DefaultServerCallContext : ServerCallContext + { + private readonly CallSafeHandle callHandle; + private readonly string method; + private readonly string host; + private readonly DateTime deadline; + private readonly Metadata requestHeaders; + private readonly CancellationToken cancellationToken; + private readonly Metadata responseTrailers; + private Status status; + private readonly IServerResponseStream serverResponseStream; + private readonly Lazy authContext; + + /// + /// Creates a new instance of ServerCallContext. + /// To allow reuse of ServerCallContext API by different gRPC implementations, the implementation of some members is provided externally. + /// To provide state, this ServerCallContext instance and extraData will be passed to the member implementations. + /// + internal DefaultServerCallContext(CallSafeHandle callHandle, string method, string host, DateTime deadline, + Metadata requestHeaders, CancellationToken cancellationToken, IServerResponseStream serverResponseStream) + { + this.callHandle = callHandle; + this.method = method; + this.host = host; + this.deadline = deadline; + this.requestHeaders = requestHeaders; + this.cancellationToken = cancellationToken; + this.responseTrailers = new Metadata(); + this.status = Status.DefaultSuccess; + this.serverResponseStream = serverResponseStream; + // TODO(jtattermusch): avoid unnecessary allocation of factory function and the lazy object + this.authContext = new Lazy(GetAuthContextEager); + } + + protected override ContextPropagationToken CreatePropagationTokenCore(ContextPropagationOptions options) + { + return new ContextPropagationTokenImpl(callHandle, deadline, cancellationToken, options); + } + + protected override Task WriteResponseHeadersAsyncCore(Metadata responseHeaders) + { + return serverResponseStream.WriteResponseHeadersAsync(responseHeaders); + } + + protected override string MethodCore => method; + + protected override string HostCore => host; + + protected override string PeerCore => callHandle.GetPeer(); + + protected override DateTime DeadlineCore => deadline; + + protected override Metadata RequestHeadersCore => requestHeaders; + + protected override CancellationToken CancellationTokenCore => cancellationToken; + + protected override Metadata ResponseTrailersCore => responseTrailers; + + protected override Status StatusCore + { + get => status; + set => status = value; + } + + protected override WriteOptions WriteOptionsCore + { + get => serverResponseStream.WriteOptions; + set => serverResponseStream.WriteOptions = value; + } + + protected override AuthContext AuthContextCore => authContext.Value; + + private AuthContext GetAuthContextEager() + { + using (var authContextNative = callHandle.GetAuthContext()) + { + return authContextNative.ToAuthContext(); + } + } + } +} diff --git a/src/csharp/Grpc.Core/Internal/INativeCall.cs b/src/csharp/Grpc.Core/Internal/INativeCall.cs index 5c35b2ba461..98117c6988a 100644 --- a/src/csharp/Grpc.Core/Internal/INativeCall.cs +++ b/src/csharp/Grpc.Core/Internal/INativeCall.cs @@ -22,7 +22,7 @@ namespace Grpc.Core.Internal { internal interface IUnaryResponseClientCallback { - void OnUnaryResponseClient(bool success, ClientSideStatus receivedStatus, byte[] receivedMessage, Metadata responseHeaders); + void OnUnaryResponseClient(bool success, ClientSideStatus receivedStatus, IBufferReader receivedMessageReader, Metadata responseHeaders); } // Received status for streaming response calls. @@ -33,7 +33,7 @@ namespace Grpc.Core.Internal internal interface IReceivedMessageCallback { - void OnReceivedMessage(bool success, byte[] receivedMessage); + void OnReceivedMessage(bool success, IBufferReader receivedMessageReader); } internal interface IReceivedResponseHeadersCallback diff --git a/src/csharp/Grpc.Core/Internal/IServerResponseStream.cs b/src/csharp/Grpc.Core/Internal/IServerResponseStream.cs new file mode 100644 index 00000000000..874aae703a2 --- /dev/null +++ b/src/csharp/Grpc.Core/Internal/IServerResponseStream.cs @@ -0,0 +1,38 @@ +#region Copyright notice and license +// Copyright 2019 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. +// 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.Tasks; +using Grpc.Core.Internal; + +namespace Grpc.Core.Internal +{ + /// + /// Exposes non-generic members of ServerReponseStream. + /// + internal interface IServerResponseStream + { + /// + /// Asynchronously sends response headers for the current call to the client. See ServerCallContext.WriteResponseHeadersAsync for exact semantics. + /// + Task WriteResponseHeadersAsync(Metadata responseHeaders); + + /// + /// Gets or sets the write options. + /// + WriteOptions WriteOptions { get; set; } + } +} diff --git a/src/csharp/Grpc.Core/Internal/MarshalUtils.cs b/src/csharp/Grpc.Core/Internal/MarshalUtils.cs index 09ded1a0363..e3e41617955 100644 --- a/src/csharp/Grpc.Core/Internal/MarshalUtils.cs +++ b/src/csharp/Grpc.Core/Internal/MarshalUtils.cs @@ -28,7 +28,6 @@ namespace Grpc.Core.Internal internal static class MarshalUtils { static readonly Encoding EncodingUTF8 = System.Text.Encoding.UTF8; - static readonly Encoding EncodingASCII = System.Text.Encoding.ASCII; /// /// Converts IntPtr pointing to a UTF-8 encoded byte array to string. @@ -62,21 +61,5 @@ namespace Grpc.Core.Internal { return EncodingUTF8.GetString(bytes); } - - /// - /// Returns byte array containing ASCII encoding of given string. - /// - public static byte[] GetBytesASCII(string str) - { - return EncodingASCII.GetBytes(str); - } - - /// - /// Get string from an ASCII encoded byte array. - /// - public static string GetStringASCII(byte[] bytes) - { - return EncodingASCII.GetString(bytes); - } } } diff --git a/src/csharp/Grpc.Core/Internal/MonoPInvokeCallbackAttribute.cs b/src/csharp/Grpc.Core/Internal/MonoPInvokeCallbackAttribute.cs new file mode 100644 index 00000000000..64eb386a3c5 --- /dev/null +++ b/src/csharp/Grpc.Core/Internal/MonoPInvokeCallbackAttribute.cs @@ -0,0 +1,40 @@ +#region Copyright notice and license + +// Copyright 2019 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. +// 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; + +namespace Grpc.Core.Internal +{ + /// + /// Use this attribute to mark methods that will be called back from P/Invoke calls. + /// iOS (and probably other AOT platforms) needs to have delegates registered. + /// Instead of depending on Xamarin.iOS for this, we can just create our own, + /// the iOS runtime just checks for the type name. + /// See: https://docs.microsoft.com/en-gb/xamarin/ios/internals/limitations#reverse-callbacks + /// + [AttributeUsage(AttributeTargets.Method)] + internal sealed class MonoPInvokeCallbackAttribute : Attribute + { + public MonoPInvokeCallbackAttribute(Type type) + { + Type = type; + } + + public Type Type { get; private set; } + } +} diff --git a/src/csharp/Grpc.Core/Internal/NativeCallbackDispatcher.cs b/src/csharp/Grpc.Core/Internal/NativeCallbackDispatcher.cs new file mode 100644 index 00000000000..0777d7933e6 --- /dev/null +++ b/src/csharp/Grpc.Core/Internal/NativeCallbackDispatcher.cs @@ -0,0 +1,91 @@ +#region Copyright notice and license + +// Copyright 2019 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. +// 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.Collections.Concurrent; +using System.Diagnostics; +using System.IO; +using System.Runtime.InteropServices; +using System.Threading; +using System.Collections.Generic; +using Grpc.Core.Logging; +using Grpc.Core.Utils; + +namespace Grpc.Core.Internal +{ + internal delegate int UniversalNativeCallback(IntPtr arg0, IntPtr arg1, IntPtr arg2, IntPtr arg3, IntPtr arg4, IntPtr arg5); + + internal delegate int NativeCallbackDispatcherCallback(IntPtr tag, IntPtr arg0, IntPtr arg1, IntPtr arg2, IntPtr arg3, IntPtr arg4, IntPtr arg5); + + internal class NativeCallbackDispatcher + { + static readonly ILogger Logger = GrpcEnvironment.Logger.ForType(); + + static NativeCallbackDispatcherCallback dispatcherCallback; + + public static void Init(NativeMethods native) + { + GrpcPreconditions.CheckState(dispatcherCallback == null); + dispatcherCallback = new NativeCallbackDispatcherCallback(HandleDispatcherCallback); + native.grpcsharp_native_callback_dispatcher_init(dispatcherCallback); + } + + public static NativeCallbackRegistration RegisterCallback(UniversalNativeCallback callback) + { + var gcHandle = GCHandle.Alloc(callback); + return new NativeCallbackRegistration(gcHandle); + } + + [MonoPInvokeCallback(typeof(NativeCallbackDispatcherCallback))] + private static int HandleDispatcherCallback(IntPtr tag, IntPtr arg0, IntPtr arg1, IntPtr arg2, IntPtr arg3, IntPtr arg4, IntPtr arg5) + { + try + { + var gcHandle = GCHandle.FromIntPtr(tag); + var callback = (UniversalNativeCallback) gcHandle.Target; + return callback(arg0, arg1, arg2, arg3, arg4, arg5); + } + catch (Exception e) + { + // eat the exception, we must not throw when inside callback from native code. + Logger.Error(e, "Caught exception inside callback from native code."); + return 0; + } + } + } + + internal class NativeCallbackRegistration : IDisposable + { + readonly GCHandle handle; + + public NativeCallbackRegistration(GCHandle handle) + { + this.handle = handle; + } + + public IntPtr Tag => GCHandle.ToIntPtr(handle); + + public void Dispose() + { + if (handle.IsAllocated) + { + handle.Free(); + } + } + } +} diff --git a/src/csharp/Grpc.Core/Internal/NativeExtension.cs b/src/csharp/Grpc.Core/Internal/NativeExtension.cs index f526b913af0..945650371fe 100644 --- a/src/csharp/Grpc.Core/Internal/NativeExtension.cs +++ b/src/csharp/Grpc.Core/Internal/NativeExtension.cs @@ -43,6 +43,9 @@ namespace Grpc.Core.Internal // to make sure we don't lose any logs. NativeLogRedirector.Redirect(this.nativeMethods); + // Initialize + NativeCallbackDispatcher.Init(this.nativeMethods); + DefaultSslRootsOverride.Override(this.nativeMethods); Logger.Debug("gRPC native library loaded successfully."); @@ -83,13 +86,13 @@ namespace Grpc.Core.Internal // See https://github.com/grpc/grpc/pull/7303 for one option. var assemblyDirectory = Path.GetDirectoryName(GetAssemblyPath()); - // With old-style VS projects, the native libraries get copied using a .targets rule to the build output folder + // With "classic" VS projects, the native libraries get copied using a .targets rule to the build output folder // alongside the compiled assembly. // With dotnet cli projects targeting net45 framework, the native libraries (just the required ones) // are similarly copied to the built output folder, through the magic of Microsoft.NETCore.Platforms. var classicPath = Path.Combine(assemblyDirectory, GetNativeLibraryFilename()); - // With dotnet cli project targeting netcoreapp1.0, projects will use Grpc.Core assembly directly in the location where it got restored + // With dotnet cli project targeting netcoreappX.Y, projects will use Grpc.Core assembly directly in the location where it got restored // by nuget. We locate the native libraries based on known structure of Grpc.Core nuget package. // When "dotnet publish" is used, the runtimes directory is copied next to the published assemblies. string runtimesDirectory = string.Format("runtimes/{0}/native", GetPlatformString()); @@ -153,7 +156,7 @@ namespace Grpc.Core.Internal private static string GetAssemblyPath() { var assembly = typeof(NativeExtension).GetTypeInfo().Assembly; -#if NETSTANDARD1_5 +#if NETSTANDARD1_5 || NETSTANDARD2_0 // Assembly.EscapedCodeBase does not exist under CoreCLR, but assemblies imported from a nuget package // don't seem to be shadowed by DNX-based projects at all. return assembly.Location; @@ -172,7 +175,7 @@ namespace Grpc.Core.Internal #endif } -#if !NETSTANDARD1_5 +#if !NETSTANDARD1_5 && !NETSTANDARD2_0 private static bool IsFileUri(string uri) { return uri.ToLowerInvariant().StartsWith(Uri.UriSchemeFile); diff --git a/src/csharp/Grpc.Core/Internal/NativeLogRedirector.cs b/src/csharp/Grpc.Core/Internal/NativeLogRedirector.cs index 30264acb10b..062c0101b91 100644 --- a/src/csharp/Grpc.Core/Internal/NativeLogRedirector.cs +++ b/src/csharp/Grpc.Core/Internal/NativeLogRedirector.cs @@ -87,22 +87,4 @@ namespace Grpc.Core.Internal } } } - - /// - /// Use this attribute to mark methods that will be called back from P/Invoke calls. - /// iOS (and probably other AOT platforms) needs to have delegates registered. - /// Instead of depending on Xamarin.iOS for this, we can just create our own, - /// the iOS runtime just checks for the type name. - /// See: https://docs.microsoft.com/en-gb/xamarin/ios/internals/limitations#reverse-callbacks - /// - [AttributeUsage(AttributeTargets.Method)] - internal sealed class MonoPInvokeCallbackAttribute : Attribute - { - public MonoPInvokeCallbackAttribute(Type type) - { - Type = type; - } - - public Type Type { get; private set; } - } } diff --git a/src/csharp/Grpc.Core/Internal/NativeMetadataCredentialsPlugin.cs b/src/csharp/Grpc.Core/Internal/NativeMetadataCredentialsPlugin.cs index faeb51e6f7a..f47988f7f76 100644 --- a/src/csharp/Grpc.Core/Internal/NativeMetadataCredentialsPlugin.cs +++ b/src/csharp/Grpc.Core/Internal/NativeMetadataCredentialsPlugin.cs @@ -23,8 +23,6 @@ using Grpc.Core.Utils; namespace Grpc.Core.Internal { - internal delegate void NativeMetadataInterceptor(IntPtr statePtr, IntPtr serviceUrlPtr, IntPtr methodNamePtr, IntPtr callbackPtr, IntPtr userDataPtr, bool isDestroy); - internal class NativeMetadataCredentialsPlugin { const string GetMetadataExceptionStatusMsg = "Exception occurred in metadata credentials plugin."; @@ -33,18 +31,14 @@ namespace Grpc.Core.Internal static readonly NativeMethods Native = NativeMethods.Get(); AsyncAuthInterceptor interceptor; - GCHandle gcHandle; - NativeMetadataInterceptor nativeInterceptor; CallCredentialsSafeHandle credentials; + NativeCallbackRegistration callbackRegistration; public NativeMetadataCredentialsPlugin(AsyncAuthInterceptor interceptor) { this.interceptor = GrpcPreconditions.CheckNotNull(interceptor, "interceptor"); - this.nativeInterceptor = NativeMetadataInterceptorHandler; - - // Make sure the callback doesn't get garbage collected until it is destroyed. - this.gcHandle = GCHandle.Alloc(this.nativeInterceptor, GCHandleType.Normal); - this.credentials = Native.grpcsharp_metadata_credentials_create_from_plugin(nativeInterceptor); + this.callbackRegistration = NativeCallbackDispatcher.RegisterCallback(HandleUniversalCallback); + this.credentials = Native.grpcsharp_metadata_credentials_create_from_plugin(this.callbackRegistration.Tag); } public CallCredentialsSafeHandle Credentials @@ -52,11 +46,17 @@ namespace Grpc.Core.Internal get { return credentials; } } - private void NativeMetadataInterceptorHandler(IntPtr statePtr, IntPtr serviceUrlPtr, IntPtr methodNamePtr, IntPtr callbackPtr, IntPtr userDataPtr, bool isDestroy) + private int HandleUniversalCallback(IntPtr arg0, IntPtr arg1, IntPtr arg2, IntPtr arg3, IntPtr arg4, IntPtr arg5) + { + NativeMetadataInterceptorHandler(arg0, arg1, arg2, arg3, arg4 != IntPtr.Zero); + return 0; + } + + private void NativeMetadataInterceptorHandler(IntPtr serviceUrlPtr, IntPtr methodNamePtr, IntPtr callbackPtr, IntPtr userDataPtr, bool isDestroy) { if (isDestroy) { - gcHandle.Free(); + this.callbackRegistration.Dispose(); return; } diff --git a/src/csharp/Grpc.Core/Internal/NativeMethods.Generated.cs b/src/csharp/Grpc.Core/Internal/NativeMethods.Generated.cs index a45cbe4107d..b8a60b31c40 100644 --- a/src/csharp/Grpc.Core/Internal/NativeMethods.Generated.cs +++ b/src/csharp/Grpc.Core/Internal/NativeMethods.Generated.cs @@ -40,7 +40,7 @@ namespace Grpc.Core.Internal public readonly Delegates.grpcsharp_batch_context_create_delegate grpcsharp_batch_context_create; public readonly Delegates.grpcsharp_batch_context_recv_initial_metadata_delegate grpcsharp_batch_context_recv_initial_metadata; public readonly Delegates.grpcsharp_batch_context_recv_message_length_delegate grpcsharp_batch_context_recv_message_length; - public readonly Delegates.grpcsharp_batch_context_recv_message_to_buffer_delegate grpcsharp_batch_context_recv_message_to_buffer; + public readonly Delegates.grpcsharp_batch_context_recv_message_next_slice_peek_delegate grpcsharp_batch_context_recv_message_next_slice_peek; public readonly Delegates.grpcsharp_batch_context_recv_status_on_client_status_delegate grpcsharp_batch_context_recv_status_on_client_status; public readonly Delegates.grpcsharp_batch_context_recv_status_on_client_details_delegate grpcsharp_batch_context_recv_status_on_client_details; public readonly Delegates.grpcsharp_batch_context_recv_status_on_client_trailing_metadata_delegate grpcsharp_batch_context_recv_status_on_client_trailing_metadata; @@ -103,6 +103,7 @@ namespace Grpc.Core.Internal public readonly Delegates.grpcsharp_metadata_array_get_value_delegate grpcsharp_metadata_array_get_value; public readonly Delegates.grpcsharp_metadata_array_destroy_full_delegate grpcsharp_metadata_array_destroy_full; public readonly Delegates.grpcsharp_redirect_log_delegate grpcsharp_redirect_log; + public readonly Delegates.grpcsharp_native_callback_dispatcher_init_delegate grpcsharp_native_callback_dispatcher_init; public readonly Delegates.grpcsharp_metadata_credentials_create_from_plugin_delegate grpcsharp_metadata_credentials_create_from_plugin; public readonly Delegates.grpcsharp_metadata_credentials_notify_from_plugin_delegate grpcsharp_metadata_credentials_notify_from_plugin; public readonly Delegates.grpcsharp_ssl_server_credentials_create_delegate grpcsharp_ssl_server_credentials_create; @@ -140,7 +141,7 @@ namespace Grpc.Core.Internal this.grpcsharp_batch_context_create = GetMethodDelegate(library); this.grpcsharp_batch_context_recv_initial_metadata = GetMethodDelegate(library); this.grpcsharp_batch_context_recv_message_length = GetMethodDelegate(library); - this.grpcsharp_batch_context_recv_message_to_buffer = GetMethodDelegate(library); + this.grpcsharp_batch_context_recv_message_next_slice_peek = GetMethodDelegate(library); this.grpcsharp_batch_context_recv_status_on_client_status = GetMethodDelegate(library); this.grpcsharp_batch_context_recv_status_on_client_details = GetMethodDelegate(library); this.grpcsharp_batch_context_recv_status_on_client_trailing_metadata = GetMethodDelegate(library); @@ -203,6 +204,7 @@ namespace Grpc.Core.Internal this.grpcsharp_metadata_array_get_value = GetMethodDelegate(library); this.grpcsharp_metadata_array_destroy_full = GetMethodDelegate(library); this.grpcsharp_redirect_log = GetMethodDelegate(library); + this.grpcsharp_native_callback_dispatcher_init = GetMethodDelegate(library); this.grpcsharp_metadata_credentials_create_from_plugin = GetMethodDelegate(library); this.grpcsharp_metadata_credentials_notify_from_plugin = GetMethodDelegate(library); this.grpcsharp_ssl_server_credentials_create = GetMethodDelegate(library); @@ -239,7 +241,7 @@ namespace Grpc.Core.Internal this.grpcsharp_batch_context_create = DllImportsFromStaticLib.grpcsharp_batch_context_create; this.grpcsharp_batch_context_recv_initial_metadata = DllImportsFromStaticLib.grpcsharp_batch_context_recv_initial_metadata; this.grpcsharp_batch_context_recv_message_length = DllImportsFromStaticLib.grpcsharp_batch_context_recv_message_length; - this.grpcsharp_batch_context_recv_message_to_buffer = DllImportsFromStaticLib.grpcsharp_batch_context_recv_message_to_buffer; + this.grpcsharp_batch_context_recv_message_next_slice_peek = DllImportsFromStaticLib.grpcsharp_batch_context_recv_message_next_slice_peek; this.grpcsharp_batch_context_recv_status_on_client_status = DllImportsFromStaticLib.grpcsharp_batch_context_recv_status_on_client_status; this.grpcsharp_batch_context_recv_status_on_client_details = DllImportsFromStaticLib.grpcsharp_batch_context_recv_status_on_client_details; this.grpcsharp_batch_context_recv_status_on_client_trailing_metadata = DllImportsFromStaticLib.grpcsharp_batch_context_recv_status_on_client_trailing_metadata; @@ -302,6 +304,7 @@ namespace Grpc.Core.Internal this.grpcsharp_metadata_array_get_value = DllImportsFromStaticLib.grpcsharp_metadata_array_get_value; this.grpcsharp_metadata_array_destroy_full = DllImportsFromStaticLib.grpcsharp_metadata_array_destroy_full; this.grpcsharp_redirect_log = DllImportsFromStaticLib.grpcsharp_redirect_log; + this.grpcsharp_native_callback_dispatcher_init = DllImportsFromStaticLib.grpcsharp_native_callback_dispatcher_init; this.grpcsharp_metadata_credentials_create_from_plugin = DllImportsFromStaticLib.grpcsharp_metadata_credentials_create_from_plugin; this.grpcsharp_metadata_credentials_notify_from_plugin = DllImportsFromStaticLib.grpcsharp_metadata_credentials_notify_from_plugin; this.grpcsharp_ssl_server_credentials_create = DllImportsFromStaticLib.grpcsharp_ssl_server_credentials_create; @@ -338,7 +341,7 @@ namespace Grpc.Core.Internal this.grpcsharp_batch_context_create = DllImportsFromSharedLib.grpcsharp_batch_context_create; this.grpcsharp_batch_context_recv_initial_metadata = DllImportsFromSharedLib.grpcsharp_batch_context_recv_initial_metadata; this.grpcsharp_batch_context_recv_message_length = DllImportsFromSharedLib.grpcsharp_batch_context_recv_message_length; - this.grpcsharp_batch_context_recv_message_to_buffer = DllImportsFromSharedLib.grpcsharp_batch_context_recv_message_to_buffer; + this.grpcsharp_batch_context_recv_message_next_slice_peek = DllImportsFromSharedLib.grpcsharp_batch_context_recv_message_next_slice_peek; this.grpcsharp_batch_context_recv_status_on_client_status = DllImportsFromSharedLib.grpcsharp_batch_context_recv_status_on_client_status; this.grpcsharp_batch_context_recv_status_on_client_details = DllImportsFromSharedLib.grpcsharp_batch_context_recv_status_on_client_details; this.grpcsharp_batch_context_recv_status_on_client_trailing_metadata = DllImportsFromSharedLib.grpcsharp_batch_context_recv_status_on_client_trailing_metadata; @@ -401,6 +404,7 @@ namespace Grpc.Core.Internal this.grpcsharp_metadata_array_get_value = DllImportsFromSharedLib.grpcsharp_metadata_array_get_value; this.grpcsharp_metadata_array_destroy_full = DllImportsFromSharedLib.grpcsharp_metadata_array_destroy_full; this.grpcsharp_redirect_log = DllImportsFromSharedLib.grpcsharp_redirect_log; + this.grpcsharp_native_callback_dispatcher_init = DllImportsFromSharedLib.grpcsharp_native_callback_dispatcher_init; this.grpcsharp_metadata_credentials_create_from_plugin = DllImportsFromSharedLib.grpcsharp_metadata_credentials_create_from_plugin; this.grpcsharp_metadata_credentials_notify_from_plugin = DllImportsFromSharedLib.grpcsharp_metadata_credentials_notify_from_plugin; this.grpcsharp_ssl_server_credentials_create = DllImportsFromSharedLib.grpcsharp_ssl_server_credentials_create; @@ -440,7 +444,7 @@ namespace Grpc.Core.Internal public delegate BatchContextSafeHandle grpcsharp_batch_context_create_delegate(); public delegate IntPtr grpcsharp_batch_context_recv_initial_metadata_delegate(BatchContextSafeHandle ctx); public delegate IntPtr grpcsharp_batch_context_recv_message_length_delegate(BatchContextSafeHandle ctx); - public delegate void grpcsharp_batch_context_recv_message_to_buffer_delegate(BatchContextSafeHandle ctx, byte[] buffer, UIntPtr bufferLen); + public delegate int grpcsharp_batch_context_recv_message_next_slice_peek_delegate(BatchContextSafeHandle ctx, out UIntPtr sliceLen, out IntPtr sliceDataPtr); public delegate StatusCode grpcsharp_batch_context_recv_status_on_client_status_delegate(BatchContextSafeHandle ctx); public delegate IntPtr grpcsharp_batch_context_recv_status_on_client_details_delegate(BatchContextSafeHandle ctx, out UIntPtr detailsLength); public delegate IntPtr grpcsharp_batch_context_recv_status_on_client_trailing_metadata_delegate(BatchContextSafeHandle ctx); @@ -478,7 +482,7 @@ namespace Grpc.Core.Internal public delegate void grpcsharp_channel_args_set_integer_delegate(ChannelArgsSafeHandle args, UIntPtr index, string key, int value); public delegate void grpcsharp_channel_args_destroy_delegate(IntPtr args); public delegate void grpcsharp_override_default_ssl_roots_delegate(string pemRootCerts); - public delegate ChannelCredentialsSafeHandle grpcsharp_ssl_credentials_create_delegate(string pemRootCerts, string keyCertPairCertChain, string keyCertPairPrivateKey); + public delegate ChannelCredentialsSafeHandle grpcsharp_ssl_credentials_create_delegate(string pemRootCerts, string keyCertPairCertChain, string keyCertPairPrivateKey, IntPtr verifyPeerCallbackTag); public delegate ChannelCredentialsSafeHandle grpcsharp_composite_channel_credentials_create_delegate(ChannelCredentialsSafeHandle channelCreds, CallCredentialsSafeHandle callCreds); public delegate void grpcsharp_channel_credentials_release_delegate(IntPtr credentials); public delegate ChannelSafeHandle grpcsharp_insecure_channel_create_delegate(string target, ChannelArgsSafeHandle channelArgs); @@ -503,7 +507,8 @@ namespace Grpc.Core.Internal public delegate IntPtr grpcsharp_metadata_array_get_value_delegate(IntPtr metadataArray, UIntPtr index, out UIntPtr valueLength); public delegate void grpcsharp_metadata_array_destroy_full_delegate(IntPtr array); public delegate void grpcsharp_redirect_log_delegate(GprLogDelegate callback); - public delegate CallCredentialsSafeHandle grpcsharp_metadata_credentials_create_from_plugin_delegate(NativeMetadataInterceptor interceptor); + public delegate void grpcsharp_native_callback_dispatcher_init_delegate(NativeCallbackDispatcherCallback dispatcher); + public delegate CallCredentialsSafeHandle grpcsharp_metadata_credentials_create_from_plugin_delegate(IntPtr nativeCallbackTag); public delegate void grpcsharp_metadata_credentials_notify_from_plugin_delegate(IntPtr callbackPtr, IntPtr userData, MetadataArraySafeHandle metadataArray, StatusCode statusCode, string errorDetails); public delegate ServerCredentialsSafeHandle grpcsharp_ssl_server_credentials_create_delegate(string pemRootCerts, string[] keyCertPairCertChainArray, string[] keyCertPairPrivateKeyArray, UIntPtr numKeyCertPairs, SslClientCertificateRequestType clientCertificateRequest); public delegate void grpcsharp_server_credentials_release_delegate(IntPtr credentials); @@ -557,7 +562,7 @@ namespace Grpc.Core.Internal public static extern IntPtr grpcsharp_batch_context_recv_message_length(BatchContextSafeHandle ctx); [DllImport(ImportName)] - public static extern void grpcsharp_batch_context_recv_message_to_buffer(BatchContextSafeHandle ctx, byte[] buffer, UIntPtr bufferLen); + public static extern int grpcsharp_batch_context_recv_message_next_slice_peek(BatchContextSafeHandle ctx, out UIntPtr sliceLen, out IntPtr sliceDataPtr); [DllImport(ImportName)] public static extern StatusCode grpcsharp_batch_context_recv_status_on_client_status(BatchContextSafeHandle ctx); @@ -671,7 +676,7 @@ namespace Grpc.Core.Internal public static extern void grpcsharp_override_default_ssl_roots(string pemRootCerts); [DllImport(ImportName)] - public static extern ChannelCredentialsSafeHandle grpcsharp_ssl_credentials_create(string pemRootCerts, string keyCertPairCertChain, string keyCertPairPrivateKey); + public static extern ChannelCredentialsSafeHandle grpcsharp_ssl_credentials_create(string pemRootCerts, string keyCertPairCertChain, string keyCertPairPrivateKey, IntPtr verifyPeerCallbackTag); [DllImport(ImportName)] public static extern ChannelCredentialsSafeHandle grpcsharp_composite_channel_credentials_create(ChannelCredentialsSafeHandle channelCreds, CallCredentialsSafeHandle callCreds); @@ -746,7 +751,10 @@ namespace Grpc.Core.Internal public static extern void grpcsharp_redirect_log(GprLogDelegate callback); [DllImport(ImportName)] - public static extern CallCredentialsSafeHandle grpcsharp_metadata_credentials_create_from_plugin(NativeMetadataInterceptor interceptor); + public static extern void grpcsharp_native_callback_dispatcher_init(NativeCallbackDispatcherCallback dispatcher); + + [DllImport(ImportName)] + public static extern CallCredentialsSafeHandle grpcsharp_metadata_credentials_create_from_plugin(IntPtr nativeCallbackTag); [DllImport(ImportName)] public static extern void grpcsharp_metadata_credentials_notify_from_plugin(IntPtr callbackPtr, IntPtr userData, MetadataArraySafeHandle metadataArray, StatusCode statusCode, string errorDetails); @@ -850,7 +858,7 @@ namespace Grpc.Core.Internal public static extern IntPtr grpcsharp_batch_context_recv_message_length(BatchContextSafeHandle ctx); [DllImport(ImportName)] - public static extern void grpcsharp_batch_context_recv_message_to_buffer(BatchContextSafeHandle ctx, byte[] buffer, UIntPtr bufferLen); + public static extern int grpcsharp_batch_context_recv_message_next_slice_peek(BatchContextSafeHandle ctx, out UIntPtr sliceLen, out IntPtr sliceDataPtr); [DllImport(ImportName)] public static extern StatusCode grpcsharp_batch_context_recv_status_on_client_status(BatchContextSafeHandle ctx); @@ -964,7 +972,7 @@ namespace Grpc.Core.Internal public static extern void grpcsharp_override_default_ssl_roots(string pemRootCerts); [DllImport(ImportName)] - public static extern ChannelCredentialsSafeHandle grpcsharp_ssl_credentials_create(string pemRootCerts, string keyCertPairCertChain, string keyCertPairPrivateKey); + public static extern ChannelCredentialsSafeHandle grpcsharp_ssl_credentials_create(string pemRootCerts, string keyCertPairCertChain, string keyCertPairPrivateKey, IntPtr verifyPeerCallbackTag); [DllImport(ImportName)] public static extern ChannelCredentialsSafeHandle grpcsharp_composite_channel_credentials_create(ChannelCredentialsSafeHandle channelCreds, CallCredentialsSafeHandle callCreds); @@ -1039,7 +1047,10 @@ namespace Grpc.Core.Internal public static extern void grpcsharp_redirect_log(GprLogDelegate callback); [DllImport(ImportName)] - public static extern CallCredentialsSafeHandle grpcsharp_metadata_credentials_create_from_plugin(NativeMetadataInterceptor interceptor); + public static extern void grpcsharp_native_callback_dispatcher_init(NativeCallbackDispatcherCallback dispatcher); + + [DllImport(ImportName)] + public static extern CallCredentialsSafeHandle grpcsharp_metadata_credentials_create_from_plugin(IntPtr nativeCallbackTag); [DllImport(ImportName)] public static extern void grpcsharp_metadata_credentials_notify_from_plugin(IntPtr callbackPtr, IntPtr userData, MetadataArraySafeHandle metadataArray, StatusCode statusCode, string errorDetails); diff --git a/src/csharp/Grpc.Core/Internal/PlatformApis.cs b/src/csharp/Grpc.Core/Internal/PlatformApis.cs index a8f147545b4..8d7e8c2acb5 100644 --- a/src/csharp/Grpc.Core/Internal/PlatformApis.cs +++ b/src/csharp/Grpc.Core/Internal/PlatformApis.cs @@ -49,7 +49,7 @@ namespace Grpc.Core.Internal static PlatformApis() { -#if NETSTANDARD1_5 +#if NETSTANDARD1_5 || NETSTANDARD2_0 isLinux = RuntimeInformation.IsOSPlatform(OSPlatform.Linux); isMacOSX = RuntimeInformation.IsOSPlatform(OSPlatform.OSX); isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows); @@ -171,7 +171,7 @@ namespace Grpc.Core.Internal public static string GetUnityRuntimePlatform() { GrpcPreconditions.CheckState(IsUnity, "Not running on Unity."); -#if NETSTANDARD1_5 +#if NETSTANDARD1_5 || NETSTANDARD2_0 return Type.GetType(UnityEngineApplicationClassName).GetTypeInfo().GetProperty("platform").GetValue(null).ToString(); #else return Type.GetType(UnityEngineApplicationClassName).GetProperty("platform").GetValue(null).ToString(); diff --git a/src/csharp/Grpc.Core/Internal/ReusableSliceBuffer.cs b/src/csharp/Grpc.Core/Internal/ReusableSliceBuffer.cs new file mode 100644 index 00000000000..2d38509e511 --- /dev/null +++ b/src/csharp/Grpc.Core/Internal/ReusableSliceBuffer.cs @@ -0,0 +1,148 @@ +#region Copyright notice and license + +// Copyright 2019 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. +// 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 + +#if GRPC_CSHARP_SUPPORT_SYSTEM_MEMORY + +using Grpc.Core.Utils; +using System; +using System.Threading; + +using System.Buffers; + +namespace Grpc.Core.Internal +{ + internal class ReusableSliceBuffer + { + public const int MaxCachedSegments = 1024; // ~4MB payload for 4K slices + + readonly SliceSegment[] cachedSegments = new SliceSegment[MaxCachedSegments]; + int populatedSegmentCount; + + public ReadOnlySequence PopulateFrom(IBufferReader bufferReader) + { + populatedSegmentCount = 0; + long offset = 0; + SliceSegment prevSegment = null; + while (bufferReader.TryGetNextSlice(out Slice slice)) + { + // Initialize cached segment if still null or just allocate a new segment if we already reached MaxCachedSegments + var current = populatedSegmentCount < cachedSegments.Length ? cachedSegments[populatedSegmentCount] : new SliceSegment(); + if (current == null) + { + current = cachedSegments[populatedSegmentCount] = new SliceSegment(); + } + + current.Reset(slice, offset); + prevSegment?.SetNext(current); + + populatedSegmentCount ++; + offset += slice.Length; + prevSegment = current; + } + + // Not necessary for ending the ReadOnlySequence, but for making sure we + // don't keep more than MaxCachedSegments alive. + prevSegment?.SetNext(null); + + if (populatedSegmentCount == 0) + { + return ReadOnlySequence.Empty; + } + + var firstSegment = cachedSegments[0]; + var lastSegment = prevSegment; + return new ReadOnlySequence(firstSegment, 0, lastSegment, lastSegment.Memory.Length); + } + + public void Invalidate() + { + if (populatedSegmentCount == 0) + { + return; + } + var segment = cachedSegments[0]; + while (segment != null) + { + segment.Reset(new Slice(IntPtr.Zero, 0), 0); + var nextSegment = (SliceSegment) segment.Next; + segment.SetNext(null); + segment = nextSegment; + } + populatedSegmentCount = 0; + } + + // Represents a segment in ReadOnlySequence + // Segment is backed by Slice and the instances are reusable. + private class SliceSegment : ReadOnlySequenceSegment + { + readonly SliceMemoryManager pointerMemoryManager = new SliceMemoryManager(); + + public void Reset(Slice slice, long runningIndex) + { + pointerMemoryManager.Reset(slice); + Memory = pointerMemoryManager.Memory; // maybe not always necessary + RunningIndex = runningIndex; + } + + public void SetNext(ReadOnlySequenceSegment next) + { + Next = next; + } + } + + // Allow creating instances of Memory from Slice. + // Represents a chunk of native memory, but doesn't manage its lifetime. + // Instances of this class are reuseable - they can be reset to point to a different memory chunk. + // That is important to make the instances cacheable (rather then creating new instances + // the old ones will be reused to reduce GC pressure). + private class SliceMemoryManager : MemoryManager + { + private Slice slice; + + public void Reset(Slice slice) + { + this.slice = slice; + } + + public void Reset() + { + Reset(new Slice(IntPtr.Zero, 0)); + } + + public override Span GetSpan() + { + return slice.ToSpanUnsafe(); + } + + public override MemoryHandle Pin(int elementIndex = 0) + { + throw new NotSupportedException(); + } + + public override void Unpin() + { + } + + protected override void Dispose(bool disposing) + { + // NOP + } + } + } +} +#endif diff --git a/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs b/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs index ec732e8c7f4..0c9297413c3 100644 --- a/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs +++ b/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs @@ -31,7 +31,6 @@ namespace Grpc.Core.Internal internal interface IServerCallHandler { Task HandleCall(ServerRpcNew newRpc, CompletionQueueSafeHandle cq); - IServerCallHandler Intercept(Interceptor interceptor); } internal class UnaryServerCallHandler : IServerCallHandler @@ -71,7 +70,7 @@ namespace Grpc.Core.Internal var response = await handler(request, context).ConfigureAwait(false); status = context.Status; responseWithFlags = new AsyncCallServer.ResponseWithFlags(response, HandlerUtils.GetWriteFlags(context.WriteOptions)); - } + } catch (Exception e) { if (!(e is RpcException)) @@ -91,11 +90,6 @@ namespace Grpc.Core.Internal } await finishedTask.ConfigureAwait(false); } - - public IServerCallHandler Intercept(Interceptor interceptor) - { - return new UnaryServerCallHandler(method, (request, context) => interceptor.UnaryServerHandler(request, context, handler)); - } } internal class ServerStreamingServerCallHandler : IServerCallHandler @@ -154,11 +148,6 @@ namespace Grpc.Core.Internal } await finishedTask.ConfigureAwait(false); } - - public IServerCallHandler Intercept(Interceptor interceptor) - { - return new ServerStreamingServerCallHandler(method, (request, responseStream, context) => interceptor.ServerStreamingServerHandler(request, responseStream, context, handler)); - } } internal class ClientStreamingServerCallHandler : IServerCallHandler @@ -217,11 +206,6 @@ namespace Grpc.Core.Internal } await finishedTask.ConfigureAwait(false); } - - public IServerCallHandler Intercept(Interceptor interceptor) - { - return new ClientStreamingServerCallHandler(method, (requestStream, context) => interceptor.ClientStreamingServerHandler(requestStream, context, handler)); - } } internal class DuplexStreamingServerCallHandler : IServerCallHandler @@ -277,11 +261,6 @@ namespace Grpc.Core.Internal } await finishedTask.ConfigureAwait(false); } - - public IServerCallHandler Intercept(Interceptor interceptor) - { - return new DuplexStreamingServerCallHandler(method, (requestStream, responseStream, context) => interceptor.DuplexStreamingServerHandler(requestStream, responseStream, context, handler)); - } } internal class UnimplementedMethodCallHandler : IServerCallHandler @@ -310,11 +289,6 @@ namespace Grpc.Core.Internal { return callHandlerImpl.HandleCall(newRpc, cq); } - - public IServerCallHandler Intercept(Interceptor interceptor) - { - return this; // Do not intercept unimplemented methods. - } } internal static class HandlerUtils @@ -345,14 +319,10 @@ namespace Grpc.Core.Internal return writeOptions != null ? writeOptions.Flags : default(WriteFlags); } - public static ServerCallContext NewContext(ServerRpcNew newRpc, ServerResponseStream serverResponseStream, CancellationToken cancellationToken) - where TRequest : class - where TResponse : class + public static ServerCallContext NewContext(ServerRpcNew newRpc, IServerResponseStream serverResponseStream, CancellationToken cancellationToken) { DateTime realtimeDeadline = newRpc.Deadline.ToClockType(ClockType.Realtime).ToDateTime(); - - return new ServerCallContext(newRpc.Call, newRpc.Method, newRpc.Host, realtimeDeadline, - newRpc.RequestMetadata, cancellationToken, serverResponseStream.WriteResponseHeadersAsync, serverResponseStream); + return new DefaultServerCallContext(newRpc.Call, newRpc.Method, newRpc.Host, realtimeDeadline, newRpc.RequestMetadata, cancellationToken, serverResponseStream); } } } diff --git a/src/csharp/Grpc.Core/Internal/ServerResponseStream.cs b/src/csharp/Grpc.Core/Internal/ServerResponseStream.cs index 352b98829c7..079849e4c61 100644 --- a/src/csharp/Grpc.Core/Internal/ServerResponseStream.cs +++ b/src/csharp/Grpc.Core/Internal/ServerResponseStream.cs @@ -23,7 +23,7 @@ namespace Grpc.Core.Internal /// /// Writes responses asynchronously to an underlying AsyncCallServer object. /// - internal class ServerResponseStream : IServerStreamWriter, IHasWriteOptions + internal class ServerResponseStream : IServerStreamWriter, IServerResponseStream where TRequest : class where TResponse : class { diff --git a/src/csharp/Grpc.Core/Internal/ServerServiceDefinitionExtensions.cs b/src/csharp/Grpc.Core/Internal/ServerServiceDefinitionExtensions.cs new file mode 100644 index 00000000000..cc4654c9acf --- /dev/null +++ b/src/csharp/Grpc.Core/Internal/ServerServiceDefinitionExtensions.cs @@ -0,0 +1,78 @@ +#region Copyright notice and license + +// Copyright 2019 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. +// 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.Collections.Generic; +using System.Collections.ObjectModel; +using Grpc.Core.Internal; + +namespace Grpc.Core.Internal +{ + internal static class ServerServiceDefinitionExtensions + { + /// + /// Maps methods from ServerServiceDefinition to server call handlers. + /// + internal static ReadOnlyDictionary GetCallHandlers(this ServerServiceDefinition serviceDefinition) + { + var binder = new DefaultServiceBinder(); + serviceDefinition.BindService(binder); + return binder.GetCallHandlers(); + } + + /// + /// Helper for converting ServerServiceDefinition to server call handlers. + /// + private class DefaultServiceBinder : ServiceBinderBase + { + readonly Dictionary callHandlers = new Dictionary(); + + internal ReadOnlyDictionary GetCallHandlers() + { + return new ReadOnlyDictionary(this.callHandlers); + } + + public override void AddMethod( + Method method, + UnaryServerMethod handler) + { + callHandlers.Add(method.FullName, ServerCalls.UnaryCall(method, handler)); + } + + public override void AddMethod( + Method method, + ClientStreamingServerMethod handler) + { + callHandlers.Add(method.FullName, ServerCalls.ClientStreamingCall(method, handler)); + } + + public override void AddMethod( + Method method, + ServerStreamingServerMethod handler) + { + callHandlers.Add(method.FullName, ServerCalls.ServerStreamingCall(method, handler)); + } + + public override void AddMethod( + Method method, + DuplexStreamingServerMethod handler) + { + callHandlers.Add(method.FullName, ServerCalls.DuplexStreamingCall(method, handler)); + } + } + } +} diff --git a/src/csharp/Grpc.Core/Internal/Slice.cs b/src/csharp/Grpc.Core/Internal/Slice.cs new file mode 100644 index 00000000000..22eb9537951 --- /dev/null +++ b/src/csharp/Grpc.Core/Internal/Slice.cs @@ -0,0 +1,68 @@ +#region Copyright notice and license + +// Copyright 2019 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. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#endregion + +using System; +using System.Runtime.InteropServices; +using System.Threading; +using Grpc.Core.Utils; + +namespace Grpc.Core.Internal +{ + /// + /// Slice of native memory. + /// Rough equivalent of grpc_slice (but doesn't support inlined slices, just a pointer to data and length) + /// + internal struct Slice + { + private readonly IntPtr dataPtr; + private readonly int length; + + public Slice(IntPtr dataPtr, int length) + { + this.dataPtr = dataPtr; + this.length = length; + } + + public int Length => length; + + // copies data of the slice to given span. + // there needs to be enough space in the destination buffer + public void CopyTo(ArraySegment destination) + { + Marshal.Copy(dataPtr, destination.Array, destination.Offset, length); + } + +#if GRPC_CSHARP_SUPPORT_SYSTEM_MEMORY + public Span ToSpanUnsafe() + { + unsafe + { + return new Span((byte*) dataPtr, length); + } + } +#endif + + /// + /// Returns a that represents the current . + /// + public override string ToString() + { + return string.Format("[Slice: dataPtr={0}, length={1}]", dataPtr, length); + } + } +} diff --git a/src/csharp/Grpc.Core/Internal/UnmanagedLibrary.cs b/src/csharp/Grpc.Core/Internal/UnmanagedLibrary.cs index 1786fc2e3f6..056758df8ca 100644 --- a/src/csharp/Grpc.Core/Internal/UnmanagedLibrary.cs +++ b/src/csharp/Grpc.Core/Internal/UnmanagedLibrary.cs @@ -120,7 +120,7 @@ namespace Grpc.Core.Internal { throw new MissingMethodException(string.Format("The native method \"{0}\" does not exist", methodName)); } -#if NETSTANDARD1_5 +#if NETSTANDARD1_5 || NETSTANDARD2_0 return Marshal.GetDelegateForFunctionPointer(ptr); // non-generic version is obsolete #else return Marshal.GetDelegateForFunctionPointer(ptr, typeof(T)) as T; // generic version not available in .NET45 diff --git a/src/csharp/Grpc.Core/Server.cs b/src/csharp/Grpc.Core/Server.cs index 64bb407c57f..26d182ae53b 100644 --- a/src/csharp/Grpc.Core/Server.cs +++ b/src/csharp/Grpc.Core/Server.cs @@ -257,7 +257,7 @@ namespace Grpc.Core lock (myLock) { GrpcPreconditions.CheckState(!startRequested); - foreach (var entry in serviceDefinition.CallHandlers) + foreach (var entry in serviceDefinition.GetCallHandlers()) { callHandlers.Add(entry.Key, entry.Value); } diff --git a/src/csharp/Grpc.Core/ServerCallContext.cs b/src/csharp/Grpc.Core/ServerCallContext.cs deleted file mode 100644 index 74a7deabea0..00000000000 --- a/src/csharp/Grpc.Core/ServerCallContext.cs +++ /dev/null @@ -1,234 +0,0 @@ -#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.Internal; - -namespace Grpc.Core -{ - /// - /// Context for a server-side call. - /// - public class ServerCallContext - { - private readonly CallSafeHandle callHandle; - private readonly string method; - private readonly string host; - private readonly DateTime deadline; - private readonly Metadata requestHeaders; - private readonly CancellationToken cancellationToken; - private readonly Metadata responseTrailers = new Metadata(); - private readonly Func writeHeadersFunc; - private readonly IHasWriteOptions writeOptionsHolder; - private readonly Lazy authContext; - private readonly Func testingOnlyPeerGetter; - private readonly Func testingOnlyAuthContextGetter; - private readonly Func testingOnlyContextPropagationTokenFactory; - - private Status status = Status.DefaultSuccess; - - internal ServerCallContext(CallSafeHandle callHandle, string method, string host, DateTime deadline, Metadata requestHeaders, CancellationToken cancellationToken, - Func 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 writeHeadersFunc, IHasWriteOptions writeOptionsHolder, - Func testingOnlyPeerGetter, Func testingOnlyAuthContextGetter, Func testingOnlyContextPropagationTokenFactory) - { - this.callHandle = callHandle; - this.method = method; - this.host = host; - this.deadline = deadline; - this.requestHeaders = requestHeaders; - this.cancellationToken = cancellationToken; - this.writeHeadersFunc = writeHeadersFunc; - this.writeOptionsHolder = writeOptionsHolder; - this.authContext = new Lazy(GetAuthContextEager); - this.testingOnlyPeerGetter = testingOnlyPeerGetter; - this.testingOnlyAuthContextGetter = testingOnlyAuthContextGetter; - this.testingOnlyContextPropagationTokenFactory = testingOnlyContextPropagationTokenFactory; - } - - /// - /// Asynchronously sends response headers for the current call to the client. This method may only be invoked once for each call and needs to be invoked - /// before any response messages are written. Writing the first response message implicitly sends empty response headers if WriteResponseHeadersAsync haven't - /// been called yet. - /// - /// The response headers to send. - /// The task that finished once response headers have been written. - public Task WriteResponseHeadersAsync(Metadata responseHeaders) - { - return writeHeadersFunc(responseHeaders); - } - - /// - /// Creates a propagation token to be used to propagate call context to a child call. - /// - public ContextPropagationToken CreatePropagationToken(ContextPropagationOptions options = null) - { - if (testingOnlyContextPropagationTokenFactory != null) - { - return testingOnlyContextPropagationTokenFactory(); - } - return new ContextPropagationToken(callHandle, deadline, cancellationToken, options); - } - - /// Name of method called in this RPC. - public string Method - { - get - { - return this.method; - } - } - - /// Name of host called in this RPC. - public string Host - { - get - { - return this.host; - } - } - - /// Address of the remote endpoint in URI format. - public string Peer - { - 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. - return this.callHandle.GetPeer(); - } - } - - /// Deadline for this RPC. - public DateTime Deadline - { - get - { - return this.deadline; - } - } - - /// Initial metadata sent by client. - public Metadata RequestHeaders - { - get - { - return this.requestHeaders; - } - } - - /// Cancellation token signals when call is cancelled. - public CancellationToken CancellationToken - { - get - { - return this.cancellationToken; - } - } - - /// Trailers to send back to client after RPC finishes. - public Metadata ResponseTrailers - { - get - { - return this.responseTrailers; - } - } - - /// Status to send back to client after RPC finishes. - public Status Status - { - get - { - return this.status; - } - - set - { - status = value; - } - } - - /// - /// Allows setting write options for the following write. - /// For streaming response calls, this property is also exposed as on IServerStreamWriter for convenience. - /// Both properties are backed by the same underlying value. - /// - public WriteOptions WriteOptions - { - get - { - return writeOptionsHolder.WriteOptions; - } - - set - { - writeOptionsHolder.WriteOptions = value; - } - } - - /// - /// Gets the AuthContext associated with this call. - /// Note: Access to AuthContext is an experimental API that can change without any prior notice. - /// - public AuthContext AuthContext - { - get - { - if (testingOnlyAuthContextGetter != null) - { - return testingOnlyAuthContextGetter(); - } - return authContext.Value; - } - } - - private AuthContext GetAuthContextEager() - { - using (var authContextNative = callHandle.GetAuthContext()) - { - return authContextNative.ToAuthContext(); - } - } - } - - /// - /// Allows sharing write options between ServerCallContext and other objects. - /// - internal interface IHasWriteOptions - { - /// - /// Gets or sets the write options. - /// - WriteOptions WriteOptions { get; set; } - } -} diff --git a/src/csharp/Grpc.Core/SourceLink.csproj.include b/src/csharp/Grpc.Core/SourceLink.csproj.include index 0ec273f57e6..9c027deaa3e 100755 --- a/src/csharp/Grpc.Core/SourceLink.csproj.include +++ b/src/csharp/Grpc.Core/SourceLink.csproj.include @@ -1,19 +1,14 @@ - - - true - lib/netstandard1.5 - - - true - lib/net45 - - + + + $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb + true + - + diff --git a/src/csharp/Grpc.Core/Utils/TaskUtils.cs b/src/csharp/Grpc.Core/Utils/TaskUtils.cs index f25106f8dd8..21cd63336dc 100644 --- a/src/csharp/Grpc.Core/Utils/TaskUtils.cs +++ b/src/csharp/Grpc.Core/Utils/TaskUtils.cs @@ -33,7 +33,7 @@ namespace Grpc.Core.Utils { get { -#if NETSTANDARD1_5 +#if NETSTANDARD1_5 || NETSTANDARD2_0 return Task.CompletedTask; #else return Task.FromResult(null); // for .NET45, emulate the functionality diff --git a/src/csharp/Grpc.Core/VerifyPeerContext.cs b/src/csharp/Grpc.Core/VerifyPeerContext.cs new file mode 100644 index 00000000000..b1dc60f8e27 --- /dev/null +++ b/src/csharp/Grpc.Core/VerifyPeerContext.cs @@ -0,0 +1,48 @@ +#region Copyright notice and license + +// Copyright 2019 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. +// 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 + +namespace Grpc.Core +{ + /// + /// Verification context for VerifyPeerCallback. + /// Note: experimental API that can change or be removed without any prior notice. + /// + public class VerifyPeerContext + { + /// + /// Initializes a new instance of the class. + /// + /// The target name of the peer. + /// The PEM encoded certificate of the peer. + internal VerifyPeerContext(string targetName, string peerPem) + { + this.TargetName = targetName; + this.PeerPem = peerPem; + } + + /// + /// The target name of the peer. + /// + public string TargetName { get; } + + /// + /// The PEM encoded certificate of the peer. + /// + public string PeerPem { get; } + } +} diff --git a/src/csharp/Grpc.Core/Version.csproj.include b/src/csharp/Grpc.Core/Version.csproj.include index ed0d8843650..6354a053965 100755 --- a/src/csharp/Grpc.Core/Version.csproj.include +++ b/src/csharp/Grpc.Core/Version.csproj.include @@ -1,7 +1,7 @@ - 1.17.0-dev + 1.19.1 3.6.1 diff --git a/src/csharp/Grpc.Examples.MathClient/Grpc.Examples.MathClient.csproj b/src/csharp/Grpc.Examples.MathClient/Grpc.Examples.MathClient.csproj index db4e3ef4e3f..03018239525 100755 --- a/src/csharp/Grpc.Examples.MathClient/Grpc.Examples.MathClient.csproj +++ b/src/csharp/Grpc.Examples.MathClient/Grpc.Examples.MathClient.csproj @@ -1,13 +1,10 @@  - - net45;netcoreapp1.0 - Grpc.Examples.MathClient + net45;netcoreapp2.1 Exe - Grpc.Examples.MathClient true @@ -21,7 +18,7 @@ - + diff --git a/src/csharp/Grpc.Examples.MathServer/Grpc.Examples.MathServer.csproj b/src/csharp/Grpc.Examples.MathServer/Grpc.Examples.MathServer.csproj index b12b418d015..03018239525 100755 --- a/src/csharp/Grpc.Examples.MathServer/Grpc.Examples.MathServer.csproj +++ b/src/csharp/Grpc.Examples.MathServer/Grpc.Examples.MathServer.csproj @@ -1,13 +1,10 @@  - - net45;netcoreapp1.0 - Grpc.Examples.MathServer + net45;netcoreapp2.1 Exe - Grpc.Examples.MathServer true @@ -21,7 +18,7 @@ - + diff --git a/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj b/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj index 7493eb8051d..b3fbbfffcca 100755 --- a/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj +++ b/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj @@ -1,13 +1,10 @@  - - net45;netcoreapp1.0 - Grpc.Examples.Tests + net45;netcoreapp2.1 Exe - Grpc.Examples.Tests true @@ -28,7 +25,7 @@ - + diff --git a/src/csharp/Grpc.Examples.Tests/NUnitMain.cs b/src/csharp/Grpc.Examples.Tests/NUnitMain.cs index bcb8b46b644..107df648099 100644 --- a/src/csharp/Grpc.Examples.Tests/NUnitMain.cs +++ b/src/csharp/Grpc.Examples.Tests/NUnitMain.cs @@ -34,11 +34,7 @@ namespace Grpc.Examples.Tests { // Make logger immune to NUnit capturing stdout and stderr to workaround https://github.com/nunit/nunit/issues/1406. GrpcEnvironment.SetLogger(new ConsoleLogger()); -#if NETCOREAPP1_0 - return new AutoRun(typeof(NUnitMain).GetTypeInfo().Assembly).Execute(args, new ExtendedTextWrapper(Console.Out), Console.In); -#else - return new AutoRun().Execute(args); -#endif + return new AutoRun(typeof(NUnitMain).GetTypeInfo().Assembly).Execute(args); } } } diff --git a/src/csharp/Grpc.Examples/Grpc.Examples.csproj b/src/csharp/Grpc.Examples/Grpc.Examples.csproj index baa3b4ce6c1..66ea71853bf 100755 --- a/src/csharp/Grpc.Examples/Grpc.Examples.csproj +++ b/src/csharp/Grpc.Examples/Grpc.Examples.csproj @@ -1,17 +1,14 @@  - - net45;netcoreapp1.0 - Grpc.Examples - Grpc.Examples + net45;netcoreapp2.1 true - + diff --git a/src/csharp/Grpc.Examples/MathGrpc.cs b/src/csharp/Grpc.Examples/MathGrpc.cs index e5be387e67e..fab64354411 100644 --- a/src/csharp/Grpc.Examples/MathGrpc.cs +++ b/src/csharp/Grpc.Examples/MathGrpc.cs @@ -67,6 +67,7 @@ namespace Math { } /// Base class for server-side implementations of Math + [grpc::BindServiceMethod(typeof(Math), "BindService")] public abstract partial class MathBase { /// @@ -287,16 +288,16 @@ namespace Math { .AddMethod(__Method_Sum, serviceImpl.Sum).Build(); } - /// Register service method implementations with a service binder. Useful when customizing the service binding logic. + /// Register service method with a service binder with or without implementation. Useful when customizing the service binding logic. /// Note: this method is part of an experimental API that can change or be removed without any prior notice. /// Service methods will be bound by calling AddMethod on this object. /// An object implementing the server-side handling logic. public static void BindService(grpc::ServiceBinderBase serviceBinder, MathBase serviceImpl) { - serviceBinder.AddMethod(__Method_Div, serviceImpl.Div); - serviceBinder.AddMethod(__Method_DivMany, serviceImpl.DivMany); - serviceBinder.AddMethod(__Method_Fib, serviceImpl.Fib); - serviceBinder.AddMethod(__Method_Sum, serviceImpl.Sum); + serviceBinder.AddMethod(__Method_Div, serviceImpl == null ? null : new grpc::UnaryServerMethod(serviceImpl.Div)); + serviceBinder.AddMethod(__Method_DivMany, serviceImpl == null ? null : new grpc::DuplexStreamingServerMethod(serviceImpl.DivMany)); + serviceBinder.AddMethod(__Method_Fib, serviceImpl == null ? null : new grpc::ServerStreamingServerMethod(serviceImpl.Fib)); + serviceBinder.AddMethod(__Method_Sum, serviceImpl == null ? null : new grpc::ClientStreamingServerMethod(serviceImpl.Sum)); } } diff --git a/src/csharp/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.csproj b/src/csharp/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.csproj index 616e56df105..223c9985ecd 100755 --- a/src/csharp/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.csproj +++ b/src/csharp/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.csproj @@ -1,13 +1,10 @@  - - net45;netcoreapp1.0 - Grpc.HealthCheck.Tests + net45;netcoreapp2.1 Exe - Grpc.HealthCheck.Tests true @@ -26,7 +23,7 @@ - + diff --git a/src/csharp/Grpc.HealthCheck.Tests/NUnitMain.cs b/src/csharp/Grpc.HealthCheck.Tests/NUnitMain.cs index 365551e8956..db6d32a5b25 100644 --- a/src/csharp/Grpc.HealthCheck.Tests/NUnitMain.cs +++ b/src/csharp/Grpc.HealthCheck.Tests/NUnitMain.cs @@ -34,11 +34,7 @@ namespace Grpc.HealthCheck.Tests { // Make logger immune to NUnit capturing stdout and stderr to workaround https://github.com/nunit/nunit/issues/1406. GrpcEnvironment.SetLogger(new ConsoleLogger()); -#if NETCOREAPP1_0 - return new AutoRun(typeof(NUnitMain).GetTypeInfo().Assembly).Execute(args, new ExtendedTextWrapper(Console.Out), Console.In); -#else - return new AutoRun().Execute(args); -#endif + return new AutoRun(typeof(NUnitMain).GetTypeInfo().Assembly).Execute(args); } } } diff --git a/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj b/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj index da61253455a..7e8a8a7de87 100755 --- a/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj +++ b/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj @@ -1,19 +1,20 @@  - - Copyright 2015, Google Inc. - gRPC C# Healthchecking - $(GrpcCsharpVersion) - Google Inc. - net45;netstandard1.5 - Grpc.HealthCheck - Grpc.HealthCheck - gRPC health check + The gRPC Authors + Copyright 2015 The gRPC Authors + gRPC C# Health Checking (for Grpc.Core) + https://github.com/grpc/grpc.github.io/raw/master/img/grpc_square_reverse_4x.png + Apache-2.0 https://github.com/grpc/grpc - https://github.com/grpc/grpc/blob/master/LICENSE + gRPC health check + $(GrpcCsharpVersion) + + + + net45;netstandard1.5;netstandard2.0 true true @@ -21,7 +22,7 @@ - + diff --git a/src/csharp/Grpc.HealthCheck/Health.cs b/src/csharp/Grpc.HealthCheck/Health.cs index 2c3bb45c3cf..82e42febedd 100644 --- a/src/csharp/Grpc.HealthCheck/Health.cs +++ b/src/csharp/Grpc.HealthCheck/Health.cs @@ -296,7 +296,7 @@ namespace Grpc.Health.V1 { _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); break; case 8: { - status_ = (global::Grpc.Health.V1.HealthCheckResponse.Types.ServingStatus) input.ReadEnum(); + Status = (global::Grpc.Health.V1.HealthCheckResponse.Types.ServingStatus) input.ReadEnum(); break; } } diff --git a/src/csharp/Grpc.HealthCheck/HealthGrpc.cs b/src/csharp/Grpc.HealthCheck/HealthGrpc.cs index 51956f2f234..7137b907274 100644 --- a/src/csharp/Grpc.HealthCheck/HealthGrpc.cs +++ b/src/csharp/Grpc.HealthCheck/HealthGrpc.cs @@ -54,6 +54,7 @@ namespace Grpc.Health.V1 { } /// Base class for server-side implementations of Health + [grpc::BindServiceMethod(typeof(Health), "BindService")] public abstract partial class HealthBase { /// @@ -233,14 +234,14 @@ namespace Grpc.Health.V1 { .AddMethod(__Method_Watch, serviceImpl.Watch).Build(); } - /// Register service method implementations with a service binder. Useful when customizing the service binding logic. + /// Register service method with a service binder with or without implementation. Useful when customizing the service binding logic. /// Note: this method is part of an experimental API that can change or be removed without any prior notice. /// Service methods will be bound by calling AddMethod on this object. /// An object implementing the server-side handling logic. public static void BindService(grpc::ServiceBinderBase serviceBinder, HealthBase serviceImpl) { - serviceBinder.AddMethod(__Method_Check, serviceImpl.Check); - serviceBinder.AddMethod(__Method_Watch, serviceImpl.Watch); + serviceBinder.AddMethod(__Method_Check, serviceImpl == null ? null : new grpc::UnaryServerMethod(serviceImpl.Check)); + serviceBinder.AddMethod(__Method_Watch, serviceImpl == null ? null : new grpc::ServerStreamingServerMethod(serviceImpl.Watch)); } } diff --git a/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj b/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj index 35713156ea2..a5baf96357d 100755 --- a/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj +++ b/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj @@ -1,13 +1,10 @@  - - net45;netcoreapp1.0 - Grpc.IntegrationTesting.Client + net45;netcoreapp2.1 Exe - Grpc.IntegrationTesting.Client true @@ -21,7 +18,7 @@ - + diff --git a/src/csharp/Grpc.IntegrationTesting.QpsWorker/Grpc.IntegrationTesting.QpsWorker.csproj b/src/csharp/Grpc.IntegrationTesting.QpsWorker/Grpc.IntegrationTesting.QpsWorker.csproj index 3ecefe3bc4f..8f4833ea749 100755 --- a/src/csharp/Grpc.IntegrationTesting.QpsWorker/Grpc.IntegrationTesting.QpsWorker.csproj +++ b/src/csharp/Grpc.IntegrationTesting.QpsWorker/Grpc.IntegrationTesting.QpsWorker.csproj @@ -1,13 +1,10 @@  - - net45;netcoreapp1.0 - Grpc.IntegrationTesting.QpsWorker + net45;netcoreapp2.1 Exe - Grpc.IntegrationTesting.QpsWorker true true @@ -22,7 +19,7 @@ - + diff --git a/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj b/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj index 1092b2c21ef..a5baf96357d 100755 --- a/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj +++ b/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj @@ -1,13 +1,10 @@  - - net45;netcoreapp1.0 - Grpc.IntegrationTesting.Server + net45;netcoreapp2.1 Exe - Grpc.IntegrationTesting.Server true @@ -19,9 +16,9 @@ - + - + diff --git a/src/csharp/Grpc.IntegrationTesting.StressClient/Grpc.IntegrationTesting.StressClient.csproj b/src/csharp/Grpc.IntegrationTesting.StressClient/Grpc.IntegrationTesting.StressClient.csproj index 22272547f61..a5baf96357d 100755 --- a/src/csharp/Grpc.IntegrationTesting.StressClient/Grpc.IntegrationTesting.StressClient.csproj +++ b/src/csharp/Grpc.IntegrationTesting.StressClient/Grpc.IntegrationTesting.StressClient.csproj @@ -1,13 +1,10 @@  - - net45;netcoreapp1.0 - Grpc.IntegrationTesting.StressClient + net45;netcoreapp2.1 Exe - Grpc.IntegrationTesting.StressClient true @@ -21,7 +18,7 @@ - + diff --git a/src/csharp/Grpc.IntegrationTesting/BenchmarkServiceGrpc.cs b/src/csharp/Grpc.IntegrationTesting/BenchmarkServiceGrpc.cs index 3431b5fa181..5b37b144f2a 100644 --- a/src/csharp/Grpc.IntegrationTesting/BenchmarkServiceGrpc.cs +++ b/src/csharp/Grpc.IntegrationTesting/BenchmarkServiceGrpc.cs @@ -74,6 +74,7 @@ namespace Grpc.Testing { } /// Base class for server-side implementations of BenchmarkService + [grpc::BindServiceMethod(typeof(BenchmarkService), "BindService")] public abstract partial class BenchmarkServiceBase { /// @@ -324,17 +325,17 @@ namespace Grpc.Testing { .AddMethod(__Method_StreamingBothWays, serviceImpl.StreamingBothWays).Build(); } - /// Register service method implementations with a service binder. Useful when customizing the service binding logic. + /// Register service method with a service binder with or without implementation. Useful when customizing the service binding logic. /// Note: this method is part of an experimental API that can change or be removed without any prior notice. /// Service methods will be bound by calling AddMethod on this object. /// An object implementing the server-side handling logic. public static void BindService(grpc::ServiceBinderBase serviceBinder, BenchmarkServiceBase serviceImpl) { - serviceBinder.AddMethod(__Method_UnaryCall, serviceImpl.UnaryCall); - serviceBinder.AddMethod(__Method_StreamingCall, serviceImpl.StreamingCall); - serviceBinder.AddMethod(__Method_StreamingFromClient, serviceImpl.StreamingFromClient); - serviceBinder.AddMethod(__Method_StreamingFromServer, serviceImpl.StreamingFromServer); - serviceBinder.AddMethod(__Method_StreamingBothWays, serviceImpl.StreamingBothWays); + serviceBinder.AddMethod(__Method_UnaryCall, serviceImpl == null ? null : new grpc::UnaryServerMethod(serviceImpl.UnaryCall)); + serviceBinder.AddMethod(__Method_StreamingCall, serviceImpl == null ? null : new grpc::DuplexStreamingServerMethod(serviceImpl.StreamingCall)); + serviceBinder.AddMethod(__Method_StreamingFromClient, serviceImpl == null ? null : new grpc::ClientStreamingServerMethod(serviceImpl.StreamingFromClient)); + serviceBinder.AddMethod(__Method_StreamingFromServer, serviceImpl == null ? null : new grpc::ServerStreamingServerMethod(serviceImpl.StreamingFromServer)); + serviceBinder.AddMethod(__Method_StreamingBothWays, serviceImpl == null ? null : new grpc::DuplexStreamingServerMethod(serviceImpl.StreamingBothWays)); } } diff --git a/src/csharp/Grpc.IntegrationTesting/Control.cs b/src/csharp/Grpc.IntegrationTesting/Control.cs index 368b86659a5..3cac3b9d759 100644 --- a/src/csharp/Grpc.IntegrationTesting/Control.cs +++ b/src/csharp/Grpc.IntegrationTesting/Control.cs @@ -96,12 +96,13 @@ namespace Grpc.Testing { "GAcgAygIEhYKDnNlcnZlcl9zdWNjZXNzGAggAygIEjkKD3JlcXVlc3RfcmVz", "dWx0cxgJIAMoCzIgLmdycGMudGVzdGluZy5SZXF1ZXN0UmVzdWx0Q291bnQq", "VgoKQ2xpZW50VHlwZRIPCgtTWU5DX0NMSUVOVBAAEhAKDEFTWU5DX0NMSUVO", - "VBABEhAKDE9USEVSX0NMSUVOVBACEhMKD0NBTExCQUNLX0NMSUVOVBADKlsK", + "VBABEhAKDE9USEVSX0NMSUVOVBACEhMKD0NBTExCQUNLX0NMSUVOVBADKnAK", "ClNlcnZlclR5cGUSDwoLU1lOQ19TRVJWRVIQABIQCgxBU1lOQ19TRVJWRVIQ", "ARIYChRBU1lOQ19HRU5FUklDX1NFUlZFUhACEhAKDE9USEVSX1NFUlZFUhAD", - "KnIKB1JwY1R5cGUSCQoFVU5BUlkQABINCglTVFJFQU1JTkcQARIZChVTVFJF", - "QU1JTkdfRlJPTV9DTElFTlQQAhIZChVTVFJFQU1JTkdfRlJPTV9TRVJWRVIQ", - "AxIXChNTVFJFQU1JTkdfQk9USF9XQVlTEARiBnByb3RvMw==")); + "EhMKD0NBTExCQUNLX1NFUlZFUhAEKnIKB1JwY1R5cGUSCQoFVU5BUlkQABIN", + "CglTVFJFQU1JTkcQARIZChVTVFJFQU1JTkdfRlJPTV9DTElFTlQQAhIZChVT", + "VFJFQU1JTkdfRlJPTV9TRVJWRVIQAxIXChNTVFJFQU1JTkdfQk9USF9XQVlT", + "EARiBnByb3RvMw==")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { global::Grpc.Testing.PayloadsReflection.Descriptor, global::Grpc.Testing.StatsReflection.Descriptor, }, new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Grpc.Testing.ClientType), typeof(global::Grpc.Testing.ServerType), typeof(global::Grpc.Testing.RpcType), }, new pbr::GeneratedClrTypeInfo[] { @@ -152,6 +153,7 @@ namespace Grpc.Testing { /// used for some language-specific variants /// [pbr::OriginalName("OTHER_SERVER")] OtherServer = 3, + [pbr::OriginalName("CALLBACK_SERVER")] CallbackServer = 4, } public enum RpcType { @@ -1500,7 +1502,7 @@ namespace Grpc.Testing { } if (other.securityParams_ != null) { if (securityParams_ == null) { - securityParams_ = new global::Grpc.Testing.SecurityParams(); + SecurityParams = new global::Grpc.Testing.SecurityParams(); } SecurityParams.MergeFrom(other.SecurityParams); } @@ -1518,19 +1520,19 @@ namespace Grpc.Testing { } if (other.loadParams_ != null) { if (loadParams_ == null) { - loadParams_ = new global::Grpc.Testing.LoadParams(); + LoadParams = new global::Grpc.Testing.LoadParams(); } LoadParams.MergeFrom(other.LoadParams); } if (other.payloadConfig_ != null) { if (payloadConfig_ == null) { - payloadConfig_ = new global::Grpc.Testing.PayloadConfig(); + PayloadConfig = new global::Grpc.Testing.PayloadConfig(); } PayloadConfig.MergeFrom(other.PayloadConfig); } if (other.histogramParams_ != null) { if (histogramParams_ == null) { - histogramParams_ = new global::Grpc.Testing.HistogramParams(); + HistogramParams = new global::Grpc.Testing.HistogramParams(); } HistogramParams.MergeFrom(other.HistogramParams); } @@ -1570,14 +1572,14 @@ namespace Grpc.Testing { break; } case 16: { - clientType_ = (global::Grpc.Testing.ClientType) input.ReadEnum(); + ClientType = (global::Grpc.Testing.ClientType) input.ReadEnum(); break; } case 26: { if (securityParams_ == null) { - securityParams_ = new global::Grpc.Testing.SecurityParams(); + SecurityParams = new global::Grpc.Testing.SecurityParams(); } - input.ReadMessage(securityParams_); + input.ReadMessage(SecurityParams); break; } case 32: { @@ -1593,28 +1595,28 @@ namespace Grpc.Testing { break; } case 64: { - rpcType_ = (global::Grpc.Testing.RpcType) input.ReadEnum(); + RpcType = (global::Grpc.Testing.RpcType) input.ReadEnum(); break; } case 82: { if (loadParams_ == null) { - loadParams_ = new global::Grpc.Testing.LoadParams(); + LoadParams = new global::Grpc.Testing.LoadParams(); } - input.ReadMessage(loadParams_); + input.ReadMessage(LoadParams); break; } case 90: { if (payloadConfig_ == null) { - payloadConfig_ = new global::Grpc.Testing.PayloadConfig(); + PayloadConfig = new global::Grpc.Testing.PayloadConfig(); } - input.ReadMessage(payloadConfig_); + input.ReadMessage(PayloadConfig); break; } case 98: { if (histogramParams_ == null) { - histogramParams_ = new global::Grpc.Testing.HistogramParams(); + HistogramParams = new global::Grpc.Testing.HistogramParams(); } - input.ReadMessage(histogramParams_); + input.ReadMessage(HistogramParams); break; } case 106: @@ -1763,7 +1765,7 @@ namespace Grpc.Testing { } if (other.stats_ != null) { if (stats_ == null) { - stats_ = new global::Grpc.Testing.ClientStats(); + Stats = new global::Grpc.Testing.ClientStats(); } Stats.MergeFrom(other.Stats); } @@ -1780,9 +1782,9 @@ namespace Grpc.Testing { break; case 10: { if (stats_ == null) { - stats_ = new global::Grpc.Testing.ClientStats(); + Stats = new global::Grpc.Testing.ClientStats(); } - input.ReadMessage(stats_); + input.ReadMessage(Stats); break; } } @@ -2465,7 +2467,7 @@ namespace Grpc.Testing { } if (other.securityParams_ != null) { if (securityParams_ == null) { - securityParams_ = new global::Grpc.Testing.SecurityParams(); + SecurityParams = new global::Grpc.Testing.SecurityParams(); } SecurityParams.MergeFrom(other.SecurityParams); } @@ -2480,7 +2482,7 @@ namespace Grpc.Testing { } if (other.payloadConfig_ != null) { if (payloadConfig_ == null) { - payloadConfig_ = new global::Grpc.Testing.PayloadConfig(); + PayloadConfig = new global::Grpc.Testing.PayloadConfig(); } PayloadConfig.MergeFrom(other.PayloadConfig); } @@ -2507,14 +2509,14 @@ namespace Grpc.Testing { _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); break; case 8: { - serverType_ = (global::Grpc.Testing.ServerType) input.ReadEnum(); + ServerType = (global::Grpc.Testing.ServerType) input.ReadEnum(); break; } case 18: { if (securityParams_ == null) { - securityParams_ = new global::Grpc.Testing.SecurityParams(); + SecurityParams = new global::Grpc.Testing.SecurityParams(); } - input.ReadMessage(securityParams_); + input.ReadMessage(SecurityParams); break; } case 32: { @@ -2531,9 +2533,9 @@ namespace Grpc.Testing { } case 74: { if (payloadConfig_ == null) { - payloadConfig_ = new global::Grpc.Testing.PayloadConfig(); + PayloadConfig = new global::Grpc.Testing.PayloadConfig(); } - input.ReadMessage(payloadConfig_); + input.ReadMessage(PayloadConfig); break; } case 82: @@ -2922,7 +2924,7 @@ namespace Grpc.Testing { } if (other.stats_ != null) { if (stats_ == null) { - stats_ = new global::Grpc.Testing.ServerStats(); + Stats = new global::Grpc.Testing.ServerStats(); } Stats.MergeFrom(other.Stats); } @@ -2945,9 +2947,9 @@ namespace Grpc.Testing { break; case 10: { if (stats_ == null) { - stats_ = new global::Grpc.Testing.ServerStats(); + Stats = new global::Grpc.Testing.ServerStats(); } - input.ReadMessage(stats_); + input.ReadMessage(Stats); break; } case 16: { @@ -3582,7 +3584,7 @@ namespace Grpc.Testing { } if (other.clientConfig_ != null) { if (clientConfig_ == null) { - clientConfig_ = new global::Grpc.Testing.ClientConfig(); + ClientConfig = new global::Grpc.Testing.ClientConfig(); } ClientConfig.MergeFrom(other.ClientConfig); } @@ -3591,7 +3593,7 @@ namespace Grpc.Testing { } if (other.serverConfig_ != null) { if (serverConfig_ == null) { - serverConfig_ = new global::Grpc.Testing.ServerConfig(); + ServerConfig = new global::Grpc.Testing.ServerConfig(); } ServerConfig.MergeFrom(other.ServerConfig); } @@ -3624,9 +3626,9 @@ namespace Grpc.Testing { } case 18: { if (clientConfig_ == null) { - clientConfig_ = new global::Grpc.Testing.ClientConfig(); + ClientConfig = new global::Grpc.Testing.ClientConfig(); } - input.ReadMessage(clientConfig_); + input.ReadMessage(ClientConfig); break; } case 24: { @@ -3635,9 +3637,9 @@ namespace Grpc.Testing { } case 34: { if (serverConfig_ == null) { - serverConfig_ = new global::Grpc.Testing.ServerConfig(); + ServerConfig = new global::Grpc.Testing.ServerConfig(); } - input.ReadMessage(serverConfig_); + input.ReadMessage(ServerConfig); break; } case 40: { @@ -4694,13 +4696,13 @@ namespace Grpc.Testing { } if (other.scenario_ != null) { if (scenario_ == null) { - scenario_ = new global::Grpc.Testing.Scenario(); + Scenario = new global::Grpc.Testing.Scenario(); } Scenario.MergeFrom(other.Scenario); } if (other.latencies_ != null) { if (latencies_ == null) { - latencies_ = new global::Grpc.Testing.HistogramData(); + Latencies = new global::Grpc.Testing.HistogramData(); } Latencies.MergeFrom(other.Latencies); } @@ -4709,7 +4711,7 @@ namespace Grpc.Testing { serverCores_.Add(other.serverCores_); if (other.summary_ != null) { if (summary_ == null) { - summary_ = new global::Grpc.Testing.ScenarioResultSummary(); + Summary = new global::Grpc.Testing.ScenarioResultSummary(); } Summary.MergeFrom(other.Summary); } @@ -4729,16 +4731,16 @@ namespace Grpc.Testing { break; case 10: { if (scenario_ == null) { - scenario_ = new global::Grpc.Testing.Scenario(); + Scenario = new global::Grpc.Testing.Scenario(); } - input.ReadMessage(scenario_); + input.ReadMessage(Scenario); break; } case 18: { if (latencies_ == null) { - latencies_ = new global::Grpc.Testing.HistogramData(); + Latencies = new global::Grpc.Testing.HistogramData(); } - input.ReadMessage(latencies_); + input.ReadMessage(Latencies); break; } case 26: { @@ -4756,9 +4758,9 @@ namespace Grpc.Testing { } case 50: { if (summary_ == null) { - summary_ = new global::Grpc.Testing.ScenarioResultSummary(); + Summary = new global::Grpc.Testing.ScenarioResultSummary(); } - input.ReadMessage(summary_); + input.ReadMessage(Summary); break; } case 58: diff --git a/src/csharp/Grpc.IntegrationTesting/EchoMessages.cs b/src/csharp/Grpc.IntegrationTesting/EchoMessages.cs index 80a1007e9a5..e5af4a93e99 100644 --- a/src/csharp/Grpc.IntegrationTesting/EchoMessages.cs +++ b/src/csharp/Grpc.IntegrationTesting/EchoMessages.cs @@ -864,7 +864,7 @@ namespace Grpc.Testing { } if (other.debugInfo_ != null) { if (debugInfo_ == null) { - debugInfo_ = new global::Grpc.Testing.DebugInfo(); + DebugInfo = new global::Grpc.Testing.DebugInfo(); } DebugInfo.MergeFrom(other.DebugInfo); } @@ -876,7 +876,7 @@ namespace Grpc.Testing { } if (other.expectedError_ != null) { if (expectedError_ == null) { - expectedError_ = new global::Grpc.Testing.ErrorStatus(); + ExpectedError = new global::Grpc.Testing.ErrorStatus(); } ExpectedError.MergeFrom(other.ExpectedError); } @@ -939,9 +939,9 @@ namespace Grpc.Testing { } case 90: { if (debugInfo_ == null) { - debugInfo_ = new global::Grpc.Testing.DebugInfo(); + DebugInfo = new global::Grpc.Testing.DebugInfo(); } - input.ReadMessage(debugInfo_); + input.ReadMessage(DebugInfo); break; } case 96: { @@ -954,9 +954,9 @@ namespace Grpc.Testing { } case 114: { if (expectedError_ == null) { - expectedError_ = new global::Grpc.Testing.ErrorStatus(); + ExpectedError = new global::Grpc.Testing.ErrorStatus(); } - input.ReadMessage(expectedError_); + input.ReadMessage(ExpectedError); break; } case 120: { @@ -1104,7 +1104,7 @@ namespace Grpc.Testing { } if (other.param_ != null) { if (param_ == null) { - param_ = new global::Grpc.Testing.RequestParams(); + Param = new global::Grpc.Testing.RequestParams(); } Param.MergeFrom(other.Param); } @@ -1125,9 +1125,9 @@ namespace Grpc.Testing { } case 18: { if (param_ == null) { - param_ = new global::Grpc.Testing.RequestParams(); + Param = new global::Grpc.Testing.RequestParams(); } - input.ReadMessage(param_); + input.ReadMessage(Param); break; } } @@ -1452,7 +1452,7 @@ namespace Grpc.Testing { } if (other.param_ != null) { if (param_ == null) { - param_ = new global::Grpc.Testing.ResponseParams(); + Param = new global::Grpc.Testing.ResponseParams(); } Param.MergeFrom(other.Param); } @@ -1473,9 +1473,9 @@ namespace Grpc.Testing { } case 18: { if (param_ == null) { - param_ = new global::Grpc.Testing.ResponseParams(); + Param = new global::Grpc.Testing.ResponseParams(); } - input.ReadMessage(param_); + input.ReadMessage(Param); break; } } diff --git a/src/csharp/Grpc.IntegrationTesting/EmptyServiceGrpc.cs b/src/csharp/Grpc.IntegrationTesting/EmptyServiceGrpc.cs index 7e77f8d1141..50c6e159206 100644 --- a/src/csharp/Grpc.IntegrationTesting/EmptyServiceGrpc.cs +++ b/src/csharp/Grpc.IntegrationTesting/EmptyServiceGrpc.cs @@ -39,6 +39,7 @@ namespace Grpc.Testing { } /// Base class for server-side implementations of EmptyService + [grpc::BindServiceMethod(typeof(EmptyService), "BindService")] public abstract partial class EmptyServiceBase { } @@ -80,7 +81,7 @@ namespace Grpc.Testing { return grpc::ServerServiceDefinition.CreateBuilder().Build(); } - /// Register service method implementations with a service binder. Useful when customizing the service binding logic. + /// Register service method with a service binder with or without implementation. Useful when customizing the service binding logic. /// Note: this method is part of an experimental API that can change or be removed without any prior notice. /// Service methods will be bound by calling AddMethod on this object. /// An object implementing the server-side handling logic. diff --git a/src/csharp/Grpc.IntegrationTesting/ExternalDnsClientServerTest.cs b/src/csharp/Grpc.IntegrationTesting/ExternalDnsClientServerTest.cs new file mode 100644 index 00000000000..1360d2506bb --- /dev/null +++ b/src/csharp/Grpc.IntegrationTesting/ExternalDnsClientServerTest.cs @@ -0,0 +1,74 @@ +#region Copyright notice and license + +// Copyright 2019 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. +// 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.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Grpc.Core; +using Grpc.Core.Utils; +using Grpc.Testing; +using NUnit.Framework; + +namespace Grpc.IntegrationTesting +{ + /// + /// Runs interop tests in-process, with that client using a target + /// name that using a target name that triggers interaction with + /// external DNS servers (even though it resolves to the in-proc server). + /// This test is a trimmed-down sibling test to the one in + /// "ExternalDnsWithTracingClientServerTest", and is meant mostly for + /// comparison with that one. + /// + public class ExternalDnsClientServerTest + { + Server server; + Channel channel; + TestService.TestServiceClient client; + + [OneTimeSetUp] + public void Init() + { + // Disable SO_REUSEPORT to prevent https://github.com/grpc/grpc/issues/10755 + server = new Server(new[] { new ChannelOption(ChannelOptions.SoReuseport, 0) }) + { + Services = { TestService.BindService(new TestServiceImpl()) }, + Ports = { { "[::1]", ServerPort.PickUnused, ServerCredentials.Insecure } } + }; + server.Start(); + + int port = server.Ports.Single().BoundPort; + channel = new Channel("loopback6.unittest.grpc.io", port, ChannelCredentials.Insecure); + client = new TestService.TestServiceClient(channel); + } + + [OneTimeTearDown] + public void Cleanup() + { + channel.ShutdownAsync().Wait(); + server.ShutdownAsync().Wait(); + } + + [Test] + public void EmptyUnary() + { + InteropClient.RunEmptyUnary(client); + } + } +} diff --git a/src/csharp/Grpc.IntegrationTesting/ExternalDnsWithTracingClientServerTest.cs b/src/csharp/Grpc.IntegrationTesting/ExternalDnsWithTracingClientServerTest.cs new file mode 100644 index 00000000000..f9fdcc3f9c9 --- /dev/null +++ b/src/csharp/Grpc.IntegrationTesting/ExternalDnsWithTracingClientServerTest.cs @@ -0,0 +1,167 @@ +#region Copyright notice and license + +// Copyright 2019 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. +// 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.Collections.Generic; +using System.Net.Sockets; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Grpc.Core; +using Grpc.Core.Logging; +using Grpc.Core.Utils; +using Grpc.Testing; +using NUnit.Framework; + +namespace Grpc.IntegrationTesting +{ + /// + /// See https://github.com/grpc/issues/18074, this test is meant to + /// try to trigger the described bug. + /// Runs interop tests in-process, with that client using a target + /// name that using a target name that triggers interaction with + /// external DNS servers (even though it resolves to the in-proc server). + /// + public class ExternalDnsWithTracingClientServerTest + { + Server server; + Channel channel; + TestService.TestServiceClient client; + SocketUsingLogger newLogger; + + [OneTimeSetUp] + public void Init() + { + // TODO(https://github.com/grpc/grpc/issues/14963): on linux, setting + // these environment variables might not actually have any affect. + // This is OK because we only really care about running this test on + // Windows, however, a fix made for $14963 should be applied here. + Environment.SetEnvironmentVariable("GRPC_TRACE", "all"); + Environment.SetEnvironmentVariable("GRPC_VERBOSITY", "DEBUG"); + newLogger = new SocketUsingLogger(GrpcEnvironment.Logger); + GrpcEnvironment.SetLogger(newLogger); + // Disable SO_REUSEPORT to prevent https://github.com/grpc/grpc/issues/10755 + server = new Server(new[] { new ChannelOption(ChannelOptions.SoReuseport, 0) }) + { + Services = { TestService.BindService(new TestServiceImpl()) }, + Ports = { { "[::1]", ServerPort.PickUnused, ServerCredentials.Insecure } } + }; + server.Start(); + + int port = server.Ports.Single().BoundPort; + channel = new Channel("loopback6.unittest.grpc.io", port, ChannelCredentials.Insecure); + client = new TestService.TestServiceClient(channel); + } + + [OneTimeTearDown] + public void Cleanup() + { + channel.ShutdownAsync().Wait(); + server.ShutdownAsync().Wait(); + } + + [Test] + public void EmptyUnary() + { + InteropClient.RunEmptyUnary(client); + } + } + + /// + /// Logger which does some socket operation after delegating + /// actual logging to its delegate logger. The main goal is to + /// reset the current thread's WSA error status. + /// The only reason for the delegateLogger is to continue + /// to have this test display debug logs. + /// + internal sealed class SocketUsingLogger : ILogger + { + private ILogger delegateLogger; + + public SocketUsingLogger(ILogger delegateLogger) { + this.delegateLogger = delegateLogger; + } + + public void Debug(string message) + { + MyLog(() => delegateLogger.Debug(message)); + } + + public void Debug(string format, params object[] formatArgs) + { + MyLog(() => delegateLogger.Debug(format, formatArgs)); + } + + public void Error(string message) + { + MyLog(() => delegateLogger.Error(message)); + } + + public void Error(Exception exception, string message) + { + MyLog(() => delegateLogger.Error(exception, message)); + } + + public void Error(string format, params object[] formatArgs) + { + MyLog(() => delegateLogger.Error(format, formatArgs)); + } + + public ILogger ForType() + { + return this; + } + + public void Info(string message) + { + MyLog(() => delegateLogger.Info(message)); + } + + public void Info(string format, params object[] formatArgs) + { + MyLog(() => delegateLogger.Info(format, formatArgs)); + } + + public void Warning(string message) + { + MyLog(() => delegateLogger.Warning(message)); + } + + public void Warning(Exception exception, string message) + { + MyLog(() => delegateLogger.Warning(exception, message)); + } + + public void Warning(string format, params object[] formatArgs) + { + MyLog(() => delegateLogger.Warning(format, formatArgs)); + } + + private void MyLog(Action delegateLog) + { + delegateLog(); + // Create and close a socket, just in order to affect + // the WSA (on Windows) error status of the current thread. + Socket s = new Socket(AddressFamily.InterNetwork, + SocketType.Stream, + ProtocolType.Tcp); + + s.Dispose(); + } + } +} diff --git a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj index 8daf3fa98bb..9d719896fc1 100755 --- a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj +++ b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj @@ -1,13 +1,10 @@  - - net45;netcoreapp1.0 - Grpc.IntegrationTesting + net45;netcoreapp2.1 Exe - Grpc.IntegrationTesting true @@ -29,7 +26,7 @@ - + diff --git a/src/csharp/Grpc.IntegrationTesting/InteropClient.cs b/src/csharp/Grpc.IntegrationTesting/InteropClient.cs index e83a8a7274a..47503530820 100644 --- a/src/csharp/Grpc.IntegrationTesting/InteropClient.cs +++ b/src/csharp/Grpc.IntegrationTesting/InteropClient.cs @@ -45,7 +45,7 @@ namespace Grpc.IntegrationTesting [Option("server_host", Default = "localhost")] public string ServerHost { get; set; } - [Option("server_host_override", Default = TestCredentials.DefaultHostOverride)] + [Option("server_host_override")] public string ServerHostOverride { get; set; } [Option("server_port", Required = true)] diff --git a/src/csharp/Grpc.IntegrationTesting/Messages.cs b/src/csharp/Grpc.IntegrationTesting/Messages.cs index 35546f1b671..3b6c0010222 100644 --- a/src/csharp/Grpc.IntegrationTesting/Messages.cs +++ b/src/csharp/Grpc.IntegrationTesting/Messages.cs @@ -379,7 +379,7 @@ namespace Grpc.Testing { _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); break; case 8: { - type_ = (global::Grpc.Testing.PayloadType) input.ReadEnum(); + Type = (global::Grpc.Testing.PayloadType) input.ReadEnum(); break; } case 18: { @@ -844,7 +844,7 @@ namespace Grpc.Testing { } if (other.payload_ != null) { if (payload_ == null) { - payload_ = new global::Grpc.Testing.Payload(); + Payload = new global::Grpc.Testing.Payload(); } Payload.MergeFrom(other.Payload); } @@ -856,19 +856,19 @@ namespace Grpc.Testing { } if (other.responseCompressed_ != null) { if (responseCompressed_ == null) { - responseCompressed_ = new global::Grpc.Testing.BoolValue(); + ResponseCompressed = new global::Grpc.Testing.BoolValue(); } ResponseCompressed.MergeFrom(other.ResponseCompressed); } if (other.responseStatus_ != null) { if (responseStatus_ == null) { - responseStatus_ = new global::Grpc.Testing.EchoStatus(); + ResponseStatus = new global::Grpc.Testing.EchoStatus(); } ResponseStatus.MergeFrom(other.ResponseStatus); } if (other.expectCompressed_ != null) { if (expectCompressed_ == null) { - expectCompressed_ = new global::Grpc.Testing.BoolValue(); + ExpectCompressed = new global::Grpc.Testing.BoolValue(); } ExpectCompressed.MergeFrom(other.ExpectCompressed); } @@ -884,7 +884,7 @@ namespace Grpc.Testing { _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); break; case 8: { - responseType_ = (global::Grpc.Testing.PayloadType) input.ReadEnum(); + ResponseType = (global::Grpc.Testing.PayloadType) input.ReadEnum(); break; } case 16: { @@ -893,9 +893,9 @@ namespace Grpc.Testing { } case 26: { if (payload_ == null) { - payload_ = new global::Grpc.Testing.Payload(); + Payload = new global::Grpc.Testing.Payload(); } - input.ReadMessage(payload_); + input.ReadMessage(Payload); break; } case 32: { @@ -908,23 +908,23 @@ namespace Grpc.Testing { } case 50: { if (responseCompressed_ == null) { - responseCompressed_ = new global::Grpc.Testing.BoolValue(); + ResponseCompressed = new global::Grpc.Testing.BoolValue(); } - input.ReadMessage(responseCompressed_); + input.ReadMessage(ResponseCompressed); break; } case 58: { if (responseStatus_ == null) { - responseStatus_ = new global::Grpc.Testing.EchoStatus(); + ResponseStatus = new global::Grpc.Testing.EchoStatus(); } - input.ReadMessage(responseStatus_); + input.ReadMessage(ResponseStatus); break; } case 66: { if (expectCompressed_ == null) { - expectCompressed_ = new global::Grpc.Testing.BoolValue(); + ExpectCompressed = new global::Grpc.Testing.BoolValue(); } - input.ReadMessage(expectCompressed_); + input.ReadMessage(ExpectCompressed); break; } } @@ -1095,7 +1095,7 @@ namespace Grpc.Testing { } if (other.payload_ != null) { if (payload_ == null) { - payload_ = new global::Grpc.Testing.Payload(); + Payload = new global::Grpc.Testing.Payload(); } Payload.MergeFrom(other.Payload); } @@ -1118,9 +1118,9 @@ namespace Grpc.Testing { break; case 10: { if (payload_ == null) { - payload_ = new global::Grpc.Testing.Payload(); + Payload = new global::Grpc.Testing.Payload(); } - input.ReadMessage(payload_); + input.ReadMessage(Payload); break; } case 18: { @@ -1277,13 +1277,13 @@ namespace Grpc.Testing { } if (other.payload_ != null) { if (payload_ == null) { - payload_ = new global::Grpc.Testing.Payload(); + Payload = new global::Grpc.Testing.Payload(); } Payload.MergeFrom(other.Payload); } if (other.expectCompressed_ != null) { if (expectCompressed_ == null) { - expectCompressed_ = new global::Grpc.Testing.BoolValue(); + ExpectCompressed = new global::Grpc.Testing.BoolValue(); } ExpectCompressed.MergeFrom(other.ExpectCompressed); } @@ -1300,16 +1300,16 @@ namespace Grpc.Testing { break; case 10: { if (payload_ == null) { - payload_ = new global::Grpc.Testing.Payload(); + Payload = new global::Grpc.Testing.Payload(); } - input.ReadMessage(payload_); + input.ReadMessage(Payload); break; } case 18: { if (expectCompressed_ == null) { - expectCompressed_ = new global::Grpc.Testing.BoolValue(); + ExpectCompressed = new global::Grpc.Testing.BoolValue(); } - input.ReadMessage(expectCompressed_); + input.ReadMessage(ExpectCompressed); break; } } @@ -1624,7 +1624,7 @@ namespace Grpc.Testing { } if (other.compressed_ != null) { if (compressed_ == null) { - compressed_ = new global::Grpc.Testing.BoolValue(); + Compressed = new global::Grpc.Testing.BoolValue(); } Compressed.MergeFrom(other.Compressed); } @@ -1649,9 +1649,9 @@ namespace Grpc.Testing { } case 26: { if (compressed_ == null) { - compressed_ = new global::Grpc.Testing.BoolValue(); + Compressed = new global::Grpc.Testing.BoolValue(); } - input.ReadMessage(compressed_); + input.ReadMessage(Compressed); break; } } @@ -1846,13 +1846,13 @@ namespace Grpc.Testing { responseParameters_.Add(other.responseParameters_); if (other.payload_ != null) { if (payload_ == null) { - payload_ = new global::Grpc.Testing.Payload(); + Payload = new global::Grpc.Testing.Payload(); } Payload.MergeFrom(other.Payload); } if (other.responseStatus_ != null) { if (responseStatus_ == null) { - responseStatus_ = new global::Grpc.Testing.EchoStatus(); + ResponseStatus = new global::Grpc.Testing.EchoStatus(); } ResponseStatus.MergeFrom(other.ResponseStatus); } @@ -1868,7 +1868,7 @@ namespace Grpc.Testing { _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); break; case 8: { - responseType_ = (global::Grpc.Testing.PayloadType) input.ReadEnum(); + ResponseType = (global::Grpc.Testing.PayloadType) input.ReadEnum(); break; } case 18: { @@ -1877,16 +1877,16 @@ namespace Grpc.Testing { } case 26: { if (payload_ == null) { - payload_ = new global::Grpc.Testing.Payload(); + Payload = new global::Grpc.Testing.Payload(); } - input.ReadMessage(payload_); + input.ReadMessage(Payload); break; } case 58: { if (responseStatus_ == null) { - responseStatus_ = new global::Grpc.Testing.EchoStatus(); + ResponseStatus = new global::Grpc.Testing.EchoStatus(); } - input.ReadMessage(responseStatus_); + input.ReadMessage(ResponseStatus); break; } } @@ -2008,7 +2008,7 @@ namespace Grpc.Testing { } if (other.payload_ != null) { if (payload_ == null) { - payload_ = new global::Grpc.Testing.Payload(); + Payload = new global::Grpc.Testing.Payload(); } Payload.MergeFrom(other.Payload); } @@ -2025,9 +2025,9 @@ namespace Grpc.Testing { break; case 10: { if (payload_ == null) { - payload_ = new global::Grpc.Testing.Payload(); + Payload = new global::Grpc.Testing.Payload(); } - input.ReadMessage(payload_); + input.ReadMessage(Payload); break; } } diff --git a/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs b/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs index c66a9a9161e..9b11e990d2d 100644 --- a/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs +++ b/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs @@ -58,6 +58,7 @@ namespace Grpc.Testing { } /// Base class for server-side implementations of MetricsService + [grpc::BindServiceMethod(typeof(MetricsService), "BindService")] public abstract partial class MetricsServiceBase { /// @@ -193,14 +194,14 @@ namespace Grpc.Testing { .AddMethod(__Method_GetGauge, serviceImpl.GetGauge).Build(); } - /// Register service method implementations with a service binder. Useful when customizing the service binding logic. + /// Register service method with a service binder with or without implementation. Useful when customizing the service binding logic. /// Note: this method is part of an experimental API that can change or be removed without any prior notice. /// Service methods will be bound by calling AddMethod on this object. /// An object implementing the server-side handling logic. public static void BindService(grpc::ServiceBinderBase serviceBinder, MetricsServiceBase serviceImpl) { - serviceBinder.AddMethod(__Method_GetAllGauges, serviceImpl.GetAllGauges); - serviceBinder.AddMethod(__Method_GetGauge, serviceImpl.GetGauge); + serviceBinder.AddMethod(__Method_GetAllGauges, serviceImpl == null ? null : new grpc::ServerStreamingServerMethod(serviceImpl.GetAllGauges)); + serviceBinder.AddMethod(__Method_GetGauge, serviceImpl == null ? null : new grpc::UnaryServerMethod(serviceImpl.GetGauge)); } } diff --git a/src/csharp/Grpc.IntegrationTesting/NUnitMain.cs b/src/csharp/Grpc.IntegrationTesting/NUnitMain.cs index 9d24762e0ae..4135186275d 100644 --- a/src/csharp/Grpc.IntegrationTesting/NUnitMain.cs +++ b/src/csharp/Grpc.IntegrationTesting/NUnitMain.cs @@ -34,11 +34,7 @@ namespace Grpc.IntegrationTesting { // Make logger immune to NUnit capturing stdout and stderr to workaround https://github.com/nunit/nunit/issues/1406. GrpcEnvironment.SetLogger(new ConsoleLogger()); -#if NETCOREAPP1_0 - return new AutoRun(typeof(NUnitMain).GetTypeInfo().Assembly).Execute(args, new ExtendedTextWrapper(Console.Out), Console.In); -#else - return new AutoRun().Execute(args); -#endif + return new AutoRun(typeof(NUnitMain).GetTypeInfo().Assembly).Execute(args); } } } diff --git a/src/csharp/Grpc.IntegrationTesting/ReportQpsScenarioServiceGrpc.cs b/src/csharp/Grpc.IntegrationTesting/ReportQpsScenarioServiceGrpc.cs index 954c1722723..1a505ebc764 100644 --- a/src/csharp/Grpc.IntegrationTesting/ReportQpsScenarioServiceGrpc.cs +++ b/src/csharp/Grpc.IntegrationTesting/ReportQpsScenarioServiceGrpc.cs @@ -46,6 +46,7 @@ namespace Grpc.Testing { } /// Base class for server-side implementations of ReportQpsScenarioService + [grpc::BindServiceMethod(typeof(ReportQpsScenarioService), "BindService")] public abstract partial class ReportQpsScenarioServiceBase { /// @@ -143,13 +144,13 @@ namespace Grpc.Testing { .AddMethod(__Method_ReportScenario, serviceImpl.ReportScenario).Build(); } - /// Register service method implementations with a service binder. Useful when customizing the service binding logic. + /// Register service method with a service binder with or without implementation. Useful when customizing the service binding logic. /// Note: this method is part of an experimental API that can change or be removed without any prior notice. /// Service methods will be bound by calling AddMethod on this object. /// An object implementing the server-side handling logic. public static void BindService(grpc::ServiceBinderBase serviceBinder, ReportQpsScenarioServiceBase serviceImpl) { - serviceBinder.AddMethod(__Method_ReportScenario, serviceImpl.ReportScenario); + serviceBinder.AddMethod(__Method_ReportScenario, serviceImpl == null ? null : new grpc::UnaryServerMethod(serviceImpl.ReportScenario)); } } diff --git a/src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs b/src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs index b3c47c2d8d3..4c1189320fa 100644 --- a/src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs +++ b/src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs @@ -46,7 +46,8 @@ namespace Grpc.IntegrationTesting KeyCertificatePair keyCertPair; public void InitClientAndServer(bool clientAddKeyCertPair, - SslClientCertificateRequestType clientCertRequestType) + SslClientCertificateRequestType clientCertRequestType, + VerifyPeerCallback verifyPeerCallback = null) { rootCert = File.ReadAllText(TestCredentials.ClientCertAuthorityPath); keyCertPair = new KeyCertificatePair( @@ -54,7 +55,7 @@ namespace Grpc.IntegrationTesting File.ReadAllText(TestCredentials.ServerPrivateKeyPath)); var serverCredentials = new SslServerCredentials(new[] { keyCertPair }, rootCert, clientCertRequestType); - var clientCredentials = clientAddKeyCertPair ? new SslCredentials(rootCert, keyCertPair) : new SslCredentials(rootCert); + var clientCredentials = new SslCredentials(rootCert, clientAddKeyCertPair ? keyCertPair : null, verifyPeerCallback); // Disable SO_REUSEPORT to prevent https://github.com/grpc/grpc/issues/10755 server = new Server(new[] { new ChannelOption(ChannelOptions.SoReuseport, 0) }) @@ -188,6 +189,52 @@ namespace Grpc.IntegrationTesting Assert.Throws(typeof(ArgumentNullException), () => new SslServerCredentials(keyCertPairs, null, SslClientCertificateRequestType.RequestAndRequireAndVerify)); } + [Test] + public async Task VerifyPeerCallback_Accepted() + { + string targetNameFromCallback = null; + string peerPemFromCallback = null; + InitClientAndServer( + clientAddKeyCertPair: false, + clientCertRequestType: SslClientCertificateRequestType.DontRequest, + verifyPeerCallback: (ctx) => + { + targetNameFromCallback = ctx.TargetName; + peerPemFromCallback = ctx.PeerPem; + return true; + }); + await CheckAccepted(expectPeerAuthenticated: false); + Assert.AreEqual(TestCredentials.DefaultHostOverride, targetNameFromCallback); + var expectedServerPem = File.ReadAllText(TestCredentials.ServerCertChainPath).Replace("\r", ""); + Assert.AreEqual(expectedServerPem, peerPemFromCallback); + } + + [Test] + public void VerifyPeerCallback_CallbackThrows_Rejected() + { + InitClientAndServer( + clientAddKeyCertPair: false, + clientCertRequestType: SslClientCertificateRequestType.DontRequest, + verifyPeerCallback: (ctx) => + { + throw new Exception("VerifyPeerCallback has thrown on purpose."); + }); + CheckRejected(); + } + + [Test] + public void VerifyPeerCallback_Rejected() + { + InitClientAndServer( + clientAddKeyCertPair: false, + clientCertRequestType: SslClientCertificateRequestType.DontRequest, + verifyPeerCallback: (ctx) => + { + return false; + }); + CheckRejected(); + } + private async Task CheckAccepted(bool expectPeerAuthenticated) { var call = client.UnaryCallAsync(new SimpleRequest { ResponseSize = 10 }); diff --git a/src/csharp/Grpc.IntegrationTesting/Stats.cs b/src/csharp/Grpc.IntegrationTesting/Stats.cs index af83eef7ba8..c3e5664e11a 100644 --- a/src/csharp/Grpc.IntegrationTesting/Stats.cs +++ b/src/csharp/Grpc.IntegrationTesting/Stats.cs @@ -328,7 +328,7 @@ namespace Grpc.Testing { } if (other.coreStats_ != null) { if (coreStats_ == null) { - coreStats_ = new global::Grpc.Core.Stats(); + CoreStats = new global::Grpc.Core.Stats(); } CoreStats.MergeFrom(other.CoreStats); } @@ -369,9 +369,9 @@ namespace Grpc.Testing { } case 58: { if (coreStats_ == null) { - coreStats_ = new global::Grpc.Core.Stats(); + CoreStats = new global::Grpc.Core.Stats(); } - input.ReadMessage(coreStats_); + input.ReadMessage(CoreStats); break; } } @@ -1210,7 +1210,7 @@ namespace Grpc.Testing { } if (other.latencies_ != null) { if (latencies_ == null) { - latencies_ = new global::Grpc.Testing.HistogramData(); + Latencies = new global::Grpc.Testing.HistogramData(); } Latencies.MergeFrom(other.Latencies); } @@ -1229,7 +1229,7 @@ namespace Grpc.Testing { } if (other.coreStats_ != null) { if (coreStats_ == null) { - coreStats_ = new global::Grpc.Core.Stats(); + CoreStats = new global::Grpc.Core.Stats(); } CoreStats.MergeFrom(other.CoreStats); } @@ -1246,9 +1246,9 @@ namespace Grpc.Testing { break; case 10: { if (latencies_ == null) { - latencies_ = new global::Grpc.Testing.HistogramData(); + Latencies = new global::Grpc.Testing.HistogramData(); } - input.ReadMessage(latencies_); + input.ReadMessage(Latencies); break; } case 17: { @@ -1273,9 +1273,9 @@ namespace Grpc.Testing { } case 58: { if (coreStats_ == null) { - coreStats_ = new global::Grpc.Core.Stats(); + CoreStats = new global::Grpc.Core.Stats(); } - input.ReadMessage(coreStats_); + input.ReadMessage(CoreStats); break; } } diff --git a/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs b/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs index d125fd5627b..e7b93094c65 100644 --- a/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs +++ b/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs @@ -105,6 +105,7 @@ namespace Grpc.Testing { } /// Base class for server-side implementations of TestService + [grpc::BindServiceMethod(typeof(TestService), "BindService")] public abstract partial class TestServiceBase { /// @@ -539,20 +540,20 @@ namespace Grpc.Testing { .AddMethod(__Method_UnimplementedCall, serviceImpl.UnimplementedCall).Build(); } - /// Register service method implementations with a service binder. Useful when customizing the service binding logic. + /// Register service method with a service binder with or without implementation. Useful when customizing the service binding logic. /// Note: this method is part of an experimental API that can change or be removed without any prior notice. /// Service methods will be bound by calling AddMethod on this object. /// An object implementing the server-side handling logic. public static void BindService(grpc::ServiceBinderBase serviceBinder, TestServiceBase serviceImpl) { - serviceBinder.AddMethod(__Method_EmptyCall, serviceImpl.EmptyCall); - serviceBinder.AddMethod(__Method_UnaryCall, serviceImpl.UnaryCall); - serviceBinder.AddMethod(__Method_CacheableUnaryCall, serviceImpl.CacheableUnaryCall); - serviceBinder.AddMethod(__Method_StreamingOutputCall, serviceImpl.StreamingOutputCall); - serviceBinder.AddMethod(__Method_StreamingInputCall, serviceImpl.StreamingInputCall); - serviceBinder.AddMethod(__Method_FullDuplexCall, serviceImpl.FullDuplexCall); - serviceBinder.AddMethod(__Method_HalfDuplexCall, serviceImpl.HalfDuplexCall); - serviceBinder.AddMethod(__Method_UnimplementedCall, serviceImpl.UnimplementedCall); + serviceBinder.AddMethod(__Method_EmptyCall, serviceImpl == null ? null : new grpc::UnaryServerMethod(serviceImpl.EmptyCall)); + serviceBinder.AddMethod(__Method_UnaryCall, serviceImpl == null ? null : new grpc::UnaryServerMethod(serviceImpl.UnaryCall)); + serviceBinder.AddMethod(__Method_CacheableUnaryCall, serviceImpl == null ? null : new grpc::UnaryServerMethod(serviceImpl.CacheableUnaryCall)); + serviceBinder.AddMethod(__Method_StreamingOutputCall, serviceImpl == null ? null : new grpc::ServerStreamingServerMethod(serviceImpl.StreamingOutputCall)); + serviceBinder.AddMethod(__Method_StreamingInputCall, serviceImpl == null ? null : new grpc::ClientStreamingServerMethod(serviceImpl.StreamingInputCall)); + serviceBinder.AddMethod(__Method_FullDuplexCall, serviceImpl == null ? null : new grpc::DuplexStreamingServerMethod(serviceImpl.FullDuplexCall)); + serviceBinder.AddMethod(__Method_HalfDuplexCall, serviceImpl == null ? null : new grpc::DuplexStreamingServerMethod(serviceImpl.HalfDuplexCall)); + serviceBinder.AddMethod(__Method_UnimplementedCall, serviceImpl == null ? null : new grpc::UnaryServerMethod(serviceImpl.UnimplementedCall)); } } @@ -580,6 +581,7 @@ namespace Grpc.Testing { } /// Base class for server-side implementations of UnimplementedService + [grpc::BindServiceMethod(typeof(UnimplementedService), "BindService")] public abstract partial class UnimplementedServiceBase { /// @@ -677,13 +679,13 @@ namespace Grpc.Testing { .AddMethod(__Method_UnimplementedCall, serviceImpl.UnimplementedCall).Build(); } - /// Register service method implementations with a service binder. Useful when customizing the service binding logic. + /// Register service method with a service binder with or without implementation. Useful when customizing the service binding logic. /// Note: this method is part of an experimental API that can change or be removed without any prior notice. /// Service methods will be bound by calling AddMethod on this object. /// An object implementing the server-side handling logic. public static void BindService(grpc::ServiceBinderBase serviceBinder, UnimplementedServiceBase serviceImpl) { - serviceBinder.AddMethod(__Method_UnimplementedCall, serviceImpl.UnimplementedCall); + serviceBinder.AddMethod(__Method_UnimplementedCall, serviceImpl == null ? null : new grpc::UnaryServerMethod(serviceImpl.UnimplementedCall)); } } @@ -719,6 +721,7 @@ namespace Grpc.Testing { } /// Base class for server-side implementations of ReconnectService + [grpc::BindServiceMethod(typeof(ReconnectService), "BindService")] public abstract partial class ReconnectServiceBase { public virtual global::System.Threading.Tasks.Task Start(global::Grpc.Testing.ReconnectParams request, grpc::ServerCallContext context) @@ -804,14 +807,14 @@ namespace Grpc.Testing { .AddMethod(__Method_Stop, serviceImpl.Stop).Build(); } - /// Register service method implementations with a service binder. Useful when customizing the service binding logic. + /// Register service method with a service binder with or without implementation. Useful when customizing the service binding logic. /// Note: this method is part of an experimental API that can change or be removed without any prior notice. /// Service methods will be bound by calling AddMethod on this object. /// An object implementing the server-side handling logic. public static void BindService(grpc::ServiceBinderBase serviceBinder, ReconnectServiceBase serviceImpl) { - serviceBinder.AddMethod(__Method_Start, serviceImpl.Start); - serviceBinder.AddMethod(__Method_Stop, serviceImpl.Stop); + serviceBinder.AddMethod(__Method_Start, serviceImpl == null ? null : new grpc::UnaryServerMethod(serviceImpl.Start)); + serviceBinder.AddMethod(__Method_Stop, serviceImpl == null ? null : new grpc::UnaryServerMethod(serviceImpl.Stop)); } } diff --git a/src/csharp/Grpc.IntegrationTesting/WorkerServiceGrpc.cs b/src/csharp/Grpc.IntegrationTesting/WorkerServiceGrpc.cs index 5b22337d533..14c26f99a6b 100644 --- a/src/csharp/Grpc.IntegrationTesting/WorkerServiceGrpc.cs +++ b/src/csharp/Grpc.IntegrationTesting/WorkerServiceGrpc.cs @@ -72,6 +72,7 @@ namespace Grpc.Testing { } /// Base class for server-side implementations of WorkerService + [grpc::BindServiceMethod(typeof(WorkerService), "BindService")] public abstract partial class WorkerServiceBase { /// @@ -321,16 +322,16 @@ namespace Grpc.Testing { .AddMethod(__Method_QuitWorker, serviceImpl.QuitWorker).Build(); } - /// Register service method implementations with a service binder. Useful when customizing the service binding logic. + /// Register service method with a service binder with or without implementation. Useful when customizing the service binding logic. /// Note: this method is part of an experimental API that can change or be removed without any prior notice. /// Service methods will be bound by calling AddMethod on this object. /// An object implementing the server-side handling logic. public static void BindService(grpc::ServiceBinderBase serviceBinder, WorkerServiceBase serviceImpl) { - serviceBinder.AddMethod(__Method_RunServer, serviceImpl.RunServer); - serviceBinder.AddMethod(__Method_RunClient, serviceImpl.RunClient); - serviceBinder.AddMethod(__Method_CoreCount, serviceImpl.CoreCount); - serviceBinder.AddMethod(__Method_QuitWorker, serviceImpl.QuitWorker); + serviceBinder.AddMethod(__Method_RunServer, serviceImpl == null ? null : new grpc::DuplexStreamingServerMethod(serviceImpl.RunServer)); + serviceBinder.AddMethod(__Method_RunClient, serviceImpl == null ? null : new grpc::DuplexStreamingServerMethod(serviceImpl.RunClient)); + serviceBinder.AddMethod(__Method_CoreCount, serviceImpl == null ? null : new grpc::UnaryServerMethod(serviceImpl.CoreCount)); + serviceBinder.AddMethod(__Method_QuitWorker, serviceImpl == null ? null : new grpc::UnaryServerMethod(serviceImpl.QuitWorker)); } } diff --git a/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj b/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj index d39d46cf1b0..e0fcdecd9ac 100644 --- a/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj +++ b/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj @@ -1,13 +1,10 @@  - - net45;netcoreapp1.0 - Grpc.Microbenchmarks + net45;netcoreapp2.1 Exe - Grpc.Microbenchmarks true @@ -25,7 +22,7 @@ - + diff --git a/src/csharp/Grpc.Reflection.Tests/Grpc.Reflection.Tests.csproj b/src/csharp/Grpc.Reflection.Tests/Grpc.Reflection.Tests.csproj index 0c12f38f25a..ef9d2a1c570 100755 --- a/src/csharp/Grpc.Reflection.Tests/Grpc.Reflection.Tests.csproj +++ b/src/csharp/Grpc.Reflection.Tests/Grpc.Reflection.Tests.csproj @@ -1,13 +1,10 @@  - - net45;netcoreapp1.0 - Grpc.Reflection.Tests + net45;netcoreapp2.1 Exe - Grpc.Reflection.Tests true @@ -26,7 +23,7 @@ - + diff --git a/src/csharp/Grpc.Reflection.Tests/NUnitMain.cs b/src/csharp/Grpc.Reflection.Tests/NUnitMain.cs index 49ed1cc8d44..de4b4af6cfa 100644 --- a/src/csharp/Grpc.Reflection.Tests/NUnitMain.cs +++ b/src/csharp/Grpc.Reflection.Tests/NUnitMain.cs @@ -34,11 +34,7 @@ namespace Grpc.Reflection.Tests { // Make logger immune to NUnit capturing stdout and stderr to workaround https://github.com/nunit/nunit/issues/1406. GrpcEnvironment.SetLogger(new ConsoleLogger()); -#if NETCOREAPP1_0 - return new AutoRun(typeof(NUnitMain).GetTypeInfo().Assembly).Execute(args, new ExtendedTextWrapper(Console.Out), Console.In); -#else - return new AutoRun().Execute(args); -#endif + return new AutoRun(typeof(NUnitMain).GetTypeInfo().Assembly).Execute(args); } } } diff --git a/src/csharp/Grpc.Reflection/Grpc.Reflection.csproj b/src/csharp/Grpc.Reflection/Grpc.Reflection.csproj index 862ecda5fd9..cf08e58ed65 100755 --- a/src/csharp/Grpc.Reflection/Grpc.Reflection.csproj +++ b/src/csharp/Grpc.Reflection/Grpc.Reflection.csproj @@ -1,19 +1,20 @@ - + - - Copyright 2016, Google Inc. - gRPC C# Reflection - $(GrpcCsharpVersion) - Google Inc. - net45;netstandard1.5 - Grpc.Reflection - Grpc.Reflection - gRPC reflection + The gRPC Authors + Copyright 2016 The gRPC Authors + gRPC C# Server Reflection (for Grpc.Core) + https://github.com/grpc/grpc.github.io/raw/master/img/grpc_square_reverse_4x.png + Apache-2.0 https://github.com/grpc/grpc - https://github.com/grpc/grpc/blob/master/LICENSE + gRPC reflection + $(GrpcCsharpVersion) + + + + net45;netstandard1.5;netstandard2.0 true true @@ -21,7 +22,7 @@ - + diff --git a/src/csharp/Grpc.Reflection/Reflection.cs b/src/csharp/Grpc.Reflection/Reflection.cs index e319be5bff7..a1b99dff431 100644 --- a/src/csharp/Grpc.Reflection/Reflection.cs +++ b/src/csharp/Grpc.Reflection/Reflection.cs @@ -850,7 +850,7 @@ namespace Grpc.Reflection.V1Alpha { } if (other.originalRequest_ != null) { if (originalRequest_ == null) { - originalRequest_ = new global::Grpc.Reflection.V1Alpha.ServerReflectionRequest(); + OriginalRequest = new global::Grpc.Reflection.V1Alpha.ServerReflectionRequest(); } OriginalRequest.MergeFrom(other.OriginalRequest); } @@ -898,9 +898,9 @@ namespace Grpc.Reflection.V1Alpha { } case 18: { if (originalRequest_ == null) { - originalRequest_ = new global::Grpc.Reflection.V1Alpha.ServerReflectionRequest(); + OriginalRequest = new global::Grpc.Reflection.V1Alpha.ServerReflectionRequest(); } - input.ReadMessage(originalRequest_); + input.ReadMessage(OriginalRequest); break; } case 34: { diff --git a/src/csharp/Grpc.Reflection/ReflectionGrpc.cs b/src/csharp/Grpc.Reflection/ReflectionGrpc.cs index ed55c2f584f..f97b3143a69 100644 --- a/src/csharp/Grpc.Reflection/ReflectionGrpc.cs +++ b/src/csharp/Grpc.Reflection/ReflectionGrpc.cs @@ -46,6 +46,7 @@ namespace Grpc.Reflection.V1Alpha { } /// Base class for server-side implementations of ServerReflection + [grpc::BindServiceMethod(typeof(ServerReflection), "BindService")] public abstract partial class ServerReflectionBase { /// @@ -123,13 +124,13 @@ namespace Grpc.Reflection.V1Alpha { .AddMethod(__Method_ServerReflectionInfo, serviceImpl.ServerReflectionInfo).Build(); } - /// Register service method implementations with a service binder. Useful when customizing the service binding logic. + /// Register service method with a service binder with or without implementation. Useful when customizing the service binding logic. /// Note: this method is part of an experimental API that can change or be removed without any prior notice. /// Service methods will be bound by calling AddMethod on this object. /// An object implementing the server-side handling logic. public static void BindService(grpc::ServiceBinderBase serviceBinder, ServerReflectionBase serviceImpl) { - serviceBinder.AddMethod(__Method_ServerReflectionInfo, serviceImpl.ServerReflectionInfo); + serviceBinder.AddMethod(__Method_ServerReflectionInfo, serviceImpl == null ? null : new grpc::DuplexStreamingServerMethod(serviceImpl.ServerReflectionInfo)); } } diff --git a/src/csharp/Grpc.Tools.Tests/CSharpGeneratorTest.cs b/src/csharp/Grpc.Tools.Tests/CSharpGeneratorTest.cs index e4c9b2fa843..320bb6dc9fc 100644 --- a/src/csharp/Grpc.Tools.Tests/CSharpGeneratorTest.cs +++ b/src/csharp/Grpc.Tools.Tests/CSharpGeneratorTest.cs @@ -33,12 +33,15 @@ namespace Grpc.Tools.Tests [TestCase("foo.proto", "Foo.cs", "FooGrpc.cs")] [TestCase("sub/foo.proto", "Foo.cs", "FooGrpc.cs")] [TestCase("one_two.proto", "OneTwo.cs", "OneTwoGrpc.cs")] - [TestCase("__one_two!.proto", "OneTwo!.cs", "OneTwo!Grpc.cs")] - [TestCase("one(two).proto", "One(two).cs", "One(two)Grpc.cs")] - [TestCase("one_(two).proto", "One(two).cs", "One(two)Grpc.cs")] - [TestCase("one two.proto", "One two.cs", "One twoGrpc.cs")] - [TestCase("one_ two.proto", "One two.cs", "One twoGrpc.cs")] - [TestCase("one .proto", "One .cs", "One Grpc.cs")] + [TestCase("ONE_TWO.proto", "ONETWO.cs", "ONETWOGrpc.cs")] + [TestCase("one.two.proto", "OneTwo.cs", "One.twoGrpc.cs")] + [TestCase("one123two.proto", "One123Two.cs", "One123twoGrpc.cs")] + [TestCase("__one_two!.proto", "OneTwo.cs", "OneTwo!Grpc.cs")] + [TestCase("one(two).proto", "OneTwo.cs", "One(two)Grpc.cs")] + [TestCase("one_(two).proto", "OneTwo.cs", "One(two)Grpc.cs")] + [TestCase("one two.proto", "OneTwo.cs", "One twoGrpc.cs")] + [TestCase("one_ two.proto", "OneTwo.cs", "One twoGrpc.cs")] + [TestCase("one .proto", "One.cs", "One Grpc.cs")] public void NameMangling(string proto, string expectCs, string expectGrpcCs) { var poss = _generator.GetPossibleOutputs(Utils.MakeItem(proto, "grpcservices", "both")); diff --git a/src/csharp/Grpc.Tools.Tests/Grpc.Tools.Tests.csproj b/src/csharp/Grpc.Tools.Tests/Grpc.Tools.Tests.csproj index a2d4874eece..7ad2ce21694 100644 --- a/src/csharp/Grpc.Tools.Tests/Grpc.Tools.Tests.csproj +++ b/src/csharp/Grpc.Tools.Tests/Grpc.Tools.Tests.csproj @@ -1,9 +1,7 @@ - - - net45;netcoreapp1.0 + net45;netcoreapp2.1 Exe diff --git a/src/csharp/Grpc.Tools.Tests/NUnitMain.cs b/src/csharp/Grpc.Tools.Tests/NUnitMain.cs index 418c33820eb..d30d608aa33 100644 --- a/src/csharp/Grpc.Tools.Tests/NUnitMain.cs +++ b/src/csharp/Grpc.Tools.Tests/NUnitMain.cs @@ -24,10 +24,6 @@ namespace Grpc.Tools.Tests static class NUnitMain { public static int Main(string[] args) => -#if NETCOREAPP1_0 || NETCOREAPP1_1 new AutoRun(typeof(NUnitMain).GetTypeInfo().Assembly).Execute(args); -#else - new AutoRun().Execute(args); -#endif }; } diff --git a/src/csharp/Grpc.Tools.Tests/ProtoCompileBasicTest.cs b/src/csharp/Grpc.Tools.Tests/ProtoCompileBasicTest.cs index ea763f4e408..ca850c5979e 100644 --- a/src/csharp/Grpc.Tools.Tests/ProtoCompileBasicTest.cs +++ b/src/csharp/Grpc.Tools.Tests/ProtoCompileBasicTest.cs @@ -16,6 +16,8 @@ #endregion +using System.Collections.Generic; +using System.Linq; using System.Reflection; // UWYU: Object.GetType() extension. using Microsoft.Build.Framework; using Moq; @@ -30,6 +32,7 @@ namespace Grpc.Tools.Tests { public string LastPathToTool { get; private set; } public string[] LastResponseFile { get; private set; } + public List StdErrMessages { get; } = new List(); protected override int ExecuteTool(string pathToTool, string response, @@ -45,8 +48,13 @@ namespace Grpc.Tools.Tests LastPathToTool = pathToTool; LastResponseFile = response.Remove(response.Length - 1).Split('\n'); + foreach (string message in StdErrMessages) + { + LogEventsFromTextOutput(message, MessageImportance.High); + } + // Do not run the tool, but pretend it ran successfully. - return 0; + return StdErrMessages.Any() ? -1 : 0; } }; @@ -62,7 +70,7 @@ namespace Grpc.Tools.Tests }; } - [TestCase("ProtoBuf")] + [TestCase("Protobuf")] [TestCase("Generator")] [TestCase("OutputDir")] [Description("We trust MSBuild to initialize these properties.")] diff --git a/src/csharp/Grpc.Tools.Tests/ProtoCompileCommandLineGeneratorTest.cs b/src/csharp/Grpc.Tools.Tests/ProtoCompileCommandLineGeneratorTest.cs index cac71466345..5f6a53b6713 100644 --- a/src/csharp/Grpc.Tools.Tests/ProtoCompileCommandLineGeneratorTest.cs +++ b/src/csharp/Grpc.Tools.Tests/ProtoCompileCommandLineGeneratorTest.cs @@ -30,7 +30,7 @@ namespace Grpc.Tools.Tests { _task.Generator = "csharp"; _task.OutputDir = "outdir"; - _task.ProtoBuf = Utils.MakeSimpleItems("a.proto"); + _task.Protobuf = Utils.MakeSimpleItems("a.proto"); } void ExecuteExpectSuccess() @@ -49,16 +49,16 @@ namespace Grpc.Tools.Tests ExecuteExpectSuccess(); Assert.That(_task.LastPathToTool, Does.Match(@"protoc(.exe)?$")); Assert.That(_task.LastResponseFile, Is.EqualTo(new[] { - "--csharp_out=outdir", "a.proto" })); + "--csharp_out=outdir", "--error_format=msvs", "a.proto" })); } [Test] public void CompileTwoFiles() { - _task.ProtoBuf = Utils.MakeSimpleItems("a.proto", "foo/b.proto"); + _task.Protobuf = Utils.MakeSimpleItems("a.proto", "foo/b.proto"); ExecuteExpectSuccess(); Assert.That(_task.LastResponseFile, Is.EqualTo(new[] { - "--csharp_out=outdir", "a.proto", "foo/b.proto" })); + "--csharp_out=outdir", "--error_format=msvs", "a.proto", "foo/b.proto" })); } [Test] @@ -68,7 +68,7 @@ namespace Grpc.Tools.Tests ExecuteExpectSuccess(); Assert.That(_task.LastResponseFile, Is.EqualTo(new[] { "--csharp_out=outdir", "--proto_path=/path1", - "--proto_path=/path2", "a.proto" })); + "--proto_path=/path2", "--error_format=msvs", "a.proto" })); } [TestCase("Cpp")] @@ -87,7 +87,7 @@ namespace Grpc.Tools.Tests ExecuteExpectSuccess(); gen = gen.ToLowerInvariant(); Assert.That(_task.LastResponseFile, Is.EqualTo(new[] { - $"--{gen}_out=outdir", $"--{gen}_opt=foo,bar", "a.proto" })); + $"--{gen}_out=outdir", $"--{gen}_opt=foo,bar", "--error_format=msvs", "a.proto" })); } [Test] @@ -175,5 +175,86 @@ namespace Grpc.Tools.Tests Assert.That(_task.LastResponseFile, Does.Contain("--csharp_out=" + expect)); } + + [TestCase( + "../Protos/greet.proto(19) : warning in column=5 : warning : When enum name is stripped and label is PascalCased (Zero) this value label conflicts with Zero.", + "../Protos/greet.proto", + 19, + 5, + "warning : When enum name is stripped and label is PascalCased (Zero) this value label conflicts with Zero.")] + [TestCase( + "../Protos/greet.proto: warning: Import google/protobuf/empty.proto but not used.", + "../Protos/greet.proto", + 0, + 0, + "Import google/protobuf/empty.proto but not used.")] + [TestCase("../Protos/greet.proto(14) : error in column=10: \"name\" is already defined in \"Greet.HelloRequest\".", null, 0, 0, null)] + [TestCase("../Protos/greet.proto: Import \"google / protobuf / empty.proto\" was listed twice.", null, 0, 0, null)] + public void WarningsParsed(string stderr, string file, int line, int col, string message) + { + _task.StdErrMessages.Add(stderr); + + _mockEngine + .Setup(me => me.LogWarningEvent(It.IsAny())) + .Callback((BuildWarningEventArgs e) => { + if (file != null) + { + Assert.AreEqual(file, e.File); + Assert.AreEqual(line, e.LineNumber); + Assert.AreEqual(col, e.ColumnNumber); + Assert.AreEqual(message, e.Message); + } + else + { + Assert.Fail($"Error logged by build engine:\n{e.Message}"); + } + }); + + bool result = _task.Execute(); + Assert.IsFalse(result); + } + + [TestCase( + "../Protos/greet.proto(14) : error in column=10: \"name\" is already defined in \"Greet.HelloRequest\".", + "../Protos/greet.proto", + 14, + 10, + "\"name\" is already defined in \"Greet.HelloRequest\".")] + [TestCase( + "../Protos/greet.proto: Import \"google / protobuf / empty.proto\" was listed twice.", + "../Protos/greet.proto", + 0, + 0, + "Import \"google / protobuf / empty.proto\" was listed twice.")] + [TestCase("../Protos/greet.proto(19) : warning in column=5 : warning : When enum name is stripped and label is PascalCased (Zero) this value label conflicts with Zero.", null, 0, 0, null)] + [TestCase("../Protos/greet.proto: warning: Import google/protobuf/empty.proto but not used.", null, 0, 0, null)] + public void ErrorsParsed(string stderr, string file, int line, int col, string message) + { + _task.StdErrMessages.Add(stderr); + + _mockEngine + .Setup(me => me.LogErrorEvent(It.IsAny())) + .Callback((BuildErrorEventArgs e) => { + if (file != null) + { + Assert.AreEqual(file, e.File); + Assert.AreEqual(line, e.LineNumber); + Assert.AreEqual(col, e.ColumnNumber); + Assert.AreEqual(message, e.Message); + } + else + { + // Ignore expected error + // "protoc/protoc.exe" existed with code -1. + if (!e.Message.EndsWith("exited with code -1.")) + { + Assert.Fail($"Error logged by build engine:\n{e.Message}"); + } + } + }); + + bool result = _task.Execute(); + Assert.IsFalse(result); + } }; } diff --git a/src/csharp/Grpc.Tools.Tests/ProtoCompileCommandLinePrinterTest.cs b/src/csharp/Grpc.Tools.Tests/ProtoCompileCommandLinePrinterTest.cs index 1773dcb8750..a11e3462fa0 100644 --- a/src/csharp/Grpc.Tools.Tests/ProtoCompileCommandLinePrinterTest.cs +++ b/src/csharp/Grpc.Tools.Tests/ProtoCompileCommandLinePrinterTest.cs @@ -29,7 +29,7 @@ namespace Grpc.Tools.Tests { _task.Generator = "csharp"; _task.OutputDir = "outdir"; - _task.ProtoBuf = Utils.MakeSimpleItems("a.proto"); + _task.Protobuf = Utils.MakeSimpleItems("a.proto"); _mockEngine .Setup(me => me.LogMessageEvent(It.IsAny())) diff --git a/src/csharp/Grpc.Tools/Common.cs b/src/csharp/Grpc.Tools/Common.cs index e6acdd63939..13cd6a32316 100644 --- a/src/csharp/Grpc.Tools/Common.cs +++ b/src/csharp/Grpc.Tools/Common.cs @@ -31,7 +31,7 @@ namespace Grpc.Tools { // On output dependency lists. public static string Source = "Source"; - // On ProtoBuf items. + // On Protobuf items. public static string ProtoRoot = "ProtoRoot"; public static string OutputDir = "OutputDir"; public static string GrpcServices = "GrpcServices"; @@ -60,7 +60,7 @@ namespace Grpc.Tools : RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? OsKind.MacOsX : OsKind.Unknown; - switch (RuntimeInformation.OSArchitecture) + switch (RuntimeInformation.ProcessArchitecture) { case Architecture.X86: Cpu = CpuKind.X86; break; case Architecture.X64: Cpu = CpuKind.X64; break; @@ -86,7 +86,7 @@ namespace Grpc.Tools } // Hope we are not building on ARM under Xamarin! - Cpu = Environment.Is64BitOperatingSystem ? CpuKind.X64 : CpuKind.X86; + Cpu = Environment.Is64BitProcess ? CpuKind.X64 : CpuKind.X86; #endif } }; diff --git a/src/csharp/Grpc.Tools/GeneratorServices.cs b/src/csharp/Grpc.Tools/GeneratorServices.cs index 536ec43c836..c69c6893a03 100644 --- a/src/csharp/Grpc.Tools/GeneratorServices.cs +++ b/src/csharp/Grpc.Tools/GeneratorServices.cs @@ -66,29 +66,28 @@ namespace Grpc.Tools public override string[] GetPossibleOutputs(ITaskItem protoItem) { bool doGrpc = GrpcOutputPossible(protoItem); - string filename = LowerUnderscoreToUpperCamel( - Path.GetFileNameWithoutExtension(protoItem.ItemSpec)); - var outputs = new string[doGrpc ? 2 : 1]; + string basename = Path.GetFileNameWithoutExtension(protoItem.ItemSpec); + string outdir = protoItem.GetMetadata(Metadata.OutputDir); - string fileStem = Path.Combine(outdir, filename); - outputs[0] = fileStem + ".cs"; + string filename = LowerUnderscoreToUpperCamelProtocWay(basename); + outputs[0] = Path.Combine(outdir, filename) + ".cs"; + if (doGrpc) { // Override outdir if kGrpcOutputDir present, default to proto output. - outdir = protoItem.GetMetadata(Metadata.GrpcOutputDir); - if (outdir != "") - { - fileStem = Path.Combine(outdir, filename); - } - outputs[1] = fileStem + "Grpc.cs"; + string grpcdir = protoItem.GetMetadata(Metadata.GrpcOutputDir); + filename = LowerUnderscoreToUpperCamelGrpcWay(basename); + outputs[1] = Path.Combine( + grpcdir != "" ? grpcdir : outdir, filename) + "Grpc.cs"; } return outputs; } - string LowerUnderscoreToUpperCamel(string str) + // This is how the gRPC codegen currently construct its output filename. + // See src/compiler/generator_helpers.h:118. + string LowerUnderscoreToUpperCamelGrpcWay(string str) { - // See src/compiler/generator_helpers.h:118 var result = new StringBuilder(str.Length, str.Length); bool cap = true; foreach (char c in str) @@ -109,6 +108,26 @@ namespace Grpc.Tools } return result.ToString(); } + + // This is how the protoc codegen constructs its output filename. + // See protobuf/compiler/csharp/csharp_helpers.cc:137. + // Note that protoc explicitly discards non-ASCII letters. + string LowerUnderscoreToUpperCamelProtocWay(string str) + { + var result = new StringBuilder(str.Length, str.Length); + bool cap = true; + foreach (char c in str) + { + char upperC = char.ToUpperInvariant(c); + bool isAsciiLetter = 'A' <= upperC && upperC <= 'Z'; + if (isAsciiLetter || ('0' <= c && c <= '9')) + { + result.Append(cap ? upperC : c); + } + cap = !isAsciiLetter; + } + return result.ToString(); + } }; // C++ generator services. @@ -164,7 +183,7 @@ namespace Grpc.Tools protoDir = EndWithSlash(protoDir); if (!protoDir.StartsWith(rootDir)) { - Log.LogWarning("ProtoBuf item '{0}' has the ProtoRoot metadata '{1}' " + + Log.LogWarning("Protobuf item '{0}' has the ProtoRoot metadata '{1}' " + "which is not prefix to its path. Cannot compute relative path.", proto, root); return ""; diff --git a/src/csharp/Grpc.Tools/Grpc.Tools.csproj b/src/csharp/Grpc.Tools/Grpc.Tools.csproj index 61fa75a4ec2..d09d97d1397 100644 --- a/src/csharp/Grpc.Tools/Grpc.Tools.csproj +++ b/src/csharp/Grpc.Tools/Grpc.Tools.csproj @@ -1,10 +1,8 @@ - - Protobuf.MSBuild - $(GrpcCsharpVersion) + $(GrpcCsharpVersion) net45;netstandard1.3 @@ -45,17 +43,18 @@ true true Grpc.Tools + The gRPC Authors + Copyright 2018 The gRPC Authors gRPC and Protocol Buffer compiler for managed C# and native C++ projects. Add this package to a project that contains .proto files to be compiled to code. It contains the compilers, include files and project system integration for gRPC and Protocol buffer service description files necessary to build them on Windows, Linux and MacOS. Managed runtime is supplied separately in the Grpc.Core package. - Copyright 2018 gRPC authors - gRPC authors - https://github.com/grpc/grpc/blob/master/LICENSE + https://github.com/grpc/grpc.github.io/raw/master/img/grpc_square_reverse_4x.png + Apache-2.0 https://github.com/grpc/grpc - gRPC RPC protocol HTTP/2 + gRPC RPC HTTP/2 @@ -69,20 +68,20 @@ Linux and MacOS. Managed runtime is supplied separately in the Grpc.Core package - <_Asset PackagePath="tools/windows_x86/protoc.exe" Include="$(Assets_ProtoCompiler)windows_x86/protoc.exe" /> - <_Asset PackagePath="tools/windows_x64/protoc.exe" Include="$(Assets_ProtoCompiler)windows_x64/protoc.exe" /> - <_Asset PackagePath="tools/linux_x86/protoc" Include="$(Assets_ProtoCompiler)linux_x86/protoc" /> - <_Asset PackagePath="tools/linux_x64/protoc" Include="$(Assets_ProtoCompiler)linux_x64/protoc" /> - <_Asset PackagePath="tools/macosx_x86/protoc" Include="$(Assets_ProtoCompiler)macos_x86/protoc" /> - <_Asset PackagePath="tools/macosx_x64/protoc" Include="$(Assets_ProtoCompiler)macos_x64/protoc" /> + <_Asset PackagePath="tools/windows_x86/" Include="$(Assets_ProtoCompiler)windows_x86/protoc.exe" /> + <_Asset PackagePath="tools/windows_x64/" Include="$(Assets_ProtoCompiler)windows_x64/protoc.exe" /> + <_Asset PackagePath="tools/linux_x86/" Include="$(Assets_ProtoCompiler)linux_x86/protoc" /> + <_Asset PackagePath="tools/linux_x64/" Include="$(Assets_ProtoCompiler)linux_x64/protoc" /> + <_Asset PackagePath="tools/macosx_x86/" Include="$(Assets_ProtoCompiler)macos_x86/protoc" /> + <_Asset PackagePath="tools/macosx_x64/" Include="$(Assets_ProtoCompiler)macos_x64/protoc" /> - <_Asset PackagePath="tools/windows_x86/grpc_csharp_plugin.exe" Include="$(Assets_GrpcPlugins)protoc_windows_x86/grpc_csharp_plugin.exe" /> - <_Asset PackagePath="tools/windows_x64/grpc_csharp_plugin.exe" Include="$(Assets_GrpcPlugins)protoc_windows_x64/grpc_csharp_plugin.exe" /> - <_Asset PackagePath="tools/linux_x86/grpc_csharp_plugin" Include="$(Assets_GrpcPlugins)protoc_linux_x86/grpc_csharp_plugin" /> - <_Asset PackagePath="tools/linux_x64/grpc_csharp_plugin" Include="$(Assets_GrpcPlugins)protoc_linux_x64/grpc_csharp_plugin" /> - <_Asset PackagePath="tools/macosx_x86/grpc_csharp_plugin" Include="$(Assets_GrpcPlugins)protoc_macos_x86/grpc_csharp_plugin" /> - <_Asset PackagePath="tools/macosx_x64/grpc_csharp_plugin" Include="$(Assets_GrpcPlugins)protoc_macos_x64/grpc_csharp_plugin" /> + <_Asset PackagePath="tools/windows_x86/" Include="$(Assets_GrpcPlugins)protoc_windows_x86/grpc_csharp_plugin.exe" /> + <_Asset PackagePath="tools/windows_x64/" Include="$(Assets_GrpcPlugins)protoc_windows_x64/grpc_csharp_plugin.exe" /> + <_Asset PackagePath="tools/linux_x86/" Include="$(Assets_GrpcPlugins)protoc_linux_x86/grpc_csharp_plugin" /> + <_Asset PackagePath="tools/linux_x64/" Include="$(Assets_GrpcPlugins)protoc_linux_x64/grpc_csharp_plugin" /> + <_Asset PackagePath="tools/macosx_x86/" Include="$(Assets_GrpcPlugins)protoc_macos_x86/grpc_csharp_plugin" /> + <_Asset PackagePath="tools/macosx_x64/" Include="$(Assets_GrpcPlugins)protoc_macos_x64/grpc_csharp_plugin" /> diff --git a/src/csharp/Grpc.Tools/ProtoCompile.cs b/src/csharp/Grpc.Tools/ProtoCompile.cs index 93608e1ac02..40cfbeb029b 100644 --- a/src/csharp/Grpc.Tools/ProtoCompile.cs +++ b/src/csharp/Grpc.Tools/ProtoCompile.cs @@ -16,7 +16,10 @@ #endregion +using System; +using System.Collections.Generic; using System.Text; +using System.Text.RegularExpressions; using Microsoft.Build.Framework; using Microsoft.Build.Utilities; @@ -123,6 +126,110 @@ namespace Grpc.Tools "javanano", "js", "objc", "php", "python", "ruby" }; + static readonly TimeSpan s_regexTimeout = TimeSpan.FromMilliseconds(100); + + static readonly List s_errorListFilters = new List() + { + // Example warning with location + //../Protos/greet.proto(19) : warning in column=5 : warning : When enum name is stripped and label is PascalCased (Zero), + // this value label conflicts with Zero. This will make the proto fail to compile for some languages, such as C#. + new ErrorListFilter + { + Pattern = new Regex( + pattern: "(?'FILENAME'.+)\\((?'LINE'\\d+)\\) ?: ?warning in column=(?'COLUMN'\\d+) ?: ?(?'TEXT'.*)", + options: RegexOptions.Compiled | RegexOptions.IgnoreCase, + matchTimeout: s_regexTimeout), + LogAction = (log, match) => + { + int.TryParse(match.Groups["LINE"].Value, out var line); + int.TryParse(match.Groups["COLUMN"].Value, out var column); + + log.LogWarning( + subcategory: null, + warningCode: null, + helpKeyword: null, + file: match.Groups["FILENAME"].Value, + lineNumber: line, + columnNumber: column, + endLineNumber: 0, + endColumnNumber: 0, + message: match.Groups["TEXT"].Value); + } + }, + + // Example error with location + //../Protos/greet.proto(14) : error in column=10: "name" is already defined in "Greet.HelloRequest". + new ErrorListFilter + { + Pattern = new Regex( + pattern: "(?'FILENAME'.+)\\((?'LINE'\\d+)\\) ?: ?error in column=(?'COLUMN'\\d+) ?: ?(?'TEXT'.*)", + options: RegexOptions.Compiled | RegexOptions.IgnoreCase, + matchTimeout: s_regexTimeout), + LogAction = (log, match) => + { + int.TryParse(match.Groups["LINE"].Value, out var line); + int.TryParse(match.Groups["COLUMN"].Value, out var column); + + log.LogError( + subcategory: null, + errorCode: null, + helpKeyword: null, + file: match.Groups["FILENAME"].Value, + lineNumber: line, + columnNumber: column, + endLineNumber: 0, + endColumnNumber: 0, + message: match.Groups["TEXT"].Value); + } + }, + + // Example warning without location + //../Protos/greet.proto: warning: Import google/protobuf/empty.proto but not used. + new ErrorListFilter + { + Pattern = new Regex( + pattern: "(?'FILENAME'.+): ?warning: ?(?'TEXT'.*)", + options: RegexOptions.Compiled | RegexOptions.IgnoreCase, + matchTimeout: s_regexTimeout), + LogAction = (log, match) => + { + log.LogWarning( + subcategory: null, + warningCode: null, + helpKeyword: null, + file: match.Groups["FILENAME"].Value, + lineNumber: 0, + columnNumber: 0, + endLineNumber: 0, + endColumnNumber: 0, + message: match.Groups["TEXT"].Value); + } + }, + + // Example error without location + //../Protos/greet.proto: Import "google/protobuf/empty.proto" was listed twice. + new ErrorListFilter + { + Pattern = new Regex( + pattern: "(?'FILENAME'.+): ?(?'TEXT'.*)", + options: RegexOptions.Compiled | RegexOptions.IgnoreCase, + matchTimeout: s_regexTimeout), + LogAction = (log, match) => + { + log.LogError( + subcategory: null, + errorCode: null, + helpKeyword: null, + file: match.Groups["FILENAME"].Value, + lineNumber: 0, + columnNumber: 0, + endLineNumber: 0, + endColumnNumber: 0, + message: match.Groups["TEXT"].Value); + } + } + }; + /// /// Code generator. /// @@ -133,7 +240,7 @@ namespace Grpc.Tools /// Protobuf files to compile. /// [Required] - public ITaskItem[] ProtoBuf { get; set; } + public ITaskItem[] Protobuf { get; set; } /// /// Directory where protoc dependency files are cached. If provided, dependency @@ -237,7 +344,7 @@ namespace Grpc.Tools Log.LogError("Properties ProtoDepDir and DependencyOut may not be both specified"); } - if (ProtoBuf.Length > 1 && (ProtoDepDir != null || DependencyOut != null)) + if (Protobuf.Length > 1 && (ProtoDepDir != null || DependencyOut != null)) { Log.LogError("Proto compiler currently allows only one input when " + "--dependency_out is specified (via ProtoDepDir or DependencyOut). " + @@ -247,7 +354,7 @@ namespace Grpc.Tools // Use ProtoDepDir to autogenerate DependencyOut if (ProtoDepDir != null) { - DependencyOut = DepFileUtil.GetDepFilenameForProto(ProtoDepDir, ProtoBuf[0].ItemSpec); + DependencyOut = DepFileUtil.GetDepFilenameForProto(ProtoDepDir, Protobuf[0].ItemSpec); } if (GrpcPluginExe == null) @@ -318,7 +425,8 @@ namespace Grpc.Tools cmd.AddSwitchMaybe("proto_path", TrimEndSlash(path)); } cmd.AddSwitchMaybe("dependency_out", DependencyOut); - foreach (var proto in ProtoBuf) + cmd.AddSwitchMaybe("error_format", "msvs"); + foreach (var proto in Protobuf) { cmd.AddArg(proto.ItemSpec); } @@ -405,6 +513,22 @@ namespace Grpc.Tools base.LogToolCommand(printer.ToString()); } + protected override void LogEventsFromTextOutput(string singleLine, MessageImportance messageImportance) + { + foreach (ErrorListFilter filter in s_errorListFilters) + { + Match match = filter.Pattern.Match(singleLine); + + if (match.Success) + { + filter.LogAction(Log, match); + return; + } + } + + base.LogEventsFromTextOutput(singleLine, messageImportance); + } + // Main task entry point. public override bool Execute() { @@ -437,5 +561,11 @@ namespace Grpc.Tools return true; } + + class ErrorListFilter + { + public Regex Pattern { get; set; } + public Action LogAction { get; set; } + } }; } diff --git a/src/csharp/Grpc.Tools/ProtoCompilerOutputs.cs b/src/csharp/Grpc.Tools/ProtoCompilerOutputs.cs index 915be3421e8..24c0dd8482d 100644 --- a/src/csharp/Grpc.Tools/ProtoCompilerOutputs.cs +++ b/src/csharp/Grpc.Tools/ProtoCompilerOutputs.cs @@ -38,7 +38,7 @@ namespace Grpc.Tools /// files actually produced by the compiler. /// [Required] - public ITaskItem[] ProtoBuf { get; set; } + public ITaskItem[] Protobuf { get; set; } /// /// Output items per each potential output. We do not look at existing @@ -68,7 +68,7 @@ namespace Grpc.Tools // Get language-specific possible output. The generator expects certain // metadata be set on the proto item. var possible = new List(); - foreach (var proto in ProtoBuf) + foreach (var proto in Protobuf) { var outputs = generator.GetPossibleOutputs(proto); foreach (string output in outputs) diff --git a/src/csharp/Grpc.Tools/ProtoReadDependencies.cs b/src/csharp/Grpc.Tools/ProtoReadDependencies.cs index 963837e8b74..34e1379f679 100644 --- a/src/csharp/Grpc.Tools/ProtoReadDependencies.cs +++ b/src/csharp/Grpc.Tools/ProtoReadDependencies.cs @@ -29,7 +29,7 @@ namespace Grpc.Tools /// of proto files cached under ProtoDepDir. /// [Required] - public ITaskItem[] ProtoBuf { get; set; } + public ITaskItem[] Protobuf { get; set; } /// /// Directory where protoc dependency files are cached. @@ -55,7 +55,7 @@ namespace Grpc.Tools if (ProtoDepDir != null) { var dependencies = new List(); - foreach (var proto in ProtoBuf) + foreach (var proto in Protobuf) { string[] deps = DepFileUtil.ReadDependencyInputs(ProtoDepDir, proto.ItemSpec, Log); foreach (string dep in deps) diff --git a/src/csharp/Grpc.Tools/build/_grpc/Grpc.CSharp.xml b/src/csharp/Grpc.Tools/build/_grpc/Grpc.CSharp.xml index 54468eb5eff..66862582dad 100644 --- a/src/csharp/Grpc.Tools/build/_grpc/Grpc.CSharp.xml +++ b/src/csharp/Grpc.Tools/build/_grpc/Grpc.CSharp.xml @@ -1,11 +1,11 @@ - - @@ -21,7 +21,7 @@ - diff --git a/src/csharp/Grpc.Tools/build/_grpc/_Grpc.Tools.targets b/src/csharp/Grpc.Tools/build/_grpc/_Grpc.Tools.targets index 5f76c03ce57..dd01b8183db 100644 --- a/src/csharp/Grpc.Tools/build/_grpc/_Grpc.Tools.targets +++ b/src/csharp/Grpc.Tools/build/_grpc/_Grpc.Tools.targets @@ -13,18 +13,17 @@ - - Both - + + Both + - $(Protobuf_PackagedToolsPath)\$(Protobuf_ToolsOs)_x86\$(gRPC_PluginFileName).exe + >$(Protobuf_PackagedToolsPath)\$(Protobuf_ToolsOs)_$(Protobuf_ToolsCpu)\$(gRPC_PluginFileName).exe $(Protobuf_PackagedToolsPath)/$(Protobuf_ToolsOs)_$(Protobuf_ToolsCpu)/$(gRPC_PluginFileName) diff --git a/src/csharp/Grpc.Tools/build/_protobuf/Google.Protobuf.Tools.props b/src/csharp/Grpc.Tools/build/_protobuf/Google.Protobuf.Tools.props index 9f2d8bb4b5c..22bfef7f66a 100644 --- a/src/csharp/Grpc.Tools/build/_protobuf/Google.Protobuf.Tools.props +++ b/src/csharp/Grpc.Tools/build/_protobuf/Google.Protobuf.Tools.props @@ -15,10 +15,10 @@ - + diff --git a/src/csharp/Grpc.Tools/build/_protobuf/Google.Protobuf.Tools.targets b/src/csharp/Grpc.Tools/build/_protobuf/Google.Protobuf.Tools.targets index 1d233d23a80..b1030ba1f8b 100644 --- a/src/csharp/Grpc.Tools/build/_protobuf/Google.Protobuf.Tools.targets +++ b/src/csharp/Grpc.Tools/build/_protobuf/Google.Protobuf.Tools.targets @@ -22,27 +22,28 @@ - - Public - True - - True - $(Protobuf_OutputPath) - + + Public + True + + True + $(Protobuf_OutputPath) + MSBuild:Compile + File;BrowseObject - + - false + false @@ -74,14 +75,13 @@ $(_Protobuf_ToolsOs) $(_Protobuf_ToolsCpu) - $(Protobuf_PackagedToolsPath)\$(Protobuf_ToolsOs)_x86\protoc.exe + >$(Protobuf_PackagedToolsPath)\$(Protobuf_ToolsOs)_$(Protobuf_ToolsCpu)\protoc.exe $(Protobuf_PackagedToolsPath)/$(Protobuf_ToolsOs)_$(Protobuf_ToolsCpu)/protoc - @@ -94,10 +94,10 @@ - + Files="@(Protobuf->WithMetadataValue('ProtoRoot',''))"> - + . @@ -155,13 +155,13 @@ - @@ -247,7 +247,7 @@ @@ -264,7 +264,7 @@ + Condition=" '$(DisableProtobufDesignTimeBuild)' != 'true' "> @@ -327,7 +327,7 @@ @@ -376,9 +376,9 @@ * The Pack target includes .proto files into the source package. --> + Condition=" '@(Protobuf)' != '' " > - + diff --git a/src/csharp/Grpc.Tools/build/_protobuf/Protobuf.CSharp.xml b/src/csharp/Grpc.Tools/build/_protobuf/Protobuf.CSharp.xml index 2c41fbcbd06..66b9f4bd5da 100644 --- a/src/csharp/Grpc.Tools/build/_protobuf/Protobuf.CSharp.xml +++ b/src/csharp/Grpc.Tools/build/_protobuf/Protobuf.CSharp.xml @@ -4,18 +4,18 @@ + ItemType="Protobuf" /> - - - @@ -31,7 +31,7 @@ - @@ -42,7 +42,7 @@ Category="Misc" Description="Location of the file."> - @@ -53,7 +53,7 @@ Category="Misc" Description="Name of the file or folder."> - @@ -81,7 +81,7 @@ - @@ -90,7 +90,7 @@ Category="Protobuf" Default="true" Description="Specifies if this file is compiled or only imported by other files."> - diff --git a/src/csharp/Grpc.nuspec b/src/csharp/Grpc.nuspec deleted file mode 100644 index 7fbd8619230..00000000000 --- a/src/csharp/Grpc.nuspec +++ /dev/null @@ -1,22 +0,0 @@ - - - - Grpc - gRPC C# - C# implementation of gRPC - an RPC library and framework - C# implementation of gRPC - an RPC library and framework. See project site for more info. - $version$ - Google Inc. - grpc-packages - https://github.com/grpc/grpc/blob/master/LICENSE - https://github.com/grpc/grpc - false - Release $version$ of gRPC C# - Copyright 2015, Google Inc. - gRPC RPC Protocol HTTP/2 - - - - - - diff --git a/src/csharp/Grpc.sln b/src/csharp/Grpc.sln index 6c1b2e99980..25030cc110e 100644 --- a/src/csharp/Grpc.sln +++ b/src/csharp/Grpc.sln @@ -3,6 +3,8 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 VisualStudioVersion = 15.0.26430.4 MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Grpc.Core.Api", "Grpc.Core.Api\Grpc.Core.Api.csproj", "{63FCEA50-1505-11E9-B56E-0800200C9A66}" +EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Grpc.Core", "Grpc.Core\Grpc.Core.csproj", "{BD878CB3-BDB4-46AB-84EF-C3B4729F56BC}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Grpc.Auth", "Grpc.Auth\Grpc.Auth.csproj", "{2A16007A-5D67-4C53-BEC8-51E5064D18BF}" @@ -49,6 +51,10 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution + {63FCEA50-1505-11E9-B56E-0800200C9A66}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {63FCEA50-1505-11E9-B56E-0800200C9A66}.Debug|Any CPU.Build.0 = Debug|Any CPU + {63FCEA50-1505-11E9-B56E-0800200C9A66}.Release|Any CPU.ActiveCfg = Release|Any CPU + {63FCEA50-1505-11E9-B56E-0800200C9A66}.Release|Any CPU.Build.0 = Release|Any CPU {BD878CB3-BDB4-46AB-84EF-C3B4729F56BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {BD878CB3-BDB4-46AB-84EF-C3B4729F56BC}.Debug|Any CPU.Build.0 = Debug|Any CPU {BD878CB3-BDB4-46AB-84EF-C3B4729F56BC}.Release|Any CPU.ActiveCfg = Release|Any CPU diff --git a/src/csharp/Grpc/.gitignore b/src/csharp/Grpc/.gitignore new file mode 100644 index 00000000000..1746e3269ed --- /dev/null +++ b/src/csharp/Grpc/.gitignore @@ -0,0 +1,2 @@ +bin +obj diff --git a/src/csharp/Grpc/Grpc.csproj b/src/csharp/Grpc/Grpc.csproj new file mode 100644 index 00000000000..b71cd93ff9a --- /dev/null +++ b/src/csharp/Grpc/Grpc.csproj @@ -0,0 +1,26 @@ + + + + + + The gRPC Authors + Copyright 2015 The gRPC Authors + Metapackage for gRPC C# + https://github.com/grpc/grpc.github.io/raw/master/img/grpc_square_reverse_4x.png + Apache-2.0 + https://github.com/grpc/grpc + gRPC RPC HTTP/2 + $(GrpcCsharpVersion) + + + + net45;netstandard1.5;netstandard2.0 + + false + true + + + + + + diff --git a/src/csharp/README.md b/src/csharp/README.md index 9a91035d06a..c01cae0422d 100644 --- a/src/csharp/README.md +++ b/src/csharp/README.md @@ -40,6 +40,17 @@ See [Experimentally supported platforms](experimental) for instructions. See [Experimentally supported platforms](experimental) for instructions. +NUGET DEVELOPMENT FEED (NIGHTLY BUILDS) +-------------- + +In production, you should use officially released stable packages available on http://nuget.org, but if you want to test the newest upstream bug fixes and features early, you can can use the development nuget feed where new nuget builds are uploaded nightly. + +Feed URL (NuGet v2): https://grpc.jfrog.io/grpc/api/nuget/grpc-nuget-dev + +Feed URL (NuGet v3): https://grpc.jfrog.io/grpc/api/nuget/v3/grpc-nuget-dev + +The same development nuget packages and packages for other languages can also be found at https://packages.grpc.io/ + BUILD FROM SOURCE ----------------- @@ -103,5 +114,5 @@ THE NATIVE DEPENDENCY Internally, gRPC C# uses a native library written in C (gRPC C core) and invokes its functionality via P/Invoke. The fact that a native library is used should be fully transparent to the users and just installing the `Grpc.Core` NuGet package is the only step needed to use gRPC C# on all supported platforms. [API Reference]: https://grpc.io/grpc/csharp/api/Grpc.Core.html -[Helloworld Example]: ../../examples/csharp/helloworld +[Helloworld Example]: ../../examples/csharp/Helloworld [RouteGuide Tutorial]: https://grpc.io/docs/tutorials/basic/csharp.html diff --git a/src/csharp/build/dependencies.props b/src/csharp/build/dependencies.props new file mode 100644 index 00000000000..dd5f172c27b --- /dev/null +++ b/src/csharp/build/dependencies.props @@ -0,0 +1,7 @@ + + + + 1.22.0-dev + 3.7.0 + + diff --git a/src/csharp/build_packages_dotnetcli.bat b/src/csharp/build_packages_dotnetcli.bat index 27688360e9a..f500310865b 100755 --- a/src/csharp/build_packages_dotnetcli.bat +++ b/src/csharp/build_packages_dotnetcli.bat @@ -12,11 +12,6 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. -@rem Current package versions -set VERSION=1.17.0-dev - -@rem Adjust the location of nuget.exe -set NUGET=C:\nuget\nuget.exe set DOTNET=dotnet mkdir ..\..\artifacts @@ -29,20 +24,24 @@ powershell -Command "cp -r ..\..\input_artifacts\csharp_ext_* nativelibs" mkdir protoc_plugins powershell -Command "cp -r ..\..\input_artifacts\protoc_* protoc_plugins" +@rem Add current timestamp to dev nugets +expand_dev_version.sh + %DOTNET% restore Grpc.sln || goto :error @rem To be able to build, we also need to put grpc_csharp_ext to its normal location xcopy /Y /I nativelibs\csharp_ext_windows_x64\grpc_csharp_ext.dll ..\..\cmake\build\x64\Release\ +%DOTNET% pack --configuration Release Grpc.Core.Api --output ..\..\..\artifacts || goto :error %DOTNET% pack --configuration Release Grpc.Core --output ..\..\..\artifacts || goto :error %DOTNET% pack --configuration Release Grpc.Core.Testing --output ..\..\..\artifacts || goto :error %DOTNET% pack --configuration Release Grpc.Auth --output ..\..\..\artifacts || goto :error %DOTNET% pack --configuration Release Grpc.HealthCheck --output ..\..\..\artifacts || goto :error %DOTNET% pack --configuration Release Grpc.Reflection --output ..\..\..\artifacts || goto :error %DOTNET% pack --configuration Release Grpc.Tools --output ..\..\..\artifacts || goto :error - -%NUGET% pack Grpc.nuspec -Version %VERSION% -OutputDirectory ..\..\artifacts || goto :error -%NUGET% pack Grpc.Core.NativeDebug.nuspec -Version %VERSION% -OutputDirectory ..\..\artifacts +@rem build auxiliary packages +%DOTNET% pack --configuration Release Grpc --output ..\..\..\artifacts || goto :error +%DOTNET% pack --configuration Release Grpc.Core.NativeDebug --output ..\..\..\artifacts || goto :error @rem copy resulting nuget packages to artifacts directory xcopy /Y /I *.nupkg ..\..\artifacts\ || goto :error diff --git a/src/csharp/build_unitypackage.bat b/src/csharp/build_unitypackage.bat index dd74de0491a..2f4cd2739da 100644 --- a/src/csharp/build_unitypackage.bat +++ b/src/csharp/build_unitypackage.bat @@ -13,7 +13,7 @@ @rem limitations under the License. @rem Current package versions -set VERSION=1.17.0-dev +set VERSION=1.22.0-dev @rem Adjust the location of nuget.exe set NUGET=C:\nuget\nuget.exe @@ -40,6 +40,9 @@ xcopy /Y /I nativelibs\csharp_ext_windows_x64\grpc_csharp_ext.dll ..\..\cmake\bu @rem copy Grpc assemblies to the unity package skeleton @rem TODO(jtattermusch): Add Grpc.Auth assembly and its dependencies +copy /Y Grpc.Core.Api\bin\Release\net45\Grpc.Core.Api.dll unitypackage\unitypackage_skeleton\Plugins\Grpc.Core.Api\lib\net45\Grpc.Core.Api.dll || goto :error +copy /Y Grpc.Core.Api\bin\Release\net45\Grpc.Core.Api.pdb unitypackage\unitypackage_skeleton\Plugins\Grpc.Core.Api\lib\net45\Grpc.Core.Api.pdb || goto :error +copy /Y Grpc.Core.Api\bin\Release\net45\Grpc.Core.Api.xml unitypackage\unitypackage_skeleton\Plugins\Grpc.Core.Api\lib\net45\Grpc.Core.Api.xml || goto :error copy /Y Grpc.Core\bin\Release\net45\Grpc.Core.dll unitypackage\unitypackage_skeleton\Plugins\Grpc.Core\lib\net45\Grpc.Core.dll || goto :error copy /Y Grpc.Core\bin\Release\net45\Grpc.Core.pdb unitypackage\unitypackage_skeleton\Plugins\Grpc.Core\lib\net45\Grpc.Core.pdb || goto :error copy /Y Grpc.Core\bin\Release\net45\Grpc.Core.xml unitypackage\unitypackage_skeleton\Plugins\Grpc.Core\lib\net45\Grpc.Core.xml || goto :error diff --git a/src/csharp/doc/docfx.json b/src/csharp/doc/docfx.json index 0ce5f7262a0..36bf6573bb4 100644 --- a/src/csharp/doc/docfx.json +++ b/src/csharp/doc/docfx.json @@ -3,7 +3,8 @@ { "src": [ { - "files": ["Grpc.Core/Grpc.Core.csproj", + "files": ["Grpc.Core.Api/Grpc.Core.Api.csproj", + "Grpc.Core/Grpc.Core.csproj", "Grpc.Auth/Grpc.Auth.csproj", "Grpc.Core.Testing/Grpc.Core.Testing.csproj", "Grpc.HealthCheck/Grpc.HealthCheck.csproj", diff --git a/tools/run_tests/helper_scripts/run_lcov.sh b/src/csharp/expand_dev_version.sh old mode 100755 new mode 100644 similarity index 58% rename from tools/run_tests/helper_scripts/run_lcov.sh rename to src/csharp/expand_dev_version.sh index 9d8b6793fce..714762afac1 --- a/tools/run_tests/helper_scripts/run_lcov.sh +++ b/src/csharp/expand_dev_version.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2015 gRPC authors. +# Copyright 2019 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. @@ -13,19 +13,13 @@ # See the License for the specific language governing permissions and # limitations under the License. -set -ex +# Updates the GrpcSharpVersion property so that we can build +# dev nuget packages differentiated by timestamp. -out=$(readlink -f "${1:-coverage}") +set -e -root=$(readlink -f "$(dirname "$0")/../../..") -shift || true -tmp=$(mktemp) -cd "$root" -tools/run_tests/run_tests.py -c gcov -l c c++ "$@" || true -lcov --capture --directory . --output-file "$tmp" -genhtml "$tmp" --output-directory "$out" -rm "$tmp" -if which xdg-open > /dev/null -then - xdg-open "file://$out/index.html" -fi +cd "$(dirname "$0")" + +DEV_DATETIME_SUFFIX=$(date -u "+%Y%m%d%H%M") +# expand the -dev suffix to contain current timestamp +sed -ibak "s/-dev<\/GrpcCsharpVersion>/-dev${DEV_DATETIME_SUFFIX}<\/GrpcCsharpVersion>/" build/dependencies.props diff --git a/src/csharp/experimental/README.md b/src/csharp/experimental/README.md index 64515075ce0..b5c106e320c 100644 --- a/src/csharp/experimental/README.md +++ b/src/csharp/experimental/README.md @@ -14,7 +14,7 @@ Xamarin.Android `arm64-v8a` (some newer Android devices), `x86` (for emulator) Xamarin.iOS -- supported architectures: arm64 (iPhone 6+) and x86_64 (iPhone simulator) +- supported architectures: armv7, arm64 (iPhone 6+) and x86_64 (iPhone simulator) # Unity diff --git a/src/csharp/experimental/build_native_ext_for_ios.sh b/src/csharp/experimental/build_native_ext_for_ios.sh index 69c9cdf021c..130f4c51e96 100755 --- a/src/csharp/experimental/build_native_ext_for_ios.sh +++ b/src/csharp/experimental/build_native_ext_for_ios.sh @@ -13,7 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -# Helper script to crosscompile grpc_csharp_ext native extension for Android. +# Helper script to crosscompile grpc_csharp_ext native extension for iOS. set -ex @@ -28,9 +28,8 @@ function build { PATH_CC="$(xcrun --sdk $SDK --find clang)" PATH_CXX="$(xcrun --sdk $SDK --find clang++)" - # TODO(jtattermusch): add -mios-version-min=6.0 and -Wl,ios_version_min=6.0 - CPPFLAGS="-O2 -Wframe-larger-than=16384 -arch $ARCH -isysroot $(xcrun --sdk $SDK --show-sdk-path) -DPB_NO_PACKED_STRUCTS=1" - LDFLAGS="-arch $ARCH -isysroot $(xcrun --sdk $SDK --show-sdk-path)" + CPPFLAGS="-O2 -Wframe-larger-than=16384 -arch $ARCH -isysroot $(xcrun --sdk $SDK --show-sdk-path) -mios-version-min=6.0 -DPB_NO_PACKED_STRUCTS=1" + LDFLAGS="-arch $ARCH -isysroot $(xcrun --sdk $SDK --show-sdk-path) -Wl,ios_version_min=6.0" # TODO(jtattermusch): revisit the build arguments make -j4 static_csharp \ @@ -51,10 +50,12 @@ function fatten { mkdir -p libs/ios lipo -create -output libs/ios/lib$LIB_NAME.a \ + libs/ios_armv7/lib$LIB_NAME.a \ libs/ios_arm64/lib$LIB_NAME.a \ libs/ios_x86_64/lib$LIB_NAME.a } +build iphoneos armv7 build iphoneos arm64 build iphonesimulator x86_64 diff --git a/src/csharp/ext/grpc_csharp_ext.c b/src/csharp/ext/grpc_csharp_ext.c index ed002ae1fff..51e498bcfb8 100644 --- a/src/csharp/ext/grpc_csharp_ext.c +++ b/src/csharp/ext/grpc_csharp_ext.c @@ -59,12 +59,16 @@ typedef struct grpcsharp_batch_context { } send_status_from_server; grpc_metadata_array recv_initial_metadata; grpc_byte_buffer* recv_message; + grpc_byte_buffer_reader* recv_message_reader; struct { grpc_metadata_array trailing_metadata; grpc_status_code status; grpc_slice status_details; } recv_status_on_client; int recv_close_on_server_cancelled; + + /* reserve space for byte_buffer_reader */ + grpc_byte_buffer_reader reserved_recv_message_reader; } grpcsharp_batch_context; GPR_EXPORT grpcsharp_batch_context* GPR_CALLTYPE @@ -206,6 +210,9 @@ grpcsharp_batch_context_reset(grpcsharp_batch_context* ctx) { grpcsharp_metadata_array_destroy_metadata_only(&(ctx->recv_initial_metadata)); + if (ctx->recv_message_reader) { + grpc_byte_buffer_reader_destroy(ctx->recv_message_reader); + } grpc_byte_buffer_destroy(ctx->recv_message); grpcsharp_metadata_array_destroy_metadata_only( @@ -264,27 +271,42 @@ GPR_EXPORT intptr_t GPR_CALLTYPE grpcsharp_batch_context_recv_message_length( } /* - * Copies data from recv_message to a buffer. Fatal error occurs if - * buffer is too small. + * Gets the next slice from recv_message byte buffer. + * Returns 1 if a slice was get successfully, 0 if there are no more slices to + * read. Set slice_len to the length of the slice and the slice_data_ptr to + * point to slice's data. Caller must ensure that the byte buffer being read + * from stays alive as long as the data of the slice are being accessed + * (grpc_byte_buffer_reader_peek method is used internally) + * + * Remarks: + * Slices can only be iterated once. + * Initializes recv_message_buffer_reader if it was not initialized yet. */ -GPR_EXPORT void GPR_CALLTYPE grpcsharp_batch_context_recv_message_to_buffer( - const grpcsharp_batch_context* ctx, char* buffer, size_t buffer_len) { - grpc_byte_buffer_reader reader; - grpc_slice slice; - size_t offset = 0; +GPR_EXPORT int GPR_CALLTYPE +grpcsharp_batch_context_recv_message_next_slice_peek( + grpcsharp_batch_context* ctx, size_t* slice_len, uint8_t** slice_data_ptr) { + *slice_len = 0; + *slice_data_ptr = NULL; - GPR_ASSERT(grpc_byte_buffer_reader_init(&reader, ctx->recv_message)); - - while (grpc_byte_buffer_reader_next(&reader, &slice)) { - size_t len = GRPC_SLICE_LENGTH(slice); - GPR_ASSERT(offset + len <= buffer_len); - memcpy(buffer + offset, GRPC_SLICE_START_PTR(slice), - GRPC_SLICE_LENGTH(slice)); - offset += len; - grpc_slice_unref(slice); + if (!ctx->recv_message) { + return 0; } - grpc_byte_buffer_reader_destroy(&reader); + if (!ctx->recv_message_reader) { + ctx->recv_message_reader = &ctx->reserved_recv_message_reader; + GPR_ASSERT(grpc_byte_buffer_reader_init(ctx->recv_message_reader, + ctx->recv_message)); + } + + grpc_slice* slice_ptr; + if (!grpc_byte_buffer_reader_peek(ctx->recv_message_reader, &slice_ptr)) { + return 0; + } + + /* recv_message buffer must not be deleted before all the data is read */ + *slice_len = GRPC_SLICE_LENGTH(*slice_ptr); + *slice_data_ptr = GRPC_SLICE_START_PTR(*slice_ptr); + return 1; } GPR_EXPORT grpc_status_code GPR_CALLTYPE @@ -901,6 +923,21 @@ grpcsharp_server_request_call(grpc_server* server, grpc_completion_queue* cq, &(ctx->request_metadata), cq, cq, ctx); } +/* Native callback dispatcher */ + +typedef int(GPR_CALLTYPE* grpcsharp_native_callback_dispatcher_func)( + void* tag, void* arg0, void* arg1, void* arg2, void* arg3, void* arg4, + void* arg5); + +static grpcsharp_native_callback_dispatcher_func native_callback_dispatcher = + NULL; + +GPR_EXPORT void GPR_CALLTYPE grpcsharp_native_callback_dispatcher_init( + grpcsharp_native_callback_dispatcher_func func) { + GPR_ASSERT(func); + native_callback_dispatcher = func; +} + /* Security */ static char* default_pem_root_certs = NULL; @@ -927,21 +964,47 @@ grpcsharp_override_default_ssl_roots(const char* pem_root_certs) { grpc_set_ssl_roots_override_callback(override_ssl_roots_handler); } +static void grpcsharp_verify_peer_destroy_handler(void* userdata) { + native_callback_dispatcher(userdata, NULL, NULL, (void*)1, NULL, NULL, NULL); +} + +static int grpcsharp_verify_peer_handler(const char* target_name, + const char* peer_pem, void* userdata) { + return native_callback_dispatcher(userdata, (void*)target_name, + (void*)peer_pem, (void*)0, NULL, NULL, + NULL); +} + GPR_EXPORT grpc_channel_credentials* GPR_CALLTYPE grpcsharp_ssl_credentials_create(const char* pem_root_certs, const char* key_cert_pair_cert_chain, - const char* key_cert_pair_private_key) { + const char* key_cert_pair_private_key, + void* verify_peer_callback_tag) { grpc_ssl_pem_key_cert_pair key_cert_pair; + verify_peer_options verify_options; + grpc_ssl_pem_key_cert_pair* key_cert_pair_ptr = NULL; + verify_peer_options* verify_options_ptr = NULL; + if (key_cert_pair_cert_chain || key_cert_pair_private_key) { + memset(&key_cert_pair, 0, sizeof(key_cert_pair)); key_cert_pair.cert_chain = key_cert_pair_cert_chain; key_cert_pair.private_key = key_cert_pair_private_key; - return grpc_ssl_credentials_create(pem_root_certs, &key_cert_pair, NULL, - NULL); + key_cert_pair_ptr = &key_cert_pair; } else { GPR_ASSERT(!key_cert_pair_cert_chain); GPR_ASSERT(!key_cert_pair_private_key); - return grpc_ssl_credentials_create(pem_root_certs, NULL, NULL, NULL); } + + if (verify_peer_callback_tag != NULL) { + memset(&verify_options, 0, sizeof(verify_peer_options)); + verify_options.verify_peer_callback_userdata = verify_peer_callback_tag; + verify_options.verify_peer_destruct = grpcsharp_verify_peer_destroy_handler; + verify_options.verify_peer_callback = grpcsharp_verify_peer_handler; + verify_options_ptr = &verify_options; + } + + return grpc_ssl_credentials_create(pem_root_certs, key_cert_pair_ptr, + verify_options_ptr, NULL); } GPR_EXPORT void GPR_CALLTYPE @@ -1023,37 +1086,28 @@ GPR_EXPORT void GPR_CALLTYPE grpcsharp_metadata_credentials_notify_from_plugin( } } -typedef void(GPR_CALLTYPE* grpcsharp_metadata_interceptor_func)( - void* state, const char* service_url, const char* method_name, - grpc_credentials_plugin_metadata_cb cb, void* user_data, - int32_t is_destroy); - static int grpcsharp_get_metadata_handler( void* state, grpc_auth_metadata_context context, grpc_credentials_plugin_metadata_cb cb, void* user_data, grpc_metadata creds_md[GRPC_METADATA_CREDENTIALS_PLUGIN_SYNC_MAX], size_t* num_creds_md, grpc_status_code* status, const char** error_details) { - grpcsharp_metadata_interceptor_func interceptor = - (grpcsharp_metadata_interceptor_func)(intptr_t)state; - interceptor(state, context.service_url, context.method_name, cb, user_data, - 0); + native_callback_dispatcher(state, (void*)context.service_url, + (void*)context.method_name, cb, user_data, + (void*)0, NULL); return 0; /* Asynchronous return. */ } static void grpcsharp_metadata_credentials_destroy_handler(void* state) { - grpcsharp_metadata_interceptor_func interceptor = - (grpcsharp_metadata_interceptor_func)(intptr_t)state; - interceptor(state, NULL, NULL, NULL, NULL, 1); + native_callback_dispatcher(state, NULL, NULL, NULL, NULL, (void*)1, NULL); } GPR_EXPORT grpc_call_credentials* GPR_CALLTYPE -grpcsharp_metadata_credentials_create_from_plugin( - grpcsharp_metadata_interceptor_func metadata_interceptor) { +grpcsharp_metadata_credentials_create_from_plugin(void* callback_tag) { grpc_metadata_credentials_plugin plugin; plugin.get_metadata = grpcsharp_get_metadata_handler; plugin.destroy = grpcsharp_metadata_credentials_destroy_handler; - plugin.state = (void*)(intptr_t)metadata_interceptor; + plugin.state = callback_tag; plugin.type = ""; return grpc_metadata_credentials_create_from_plugin(plugin, NULL); } diff --git a/src/csharp/install_dotnet_sdk.ps1 b/src/csharp/install_dotnet_sdk.ps1 new file mode 100644 index 00000000000..57328fa9981 --- /dev/null +++ b/src/csharp/install_dotnet_sdk.ps1 @@ -0,0 +1,16 @@ +#!/usr/bin/env powershell +# Install dotnet SDK needed to build C# projects on Windows + +Set-StrictMode -Version 2 +$ErrorActionPreference = 'Stop' + +# avoid "Unknown error on a send" in Invoke-WebRequest +[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 + +$InstallScriptUrl = 'https://dot.net/v1/dotnet-install.ps1' +$InstallScriptPath = Join-Path "$env:TEMP" 'dotnet-install.ps1' + +# Download install script +Write-Host "Downloading install script: $InstallScriptUrl => $InstallScriptPath" +Invoke-WebRequest -Uri $InstallScriptUrl -OutFile $InstallScriptPath +&$InstallScriptPath -Version 2.1.504 diff --git a/src/csharp/tests.json b/src/csharp/tests.json index 760776f9e70..cacdb305d2e 100644 --- a/src/csharp/tests.json +++ b/src/csharp/tests.json @@ -7,8 +7,12 @@ "Grpc.Core.Internal.Tests.ChannelArgsSafeHandleTest", "Grpc.Core.Internal.Tests.CompletionQueueEventTest", "Grpc.Core.Internal.Tests.CompletionQueueSafeHandleTest", + "Grpc.Core.Internal.Tests.DefaultDeserializationContextTest", "Grpc.Core.Internal.Tests.DefaultObjectPoolTest", + "Grpc.Core.Internal.Tests.FakeBufferReaderManagerTest", "Grpc.Core.Internal.Tests.MetadataArraySafeHandleTest", + "Grpc.Core.Internal.Tests.ReusableSliceBufferTest", + "Grpc.Core.Internal.Tests.SliceTest", "Grpc.Core.Internal.Tests.TimespecTest", "Grpc.Core.Tests.AppDomainUnloadTest", "Grpc.Core.Tests.AuthContextTest", @@ -53,6 +57,8 @@ ], "Grpc.IntegrationTesting": [ "Grpc.IntegrationTesting.CustomErrorDetailsTest", + "Grpc.IntegrationTesting.ExternalDnsClientServerTest", + "Grpc.IntegrationTesting.ExternalDnsWithTracingClientServerTest", "Grpc.IntegrationTesting.GeneratedClientTest", "Grpc.IntegrationTesting.GeneratedServiceBaseTest", "Grpc.IntegrationTesting.HistogramTest", diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core.Api.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core.Api.meta new file mode 100644 index 00000000000..f5d5149c2a5 --- /dev/null +++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core.Api.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 9b4ba511bab164bf9a5d0db8bb681b05 +folderAsset: yes +timeCreated: 1531219385 +licenseType: Free +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core.Api/lib.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core.Api/lib.meta new file mode 100644 index 00000000000..88c1aedbae1 --- /dev/null +++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core.Api/lib.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 21a3894045fc74e85a09ab84c0e35c3a +folderAsset: yes +timeCreated: 1531219385 +licenseType: Free +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core.Api/lib/net45.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core.Api/lib/net45.meta new file mode 100644 index 00000000000..8012e3d581b --- /dev/null +++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core.Api/lib/net45.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 9fd1c7cd7b6ed4d5285de90a332fb93e +folderAsset: yes +timeCreated: 1531219385 +licenseType: Free +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core.Api/lib/net45/Grpc.Core.Api.dll.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core.Api/lib/net45/Grpc.Core.Api.dll.meta new file mode 100644 index 00000000000..7b939f861c8 --- /dev/null +++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core.Api/lib/net45/Grpc.Core.Api.dll.meta @@ -0,0 +1,32 @@ +fileFormatVersion: 2 +guid: c9bf7237d50ec4e99ba7d2c153b80e8f +timeCreated: 1531219386 +licenseType: Free +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + isPreloaded: 0 + isOverridable: 0 + platformData: + - first: + Any: + second: + enabled: 1 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + DefaultValueInitialized: true + - first: + Windows Store Apps: WindowsStoreApps + second: + enabled: 0 + settings: + CPU: AnyCPU + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core.Api/lib/net45/Grpc.Core.Api.pdb.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core.Api/lib/net45/Grpc.Core.Api.pdb.meta new file mode 100644 index 00000000000..48019325cdc --- /dev/null +++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core.Api/lib/net45/Grpc.Core.Api.pdb.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: bf384c9cae7a648c488af0193b3e74c0 +timeCreated: 1531219385 +licenseType: Free +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core.Api/lib/net45/Grpc.Core.Api.xml.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core.Api/lib/net45/Grpc.Core.Api.xml.meta new file mode 100644 index 00000000000..e3814dc5850 --- /dev/null +++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core.Api/lib/net45/Grpc.Core.Api.xml.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 0a4fb8823a783423880c9d8c9d3b5cf4 +timeCreated: 1531219386 +licenseType: Free +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/grpc_csharp_ext_dummy_stubs.c b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/grpc_csharp_ext_dummy_stubs.c new file mode 100644 index 00000000000..c2f9d20333d --- /dev/null +++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/grpc_csharp_ext_dummy_stubs.c @@ -0,0 +1,408 @@ + +// Copyright 2019 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. +// 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. + +// When building for Unity Android with il2cpp backend, Unity tries to link +// the __Internal PInvoke definitions (which are required by iOS) even though +// the .so/.dll will be actually used. This file provides dummy stubs to +// make il2cpp happy. +// See https://github.com/grpc/grpc/issues/16012 + +#include +#include + +void grpcsharp_init() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_shutdown() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_version_string() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_batch_context_create() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_batch_context_recv_initial_metadata() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_batch_context_recv_message_length() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_batch_context_recv_message_next_slice_peek() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_batch_context_recv_status_on_client_status() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_batch_context_recv_status_on_client_details() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_batch_context_recv_status_on_client_trailing_metadata() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_batch_context_recv_close_on_server_cancelled() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_batch_context_reset() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_batch_context_destroy() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_request_call_context_create() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_request_call_context_call() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_request_call_context_method() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_request_call_context_host() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_request_call_context_deadline() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_request_call_context_request_metadata() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_request_call_context_reset() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_request_call_context_destroy() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_composite_call_credentials_create() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_call_credentials_release() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_call_cancel() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_call_cancel_with_status() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_call_start_unary() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_call_start_client_streaming() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_call_start_server_streaming() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_call_start_duplex_streaming() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_call_send_message() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_call_send_close_from_client() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_call_send_status_from_server() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_call_recv_message() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_call_recv_initial_metadata() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_call_start_serverside() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_call_send_initial_metadata() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_call_set_credentials() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_call_get_peer() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_call_destroy() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_channel_args_create() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_channel_args_set_string() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_channel_args_set_integer() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_channel_args_destroy() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_override_default_ssl_roots() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_ssl_credentials_create() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_composite_channel_credentials_create() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_channel_credentials_release() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_insecure_channel_create() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_secure_channel_create() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_channel_create_call() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_channel_check_connectivity_state() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_channel_watch_connectivity_state() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_channel_get_target() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_channel_destroy() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_sizeof_grpc_event() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_completion_queue_create_async() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_completion_queue_create_sync() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_completion_queue_shutdown() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_completion_queue_next() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_completion_queue_pluck() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_completion_queue_destroy() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void gprsharp_free() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_metadata_array_create() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_metadata_array_add() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_metadata_array_count() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_metadata_array_get_key() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_metadata_array_get_value() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_metadata_array_destroy_full() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_redirect_log() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_native_callback_dispatcher_init() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_metadata_credentials_create_from_plugin() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_metadata_credentials_notify_from_plugin() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_ssl_server_credentials_create() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_server_credentials_release() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_server_create() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_server_register_completion_queue() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_server_add_insecure_http2_port() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_server_add_secure_http2_port() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_server_start() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_server_request_call() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_server_cancel_all_calls() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_server_shutdown_and_notify_callback() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_server_destroy() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_call_auth_context() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_auth_context_peer_identity_property_name() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_auth_context_property_iterator() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_auth_property_iterator_next() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_auth_context_release() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void gprsharp_now() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void gprsharp_inf_future() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void gprsharp_inf_past() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void gprsharp_convert_clock_type() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void gprsharp_sizeof_timespec() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_test_callback() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_test_nop() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_test_override_method() { + fprintf(stderr, "Should never reach here"); + abort(); +} diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/grpc_csharp_ext_dummy_stubs.c.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/grpc_csharp_ext_dummy_stubs.c.meta new file mode 100644 index 00000000000..d93af38e48a --- /dev/null +++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/grpc_csharp_ext_dummy_stubs.c.meta @@ -0,0 +1,93 @@ +fileFormatVersion: 2 +guid: 576b78662f1f8af4fa751f709b620f52 +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + isPreloaded: 0 + isOverridable: 0 + platformData: + - first: + '': Any + second: + enabled: 0 + settings: + Exclude Android: 0 + Exclude Editor: 1 + Exclude Linux: 1 + Exclude Linux64: 1 + Exclude LinuxUniversal: 1 + Exclude OSXUniversal: 1 + Exclude Win: 0 + Exclude Win64: 0 + - first: + Android: Android + second: + enabled: 1 + settings: + CPU: ARMv7 + - first: + Any: + second: + enabled: 0 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + CPU: AnyCPU + DefaultValueInitialized: true + OS: AnyOS + - first: + Facebook: Win + second: + enabled: 0 + settings: + CPU: AnyCPU + - first: + Facebook: Win64 + second: + enabled: 0 + settings: + CPU: AnyCPU + - first: + Standalone: Linux + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: Linux64 + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: LinuxUniversal + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: OSXUniversal + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: Win + second: + enabled: 1 + settings: + CPU: AnyCPU + - first: + Standalone: Win64 + second: + enabled: 1 + settings: + CPU: AnyCPU + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec index a95a120d213..401540209af 100644 --- a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec +++ b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec @@ -42,7 +42,7 @@ Pod::Spec.new do |s| # 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.17.0-dev' + v = '1.22.0-dev' s.version = v s.summary = 'The gRPC ProtoC plugin generates Objective-C files from .proto services.' s.description = <<-DESC @@ -101,10 +101,11 @@ Pod::Spec.new do |s| s.preserve_paths = plugin # Restrict the protoc version to the one supported by this plugin. - s.dependency '!ProtoCompiler', '3.6.0' + s.dependency '!ProtoCompiler', '3.7.0' # For the Protobuf dependency not to complain: s.ios.deployment_target = '7.0' s.osx.deployment_target = '10.9' + s.tvos.deployment_target = '10.0' # Restrict the gRPC runtime version to the one supported by this plugin. s.dependency 'gRPC-ProtoRPC', v diff --git a/src/objective-c/!ProtoCompiler.podspec b/src/objective-c/!ProtoCompiler.podspec index b98339941e5..58d74be4d4e 100644 --- a/src/objective-c/!ProtoCompiler.podspec +++ b/src/objective-c/!ProtoCompiler.podspec @@ -36,7 +36,7 @@ Pod::Spec.new do |s| # exclamation mark ensures that other "regular" pods will be able to find it as it'll be installed # before them. s.name = '!ProtoCompiler' - v = '3.6.0' + v = '3.7.0' s.version = v s.summary = 'The Protobuf Compiler (protoc) generates Objective-C files from .proto files' s.description = <<-DESC @@ -112,6 +112,7 @@ Pod::Spec.new do |s| # For the Protobuf dependency not to complain: s.ios.deployment_target = '7.0' s.osx.deployment_target = '10.9' + s.tvos.deployment_target = '10.0' # This is only for local development of protoc: If the Podfile brings this pod from a local # directory using `:path`, CocoaPods won't download the zip file and so the compiler won't be diff --git a/src/objective-c/BoringSSL-GRPC.podspec b/src/objective-c/BoringSSL-GRPC.podspec index 04e4d5768f2..2ec146e7ebe 100644 --- a/src/objective-c/BoringSSL-GRPC.podspec +++ b/src/objective-c/BoringSSL-GRPC.podspec @@ -1,4 +1,5 @@ + # This file has been automatically generated from a template file. # Please make modifications to # `templates/src/objective-c/BoringSSL-GRPC.podspec.template` instead. This @@ -38,7 +39,7 @@ Pod::Spec.new do |s| s.name = 'BoringSSL-GRPC' - version = '0.0.2' + version = '0.0.3' s.version = version s.summary = 'BoringSSL is a fork of OpenSSL that is designed to meet Google\'s needs.' # Adapted from the homepage: @@ -78,8 +79,9 @@ Pod::Spec.new do |s| :commit => "b29b21a81b32ec273f118f589f46d56ad3332420", } - s.ios.deployment_target = '5.0' + s.ios.deployment_target = '7.0' s.osx.deployment_target = '10.7' + s.tvos.deployment_target = '10.0' name = 'openssl_grpc' diff --git a/src/objective-c/GRPCClient/GRPCCall+ChannelArg.h b/src/objective-c/GRPCClient/GRPCCall+ChannelArg.h index 803f19dedfe..2ddd53a5c66 100644 --- a/src/objective-c/GRPCClient/GRPCCall+ChannelArg.h +++ b/src/objective-c/GRPCClient/GRPCCall+ChannelArg.h @@ -19,52 +19,20 @@ #include -typedef NS_ENUM(NSInteger, GRPCCompressAlgorithm) { - GRPCCompressNone, - GRPCCompressDeflate, - GRPCCompressGzip, -}; - -/** - * Methods to configure GRPC channel options. - */ +// Deprecated interface. Please use GRPCCallOptions instead. @interface GRPCCall (ChannelArg) -/** - * Use the provided @c userAgentPrefix at the beginning of the HTTP User Agent string for all calls - * to the specified @c host. - */ + (void)setUserAgentPrefix:(nonnull NSString *)userAgentPrefix forHost:(nonnull NSString *)host; - -/** 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)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; - -/** Enable/Disable automatic retry of gRPC calls on the channel. If automatic retry is enabled, the - * retry is controlled by server's service config. If automatic retry is disabled, failed calls are - * immediately returned to the application layer. */ + (void)enableRetry:(BOOL)enabled forHost:(nonnull NSString *)host; - -/** Set channel connection timeout and backoff parameters. All parameters are positive integers in - * milliseconds. Set a parameter to 0 to make gRPC use default value for that parameter. - * - * Refer to gRPC's doc at https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md for the - * details of each parameter. */ + (void)setMinConnectTimeout:(unsigned int)timeout initialBackoff:(unsigned int)initialBackoff maxBackoff:(unsigned int)maxBackoff diff --git a/src/objective-c/GRPCClient/GRPCCall+ChannelArg.m b/src/objective-c/GRPCClient/GRPCCall+ChannelArg.m index 0e631fb3adf..ae60d6208e1 100644 --- a/src/objective-c/GRPCClient/GRPCCall+ChannelArg.m +++ b/src/objective-c/GRPCClient/GRPCCall+ChannelArg.m @@ -18,6 +18,7 @@ #import "GRPCCall+ChannelArg.h" +#import "private/GRPCChannelPool.h" #import "private/GRPCHost.h" #import @@ -31,11 +32,11 @@ + (void)setResponseSizeLimit:(NSUInteger)limit forHost:(nonnull NSString *)host { GRPCHost *hostConfig = [GRPCHost hostWithAddress:host]; - hostConfig.responseSizeLimitOverride = @(limit); + hostConfig.responseSizeLimitOverride = limit; } + (void)closeOpenConnections { - [GRPCHost flushChannelCache]; + [[GRPCChannelPool sharedInstance] disconnectAllChannels]; } + (void)setDefaultCompressMethod:(GRPCCompressAlgorithm)algorithm forhost:(nonnull NSString *)host { diff --git a/src/objective-c/GRPCClient/GRPCCall+ChannelCredentials.h b/src/objective-c/GRPCClient/GRPCCall+ChannelCredentials.h index d7d15c4ee38..7d6f79b7655 100644 --- a/src/objective-c/GRPCClient/GRPCCall+ChannelCredentials.h +++ b/src/objective-c/GRPCClient/GRPCCall+ChannelCredentials.h @@ -18,20 +18,12 @@ #import "GRPCCall.h" -/** Helpers for setting TLS Trusted Roots, Client Certificates, and Private Key */ +// Deprecated interface. Please use GRPCCallOptions instead. @interface GRPCCall (ChannelCredentials) -/** - * Use the provided @c pemRootCert as the set of trusted root Certificate Authorities for @c host. - */ + (BOOL)setTLSPEMRootCerts:(nullable NSString *)pemRootCert forHost:(nonnull NSString *)host 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 - * used. - */ + (BOOL)setTLSPEMRootCerts:(nullable NSString *)pemRootCerts withPrivateKey:(nullable NSString *)pemPrivateKey withCertChain:(nullable NSString *)pemCertChain diff --git a/src/objective-c/GRPCClient/GRPCCall+Cronet.h b/src/objective-c/GRPCClient/GRPCCall+Cronet.h index 2a5f6e9cf0e..3059c6f1860 100644 --- a/src/objective-c/GRPCClient/GRPCCall+Cronet.h +++ b/src/objective-c/GRPCClient/GRPCCall+Cronet.h @@ -20,22 +20,11 @@ #import "GRPCCall.h" -/** - * Methods for using cronet transport. - */ +// Deprecated interface. Please use GRPCCallOptions instead. @interface GRPCCall (Cronet) -/** - * This method should be called before issuing the first RPC. It should be - * called only once. Create an instance of Cronet engine in your app elsewhere - * and pass the instance pointer in the stream_engine parameter. Once set, - * all subsequent RPCs will use Cronet transport. The method is not thread - * safe. - */ + (void)useCronetWithEngine:(stream_engine*)engine; - + (stream_engine*)cronetEngine; - + (BOOL)isUsingCronet; @end diff --git a/src/objective-c/GRPCClient/GRPCCall+OAuth2.h b/src/objective-c/GRPCClient/GRPCCall+OAuth2.h index adb1042aa0e..60cdc50bfda 100644 --- a/src/objective-c/GRPCClient/GRPCCall+OAuth2.h +++ b/src/objective-c/GRPCClient/GRPCCall+OAuth2.h @@ -18,34 +18,13 @@ #import "GRPCCall.h" -/** - * The protocol of an OAuth2 token object from which GRPCCall can acquire a token. - */ -@protocol GRPCAuthorizationProtocol -- (void)getTokenWithHandler:(void (^)(NSString *token))hander; -@end +#import "GRPCCallOptions.h" -/** Helpers for setting and reading headers compatible with OAuth2. */ +// Deprecated interface. Please use GRPCCallOptions instead. @interface GRPCCall (OAuth2) -/** - * Setting this property is equivalent to setting "Bearer " as the value of the - * request header with key "authorization" (the authorization header). Setting it to nil removes the - * authorization header from the request. - * The value obtained by getting the property is the OAuth2 bearer token if the authorization header - * of the request has the form "Bearer ", or nil otherwise. - */ -@property(atomic, copy) NSString *oauth2AccessToken; - -/** Returns the value (if any) of the "www-authenticate" response header (the challenge header). */ -@property(atomic, readonly) NSString *oauth2ChallengeHeader; - -/** - * The authorization token object to be used when starting the call. If the value is set to nil, no - * oauth authentication will be used. - * - * If tokenProvider exists, it takes precedence over the token set by oauth2AccessToken. - */ +@property(atomic, copy) NSString* oauth2AccessToken; +@property(atomic, copy, readonly) NSString* oauth2ChallengeHeader; @property(atomic, strong) id tokenProvider; @end diff --git a/src/objective-c/GRPCClient/GRPCCall+Tests.h b/src/objective-c/GRPCClient/GRPCCall+Tests.h index 5d35182ae52..edaa5ed582c 100644 --- a/src/objective-c/GRPCClient/GRPCCall+Tests.h +++ b/src/objective-c/GRPCClient/GRPCCall+Tests.h @@ -18,34 +18,13 @@ #import "GRPCCall.h" -/** - * Methods to let tune down the security of gRPC connections for specific hosts. These shouldn't be - * used in releases, but are sometimes needed for testing. - */ +// Deprecated interface. Please use GRPCCallOptions instead. @interface GRPCCall (Tests) -/** - * Establish all SSL connections to the provided host using the passed SSL target name and the root - * certificates found in the file at |certsPath|. - * - * Must be called before any gRPC call to that host is made. It's illegal to pass the same host to - * more than one invocation of the methods of this category. - */ + (void)useTestCertsPath:(NSString *)certsPath testName:(NSString *)testName forHost:(NSString *)host; - -/** - * Establish all connections to the provided host using cleartext instead of SSL. - * - * Must be called before any gRPC call to that host is made. It's illegal to pass the same host to - * more than one invocation of the methods of this category. - */ + (void)useInsecureConnectionsForHost:(NSString *)host; - -/** - * Resets all host configurations to their default values, and flushes all connections from the - * cache. - */ + (void)resetHostSettings; + @end diff --git a/src/objective-c/GRPCClient/GRPCCall+Tests.m b/src/objective-c/GRPCClient/GRPCCall+Tests.m index 0db3ad6b399..ac3b6a658f9 100644 --- a/src/objective-c/GRPCClient/GRPCCall+Tests.m +++ b/src/objective-c/GRPCClient/GRPCCall+Tests.m @@ -20,6 +20,8 @@ #import "private/GRPCHost.h" +#import "GRPCCallOptions.h" + @implementation GRPCCall (Tests) + (void)useTestCertsPath:(NSString *)certsPath @@ -42,7 +44,7 @@ + (void)useInsecureConnectionsForHost:(NSString *)host { GRPCHost *hostConfig = [GRPCHost hostWithAddress:host]; - hostConfig.secure = NO; + hostConfig.transportType = GRPCTransportTypeInsecure; } + (void)resetHostSettings { diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index e0ef8b1391f..a430d5ca158 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -37,6 +37,10 @@ #include +#include "GRPCCallOptions.h" + +NS_ASSUME_NONNULL_BEGIN + #pragma mark gRPC errors /** Domain of NSError objects produced by gRPC. */ @@ -131,7 +135,8 @@ typedef NS_ENUM(NSUInteger, GRPCErrorCode) { /** * The server is currently unavailable. This is most likely a transient condition and may be - * corrected by retrying with a backoff. + * corrected by retrying with a backoff. Note that it is not always safe to retry + * non-idempotent operations. */ GRPCErrorCodeUnavailable = 14, @@ -139,43 +144,163 @@ typedef NS_ENUM(NSUInteger, GRPCErrorCode) { GRPCErrorCodeDataLoss = 15, }; -/** - * Safety remark of a gRPC method as defined in RFC 2616 Section 9.1 - */ -typedef NS_ENUM(NSUInteger, GRPCCallSafety) { - /** Signal that there is no guarantees on how the call affects the server state. */ - 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. */ - GRPCCallSafetyCacheableRequest = 2, -}; - /** * Keys used in |NSError|'s |userInfo| dictionary to store the response headers and trailers sent by * the server. */ -extern id const kGRPCHeadersKey; -extern id const kGRPCTrailersKey; +extern NSString *const kGRPCHeadersKey; +extern NSString *const kGRPCTrailersKey; + +/** An object can implement this protocol to receive responses from server from a call. */ +@protocol GRPCResponseHandler + +@required + +/** + * All the responses must be issued to a user-provided dispatch queue. This property specifies the + * dispatch queue to be used for issuing the notifications. + */ +@property(atomic, readonly) dispatch_queue_t dispatchQueue; + +@optional + +/** + * Issued when initial metadata is received from the server. + */ +- (void)didReceiveInitialMetadata:(nullable NSDictionary *)initialMetadata; + +/** + * Issued when a message is received from the server. The message is the raw data received from the + * server, with decompression and without proto deserialization. + */ +- (void)didReceiveRawMessage:(nullable NSData *)message; + +/** + * Issued when a call finished. If the call finished successfully, \a error is nil and \a + * trainingMetadata consists any trailing metadata received from the server. Otherwise, \a error + * is non-nil and contains the corresponding error information, including gRPC error codes and + * error descriptions. + */ +- (void)didCloseWithTrailingMetadata:(nullable NSDictionary *)trailingMetadata + error:(nullable NSError *)error; + +/** + * Issued when flow control is enabled for the call and a message written with writeData: method of + * GRPCCall2 is passed to gRPC core with SEND_MESSAGE operation. + */ +- (void)didWriteData; + +@end + +/** + * Call related parameters. These parameters are automatically specified by Protobuf. If directly + * using the \a GRPCCall2 class, users should specify these parameters manually. + */ +@interface GRPCRequestOptions : NSObject + +- (instancetype)init NS_UNAVAILABLE; + ++ (instancetype) new NS_UNAVAILABLE; + +/** Initialize with all properties. */ +- (instancetype)initWithHost:(NSString *)host + path:(NSString *)path + safety:(GRPCCallSafety)safety NS_DESIGNATED_INITIALIZER; + +/** The host serving the RPC service. */ +@property(copy, readonly) NSString *host; +/** The path to the RPC call. */ +@property(copy, readonly) NSString *path; +/** + * Specify whether the call is idempotent or cachable. gRPC may select different HTTP verbs for the + * call based on this information. The default verb used by gRPC is POST. + */ +@property(readonly) GRPCCallSafety safety; + +@end #pragma mark GRPCCall -/** Represents a single gRPC remote call. */ +/** + * A \a GRPCCall2 object represents an RPC call. + */ +@interface GRPCCall2 : NSObject + +- (instancetype)init NS_UNAVAILABLE; + ++ (instancetype) new NS_UNAVAILABLE; + +/** + * Designated initializer for a call. + * \param requestOptions Protobuf generated parameters for the call. + * \param responseHandler The object to which responses should be issued. + * \param callOptions Options for the call. + */ +- (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions + responseHandler:(id)responseHandler + callOptions:(nullable GRPCCallOptions *)callOptions + NS_DESIGNATED_INITIALIZER; +/** + * Convenience initializer for a call that uses default call options (see GRPCCallOptions.m for + * the default options). + */ +- (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions + responseHandler:(id)responseHandler; + +/** + * Starts the call. This function must only be called once for each instance. + */ +- (void)start; + +/** + * Cancel the request of this call at best effort. It attempts to notify the server that the RPC + * should be cancelled, and issue didCloseWithTrailingMetadata:error: callback with error code + * CANCELED if no other error code has already been issued. + */ +- (void)cancel; + +/** + * Send a message to the server. Data are sent as raw bytes in gRPC message frames. + */ +- (void)writeData:(NSData *)data; + +/** + * Finish the RPC request and half-close the call. The server may still send messages and/or + * trailers to the client. The method must only be called once and after start is called. + */ +- (void)finish; + +/** + * Tell gRPC to receive the next N gRPC message from gRPC core. + * + * This method should only be used when flow control is enabled. When flow control is not enabled, + * this method is a no-op. + */ +- (void)receiveNextMessages:(NSUInteger)numberOfMessages; + +/** + * Get a copy of the original call options. + */ +@property(readonly, copy) GRPCCallOptions *callOptions; + +/** Get a copy of the original request options. */ +@property(readonly, copy) GRPCRequestOptions *requestOptions; + +@end + +NS_ASSUME_NONNULL_END + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnullability-completeness" + +/** + * This interface is deprecated. Please use \a GRPCcall2. + * + * Represents a single gRPC remote call. + */ @interface GRPCCall : GRXWriter -/** - * 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; - -/** - * The timeout for the RPC call in seconds. If set to 0, the call will not timeout. If set to - * positive, the gRPC call returns with status GRPCErrorCodeDeadlineExceeded if it is not completed - * within \a timeout seconds. A negative value is not allowed. - */ -@property NSTimeInterval timeout; +- (instancetype)init NS_UNAVAILABLE; /** * The container of the request headers of an RPC conforms to this protocol, which is a subset of @@ -236,7 +361,7 @@ extern id const kGRPCTrailersKey; */ - (instancetype)initWithHost:(NSString *)host path:(NSString *)path - requestsWriter:(GRXWriter *)requestsWriter NS_DESIGNATED_INITIALIZER; + requestsWriter:(GRXWriter *)requestWriter; /** * Finishes the request side of this call, notifies the server that the RPC should be cancelled, and @@ -245,21 +370,13 @@ extern id const kGRPCTrailersKey; - (void)cancel; /** - * Set the call flag for a specific host path. - * - * Host parameter should not contain the scheme (http:// or https://), only the name or IP addr - * and the port number, for example @"localhost:5050". + * The following methods are deprecated. */ + (void)setCallSafety:(GRPCCallSafety)callSafety host:(NSString *)host path:(NSString *)path; - -/** - * Set the dispatch queue to be used for callbacks. - * - * This configuration is only effective before the call starts. - */ +@property(atomic, copy, readwrite) NSString *serverName; +@property NSTimeInterval timeout; - (void)setResponseDispatchQueue:(dispatch_queue_t)queue; -// TODO(jcanizales): Let specify a deadline. As a category of GRXWriter? @end #pragma mark Backwards compatibiity @@ -282,3 +399,4 @@ DEPRECATED_MSG_ATTRIBUTE("Use NSDictionary or NSMutableDictionary instead.") @interface NSMutableDictionary (GRPCRequestHeaders) @end #pragma clang diagnostic pop +#pragma clang diagnostic pop diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 084fbdeb491..495f94289e7 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -20,11 +20,16 @@ #import "GRPCCall+OAuth2.h" +#import #import #import +#import #include #include +#import "GRPCCallOptions.h" +#import "private/GRPCChannelPool.h" +#import "private/GRPCCompletionQueue.h" #import "private/GRPCConnectivityMonitor.h" #import "private/GRPCHost.h" #import "private/GRPCRequestHeaders.h" @@ -51,7 +56,363 @@ const char *kCFStreamVarName = "grpc_cfstream"; // Make them read-write. @property(atomic, strong) NSDictionary *responseHeaders; @property(atomic, strong) NSDictionary *responseTrailers; -@property(atomic) BOOL isWaitingForToken; + +- (instancetype)initWithHost:(NSString *)host + path:(NSString *)path + callSafety:(GRPCCallSafety)safety + requestsWriter:(GRXWriter *)requestsWriter + callOptions:(GRPCCallOptions *)callOptions; + +- (instancetype)initWithHost:(NSString *)host + path:(NSString *)path + callSafety:(GRPCCallSafety)safety + requestsWriter:(GRXWriter *)requestsWriter + callOptions:(GRPCCallOptions *)callOptions + writeDone:(void (^)(void))writeDone; + +- (void)receiveNextMessages:(NSUInteger)numberOfMessages; + +@end + +@implementation GRPCRequestOptions + +- (instancetype)initWithHost:(NSString *)host path:(NSString *)path safety:(GRPCCallSafety)safety { + NSAssert(host.length != 0 && path.length != 0, @"host and path cannot be empty"); + if (host.length == 0 || path.length == 0) { + return nil; + } + if ((self = [super init])) { + _host = [host copy]; + _path = [path copy]; + _safety = safety; + } + return self; +} + +- (id)copyWithZone:(NSZone *)zone { + GRPCRequestOptions *request = + [[GRPCRequestOptions alloc] initWithHost:_host path:_path safety:_safety]; + + return request; +} + +@end + +@implementation GRPCCall2 { + /** Options for the call. */ + GRPCCallOptions *_callOptions; + /** The handler of responses. */ + id _handler; + + // Thread safety of ivars below are protected by _dispatchQueue. + + /** + * Make use of legacy GRPCCall to make calls. Nullified when call is finished. + */ + GRPCCall *_call; + /** Flags whether initial metadata has been published to response handler. */ + BOOL _initialMetadataPublished; + /** Streaming call writeable to the underlying call. */ + GRXBufferedPipe *_pipe; + /** Serial dispatch queue for tasks inside the call. */ + dispatch_queue_t _dispatchQueue; + /** Flags whether call has started. */ + BOOL _started; + /** Flags whether call has been canceled. */ + BOOL _canceled; + /** Flags whether call has been finished. */ + BOOL _finished; + /** The number of pending messages receiving requests. */ + NSUInteger _pendingReceiveNextMessages; +} + +- (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions + responseHandler:(id)responseHandler + callOptions:(GRPCCallOptions *)callOptions { + NSAssert(requestOptions.host.length != 0 && requestOptions.path.length != 0, + @"Neither host nor path can be nil."); + NSAssert(requestOptions.safety <= GRPCCallSafetyCacheableRequest, @"Invalid call safety value."); + NSAssert(responseHandler != nil, @"Response handler required."); + if (requestOptions.host.length == 0 || requestOptions.path.length == 0) { + return nil; + } + if (requestOptions.safety > GRPCCallSafetyCacheableRequest) { + return nil; + } + if (responseHandler == nil) { + return nil; + } + + if ((self = [super init])) { + _requestOptions = [requestOptions copy]; + if (callOptions == nil) { + _callOptions = [[GRPCCallOptions alloc] init]; + } else { + _callOptions = [callOptions copy]; + } + _handler = responseHandler; + _initialMetadataPublished = NO; + _pipe = [GRXBufferedPipe pipe]; + // Set queue QoS only when iOS version is 8.0 or above and Xcode version is 9.0 or above +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 || __MAC_OS_X_VERSION_MAX_ALLOWED >= 101300 + if (@available(iOS 8.0, macOS 10.10, *)) { + _dispatchQueue = dispatch_queue_create( + NULL, + dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, 0)); + } else { +#else + { +#endif + _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); + } + dispatch_set_target_queue(_dispatchQueue, responseHandler.dispatchQueue); + _started = NO; + _canceled = NO; + _finished = NO; + } + + return self; +} + +- (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions + responseHandler:(id)responseHandler { + return + [self initWithRequestOptions:requestOptions responseHandler:responseHandler callOptions:nil]; +} + +- (void)start { + GRPCCall *copiedCall = nil; + @synchronized(self) { + NSAssert(!_started, @"Call already started."); + NSAssert(!_canceled, @"Call already canceled."); + if (_started) { + return; + } + if (_canceled) { + return; + } + + _started = YES; + if (!_callOptions) { + _callOptions = [[GRPCCallOptions alloc] init]; + } + + _call = [[GRPCCall alloc] initWithHost:_requestOptions.host + path:_requestOptions.path + callSafety:_requestOptions.safety + requestsWriter:_pipe + callOptions:_callOptions + writeDone:^{ + @synchronized(self) { + if (self->_handler) { + [self issueDidWriteData]; + } + } + }]; + [_call setResponseDispatchQueue:_dispatchQueue]; + if (_callOptions.initialMetadata) { + [_call.requestHeaders addEntriesFromDictionary:_callOptions.initialMetadata]; + } + if (_pendingReceiveNextMessages > 0) { + [_call receiveNextMessages:_pendingReceiveNextMessages]; + _pendingReceiveNextMessages = 0; + } + copiedCall = _call; + } + + void (^valueHandler)(id value) = ^(id value) { + @synchronized(self) { + if (self->_handler) { + if (!self->_initialMetadataPublished) { + self->_initialMetadataPublished = YES; + [self issueInitialMetadata:self->_call.responseHeaders]; + } + if (value) { + [self issueMessage:value]; + } + } + } + }; + void (^completionHandler)(NSError *errorOrNil) = ^(NSError *errorOrNil) { + @synchronized(self) { + if (self->_handler) { + if (!self->_initialMetadataPublished) { + self->_initialMetadataPublished = YES; + [self issueInitialMetadata:self->_call.responseHeaders]; + } + [self issueClosedWithTrailingMetadata:self->_call.responseTrailers error:errorOrNil]; + } + // Clearing _call must happen *after* dispatching close in order to get trailing + // metadata from _call. + if (self->_call) { + // Clean up the request writers. This should have no effect to _call since its + // response writeable is already nullified. + [self->_pipe writesFinishedWithError:nil]; + self->_call = nil; + self->_pipe = nil; + } + } + }; + id responseWriteable = + [[GRXWriteable alloc] initWithValueHandler:valueHandler completionHandler:completionHandler]; + [copiedCall startWithWriteable:responseWriteable]; +} + +- (void)cancel { + GRPCCall *copiedCall = nil; + @synchronized(self) { + if (_canceled) { + return; + } + + _canceled = YES; + + copiedCall = _call; + _call = nil; + _pipe = nil; + + if ([_handler respondsToSelector:@selector(didCloseWithTrailingMetadata:error:)]) { + dispatch_async(_dispatchQueue, ^{ + // Copy to local so that block is freed after cancellation completes. + id copiedHandler = nil; + @synchronized(self) { + copiedHandler = self->_handler; + self->_handler = nil; + } + + [copiedHandler didCloseWithTrailingMetadata:nil + error:[NSError errorWithDomain:kGRPCErrorDomain + code:GRPCErrorCodeCancelled + userInfo:@{ + NSLocalizedDescriptionKey : + @"Canceled by app" + }]]; + }); + } else { + _handler = nil; + } + } + [copiedCall cancel]; +} + +- (void)writeData:(NSData *)data { + GRXBufferedPipe *copiedPipe = nil; + @synchronized(self) { + NSAssert(!_canceled, @"Call already canceled."); + NSAssert(!_finished, @"Call is half-closed before sending data."); + if (_canceled) { + return; + } + if (_finished) { + return; + } + + if (_pipe) { + copiedPipe = _pipe; + } + } + [copiedPipe writeValue:data]; +} + +- (void)finish { + GRXBufferedPipe *copiedPipe = nil; + @synchronized(self) { + NSAssert(_started, @"Call not started."); + NSAssert(!_canceled, @"Call already canceled."); + NSAssert(!_finished, @"Call already half-closed."); + if (!_started) { + return; + } + if (_canceled) { + return; + } + if (_finished) { + return; + } + + if (_pipe) { + copiedPipe = _pipe; + _pipe = nil; + } + _finished = YES; + } + [copiedPipe writesFinishedWithError:nil]; +} + +- (void)issueInitialMetadata:(NSDictionary *)initialMetadata { + @synchronized(self) { + if (initialMetadata != nil && + [_handler respondsToSelector:@selector(didReceiveInitialMetadata:)]) { + dispatch_async(_dispatchQueue, ^{ + id copiedHandler = nil; + @synchronized(self) { + copiedHandler = self->_handler; + } + [copiedHandler didReceiveInitialMetadata:initialMetadata]; + }); + } + } +} + +- (void)issueMessage:(id)message { + @synchronized(self) { + if (message != nil && [_handler respondsToSelector:@selector(didReceiveRawMessage:)]) { + dispatch_async(_dispatchQueue, ^{ + id copiedHandler = nil; + @synchronized(self) { + copiedHandler = self->_handler; + } + [copiedHandler didReceiveRawMessage:message]; + }); + } + } +} + +- (void)issueClosedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { + @synchronized(self) { + if ([_handler respondsToSelector:@selector(didCloseWithTrailingMetadata:error:)]) { + dispatch_async(_dispatchQueue, ^{ + id copiedHandler = nil; + @synchronized(self) { + copiedHandler = self->_handler; + // Clean up _handler so that no more responses are reported to the handler. + self->_handler = nil; + } + [copiedHandler didCloseWithTrailingMetadata:trailingMetadata error:error]; + }); + } else { + _handler = nil; + } + } +} + +- (void)issueDidWriteData { + @synchronized(self) { + if (_callOptions.flowControlEnabled && [_handler respondsToSelector:@selector(didWriteData)]) { + dispatch_async(_dispatchQueue, ^{ + id copiedHandler = nil; + @synchronized(self) { + copiedHandler = self->_handler; + }; + [copiedHandler didWriteData]; + }); + } + } +} + +- (void)receiveNextMessages:(NSUInteger)numberOfMessages { + // branching based on _callOptions.flowControlEnabled is handled inside _call + GRPCCall *copiedCall = nil; + @synchronized(self) { + copiedCall = _call; + if (copiedCall == nil) { + _pendingReceiveNextMessages += numberOfMessages; + return; + } + } + [copiedCall receiveNextMessages:numberOfMessages]; +} + @end // The following methods of a C gRPC call object aren't reentrant, and thus @@ -75,6 +436,8 @@ const char *kCFStreamVarName = "grpc_cfstream"; NSString *_host; NSString *_path; + GRPCCallSafety _callSafety; + GRPCCallOptions *_callOptions; GRPCWrappedCall *_wrappedCall; GRPCConnectivityMonitor *_connectivityMonitor; @@ -111,8 +474,17 @@ const char *kCFStreamVarName = "grpc_cfstream"; // queue dispatch_queue_t _responseQueue; - // Whether the call is finished. If it is, should not call finishWithError again. - BOOL _finished; + // The OAuth2 token fetched from a token provider. + NSString *_fetchedOauth2AccessToken; + + // The callback to be called when a write message op is done. + void (^_writeDone)(void); + + // Indicate a read request to core is pending. + BOOL _pendingCoreRead; + + // Indicate pending read message request from user. + NSUInteger _pendingReceiveNextMessages; } @synthesize state = _state; @@ -121,133 +493,158 @@ const char *kCFStreamVarName = "grpc_cfstream"; // Guarantees the code in {} block is invoked only once. See ref at: // https://developer.apple.com/documentation/objectivec/nsobject/1418639-initialize?language=objc if (self == [GRPCCall self]) { + // Enable CFStream by default by do not overwrite if the user explicitly disables CFStream with + // environment variable "grpc_cfstream=0" + setenv(kCFStreamVarName, "1", 0); grpc_init(); callFlags = [NSMutableDictionary dictionary]; } } + (void)setCallSafety:(GRPCCallSafety)callSafety host:(NSString *)host path:(NSString *)path { + if (host.length == 0 || path.length == 0) { + return; + } NSString *hostAndPath = [NSString stringWithFormat:@"%@/%@", host, path]; - switch (callSafety) { - case GRPCCallSafetyDefault: - callFlags[hostAndPath] = @0; - break; - case GRPCCallSafetyIdempotentRequest: - callFlags[hostAndPath] = @GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST; - break; - case GRPCCallSafetyCacheableRequest: - callFlags[hostAndPath] = @GRPC_INITIAL_METADATA_CACHEABLE_REQUEST; - break; - default: - break; + @synchronized(callFlags) { + switch (callSafety) { + case GRPCCallSafetyDefault: + callFlags[hostAndPath] = @0; + break; + case GRPCCallSafetyIdempotentRequest: + callFlags[hostAndPath] = @GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST; + break; + case GRPCCallSafetyCacheableRequest: + callFlags[hostAndPath] = @GRPC_INITIAL_METADATA_CACHEABLE_REQUEST; + break; + default: + break; + } } } + (uint32_t)callFlagsForHost:(NSString *)host path:(NSString *)path { NSString *hostAndPath = [NSString stringWithFormat:@"%@/%@", host, path]; - return [callFlags[hostAndPath] intValue]; -} - -- (instancetype)init { - return [self initWithHost:nil path:nil requestsWriter:nil]; + @synchronized(callFlags) { + return [callFlags[hostAndPath] intValue]; + } } // Designated initializer - (instancetype)initWithHost:(NSString *)host path:(NSString *)path requestsWriter:(GRXWriter *)requestWriter { + return [self initWithHost:host + path:path + callSafety:GRPCCallSafetyDefault + requestsWriter:requestWriter + callOptions:nil]; +} + +- (instancetype)initWithHost:(NSString *)host + path:(NSString *)path + callSafety:(GRPCCallSafety)safety + requestsWriter:(GRXWriter *)requestsWriter + callOptions:(GRPCCallOptions *)callOptions { + return [self initWithHost:host + path:path + callSafety:safety + requestsWriter:requestsWriter + callOptions:callOptions + writeDone:nil]; +} + +- (instancetype)initWithHost:(NSString *)host + path:(NSString *)path + callSafety:(GRPCCallSafety)safety + requestsWriter:(GRXWriter *)requestsWriter + callOptions:(GRPCCallOptions *)callOptions + writeDone:(void (^)(void))writeDone { + // Purposely using pointer rather than length (host.length == 0) for backwards compatibility. + NSAssert(host != nil && path != nil, @"Neither host nor path can be nil."); + NSAssert(safety <= GRPCCallSafetyCacheableRequest, @"Invalid call safety value."); + NSAssert(requestsWriter.state == GRXWriterStateNotStarted, + @"The requests writer can't be already started."); if (!host || !path) { - [NSException raise:NSInvalidArgumentException format:@"Neither host nor path can be nil."]; + return nil; } - if (requestWriter.state != GRXWriterStateNotStarted) { - [NSException raise:NSInvalidArgumentException - format:@"The requests writer can't be already started."]; + if (safety > GRPCCallSafetyCacheableRequest) { + return nil; } + if (requestsWriter.state != GRXWriterStateNotStarted) { + return nil; + } + if ((self = [super init])) { _host = [host copy]; _path = [path copy]; + _callSafety = safety; + _callOptions = [callOptions copy]; // Serial queue to invoke the non-reentrant methods of the grpc_call object. - _callQueue = dispatch_queue_create("io.grpc.call", NULL); - - _requestWriter = requestWriter; + _callQueue = dispatch_queue_create("io.grpc.call", DISPATCH_QUEUE_SERIAL); + _requestWriter = requestsWriter; _requestHeaders = [[GRPCRequestHeaders alloc] initWithCall:self]; + _writeDone = writeDone; - if ([requestWriter isKindOfClass:[GRXImmediateSingleWriter class]]) { + if ([requestsWriter isKindOfClass:[GRXImmediateSingleWriter class]]) { _unaryCall = YES; _unaryOpBatch = [NSMutableArray arrayWithCapacity:kMaxClientBatch]; } _responseQueue = dispatch_get_main_queue(); + + // do not start a read until initial metadata is received + _pendingReceiveNextMessages = 0; + _pendingCoreRead = YES; } return self; } - (void)setResponseDispatchQueue:(dispatch_queue_t)queue { - if (_state != GRXWriterStateNotStarted) { - return; + @synchronized(self) { + if (_state != GRXWriterStateNotStarted) { + return; + } + _responseQueue = queue; } - _responseQueue = queue; } #pragma mark Finish +// This function should support being called within a @synchronized(self) block in another function +// Should not manipulate _requestWriter for deadlock prevention. - (void)finishWithError:(NSError *)errorOrNil { @synchronized(self) { + if (_state == GRXWriterStateFinished) { + return; + } _state = GRXWriterStateFinished; + + if (errorOrNil) { + [_responseWriteable cancelWithError:errorOrNil]; + } else { + [_responseWriteable enqueueSuccessfulCompletion]; + } + + // 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; - } - - if (errorOrNil) { - [_responseWriteable cancelWithError:errorOrNil]; - } else { - [_responseWriteable enqueueSuccessfulCompletion]; - } - - // Connectivity monitor is not required for CFStream - char *enableCFStream = getenv(kCFStreamVarName); - if (enableCFStream == nil || enableCFStream[0] != '1') { - [GRPCConnectivityMonitor unregisterObserver:self]; - } - - // If the call isn't retained anywhere else, it can be deallocated now. - _retainSelf = nil; -} - -- (void)cancelCall { - // Can be called from any thread, any number of times. - [_wrappedCall cancel]; } - (void)cancel { - if (!self.isWaitingForToken) { - [self cancelCall]; - } else { - self.isWaitingForToken = NO; - } - [self - maybeFinishWithError:[NSError - errorWithDomain:kGRPCErrorDomain - code:GRPCErrorCodeCancelled - userInfo:@{NSLocalizedDescriptionKey : @"Canceled by app"}]]; -} - -- (void)maybeFinishWithError:(NSError *)errorOrNil { - BOOL toFinish = NO; @synchronized(self) { - if (_finished == NO) { - _finished = YES; - toFinish = YES; + if (_state == GRXWriterStateFinished) { + return; } + [self finishWithError:[NSError + errorWithDomain:kGRPCErrorDomain + code:GRPCErrorCodeCancelled + userInfo:@{NSLocalizedDescriptionKey : @"Canceled by app"}]]; + [_wrappedCall cancel]; } - if (toFinish == YES) { - [self finishWithError:errorOrNil]; - } + _requestWriter.state = GRXWriterStateFinished; } - (void)dealloc { @@ -272,23 +669,30 @@ const char *kCFStreamVarName = "grpc_cfstream"; // If the call is currently paused, this is a noop. Restarting the call will invoke this // method. // TODO(jcanizales): Rename to readResponseIfNotPaused. -- (void)startNextRead { +- (void)maybeStartNextRead { @synchronized(self) { - if (self.state == GRXWriterStatePaused) { + if (_state != GRXWriterStateStarted) { return; } + if (_callOptions.flowControlEnabled && (_pendingCoreRead || _pendingReceiveNextMessages == 0)) { + return; + } + _pendingCoreRead = YES; + _pendingReceiveNextMessages--; } dispatch_async(_callQueue, ^{ __weak GRPCCall *weakSelf = self; - __weak GRXConcurrentWriteable *weakWriteable = self->_responseWriteable; [self startReadWithHandler:^(grpc_byte_buffer *message) { - __strong GRPCCall *strongSelf = weakSelf; - __strong GRXConcurrentWriteable *strongWriteable = weakWriteable; if (message == NULL) { // No more messages from the server return; } + __strong GRPCCall *strongSelf = weakSelf; + if (strongSelf == nil) { + grpc_byte_buffer_destroy(message); + return; + } NSData *data = [NSData grpc_dataWithByteBuffer:message]; grpc_byte_buffer_destroy(message); if (!data) { @@ -296,37 +700,91 @@ const char *kCFStreamVarName = "grpc_cfstream"; // 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 cancelCall]; - [strongSelf - maybeFinishWithError:[NSError errorWithDomain:kGRPCErrorDomain - code:GRPCErrorCodeResourceExhausted - userInfo:@{ - NSLocalizedDescriptionKey : - @"Client does not have enough memory to " - @"hold the server response." - }]]; - return; + @synchronized(strongSelf) { + strongSelf->_pendingCoreRead = NO; + [strongSelf + finishWithError:[NSError errorWithDomain:kGRPCErrorDomain + code:GRPCErrorCodeResourceExhausted + userInfo:@{ + NSLocalizedDescriptionKey : + @"Client does not have enough memory to " + @"hold the server response." + }]]; + [strongSelf->_wrappedCall cancel]; + } + strongSelf->_requestWriter.state = GRXWriterStateFinished; + } else { + @synchronized(strongSelf) { + [strongSelf->_responseWriteable enqueueValue:data + completionHandler:^{ + __strong GRPCCall *strongSelf = weakSelf; + if (strongSelf) { + @synchronized(strongSelf) { + strongSelf->_pendingCoreRead = NO; + [strongSelf maybeStartNextRead]; + } + } + }]; + } } - [strongWriteable enqueueValue:data - completionHandler:^{ - [strongSelf startNextRead]; - }]; }]; }); } #pragma mark Send headers -- (void)sendHeaders:(NSDictionary *)headers { +- (void)sendHeaders { + // TODO (mxyan): Remove after deprecated methods are removed + uint32_t callSafetyFlags = 0; + switch (_callSafety) { + case GRPCCallSafetyDefault: + callSafetyFlags = 0; + break; + case GRPCCallSafetyIdempotentRequest: + callSafetyFlags = GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST; + break; + case GRPCCallSafetyCacheableRequest: + callSafetyFlags = GRPC_INITIAL_METADATA_CACHEABLE_REQUEST; + break; + } + + NSMutableDictionary *headers = [_requestHeaders mutableCopy]; + NSString *fetchedOauth2AccessToken; + @synchronized(self) { + fetchedOauth2AccessToken = _fetchedOauth2AccessToken; + } + if (fetchedOauth2AccessToken != nil) { + headers[@"authorization"] = [kBearerPrefix stringByAppendingString:fetchedOauth2AccessToken]; + } else if (_callOptions.oauth2AccessToken != nil) { + headers[@"authorization"] = + [kBearerPrefix stringByAppendingString:_callOptions.oauth2AccessToken]; + } + // TODO(jcanizales): Add error handlers for async failures GRPCOpSendMetadata *op = [[GRPCOpSendMetadata alloc] initWithMetadata:headers - flags:[GRPCCall callFlagsForHost:_host path:_path] + flags:callSafetyFlags handler:nil]; // No clean-up needed after SEND_INITIAL_METADATA - if (!_unaryCall) { - [_wrappedCall startBatchWithOperations:@[ op ]]; - } else { - [_unaryOpBatch addObject:op]; + dispatch_async(_callQueue, ^{ + if (!self->_unaryCall) { + [self->_wrappedCall startBatchWithOperations:@[ op ]]; + } else { + [self->_unaryOpBatch addObject:op]; + } + }); +} + +- (void)receiveNextMessages:(NSUInteger)numberOfMessages { + if (numberOfMessages == 0) { + return; + } + @synchronized(self) { + _pendingReceiveNextMessages += numberOfMessages; + + if (_state != GRXWriterStateStarted || !_callOptions.flowControlEnabled) { + return; + } + [self maybeStartNextRead]; } } @@ -342,12 +800,12 @@ const char *kCFStreamVarName = "grpc_cfstream"; // Resume the request writer. GRPCCall *strongSelf = weakSelf; if (strongSelf) { - @synchronized(strongSelf->_requestWriter) { - strongSelf->_requestWriter.state = GRXWriterStateStarted; + strongSelf->_requestWriter.state = GRXWriterStateStarted; + if (strongSelf->_writeDone) { + strongSelf->_writeDone(); } } }; - GRPCOpSendMessage *op = [[GRPCOpSendMessage alloc] initWithMessage:message handler:resumingHandler]; if (!_unaryCall) { @@ -360,13 +818,17 @@ const char *kCFStreamVarName = "grpc_cfstream"; } - (void)writeValue:(id)value { - // TODO(jcanizales): Throw/assert if value isn't NSData. + NSAssert([value isKindOfClass:[NSData class]], @"value must be of type NSData"); + + @synchronized(self) { + if (_state == GRXWriterStateFinished) { + return; + } + } // Pause the input and only resume it when the C layer notifies us that writes // can proceed. - @synchronized(_requestWriter) { - _requestWriter.state = GRXWriterStatePaused; - } + _requestWriter.state = GRXWriterStatePaused; dispatch_async(_callQueue, ^{ // Write error is not processed here. It is handled by op batch of GRPC_OP_RECV_STATUS_ON_CLIENT @@ -405,11 +867,13 @@ const char *kCFStreamVarName = "grpc_cfstream"; // The second one (completionHandler), whenever the RPC finishes for any reason. - (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] ]]; + dispatch_async(_callQueue, ^{ + // TODO(jcanizales): Add error handlers for async failures + [self->_wrappedCall + startBatchWithOperations:@[ [[GRPCOpRecvMetadata alloc] initWithHandler:headersHandler] ]]; + [self->_wrappedCall + startBatchWithOperations:@[ [[GRPCOpRecvStatus alloc] initWithHandler:completionHandler] ]]; + }); } - (void)invokeCall { @@ -418,8 +882,11 @@ const char *kCFStreamVarName = "grpc_cfstream"; // Response headers received. __strong GRPCCall *strongSelf = weakSelf; if (strongSelf) { - strongSelf.responseHeaders = headers; - [strongSelf startNextRead]; + @synchronized(strongSelf) { + strongSelf.responseHeaders = headers; + strongSelf->_pendingCoreRead = NO; + [strongSelf maybeStartNextRead]; + } } } completionHandler:^(NSError *error, NSDictionary *trailers) { @@ -433,71 +900,118 @@ const char *kCFStreamVarName = "grpc_cfstream"; [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; - } + // Since gRPC core does not guarantee the headers block being called before this block, + // responseHeaders might be nil. + userInfo[kGRPCHeadersKey] = strongSelf.responseHeaders; error = [NSError errorWithDomain:error.domain code:error.code userInfo:userInfo]; } - [strongSelf maybeFinishWithError:error]; + [strongSelf finishWithError:error]; + strongSelf->_requestWriter.state = GRXWriterStateFinished; } }]; - // Now that the RPC has been initiated, request writes can start. - @synchronized(_requestWriter) { - [_requestWriter startWithWriteable:self]; - } } #pragma mark GRXWriter implementation +// Lock acquired inside startWithWriteable: - (void)startCallWithWriteable:(id)writeable { - _responseWriteable = - [[GRXConcurrentWriteable alloc] initWithWriteable:writeable dispatchQueue:_responseQueue]; + @synchronized(self) { + if (_state == GRXWriterStateFinished) { + return; + } - _wrappedCall = [[GRPCWrappedCall alloc] initWithHost:_host - serverName:_serverName - path:_path - timeout:_timeout]; - NSAssert(_wrappedCall, @"Error allocating RPC objects. Low memory?"); + _responseWriteable = + [[GRXConcurrentWriteable alloc] initWithWriteable:writeable dispatchQueue:_responseQueue]; - [self sendHeaders:_requestHeaders]; - [self invokeCall]; + GRPCPooledChannel *channel = + [[GRPCChannelPool sharedInstance] channelWithHost:_host callOptions:_callOptions]; + _wrappedCall = [channel wrappedCallWithPath:_path + completionQueue:[GRPCCompletionQueue completionQueue] + callOptions:_callOptions]; - // Connectivity monitor is not required for CFStream - char *enableCFStream = getenv(kCFStreamVarName); - if (enableCFStream == nil || enableCFStream[0] != '1') { - [GRPCConnectivityMonitor registerObserver:self selector:@selector(connectivityChanged:)]; + if (_wrappedCall == nil) { + [self finishWithError:[NSError errorWithDomain:kGRPCErrorDomain + code:GRPCErrorCodeUnavailable + userInfo:@{ + NSLocalizedDescriptionKey : + @"Failed to create call or channel." + }]]; + return; + } + + [self sendHeaders]; + [self invokeCall]; + + // Connectivity monitor is not required for CFStream + char *enableCFStream = getenv(kCFStreamVarName); + if (enableCFStream == nil || enableCFStream[0] != '1') { + [GRPCConnectivityMonitor registerObserver:self selector:@selector(connectivityChanged:)]; + } } + + // Now that the RPC has been initiated, request writes can start. + [_requestWriter startWithWriteable:self]; } - (void)startWithWriteable:(id)writeable { + id tokenProvider = nil; @synchronized(self) { _state = GRXWriterStateStarted; + + // Create a retain cycle so that this instance lives until the RPC finishes (or is cancelled). + // This makes RPCs in which the call isn't externally retained possible (as long as it is + // started before being autoreleased). Care is taken not to retain self strongly in any of the + // blocks used in this implementation, so that the life of the instance is determined by this + // retain cycle. + _retainSelf = self; + + if (_callOptions == nil) { + GRPCMutableCallOptions *callOptions = [[GRPCHost callOptionsForHost:_host] mutableCopy]; + if (_serverName.length != 0) { + callOptions.serverAuthority = _serverName; + } + if (_timeout > 0) { + callOptions.timeout = _timeout; + } + uint32_t callFlags = [GRPCCall callFlagsForHost:_host path:_path]; + if (callFlags != 0) { + if (callFlags == GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST) { + _callSafety = GRPCCallSafetyIdempotentRequest; + } else if (callFlags == GRPC_INITIAL_METADATA_CACHEABLE_REQUEST) { + _callSafety = GRPCCallSafetyCacheableRequest; + } + } + + id tokenProvider = self.tokenProvider; + if (tokenProvider != nil) { + callOptions.authTokenProvider = tokenProvider; + } + _callOptions = callOptions; + } + + NSAssert(_callOptions.authTokenProvider == nil || _callOptions.oauth2AccessToken == nil, + @"authTokenProvider and oauth2AccessToken cannot be set at the same time"); + + tokenProvider = _callOptions.authTokenProvider; } - // Create a retain cycle so that this instance lives until the RPC finishes (or is cancelled). - // This makes RPCs in which the call isn't externally retained possible (as long as it is started - // before being autoreleased). - // Care is taken not to retain self strongly in any of the blocks used in this implementation, so - // that the life of the instance is determined by this retain cycle. - _retainSelf = self; - - if (self.tokenProvider != nil) { - self.isWaitingForToken = YES; + if (tokenProvider != nil) { __weak typeof(self) weakSelf = self; - [self.tokenProvider getTokenWithHandler:^(NSString *token) { - typeof(self) strongSelf = weakSelf; - if (strongSelf && strongSelf.isWaitingForToken) { - if (token) { - NSString *t = [kBearerPrefix stringByAppendingString:token]; - strongSelf.requestHeaders[kAuthorizationHeader] = t; + [tokenProvider getTokenWithHandler:^(NSString *token) { + __strong typeof(self) strongSelf = weakSelf; + if (strongSelf) { + BOOL startCall = NO; + @synchronized(strongSelf) { + if (strongSelf->_state != GRXWriterStateFinished) { + startCall = YES; + if (token) { + strongSelf->_fetchedOauth2AccessToken = [token copy]; + } + } + } + if (startCall) { + [strongSelf startCallWithWriteable:writeable]; } - [strongSelf startCallWithWriteable:writeable]; - strongSelf.isWaitingForToken = NO; } }]; } else { @@ -526,7 +1040,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; case GRXWriterStateStarted: if (_state == GRXWriterStatePaused) { _state = newState; - [self startNextRead]; + [self maybeStartNextRead]; } return; case GRXWriterStateNotStarted: @@ -536,16 +1050,21 @@ const char *kCFStreamVarName = "grpc_cfstream"; } - (void)connectivityChanged:(NSNotification *)note { - // Cancel underlying call upon this notification + // Cancel underlying call upon this notification. + + // Retain because connectivity manager only keeps weak reference to GRPCCall. __strong GRPCCall *strongSelf = self; if (strongSelf) { - [self cancelCall]; - [self - maybeFinishWithError:[NSError errorWithDomain:kGRPCErrorDomain - code:GRPCErrorCodeUnavailable - userInfo:@{ - NSLocalizedDescriptionKey : @"Connectivity lost." - }]]; + @synchronized(strongSelf) { + [_wrappedCall cancel]; + [strongSelf + finishWithError:[NSError errorWithDomain:kGRPCErrorDomain + code:GRPCErrorCodeUnavailable + userInfo:@{ + NSLocalizedDescriptionKey : @"Connectivity lost." + }]]; + } + strongSelf->_requestWriter.state = GRXWriterStateFinished; } } diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h new file mode 100644 index 00000000000..9f77652cae7 --- /dev/null +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -0,0 +1,369 @@ +/* + * + * 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. + * + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * Safety remark of a gRPC method as defined in RFC 2616 Section 9.1 + */ +typedef NS_ENUM(NSUInteger, GRPCCallSafety) { + /** Signal that there is no guarantees on how the call affects the server state. */ + 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. + */ + GRPCCallSafetyCacheableRequest = 2, +}; + +// Compression algorithm to be used by a gRPC call +typedef NS_ENUM(NSUInteger, GRPCCompressionAlgorithm) { + GRPCCompressNone = 0, + GRPCCompressDeflate, + GRPCCompressGzip, + GRPCStreamCompressGzip, +}; + +// GRPCCompressAlgorithm is deprecated; use GRPCCompressionAlgorithm +typedef GRPCCompressionAlgorithm GRPCCompressAlgorithm; + +/** The transport to be used by a gRPC call */ +typedef NS_ENUM(NSUInteger, GRPCTransportType) { + GRPCTransportTypeDefault = 0, + /** gRPC internal HTTP/2 stack with BoringSSL */ + GRPCTransportTypeChttp2BoringSSL = 0, + /** Cronet stack */ + GRPCTransportTypeCronet, + /** Insecure channel. FOR TEST ONLY! */ + GRPCTransportTypeInsecure, +}; + +/** + * Implement this protocol to provide a token to gRPC when a call is initiated. + */ +@protocol GRPCAuthorizationProtocol + +/** + * This method is called when gRPC is about to start the call. When OAuth token is acquired, + * \a handler is expected to be called with \a token being the new token to be used for this call. + */ +- (void)getTokenWithHandler:(void (^)(NSString *_Nullable token))handler; + +@end + +@interface GRPCCallOptions : NSObject + +// Call parameters +/** + * The authority for the RPC. If nil, the default authority will be used. + * + * Note: This property does not have effect on Cronet transport and will be ignored. + * Note: This property cannot be used to validate a self-signed server certificate. It control the + * :authority header field of the call and performs an extra check that server's certificate + * matches the :authority header. + */ +@property(copy, readonly, nullable) NSString *serverAuthority; + +/** + * The timeout for the RPC call in seconds. If set to 0, the call will not timeout. If set to + * positive, the gRPC call returns with status GRPCErrorCodeDeadlineExceeded if it is not completed + * within \a timeout seconds. A negative value is not allowed. + */ +@property(readonly) NSTimeInterval timeout; + +/** + * Enable flow control of a gRPC call. The option is default to NO. If set to YES, writeData: method + * should only be called at most once before a didWriteData callback is issued, and + * receiveNextMessage: must be called each time before gRPC call issues a didReceiveMessage + * callback. + */ +@property(readonly) BOOL flowControlEnabled; + +// OAuth2 parameters. Users of gRPC may specify one of the following two parameters. + +/** + * The OAuth2 access token string. The string is prefixed with "Bearer " then used as value of the + * request's "authorization" header field. This parameter should not be used simultaneously with + * \a authTokenProvider. + */ +@property(copy, readonly, nullable) NSString *oauth2AccessToken; + +/** + * The interface to get the OAuth2 access token string. gRPC will attempt to acquire token when + * initiating the call. This parameter should not be used simultaneously with \a oauth2AccessToken. + */ +@property(readonly, nullable) id authTokenProvider; + +/** + * Initial metadata key-value pairs that should be included in the request. + */ +@property(copy, readonly, nullable) NSDictionary *initialMetadata; + +// Channel parameters; take into account of channel signature. + +/** + * Custom string that is prefixed to a request's user-agent header field before gRPC's internal + * user-agent string. + */ +@property(copy, readonly, nullable) NSString *userAgentPrefix; + +/** + * The size limit for the response received from server. If it is exceeded, an error with status + * code GRPCErrorCodeResourceExhausted is returned. + */ +@property(readonly) NSUInteger responseSizeLimit; + +/** + * The compression algorithm to be used by the gRPC call. For more details refer to + * https://github.com/grpc/grpc/blob/master/doc/compression.md + */ +@property(readonly) GRPCCompressionAlgorithm compressionAlgorithm; + +/** + * Enable/Disable gRPC call's retry feature. The default is enabled. For details of this feature + * refer to + * https://github.com/grpc/proposal/blob/master/A6-client-retries.md + */ +@property(readonly) BOOL retryEnabled; + +// HTTP/2 keep-alive feature. The parameter \a keepaliveInterval specifies the interval between two +// PING frames. The parameter \a keepaliveTimeout specifies the length of the period for which the +// call should wait for PING ACK. If PING ACK is not received after this period, the call fails. +// Negative values are not allowed. +@property(readonly) NSTimeInterval keepaliveInterval; +@property(readonly) NSTimeInterval keepaliveTimeout; + +// Parameters for connection backoff. Negative values are not allowed. +// For details of gRPC's backoff behavior, refer to +// https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md +@property(readonly) NSTimeInterval connectMinTimeout; +@property(readonly) NSTimeInterval connectInitialBackoff; +@property(readonly) NSTimeInterval connectMaxBackoff; + +/** + * Specify channel args to be used for this call. For a list of channel args available, see + * grpc/grpc_types.h + */ +@property(copy, readonly, nullable) NSDictionary *additionalChannelArgs; + +// Parameters for SSL authentication. + +/** + * PEM format root certifications that is trusted. If set to nil, gRPC uses a list of default + * root certificates. + */ +@property(copy, readonly, nullable) NSString *PEMRootCertificates; + +/** + * PEM format private key for client authentication, if required by the server. + */ +@property(copy, readonly, nullable) NSString *PEMPrivateKey; + +/** + * PEM format certificate chain for client authentication, if required by the server. + */ +@property(copy, readonly, nullable) NSString *PEMCertificateChain; + +/** + * Select the transport type to be used for this call. + */ +@property(readonly) GRPCTransportType transportType; + +/** + * Override the hostname during the TLS hostname validation process. + */ +@property(copy, readonly, nullable) NSString *hostNameOverride; + +/** + * A string that specify the domain where channel is being cached. Channels with different domains + * will not get cached to the same connection. + */ +@property(copy, readonly, nullable) NSString *channelPoolDomain; + +/** + * Channel id allows control of channel caching within a channelPoolDomain. A call with a unique + * channelID will create a new channel (connection) instead of reusing an existing one. Multiple + * calls in the same channelPoolDomain using identical channelID are allowed to share connection + * if other channel options are also the same. + */ +@property(readonly) NSUInteger channelID; + +/** + * Return if the channel options are equal to another object. + */ +- (BOOL)hasChannelOptionsEqualTo:(GRPCCallOptions *)callOptions; + +/** + * Hash for channel options. + */ +@property(readonly) NSUInteger channelOptionsHash; + +@end + +@interface GRPCMutableCallOptions : GRPCCallOptions + +// Call parameters +/** + * The authority for the RPC. If nil, the default authority will be used. + * + * Note: This property does not have effect on Cronet transport and will be ignored. + * Note: This property cannot be used to validate a self-signed server certificate. It control the + * :authority header field of the call and performs an extra check that server's certificate + * matches the :authority header. + */ +@property(copy, readwrite, nullable) NSString *serverAuthority; + +/** + * The timeout for the RPC call in seconds. If set to 0, the call will not timeout. If set to + * positive, the gRPC call returns with status GRPCErrorCodeDeadlineExceeded if it is not completed + * within \a timeout seconds. Negative value is invalid; setting the parameter to negative value + * will reset the parameter to 0. + */ +@property(readwrite) NSTimeInterval timeout; + +/** + * Enable flow control of a gRPC call. The option is default to NO. If set to YES, writeData: method + * should only be called at most once before a didWriteData callback is issued, and + * receiveNextMessage: must be called each time before gRPC call can issue a didReceiveMessage + * callback. + * + * If writeData: method is called more than once before issuance of a didWriteData callback, gRPC + * will continue to queue the message and write them to gRPC core in order. However, the user + * assumes their own responsibility of flow control by keeping tracking of the pending writes in + * the call. + */ +@property(readwrite) BOOL flowControlEnabled; + +// OAuth2 parameters. Users of gRPC may specify one of the following two parameters. + +/** + * The OAuth2 access token string. The string is prefixed with "Bearer " then used as value of the + * request's "authorization" header field. This parameter should not be used simultaneously with + * \a authTokenProvider. + */ +@property(copy, readwrite, nullable) NSString *oauth2AccessToken; + +/** + * The interface to get the OAuth2 access token string. gRPC will attempt to acquire token when + * initiating the call. This parameter should not be used simultaneously with \a oauth2AccessToken. + */ +@property(readwrite, nullable) id authTokenProvider; + +/** + * Initial metadata key-value pairs that should be included in the request. + */ +@property(copy, readwrite, nullable) NSDictionary *initialMetadata; + +// Channel parameters; take into account of channel signature. + +/** + * Custom string that is prefixed to a request's user-agent header field before gRPC's internal + * user-agent string. + */ +@property(copy, readwrite, nullable) NSString *userAgentPrefix; + +/** + * The size limit for the response received from server. If it is exceeded, an error with status + * code GRPCErrorCodeResourceExhausted is returned. + */ +@property(readwrite) NSUInteger responseSizeLimit; + +/** + * The compression algorithm to be used by the gRPC call. For more details refer to + * https://github.com/grpc/grpc/blob/master/doc/compression.md + */ +@property(readwrite) GRPCCompressionAlgorithm compressionAlgorithm; + +/** + * Enable/Disable gRPC call's retry feature. The default is enabled. For details of this feature + * refer to + * https://github.com/grpc/proposal/blob/master/A6-client-retries.md + */ +@property(readwrite) BOOL retryEnabled; + +// HTTP/2 keep-alive feature. The parameter \a keepaliveInterval specifies the interval between two +// PING frames. The parameter \a keepaliveTimeout specifies the length of the period for which the +// call should wait for PING ACK. If PING ACK is not received after this period, the call fails. +// Negative values are invalid; setting these parameters to negative value will reset the +// corresponding parameter to 0. +@property(readwrite) NSTimeInterval keepaliveInterval; +@property(readwrite) NSTimeInterval keepaliveTimeout; + +// Parameters for connection backoff. Negative value is invalid; setting the parameters to negative +// value will reset corresponding parameter to 0. +// For details of gRPC's backoff behavior, refer to +// https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md +@property(readwrite) NSTimeInterval connectMinTimeout; +@property(readwrite) NSTimeInterval connectInitialBackoff; +@property(readwrite) NSTimeInterval connectMaxBackoff; + +/** + * Specify channel args to be used for this call. For a list of channel args available, see + * grpc/grpc_types.h + */ +@property(copy, readwrite, nullable) NSDictionary *additionalChannelArgs; + +// Parameters for SSL authentication. + +/** + * PEM format root certifications that is trusted. If set to nil, gRPC uses a list of default + * root certificates. + */ +@property(copy, readwrite, nullable) NSString *PEMRootCertificates; + +/** + * PEM format private key for client authentication, if required by the server. + */ +@property(copy, readwrite, nullable) NSString *PEMPrivateKey; + +/** + * PEM format certificate chain for client authentication, if required by the server. + */ +@property(copy, readwrite, nullable) NSString *PEMCertificateChain; + +/** + * Select the transport type to be used for this call. + */ +@property(readwrite) GRPCTransportType transportType; + +/** + * Override the hostname during the TLS hostname validation process. + */ +@property(copy, readwrite, nullable) NSString *hostNameOverride; + +/** + * A string that specify the domain where channel is being cached. Channels with different domains + * will not get cached to the same channel. For example, a gRPC example app may use the channel pool + * domain 'io.grpc.example' so that its calls do not reuse the channel created by other modules in + * the same process. + */ +@property(copy, readwrite, nullable) NSString *channelPoolDomain; + +/** + * Channel id allows a call to force creating a new channel (connection) rather than using a cached + * channel. Calls using distinct channelID's will not get cached to the same channel. + */ +@property(readwrite) NSUInteger channelID; + +@end + +NS_ASSUME_NONNULL_END diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m new file mode 100644 index 00000000000..e5766414c99 --- /dev/null +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -0,0 +1,541 @@ +/* + * + * 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. + * + */ + +#import "GRPCCallOptions.h" +#import "internal/GRPCCallOptions+Internal.h" + +// The default values for the call options. +static NSString *const kDefaultServerAuthority = nil; +static const NSTimeInterval kDefaultTimeout = 0; +static const BOOL kDefaultFlowControlEnabled = NO; +static NSDictionary *const kDefaultInitialMetadata = nil; +static NSString *const kDefaultUserAgentPrefix = nil; +static const NSUInteger kDefaultResponseSizeLimit = 0; +static const GRPCCompressionAlgorithm kDefaultCompressionAlgorithm = GRPCCompressNone; +static const BOOL kDefaultRetryEnabled = YES; +static const NSTimeInterval kDefaultKeepaliveInterval = 0; +static const NSTimeInterval kDefaultKeepaliveTimeout = 0; +static const NSTimeInterval kDefaultConnectMinTimeout = 0; +static const NSTimeInterval kDefaultConnectInitialBackoff = 0; +static const NSTimeInterval kDefaultConnectMaxBackoff = 0; +static NSDictionary *const kDefaultAdditionalChannelArgs = nil; +static NSString *const kDefaultPEMRootCertificates = nil; +static NSString *const kDefaultPEMPrivateKey = nil; +static NSString *const kDefaultPEMCertificateChain = nil; +static NSString *const kDefaultOauth2AccessToken = nil; +static const id kDefaultAuthTokenProvider = nil; +static const GRPCTransportType kDefaultTransportType = GRPCTransportTypeChttp2BoringSSL; +static NSString *const kDefaultHostNameOverride = nil; +static const id kDefaultLogContext = nil; +static NSString *const kDefaultChannelPoolDomain = nil; +static const NSUInteger kDefaultChannelID = 0; + +// Check if two objects are equal. Returns YES if both are nil; +static BOOL areObjectsEqual(id obj1, id obj2) { + if (obj1 == obj2) { + return YES; + } + if (obj1 == nil || obj2 == nil) { + return NO; + } + return [obj1 isEqual:obj2]; +} + +@implementation GRPCCallOptions { + @protected + NSString *_serverAuthority; + NSTimeInterval _timeout; + BOOL _flowControlEnabled; + NSString *_oauth2AccessToken; + id _authTokenProvider; + NSDictionary *_initialMetadata; + NSString *_userAgentPrefix; + NSUInteger _responseSizeLimit; + GRPCCompressionAlgorithm _compressionAlgorithm; + BOOL _retryEnabled; + NSTimeInterval _keepaliveInterval; + NSTimeInterval _keepaliveTimeout; + NSTimeInterval _connectMinTimeout; + NSTimeInterval _connectInitialBackoff; + NSTimeInterval _connectMaxBackoff; + NSDictionary *_additionalChannelArgs; + NSString *_PEMRootCertificates; + NSString *_PEMPrivateKey; + NSString *_PEMCertificateChain; + GRPCTransportType _transportType; + NSString *_hostNameOverride; + id _logContext; + NSString *_channelPoolDomain; + NSUInteger _channelID; +} + +@synthesize serverAuthority = _serverAuthority; +@synthesize timeout = _timeout; +@synthesize flowControlEnabled = _flowControlEnabled; +@synthesize oauth2AccessToken = _oauth2AccessToken; +@synthesize authTokenProvider = _authTokenProvider; +@synthesize initialMetadata = _initialMetadata; +@synthesize userAgentPrefix = _userAgentPrefix; +@synthesize responseSizeLimit = _responseSizeLimit; +@synthesize compressionAlgorithm = _compressionAlgorithm; +@synthesize retryEnabled = _retryEnabled; +@synthesize keepaliveInterval = _keepaliveInterval; +@synthesize keepaliveTimeout = _keepaliveTimeout; +@synthesize connectMinTimeout = _connectMinTimeout; +@synthesize connectInitialBackoff = _connectInitialBackoff; +@synthesize connectMaxBackoff = _connectMaxBackoff; +@synthesize additionalChannelArgs = _additionalChannelArgs; +@synthesize PEMRootCertificates = _PEMRootCertificates; +@synthesize PEMPrivateKey = _PEMPrivateKey; +@synthesize PEMCertificateChain = _PEMCertificateChain; +@synthesize transportType = _transportType; +@synthesize hostNameOverride = _hostNameOverride; +@synthesize logContext = _logContext; +@synthesize channelPoolDomain = _channelPoolDomain; +@synthesize channelID = _channelID; + +- (instancetype)init { + return [self initWithServerAuthority:kDefaultServerAuthority + timeout:kDefaultTimeout + flowControlEnabled:kDefaultFlowControlEnabled + oauth2AccessToken:kDefaultOauth2AccessToken + authTokenProvider:kDefaultAuthTokenProvider + initialMetadata:kDefaultInitialMetadata + userAgentPrefix:kDefaultUserAgentPrefix + responseSizeLimit:kDefaultResponseSizeLimit + compressionAlgorithm:kDefaultCompressionAlgorithm + retryEnabled:kDefaultRetryEnabled + keepaliveInterval:kDefaultKeepaliveInterval + keepaliveTimeout:kDefaultKeepaliveTimeout + connectMinTimeout:kDefaultConnectMinTimeout + connectInitialBackoff:kDefaultConnectInitialBackoff + connectMaxBackoff:kDefaultConnectMaxBackoff + additionalChannelArgs:kDefaultAdditionalChannelArgs + PEMRootCertificates:kDefaultPEMRootCertificates + PEMPrivateKey:kDefaultPEMPrivateKey + PEMCertificateChain:kDefaultPEMCertificateChain + transportType:kDefaultTransportType + hostNameOverride:kDefaultHostNameOverride + logContext:kDefaultLogContext + channelPoolDomain:kDefaultChannelPoolDomain + channelID:kDefaultChannelID]; +} + +- (instancetype)initWithServerAuthority:(NSString *)serverAuthority + timeout:(NSTimeInterval)timeout + flowControlEnabled:(BOOL)flowControlEnabled + oauth2AccessToken:(NSString *)oauth2AccessToken + authTokenProvider:(id)authTokenProvider + initialMetadata:(NSDictionary *)initialMetadata + userAgentPrefix:(NSString *)userAgentPrefix + responseSizeLimit:(NSUInteger)responseSizeLimit + compressionAlgorithm:(GRPCCompressionAlgorithm)compressionAlgorithm + retryEnabled:(BOOL)retryEnabled + keepaliveInterval:(NSTimeInterval)keepaliveInterval + keepaliveTimeout:(NSTimeInterval)keepaliveTimeout + connectMinTimeout:(NSTimeInterval)connectMinTimeout + connectInitialBackoff:(NSTimeInterval)connectInitialBackoff + connectMaxBackoff:(NSTimeInterval)connectMaxBackoff + additionalChannelArgs:(NSDictionary *)additionalChannelArgs + PEMRootCertificates:(NSString *)PEMRootCertificates + PEMPrivateKey:(NSString *)PEMPrivateKey + PEMCertificateChain:(NSString *)PEMCertificateChain + transportType:(GRPCTransportType)transportType + hostNameOverride:(NSString *)hostNameOverride + logContext:(id)logContext + channelPoolDomain:(NSString *)channelPoolDomain + channelID:(NSUInteger)channelID { + if ((self = [super init])) { + _serverAuthority = [serverAuthority copy]; + _timeout = timeout < 0 ? 0 : timeout; + _flowControlEnabled = flowControlEnabled; + _oauth2AccessToken = [oauth2AccessToken copy]; + _authTokenProvider = authTokenProvider; + _initialMetadata = + initialMetadata == nil + ? nil + : [[NSDictionary alloc] initWithDictionary:initialMetadata copyItems:YES]; + _userAgentPrefix = [userAgentPrefix copy]; + _responseSizeLimit = responseSizeLimit; + _compressionAlgorithm = compressionAlgorithm; + _retryEnabled = retryEnabled; + _keepaliveInterval = keepaliveInterval < 0 ? 0 : keepaliveInterval; + _keepaliveTimeout = keepaliveTimeout < 0 ? 0 : keepaliveTimeout; + _connectMinTimeout = connectMinTimeout < 0 ? 0 : connectMinTimeout; + _connectInitialBackoff = connectInitialBackoff < 0 ? 0 : connectInitialBackoff; + _connectMaxBackoff = connectMaxBackoff < 0 ? 0 : connectMaxBackoff; + _additionalChannelArgs = + additionalChannelArgs == nil + ? nil + : [[NSDictionary alloc] initWithDictionary:additionalChannelArgs copyItems:YES]; + _PEMRootCertificates = [PEMRootCertificates copy]; + _PEMPrivateKey = [PEMPrivateKey copy]; + _PEMCertificateChain = [PEMCertificateChain copy]; + _transportType = transportType; + _hostNameOverride = [hostNameOverride copy]; + _logContext = logContext; + _channelPoolDomain = [channelPoolDomain copy]; + _channelID = channelID; + } + return self; +} + +- (nonnull id)copyWithZone:(NSZone *)zone { + GRPCCallOptions *newOptions = + [[GRPCCallOptions allocWithZone:zone] initWithServerAuthority:_serverAuthority + timeout:_timeout + flowControlEnabled:_flowControlEnabled + oauth2AccessToken:_oauth2AccessToken + authTokenProvider:_authTokenProvider + initialMetadata:_initialMetadata + userAgentPrefix:_userAgentPrefix + responseSizeLimit:_responseSizeLimit + compressionAlgorithm:_compressionAlgorithm + retryEnabled:_retryEnabled + keepaliveInterval:_keepaliveInterval + keepaliveTimeout:_keepaliveTimeout + connectMinTimeout:_connectMinTimeout + connectInitialBackoff:_connectInitialBackoff + connectMaxBackoff:_connectMaxBackoff + additionalChannelArgs:_additionalChannelArgs + PEMRootCertificates:_PEMRootCertificates + PEMPrivateKey:_PEMPrivateKey + PEMCertificateChain:_PEMCertificateChain + transportType:_transportType + hostNameOverride:_hostNameOverride + logContext:_logContext + channelPoolDomain:_channelPoolDomain + channelID:_channelID]; + return newOptions; +} + +- (nonnull id)mutableCopyWithZone:(NSZone *)zone { + GRPCMutableCallOptions *newOptions = [[GRPCMutableCallOptions allocWithZone:zone] + initWithServerAuthority:[_serverAuthority copy] + timeout:_timeout + flowControlEnabled:_flowControlEnabled + oauth2AccessToken:[_oauth2AccessToken copy] + authTokenProvider:_authTokenProvider + initialMetadata:[[NSDictionary alloc] initWithDictionary:_initialMetadata + copyItems:YES] + userAgentPrefix:[_userAgentPrefix copy] + responseSizeLimit:_responseSizeLimit + compressionAlgorithm:_compressionAlgorithm + retryEnabled:_retryEnabled + keepaliveInterval:_keepaliveInterval + keepaliveTimeout:_keepaliveTimeout + connectMinTimeout:_connectMinTimeout + connectInitialBackoff:_connectInitialBackoff + connectMaxBackoff:_connectMaxBackoff + additionalChannelArgs:[[NSDictionary alloc] initWithDictionary:_additionalChannelArgs + copyItems:YES] + PEMRootCertificates:[_PEMRootCertificates copy] + PEMPrivateKey:[_PEMPrivateKey copy] + PEMCertificateChain:[_PEMCertificateChain copy] + transportType:_transportType + hostNameOverride:[_hostNameOverride copy] + logContext:_logContext + channelPoolDomain:[_channelPoolDomain copy] + channelID:_channelID]; + return newOptions; +} + +- (BOOL)hasChannelOptionsEqualTo:(GRPCCallOptions *)callOptions { + if (callOptions == nil) return NO; + if (!areObjectsEqual(callOptions.userAgentPrefix, _userAgentPrefix)) return NO; + if (!(callOptions.responseSizeLimit == _responseSizeLimit)) return NO; + if (!(callOptions.compressionAlgorithm == _compressionAlgorithm)) return NO; + if (!(callOptions.retryEnabled == _retryEnabled)) return NO; + if (!(callOptions.keepaliveInterval == _keepaliveInterval)) return NO; + if (!(callOptions.keepaliveTimeout == _keepaliveTimeout)) return NO; + if (!(callOptions.connectMinTimeout == _connectMinTimeout)) return NO; + if (!(callOptions.connectInitialBackoff == _connectInitialBackoff)) return NO; + if (!(callOptions.connectMaxBackoff == _connectMaxBackoff)) return NO; + if (!areObjectsEqual(callOptions.additionalChannelArgs, _additionalChannelArgs)) return NO; + if (!areObjectsEqual(callOptions.PEMRootCertificates, _PEMRootCertificates)) return NO; + if (!areObjectsEqual(callOptions.PEMPrivateKey, _PEMPrivateKey)) return NO; + if (!areObjectsEqual(callOptions.PEMCertificateChain, _PEMCertificateChain)) return NO; + if (!areObjectsEqual(callOptions.hostNameOverride, _hostNameOverride)) return NO; + if (!(callOptions.transportType == _transportType)) return NO; + if (!areObjectsEqual(callOptions.logContext, _logContext)) return NO; + if (!areObjectsEqual(callOptions.channelPoolDomain, _channelPoolDomain)) return NO; + if (!(callOptions.channelID == _channelID)) return NO; + + return YES; +} + +- (NSUInteger)channelOptionsHash { + NSUInteger result = 0; + result ^= _userAgentPrefix.hash; + result ^= _responseSizeLimit; + result ^= _compressionAlgorithm; + result ^= _retryEnabled; + result ^= (unsigned int)(_keepaliveInterval * 1000); + result ^= (unsigned int)(_keepaliveTimeout * 1000); + result ^= (unsigned int)(_connectMinTimeout * 1000); + result ^= (unsigned int)(_connectInitialBackoff * 1000); + result ^= (unsigned int)(_connectMaxBackoff * 1000); + result ^= _additionalChannelArgs.hash; + result ^= _PEMRootCertificates.hash; + result ^= _PEMPrivateKey.hash; + result ^= _PEMCertificateChain.hash; + result ^= _hostNameOverride.hash; + result ^= _transportType; + result ^= _logContext.hash; + result ^= _channelPoolDomain.hash; + result ^= _channelID; + + return result; +} + +@end + +@implementation GRPCMutableCallOptions + +@dynamic serverAuthority; +@dynamic timeout; +@dynamic flowControlEnabled; +@dynamic oauth2AccessToken; +@dynamic authTokenProvider; +@dynamic initialMetadata; +@dynamic userAgentPrefix; +@dynamic responseSizeLimit; +@dynamic compressionAlgorithm; +@dynamic retryEnabled; +@dynamic keepaliveInterval; +@dynamic keepaliveTimeout; +@dynamic connectMinTimeout; +@dynamic connectInitialBackoff; +@dynamic connectMaxBackoff; +@dynamic additionalChannelArgs; +@dynamic PEMRootCertificates; +@dynamic PEMPrivateKey; +@dynamic PEMCertificateChain; +@dynamic transportType; +@dynamic hostNameOverride; +@dynamic logContext; +@dynamic channelPoolDomain; +@dynamic channelID; + +- (instancetype)init { + return [self initWithServerAuthority:kDefaultServerAuthority + timeout:kDefaultTimeout + flowControlEnabled:kDefaultFlowControlEnabled + oauth2AccessToken:kDefaultOauth2AccessToken + authTokenProvider:kDefaultAuthTokenProvider + initialMetadata:kDefaultInitialMetadata + userAgentPrefix:kDefaultUserAgentPrefix + responseSizeLimit:kDefaultResponseSizeLimit + compressionAlgorithm:kDefaultCompressionAlgorithm + retryEnabled:kDefaultRetryEnabled + keepaliveInterval:kDefaultKeepaliveInterval + keepaliveTimeout:kDefaultKeepaliveTimeout + connectMinTimeout:kDefaultConnectMinTimeout + connectInitialBackoff:kDefaultConnectInitialBackoff + connectMaxBackoff:kDefaultConnectMaxBackoff + additionalChannelArgs:kDefaultAdditionalChannelArgs + PEMRootCertificates:kDefaultPEMRootCertificates + PEMPrivateKey:kDefaultPEMPrivateKey + PEMCertificateChain:kDefaultPEMCertificateChain + transportType:kDefaultTransportType + hostNameOverride:kDefaultHostNameOverride + logContext:kDefaultLogContext + channelPoolDomain:kDefaultChannelPoolDomain + channelID:kDefaultChannelID]; +} + +- (nonnull id)copyWithZone:(NSZone *)zone { + GRPCCallOptions *newOptions = + [[GRPCCallOptions allocWithZone:zone] initWithServerAuthority:_serverAuthority + timeout:_timeout + flowControlEnabled:_flowControlEnabled + oauth2AccessToken:_oauth2AccessToken + authTokenProvider:_authTokenProvider + initialMetadata:_initialMetadata + userAgentPrefix:_userAgentPrefix + responseSizeLimit:_responseSizeLimit + compressionAlgorithm:_compressionAlgorithm + retryEnabled:_retryEnabled + keepaliveInterval:_keepaliveInterval + keepaliveTimeout:_keepaliveTimeout + connectMinTimeout:_connectMinTimeout + connectInitialBackoff:_connectInitialBackoff + connectMaxBackoff:_connectMaxBackoff + additionalChannelArgs:_additionalChannelArgs + PEMRootCertificates:_PEMRootCertificates + PEMPrivateKey:_PEMPrivateKey + PEMCertificateChain:_PEMCertificateChain + transportType:_transportType + hostNameOverride:_hostNameOverride + logContext:_logContext + channelPoolDomain:_channelPoolDomain + channelID:_channelID]; + return newOptions; +} + +- (nonnull id)mutableCopyWithZone:(NSZone *)zone { + GRPCMutableCallOptions *newOptions = [[GRPCMutableCallOptions allocWithZone:zone] + initWithServerAuthority:_serverAuthority + timeout:_timeout + flowControlEnabled:_flowControlEnabled + oauth2AccessToken:_oauth2AccessToken + authTokenProvider:_authTokenProvider + initialMetadata:_initialMetadata + userAgentPrefix:_userAgentPrefix + responseSizeLimit:_responseSizeLimit + compressionAlgorithm:_compressionAlgorithm + retryEnabled:_retryEnabled + keepaliveInterval:_keepaliveInterval + keepaliveTimeout:_keepaliveTimeout + connectMinTimeout:_connectMinTimeout + connectInitialBackoff:_connectInitialBackoff + connectMaxBackoff:_connectMaxBackoff + additionalChannelArgs:[_additionalChannelArgs copy] + PEMRootCertificates:_PEMRootCertificates + PEMPrivateKey:_PEMPrivateKey + PEMCertificateChain:_PEMCertificateChain + transportType:_transportType + hostNameOverride:_hostNameOverride + logContext:_logContext + channelPoolDomain:_channelPoolDomain + channelID:_channelID]; + return newOptions; +} + +- (void)setServerAuthority:(NSString *)serverAuthority { + _serverAuthority = [serverAuthority copy]; +} + +- (void)setTimeout:(NSTimeInterval)timeout { + if (timeout < 0) { + _timeout = 0; + } else { + _timeout = timeout; + } +} + +- (void)setFlowControlEnabled:(BOOL)flowControlEnabled { + _flowControlEnabled = flowControlEnabled; +} + +- (void)setOauth2AccessToken:(NSString *)oauth2AccessToken { + _oauth2AccessToken = [oauth2AccessToken copy]; +} + +- (void)setAuthTokenProvider:(id)authTokenProvider { + _authTokenProvider = authTokenProvider; +} + +- (void)setInitialMetadata:(NSDictionary *)initialMetadata { + _initialMetadata = [[NSDictionary alloc] initWithDictionary:initialMetadata copyItems:YES]; +} + +- (void)setUserAgentPrefix:(NSString *)userAgentPrefix { + _userAgentPrefix = [userAgentPrefix copy]; +} + +- (void)setResponseSizeLimit:(NSUInteger)responseSizeLimit { + _responseSizeLimit = responseSizeLimit; +} + +- (void)setCompressionAlgorithm:(GRPCCompressionAlgorithm)compressionAlgorithm { + _compressionAlgorithm = compressionAlgorithm; +} + +- (void)setRetryEnabled:(BOOL)retryEnabled { + _retryEnabled = retryEnabled; +} + +- (void)setKeepaliveInterval:(NSTimeInterval)keepaliveInterval { + if (keepaliveInterval < 0) { + _keepaliveInterval = 0; + } else { + _keepaliveInterval = keepaliveInterval; + } +} + +- (void)setKeepaliveTimeout:(NSTimeInterval)keepaliveTimeout { + if (keepaliveTimeout < 0) { + _keepaliveTimeout = 0; + } else { + _keepaliveTimeout = keepaliveTimeout; + } +} + +- (void)setConnectMinTimeout:(NSTimeInterval)connectMinTimeout { + if (connectMinTimeout < 0) { + _connectMinTimeout = 0; + } else { + _connectMinTimeout = connectMinTimeout; + } +} + +- (void)setConnectInitialBackoff:(NSTimeInterval)connectInitialBackoff { + if (connectInitialBackoff < 0) { + _connectInitialBackoff = 0; + } else { + _connectInitialBackoff = connectInitialBackoff; + } +} + +- (void)setConnectMaxBackoff:(NSTimeInterval)connectMaxBackoff { + if (connectMaxBackoff < 0) { + _connectMaxBackoff = 0; + } else { + _connectMaxBackoff = connectMaxBackoff; + } +} + +- (void)setAdditionalChannelArgs:(NSDictionary *)additionalChannelArgs { + _additionalChannelArgs = + [[NSDictionary alloc] initWithDictionary:additionalChannelArgs copyItems:YES]; +} + +- (void)setPEMRootCertificates:(NSString *)PEMRootCertificates { + _PEMRootCertificates = [PEMRootCertificates copy]; +} + +- (void)setPEMPrivateKey:(NSString *)PEMPrivateKey { + _PEMPrivateKey = [PEMPrivateKey copy]; +} + +- (void)setPEMCertificateChain:(NSString *)PEMCertificateChain { + _PEMCertificateChain = [PEMCertificateChain copy]; +} + +- (void)setTransportType:(GRPCTransportType)transportType { + _transportType = transportType; +} + +- (void)setHostNameOverride:(NSString *)hostNameOverride { + _hostNameOverride = [hostNameOverride copy]; +} + +- (void)setLogContext:(id)logContext { + _logContext = logContext; +} + +- (void)setChannelPoolDomain:(NSString *)channelPoolDomain { + _channelPoolDomain = [channelPoolDomain copy]; +} + +- (void)setChannelID:(NSUInteger)channelID { + _channelID = channelID; +} + +@end diff --git a/src/objective-c/GRPCClient/internal/GRPCCallOptions+Internal.h b/src/objective-c/GRPCClient/internal/GRPCCallOptions+Internal.h new file mode 100644 index 00000000000..eb691b3acb1 --- /dev/null +++ b/src/objective-c/GRPCClient/internal/GRPCCallOptions+Internal.h @@ -0,0 +1,39 @@ +/* + * + * 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. + * + */ + +#import + +#import "../GRPCCallOptions.h" + +@interface GRPCCallOptions () + +/** + * Parameter used for internal logging. + */ +@property(readonly) id logContext; + +@end + +@interface GRPCMutableCallOptions () + +/** + * Parameter used for internal logging. + */ +@property(readwrite) id logContext; + +@end diff --git a/src/objective-c/GRPCClient/private/ChannelArgsUtil.h b/src/objective-c/GRPCClient/private/ChannelArgsUtil.h new file mode 100644 index 00000000000..f271e846f00 --- /dev/null +++ b/src/objective-c/GRPCClient/private/ChannelArgsUtil.h @@ -0,0 +1,38 @@ +/* + * + * 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. + * + */ + +#import + +#include + +/** Free resources in the grpc core struct grpc_channel_args */ +void GRPCFreeChannelArgs(grpc_channel_args* channel_args); + +/** + * Allocates a @c grpc_channel_args and populates it with the options specified + * in the + * @c dictionary. Keys must be @c NSString, @c NSNumber, or a pointer. If the + * value responds to + * @c @selector(UTF8String) then it will be mapped to @c GRPC_ARG_STRING. If the + * value responds to + * @c @selector(intValue), it will be mapped to @c GRPC_ARG_INTEGER. Otherwise, + * if the value is not nil, it is mapped as a pointer. The caller of this + * function is responsible for calling + * @c GRPCFreeChannelArgs to free the @c grpc_channel_args struct. + */ +grpc_channel_args* GRPCBuildChannelArgs(NSDictionary* dictionary); diff --git a/src/objective-c/GRPCClient/private/ChannelArgsUtil.m b/src/objective-c/GRPCClient/private/ChannelArgsUtil.m new file mode 100644 index 00000000000..c1c65c33841 --- /dev/null +++ b/src/objective-c/GRPCClient/private/ChannelArgsUtil.m @@ -0,0 +1,94 @@ +/* + * + * 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. + * + */ + +#import "ChannelArgsUtil.h" + +#include +#include + +#include + +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; +} + +static void destroy_pointer_arg(void *p) { + // Decrease ref count to the object when destroying + CFRelease((CFTypeRef)p); +} + +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}; + +void GRPCFreeChannelArgs(grpc_channel_args *channel_args) { + for (size_t i = 0; i < channel_args->num_args; ++i) { + grpc_arg *arg = &channel_args->args[i]; + gpr_free(arg->key); + if (arg->type == GRPC_ARG_STRING) { + gpr_free(arg->value.string); + } + } + gpr_free(channel_args->args); + gpr_free(channel_args); +} + +grpc_channel_args *GRPCBuildChannelArgs(NSDictionary *dictionary) { + if (dictionary.count == 0) { + return NULL; + } + + NSArray *keys = [dictionary allKeys]; + NSUInteger argCount = [keys count]; + + grpc_channel_args *channelArgs = gpr_malloc(sizeof(grpc_channel_args)); + channelArgs->args = gpr_malloc(argCount * sizeof(grpc_arg)); + + // TODO(kriswuollett) Check that keys adhere to GRPC core library requirements + + NSUInteger j = 0; + for (NSUInteger i = 0; i < argCount; ++i) { + grpc_arg *arg = &channelArgs->args[j]; + arg->key = gpr_strdup([keys[i] UTF8String]); + + id value = dictionary[keys[i]]; + if ([value respondsToSelector:@selector(UTF8String)]) { + arg->type = GRPC_ARG_STRING; + arg->value.string = gpr_strdup([value UTF8String]); + j++; + } else if ([value respondsToSelector:@selector(intValue)]) { + int64_t value64 = [value longLongValue]; + if (value64 <= INT_MAX || value64 >= INT_MIN) { + arg->type = GRPC_ARG_INTEGER; + arg->value.integer = (int)value64; + j++; + } + } else if (value != nil) { + arg->type = GRPC_ARG_POINTER; + arg->value.pointer.p = (__bridge_retained void *)value; + arg->value.pointer.vtable = &objc_arg_vtable; + j++; + } + } + channelArgs->num_args = j; + + return channelArgs; +} diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.h b/src/objective-c/GRPCClient/private/GRPCChannel.h index 6499d4398c8..bbada0d8cb3 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.h +++ b/src/objective-c/GRPCClient/private/GRPCChannel.h @@ -20,49 +20,68 @@ #include +@protocol GRPCChannelFactory; + @class GRPCCompletionQueue; +@class GRPCCallOptions; +@class GRPCChannelConfiguration; struct grpc_channel_credentials; +NS_ASSUME_NONNULL_BEGIN + +/** + * Signature for the channel. If two channel's signatures are the same and connect to the same + * remote, they share the same underlying \a GRPCChannel object. + */ +@interface GRPCChannelConfiguration : NSObject + +- (instancetype)init NS_UNAVAILABLE; + ++ (instancetype) new NS_UNAVAILABLE; + +/** The host that this channel is connected to. */ +@property(copy, readonly) NSString *host; + +/** + * Options of the corresponding call. Note that only the channel-related options are of interest to + * this class. + */ +@property(readonly) GRPCCallOptions *callOptions; + +/** Acquire the factory to generate a new channel with current configurations. */ +@property(readonly) id channelFactory; + +/** Acquire the dictionary of channel args with current configurations. */ +@property(copy, readonly) NSDictionary *channelArgs; + +- (nullable instancetype)initWithHost:(NSString *)host + callOptions:(GRPCCallOptions *)callOptions NS_DESIGNATED_INITIALIZER; + +@end + /** * Each separate instance of this class represents at least one TCP connection to the provided host. */ @interface GRPCChannel : NSObject -@property(nonatomic, readonly, nonnull) struct grpc_channel *unmanagedChannel; - - (nullable instancetype)init NS_UNAVAILABLE; ++ (nullable instancetype) new NS_UNAVAILABLE; + /** - * Creates a secure channel to the specified @c host using default credentials and channel - * arguments. If certificates could not be found to create a secure channel, then @c nil is + * Create a channel with remote \a host and signature \a channelConfigurations. + */ +- (nullable instancetype)initWithChannelConfiguration: + (GRPCChannelConfiguration *)channelConfiguration NS_DESIGNATED_INITIALIZER; + +/** + * Create a grpc core call object (grpc_call) from this channel. If no call is created, NULL is * returned. */ -+ (nullable GRPCChannel *)secureChannelWithHost:(nonnull NSString *)host; +- (nullable grpc_call *)unmanagedCallWithPath:(NSString *)path + completionQueue:(GRPCCompletionQueue *)queue + callOptions:(GRPCCallOptions *)callOptions; -/** - * Creates a secure channel to the specified @c host using Cronet as a transport mechanism. - */ -#ifdef GRPC_COMPILE_WITH_CRONET -+ (nullable GRPCChannel *)secureCronetChannelWithHost:(nonnull NSString *)host - channelArgs:(nonnull NSDictionary *)channelArgs; -#endif -/** - * Creates a secure channel to the specified @c host using the specified @c credentials and - * @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; - -/** - * Creates an insecure channel to the specified @c host using the specified @c channelArgs. - */ -+ (nonnull GRPCChannel *)insecureChannelWithHost:(nonnull NSString *)host - channelArgs:(nullable NSDictionary *)channelArgs; - -- (nullable grpc_call *)unmanagedCallWithPath:(nonnull NSString *)path - serverName:(nonnull NSString *)serverName - timeout:(NSTimeInterval)timeout - completionQueue:(nonnull GRPCCompletionQueue *)queue; @end + +NS_ASSUME_NONNULL_END diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index b1f6ea270ef..1a79fb04a0d 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -18,206 +18,243 @@ #import "GRPCChannel.h" -#include -#ifdef GRPC_COMPILE_WITH_CRONET -#include -#endif -#include #include -#include -#ifdef GRPC_COMPILE_WITH_CRONET -#import -#import -#endif +#import "../internal/GRPCCallOptions+Internal.h" +#import "ChannelArgsUtil.h" +#import "GRPCChannelFactory.h" +#import "GRPCChannelPool.h" #import "GRPCCompletionQueue.h" +#import "GRPCCronetChannelFactory.h" +#import "GRPCInsecureChannelFactory.h" +#import "GRPCSecureChannelFactory.h" +#import "version.h" -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; -} +#import +#import -static void destroy_pointer_arg(void *p) { - // Decrease ref count to the object when destroying - CFRelease((CFTreeRef)p); -} +@implementation GRPCChannelConfiguration -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 void FreeChannelArgs(grpc_channel_args *channel_args) { - for (size_t i = 0; i < channel_args->num_args; ++i) { - grpc_arg *arg = &channel_args->args[i]; - gpr_free(arg->key); - if (arg->type == GRPC_ARG_STRING) { - gpr_free(arg->value.string); - } - } - gpr_free(channel_args->args); - gpr_free(channel_args); -} - -/** - * Allocates a @c grpc_channel_args and populates it with the options specified in the - * @c dictionary. Keys must be @c NSString. If the value responds to @c @selector(UTF8String) then - * it will be mapped to @c GRPC_ARG_STRING. If not, it will be mapped to @c GRPC_ARG_INTEGER if the - * value responds to @c @selector(intValue). Otherwise, an exception will be raised. The caller of - * this function is responsible for calling @c freeChannelArgs on a non-NULL returned value. - */ -static grpc_channel_args *BuildChannelArgs(NSDictionary *dictionary) { - if (!dictionary) { - return NULL; +- (instancetype)initWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions { + NSAssert(host.length > 0, @"Host must not be empty."); + NSAssert(callOptions != nil, @"callOptions must not be empty."); + if (host.length == 0 || callOptions == nil) { + return nil; } - NSArray *keys = [dictionary allKeys]; - NSUInteger argCount = [keys count]; + if ((self = [super init])) { + _host = [host copy]; + _callOptions = [callOptions copy]; + } + return self; +} - grpc_channel_args *channelArgs = gpr_malloc(sizeof(grpc_channel_args)); - channelArgs->num_args = argCount; - channelArgs->args = gpr_malloc(argCount * sizeof(grpc_arg)); +- (id)channelFactory { + GRPCTransportType type = _callOptions.transportType; + switch (type) { + case GRPCTransportTypeChttp2BoringSSL: + // TODO (mxyan): Remove when the API is deprecated +#ifdef GRPC_COMPILE_WITH_CRONET + if (![GRPCCall isUsingCronet]) { +#else + { +#endif + NSError *error; + id factory = [GRPCSecureChannelFactory + factoryWithPEMRootCertificates:_callOptions.PEMRootCertificates + privateKey:_callOptions.PEMPrivateKey + certChain:_callOptions.PEMCertificateChain + error:&error]; + NSAssert(factory != nil, @"Failed to create secure channel factory"); + if (factory == nil) { + NSLog(@"Error creating secure channel factory: %@", error); + } + return factory; + } + // fallthrough + case GRPCTransportTypeCronet: + return [GRPCCronetChannelFactory sharedInstance]; + case GRPCTransportTypeInsecure: + return [GRPCInsecureChannelFactory sharedInstance]; + } +} - // TODO(kriswuollett) Check that keys adhere to GRPC core library requirements +- (NSDictionary *)channelArgs { + NSMutableDictionary *args = [NSMutableDictionary new]; - for (NSUInteger i = 0; i < argCount; ++i) { - grpc_arg *arg = &channelArgs->args[i]; - arg->key = gpr_strdup([keys[i] UTF8String]); - - id value = dictionary[keys[i]]; - if ([value respondsToSelector:@selector(UTF8String)]) { - arg->type = GRPC_ARG_STRING; - arg->value.string = gpr_strdup([value UTF8String]); - } else if ([value respondsToSelector:@selector(intValue)]) { - arg->type = GRPC_ARG_INTEGER; - arg->value.integer = [value intValue]; - } else if (value != nil) { - arg->type = GRPC_ARG_POINTER; - arg->value.pointer.p = (__bridge_retained void *)value; - arg->value.pointer.vtable = &objc_arg_vtable; - } else { - [NSException raise:NSInvalidArgumentException - format:@"Invalid value type: %@", [value class]]; - } + NSString *userAgent = @"grpc-objc/" GRPC_OBJC_VERSION_STRING; + NSString *userAgentPrefix = _callOptions.userAgentPrefix; + if (userAgentPrefix.length != 0) { + args[@GRPC_ARG_PRIMARY_USER_AGENT_STRING] = + [_callOptions.userAgentPrefix stringByAppendingFormat:@" %@", userAgent]; + } else { + args[@GRPC_ARG_PRIMARY_USER_AGENT_STRING] = userAgent; } - return channelArgs; + NSString *hostNameOverride = _callOptions.hostNameOverride; + if (hostNameOverride) { + args[@GRPC_SSL_TARGET_NAME_OVERRIDE_ARG] = hostNameOverride; + } + + if (_callOptions.responseSizeLimit) { + args[@GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH] = + [NSNumber numberWithUnsignedInteger:_callOptions.responseSizeLimit]; + } + + if (_callOptions.compressionAlgorithm != GRPC_COMPRESS_NONE) { + args[@GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM] = + [NSNumber numberWithInt:_callOptions.compressionAlgorithm]; + } + + if (_callOptions.keepaliveInterval != 0) { + args[@GRPC_ARG_KEEPALIVE_TIME_MS] = + [NSNumber numberWithUnsignedInteger:(NSUInteger)(_callOptions.keepaliveInterval * 1000)]; + args[@GRPC_ARG_KEEPALIVE_TIMEOUT_MS] = + [NSNumber numberWithUnsignedInteger:(NSUInteger)(_callOptions.keepaliveTimeout * 1000)]; + } + + if (!_callOptions.retryEnabled) { + args[@GRPC_ARG_ENABLE_RETRIES] = [NSNumber numberWithInt:_callOptions.retryEnabled ? 1 : 0]; + } + + if (_callOptions.connectMinTimeout > 0) { + args[@GRPC_ARG_MIN_RECONNECT_BACKOFF_MS] = + [NSNumber numberWithUnsignedInteger:(NSUInteger)(_callOptions.connectMinTimeout * 1000)]; + } + if (_callOptions.connectInitialBackoff > 0) { + args[@GRPC_ARG_INITIAL_RECONNECT_BACKOFF_MS] = [NSNumber + numberWithUnsignedInteger:(NSUInteger)(_callOptions.connectInitialBackoff * 1000)]; + } + if (_callOptions.connectMaxBackoff > 0) { + args[@GRPC_ARG_MAX_RECONNECT_BACKOFF_MS] = + [NSNumber numberWithUnsignedInteger:(NSUInteger)(_callOptions.connectMaxBackoff * 1000)]; + } + + if (_callOptions.logContext != nil) { + args[@GRPC_ARG_MOBILE_LOG_CONTEXT] = _callOptions.logContext; + } + + if (_callOptions.channelPoolDomain.length != 0) { + args[@GRPC_ARG_CHANNEL_POOL_DOMAIN] = _callOptions.channelPoolDomain; + } + + [args addEntriesFromDictionary:_callOptions.additionalChannelArgs]; + + return args; } +- (id)copyWithZone:(NSZone *)zone { + GRPCChannelConfiguration *newConfig = + [[GRPCChannelConfiguration alloc] initWithHost:_host callOptions:_callOptions]; + + return newConfig; +} + +- (BOOL)isEqual:(id)object { + if (![object isKindOfClass:[GRPCChannelConfiguration class]]) { + return NO; + } + GRPCChannelConfiguration *obj = (GRPCChannelConfiguration *)object; + if (!(obj.host == _host || (_host != nil && [obj.host isEqualToString:_host]))) return NO; + if (!(obj.callOptions == _callOptions || [obj.callOptions hasChannelOptionsEqualTo:_callOptions])) + return NO; + + return YES; +} + +- (NSUInteger)hash { + NSUInteger result = 31; + result ^= _host.hash; + result ^= _callOptions.channelOptionsHash; + + return result; +} + +@end + @implementation GRPCChannel { - // Retain arguments to channel_create because they may not be used on the thread that invoked - // the channel_create function. - NSString *_host; - grpc_channel_args *_channelArgs; + GRPCChannelConfiguration *_configuration; + + grpc_channel *_unmanagedChannel; } -#ifdef GRPC_COMPILE_WITH_CRONET -- (instancetype)initWithHost:(NSString *)host - cronetEngine:(stream_engine *)cronetEngine - channelArgs:(NSDictionary *)channelArgs { - if (!host) { - [NSException raise:NSInvalidArgumentException format:@"host argument missing"]; - } - - if (self = [super init]) { - _channelArgs = BuildChannelArgs(channelArgs); - _host = [host copy]; - _unmanagedChannel = - grpc_cronet_secure_channel_create(cronetEngine, _host.UTF8String, _channelArgs, NULL); - } - - return self; -} -#endif - -- (instancetype)initWithHost:(NSString *)host - secure:(BOOL)secure - credentials:(struct grpc_channel_credentials *)credentials - channelArgs:(NSDictionary *)channelArgs { - if (!host) { - [NSException raise:NSInvalidArgumentException format:@"host argument missing"]; - } - - if (secure && !credentials) { +- (instancetype)initWithChannelConfiguration:(GRPCChannelConfiguration *)channelConfiguration { + NSAssert(channelConfiguration != nil, @"channelConfiguration must not be empty."); + if (channelConfiguration == nil) { return nil; } - if (self = [super init]) { - _channelArgs = BuildChannelArgs(channelArgs); - _host = [host copy]; - if (secure) { - _unmanagedChannel = - grpc_secure_channel_create(credentials, _host.UTF8String, _channelArgs, NULL); + if ((self = [super init])) { + _configuration = [channelConfiguration copy]; + + // Create gRPC core channel object. + NSString *host = channelConfiguration.host; + NSAssert(host.length != 0, @"host cannot be nil"); + NSDictionary *channelArgs; + if (channelConfiguration.callOptions.additionalChannelArgs.count != 0) { + NSMutableDictionary *args = [channelConfiguration.channelArgs mutableCopy]; + [args addEntriesFromDictionary:channelConfiguration.callOptions.additionalChannelArgs]; + channelArgs = args; } else { - _unmanagedChannel = grpc_insecure_channel_create(_host.UTF8String, _channelArgs, NULL); + channelArgs = channelConfiguration.channelArgs; + } + id factory = channelConfiguration.channelFactory; + _unmanagedChannel = [factory createChannelWithHost:host channelArgs:channelArgs]; + NSAssert(_unmanagedChannel != NULL, @"Failed to create channel"); + if (_unmanagedChannel == NULL) { + NSLog(@"Unable to create channel."); + return nil; } } - return self; } -- (void)dealloc { - // TODO(jcanizales): Be sure to add a test with a server that closes the connection prematurely, - // as in the past that made this call to crash. - grpc_channel_destroy(_unmanagedChannel); - FreeChannelArgs(_channelArgs); -} - -#ifdef GRPC_COMPILE_WITH_CRONET -+ (GRPCChannel *)secureCronetChannelWithHost:(NSString *)host - channelArgs:(NSDictionary *)channelArgs { - stream_engine *engine = [GRPCCall cronetEngine]; - if (!engine) { - [NSException raise:NSInvalidArgumentException format:@"cronet_engine is NULL. Set it first."]; - return nil; - } - return [[GRPCChannel alloc] initWithHost:host cronetEngine:engine channelArgs:channelArgs]; -} -#endif - -+ (GRPCChannel *)secureChannelWithHost:(NSString *)host { - return [[GRPCChannel alloc] initWithHost:host secure:YES credentials:NULL channelArgs:NULL]; -} - -+ (GRPCChannel *)secureChannelWithHost:(NSString *)host - credentials:(struct grpc_channel_credentials *)credentials - channelArgs:(NSDictionary *)channelArgs { - return [[GRPCChannel alloc] initWithHost:host - secure:YES - credentials:credentials - 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 - serverName:(NSString *)serverName - timeout:(NSTimeInterval)timeout - completionQueue:(GRPCCompletionQueue *)queue { - GPR_ASSERT(timeout >= 0); - if (timeout < 0) { - timeout = 0; - } - grpc_slice host_slice = grpc_empty_slice(); - if (serverName) { - host_slice = grpc_slice_from_copied_string(serverName.UTF8String); - } + completionQueue:(GRPCCompletionQueue *)queue + callOptions:(GRPCCallOptions *)callOptions { + NSAssert(path.length > 0, @"path must not be empty."); + NSAssert(queue != nil, @"completionQueue must not be empty."); + NSAssert(callOptions != nil, @"callOptions must not be empty."); + if (path.length == 0) return NULL; + if (queue == nil) return NULL; + if (callOptions == nil) return NULL; + + grpc_call *call = NULL; + // No need to lock here since _unmanagedChannel is only changed in _dealloc + NSAssert(_unmanagedChannel != NULL, @"Channel should have valid unmanaged channel."); + if (_unmanagedChannel == NULL) return NULL; + + NSString *serverAuthority = + callOptions.transportType == GRPCTransportTypeCronet ? nil : callOptions.serverAuthority; + NSTimeInterval timeout = callOptions.timeout; + NSAssert(timeout >= 0, @"Invalid timeout"); + if (timeout < 0) return NULL; + grpc_slice host_slice = serverAuthority + ? grpc_slice_from_copied_string(serverAuthority.UTF8String) + : grpc_empty_slice(); 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); - if (serverName) { + call = grpc_channel_create_call(_unmanagedChannel, NULL, GRPC_PROPAGATE_DEFAULTS, + queue.unmanagedQueue, path_slice, + serverAuthority ? &host_slice : NULL, deadline_ms, NULL); + if (serverAuthority) { grpc_slice_unref(host_slice); } grpc_slice_unref(path_slice); + NSAssert(call != nil, @"Unable to create call."); + if (call == NULL) { + NSLog(@"Unable to create call."); + } return call; } +- (void)dealloc { + if (_unmanagedChannel) { + grpc_channel_destroy(_unmanagedChannel); + } +} + @end diff --git a/src/objective-c/GRPCClient/private/GRPCChannelFactory.h b/src/objective-c/GRPCClient/private/GRPCChannelFactory.h new file mode 100644 index 00000000000..a934e966e9d --- /dev/null +++ b/src/objective-c/GRPCClient/private/GRPCChannelFactory.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. + * + */ + +#import + +#include + +NS_ASSUME_NONNULL_BEGIN + +/** A factory interface which generates new channel. */ +@protocol GRPCChannelFactory + +/** Create a channel with specific channel args to a specific host. */ +- (nullable grpc_channel *)createChannelWithHost:(NSString *)host + channelArgs:(nullable NSDictionary *)args; + +@end + +NS_ASSUME_NONNULL_END diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool+Test.h b/src/objective-c/GRPCClient/private/GRPCChannelPool+Test.h new file mode 100644 index 00000000000..e2c3aee3d92 --- /dev/null +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool+Test.h @@ -0,0 +1,51 @@ +/* + * + * 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. + * + */ + +#import "GRPCChannelPool.h" + +NS_ASSUME_NONNULL_BEGIN + +/** Test-only interface for \a GRPCPooledChannel. */ +@interface GRPCPooledChannel (Test) + +/** + * Initialize a pooled channel with non-default destroy delay for testing purpose. + */ +- (nullable instancetype)initWithChannelConfiguration: + (GRPCChannelConfiguration *)channelConfiguration + destroyDelay:(NSTimeInterval)destroyDelay; + +/** + * Return the pointer to the raw channel wrapped. + */ +@property(atomic, readonly, nullable) GRPCChannel *wrappedChannel; + +@end + +/** Test-only interface for \a GRPCChannelPool. */ +@interface GRPCChannelPool (Test) + +/** + * Get an instance of pool isolated from the global shared pool with channels' destroy delay being + * \a destroyDelay. + */ +- (nullable instancetype)initTestPool; + +@end + +NS_ASSUME_NONNULL_END diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.h b/src/objective-c/GRPCClient/private/GRPCChannelPool.h new file mode 100644 index 00000000000..e00ee69e63a --- /dev/null +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.h @@ -0,0 +1,101 @@ +/* + * + * 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. + * + */ + +#import + +#import "GRPCChannelFactory.h" + +NS_ASSUME_NONNULL_BEGIN + +@protocol GRPCChannel; +@class GRPCChannel; +@class GRPCChannelPool; +@class GRPCCompletionQueue; +@class GRPCChannelConfiguration; +@class GRPCWrappedCall; + +/** + * A proxied channel object that can be retained and used to create GRPCWrappedCall object + * regardless of the current connection status. If a connection is not established when a + * GRPCWrappedCall object is requested, it issues a connection/reconnection. This behavior is to + * follow that of gRPC core's channel object. + */ +@interface GRPCPooledChannel : NSObject + +- (nullable instancetype)init NS_UNAVAILABLE; + ++ (nullable instancetype) new NS_UNAVAILABLE; + +/** + * Initialize with an actual channel object \a channel and a reference to the channel pool. + */ +- (nullable instancetype)initWithChannelConfiguration: + (GRPCChannelConfiguration *)channelConfiguration; + +/** + * Create a GRPCWrappedCall object (grpc_call) from this channel. If channel is disconnected, get a + * new channel object from the channel pool. + */ +- (nullable GRPCWrappedCall *)wrappedCallWithPath:(NSString *)path + completionQueue:(GRPCCompletionQueue *)queue + callOptions:(GRPCCallOptions *)callOptions; + +/** + * Notify the pooled channel that a wrapped call object is no longer referenced and will be + * dealloc'ed. + */ +- (void)notifyWrappedCallDealloc:(GRPCWrappedCall *)wrappedCall; + +/** + * Force the channel to disconnect immediately. GRPCWrappedCall objects previously created with + * \a wrappedCallWithPath are failed if not already finished. Subsequent calls to + * unmanagedCallWithPath: will attempt to reconnect to the remote channel. + */ +- (void)disconnect; + +@end + +/** + * Manage the pool of connected channels. When a channel is no longer referenced by any call, + * destroy the channel after a certain period of time elapsed. + */ +@interface GRPCChannelPool : NSObject + +- (nullable instancetype)init NS_UNAVAILABLE; + ++ (nullable instancetype) new NS_UNAVAILABLE; + +/** + * Get the global channel pool. + */ ++ (nullable instancetype)sharedInstance; + +/** + * Return a channel with a particular configuration. The channel may be a cached channel. + */ +- (nullable GRPCPooledChannel *)channelWithHost:(NSString *)host + callOptions:(GRPCCallOptions *)callOptions; + +/** + * Disconnect all channels in this pool. + */ +- (void)disconnectAllChannels; + +@end + +NS_ASSUME_NONNULL_END diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m new file mode 100644 index 00000000000..60a33eda824 --- /dev/null +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -0,0 +1,282 @@ +/* + * + * 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. + * + */ + +#import + +#import "../internal/GRPCCallOptions+Internal.h" +#import "GRPCChannel.h" +#import "GRPCChannelFactory.h" +#import "GRPCChannelPool+Test.h" +#import "GRPCChannelPool.h" +#import "GRPCCompletionQueue.h" +#import "GRPCConnectivityMonitor.h" +#import "GRPCCronetChannelFactory.h" +#import "GRPCInsecureChannelFactory.h" +#import "GRPCSecureChannelFactory.h" +#import "GRPCWrappedCall.h" +#import "version.h" + +#import +#include + +extern const char *kCFStreamVarName; + +static GRPCChannelPool *gChannelPool; +static dispatch_once_t gInitChannelPool; + +/** When all calls of a channel are destroyed, destroy the channel after this much seconds. */ +static const NSTimeInterval kDefaultChannelDestroyDelay = 30; + +@implementation GRPCPooledChannel { + GRPCChannelConfiguration *_channelConfiguration; + NSTimeInterval _destroyDelay; + + NSHashTable *_wrappedCalls; + GRPCChannel *_wrappedChannel; + NSDate *_lastTimedDestroy; + dispatch_queue_t _timerQueue; +} + +- (instancetype)initWithChannelConfiguration:(GRPCChannelConfiguration *)channelConfiguration { + return [self initWithChannelConfiguration:channelConfiguration + destroyDelay:kDefaultChannelDestroyDelay]; +} + +- (nullable instancetype)initWithChannelConfiguration: + (GRPCChannelConfiguration *)channelConfiguration + destroyDelay:(NSTimeInterval)destroyDelay { + NSAssert(channelConfiguration != nil, @"channelConfiguration cannot be empty."); + if (channelConfiguration == nil) { + return nil; + } + + if ((self = [super init])) { + _channelConfiguration = [channelConfiguration copy]; + _destroyDelay = destroyDelay; + _wrappedCalls = [NSHashTable weakObjectsHashTable]; + _wrappedChannel = nil; + _lastTimedDestroy = nil; +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 || __MAC_OS_X_VERSION_MAX_ALLOWED >= 101300 + if (@available(iOS 8.0, macOS 10.10, *)) { + _timerQueue = dispatch_queue_create(NULL, dispatch_queue_attr_make_with_qos_class( + DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, 0)); + } else { +#else + { +#endif + _timerQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); + } + } + + return self; +} + +- (void)dealloc { + // Disconnect GRPCWrappedCall objects created but not yet removed + if (_wrappedCalls.allObjects.count != 0) { + for (GRPCWrappedCall *wrappedCall in _wrappedCalls.allObjects) { + [wrappedCall channelDisconnected]; + }; + } +} + +- (GRPCWrappedCall *)wrappedCallWithPath:(NSString *)path + completionQueue:(GRPCCompletionQueue *)queue + callOptions:(GRPCCallOptions *)callOptions { + NSAssert(path.length > 0, @"path must not be empty."); + NSAssert(queue != nil, @"completionQueue must not be empty."); + NSAssert(callOptions, @"callOptions must not be empty."); + if (path.length == 0 || queue == nil || callOptions == nil) { + return nil; + } + + GRPCWrappedCall *call = nil; + + @synchronized(self) { + if (_wrappedChannel == nil) { + _wrappedChannel = [[GRPCChannel alloc] initWithChannelConfiguration:_channelConfiguration]; + if (_wrappedChannel == nil) { + NSAssert(_wrappedChannel != nil, @"Unable to get a raw channel for proxy."); + return nil; + } + } + _lastTimedDestroy = nil; + + grpc_call *unmanagedCall = + [_wrappedChannel unmanagedCallWithPath:path + completionQueue:[GRPCCompletionQueue completionQueue] + callOptions:callOptions]; + if (unmanagedCall == NULL) { + NSAssert(unmanagedCall != NULL, @"Unable to create grpc_call object"); + return nil; + } + + call = [[GRPCWrappedCall alloc] initWithUnmanagedCall:unmanagedCall pooledChannel:self]; + if (call == nil) { + NSAssert(call != nil, @"Unable to create GRPCWrappedCall object"); + grpc_call_unref(unmanagedCall); + return nil; + } + + [_wrappedCalls addObject:call]; + } + return call; +} + +- (void)notifyWrappedCallDealloc:(GRPCWrappedCall *)wrappedCall { + NSAssert(wrappedCall != nil, @"wrappedCall cannot be empty."); + if (wrappedCall == nil) { + return; + } + @synchronized(self) { + // Detect if all objects weakly referenced in _wrappedCalls are (implicitly) removed. + // _wrappedCalls.count does not work here since the hash table may include deallocated weak + // references. _wrappedCalls.allObjects forces removal of those objects. + if (_wrappedCalls.allObjects.count == 0) { + // No more call has reference to this channel. We may start the timer for destroying the + // channel now. + NSDate *now = [NSDate date]; + NSAssert(now != nil, @"Unable to create NSDate object 'now'."); + _lastTimedDestroy = now; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)_destroyDelay * NSEC_PER_SEC), + _timerQueue, ^{ + @synchronized(self) { + // Check _lastTimedDestroy against now in case more calls are created (and + // maybe destroyed) after this dispatch_async. In that case the current + // dispatch_after block should be discarded; the channel should be + // destroyed in a later dispatch_after block. + if (now != nil && self->_lastTimedDestroy == now) { + self->_wrappedChannel = nil; + self->_lastTimedDestroy = nil; + } + } + }); + } + } +} + +- (void)disconnect { + NSArray *copiedWrappedCalls = nil; + @synchronized(self) { + if (_wrappedChannel != nil) { + _wrappedChannel = nil; + copiedWrappedCalls = _wrappedCalls.allObjects; + [_wrappedCalls removeAllObjects]; + } + } + for (GRPCWrappedCall *wrappedCall in copiedWrappedCalls) { + [wrappedCall channelDisconnected]; + } +} + +- (GRPCChannel *)wrappedChannel { + GRPCChannel *channel = nil; + @synchronized(self) { + channel = _wrappedChannel; + } + return channel; +} + +@end + +@interface GRPCChannelPool () + +- (instancetype)initPrivate NS_DESIGNATED_INITIALIZER; + +@end + +@implementation GRPCChannelPool { + NSMutableDictionary *_channelPool; +} + ++ (instancetype)sharedInstance { + dispatch_once(&gInitChannelPool, ^{ + gChannelPool = [[GRPCChannelPool alloc] initPrivate]; + NSAssert(gChannelPool != nil, @"Cannot initialize global channel pool."); + }); + return gChannelPool; +} + +- (instancetype)initPrivate { + if ((self = [super init])) { + _channelPool = [NSMutableDictionary dictionary]; + + // Connectivity monitor is not required for CFStream + char *enableCFStream = getenv(kCFStreamVarName); + if (enableCFStream == nil || enableCFStream[0] != '1') { + [GRPCConnectivityMonitor registerObserver:self selector:@selector(connectivityChange:)]; + } + } + return self; +} + +- (void)dealloc { + [GRPCConnectivityMonitor unregisterObserver:self]; +} + +- (GRPCPooledChannel *)channelWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions { + NSAssert(host.length > 0, @"Host must not be empty."); + NSAssert(callOptions != nil, @"callOptions must not be empty."); + if (host.length == 0 || callOptions == nil) { + return nil; + } + + // remove trailing slash of hostname + NSURL *hostURL = [NSURL URLWithString:[@"https://" stringByAppendingString:host]]; + if (hostURL.host && hostURL.port == nil) { + host = [hostURL.host stringByAppendingString:@":443"]; + } + + GRPCPooledChannel *pooledChannel = nil; + GRPCChannelConfiguration *configuration = + [[GRPCChannelConfiguration alloc] initWithHost:host callOptions:callOptions]; + @synchronized(self) { + pooledChannel = _channelPool[configuration]; + if (pooledChannel == nil) { + pooledChannel = [[GRPCPooledChannel alloc] initWithChannelConfiguration:configuration]; + _channelPool[configuration] = pooledChannel; + } + } + return pooledChannel; +} + +- (void)disconnectAllChannels { + NSArray *copiedPooledChannels; + @synchronized(self) { + copiedPooledChannels = _channelPool.allValues; + } + + // Disconnect pooled channels. + for (GRPCPooledChannel *pooledChannel in copiedPooledChannels) { + [pooledChannel disconnect]; + } +} + +- (void)connectivityChange:(NSNotification *)note { + [self disconnectAllChannels]; +} + +@end + +@implementation GRPCChannelPool (Test) + +- (instancetype)initTestPool { + return [self initPrivate]; +} + +@end diff --git a/src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.m b/src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.m index a36788b35aa..bb8618ff335 100644 --- a/src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.m +++ b/src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.m @@ -76,14 +76,14 @@ static void ReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReach } } -+ (void)registerObserver:(_Nonnull id)observer selector:(SEL)selector { ++ (void)registerObserver:(id)observer selector:(SEL)selector { [[NSNotificationCenter defaultCenter] addObserver:observer selector:selector name:kGRPCConnectivityNotification object:nil]; } -+ (void)unregisterObserver:(_Nonnull id)observer { ++ (void)unregisterObserver:(id)observer { [[NSNotificationCenter defaultCenter] removeObserver:observer]; } diff --git a/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.h b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.h new file mode 100644 index 00000000000..738dfdb7370 --- /dev/null +++ b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.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. + * + */ +#import "GRPCChannelFactory.h" + +@class GRPCChannel; +typedef struct stream_engine stream_engine; + +NS_ASSUME_NONNULL_BEGIN + +@interface GRPCCronetChannelFactory : NSObject + ++ (nullable instancetype)sharedInstance; + +- (nullable grpc_channel *)createChannelWithHost:(NSString *)host + channelArgs:(nullable NSDictionary *)args; + +- (nullable instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m new file mode 100644 index 00000000000..5bcb021dc4b --- /dev/null +++ b/src/objective-c/GRPCClient/private/GRPCCronetChannelFactory.m @@ -0,0 +1,79 @@ +/* + * + * 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. + * + */ + +#import "GRPCCronetChannelFactory.h" + +#import "ChannelArgsUtil.h" +#import "GRPCChannel.h" + +#ifdef GRPC_COMPILE_WITH_CRONET + +#import +#include + +@implementation GRPCCronetChannelFactory { + stream_engine *_cronetEngine; +} + ++ (instancetype)sharedInstance { + static GRPCCronetChannelFactory *instance; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + instance = [[self alloc] initWithEngine:[Cronet getGlobalEngine]]; + }); + return instance; +} + +- (instancetype)initWithEngine:(stream_engine *)engine { + NSAssert(engine != NULL, @"Cronet engine cannot be empty."); + if (!engine) { + return nil; + } + if ((self = [super init])) { + _cronetEngine = engine; + } + return self; +} + +- (grpc_channel *)createChannelWithHost:(NSString *)host channelArgs:(NSDictionary *)args { + grpc_channel_args *channelArgs = GRPCBuildChannelArgs(args); + grpc_channel *unmanagedChannel = + grpc_cronet_secure_channel_create(_cronetEngine, host.UTF8String, channelArgs, NULL); + GRPCFreeChannelArgs(channelArgs); + return unmanagedChannel; +} + +@end + +#else + +@implementation GRPCCronetChannelFactory + ++ (instancetype)sharedInstance { + NSAssert(NO, @"Must enable macro GRPC_COMPILE_WITH_CRONET to build Cronet channel."); + return nil; +} + +- (grpc_channel *)createChannelWithHost:(NSString *)host channelArgs:(NSDictionary *)args { + NSAssert(NO, @"Must enable macro GRPC_COMPILE_WITH_CRONET to build Cronet channel."); + return NULL; +} + +@end + +#endif diff --git a/src/objective-c/GRPCClient/private/GRPCHost.h b/src/objective-c/GRPCClient/private/GRPCHost.h index 291b07df377..ca3c52ea177 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.h +++ b/src/objective-c/GRPCClient/private/GRPCHost.h @@ -20,6 +20,10 @@ #import +#import "GRPCChannelFactory.h" + +#import + NS_ASSUME_NONNULL_BEGIN @class GRPCCompletionQueue; @@ -28,12 +32,10 @@ struct grpc_channel_credentials; @interface GRPCHost : NSObject -+ (void)flushChannelCache; + (void)resetAllHostSettings; @property(nonatomic, readonly) NSString *address; @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; @@ -44,14 +46,14 @@ struct grpc_channel_credentials; @property(nonatomic) unsigned int initialConnectBackoff; @property(nonatomic) unsigned int maxConnectBackoff; -/** The following properties should only be modified for testing: */ +@property(nonatomic) id channelFactory; -@property(nonatomic, getter=isSecure) BOOL secure; +/** The following properties should only be modified for testing: */ @property(nonatomic, copy, nullable) NSString *hostNameOverride; /** The default response size limit is 4MB. Set this to override that default. */ -@property(nonatomic, strong, nullable) NSNumber *responseSizeLimitOverride; +@property(nonatomic) NSUInteger responseSizeLimitOverride; - (nullable instancetype)init NS_UNAVAILABLE; /** Host objects initialized with the same address are the same. */ @@ -62,19 +64,10 @@ struct grpc_channel_credentials; withCertChain:(nullable NSString *)pemCertChain error:(NSError **)errorPtr; -/** Create a grpc_call object to the provided path on this host. */ -- (nullable struct grpc_call *)unmanagedCallWithPath:(NSString *)path - serverName:(NSString *)serverName - timeout:(NSTimeInterval)timeout - completionQueue:(GRPCCompletionQueue *)queue; +@property(atomic) GRPCTransportType transportType; + ++ (GRPCCallOptions *)callOptionsForHost:(NSString *)host; -// TODO: There's a race when a new RPC is coming through just as an existing one is getting -// notified that there's no connectivity. If connectivity comes back at that moment, the new RPC -// will have its channel destroyed by the other RPC, and will never get notified of a problem, so -// it'll hang (the C layer logs a timeout, with exponential back off). One solution could be to pass -// the GRPCChannel to the GRPCCall, renaming this as "disconnectChannel:channel", which would only -// act on that specific channel. -- (void)disconnect; @end NS_ASSUME_NONNULL_END diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m index 85b95dee914..24348c3aed7 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.m +++ b/src/objective-c/GRPCClient/private/GRPCHost.m @@ -18,46 +18,36 @@ #import "GRPCHost.h" +#import #import +#import + #include #include -#ifdef GRPC_COMPILE_WITH_CRONET -#import -#import -#endif -#import "GRPCChannel.h" +#import "../internal/GRPCCallOptions+Internal.h" +#import "GRPCChannelFactory.h" #import "GRPCCompletionQueue.h" #import "GRPCConnectivityMonitor.h" +#import "GRPCCronetChannelFactory.h" +#import "GRPCSecureChannelFactory.h" #import "NSDictionary+GRPC.h" #import "version.h" NS_ASSUME_NONNULL_BEGIN -extern const char *kCFStreamVarName; - -static NSMutableDictionary *kHostCache; +static NSMutableDictionary *gHostCache; @implementation GRPCHost { - // TODO(mlumish): Investigate whether caching channels with strong links is a good idea. - GRPCChannel *_channel; + NSString *_PEMRootCertificates; + NSString *_PEMPrivateKey; + NSString *_PEMCertificateChain; } + (nullable instancetype)hostWithAddress:(NSString *)address { return [[self alloc] initWithAddress:address]; } -- (void)dealloc { - if (_channelCreds != nil) { - grpc_channel_credentials_release(_channelCreds); - } - // Connectivity monitor is not required for CFStream - char *enableCFStream = getenv(kCFStreamVarName); - if (enableCFStream == nil || enableCFStream[0] != '1') { - [GRPCConnectivityMonitor unregisterObserver:self]; - } -} - // Default initializer. - (nullable instancetype)initWithAddress:(NSString *)address { if (!address) { @@ -76,241 +66,89 @@ static NSMutableDictionary *kHostCache; // Look up the GRPCHost in the cache. static dispatch_once_t cacheInitialization; dispatch_once(&cacheInitialization, ^{ - kHostCache = [NSMutableDictionary dictionary]; + gHostCache = [NSMutableDictionary dictionary]; }); - @synchronized(kHostCache) { - GRPCHost *cachedHost = kHostCache[address]; + @synchronized(gHostCache) { + GRPCHost *cachedHost = gHostCache[address]; if (cachedHost) { return cachedHost; } if ((self = [super init])) { - _address = address; - _secure = YES; - kHostCache[address] = self; - _compressAlgorithm = GRPC_COMPRESS_NONE; + _address = [address copy]; _retryEnabled = YES; - } - - // Connectivity monitor is not required for CFStream - char *enableCFStream = getenv(kCFStreamVarName); - if (enableCFStream == nil || enableCFStream[0] != '1') { - [GRPCConnectivityMonitor registerObserver:self selector:@selector(connectivityChange:)]; + gHostCache[address] = self; } } return self; } -+ (void)flushChannelCache { - @synchronized(kHostCache) { - [kHostCache enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, GRPCHost *_Nonnull host, - BOOL *_Nonnull stop) { - [host disconnect]; - }]; - } -} - + (void)resetAllHostSettings { - @synchronized(kHostCache) { - kHostCache = [NSMutableDictionary dictionary]; + @synchronized(gHostCache) { + gHostCache = [NSMutableDictionary dictionary]; } } -- (nullable grpc_call *)unmanagedCallWithPath:(NSString *)path - serverName:(NSString *)serverName - timeout:(NSTimeInterval)timeout - completionQueue:(GRPCCompletionQueue *)queue { - // 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) { - _channel = [self newChannel]; - } - channel = _channel; - } - return [channel unmanagedCallWithPath:path - serverName:serverName - timeout:timeout - completionQueue:queue]; -} - -- (NSData *)nullTerminatedDataWithString:(NSString *)string { - // dataUsingEncoding: does not return a null-terminated string. - NSData *data = [string dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]; - NSMutableData *nullTerminated = [NSMutableData dataWithData:data]; - [nullTerminated appendBytes:"\0" length:1]; - return nullTerminated; -} - - (BOOL)setTLSPEMRootCerts:(nullable NSString *)pemRootCerts withPrivateKey:(nullable NSString *)pemPrivateKey withCertChain:(nullable NSString *)pemCertChain error:(NSError **)errorPtr { - static NSData *kDefaultRootsASCII; - static NSError *kDefaultRootsError; - static dispatch_once_t loading; - dispatch_once(&loading, ^{ - 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]; - if (contentInUTF8 == nil) { - kDefaultRootsError = error; - return; - } - kDefaultRootsASCII = [self nullTerminatedDataWithString:contentInUTF8]; - }); - - NSData *rootsASCII; - if (pemRootCerts != nil) { - rootsASCII = [self nullTerminatedDataWithString:pemRootCerts]; - } 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); - return NO; - } - rootsASCII = kDefaultRootsASCII; - } - - grpc_channel_credentials *creds; - if (pemPrivateKey == nil && pemCertChain == nil) { - creds = grpc_ssl_credentials_create(rootsASCII.bytes, NULL, NULL, NULL); - } else { - assert(pemPrivateKey != nil && pemCertChain != nil); - grpc_ssl_pem_key_cert_pair key_cert_pair; - NSData *privateKeyASCII = [self nullTerminatedDataWithString:pemPrivateKey]; - NSData *certChainASCII = [self nullTerminatedDataWithString:pemCertChain]; - 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, NULL); - } - - @synchronized(self) { - if (_channelCreds != nil) { - grpc_channel_credentials_release(_channelCreds); - } - _channelCreds = creds; - } - + _PEMRootCertificates = [pemRootCerts copy]; + _PEMPrivateKey = [pemPrivateKey copy]; + _PEMCertificateChain = [pemCertChain copy]; return YES; } -- (NSDictionary *)channelArgsUsingCronet:(BOOL)useCronet { - NSMutableDictionary *args = [NSMutableDictionary dictionary]; - - // TODO(jcanizales): Add OS and device information (see - // https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#user-agents ). - NSString *userAgent = @"grpc-objc/" GRPC_OBJC_VERSION_STRING; - if (_userAgentPrefix) { - userAgent = [_userAgentPrefix stringByAppendingFormat:@" %@", userAgent]; - } - args[@GRPC_ARG_PRIMARY_USER_AGENT_STRING] = userAgent; - - if (_secure && _hostNameOverride) { - args[@GRPC_SSL_TARGET_NAME_OVERRIDE_ARG] = _hostNameOverride; - } - - if (_responseSizeLimitOverride != nil) { - args[@GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH] = _responseSizeLimitOverride; - } - - if (_compressAlgorithm != GRPC_COMPRESS_NONE) { - 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 logContext = self.logContext; - if (logContext != nil) { - args[@GRPC_ARG_MOBILE_LOG_CONTEXT] = logContext; - } - - if (useCronet) { - args[@GRPC_ARG_DISABLE_CLIENT_AUTHORITY_FILTER] = [NSNumber numberWithInt:1]; - } - - if (_retryEnabled == NO) { - args[@GRPC_ARG_ENABLE_RETRIES] = [NSNumber numberWithInt:0]; - } - - if (_minConnectTimeout > 0) { - args[@GRPC_ARG_MIN_RECONNECT_BACKOFF_MS] = [NSNumber numberWithInt:_minConnectTimeout]; - } - if (_initialConnectBackoff > 0) { - args[@GRPC_ARG_INITIAL_RECONNECT_BACKOFF_MS] = [NSNumber numberWithInt:_initialConnectBackoff]; - } - if (_maxConnectBackoff > 0) { - args[@GRPC_ARG_MAX_RECONNECT_BACKOFF_MS] = [NSNumber numberWithInt:_maxConnectBackoff]; - } - - return args; -} - -- (GRPCChannel *)newChannel { - BOOL useCronet = NO; +- (GRPCCallOptions *)callOptions { + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.userAgentPrefix = _userAgentPrefix; + options.responseSizeLimit = _responseSizeLimitOverride; + options.compressionAlgorithm = (GRPCCompressionAlgorithm)_compressAlgorithm; + options.retryEnabled = _retryEnabled; + options.keepaliveInterval = (NSTimeInterval)_keepaliveInterval / 1000; + options.keepaliveTimeout = (NSTimeInterval)_keepaliveTimeout / 1000; + options.connectMinTimeout = (NSTimeInterval)_minConnectTimeout / 1000; + options.connectInitialBackoff = (NSTimeInterval)_initialConnectBackoff / 1000; + options.connectMaxBackoff = (NSTimeInterval)_maxConnectBackoff / 1000; + options.PEMRootCertificates = _PEMRootCertificates; + options.PEMPrivateKey = _PEMPrivateKey; + options.PEMCertificateChain = _PEMCertificateChain; + options.hostNameOverride = _hostNameOverride; #ifdef GRPC_COMPILE_WITH_CRONET - useCronet = [GRPCCall isUsingCronet]; -#endif - NSDictionary *args = [self channelArgsUsingCronet:useCronet]; - if (_secure) { - GRPCChannel *channel; - @synchronized(self) { - if (_channelCreds == nil) { - [self setTLSPEMRootCerts:nil withPrivateKey:nil withCertChain:nil error:nil]; - } -#ifdef GRPC_COMPILE_WITH_CRONET - if (useCronet) { - channel = [GRPCChannel secureCronetChannelWithHost:_address channelArgs:args]; - } else -#endif - { - channel = - [GRPCChannel secureChannelWithHost:_address credentials:_channelCreds channelArgs:args]; - } + // By old API logic, insecure channel precedes Cronet channel; Cronet channel preceeds default + // channel. + if ([GRPCCall isUsingCronet]) { + if (_transportType == GRPCTransportTypeInsecure) { + options.transportType = GRPCTransportTypeInsecure; + } else { + NSAssert(_transportType == GRPCTransportTypeDefault, @"Invalid transport type"); + options.transportType = GRPCTransportTypeCronet; } - return channel; - } else { - return [GRPCChannel insecureChannelWithHost:_address channelArgs:args]; + } else +#endif + { + options.transportType = _transportType; } + options.logContext = _logContext; + + return options; } -- (NSString *)hostName { - // TODO(jcanizales): Default to nil instead of _address when Issue #2635 is clarified. - return _hostNameOverride ?: _address; -} - -- (void)disconnect { - // This is racing -[GRPCHost unmanagedCallWithPath:completionQueue:]. - @synchronized(self) { - _channel = nil; ++ (GRPCCallOptions *)callOptionsForHost:(NSString *)host { + // TODO (mxyan): Remove when old API is deprecated + NSURL *hostURL = [NSURL URLWithString:[@"https://" stringByAppendingString:host]]; + if (hostURL.host && hostURL.port == nil) { + host = [hostURL.host stringByAppendingString:@":443"]; } -} -// Flushes the host cache when connectivity status changes or when connection switch between Wifi -// and Cellular data, so that a new call will use a new channel. Otherwise, a new call will still -// use the cached channel which is no longer available and will cause gRPC to hang. -- (void)connectivityChange:(NSNotification *)note { - [self disconnect]; + GRPCCallOptions *callOptions = nil; + @synchronized(gHostCache) { + callOptions = [gHostCache[host] callOptions]; + } + if (callOptions == nil) { + callOptions = [[GRPCCallOptions alloc] init]; + } + return callOptions; } @end diff --git a/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.h b/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.h new file mode 100644 index 00000000000..2d471aebed6 --- /dev/null +++ b/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.h @@ -0,0 +1,35 @@ +/* + * + * 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. + * + */ +#import "GRPCChannelFactory.h" + +@class GRPCChannel; + +NS_ASSUME_NONNULL_BEGIN + +@interface GRPCInsecureChannelFactory : NSObject + ++ (nullable instancetype)sharedInstance; + +- (nullable grpc_channel *)createChannelWithHost:(NSString *)host + channelArgs:(nullable NSDictionary *)args; + +- (nullable instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m new file mode 100644 index 00000000000..8ad1e848f55 --- /dev/null +++ b/src/objective-c/GRPCClient/private/GRPCInsecureChannelFactory.m @@ -0,0 +1,43 @@ +/* + * + * 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. + * + */ + +#import "GRPCInsecureChannelFactory.h" + +#import "ChannelArgsUtil.h" +#import "GRPCChannel.h" + +@implementation GRPCInsecureChannelFactory + ++ (instancetype)sharedInstance { + static GRPCInsecureChannelFactory *instance; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + instance = [[self alloc] init]; + }); + return instance; +} + +- (grpc_channel *)createChannelWithHost:(NSString *)host channelArgs:(NSDictionary *)args { + grpc_channel_args *coreChannelArgs = GRPCBuildChannelArgs(args); + grpc_channel *unmanagedChannel = + grpc_insecure_channel_create(host.UTF8String, coreChannelArgs, NULL); + GRPCFreeChannelArgs(coreChannelArgs); + return unmanagedChannel; +} + +@end diff --git a/src/objective-c/GRPCClient/private/GRPCRequestHeaders.m b/src/objective-c/GRPCClient/private/GRPCRequestHeaders.m index fa4f022ff02..5f117f0607b 100644 --- a/src/objective-c/GRPCClient/private/GRPCRequestHeaders.m +++ b/src/objective-c/GRPCClient/private/GRPCRequestHeaders.m @@ -36,7 +36,7 @@ static void CheckIsNonNilASCII(NSString *name, NSString *value) { // Precondition: key isn't nil. static void CheckKeyValuePairIsValid(NSString *key, id value) { if ([key hasSuffix:@"-bin"]) { - if (![value isKindOfClass:NSData.class]) { + if (![value isKindOfClass:[NSData class]]) { [NSException raise:NSInvalidArgumentException format: @"Expected NSData value for header %@ ending in \"-bin\", " @@ -44,7 +44,7 @@ static void CheckKeyValuePairIsValid(NSString *key, id value) { key, value]; } } else { - if (![value isKindOfClass:NSString.class]) { + if (![value isKindOfClass:[NSString class]]) { [NSException raise:NSInvalidArgumentException format: @"Expected NSString value for header %@ not ending in \"-bin\", " diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h new file mode 100644 index 00000000000..572f20d341f --- /dev/null +++ b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h @@ -0,0 +1,43 @@ +/* + * + * 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. + * + */ +#import "GRPCChannelFactory.h" + +@class GRPCChannel; + +NS_ASSUME_NONNULL_BEGIN + +@interface GRPCSecureChannelFactory : NSObject + +/** + * Creates a secure channel factory which uses provided root certificates and client authentication + * credentials. If rootCerts is nil, gRPC will use its default root certificates. If rootCerts is + * provided, it must only contain the server's CA to avoid memory issue. + */ ++ (nullable instancetype)factoryWithPEMRootCertificates:(nullable NSString *)rootCerts + privateKey:(nullable NSString *)privateKey + certChain:(nullable NSString *)certChain + error:(NSError **)errorPtr; + +- (nullable grpc_channel *)createChannelWithHost:(NSString *)host + channelArgs:(nullable NSDictionary *)args; + +- (nullable instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m new file mode 100644 index 00000000000..7557367ed4a --- /dev/null +++ b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m @@ -0,0 +1,114 @@ +/* + * + * 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. + * + */ + +#import "GRPCSecureChannelFactory.h" + +#include + +#import "ChannelArgsUtil.h" +#import "GRPCChannel.h" + +@implementation GRPCSecureChannelFactory { + grpc_channel_credentials *_channelCreds; +} + ++ (instancetype)factoryWithPEMRootCertificates:(NSString *)rootCerts + privateKey:(NSString *)privateKey + certChain:(NSString *)certChain + error:(NSError **)errorPtr { + return [[self alloc] initWithPEMRootCerts:rootCerts + privateKey:privateKey + certChain:certChain + error:errorPtr]; +} + +- (NSData *)nullTerminatedDataWithString:(NSString *)string { + // dataUsingEncoding: does not return a null-terminated string. + NSData *data = [string dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]; + if (data == nil) { + return nil; + } + NSMutableData *nullTerminated = [NSMutableData dataWithData:data]; + [nullTerminated appendBytes:"\0" length:1]; + return nullTerminated; +} + +- (instancetype)initWithPEMRootCerts:(NSString *)rootCerts + privateKey:(NSString *)privateKey + certChain:(NSString *)certChain + error:(NSError **)errorPtr { + static dispatch_once_t loading; + dispatch_once(&loading, ^{ + NSString *rootsPEM = @"roots"; + NSString *resourceBundlePath = @"gRPCCertificates.bundle"; // .pem + // Do not use NSBundle.mainBundle, as it's nil for tests of library projects. + NSBundle *bundle = [NSBundle bundleForClass:[self class]]; + NSBundle *resourceBundle = [NSBundle + bundleWithURL:[[bundle resourceURL] URLByAppendingPathComponent:resourceBundlePath]]; + NSString *path = [resourceBundle pathForResource:rootsPEM ofType:@"pem"]; + setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, + [path cStringUsingEncoding:NSUTF8StringEncoding], 1); + }); + + NSData *rootsASCII = nil; + // if rootCerts is not provided, gRPC will use its own default certs + if (rootCerts != nil) { + rootsASCII = [self nullTerminatedDataWithString:rootCerts]; + } + + grpc_channel_credentials *creds = NULL; + if (privateKey.length == 0 && certChain.length == 0) { + creds = grpc_ssl_credentials_create(rootsASCII.bytes, NULL, NULL, NULL); + } else { + grpc_ssl_pem_key_cert_pair key_cert_pair; + NSData *privateKeyASCII = [self nullTerminatedDataWithString:privateKey]; + NSData *certChainASCII = [self nullTerminatedDataWithString:certChain]; + key_cert_pair.private_key = privateKeyASCII.bytes; + key_cert_pair.cert_chain = certChainASCII.bytes; + if (key_cert_pair.private_key == NULL || key_cert_pair.cert_chain == NULL) { + creds = grpc_ssl_credentials_create(rootsASCII.bytes, NULL, NULL, NULL); + } else { + creds = grpc_ssl_credentials_create(rootsASCII.bytes, &key_cert_pair, NULL, NULL); + } + } + + if ((self = [super init])) { + _channelCreds = creds; + } + return self; +} + +- (grpc_channel *)createChannelWithHost:(NSString *)host channelArgs:(NSDictionary *)args { + NSAssert(host.length != 0, @"host cannot be empty"); + if (host.length == 0) { + return NULL; + } + grpc_channel_args *coreChannelArgs = GRPCBuildChannelArgs(args); + grpc_channel *unmanagedChannel = + grpc_secure_channel_create(_channelCreds, host.UTF8String, coreChannelArgs, NULL); + GRPCFreeChannelArgs(coreChannelArgs); + return unmanagedChannel; +} + +- (void)dealloc { + if (_channelCreds != NULL) { + grpc_channel_credentials_release(_channelCreds); + } +} + +@end diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.h b/src/objective-c/GRPCClient/private/GRPCWrappedCall.h index f711850c2f0..92bd1be2570 100644 --- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.h +++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.h @@ -71,12 +71,16 @@ #pragma mark GRPCWrappedCall +@class GRPCPooledChannel; + @interface GRPCWrappedCall : NSObject -- (instancetype)initWithHost:(NSString *)host - serverName:(NSString *)serverName - path:(NSString *)path - timeout:(NSTimeInterval)timeout NS_DESIGNATED_INITIALIZER; +- (instancetype)init NS_UNAVAILABLE; + ++ (instancetype) new NS_UNAVAILABLE; + +- (instancetype)initWithUnmanagedCall:(grpc_call *)unmanagedCall + pooledChannel:(GRPCPooledChannel *)pooledChannel NS_DESIGNATED_INITIALIZER; - (void)startBatchWithOperations:(NSArray *)ops errorHandler:(void (^)(void))errorHandler; @@ -84,4 +88,6 @@ - (void)cancel; +- (void)channelDisconnected; + @end diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m index 7781d27ca4f..7d7e77f6ba0 100644 --- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m +++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m @@ -23,6 +23,8 @@ #include #include +#import "GRPCChannel.h" +#import "GRPCChannelPool.h" #import "GRPCCompletionQueue.h" #import "GRPCHost.h" #import "NSData+GRPC.h" @@ -234,35 +236,22 @@ #pragma mark GRPCWrappedCall @implementation GRPCWrappedCall { - GRPCCompletionQueue *_queue; + // pooledChannel holds weak reference to this object so this is ok + GRPCPooledChannel *_pooledChannel; grpc_call *_call; } -- (instancetype)init { - return [self initWithHost:nil serverName:nil path:nil timeout:0]; -} - -- (instancetype)initWithHost:(NSString *)host - serverName:(NSString *)serverName - path:(NSString *)path - timeout:(NSTimeInterval)timeout { - if (!path || !host) { - [NSException raise:NSInvalidArgumentException format:@"path and host cannot be nil."]; +- (instancetype)initWithUnmanagedCall:(grpc_call *)unmanagedCall + pooledChannel:(GRPCPooledChannel *)pooledChannel { + NSAssert(unmanagedCall != NULL, @"unmanagedCall cannot be empty."); + NSAssert(pooledChannel != nil, @"pooledChannel cannot be empty."); + if (unmanagedCall == NULL || pooledChannel == nil) { + return nil; } - if (self = [super init]) { - // Each completion queue consumes one thread. There's a trade to be made between creating and - // consuming too many threads and having contention of multiple calls in a single completion - // queue. Currently we use a singleton queue. - _queue = [GRPCCompletionQueue completionQueue]; - - _call = [[GRPCHost hostWithAddress:host] unmanagedCallWithPath:path - serverName:serverName - timeout:timeout - completionQueue:_queue]; - if (_call == NULL) { - return nil; - } + if ((self = [super init])) { + _call = unmanagedCall; + _pooledChannel = pooledChannel; } return self; } @@ -278,41 +267,70 @@ [GRPCOpBatchLog addOpBatchToLog:operations]; #endif - size_t nops = operations.count; - grpc_op *ops_array = gpr_malloc(nops * sizeof(grpc_op)); - size_t i = 0; - 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); - gpr_free(ops_array); + @synchronized(self) { + if (_call != NULL) { + size_t nops = operations.count; + grpc_op *ops_array = gpr_malloc(nops * sizeof(grpc_op)); + size_t i = 0; + 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); + 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]; + NSAssert(error == GRPC_CALL_OK, @"Error starting a batch of operations: %i", error); + // To avoid compiler complaint when NSAssert is disabled. + if (error != GRPC_CALL_OK) { + return; + } + } } } - (void)cancel { - grpc_call_cancel(_call, NULL); + @synchronized(self) { + if (_call != NULL) { + grpc_call_cancel(_call, NULL); + } + } +} + +- (void)channelDisconnected { + @synchronized(self) { + if (_call != NULL) { + // Unreference the call will lead to its cancellation in the core. Note that since + // this function is only called with a network state change, any existing GRPCCall object will + // also receive the same notification and cancel themselves with GRPCErrorCodeUnavailable, so + // the user gets GRPCErrorCodeUnavailable in this case. + grpc_call_unref(_call); + _call = NULL; + } + } } - (void)dealloc { - grpc_call_unref(_call); + @synchronized(self) { + if (_call != NULL) { + grpc_call_unref(_call); + _call = NULL; + } + } + // Explicitly converting weak reference _pooledChannel to strong. + __strong GRPCPooledChannel *channel = _pooledChannel; + [channel notifyWrappedCallDealloc:self]; } @end diff --git a/src/objective-c/GRPCClient/private/version.h b/src/objective-c/GRPCClient/private/version.h index d5463c0b4cc..6fe0c396dd3 100644 --- a/src/objective-c/GRPCClient/private/version.h +++ b/src/objective-c/GRPCClient/private/version.h @@ -22,4 +22,4 @@ // instead. This file can be regenerated from the template by running // `tools/buildgen/generate_projects.sh`. -#define GRPC_OBJC_VERSION_STRING @"1.17.0-dev" +#define GRPC_OBJC_VERSION_STRING @"1.22.0-dev" diff --git a/src/objective-c/ProtoRPC/ProtoRPC.h b/src/objective-c/ProtoRPC/ProtoRPC.h index 45d35260921..12db46adeda 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.h +++ b/src/objective-c/ProtoRPC/ProtoRPC.h @@ -21,6 +21,149 @@ #import "ProtoMethod.h" +NS_ASSUME_NONNULL_BEGIN + +@class GPBMessage; + +/** An object can implement this protocol to receive responses from server from a call. */ +@protocol GRPCProtoResponseHandler + +@required + +/** + * All the responses must be issued to a user-provided dispatch queue. This property specifies the + * dispatch queue to be used for issuing the notifications. + */ +@property(atomic, readonly) dispatch_queue_t dispatchQueue; + +@optional + +/** + * Issued when initial metadata is received from the server. + */ +- (void)didReceiveInitialMetadata:(nullable NSDictionary *)initialMetadata; + +/** + * Issued when a message is received from the server. The message is the deserialized proto object. + */ +- (void)didReceiveProtoMessage:(nullable GPBMessage *)message; + +/** + * Issued when a call finished. If the call finished successfully, \a error is nil and \a + * trainingMetadata consists any trailing metadata received from the server. Otherwise, \a error + * is non-nil and contains the corresponding error information, including gRPC error codes and + * error descriptions. + */ +- (void)didCloseWithTrailingMetadata:(nullable NSDictionary *)trailingMetadata + error:(nullable NSError *)error; + +/** + * Issued when flow control is enabled for the call and a message (written with writeMessage: method + * of GRPCStreamingProtoCall or the initializer of GRPCUnaryProtoCall) is passed to gRPC core with + * SEND_MESSAGE operation. + */ +- (void)didWriteMessage; + +@end + +/** A unary-request RPC call with Protobuf. */ +@interface GRPCUnaryProtoCall : NSObject + +- (instancetype)init NS_UNAVAILABLE; + ++ (instancetype) new NS_UNAVAILABLE; + +/** + * Users should not use this initializer directly. Call objects will be created, initialized, and + * returned to users by methods of the generated service. + */ +- (nullable instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions + message:(GPBMessage *)message + responseHandler:(id)handler + callOptions:(nullable GRPCCallOptions *)callOptions + responseClass:(Class)responseClass NS_DESIGNATED_INITIALIZER; + +/** + * Start the call. This function must only be called once for each instance. + */ +- (void)start; + +/** + * Cancel the request of this call at best effort. It attempts to notify the server that the RPC + * should be cancelled, and issue didCloseWithTrailingMetadata:error: callback with error code + * CANCELED if no other error code has already been issued. + */ +- (void)cancel; + +@end + +/** A client-streaming RPC call with Protobuf. */ +@interface GRPCStreamingProtoCall : NSObject + +- (instancetype)init NS_UNAVAILABLE; + ++ (instancetype) new NS_UNAVAILABLE; + +/** + * Users should not use this initializer directly. Call objects will be created, initialized, and + * returned to users by methods of the generated service. + */ +- (nullable instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions + responseHandler:(id)handler + callOptions:(nullable GRPCCallOptions *)callOptions + responseClass:(Class)responseClass NS_DESIGNATED_INITIALIZER; + +/** + * Start the call. This function must only be called once for each instance. + */ +- (void)start; + +/** + * Cancel the request of this call at best effort. It attempts to notify the server that the RPC + * should be cancelled, and issue didCloseWithTrailingMetadata:error: callback with error code + * CANCELED if no other error code has already been issued. + */ +- (void)cancel; + +/** + * Send a message to the server. The message should be a Protobuf message which will be serialized + * internally. + */ +- (void)writeMessage:(GPBMessage *)message; + +/** + * Finish the RPC request and half-close the call. The server may still send messages and/or + * trailers to the client. + */ +- (void)finish; + +/** + * Tell gRPC to receive another message. + * + * This method should only be used when flow control is enabled. If flow control is enabled, gRPC + * will only receive additional messages after the user indicates so by using either + * receiveNextMessage: or receiveNextMessages: methods. If flow control is not enabled, messages + * will be automatically received after the previous one is delivered. + */ +- (void)receiveNextMessage; + +/** + * Tell gRPC to receive another N message. + * + * This method should only be used when flow control is enabled. If flow control is enabled, the + * messages received from the server are buffered in gRPC until the user want to receive the next + * message. If flow control is not enabled, messages will be automatically received after the + * previous one is delivered. + */ +- (void)receiveNextMessages:(NSUInteger)numberOfMessages; + +@end + +NS_ASSUME_NONNULL_END + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnullability-completeness" + __attribute__((deprecated("Please use GRPCProtoCall."))) @interface ProtoRPC : GRPCCall @@ -47,3 +190,5 @@ __attribute__((deprecated("Please use GRPCProtoCall."))) @interface ProtoRPC #pragma clang diagnostic pop @end + +#pragma clang diagnostic pop diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index 5dca971b08a..80988be318b 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -23,9 +23,13 @@ #else #import #endif +#import #import #import +/** + * Generate an NSError object that represents a failure in parsing a proto class. + */ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsingError) { NSDictionary *info = @{ NSLocalizedDescriptionKey : @"Unable to parse response from the server", @@ -41,6 +45,253 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing return [NSError errorWithDomain:@"io.grpc" code:13 userInfo:info]; } +@implementation GRPCUnaryProtoCall { + GRPCStreamingProtoCall *_call; + GPBMessage *_message; +} + +- (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions + message:(GPBMessage *)message + responseHandler:(id)handler + callOptions:(GRPCCallOptions *)callOptions + responseClass:(Class)responseClass { + NSAssert(message != nil, @"message cannot be empty."); + NSAssert(responseClass != nil, @"responseClass cannot be empty."); + if (message == nil || responseClass == nil) { + return nil; + } + if ((self = [super init])) { + _call = [[GRPCStreamingProtoCall alloc] initWithRequestOptions:requestOptions + responseHandler:handler + callOptions:callOptions + responseClass:responseClass]; + _message = [message copy]; + } + return self; +} + +- (void)start { + [_call start]; + [_call receiveNextMessage]; + [_call writeMessage:_message]; + [_call finish]; +} + +- (void)cancel { + [_call cancel]; +} + +@end + +@interface GRPCStreamingProtoCall () + +@end + +@implementation GRPCStreamingProtoCall { + GRPCRequestOptions *_requestOptions; + id _handler; + GRPCCallOptions *_callOptions; + Class _responseClass; + + GRPCCall2 *_call; + dispatch_queue_t _dispatchQueue; +} + +- (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions + responseHandler:(id)handler + callOptions:(GRPCCallOptions *)callOptions + responseClass:(Class)responseClass { + NSAssert(requestOptions.host.length != 0 && requestOptions.path.length != 0 && + requestOptions.safety <= GRPCCallSafetyCacheableRequest, + @"Invalid callOptions."); + NSAssert(handler != nil, @"handler cannot be empty."); + if (requestOptions.host.length == 0 || requestOptions.path.length == 0 || + requestOptions.safety > GRPCCallSafetyCacheableRequest) { + return nil; + } + if (handler == nil) { + return nil; + } + + if ((self = [super init])) { + _requestOptions = [requestOptions copy]; + _handler = handler; + _callOptions = [callOptions copy]; + _responseClass = responseClass; + + // Set queue QoS only when iOS version is 8.0 or above and Xcode version is 9.0 or above +#if __IPHONE_OS_VERSION_MAX_ALLOWED < 110000 || __MAC_OS_X_VERSION_MAX_ALLOWED < 101300 + if (@available(iOS 8.0, macOS 10.10, *)) { + _dispatchQueue = dispatch_queue_create( + NULL, + dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, 0)); + } else { +#else + { +#endif + _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); + } + dispatch_set_target_queue(_dispatchQueue, handler.dispatchQueue); + + _call = [[GRPCCall2 alloc] initWithRequestOptions:_requestOptions + responseHandler:self + callOptions:_callOptions]; + } + return self; +} + +- (void)start { + GRPCCall2 *copiedCall; + @synchronized(self) { + copiedCall = _call; + } + [copiedCall start]; +} + +- (void)cancel { + GRPCCall2 *copiedCall; + @synchronized(self) { + copiedCall = _call; + _call = nil; + if ([_handler respondsToSelector:@selector(didCloseWithTrailingMetadata:error:)]) { + dispatch_async(_dispatchQueue, ^{ + id copiedHandler = nil; + @synchronized(self) { + copiedHandler = self->_handler; + self->_handler = nil; + } + [copiedHandler didCloseWithTrailingMetadata:nil + error:[NSError errorWithDomain:kGRPCErrorDomain + code:GRPCErrorCodeCancelled + userInfo:@{ + NSLocalizedDescriptionKey : + @"Canceled by app" + }]]; + }); + } else { + _handler = nil; + } + } + [copiedCall cancel]; +} + +- (void)writeMessage:(GPBMessage *)message { + NSAssert([message isKindOfClass:[GPBMessage class]], @"Parameter message must be a GPBMessage"); + if (![message isKindOfClass:[GPBMessage class]]) { + NSLog(@"Failed to send a message that is non-proto."); + return; + } + + GRPCCall2 *copiedCall; + @synchronized(self) { + copiedCall = _call; + } + [copiedCall writeData:[message data]]; +} + +- (void)finish { + GRPCCall2 *copiedCall; + @synchronized(self) { + copiedCall = _call; + _call = nil; + } + [copiedCall finish]; +} + +- (void)receiveNextMessage { + [self receiveNextMessages:1]; +} +- (void)receiveNextMessages:(NSUInteger)numberOfMessages { + GRPCCall2 *copiedCall; + @synchronized(self) { + copiedCall = _call; + } + [copiedCall receiveNextMessages:numberOfMessages]; +} + +- (void)didReceiveInitialMetadata:(NSDictionary *)initialMetadata { + @synchronized(self) { + if (initialMetadata != nil && + [_handler respondsToSelector:@selector(didReceiveInitialMetadata:)]) { + dispatch_async(_dispatchQueue, ^{ + id copiedHandler = nil; + @synchronized(self) { + copiedHandler = self->_handler; + } + [copiedHandler didReceiveInitialMetadata:initialMetadata]; + }); + } + } +} + +- (void)didReceiveRawMessage:(NSData *)message { + if (message == nil) return; + + NSError *error = nil; + GPBMessage *parsed = [_responseClass parseFromData:message error:&error]; + @synchronized(self) { + if (parsed && [_handler respondsToSelector:@selector(didReceiveProtoMessage:)]) { + dispatch_async(_dispatchQueue, ^{ + id copiedHandler = nil; + @synchronized(self) { + copiedHandler = self->_handler; + } + [copiedHandler didReceiveProtoMessage:parsed]; + }); + } else if (!parsed && + [_handler respondsToSelector:@selector(didCloseWithTrailingMetadata:error:)]) { + dispatch_async(_dispatchQueue, ^{ + id copiedHandler = nil; + @synchronized(self) { + copiedHandler = self->_handler; + self->_handler = nil; + } + [copiedHandler + didCloseWithTrailingMetadata:nil + error:ErrorForBadProto(message, self->_responseClass, error)]; + }); + [_call cancel]; + _call = nil; + } + } +} + +- (void)didCloseWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { + @synchronized(self) { + if ([_handler respondsToSelector:@selector(didCloseWithTrailingMetadata:error:)]) { + dispatch_async(_dispatchQueue, ^{ + id copiedHandler = nil; + @synchronized(self) { + copiedHandler = self->_handler; + self->_handler = nil; + } + [copiedHandler didCloseWithTrailingMetadata:trailingMetadata error:error]; + }); + } + _call = nil; + } +} + +- (void)didWriteData { + @synchronized(self) { + if ([_handler respondsToSelector:@selector(didWriteMessage)]) { + dispatch_async(_dispatchQueue, ^{ + id copiedHandler = nil; + @synchronized(self) { + copiedHandler = self->_handler; + } + [copiedHandler didWriteMessage]; + }); + } + } +} + +- (dispatch_queue_t)dispatchQueue { + return _dispatchQueue; +} + +@end + #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-implementations" @implementation ProtoRPC { @@ -72,7 +323,7 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing } // A writer that serializes the proto messages to send. GRXWriter *bytesWriter = [requestsWriter map:^id(GPBMessage *proto) { - if (![proto isKindOfClass:GPBMessage.class]) { + if (![proto isKindOfClass:[GPBMessage class]]) { [NSException raise:NSInvalidArgumentException format:@"Request must be a proto message: %@", proto]; } diff --git a/src/objective-c/ProtoRPC/ProtoService.h b/src/objective-c/ProtoRPC/ProtoService.h index 29c4e9be360..900ec8d0e1e 100644 --- a/src/objective-c/ProtoRPC/ProtoService.h +++ b/src/objective-c/ProtoRPC/ProtoService.h @@ -21,18 +21,47 @@ @class GRPCProtoCall; @protocol GRXWriteable; @class GRXWriter; +@class GRPCCallOptions; +@class GRPCProtoCall; +@class GRPCUnaryProtoCall; +@class GRPCStreamingProtoCall; +@protocol GRPCProtoResponseHandler; + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnullability-completeness" __attribute__((deprecated("Please use GRPCProtoService."))) @interface ProtoService - : NSObject - - (instancetype)initWithHost : (NSString *)host packageName - : (NSString *)packageName serviceName : (NSString *)serviceName NS_DESIGNATED_INITIALIZER; + : NSObject + + - + (nullable instancetype)initWithHost : (nonnull NSString *)host packageName + : (nonnull NSString *)packageName serviceName : (nonnull NSString *)serviceName callOptions + : (nullable GRPCCallOptions *)callOptions NS_DESIGNATED_INITIALIZER; + +- (instancetype)initWithHost:(NSString *)host + packageName:(NSString *)packageName + serviceName:(NSString *)serviceName; - (GRPCProtoCall *)RPCToMethod:(NSString *)method requestsWriter:(GRXWriter *)requestsWriter responseClass:(Class)responseClass responsesWriteable:(id)responsesWriteable; + +- (nullable GRPCUnaryProtoCall *)RPCToMethod:(nonnull NSString *)method + message:(nonnull id)message + responseHandler:(nonnull id)handler + callOptions:(nullable GRPCCallOptions *)callOptions + responseClass:(nonnull Class)responseClass; + +- (nullable GRPCStreamingProtoCall *)RPCToMethod:(nonnull NSString *)method + responseHandler:(nonnull id)handler + callOptions:(nullable GRPCCallOptions *)callOptions + responseClass:(nonnull Class)responseClass; + @end +#pragma clang diagnostic pop + /** * This subclass is empty now. Eventually we'll remove ProtoService class * to avoid potential naming conflict diff --git a/src/objective-c/ProtoRPC/ProtoService.m b/src/objective-c/ProtoRPC/ProtoService.m index 3e9cc5c0b2d..80a1f2f226c 100644 --- a/src/objective-c/ProtoRPC/ProtoService.m +++ b/src/objective-c/ProtoRPC/ProtoService.m @@ -18,6 +18,7 @@ #import "ProtoService.h" +#import #import #import @@ -31,6 +32,7 @@ NSString *_host; NSString *_packageName; NSString *_serviceName; + GRPCCallOptions *_callOptions; } - (instancetype)init { @@ -40,19 +42,41 @@ // Designated initializer - (instancetype)initWithHost:(NSString *)host packageName:(NSString *)packageName - serviceName:(NSString *)serviceName { - if (!host || !serviceName) { - [NSException raise:NSInvalidArgumentException - format:@"Neither host nor serviceName can be nil."]; + serviceName:(NSString *)serviceName + callOptions:(GRPCCallOptions *)callOptions { + NSAssert(host.length != 0 && packageName.length != 0 && serviceName.length != 0, + @"Invalid parameter."); + if (host.length == 0 || packageName.length == 0 || serviceName.length == 0) { + return nil; } if ((self = [super init])) { _host = [host copy]; _packageName = [packageName copy]; _serviceName = [serviceName copy]; + _callOptions = [callOptions copy]; } return self; } +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wobjc-designated-initializers" +// Do not call designated initializer here due to nullability incompatibility. This method is from +// old API and does not assert on nullability of the parameters. + +- (instancetype)initWithHost:(NSString *)host + packageName:(NSString *)packageName + serviceName:(NSString *)serviceName { + if ((self = [super init])) { + _host = [host copy]; + _packageName = [packageName copy]; + _serviceName = [serviceName copy]; + _callOptions = nil; + } + return self; +} + +#pragma clang diagnostic pop + - (GRPCProtoCall *)RPCToMethod:(NSString *)method requestsWriter:(GRXWriter *)requestsWriter responseClass:(Class)responseClass @@ -65,6 +89,41 @@ responseClass:responseClass responsesWriteable:responsesWriteable]; } + +- (GRPCUnaryProtoCall *)RPCToMethod:(NSString *)method + message:(id)message + responseHandler:(id)handler + callOptions:(GRPCCallOptions *)callOptions + responseClass:(Class)responseClass { + GRPCProtoMethod *methodName = + [[GRPCProtoMethod alloc] initWithPackage:_packageName service:_serviceName method:method]; + GRPCRequestOptions *requestOptions = + [[GRPCRequestOptions alloc] initWithHost:_host + path:methodName.HTTPPath + safety:GRPCCallSafetyDefault]; + return [[GRPCUnaryProtoCall alloc] initWithRequestOptions:requestOptions + message:message + responseHandler:handler + callOptions:callOptions ?: _callOptions + responseClass:responseClass]; +} + +- (GRPCStreamingProtoCall *)RPCToMethod:(NSString *)method + responseHandler:(id)handler + callOptions:(GRPCCallOptions *)callOptions + responseClass:(Class)responseClass { + GRPCProtoMethod *methodName = + [[GRPCProtoMethod alloc] initWithPackage:_packageName service:_serviceName method:method]; + GRPCRequestOptions *requestOptions = + [[GRPCRequestOptions alloc] initWithHost:_host + path:methodName.HTTPPath + safety:GRPCCallSafetyDefault]; + return [[GRPCStreamingProtoCall alloc] initWithRequestOptions:requestOptions + responseHandler:handler + callOptions:callOptions ?: _callOptions + responseClass:responseClass]; +} + @end @implementation GRPCProtoService diff --git a/src/objective-c/README-CFSTREAM.md b/src/objective-c/README-CFSTREAM.md index 0cb25ab237b..184d5679cbb 100644 --- a/src/objective-c/README-CFSTREAM.md +++ b/src/objective-c/README-CFSTREAM.md @@ -6,24 +6,19 @@ sockets) for networking. Using CFStream resolves a bunch of network connectivity (see the [doc](https://github.com/grpc/grpc/blob/master/src/objective-c/NetworkTransitionBehavior.md) for more information). -CFStream integration is now in experimental state. You will need explicit opt-in to use it to get +CFStream integration is now in experimental state. You will need explicit opt-in to use it to get the benefits of resolving the issues above. We expect to make CFStream the default networking -interface that gRPC uses when it is ready for production. +interface that gRPC uses when it is ready for production. + +As of v1.21.0, CFStream integration is now the default networking stack being used by gRPC +Objective-C on iOS layer. You get to use it automatically without special configuration needed. See +below on how to disable CFStream in case of problem. ## Usage -If you use gRPC following the instructions in -[README.md](https://github.com/grpc/grpc/blob/master/src/objective-c/README.md): -- Replace the -dependency on `gRPC-ProtoRPC` with `gRPC-ProtoRPC/CFStream`. -- Enable CFStream with environment variable `grpc_cfstream=1`. This can be done either in Xcode - console or by your code with `setenv()` before gRPC is initialized. - -If your project directly depends on podspecs other than `gRPC-ProtoRPC` (e.g. `gRPC` or -`gRPC-Core`): - -- Make your projects depend on subspecs corresponding to CFStream in each gRPC podspec. -- Enable CFStream with environment variable `grpc_cfstream=1`. This can be done either in Xcode - console or by your code with `setenv()` before gRPC is initialized. +If you use gRPC Objective-C library on iOS, CFStream is on automatically. If you use it on other +platforms, you can turn it on with macro `GRPC_CFSTREAM=1` for the pod 'gRPC-Core' and 'gRPC'. In +case of problem and you want to disable CFStream on iOS, you can set environment variable +"grpc\_cfstream=0". ## Notes diff --git a/src/objective-c/README.md b/src/objective-c/README.md index 32e3956a1ef..83775f86e17 100644 --- a/src/objective-c/README.md +++ b/src/objective-c/README.md @@ -242,3 +242,12 @@ pod `gRPC-Core`, :podspec => "." # assuming gRPC-Core.podspec is in the same dir These steps should allow gRPC to use OpenSSL and drop BoringSSL dependency. If you see any issue, file an issue to us. + +## Upgrade issue with BoringSSL +If you were using an old version of gRPC (<= v1.14) which depended on pod `BoringSSL` rather than +`BoringSSL-GRPC` and meet issue with the library like: +``` +ld: framework not found openssl +``` +updating `-framework openssl` in Other Linker Flags to `-framework openssl_grpc` in your project +may resolve this issue (see [#16821](https://github.com/grpc/grpc/issues/16821)). diff --git a/src/objective-c/RxLibrary/GRXBufferedPipe.h b/src/objective-c/RxLibrary/GRXBufferedPipe.h index a871ea895aa..ae08cc315bb 100644 --- a/src/objective-c/RxLibrary/GRXBufferedPipe.h +++ b/src/objective-c/RxLibrary/GRXBufferedPipe.h @@ -36,8 +36,7 @@ * crash. If you want to react to flow control signals to prevent that, instead of using this class * you can implement an object that conforms to GRXWriter. * - * Thread-safety: - * The methods of an object of this class should not be called concurrently from different threads. + * Thread-safety: the methods of this class are thread-safe. */ @interface GRXBufferedPipe : GRXWriter diff --git a/src/objective-c/RxLibrary/GRXBufferedPipe.m b/src/objective-c/RxLibrary/GRXBufferedPipe.m index 546d46cba32..74e2f03da6c 100644 --- a/src/objective-c/RxLibrary/GRXBufferedPipe.m +++ b/src/objective-c/RxLibrary/GRXBufferedPipe.m @@ -51,16 +51,22 @@ // We need a copy, so that it doesn't mutate before it's written at the other end of the pipe. value = [value copy]; } - __weak GRXBufferedPipe *weakSelf = self; dispatch_async(_writeQueue, ^(void) { - [weakSelf.writeable writeValue:value]; + @synchronized(self) { + if (self->_state == GRXWriterStateFinished) { + return; + } + [self.writeable writeValue:value]; + } }); } - (void)writesFinishedWithError:(NSError *)errorOrNil { - __weak GRXBufferedPipe *weakSelf = self; dispatch_async(_writeQueue, ^{ - [weakSelf finishWithError:errorOrNil]; + if (self->_state == GRXWriterStateFinished) { + return; + } + [self finishWithError:errorOrNil]; }); } @@ -100,14 +106,15 @@ } - (void)startWithWriteable:(id)writeable { - self.writeable = writeable; - _state = GRXWriterStateStarted; + @synchronized(self) { + self.writeable = writeable; + _state = GRXWriterStateStarted; + } dispatch_resume(_writeQueue); } - (void)finishWithError:(NSError *)errorOrNil { [self.writeable writesFinishedWithError:errorOrNil]; - self.state = GRXWriterStateFinished; } - (void)dealloc { diff --git a/src/objective-c/RxLibrary/GRXConcurrentWriteable.h b/src/objective-c/RxLibrary/GRXConcurrentWriteable.h index abb831e6fb4..5beca9d41e3 100644 --- a/src/objective-c/RxLibrary/GRXConcurrentWriteable.h +++ b/src/objective-c/RxLibrary/GRXConcurrentWriteable.h @@ -23,10 +23,10 @@ /** * This is a thread-safe wrapper over a GRXWriteable instance. It lets one enqueue calls to a - * GRXWriteable instance for the main thread, guaranteeing that writesFinishedWithError: is the last - * message sent to it (no matter what messages are sent to the wrapper, in what order, nor from - * which thread). It also guarantees that, if cancelWithError: is called from the main thread (e.g. - * by the app cancelling the writes), no further messages are sent to the writeable except + * GRXWriteable instance for the thread user provided, guaranteeing that writesFinishedWithError: is + * the last message sent to it (no matter what messages are sent to the wrapper, in what order, nor + * from which thread). It also guarantees that, if cancelWithError: is called (e.g. by the app + * cancelling the writes), no further messages are sent to the writeable except * writesFinishedWithError:. * * TODO(jcanizales): Let the user specify another queue for the writeable callbacks. @@ -43,21 +43,22 @@ - (instancetype)initWithWriteable:(id)writeable; /** - * Enqueues writeValue: to be sent to the writeable in the main thread. - * The passed handler is invoked from the main thread after writeValue: returns. + * Enqueues writeValue: to be sent to the writeable from the designated dispatch queue. + * The passed handler is invoked from designated dispatch queue after writeValue: returns. */ - (void)enqueueValue:(id)value completionHandler:(void (^)(void))handler; /** - * Enqueues writesFinishedWithError:nil to be sent to the writeable in the main thread. After that - * message is sent to the writeable, all other methods of this object are effectively noops. + * Enqueues writesFinishedWithError:nil to be sent to the writeable in the designated dispatch + * queue. After that message is sent to the writeable, all other methods of this object are + * effectively noops. */ - (void)enqueueSuccessfulCompletion; /** * If the writeable has not yet received a writesFinishedWithError: message, this will enqueue one - * to be sent to it in the main thread, and cancel all other pending messages to the writeable - * enqueued by this object (both past and future). + * to be sent to it in the designated dispatch queue, and cancel all other pending messages to the + * writeable enqueued by this object (both past and future). * The error argument cannot be nil. */ - (void)cancelWithError:(NSError *)error; diff --git a/src/objective-c/RxLibrary/GRXConcurrentWriteable.m b/src/objective-c/RxLibrary/GRXConcurrentWriteable.m index 81ccc3fbcea..115195463de 100644 --- a/src/objective-c/RxLibrary/GRXConcurrentWriteable.m +++ b/src/objective-c/RxLibrary/GRXConcurrentWriteable.m @@ -27,8 +27,15 @@ @implementation GRXConcurrentWriteable { dispatch_queue_t _writeableQueue; - // This ensures that writesFinishedWithError: is only sent once to the writeable. + + // This ivar ensures that writesFinishedWithError: is only sent once to the writeable. Protected + // by _writeableQueue. BOOL _alreadyFinished; + + // This ivar ensures that a cancelWithError: call prevents further values to be sent to + // self.writeable. It must support manipulation outside of _writeableQueue and thus needs to be + // protected by self lock. + BOOL _cancelled; } - (instancetype)init { @@ -41,6 +48,8 @@ if (self = [super init]) { _writeableQueue = queue; _writeable = writeable; + _alreadyFinished = NO; + _cancelled = NO; } return self; } @@ -51,78 +60,63 @@ - (void)enqueueValue:(id)value completionHandler:(void (^)(void))handler { dispatch_async(_writeableQueue, ^{ - // We're racing a possible cancellation performed by another thread. To turn all already- - // enqueued messages into noops, cancellation nillifies the writeable property. If we get it - // before it's nil, we won the race. - id writeable = self.writeable; - if (writeable) { - [writeable writeValue:value]; - handler(); + if (self->_alreadyFinished) { + return; } + + @synchronized(self) { + if (self->_cancelled) { + return; + } + } + + [self.writeable writeValue:value]; + handler(); }); } - (void)enqueueSuccessfulCompletion { - __weak typeof(self) weakSelf = self; dispatch_async(_writeableQueue, ^{ - typeof(self) strongSelf = weakSelf; - if (strongSelf) { - BOOL finished = NO; - @synchronized(strongSelf) { - if (!strongSelf->_alreadyFinished) { - strongSelf->_alreadyFinished = YES; - } else { - finished = YES; - } - } - if (!finished) { - // Cancellation is now impossible. None of the other three blocks can run concurrently with - // this one. - [strongSelf.writeable writesFinishedWithError:nil]; - // Skip any possible message to the wrapped writeable enqueued after this one. - strongSelf.writeable = nil; + if (self->_alreadyFinished) { + return; + } + @synchronized(self) { + if (self->_cancelled) { + return; } } + [self.writeable writesFinishedWithError:nil]; + + // Skip any possible message to the wrapped writeable enqueued after this one. + self->_alreadyFinished = YES; + self.writeable = nil; }); } - (void)cancelWithError:(NSError *)error { - NSAssert(error, @"For a successful completion, use enqueueSuccessfulCompletion."); - BOOL finished = NO; + NSAssert(error != nil, @"For a successful completion, use enqueueSuccessfulCompletion."); @synchronized(self) { - if (!_alreadyFinished) { - _alreadyFinished = YES; - } else { - finished = YES; + self->_cancelled = YES; + } + dispatch_async(_writeableQueue, ^{ + if (self->_alreadyFinished) { + // a cancel or a successful completion is already issued + return; } - } - if (!finished) { - // Skip any of the still-enqueued messages to the wrapped writeable. We use the atomic setter to - // nillify writeable because we might be running concurrently with the blocks in - // _writeableQueue, and assignment with ARC isn't atomic. - id writeable = self.writeable; - self.writeable = nil; + [self.writeable writesFinishedWithError:error]; - dispatch_async(_writeableQueue, ^{ - [writeable writesFinishedWithError:error]; - }); - } + // Skip any possible message to the wrapped writeable enqueued after this one. + self->_alreadyFinished = YES; + self.writeable = nil; + }); } - (void)cancelSilently { - BOOL finished = NO; - @synchronized(self) { - if (!_alreadyFinished) { - _alreadyFinished = YES; - } else { - finished = YES; + dispatch_async(_writeableQueue, ^{ + if (self->_alreadyFinished) { + return; } - } - if (!finished) { - // Skip any of the still-enqueued messages to the wrapped writeable. We use the atomic setter to - // nillify writeable because we might be running concurrently with the blocks in - // _writeableQueue, and assignment with ARC isn't atomic. self.writeable = nil; - } + }); } @end diff --git a/src/objective-c/RxLibrary/GRXForwardingWriter.h b/src/objective-c/RxLibrary/GRXForwardingWriter.h index 3814ff8831c..00366b64162 100644 --- a/src/objective-c/RxLibrary/GRXForwardingWriter.h +++ b/src/objective-c/RxLibrary/GRXForwardingWriter.h @@ -25,11 +25,7 @@ * input writer, and for classes that represent objects with input and * output sequences of values, like an RPC. * - * Thread-safety: - * All messages sent to this object need to be serialized. When it is started, the writer it wraps - * is started in the same thread. Manual state changes are propagated to the wrapped writer in the - * same thread too. Importantly, all messages the wrapped writer sends to its writeable need to be - * serialized with any message sent to this object. + * Thread-safety: the methods of this class are thread safe. */ @interface GRXForwardingWriter : GRXWriter - (instancetype)initWithWriter:(GRXWriter *)writer NS_DESIGNATED_INITIALIZER; diff --git a/src/objective-c/RxLibrary/GRXForwardingWriter.m b/src/objective-c/RxLibrary/GRXForwardingWriter.m index 3e522ef24e0..27ac0acdfff 100644 --- a/src/objective-c/RxLibrary/GRXForwardingWriter.m +++ b/src/objective-c/RxLibrary/GRXForwardingWriter.m @@ -54,48 +54,65 @@ [writeable writesFinishedWithError:errorOrNil]; } -// This is used to stop the input writer. It nillifies our reference to it -// to release it. -- (void)finishInput { - GRXWriter *writer = _writer; - _writer = nil; - writer.state = GRXWriterStateFinished; -} - #pragma mark GRXWriteable implementation - (void)writeValue:(id)value { - [_writeable writeValue:value]; + @synchronized(self) { + [_writeable writeValue:value]; + } } - (void)writesFinishedWithError:(NSError *)errorOrNil { - _writer = nil; - [self finishOutputWithError:errorOrNil]; + @synchronized(self) { + _writer = nil; + [self finishOutputWithError:errorOrNil]; + } } #pragma mark GRXWriter implementation - (GRXWriterState)state { - return _writer ? _writer.state : GRXWriterStateFinished; + GRXWriter *copiedWriter; + @synchronized(self) { + copiedWriter = _writer; + } + return copiedWriter ? copiedWriter.state : GRXWriterStateFinished; } - (void)setState:(GRXWriterState)state { + GRXWriter *copiedWriter = nil; if (state == GRXWriterStateFinished) { - _writeable = nil; - [self finishInput]; + @synchronized(self) { + _writeable = nil; + copiedWriter = _writer; + _writer = nil; + } + copiedWriter.state = GRXWriterStateFinished; } else { - _writer.state = state; + @synchronized(self) { + copiedWriter = _writer; + } + copiedWriter.state = state; } } - (void)startWithWriteable:(id)writeable { - _writeable = writeable; - [_writer startWithWriteable:self]; + GRXWriter *copiedWriter = nil; + @synchronized(self) { + _writeable = writeable; + copiedWriter = _writer; + } + [copiedWriter startWithWriteable:self]; } - (void)finishWithError:(NSError *)errorOrNil { - [self finishOutputWithError:errorOrNil]; - [self finishInput]; + GRXWriter *copiedWriter = nil; + @synchronized(self) { + [self finishOutputWithError:errorOrNil]; + copiedWriter = _writer; + _writer = nil; + } + copiedWriter.state = GRXWriterStateFinished; } @end diff --git a/src/objective-c/RxLibrary/GRXImmediateSingleWriter.h b/src/objective-c/RxLibrary/GRXImmediateSingleWriter.h index 601abdc6b90..2fa38b3dcea 100644 --- a/src/objective-c/RxLibrary/GRXImmediateSingleWriter.h +++ b/src/objective-c/RxLibrary/GRXImmediateSingleWriter.h @@ -23,6 +23,8 @@ /** * Utility to construct GRXWriter instances from values that are immediately available when * required. + * + * Thread safety: the methods of this class are thread safe. */ @interface GRXImmediateSingleWriter : GRXImmediateWriter diff --git a/src/objective-c/RxLibrary/GRXImmediateSingleWriter.m b/src/objective-c/RxLibrary/GRXImmediateSingleWriter.m index 3126ae4bd16..079c11b94fb 100644 --- a/src/objective-c/RxLibrary/GRXImmediateSingleWriter.m +++ b/src/objective-c/RxLibrary/GRXImmediateSingleWriter.m @@ -20,7 +20,6 @@ @implementation GRXImmediateSingleWriter { id _value; - id _writeable; } @synthesize state = _state; @@ -38,17 +37,16 @@ } - (void)startWithWriteable:(id)writeable { - _state = GRXWriterStateStarted; - _writeable = writeable; - [writeable writeValue:_value]; - [self finish]; -} - -- (void)finish { - _state = GRXWriterStateFinished; - _value = nil; - id writeable = _writeable; - _writeable = nil; + id copiedValue = nil; + @synchronized(self) { + if (_state != GRXWriterStateNotStarted) { + return; + } + copiedValue = _value; + _value = nil; + _state = GRXWriterStateFinished; + } + [writeable writeValue:copiedValue]; [writeable writesFinishedWithError:nil]; } @@ -65,9 +63,11 @@ // the original \a map function returns a new Writer of another type. So we // need to override this function here. - (GRXWriter *)map:(id (^)(id))map { - // Since _value is available when creating the object, we can simply - // apply the map and store the output. - _value = map(_value); + @synchronized(self) { + // Since _value is available when creating the object, we can simply + // apply the map and store the output. + _value = map(_value); + } return self; } diff --git a/src/objective-c/RxLibrary/GRXWriter.h b/src/objective-c/RxLibrary/GRXWriter.h index 5d99583a928..df4c80c28dd 100644 --- a/src/objective-c/RxLibrary/GRXWriter.h +++ b/src/objective-c/RxLibrary/GRXWriter.h @@ -80,9 +80,9 @@ typedef NS_ENUM(NSInteger, GRXWriterState) { * This property can be used to query the current state of the writer, which determines how it might * currently use its writeable. Some state transitions can be triggered by setting this property to * the corresponding value, and that's useful for advanced use cases like pausing an writer. For - * more details, see the documentation of the enum further down. + * more details, see the documentation of the enum further down. The property is thread safe. */ -@property(nonatomic) GRXWriterState state; +@property GRXWriterState state; /** * Transition to the Started state, and start sending messages to the writeable (a reference to it diff --git a/src/objective-c/examples/SwiftSample/ViewController.swift b/src/objective-c/examples/SwiftSample/ViewController.swift index 0ba6e21f02a..4ed10266a4d 100644 --- a/src/objective-c/examples/SwiftSample/ViewController.swift +++ b/src/objective-c/examples/SwiftSample/ViewController.swift @@ -54,8 +54,8 @@ class ViewController: UIViewController { } else { NSLog("2. Finished with error: \(error!)") } - NSLog("2. Response headers: \(RPC.responseHeaders)") - NSLog("2. Response trailers: \(RPC.responseTrailers)") + NSLog("2. Response headers: \(String(describing: RPC.responseHeaders))") + NSLog("2. Response trailers: \(String(describing: RPC.responseTrailers))") } // TODO(jcanizales): Revert to using subscript syntax once XCode 8 is released. @@ -68,7 +68,7 @@ class ViewController: UIViewController { let method = GRPCProtoMethod(package: "grpc.testing", service: "TestService", method: "UnaryCall")! - let requestsWriter = GRXWriter(value: request.data()) + let requestsWriter = GRXWriter(value: request.data())! let call = GRPCCall(host: RemoteHost, path: method.httpPath, requestsWriter: requestsWriter)! @@ -80,8 +80,8 @@ class ViewController: UIViewController { } else { NSLog("3. Finished with error: \(error!)") } - NSLog("3. Response headers: \(call.responseHeaders)") - NSLog("3. Response trailers: \(call.responseTrailers)") + NSLog("3. Response headers: \(String(describing: call.responseHeaders))") + NSLog("3. Response trailers: \(String(describing: call.responseTrailers))") }) } } diff --git a/src/objective-c/manual_tests/AppDelegate.h b/src/objective-c/manual_tests/AppDelegate.h new file mode 100644 index 00000000000..183abcf4ec8 --- /dev/null +++ b/src/objective-c/manual_tests/AppDelegate.h @@ -0,0 +1,25 @@ +/* + * + * Copyright 2019 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. + * + */ + +#import + +@interface AppDelegate : UIResponder + +@property(strong, nonatomic) UIWindow* window; + +@end diff --git a/src/objective-c/manual_tests/AppDelegate.m b/src/objective-c/manual_tests/AppDelegate.m new file mode 100644 index 00000000000..659f7528d22 --- /dev/null +++ b/src/objective-c/manual_tests/AppDelegate.m @@ -0,0 +1,23 @@ +/* + * + * Copyright 2019 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. + * + */ + +#import "AppDelegate.h" + +@implementation AppDelegate + +@end diff --git a/src/objective-c/manual_tests/GrpcIosTest.xcodeproj/project.pbxproj b/src/objective-c/manual_tests/GrpcIosTest.xcodeproj/project.pbxproj new file mode 100644 index 00000000000..3ad16c3af6e --- /dev/null +++ b/src/objective-c/manual_tests/GrpcIosTest.xcodeproj/project.pbxproj @@ -0,0 +1,509 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + 4E1314BB1DA3DC6ECCEB96AB /* libPods-GrpcIosTest.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D22EC48A487B02F76135EA3 /* libPods-GrpcIosTest.a */; }; + 5EDA909B220DF1B00046D27A /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EDA9094220DF1B00046D27A /* ViewController.m */; }; + 5EDA909C220DF1B00046D27A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EDA9096220DF1B00046D27A /* main.m */; }; + 5EDA909E220DF1B00046D27A /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5EDA9098220DF1B00046D27A /* Main.storyboard */; }; + 5EDA909F220DF1B00046D27A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EDA9099220DF1B00046D27A /* AppDelegate.m */; }; + B0C18CA7222DEF140002B502 /* GrpcIosTestUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = B0C18CA6222DEF140002B502 /* GrpcIosTestUITests.m */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + B0C18CA9222DEF140002B502 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 5EDA9073220DF0BC0046D27A /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5EDA907A220DF0BC0046D27A; + remoteInfo = GrpcIosTest; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 1D22EC48A487B02F76135EA3 /* libPods-GrpcIosTest.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-GrpcIosTest.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 5EDA907B220DF0BC0046D27A /* GrpcIosTest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = GrpcIosTest.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 5EDA9094220DF1B00046D27A /* ViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = SOURCE_ROOT; }; + 5EDA9095220DF1B00046D27A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = SOURCE_ROOT; }; + 5EDA9096220DF1B00046D27A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = SOURCE_ROOT; }; + 5EDA9098220DF1B00046D27A /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = SOURCE_ROOT; }; + 5EDA9099220DF1B00046D27A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = SOURCE_ROOT; }; + 7C9FAFB11727DCA50888C1B8 /* Pods-GrpcIosTest.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GrpcIosTest.debug.xcconfig"; path = "Pods/Target Support Files/Pods-GrpcIosTest/Pods-GrpcIosTest.debug.xcconfig"; sourceTree = ""; }; + A4E7CA72304A7B43FE8A5BC7 /* Pods-GrpcIosTest.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GrpcIosTest.release.xcconfig"; path = "Pods/Target Support Files/Pods-GrpcIosTest/Pods-GrpcIosTest.release.xcconfig"; sourceTree = ""; }; + B0C18CA4222DEF140002B502 /* GrpcIosTestUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = GrpcIosTestUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + B0C18CA6222DEF140002B502 /* GrpcIosTestUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GrpcIosTestUITests.m; sourceTree = ""; }; + B0C18CA8222DEF140002B502 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 5EDA9078220DF0BC0046D27A /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4E1314BB1DA3DC6ECCEB96AB /* libPods-GrpcIosTest.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B0C18CA1222DEF140002B502 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 2B8131AC634883AFEC02557C /* Pods */ = { + isa = PBXGroup; + children = ( + 7C9FAFB11727DCA50888C1B8 /* Pods-GrpcIosTest.debug.xcconfig */, + A4E7CA72304A7B43FE8A5BC7 /* Pods-GrpcIosTest.release.xcconfig */, + ); + name = Pods; + sourceTree = ""; + }; + 5EDA9072220DF0BC0046D27A = { + isa = PBXGroup; + children = ( + 5EDA9095220DF1B00046D27A /* AppDelegate.h */, + 5EDA9099220DF1B00046D27A /* AppDelegate.m */, + 5EDA9096220DF1B00046D27A /* main.m */, + 5EDA9098220DF1B00046D27A /* Main.storyboard */, + 5EDA9094220DF1B00046D27A /* ViewController.m */, + B0C18CA5222DEF140002B502 /* GrpcIosTestUITests */, + 5EDA907C220DF0BC0046D27A /* Products */, + 2B8131AC634883AFEC02557C /* Pods */, + E73D92116C1C328622A8C77F /* Frameworks */, + ); + sourceTree = ""; + }; + 5EDA907C220DF0BC0046D27A /* Products */ = { + isa = PBXGroup; + children = ( + 5EDA907B220DF0BC0046D27A /* GrpcIosTest.app */, + B0C18CA4222DEF140002B502 /* GrpcIosTestUITests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + B0C18CA5222DEF140002B502 /* GrpcIosTestUITests */ = { + isa = PBXGroup; + children = ( + B0C18CA6222DEF140002B502 /* GrpcIosTestUITests.m */, + B0C18CA8222DEF140002B502 /* Info.plist */, + ); + path = GrpcIosTestUITests; + sourceTree = ""; + }; + E73D92116C1C328622A8C77F /* Frameworks */ = { + isa = PBXGroup; + children = ( + 1D22EC48A487B02F76135EA3 /* libPods-GrpcIosTest.a */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 5EDA907A220DF0BC0046D27A /* GrpcIosTest */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5EDA9091220DF0BD0046D27A /* Build configuration list for PBXNativeTarget "GrpcIosTest" */; + buildPhases = ( + 33B0CC39F9DDEC2CEFB413C5 /* [CP] Check Pods Manifest.lock */, + 5EDA9077220DF0BC0046D27A /* Sources */, + 5EDA9078220DF0BC0046D27A /* Frameworks */, + 5EDA9079220DF0BC0046D27A /* Resources */, + 3EA5D3D73BDF48C306548037 /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = GrpcIosTest; + productName = GrpcIosTest; + productReference = 5EDA907B220DF0BC0046D27A /* GrpcIosTest.app */; + productType = "com.apple.product-type.application"; + }; + B0C18CA3222DEF140002B502 /* GrpcIosTestUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = B0C18CAD222DEF140002B502 /* Build configuration list for PBXNativeTarget "GrpcIosTestUITests" */; + buildPhases = ( + B0C18CA0222DEF140002B502 /* Sources */, + B0C18CA1222DEF140002B502 /* Frameworks */, + B0C18CA2222DEF140002B502 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + B0C18CAA222DEF140002B502 /* PBXTargetDependency */, + ); + name = GrpcIosTestUITests; + productName = GrpcIosTestUITests; + productReference = B0C18CA4222DEF140002B502 /* GrpcIosTestUITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 5EDA9073220DF0BC0046D27A /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 1000; + ORGANIZATIONNAME = gRPC; + TargetAttributes = { + 5EDA907A220DF0BC0046D27A = { + CreatedOnToolsVersion = 10.0; + }; + B0C18CA3222DEF140002B502 = { + CreatedOnToolsVersion = 10.0; + TestTargetID = 5EDA907A220DF0BC0046D27A; + }; + }; + }; + buildConfigurationList = 5EDA9076220DF0BC0046D27A /* Build configuration list for PBXProject "GrpcIosTest" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 5EDA9072220DF0BC0046D27A; + productRefGroup = 5EDA907C220DF0BC0046D27A /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 5EDA907A220DF0BC0046D27A /* GrpcIosTest */, + B0C18CA3222DEF140002B502 /* GrpcIosTestUITests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 5EDA9079220DF0BC0046D27A /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5EDA909E220DF1B00046D27A /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B0C18CA2222DEF140002B502 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 33B0CC39F9DDEC2CEFB413C5 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-GrpcIosTest-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + 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; + }; + 3EA5D3D73BDF48C306548037 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${SRCROOT}/Pods/Target Support Files/Pods-GrpcIosTest/Pods-GrpcIosTest-resources.sh", + "${PODS_CONFIGURATION_BUILD_DIR}/gRPC/gRPCCertificates.bundle", + ); + name = "[CP] Copy Pods Resources"; + outputFileListPaths = ( + ); + outputPaths = ( + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/gRPCCertificates.bundle", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-GrpcIosTest/Pods-GrpcIosTest-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 5EDA9077220DF0BC0046D27A /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5EDA909C220DF1B00046D27A /* main.m in Sources */, + 5EDA909B220DF1B00046D27A /* ViewController.m in Sources */, + 5EDA909F220DF1B00046D27A /* AppDelegate.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B0C18CA0222DEF140002B502 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B0C18CA7222DEF140002B502 /* GrpcIosTestUITests.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + B0C18CAA222DEF140002B502 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 5EDA907A220DF0BC0046D27A /* GrpcIosTest */; + targetProxy = B0C18CA9222DEF140002B502 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 5EDA908F220DF0BD0046D27A /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + }; + name = Debug; + }; + 5EDA9090220DF0BD0046D27A /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 5EDA9092220DF0BD0046D27A /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7C9FAFB11727DCA50888C1B8 /* Pods-GrpcIosTest.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Manual; + DEVELOPMENT_TEAM = EQHXZ8M8AV; + INFOPLIST_FILE = Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.GrpcIosTest; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = "Google Development"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 5EDA9093220DF0BD0046D27A /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = A4E7CA72304A7B43FE8A5BC7 /* Pods-GrpcIosTest.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Manual; + DEVELOPMENT_TEAM = EQHXZ8M8AV; + INFOPLIST_FILE = Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.GrpcIosTest; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = "Google Development"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + B0C18CAB222DEF140002B502 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Manual; + DEVELOPMENT_TEAM = EQHXZ8M8AV; + INFOPLIST_FILE = GrpcIosTestUITests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.google.GrpcIosTestUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE = ""; + PROVISIONING_PROFILE_SPECIFIER = "Google Development"; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = GrpcIosTest; + }; + name = Debug; + }; + B0C18CAC222DEF140002B502 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Manual; + DEVELOPMENT_TEAM = EQHXZ8M8AV; + INFOPLIST_FILE = GrpcIosTestUITests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.google.GrpcIosTestUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE = ""; + PROVISIONING_PROFILE_SPECIFIER = "Google Development"; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = GrpcIosTest; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 5EDA9076220DF0BC0046D27A /* Build configuration list for PBXProject "GrpcIosTest" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5EDA908F220DF0BD0046D27A /* Debug */, + 5EDA9090220DF0BD0046D27A /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 5EDA9091220DF0BD0046D27A /* Build configuration list for PBXNativeTarget "GrpcIosTest" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5EDA9092220DF0BD0046D27A /* Debug */, + 5EDA9093220DF0BD0046D27A /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + B0C18CAD222DEF140002B502 /* Build configuration list for PBXNativeTarget "GrpcIosTestUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B0C18CAB222DEF140002B502 /* Debug */, + B0C18CAC222DEF140002B502 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 5EDA9073220DF0BC0046D27A /* Project object */; +} diff --git a/src/objective-c/manual_tests/GrpcIosTest.xcodeproj/xcshareddata/xcschemes/GrpcIosTest.xcscheme b/src/objective-c/manual_tests/GrpcIosTest.xcodeproj/xcshareddata/xcschemes/GrpcIosTest.xcscheme new file mode 100644 index 00000000000..b9fb9d4d129 --- /dev/null +++ b/src/objective-c/manual_tests/GrpcIosTest.xcodeproj/xcshareddata/xcschemes/GrpcIosTest.xcscheme @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/objective-c/manual_tests/GrpcIosTestUITests/GrpcIosTestUITests.m b/src/objective-c/manual_tests/GrpcIosTestUITests/GrpcIosTestUITests.m new file mode 100644 index 00000000000..a75b6322148 --- /dev/null +++ b/src/objective-c/manual_tests/GrpcIosTestUITests/GrpcIosTestUITests.m @@ -0,0 +1,331 @@ +/* + * + * Copyright 2019 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. + * + */ + +#import + +NSTimeInterval const kWaitTime = 30; +int const kNumIterations = 1; + +@interface GrpcIosTestUITests : XCTestCase +@end + +@implementation GrpcIosTestUITests { + XCUIApplication *testApp; + XCUIApplication *settingsApp; +} + +- (void)setUp { + self.continueAfterFailure = NO; + [[[XCUIApplication alloc] init] launch]; + testApp = [[XCUIApplication alloc] initWithBundleIdentifier:@"io.grpc.GrpcIosTest"]; + [testApp activate]; + // Reset RPC counter + [self pressButton:@"Reset counter"]; + + settingsApp = [[XCUIApplication alloc] initWithBundleIdentifier:@"com.apple.Preferences"]; + [settingsApp activate]; + [NSThread sleepForTimeInterval:1]; + // Go back to the first page of Settings. + XCUIElement *backButton = settingsApp.navigationBars.buttons.firstMatch; + while (backButton.exists && backButton.isHittable) { + NSLog(@"Tapping back button"); + [backButton tap]; + } + XCTAssert([settingsApp.navigationBars[@"Settings"] waitForExistenceWithTimeout:kWaitTime]); + NSLog(@"Turning off airplane mode"); + // Turn off airplane mode + [self setAirplaneMode:NO]; + + // Turn on wifi + NSLog(@"Turning on wifi"); + [self setWifi:YES]; +} + +- (void)tearDown { +} + +- (void)doUnaryCall { + [testApp activate]; + [self pressButton:@"Unary call"]; +} + +- (void)do10UnaryCalls { + [testApp activate]; + [self pressButton:@"10 Unary calls"]; +} + +- (void)pressButton:(NSString *)name { + // Wait for button to be visible + while (![testApp.buttons[name] exists] || ![testApp.buttons[name] isHittable]) { + [NSThread sleepForTimeInterval:1]; + } + // Wait until all events in run loop have been processed + while (CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, true) == kCFRunLoopRunHandledSource) + ; + + NSLog(@"Pressing button: %@", name); + [testApp.buttons[name] tap]; +} + +- (void)expectCallSuccess { + XCTAssert([testApp.staticTexts[@"Call done"] waitForExistenceWithTimeout:kWaitTime]); +} + +- (void)expectCallFailed { + XCTAssert([testApp.staticTexts[@"Call failed"] waitForExistenceWithTimeout:kWaitTime]); +} + +- (void)expectCallSuccessOrFailed { + NSDate *startTime = [NSDate date]; + while (![testApp.staticTexts[@"Call done"] exists] && + ![testApp.staticTexts[@"Call failed"] exists]) { + XCTAssertLessThan([[NSDate date] timeIntervalSinceDate:startTime], kWaitTime); + [NSThread sleepForTimeInterval:1]; + } +} + +- (void)setAirplaneMode:(BOOL)to { + [settingsApp activate]; + XCUIElement *mySwitch = settingsApp.tables.element.cells.switches[@"Airplane Mode"]; + BOOL from = [(NSString *)mySwitch.value boolValue]; + NSLog(@"Setting airplane from: %d to: %d", from, to); + if (from != to) { + [mySwitch tap]; + // wait for network change to finish + [NSThread sleepForTimeInterval:5]; + } + XCTAssert([(NSString *)mySwitch.value boolValue] == to); +} +- (void)setWifi:(BOOL)to { + [settingsApp activate]; + [settingsApp.tables.element.cells.staticTexts[@"Wi-Fi"] tap]; + XCUIElement *wifiSwitch = settingsApp.tables.cells.switches[@"Wi-Fi"]; + BOOL from = [(NSString *)wifiSwitch.value boolValue]; + NSLog(@"Setting wifi from: %d to: %d", from, to); + if (from != to) { + [wifiSwitch tap]; + // wait for wifi networks to be detected + [NSThread sleepForTimeInterval:10]; + } + // Go back to the first page of Settings. + XCUIElement *backButton = settingsApp.navigationBars.buttons.firstMatch; + [backButton tap]; +} + +- (int)getRandomNumberBetween:(int)min max:(int)max { + return min + arc4random_uniform((max - min + 1)); +} + +- (void)testBackgroundBeforeCall { + NSLog(@"%s", __func__); + // Open test app + [testApp activate]; + // Send test app to background + [XCUIDevice.sharedDevice pressButton:XCUIDeviceButtonHome]; + + // Wait a bit + int sleepTime = [self getRandomNumberBetween:5 max:10]; + NSLog(@"Sleeping for %d seconds", sleepTime); + [NSThread sleepForTimeInterval:sleepTime]; + + // Bring test app to foreground and make a unary call. Call should succeed + [self doUnaryCall]; + [self expectCallSuccess]; +} + +- (void)testBackgroundDuringStreamingCall { + NSLog(@"%s", __func__); + // Open test app and start a streaming call + [testApp activate]; + [self pressButton:@"Start streaming call"]; + + // Send test app to background + [XCUIDevice.sharedDevice pressButton:XCUIDeviceButtonHome]; + + // Wait a bit + int sleepTime = [self getRandomNumberBetween:5 max:10]; + NSLog(@"Sleeping for %d seconds", sleepTime); + [NSThread sleepForTimeInterval:sleepTime]; + + // Bring test app to foreground and make a streaming call. Call should succeed. + [testApp activate]; + [self pressButton:@"Send Message"]; + [self pressButton:@"Stop streaming call"]; + [self expectCallSuccess]; +} + +- (void)testCallAfterNetworkFlap { + NSLog(@"%s", __func__); + // Open test app and make a unary call. Channel to server should be open after this. + [self doUnaryCall]; + [self expectCallSuccess]; + + // Toggle airplane mode on and off + [self setAirplaneMode:YES]; + [self setAirplaneMode:NO]; + + // Bring test app to foreground and make a unary call. The call should succeed + [self doUnaryCall]; + [self expectCallSuccess]; +} + +- (void)testCallWhileNetworkDown { + NSLog(@"%s", __func__); + // Open test app and make a unary call. Channel to server should be open after this. + [self doUnaryCall]; + [self expectCallSuccess]; + + // Turn on airplane mode + [self setAirplaneMode:YES]; + // Turn off wifi + [self setWifi:NO]; + + // Unary call should fail + [self doUnaryCall]; + [self expectCallFailed]; + + // Turn off airplane mode + [self setAirplaneMode:NO]; + // Turn on wifi + [self setWifi:YES]; + + // Unary call should succeed + [self doUnaryCall]; + [self expectCallSuccess]; +} + +- (void)testSwitchApp { + NSLog(@"%s", __func__); + // Open test app and make a unary call. Channel to server should be open after this. + [self doUnaryCall]; + [self expectCallSuccess]; + + // Send test app to background + [XCUIDevice.sharedDevice pressButton:XCUIDeviceButtonHome]; + + // Open stocks app + XCUIApplication *stocksApp = + [[XCUIApplication alloc] initWithBundleIdentifier:@"com.apple.stocks"]; + [stocksApp activate]; + // Ensure that stocks app is running in the foreground + XCTAssert([stocksApp waitForState:XCUIApplicationStateRunningForeground timeout:5]); + // Wait a bit + int sleepTime = [self getRandomNumberBetween:5 max:10]; + NSLog(@"Sleeping for %d seconds", sleepTime); + [NSThread sleepForTimeInterval:sleepTime]; + [stocksApp terminate]; + + // Make another unary call + [self doUnaryCall]; + [self expectCallSuccess]; +} + +- (void)testNetworkFlapDuringStreamingCall { + NSLog(@"%s", __func__); + // Open test app and make a unary call. Channel to server should be open after this. + [self doUnaryCall]; + [self expectCallSuccess]; + // Start streaming call and send a message + [self pressButton:@"Start streaming call"]; + [self pressButton:@"Send Message"]; + + // Toggle network on and off + [self setAirplaneMode:YES]; + [self setWifi:NO]; + [self setAirplaneMode:NO]; + [self setWifi:YES]; + + [testApp activate]; + [self pressButton:@"Stop streaming call"]; + // The call will fail if the stream gets a read error, else the call will succeed. + [self expectCallSuccessOrFailed]; + + // Make another unary call, it should succeed + [self doUnaryCall]; + [self expectCallSuccess]; +} + +- (void)testConcurrentCalls { + NSLog(@"%s", __func__); + + // Press button to start 10 unary calls + [self do10UnaryCalls]; + + // Toggle airplane mode on and off + [self setAirplaneMode:YES]; + [self setAirplaneMode:NO]; + + // 10 calls should have completed + [testApp activate]; + XCTAssert([testApp.staticTexts[@"Calls completed: 10"] waitForExistenceWithTimeout:kWaitTime]); +} + +- (void)invokeTest { + for (int i = 0; i < kNumIterations; i++) { + [super invokeTest]; + } +} + +- (void)testUnaryCallTurnOffWifi { + NSLog(@"%s", __func__); + // Open test app and make a unary call. Channel to server should be open after this. + [self doUnaryCall]; + [self expectCallSuccess]; + + // Turn off wifi + [self setWifi:NO]; + + // Phone should switch to cellular connection, call should succeed + [self doUnaryCall]; + [self expectCallSuccess]; + + // Turn on wifi + [self setWifi:YES]; + + // Call should succeed after turning wifi back on + [self doUnaryCall]; + [self expectCallSuccess]; +} + +- (void)testStreamingCallTurnOffWifi { + NSLog(@"%s", __func__); + // Open test app and make a unary call. Channel to server should be open after this. + [self doUnaryCall]; + [self expectCallSuccess]; + + // Start streaming call and send a message + [self pressButton:@"Start streaming call"]; + [self pressButton:@"Send Message"]; + + // Turn off wifi + [self setWifi:NO]; + + // Phone should switch to cellular connection, this results in the call failing + [testApp activate]; + [self pressButton:@"Stop streaming call"]; + [self expectCallFailed]; + + // Turn on wifi + [self setWifi:YES]; + + // Call should succeed after turning wifi back on + [self doUnaryCall]; + [self expectCallSuccess]; +} + +@end diff --git a/src/objective-c/manual_tests/GrpcIosTestUITests/Info.plist b/src/objective-c/manual_tests/GrpcIosTestUITests/Info.plist new file mode 100644 index 00000000000..6c40a6cd0c4 --- /dev/null +++ b/src/objective-c/manual_tests/GrpcIosTestUITests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/src/objective-c/manual_tests/Info.plist b/src/objective-c/manual_tests/Info.plist new file mode 100644 index 00000000000..8824c40c504 --- /dev/null +++ b/src/objective-c/manual_tests/Info.plist @@ -0,0 +1,43 @@ + + + + + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/src/objective-c/manual_tests/Main.storyboard b/src/objective-c/manual_tests/Main.storyboard new file mode 100644 index 00000000000..409084126d0 --- /dev/null +++ b/src/objective-c/manual_tests/Main.storyboard @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/objective-c/manual_tests/Podfile b/src/objective-c/manual_tests/Podfile new file mode 100644 index 00000000000..919e649be71 --- /dev/null +++ b/src/objective-c/manual_tests/Podfile @@ -0,0 +1,100 @@ +source 'https://github.com/CocoaPods/Specs.git' +platform :ios, '8.0' + +install! 'cocoapods', :deterministic_uuids => false + +# Location of gRPC's repo root relative to this file. +GRPC_LOCAL_SRC = '../../..' + +# Install the dependencies in the main target plus all test targets. +%w( +GrpcIosTest +).each do |target_name| + target target_name do + pod 'Protobuf', :path => "#{GRPC_LOCAL_SRC}/third_party/protobuf", :inhibit_warnings => true + + pod '!ProtoCompiler', :path => "#{GRPC_LOCAL_SRC}/src/objective-c" + pod '!ProtoCompiler-gRPCPlugin', :path => "#{GRPC_LOCAL_SRC}/src/objective-c" + + pod 'BoringSSL-GRPC', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c", :inhibit_warnings => true + + pod 'gRPC/CFStream', :path => GRPC_LOCAL_SRC + pod 'gRPC-Core/CFStream-Implementation', :path => GRPC_LOCAL_SRC + pod 'gRPC-RxLibrary', :path => GRPC_LOCAL_SRC + pod 'gRPC-ProtoRPC', :path => GRPC_LOCAL_SRC, :inhibit_warnings => true + pod 'RemoteTest', :path => "../tests/RemoteTestClient", :inhibit_warnings => true + end +end + +# gRPC-Core.podspec needs to be modified to be successfully used for local development. A Podfile's +# pre_install hook lets us do that. The block passed to it runs after the podspecs are downloaded +# and before they are installed in the user project. +# +# This podspec searches for the gRPC core library headers under "$(PODS_ROOT)/gRPC-Core", where +# Cocoapods normally places the downloaded sources. When doing local development of the libraries, +# though, Cocoapods just takes the sources from whatever directory was specified using `:path`, and +# doesn't copy them under $(PODS_ROOT). When using static libraries, one can sometimes rely on the +# symbolic links to the pods headers that Cocoapods creates under "$(PODS_ROOT)/Headers". But those +# aren't created when using dynamic frameworks. So our solution is to modify the podspec on the fly +# to point at the local directory where the sources are. +# +# TODO(jcanizales): Send a PR to Cocoapods to get rid of this need. +pre_install do |installer| + # This is the gRPC-Core podspec object, as initialized by its podspec file. + grpc_core_spec = installer.pod_targets.find{|t| t.name.start_with?('gRPC-Core')}.root_spec + + # Copied from gRPC-Core.podspec, except for the adjusted src_root: + src_root = "$(PODS_ROOT)/../#{GRPC_LOCAL_SRC}" + grpc_core_spec.pod_target_xcconfig = { + 'GRPC_SRC_ROOT' => src_root, + 'HEADER_SEARCH_PATHS' => '"$(inherited)" "$(GRPC_SRC_ROOT)/include"', + 'USER_HEADER_SEARCH_PATHS' => '"$(GRPC_SRC_ROOT)"', + # If we don't set these two settings, `include/grpc/support/time.h` and + # `src/core/lib/gpr/string.h` shadow the system `` and ``, breaking the + # build. + 'USE_HEADERMAP' => 'NO', + 'ALWAYS_SEARCH_USER_PATHS' => 'NO', + } +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + target.build_configurations.each do |config| + config.build_settings['GCC_TREAT_WARNINGS_AS_ERRORS'] = 'YES' + end + + # CocoaPods creates duplicated library targets of gRPC-Core when the test targets include + # non-default subspecs of gRPC-Core. All of these library targets start with prefix 'gRPC-Core' + # and require the same error suppresion. + if target.name.start_with?('gRPC-Core') + target.build_configurations.each do |config| + # TODO(zyc): Remove this setting after the issue is resolved + # GPR_UNREACHABLE_CODE causes "Control may reach end of non-void + # function" warning + config.build_settings['GCC_WARN_ABOUT_RETURN_TYPE'] = 'NO' + config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] = '$(inherited) COCOAPODS=1 GRPC_CRONET_WITH_PACKET_COALESCING=1' + end + end + + # Activate Cronet for the dedicated build configuration 'Cronet', which will be used solely by + # the test target 'InteropTestsRemoteWithCronet' + # Activate GRPCCall+InternalTests functions for the dedicated build configuration 'Test', which will + # be used by all test targets using it. + if target.name == 'gRPC' || target.name.start_with?('gRPC.') + target.build_configurations.each do |config| + config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] = '$(inherited) COCOAPODS=1 GRPC_TEST_OBJC=1' + end + end + + # Enable NSAssert on gRPC + if target.name == 'gRPC' || target.name.start_with?('gRPC.') || + target.name == 'ProtoRPC' || target.name.start_with?('ProtoRPC.') || + target.name == 'RxLibrary' || target.name.start_with?('RxLibrary.') + target.build_configurations.each do |config| + if config.name != 'Release' + config.build_settings['ENABLE_NS_ASSERTIONS'] = 'YES' + end + end + end + end +end diff --git a/src/objective-c/manual_tests/ViewController.m b/src/objective-c/manual_tests/ViewController.m new file mode 100644 index 00000000000..50a729e4d6a --- /dev/null +++ b/src/objective-c/manual_tests/ViewController.m @@ -0,0 +1,172 @@ +/* + * + * Copyright 2019 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. + * + */ + +#import + +#import +#import +#import +#import + +NSString *const kRemoteHost = @"grpc-test.sandbox.googleapis.com"; +const int32_t kMessageSize = 100; + +@interface ViewController : UIViewController +@property(strong, nonatomic) UILabel *callStatusLabel; +@property(strong, nonatomic) UILabel *callCountLabel; +@end + +@implementation ViewController { + RMTTestService *_service; + dispatch_queue_t _dispatchQueue; + GRPCStreamingProtoCall *_call; + int _calls_completed; +} +- (instancetype)init { + self = [super init]; + _calls_completed = 0; + return self; +} + +- (void)viewDidLoad { + [super viewDidLoad]; + _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); + _callStatusLabel = (UILabel *)[self.view viewWithTag:1]; + _callCountLabel = (UILabel *)[self.view viewWithTag:2]; +} + +- (void)startUnaryCall { + if (_service == nil) { + _service = [RMTTestService serviceWithHost:kRemoteHost]; + } + dispatch_async(dispatch_get_main_queue(), ^{ + self->_callStatusLabel.text = @""; + }); + + // Set up request proto message + RMTSimpleRequest *request = [RMTSimpleRequest message]; + request.responseType = RMTPayloadType_Compressable; + request.responseSize = kMessageSize; + request.payload.body = [NSMutableData dataWithLength:kMessageSize]; + + GRPCUnaryProtoCall *call = + [_service unaryCallWithMessage:request responseHandler:self callOptions:nil]; + + [call start]; +} + +- (IBAction)tapUnaryCall:(id)sender { + NSLog(@"In tapUnaryCall"); + [self startUnaryCall]; +} + +- (IBAction)tap10UnaryCalls:(id)sender { + NSLog(@"In tap10UnaryCalls"); + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) { + // Background thread + for (int i = 0; i < 10; ++i) { + [self startUnaryCall]; + [NSThread sleepForTimeInterval:0.5]; + } + }); +} + +- (IBAction)resetCounter:(id)sender { + _calls_completed = 0; + dispatch_async(dispatch_get_main_queue(), ^{ + self->_callCountLabel.text = + [NSString stringWithFormat:@"Calls completed: %d", self->_calls_completed]; + self->_callStatusLabel.text = @""; + }); +} + +- (IBAction)tapStreamingCallStart:(id)sender { + NSLog(@"In tapStreamingCallStart"); + if (_service == nil) { + _service = [RMTTestService serviceWithHost:kRemoteHost]; + } + dispatch_async(dispatch_get_main_queue(), ^{ + self->_callStatusLabel.text = @""; + }); + + // Set up request proto message + RMTStreamingOutputCallRequest *request = RMTStreamingOutputCallRequest.message; + RMTResponseParameters *parameters = [RMTResponseParameters message]; + parameters.size = kMessageSize; + [request.responseParametersArray addObject:parameters]; + request.payload.body = [NSMutableData dataWithLength:kMessageSize]; + + GRPCStreamingProtoCall *call = [_service fullDuplexCallWithResponseHandler:self callOptions:nil]; + [call start]; + _call = call; + // display something to confirm the tester the call is started +} + +- (IBAction)tapStreamingCallSend:(id)sender { + NSLog(@"In tapStreamingCallSend"); + if (_call == nil) return; + + RMTStreamingOutputCallRequest *request = RMTStreamingOutputCallRequest.message; + RMTResponseParameters *parameters = [RMTResponseParameters message]; + parameters.size = kMessageSize; + [request.responseParametersArray addObject:parameters]; + request.payload.body = [NSMutableData dataWithLength:kMessageSize]; + + [_call writeMessage:request]; +} + +- (IBAction)tapStreamingCallStop:(id)sender { + NSLog(@"In tapStreamingCallStop"); + if (_call == nil) return; + + [_call finish]; + _call = nil; +} + +- (void)didReceiveInitialMetadata:(NSDictionary *)initialMetadata { + NSLog(@"Recv initial metadata: %@", initialMetadata); +} + +- (void)didReceiveProtoMessage:(GPBMessage *)message { + NSLog(@"Recv message: %@", message); +} + +- (void)didCloseWithTrailingMetadata:(NSDictionary *)trailingMetadata + error:(nullable NSError *)error { + NSLog(@"Recv trailing metadata: %@, error: %@", trailingMetadata, error); + if (error == nil) { + dispatch_async(dispatch_get_main_queue(), ^{ + self->_callStatusLabel.text = @"Call done"; + }); + } else { + dispatch_async(dispatch_get_main_queue(), ^{ + self->_callStatusLabel.text = @"Call failed"; + }); + } + ++_calls_completed; + dispatch_async(dispatch_get_main_queue(), ^{ + self->_callCountLabel.text = + [NSString stringWithFormat:@"Calls completed: %d", self->_calls_completed]; + }); +} + +- (dispatch_queue_t)dispatchQueue { + return _dispatchQueue; +} + +@end diff --git a/src/objective-c/manual_tests/main.m b/src/objective-c/manual_tests/main.m new file mode 100644 index 00000000000..451b50cc0e2 --- /dev/null +++ b/src/objective-c/manual_tests/main.m @@ -0,0 +1,28 @@ +/* + * + * Copyright 2019 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. + * + */ + +#import +#import "AppDelegate.h" + +int main(int argc, char* argv[]) { + @autoreleasepool { + // enable CFStream API + setenv("grpc_cfstream", "1", 1); + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/src/objective-c/tests/APIv2Tests/APIv2Tests.m b/src/objective-c/tests/APIv2Tests/APIv2Tests.m new file mode 100644 index 00000000000..db293750ca3 --- /dev/null +++ b/src/objective-c/tests/APIv2Tests/APIv2Tests.m @@ -0,0 +1,773 @@ +/* + * + * 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. + * + */ + +#import +#import +#import +#import + +#include +#include + +#import "../version.h" + +// The server address is derived from preprocessor macro, which is +// in turn derived from environment variable of the same name. +#define NSStringize_helper(x) #x +#define NSStringize(x) @NSStringize_helper(x) +static NSString *const kHostAddress = NSStringize(HOST_PORT_LOCAL); +static NSString *const kRemoteSSLHost = NSStringize(HOST_PORT_REMOTE); + +// Package and service name of test server +static NSString *const kPackage = @"grpc.testing"; +static NSString *const kService = @"TestService"; + +static GRPCProtoMethod *kInexistentMethod; +static GRPCProtoMethod *kEmptyCallMethod; +static GRPCProtoMethod *kUnaryCallMethod; +static GRPCProtoMethod *kOutputStreamingCallMethod; +static GRPCProtoMethod *kFullDuplexCallMethod; + +static const int kSimpleDataLength = 100; + +static const NSTimeInterval kTestTimeout = 8; +static const NSTimeInterval kInvertedTimeout = 2; + +// Reveal the _class ivar for testing access +@interface GRPCCall2 () { + @public + GRPCCall *_call; +} + +@end + +// Convenience class to use blocks as callbacks +@interface ClientTestsBlockCallbacks : NSObject + +- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback + messageCallback:(void (^)(id))messageCallback + closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback + writeDataCallback:(void (^)(void))writeDataCallback; + +- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback + messageCallback:(void (^)(id))messageCallback + closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback; + +@end + +@implementation ClientTestsBlockCallbacks { + void (^_initialMetadataCallback)(NSDictionary *); + void (^_messageCallback)(id); + void (^_closeCallback)(NSDictionary *, NSError *); + void (^_writeDataCallback)(void); + dispatch_queue_t _dispatchQueue; +} + +- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback + messageCallback:(void (^)(id))messageCallback + closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback + writeDataCallback:(void (^)(void))writeDataCallback { + if ((self = [super init])) { + _initialMetadataCallback = initialMetadataCallback; + _messageCallback = messageCallback; + _closeCallback = closeCallback; + _writeDataCallback = writeDataCallback; + _dispatchQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL); + } + return self; +} + +- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback + messageCallback:(void (^)(id))messageCallback + closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback { + return [self initWithInitialMetadataCallback:initialMetadataCallback + messageCallback:messageCallback + closeCallback:closeCallback + writeDataCallback:nil]; +} + +- (void)didReceiveInitialMetadata:(NSDictionary *)initialMetadata { + if (self->_initialMetadataCallback) { + self->_initialMetadataCallback(initialMetadata); + } +} + +- (void)didReceiveRawMessage:(GPBMessage *)message { + if (self->_messageCallback) { + self->_messageCallback(message); + } +} + +- (void)didCloseWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { + if (self->_closeCallback) { + self->_closeCallback(trailingMetadata, error); + } +} + +- (void)didWriteData { + if (self->_writeDataCallback) { + self->_writeDataCallback(); + } +} + +- (dispatch_queue_t)dispatchQueue { + return _dispatchQueue; +} + +@end + +@interface CallAPIv2Tests : XCTestCase + +@end + +@implementation CallAPIv2Tests + +- (void)setUp { + // 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"]; + kOutputStreamingCallMethod = [[GRPCProtoMethod alloc] initWithPackage:kPackage + service:kService + method:@"StreamingOutputCall"]; + kFullDuplexCallMethod = + [[GRPCProtoMethod alloc] initWithPackage:kPackage service:kService method:@"FullDuplexCall"]; +} + +- (void)testMetadata { + __weak XCTestExpectation *expectation = [self expectationWithDescription:@"RPC unauthorized."]; + + RMTSimpleRequest *request = [RMTSimpleRequest message]; + request.fillUsername = YES; + request.fillOauthScope = YES; + + GRPCRequestOptions *callRequest = + [[GRPCRequestOptions alloc] initWithHost:(NSString *)kRemoteSSLHost + path:kUnaryCallMethod.HTTPPath + safety:GRPCCallSafetyDefault]; + __block NSDictionary *init_md; + __block NSDictionary *trailing_md; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.oauth2AccessToken = @"bogusToken"; + GRPCCall2 *call = [[GRPCCall2 alloc] + initWithRequestOptions:callRequest + responseHandler:[[ClientTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:^(NSDictionary *initialMetadata) { + init_md = initialMetadata; + } + messageCallback:^(id message) { + XCTFail(@"Received unexpected response."); + } + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + trailing_md = trailingMetadata; + if (error) { + XCTAssertEqual(error.code, 16, + @"Finished with unexpected error: %@", error); + XCTAssertEqualObjects(init_md, + error.userInfo[kGRPCHeadersKey]); + XCTAssertEqualObjects(trailing_md, + error.userInfo[kGRPCTrailersKey]); + NSString *challengeHeader = init_md[@"www-authenticate"]; + XCTAssertGreaterThan(challengeHeader.length, 0, + @"No challenge in response headers %@", + init_md); + [expectation fulfill]; + } + }] + callOptions:options]; + + [call start]; + [call writeData:[request data]]; + [call finish]; + + [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; +} + +- (void)testUserAgentPrefix { + __weak XCTestExpectation *completion = [self expectationWithDescription:@"Empty RPC completed."]; + __weak XCTestExpectation *recvInitialMd = + [self expectationWithDescription:@"Did not receive initial md."]; + + GRPCRequestOptions *request = [[GRPCRequestOptions alloc] initWithHost:kHostAddress + path:kEmptyCallMethod.HTTPPath + safety:GRPCCallSafetyDefault]; + NSDictionary *headers = + [NSDictionary dictionaryWithObjectsAndKeys:@"", @"x-grpc-test-echo-useragent", nil]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = GRPCTransportTypeInsecure; + options.userAgentPrefix = @"Foo"; + options.initialMetadata = headers; + GRPCCall2 *call = [[GRPCCall2 alloc] + initWithRequestOptions:request + responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:^( + NSDictionary *initialMetadata) { + NSString *userAgent = initialMetadata[@"x-grpc-test-echo-useragent"]; + // 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:@" ("]; + expectedUserAgent = [expectedUserAgent stringByAppendingString:@GPR_PLATFORM_STRING]; + expectedUserAgent = [expectedUserAgent stringByAppendingString:@"; chttp2; "]; + expectedUserAgent = [expectedUserAgent + stringByAppendingString:[NSString stringWithUTF8String:grpc_g_stands_for()]]; + expectedUserAgent = [expectedUserAgent stringByAppendingString:@")"]; + XCTAssertEqualObjects(userAgent, expectedUserAgent); + + NSError *error = nil; + // 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"); + [recvInitialMd fulfill]; + } + messageCallback:^(id message) { + XCTAssertNotNil(message); + XCTAssertEqual([message length], 0, + @"Non-empty response received: %@", message); + } + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + if (error) { + XCTFail(@"Finished with unexpected error: %@", error); + } else { + [completion fulfill]; + } + }] + callOptions:options]; + [call writeData:[NSData data]]; + [call start]; + + [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; +} + +- (void)getTokenWithHandler:(void (^)(NSString *token))handler { + dispatch_queue_t queue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); + dispatch_sync(queue, ^{ + handler(@"test-access-token"); + }); +} + +- (void)testOAuthToken { + __weak XCTestExpectation *completion = [self expectationWithDescription:@"RPC completed."]; + + GRPCRequestOptions *requestOptions = + [[GRPCRequestOptions alloc] initWithHost:kHostAddress + path:kEmptyCallMethod.HTTPPath + safety:GRPCCallSafetyDefault]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = GRPCTransportTypeInsecure; + options.authTokenProvider = self; + __block GRPCCall2 *call = [[GRPCCall2 alloc] + initWithRequestOptions:requestOptions + responseHandler:[[ClientTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:nil + messageCallback:nil + closeCallback:^(NSDictionary *trailingMetadata, + NSError *error) { + [completion fulfill]; + }] + callOptions:options]; + [call writeData:[NSData data]]; + [call start]; + [call finish]; + + [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; +} + +- (void)testResponseSizeLimitExceeded { + __weak XCTestExpectation *completion = [self expectationWithDescription:@"RPC completed."]; + + GRPCRequestOptions *requestOptions = + [[GRPCRequestOptions alloc] initWithHost:kHostAddress + path:kUnaryCallMethod.HTTPPath + safety:GRPCCallSafetyDefault]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.responseSizeLimit = kSimpleDataLength; + options.transportType = GRPCTransportTypeInsecure; + + RMTSimpleRequest *request = [RMTSimpleRequest message]; + request.payload.body = [NSMutableData dataWithLength:options.responseSizeLimit]; + request.responseSize = (int32_t)(options.responseSizeLimit * 2); + + GRPCCall2 *call = [[GRPCCall2 alloc] + initWithRequestOptions:requestOptions + responseHandler:[[ClientTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:nil + messageCallback:nil + closeCallback:^(NSDictionary *trailingMetadata, + NSError *error) { + XCTAssertNotNil(error, + @"Expecting non-nil error"); + XCTAssertEqual(error.code, + GRPCErrorCodeResourceExhausted); + [completion fulfill]; + }] + callOptions:options]; + [call writeData:[request data]]; + [call start]; + [call finish]; + + [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; +} + +- (void)testIdempotentProtoRPC { + __weak XCTestExpectation *response = [self expectationWithDescription:@"Expected response."]; + __weak XCTestExpectation *completion = [self expectationWithDescription:@"RPC completed."]; + + RMTSimpleRequest *request = [RMTSimpleRequest message]; + request.responseSize = kSimpleDataLength; + request.fillUsername = YES; + request.fillOauthScope = YES; + GRPCRequestOptions *requestOptions = + [[GRPCRequestOptions alloc] initWithHost:kHostAddress + path:kUnaryCallMethod.HTTPPath + safety:GRPCCallSafetyIdempotentRequest]; + + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = GRPCTransportTypeInsecure; + GRPCCall2 *call = [[GRPCCall2 alloc] + initWithRequestOptions:requestOptions + responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:^(id message) { + NSData *data = (NSData *)message; + XCTAssertNotNil(data, @"nil value received as response."); + XCTAssertGreaterThan(data.length, 0, + @"Empty response received."); + RMTSimpleResponse *responseProto = + [RMTSimpleResponse parseFromData:data 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]; + } + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + XCTAssertNil(error, @"Finished with unexpected error: %@", + error); + [completion fulfill]; + }] + callOptions:options]; + + [call start]; + [call writeData:[request data]]; + [call finish]; + + [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; +} + +- (void)testTimeout { + __weak XCTestExpectation *completion = [self expectationWithDescription:@"RPC completed."]; + + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.timeout = 0.001; + GRPCRequestOptions *requestOptions = + [[GRPCRequestOptions alloc] initWithHost:kHostAddress + path:kFullDuplexCallMethod.HTTPPath + safety:GRPCCallSafetyDefault]; + + GRPCCall2 *call = [[GRPCCall2 alloc] + initWithRequestOptions:requestOptions + responseHandler: + [[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:^(NSData *data) { + XCTFail(@"Failure: response received; Expect: no response received."); + } + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + XCTAssertNotNil(error, + @"Failure: no error received; Expect: receive " + @"deadline exceeded."); + XCTAssertEqual(error.code, GRPCErrorCodeDeadlineExceeded); + [completion fulfill]; + }] + callOptions:options]; + + [call start]; + + [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; +} + +- (void)testTimeoutBackoffWithTimeout:(double)timeout Backoff:(double)backoff { + const double maxConnectTime = timeout > backoff ? timeout : backoff; + const double kMargin = 0.1; + + __weak XCTestExpectation *completion = [self expectationWithDescription:@"Timeout in a second."]; + NSString *const kDummyAddress = [NSString stringWithFormat:@"127.0.0.1:10000"]; + GRPCRequestOptions *requestOptions = + [[GRPCRequestOptions alloc] initWithHost:kDummyAddress + path:@"/dummy/path" + safety:GRPCCallSafetyDefault]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.connectMinTimeout = timeout; + options.connectInitialBackoff = backoff; + options.connectMaxBackoff = 0; + + NSDate *startTime = [NSDate date]; + GRPCCall2 *call = [[GRPCCall2 alloc] + initWithRequestOptions:requestOptions + responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:^(NSData *data) { + XCTFail(@"Received message. Should not reach here."); + } + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + XCTAssertNotNil(error, + @"Finished with no error; expecting error"); + XCTAssertLessThan( + [[NSDate date] timeIntervalSinceDate:startTime], + maxConnectTime + kMargin); + [completion fulfill]; + }] + callOptions:options]; + + [call start]; + + [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; +} + +- (void)testTimeoutBackoff1 { + [self testTimeoutBackoffWithTimeout:0.7 Backoff:0.4]; +} + +- (void)testTimeoutBackoff2 { + [self testTimeoutBackoffWithTimeout:0.3 Backoff:0.8]; +} + +- (void)testCompression { + __weak XCTestExpectation *completion = [self expectationWithDescription:@"RPC completed."]; + + RMTSimpleRequest *request = [RMTSimpleRequest message]; + request.expectCompressed = [RMTBoolValue message]; + request.expectCompressed.value = YES; + request.responseCompressed = [RMTBoolValue message]; + request.expectCompressed.value = YES; + request.responseSize = kSimpleDataLength; + request.payload.body = [NSMutableData dataWithLength:kSimpleDataLength]; + GRPCRequestOptions *requestOptions = + [[GRPCRequestOptions alloc] initWithHost:kHostAddress + path:kUnaryCallMethod.HTTPPath + safety:GRPCCallSafetyDefault]; + + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = GRPCTransportTypeInsecure; + options.compressionAlgorithm = GRPCCompressGzip; + GRPCCall2 *call = [[GRPCCall2 alloc] + initWithRequestOptions:requestOptions + responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:^(NSData *data) { + NSError *error; + RMTSimpleResponse *response = + [RMTSimpleResponse parseFromData:data error:&error]; + XCTAssertNil(error, @"Error when parsing response: %@", error); + XCTAssertEqual(response.payload.body.length, kSimpleDataLength); + } + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + XCTAssertNil(error, @"Received failure: %@", error); + [completion fulfill]; + }] + + callOptions:options]; + + [call start]; + [call writeData:[request data]]; + [call finish]; + + [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; +} + +- (void)testFlowControlWrite { + __weak XCTestExpectation *expectWriteData = + [self expectationWithDescription:@"Reported write data"]; + + RMTStreamingOutputCallRequest *request = [RMTStreamingOutputCallRequest message]; + RMTResponseParameters *parameters = [RMTResponseParameters message]; + parameters.size = kSimpleDataLength; + [request.responseParametersArray addObject:parameters]; + request.payload.body = [NSMutableData dataWithLength:kSimpleDataLength]; + + GRPCRequestOptions *callRequest = + [[GRPCRequestOptions alloc] initWithHost:(NSString *)kHostAddress + path:kUnaryCallMethod.HTTPPath + safety:GRPCCallSafetyDefault]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = GRPCTransportTypeInsecure; + options.flowControlEnabled = YES; + GRPCCall2 *call = + [[GRPCCall2 alloc] initWithRequestOptions:callRequest + responseHandler:[[ClientTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:nil + messageCallback:nil + closeCallback:nil + writeDataCallback:^{ + [expectWriteData fulfill]; + }] + callOptions:options]; + + [call start]; + [call receiveNextMessages:1]; + [call writeData:[request data]]; + + // Wait for 3 seconds and make sure we do not receive the response + [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; + + [call finish]; +} + +- (void)testFlowControlRead { + __weak __block XCTestExpectation *expectBlockedMessage = + [self expectationWithDescription:@"Message not delivered without recvNextMessage"]; + __weak __block XCTestExpectation *expectPassedMessage = nil; + __weak __block XCTestExpectation *expectBlockedClose = + [self expectationWithDescription:@"Call not closed with pending message"]; + __weak __block XCTestExpectation *expectPassedClose = nil; + expectBlockedMessage.inverted = YES; + expectBlockedClose.inverted = YES; + + RMTSimpleRequest *request = [RMTSimpleRequest message]; + request.responseSize = kSimpleDataLength; + request.payload.body = [NSMutableData dataWithLength:kSimpleDataLength]; + + GRPCRequestOptions *callRequest = + [[GRPCRequestOptions alloc] initWithHost:(NSString *)kHostAddress + path:kUnaryCallMethod.HTTPPath + safety:GRPCCallSafetyDefault]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = GRPCTransportTypeInsecure; + options.flowControlEnabled = YES; + __block int unblocked = NO; + GRPCCall2 *call = [[GRPCCall2 alloc] + initWithRequestOptions:callRequest + responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:^(NSData *message) { + if (!unblocked) { + [expectBlockedMessage fulfill]; + } else { + [expectPassedMessage fulfill]; + } + } + closeCallback:^(NSDictionary *trailers, NSError *error) { + if (!unblocked) { + [expectBlockedClose fulfill]; + } else { + [expectPassedClose fulfill]; + } + }] + callOptions:options]; + + [call start]; + [call writeData:[request data]]; + [call finish]; + + // Wait to make sure we do not receive the response + [self waitForExpectationsWithTimeout:kInvertedTimeout handler:nil]; + + expectPassedMessage = + [self expectationWithDescription:@"Message delivered with receiveNextMessage"]; + expectPassedClose = [self expectationWithDescription:@"Close delivered after receiveNextMessage"]; + + unblocked = YES; + [call receiveNextMessages:1]; + + [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; +} + +- (void)testFlowControlMultipleMessages { + __weak XCTestExpectation *expectPassedMessage = + [self expectationWithDescription:@"two messages delivered with receiveNextMessage"]; + expectPassedMessage.expectedFulfillmentCount = 2; + __weak XCTestExpectation *expectBlockedMessage = + [self expectationWithDescription:@"Message 3 not delivered"]; + expectBlockedMessage.inverted = YES; + __weak XCTestExpectation *expectWriteTwice = + [self expectationWithDescription:@"Write 2 messages done"]; + expectWriteTwice.expectedFulfillmentCount = 2; + + RMTStreamingOutputCallRequest *request = [RMTStreamingOutputCallRequest message]; + RMTResponseParameters *parameters = [RMTResponseParameters message]; + parameters.size = kSimpleDataLength; + [request.responseParametersArray addObject:parameters]; + request.payload.body = [NSMutableData dataWithLength:kSimpleDataLength]; + + GRPCRequestOptions *callRequest = + [[GRPCRequestOptions alloc] initWithHost:(NSString *)kHostAddress + path:kFullDuplexCallMethod.HTTPPath + safety:GRPCCallSafetyDefault]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = GRPCTransportTypeInsecure; + options.flowControlEnabled = YES; + __block NSUInteger messageId = 0; + __block GRPCCall2 *call = [[GRPCCall2 alloc] + initWithRequestOptions:callRequest + responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:^(NSData *message) { + if (messageId <= 1) { + [expectPassedMessage fulfill]; + } else { + [expectBlockedMessage fulfill]; + } + messageId++; + } + closeCallback:nil + writeDataCallback:^{ + [expectWriteTwice fulfill]; + }] + callOptions:options]; + + [call receiveNextMessages:2]; + [call start]; + [call writeData:[request data]]; + [call writeData:[request data]]; + + [self waitForExpectationsWithTimeout:kInvertedTimeout handler:nil]; +} + +- (void)testFlowControlReadReadyBeforeStart { + __weak XCTestExpectation *expectPassedMessage = + [self expectationWithDescription:@"Message delivered with receiveNextMessage"]; + __weak XCTestExpectation *expectPassedClose = + [self expectationWithDescription:@"Close delivered with receiveNextMessage"]; + + RMTSimpleRequest *request = [RMTSimpleRequest message]; + request.responseSize = kSimpleDataLength; + request.payload.body = [NSMutableData dataWithLength:kSimpleDataLength]; + + GRPCRequestOptions *callRequest = + [[GRPCRequestOptions alloc] initWithHost:(NSString *)kHostAddress + path:kUnaryCallMethod.HTTPPath + safety:GRPCCallSafetyDefault]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = GRPCTransportTypeInsecure; + options.flowControlEnabled = YES; + __block BOOL closed = NO; + GRPCCall2 *call = [[GRPCCall2 alloc] + initWithRequestOptions:callRequest + responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:^(NSData *message) { + [expectPassedMessage fulfill]; + XCTAssertFalse(closed); + } + closeCallback:^(NSDictionary *ttrailers, NSError *error) { + closed = YES; + [expectPassedClose fulfill]; + }] + callOptions:options]; + + [call receiveNextMessages:1]; + [call start]; + [call writeData:[request data]]; + [call finish]; + + [self waitForExpectationsWithTimeout:kInvertedTimeout handler:nil]; +} + +- (void)testFlowControlReadReadyAfterStart { + __weak XCTestExpectation *expectPassedMessage = + [self expectationWithDescription:@"Message delivered with receiveNextMessage"]; + __weak XCTestExpectation *expectPassedClose = + [self expectationWithDescription:@"Close delivered with receiveNextMessage"]; + + RMTStreamingOutputCallRequest *request = [RMTStreamingOutputCallRequest message]; + RMTResponseParameters *parameters = [RMTResponseParameters message]; + parameters.size = kSimpleDataLength; + [request.responseParametersArray addObject:parameters]; + request.payload.body = [NSMutableData dataWithLength:kSimpleDataLength]; + + GRPCRequestOptions *callRequest = + [[GRPCRequestOptions alloc] initWithHost:(NSString *)kHostAddress + path:kUnaryCallMethod.HTTPPath + safety:GRPCCallSafetyDefault]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = GRPCTransportTypeInsecure; + options.flowControlEnabled = YES; + __block BOOL closed = NO; + GRPCCall2 *call = [[GRPCCall2 alloc] + initWithRequestOptions:callRequest + responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:^(NSData *message) { + [expectPassedMessage fulfill]; + XCTAssertFalse(closed); + } + closeCallback:^(NSDictionary *trailers, NSError *error) { + closed = YES; + [expectPassedClose fulfill]; + }] + callOptions:options]; + + [call start]; + [call receiveNextMessages:1]; + [call writeData:[request data]]; + [call finish]; + + [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; +} + +- (void)testFlowControlReadNonBlockingFailure { + __weak XCTestExpectation *completion = [self expectationWithDescription:@"RPC completed."]; + + GRPCRequestOptions *requestOptions = + [[GRPCRequestOptions alloc] initWithHost:kHostAddress + path:kUnaryCallMethod.HTTPPath + safety:GRPCCallSafetyDefault]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.flowControlEnabled = YES; + options.transportType = GRPCTransportTypeInsecure; + + RMTSimpleRequest *request = [RMTSimpleRequest message]; + request.payload.body = [NSMutableData dataWithLength:options.responseSizeLimit]; + + RMTEchoStatus *status = [RMTEchoStatus message]; + status.code = 2; + status.message = @"test"; + request.responseStatus = status; + + GRPCCall2 *call = [[GRPCCall2 alloc] + initWithRequestOptions:requestOptions + responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:^(NSData *data) { + XCTFail(@"Received unexpected message"); + } + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + XCTAssertNotNil(error, @"Expecting non-nil error"); + XCTAssertEqual(error.code, 2); + [completion fulfill]; + }] + callOptions:options]; + [call writeData:[request data]]; + [call start]; + [call finish]; + + [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; +} + +@end diff --git a/src/objective-c/tests/APIv2Tests/Info.plist b/src/objective-c/tests/APIv2Tests/Info.plist new file mode 100644 index 00000000000..6c40a6cd0c4 --- /dev/null +++ b/src/objective-c/tests/APIv2Tests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/src/objective-c/tests/ChannelTests/ChannelPoolTest.m b/src/objective-c/tests/ChannelTests/ChannelPoolTest.m new file mode 100644 index 00000000000..eab8c5193fb --- /dev/null +++ b/src/objective-c/tests/ChannelTests/ChannelPoolTest.m @@ -0,0 +1,63 @@ +/* + * + * 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. + * + */ + +#import + +#import "../../GRPCClient/private/GRPCChannel.h" +#import "../../GRPCClient/private/GRPCChannelPool+Test.h" +#import "../../GRPCClient/private/GRPCCompletionQueue.h" + +#define TEST_TIMEOUT 32 + +static NSString *kDummyHost = @"dummy.host"; +static NSString *kDummyHost2 = @"dummy.host.2"; +static NSString *kDummyPath = @"/dummy/path"; + +@interface ChannelPoolTest : XCTestCase + +@end + +@implementation ChannelPoolTest + ++ (void)setUp { + grpc_init(); +} + +- (void)testCreateAndCacheChannel { + GRPCChannelPool *pool = [[GRPCChannelPool alloc] initTestPool]; + GRPCCallOptions *options1 = [[GRPCCallOptions alloc] init]; + GRPCCallOptions *options2 = [options1 copy]; + GRPCMutableCallOptions *options3 = [options1 mutableCopy]; + options3.transportType = GRPCTransportTypeInsecure; + + GRPCPooledChannel *channel1 = [pool channelWithHost:kDummyHost callOptions:options1]; + GRPCPooledChannel *channel2 = [pool channelWithHost:kDummyHost callOptions:options2]; + GRPCPooledChannel *channel3 = [pool channelWithHost:kDummyHost callOptions:options3]; + GRPCPooledChannel *channel4 = [pool channelWithHost:kDummyHost2 callOptions:options1]; + + XCTAssertNotNil(channel1); + XCTAssertNotNil(channel2); + XCTAssertNotNil(channel3); + XCTAssertNotNil(channel4); + XCTAssertEqual(channel1, channel2); + XCTAssertNotEqual(channel1, channel3); + XCTAssertNotEqual(channel1, channel4); + XCTAssertNotEqual(channel3, channel4); +} + +@end diff --git a/src/objective-c/tests/ChannelTests/ChannelTests.m b/src/objective-c/tests/ChannelTests/ChannelTests.m new file mode 100644 index 00000000000..df78e8b1162 --- /dev/null +++ b/src/objective-c/tests/ChannelTests/ChannelTests.m @@ -0,0 +1,112 @@ +/* + * + * 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. + * + */ + +#import + +#import "../../GRPCClient/GRPCCallOptions.h" +#import "../../GRPCClient/private/GRPCChannel.h" +#import "../../GRPCClient/private/GRPCChannelPool+Test.h" +#import "../../GRPCClient/private/GRPCChannelPool.h" +#import "../../GRPCClient/private/GRPCCompletionQueue.h" +#import "../../GRPCClient/private/GRPCWrappedCall.h" + +static NSString *kDummyHost = @"dummy.host"; +static NSString *kDummyPath = @"/dummy/path"; + +@interface ChannelTests : XCTestCase + +@end + +@implementation ChannelTests + ++ (void)setUp { + grpc_init(); +} + +- (void)testPooledChannelCreatingChannel { + GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; + GRPCChannelConfiguration *config = + [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options]; + GRPCPooledChannel *channel = [[GRPCPooledChannel alloc] initWithChannelConfiguration:config]; + GRPCCompletionQueue *cq = [GRPCCompletionQueue completionQueue]; + GRPCWrappedCall *wrappedCall = + [channel wrappedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; + XCTAssertNotNil(channel.wrappedChannel); + (void)wrappedCall; +} + +- (void)testTimedDestroyChannel { + const NSTimeInterval kDestroyDelay = 1.0; + GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; + GRPCChannelConfiguration *config = + [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options]; + GRPCPooledChannel *channel = + [[GRPCPooledChannel alloc] initWithChannelConfiguration:config destroyDelay:kDestroyDelay]; + GRPCCompletionQueue *cq = [GRPCCompletionQueue completionQueue]; + GRPCWrappedCall *wrappedCall; + GRPCChannel *wrappedChannel; + @autoreleasepool { + wrappedCall = [channel wrappedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; + XCTAssertNotNil(channel.wrappedChannel); + + // Unref and ref channel immediately; expect using the same raw channel. + wrappedChannel = channel.wrappedChannel; + + wrappedCall = nil; + wrappedCall = [channel wrappedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; + XCTAssertEqual(channel.wrappedChannel, wrappedChannel); + + // Unref and ref channel after destroy delay; expect a new raw channel. + wrappedCall = nil; + } + sleep(kDestroyDelay + 1); + XCTAssertNil(channel.wrappedChannel); + wrappedCall = [channel wrappedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; + XCTAssertNotEqual(channel.wrappedChannel, wrappedChannel); +} + +- (void)testDisconnect { + const NSTimeInterval kDestroyDelay = 1.0; + GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; + GRPCChannelConfiguration *config = + [[GRPCChannelConfiguration alloc] initWithHost:kDummyHost callOptions:options]; + GRPCPooledChannel *channel = + [[GRPCPooledChannel alloc] initWithChannelConfiguration:config destroyDelay:kDestroyDelay]; + GRPCCompletionQueue *cq = [GRPCCompletionQueue completionQueue]; + GRPCWrappedCall *wrappedCall = + [channel wrappedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; + XCTAssertNotNil(channel.wrappedChannel); + + // Disconnect; expect wrapped channel to be dropped + [channel disconnect]; + XCTAssertNil(channel.wrappedChannel); + + // Create a new call and unref the old call; confirm that destroy of the old call does not make + // the channel disconnect, even after the destroy delay. + GRPCWrappedCall *wrappedCall2 = + [channel wrappedCallWithPath:kDummyPath completionQueue:cq callOptions:options]; + XCTAssertNotNil(channel.wrappedChannel); + GRPCChannel *wrappedChannel = channel.wrappedChannel; + wrappedCall = nil; + sleep(kDestroyDelay + 1); + XCTAssertNotNil(channel.wrappedChannel); + XCTAssertEqual(wrappedChannel, channel.wrappedChannel); + (void)wrappedCall2; +} + +@end diff --git a/src/objective-c/tests/ChannelTests/Info.plist b/src/objective-c/tests/ChannelTests/Info.plist new file mode 100644 index 00000000000..6c40a6cd0c4 --- /dev/null +++ b/src/objective-c/tests/ChannelTests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.mm b/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.mm index 80fa0f47852..2fac1be3d0e 100644 --- a/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.mm +++ b/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.mm @@ -81,13 +81,7 @@ static void cronet_init_client_secure_fullstack(grpc_end2end_test_fixture *f, grpc_channel_args *client_args, stream_engine *cronetEngine) { fullstack_secure_fixture_data *ffd = (fullstack_secure_fixture_data *)f->fixture_data; - grpc_arg arg; - arg.key = const_cast(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); } @@ -324,10 +318,6 @@ static char *roots_filename; [self testIndividualCase:(char *)"negative_deadline"]; } -- (void)testNetworkStatusChange { - [self testIndividualCase:(char *)"network_status_change"]; -} - - (void)testNoOp { [self testIndividualCase:(char *)"no_op"]; } diff --git a/src/objective-c/tests/CronetUnitTests/CronetUnitTests.m b/src/objective-c/tests/CronetUnitTests/CronetUnitTests.m index 84893b92c1a..d732bc6ba99 100644 --- a/src/objective-c/tests/CronetUnitTests/CronetUnitTests.m +++ b/src/objective-c/tests/CronetUnitTests/CronetUnitTests.m @@ -124,14 +124,6 @@ unsigned int parse_h2_length(const char *field) { ((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(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"); @@ -151,9 +143,7 @@ grpc_channel_args *add_disable_client_authority_filter_args(grpc_channel_args *a 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_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); + grpc_channel *client = grpc_cronet_secure_channel_create(cronetEngine, addr, NULL, NULL); cq_verifier *cqv = cq_verifier_create(cq); grpc_op ops[6]; @@ -265,7 +255,6 @@ grpc_channel_args *add_disable_client_authority_filter_args(grpc_channel_args *a 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"); diff --git a/src/objective-c/tests/GRPCClientTests.m b/src/objective-c/tests/GRPCClientTests.m index a0de8ba8990..b361078d54b 100644 --- a/src/objective-c/tests/GRPCClientTests.m +++ b/src/objective-c/tests/GRPCClientTests.m @@ -16,9 +16,9 @@ * */ -#import #import #import +#import #import #import @@ -297,7 +297,9 @@ static GRPCProtoMethod *kFullDuplexCallMethod; 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:@" ("]; + expectedUserAgent = [expectedUserAgent stringByAppendingString:@GPR_PLATFORM_STRING]; + expectedUserAgent = [expectedUserAgent stringByAppendingString:@"; chttp2; "]; expectedUserAgent = [expectedUserAgent stringByAppendingString:[NSString stringWithUTF8String:grpc_g_stands_for()]]; expectedUserAgent = [expectedUserAgent stringByAppendingString:@")"]; @@ -362,9 +364,10 @@ static GRPCProtoMethod *kFullDuplexCallMethod; // TODO(makarandd): Move to a different file that contains only unit tests - (void)testExceptions { + GRXWriter *writer = [GRXWriter writerWithValue:[NSData data]]; // 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:writer]; XCTFail(@"Did not receive an exception when parameters are nil"); } @catch (NSException *theException) { NSLog(@"Received exception as expected: %@", theException.name); @@ -554,13 +557,14 @@ static GRPCProtoMethod *kFullDuplexCallMethod; __weak XCTestExpectation *completion = [self expectationWithDescription:@"Timeout in a second."]; NSString *const kDummyAddress = [NSString stringWithFormat:@"8.8.8.8:1"]; - GRPCCall *call = [[GRPCCall alloc] initWithHost:kDummyAddress - path:@"" - requestsWriter:[GRXWriter writerWithValue:[NSData data]]]; + [GRPCCall useInsecureConnectionsForHost:kDummyAddress]; [GRPCCall setMinConnectTimeout:timeout * 1000 initialBackoff:backoff * 1000 maxBackoff:0 forHost:kDummyAddress]; + GRPCCall *call = [[GRPCCall alloc] initWithHost:kDummyAddress + path:@"/dummyPath" + requestsWriter:[GRXWriter writerWithValue:[NSData data]]]; NSDate *startTime = [NSDate date]; id responsesWriteable = [[GRXWriteable alloc] initWithValueHandler:^(id value) { XCTAssert(NO, @"Received message. Should not reach here"); @@ -583,11 +587,11 @@ static GRPCProtoMethod *kFullDuplexCallMethod; // The numbers of the following three tests are selected to be smaller than the default values of // initial backoff (1s) and min_connect_timeout (20s), so that if they fail we know the default // values fail to be overridden by the channel args. -- (void)testTimeoutBackoff2 { +- (void)testTimeoutBackoff1 { [self testTimeoutBackoffWithTimeout:0.7 Backoff:0.3]; } -- (void)testTimeoutBackoff3 { +- (void)testTimeoutBackoff2 { [self testTimeoutBackoffWithTimeout:0.3 Backoff:0.7]; } diff --git a/src/objective-c/tests/InteropTests.h b/src/objective-c/tests/InteropTests.h index 039d92a8d35..038f24b62e5 100644 --- a/src/objective-c/tests/InteropTests.h +++ b/src/objective-c/tests/InteropTests.h @@ -18,6 +18,8 @@ #import +#import + /** * Implements tests as described here: * https://github.com/grpc/grpc/blob/master/doc/interop-test-descriptions.md @@ -38,4 +40,23 @@ * remote servers enconde responses with different overhead (?), so this is defined per-subclass. */ - (int32_t)encodingOverhead; + +/** + * The type of transport to be used. The base implementation returns default. Subclasses should + * override to appropriate settings. + */ ++ (GRPCTransportType)transportType; + +/** + * The root certificates to be used. The base implementation returns nil. Subclasses should override + * to appropriate settings. + */ ++ (NSString *)PEMRootCertificates; + +/** + * The root certificates to be used. The base implementation returns nil. Subclasses should override + * to appropriate settings. + */ ++ (NSString *)hostNameOverride; + @end diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m index 9d796068818..aab38e3a594 100644 --- a/src/objective-c/tests/InteropTests.m +++ b/src/objective-c/tests/InteropTests.m @@ -20,7 +20,9 @@ #include +#ifdef GRPC_COMPILE_WITH_CRONET #import +#endif #import #import #import @@ -74,6 +76,81 @@ BOOL isRemoteInteropTest(NSString *host) { return [host isEqualToString:@"grpc-test.sandbox.googleapis.com"]; } +// Convenience class to use blocks as callbacks +@interface InteropTestsBlockCallbacks : NSObject + +- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback + messageCallback:(void (^)(id))messageCallback + closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback + writeMessageCallback:(void (^)(void))writeMessageCallback; + +- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback + messageCallback:(void (^)(id))messageCallback + closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback; + +@end + +@implementation InteropTestsBlockCallbacks { + void (^_initialMetadataCallback)(NSDictionary *); + void (^_messageCallback)(id); + void (^_closeCallback)(NSDictionary *, NSError *); + void (^_writeMessageCallback)(void); + dispatch_queue_t _dispatchQueue; +} + +- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback + messageCallback:(void (^)(id))messageCallback + closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback + writeMessageCallback:(void (^)(void))writeMessageCallback { + if ((self = [super init])) { + _initialMetadataCallback = initialMetadataCallback; + _messageCallback = messageCallback; + _closeCallback = closeCallback; + _writeMessageCallback = writeMessageCallback; + _dispatchQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL); + } + return self; +} + +- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback + messageCallback:(void (^)(id))messageCallback + closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback { + return [self initWithInitialMetadataCallback:initialMetadataCallback + messageCallback:messageCallback + closeCallback:closeCallback + writeMessageCallback:nil]; +} + +- (void)didReceiveInitialMetadata:(NSDictionary *)initialMetadata { + if (_initialMetadataCallback) { + _initialMetadataCallback(initialMetadata); + } +} + +- (void)didReceiveProtoMessage:(GPBMessage *)message { + if (_messageCallback) { + _messageCallback(message); + } +} + +- (void)didCloseWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { + if (_closeCallback) { + _closeCallback(trailingMetadata, error); + } +} + +- (void)didWriteMessage { + if (_writeMessageCallback) { + _writeMessageCallback(); + } +} + +- (dispatch_queue_t)dispatchQueue { + return _dispatchQueue; +} + +@end + #pragma mark Tests @implementation InteropTests { @@ -91,6 +168,18 @@ BOOL isRemoteInteropTest(NSString *host) { return 0; } ++ (GRPCTransportType)transportType { + return GRPCTransportTypeChttp2BoringSSL; +} + ++ (NSString *)PEMRootCertificates { + return nil; +} + ++ (NSString *)hostNameOverride { + return nil; +} + + (void)setUp { NSLog(@"InteropTest Started, class: %@", [[self class] description]); #ifdef GRPC_COMPILE_WITH_CRONET @@ -109,11 +198,11 @@ BOOL isRemoteInteropTest(NSString *host) { [GRPCCall resetHostSettings]; - _service = self.class.host ? [RMTTestService serviceWithHost:self.class.host] : nil; + _service = [[self class] host] ? [RMTTestService serviceWithHost:[[self class] host]] : nil; } - (void)testEmptyUnaryRPC { - XCTAssertNotNil(self.class.host); + XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"EmptyUnary"]; GPBEmpty *request = [GPBEmpty message]; @@ -131,8 +220,86 @@ BOOL isRemoteInteropTest(NSString *host) { [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } +- (void)testEmptyUnaryRPCWithV2API { + XCTAssertNotNil([[self class] host]); + __weak XCTestExpectation *expectReceive = + [self expectationWithDescription:@"EmptyUnaryWithV2API received message"]; + __weak XCTestExpectation *expectComplete = + [self expectationWithDescription:@"EmptyUnaryWithV2API completed"]; + + GPBEmpty *request = [GPBEmpty message]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = [[self class] transportType]; + options.PEMRootCertificates = [[self class] PEMRootCertificates]; + options.hostNameOverride = [[self class] hostNameOverride]; + + GRPCUnaryProtoCall *call = [_service + emptyCallWithMessage:request + responseHandler:[[InteropTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:^(id message) { + if (message) { + id expectedResponse = [GPBEmpty message]; + XCTAssertEqualObjects(message, expectedResponse); + [expectReceive fulfill]; + } + } + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + XCTAssertNil(error, @"Unexpected error: %@", error); + [expectComplete fulfill]; + }] + callOptions:options]; + [call start]; + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + +// Test that responses can be dispatched even if we do not run main run-loop +- (void)testAsyncDispatchWithV2API { + XCTAssertNotNil([[self class] host]); + + GPBEmpty *request = [GPBEmpty message]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = [[self class] transportType]; + options.PEMRootCertificates = [[self class] PEMRootCertificates]; + options.hostNameOverride = [[self class] hostNameOverride]; + + __block BOOL messageReceived = NO; + __block BOOL done = NO; + NSCondition *cond = [[NSCondition alloc] init]; + GRPCUnaryProtoCall *call = [_service + emptyCallWithMessage:request + responseHandler:[[InteropTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:^(id message) { + if (message) { + id expectedResponse = [GPBEmpty message]; + XCTAssertEqualObjects(message, expectedResponse); + [cond lock]; + messageReceived = YES; + [cond unlock]; + } + } + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + XCTAssertNil(error, @"Unexpected error: %@", error); + [cond lock]; + done = YES; + [cond signal]; + [cond unlock]; + }] + callOptions:options]; + + NSDate *deadline = [NSDate dateWithTimeIntervalSinceNow:TEST_TIMEOUT]; + [call start]; + + [cond lock]; + while (!done && [deadline timeIntervalSinceNow] > 0) { + [cond waitUntilDate:deadline]; + } + XCTAssertTrue(messageReceived); + XCTAssertTrue(done); + [cond unlock]; +} + - (void)testLargeUnaryRPC { - XCTAssertNotNil(self.class.host); + XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"LargeUnary"]; RMTSimpleRequest *request = [RMTSimpleRequest message]; @@ -155,8 +322,134 @@ BOOL isRemoteInteropTest(NSString *host) { [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } +- (void)testLargeUnaryRPCWithV2API { + XCTAssertNotNil([[self class] host]); + __weak XCTestExpectation *expectReceive = + [self expectationWithDescription:@"LargeUnaryWithV2API received message"]; + __weak XCTestExpectation *expectComplete = + [self expectationWithDescription:@"LargeUnaryWithV2API received complete"]; + + RMTSimpleRequest *request = [RMTSimpleRequest message]; + request.responseType = RMTPayloadType_Compressable; + request.responseSize = 314159; + request.payload.body = [NSMutableData dataWithLength:271828]; + + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = [[self class] transportType]; + options.PEMRootCertificates = [[self class] PEMRootCertificates]; + options.hostNameOverride = [[self class] hostNameOverride]; + + GRPCUnaryProtoCall *call = [_service + unaryCallWithMessage:request + responseHandler:[[InteropTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:^(id message) { + XCTAssertNotNil(message); + if (message) { + RMTSimpleResponse *expectedResponse = + [RMTSimpleResponse message]; + expectedResponse.payload.type = RMTPayloadType_Compressable; + expectedResponse.payload.body = + [NSMutableData dataWithLength:314159]; + XCTAssertEqualObjects(message, expectedResponse); + + [expectReceive fulfill]; + } + } + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + XCTAssertNil(error, @"Unexpected error: %@", error); + [expectComplete fulfill]; + }] + callOptions:options]; + [call start]; + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + +- (void)testConcurrentRPCsWithErrorsWithV2API { + NSMutableArray *completeExpectations = [NSMutableArray array]; + NSMutableArray *calls = [NSMutableArray array]; + int num_rpcs = 10; + for (int i = 0; i < num_rpcs; ++i) { + [completeExpectations + addObject:[self expectationWithDescription: + [NSString stringWithFormat:@"Received trailer for RPC %d", i]]]; + + RMTSimpleRequest *request = [RMTSimpleRequest message]; + request.responseType = RMTPayloadType_Compressable; + request.responseSize = 314159; + request.payload.body = [NSMutableData dataWithLength:271828]; + if (i % 3 == 0) { + request.responseStatus.code = GRPC_STATUS_UNAVAILABLE; + } else if (i % 7 == 0) { + request.responseStatus.code = GRPC_STATUS_CANCELLED; + } + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = [[self class] transportType]; + options.PEMRootCertificates = [[self class] PEMRootCertificates]; + options.hostNameOverride = [[self class] hostNameOverride]; + + GRPCUnaryProtoCall *call = [_service + unaryCallWithMessage:request + responseHandler:[[InteropTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:^(id message) { + if (message) { + RMTSimpleResponse *expectedResponse = + [RMTSimpleResponse message]; + expectedResponse.payload.type = RMTPayloadType_Compressable; + expectedResponse.payload.body = + [NSMutableData dataWithLength:314159]; + XCTAssertEqualObjects(message, expectedResponse); + } + } + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + [completeExpectations[i] fulfill]; + }] + callOptions:options]; + [calls addObject:call]; + } + + for (int i = 0; i < num_rpcs; ++i) { + GRPCUnaryProtoCall *call = calls[i]; + [call start]; + } + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + +- (void)testConcurrentRPCsWithErrors { + NSMutableArray *completeExpectations = [NSMutableArray array]; + int num_rpcs = 10; + for (int i = 0; i < num_rpcs; ++i) { + [completeExpectations + addObject:[self expectationWithDescription: + [NSString stringWithFormat:@"Received trailer for RPC %d", i]]]; + + RMTSimpleRequest *request = [RMTSimpleRequest message]; + request.responseType = RMTPayloadType_Compressable; + request.responseSize = 314159; + request.payload.body = [NSMutableData dataWithLength:271828]; + if (i % 3 == 0) { + request.responseStatus.code = GRPC_STATUS_UNAVAILABLE; + } else if (i % 7 == 0) { + request.responseStatus.code = GRPC_STATUS_CANCELLED; + } + + [_service unaryCallWithRequest:request + handler:^(RMTSimpleResponse *response, NSError *error) { + if (error == nil) { + RMTSimpleResponse *expectedResponse = [RMTSimpleResponse message]; + expectedResponse.payload.type = RMTPayloadType_Compressable; + expectedResponse.payload.body = + [NSMutableData dataWithLength:314159]; + XCTAssertEqualObjects(response, expectedResponse); + } + [completeExpectations[i] fulfill]; + }]; + } + + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + - (void)testPacketCoalescing { - XCTAssertNotNil(self.class.host); + XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"LargeUnary"]; RMTSimpleRequest *request = [RMTSimpleRequest message]; @@ -195,7 +488,7 @@ BOOL isRemoteInteropTest(NSString *host) { } - (void)test4MBResponsesAreAccepted { - XCTAssertNotNil(self.class.host); + XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"MaxResponseSize"]; RMTSimpleRequest *request = [RMTSimpleRequest message]; @@ -213,7 +506,7 @@ BOOL isRemoteInteropTest(NSString *host) { } - (void)testResponsesOverMaxSizeFailWithActionableMessage { - XCTAssertNotNil(self.class.host); + XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"ResponseOverMaxSize"]; RMTSimpleRequest *request = [RMTSimpleRequest message]; @@ -239,7 +532,7 @@ BOOL isRemoteInteropTest(NSString *host) { } - (void)testResponsesOver4MBAreAcceptedIfOptedIn { - XCTAssertNotNil(self.class.host); + XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"HigherResponseSizeLimit"]; @@ -247,7 +540,7 @@ BOOL isRemoteInteropTest(NSString *host) { const size_t kPayloadSize = 5 * 1024 * 1024; // 5MB request.responseSize = kPayloadSize; - [GRPCCall setResponseSizeLimit:6 * 1024 * 1024 forHost:self.class.host]; + [GRPCCall setResponseSizeLimit:6 * 1024 * 1024 forHost:[[self class] host]]; [_service unaryCallWithRequest:request handler:^(RMTSimpleResponse *response, NSError *error) { @@ -260,7 +553,7 @@ BOOL isRemoteInteropTest(NSString *host) { } - (void)testClientStreamingRPC { - XCTAssertNotNil(self.class.host); + XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"ClientStreaming"]; RMTStreamingInputCallRequest *request1 = [RMTStreamingInputCallRequest message]; @@ -295,7 +588,7 @@ BOOL isRemoteInteropTest(NSString *host) { } - (void)testServerStreamingRPC { - XCTAssertNotNil(self.class.host); + XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"ServerStreaming"]; NSArray *expectedSizes = @[ @31415, @9, @2653, @58979 ]; @@ -334,7 +627,7 @@ BOOL isRemoteInteropTest(NSString *host) { } - (void)testPingPongRPC { - XCTAssertNotNil(self.class.host); + XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"PingPong"]; NSArray *requests = @[ @27182, @8, @1828, @45904 ]; @@ -380,8 +673,121 @@ BOOL isRemoteInteropTest(NSString *host) { [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } +- (void)testPingPongRPCWithV2API { + XCTAssertNotNil([[self class] host]); + __weak XCTestExpectation *expectation = [self expectationWithDescription:@"PingPongWithV2API"]; + + NSArray *requests = @[ @27182, @8, @1828, @45904 ]; + NSArray *responses = @[ @31415, @9, @2653, @58979 ]; + + __block int index = 0; + + id request = [RMTStreamingOutputCallRequest messageWithPayloadSize:requests[index] + requestedResponseSize:responses[index]]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = [[self class] transportType]; + options.PEMRootCertificates = [[self class] PEMRootCertificates]; + options.hostNameOverride = [[self class] hostNameOverride]; + + __block GRPCStreamingProtoCall *call = [_service + fullDuplexCallWithResponseHandler:[[InteropTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:nil + messageCallback:^(id message) { + XCTAssertLessThan(index, 4, + @"More than 4 responses received."); + id expected = [RMTStreamingOutputCallResponse + messageWithPayloadSize:responses[index]]; + XCTAssertEqualObjects(message, expected); + index += 1; + if (index < 4) { + id request = [RMTStreamingOutputCallRequest + messageWithPayloadSize:requests[index] + requestedResponseSize:responses[index]]; + [call writeMessage:request]; + } else { + [call finish]; + } + } + closeCallback:^(NSDictionary *trailingMetadata, + NSError *error) { + XCTAssertNil(error, + @"Finished with unexpected error: %@", + error); + XCTAssertEqual(index, 4, + @"Received %i responses instead of 4.", + index); + [expectation fulfill]; + }] + callOptions:options]; + [call start]; + [call writeMessage:request]; + + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + +- (void)testPingPongRPCWithFlowControl { + XCTAssertNotNil([[self class] host]); + __weak XCTestExpectation *expectation = [self expectationWithDescription:@"PingPongWithV2API"]; + + NSArray *requests = @[ @27182, @8, @1828, @45904 ]; + NSArray *responses = @[ @31415, @9, @2653, @58979 ]; + + __block int index = 0; + + id request = [RMTStreamingOutputCallRequest messageWithPayloadSize:requests[index] + requestedResponseSize:responses[index]]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = [[self class] transportType]; + options.PEMRootCertificates = [[self class] PEMRootCertificates]; + options.hostNameOverride = [[self class] hostNameOverride]; + options.flowControlEnabled = YES; + __block BOOL canWriteData = NO; + + __block GRPCStreamingProtoCall *call = [_service + fullDuplexCallWithResponseHandler:[[InteropTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:nil + messageCallback:^(id message) { + XCTAssertLessThan(index, 4, + @"More than 4 responses received."); + id expected = [RMTStreamingOutputCallResponse + messageWithPayloadSize:responses[index]]; + XCTAssertEqualObjects(message, expected); + index += 1; + if (index < 4) { + id request = [RMTStreamingOutputCallRequest + messageWithPayloadSize:requests[index] + requestedResponseSize:responses[index]]; + XCTAssertTrue(canWriteData); + canWriteData = NO; + [call writeMessage:request]; + [call receiveNextMessage]; + } else { + [call finish]; + } + } + closeCallback:^(NSDictionary *trailingMetadata, + NSError *error) { + XCTAssertNil(error, + @"Finished with unexpected error: %@", + error); + XCTAssertEqual(index, 4, + @"Received %i responses instead of 4.", + index); + [expectation fulfill]; + } + writeMessageCallback:^{ + canWriteData = YES; + }] + callOptions:options]; + [call start]; + [call receiveNextMessage]; + [call writeMessage:request]; + + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + - (void)testEmptyStreamRPC { - XCTAssertNotNil(self.class.host); + XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"EmptyStream"]; [_service fullDuplexCallWithRequestsWriter:[GRXWriter emptyWriter] eventHandler:^(BOOL done, RMTStreamingOutputCallResponse *response, @@ -394,7 +800,7 @@ BOOL isRemoteInteropTest(NSString *host) { } - (void)testCancelAfterBeginRPC { - XCTAssertNotNil(self.class.host); + XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"CancelAfterBegin"]; // A buffered pipe to which we never write any value acts as a writer that just hangs. @@ -418,8 +824,32 @@ BOOL isRemoteInteropTest(NSString *host) { [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } +- (void)testCancelAfterBeginRPCWithV2API { + XCTAssertNotNil([[self class] host]); + __weak XCTestExpectation *expectation = + [self expectationWithDescription:@"CancelAfterBeginWithV2API"]; + + // A buffered pipe to which we never write any value acts as a writer that just hangs. + __block GRPCStreamingProtoCall *call = [_service + streamingInputCallWithResponseHandler:[[InteropTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:nil + messageCallback:^(id message) { + XCTFail(@"Not expected to receive message"); + } + closeCallback:^(NSDictionary *trailingMetadata, + NSError *error) { + XCTAssertEqual(error.code, GRPC_STATUS_CANCELLED); + [expectation fulfill]; + }] + callOptions:nil]; + [call start]; + [call cancel]; + + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + - (void)testCancelAfterFirstResponseRPC { - XCTAssertNotNil(self.class.host); + XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"CancelAfterFirstResponse"]; @@ -454,8 +884,76 @@ BOOL isRemoteInteropTest(NSString *host) { [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } +- (void)testCancelAfterFirstResponseRPCWithV2API { + XCTAssertNotNil([[self class] host]); + __weak XCTestExpectation *completionExpectation = + [self expectationWithDescription:@"Call completed."]; + __weak XCTestExpectation *responseExpectation = + [self expectationWithDescription:@"Received response."]; + + __block BOOL receivedResponse = NO; + + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = self.class.transportType; + options.PEMRootCertificates = self.class.PEMRootCertificates; + options.hostNameOverride = [[self class] hostNameOverride]; + + id request = + [RMTStreamingOutputCallRequest messageWithPayloadSize:@21782 requestedResponseSize:@31415]; + + __block GRPCStreamingProtoCall *call = [_service + fullDuplexCallWithResponseHandler:[[InteropTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:nil + messageCallback:^(id message) { + XCTAssertFalse(receivedResponse); + receivedResponse = YES; + [call cancel]; + [responseExpectation fulfill]; + } + closeCallback:^(NSDictionary *trailingMetadata, + NSError *error) { + XCTAssertEqual(error.code, GRPC_STATUS_CANCELLED); + [completionExpectation fulfill]; + }] + callOptions:options]; + [call start]; + [call writeMessage:request]; + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + +- (void)testCancelAfterFirstRequestWithV2API { + XCTAssertNotNil([[self class] host]); + __weak XCTestExpectation *completionExpectation = + [self expectationWithDescription:@"Call completed."]; + + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = self.class.transportType; + options.PEMRootCertificates = self.class.PEMRootCertificates; + options.hostNameOverride = [[self class] hostNameOverride]; + + id request = + [RMTStreamingOutputCallRequest messageWithPayloadSize:@21782 requestedResponseSize:@31415]; + + __block GRPCStreamingProtoCall *call = [_service + fullDuplexCallWithResponseHandler:[[InteropTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:nil + messageCallback:^(id message) { + XCTFail(@"Received unexpected response."); + } + closeCallback:^(NSDictionary *trailingMetadata, + NSError *error) { + XCTAssertEqual(error.code, GRPC_STATUS_CANCELLED); + [completionExpectation fulfill]; + }] + callOptions:options]; + [call start]; + [call writeMessage:request]; + [call cancel]; + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + - (void)testRPCAfterClosingOpenConnections { - XCTAssertNotNil(self.class.host); + XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"RPC after closing connection"]; @@ -471,7 +969,7 @@ BOOL isRemoteInteropTest(NSString *host) { [GRPCCall closeOpenConnections]; #pragma clang diagnostic pop - [_service + [self->_service emptyCallWithRequest:request handler:^(GPBEmpty *response, NSError *error) { XCTAssertNil( @@ -487,10 +985,10 @@ BOOL isRemoteInteropTest(NSString *host) { - (void)testCompressedUnaryRPC { // This test needs to be disabled for remote test because interop server grpc-test // does not support compression. - if (isRemoteInteropTest(self.class.host)) { + if (isRemoteInteropTest([[self class] host])) { return; } - XCTAssertNotNil(self.class.host); + XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"LargeUnary"]; RMTSimpleRequest *request = [RMTSimpleRequest message]; @@ -498,7 +996,7 @@ BOOL isRemoteInteropTest(NSString *host) { request.responseSize = 314159; request.payload.body = [NSMutableData dataWithLength:271828]; request.expectCompressed.value = YES; - [GRPCCall setDefaultCompressMethod:GRPCCompressGzip forhost:self.class.host]; + [GRPCCall setDefaultCompressMethod:GRPCCompressGzip forhost:[[self class] host]]; [_service unaryCallWithRequest:request handler:^(RMTSimpleResponse *response, NSError *error) { @@ -517,10 +1015,10 @@ BOOL isRemoteInteropTest(NSString *host) { #ifndef GRPC_COMPILE_WITH_CRONET - (void)testKeepalive { - XCTAssertNotNil(self.class.host); + XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"Keepalive"]; - [GRPCCall setKeepaliveWithInterval:1500 timeout:0 forHost:self.class.host]; + [GRPCCall setKeepaliveWithInterval:1500 timeout:0 forHost:[[self class] host]]; NSArray *requests = @[ @27182, @8 ]; NSArray *responses = @[ @31415, @9 ]; diff --git a/src/objective-c/tests/InteropTestsCallOptions/Info.plist b/src/objective-c/tests/InteropTestsCallOptions/Info.plist new file mode 100644 index 00000000000..6c40a6cd0c4 --- /dev/null +++ b/src/objective-c/tests/InteropTestsCallOptions/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/src/objective-c/tests/InteropTestsCallOptions/InteropTestsCallOptions.m b/src/objective-c/tests/InteropTestsCallOptions/InteropTestsCallOptions.m new file mode 100644 index 00000000000..db51cb1cfbb --- /dev/null +++ b/src/objective-c/tests/InteropTestsCallOptions/InteropTestsCallOptions.m @@ -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. + * + */ + +#import + +#import +#import +#import +#import +#import +#import + +#define NSStringize_helper(x) #x +#define NSStringize(x) @NSStringize_helper(x) +static NSString *kRemoteHost = NSStringize(HOST_PORT_REMOTE); +const int32_t kRemoteInteropServerOverhead = 12; + +static const NSTimeInterval TEST_TIMEOUT = 16000; + +@interface InteropTestsCallOptions : XCTestCase + +@end + +@implementation InteropTestsCallOptions { + RMTTestService *_service; +} + +- (void)setUp { + self.continueAfterFailure = NO; + _service = [RMTTestService serviceWithHost:kRemoteHost]; + _service.options = [[GRPCCallOptions alloc] init]; +} + +- (void)test4MBResponsesAreAccepted { + __weak XCTestExpectation *expectation = [self expectationWithDescription:@"MaxResponseSize"]; + + RMTSimpleRequest *request = [RMTSimpleRequest message]; + const int32_t kPayloadSize = + 4 * 1024 * 1024 - kRemoteInteropServerOverhead; // 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]; + }]; + + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + +- (void)testResponsesOverMaxSizeFailWithActionableMessage { + __weak XCTestExpectation *expectation = [self expectationWithDescription:@"ResponseOverMaxSize"]; + + RMTSimpleRequest *request = [RMTSimpleRequest message]; + const int32_t kPayloadSize = + 4 * 1024 * 1024 - kRemoteInteropServerOverhead + 1; // 1B over max size + request.responseSize = kPayloadSize; + + [_service unaryCallWithRequest:request + handler:^(RMTSimpleResponse *response, NSError *error) { + XCTAssertEqualObjects( + error.localizedDescription, + @"Received message larger than max (4194305 vs. 4194304)"); + [expectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + +- (void)testResponsesOver4MBAreAcceptedIfOptedIn { + __weak XCTestExpectation *expectation = + [self expectationWithDescription:@"HigherResponseSizeLimit"]; + + RMTSimpleRequest *request = [RMTSimpleRequest message]; + const size_t kPayloadSize = 5 * 1024 * 1024; // 5MB + request.responseSize = kPayloadSize; + + GRPCProtoCall *rpc = [_service + RPCToUnaryCallWithRequest:request + handler:^(RMTSimpleResponse *response, NSError *error) { + XCTAssertNil(error, @"Finished with unexpected error: %@", error); + XCTAssertEqual(response.payload.body.length, kPayloadSize); + [expectation fulfill]; + }]; + GRPCCallOptions *options = rpc.options; + options.responseSizeLimit = 6 * 1024 * 1024; + + [rpc start]; + + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + +- (void)testPerformanceExample { + // This is an example of a performance test case. + [self measureBlock:^{ + // Put the code you want to measure the time of here. + }]; +} + +@end diff --git a/src/objective-c/tests/InteropTestsLocalCleartext.m b/src/objective-c/tests/InteropTestsLocalCleartext.m index d49e875bd02..a9c69183332 100644 --- a/src/objective-c/tests/InteropTestsLocalCleartext.m +++ b/src/objective-c/tests/InteropTestsLocalCleartext.m @@ -41,6 +41,14 @@ static int32_t kLocalInteropServerOverhead = 10; return kLocalCleartextHost; } ++ (NSString *)PEMRootCertificates { + return nil; +} + ++ (NSString *)hostNameOverride { + return nil; +} + - (int32_t)encodingOverhead { return kLocalInteropServerOverhead; // bytes } @@ -52,4 +60,8 @@ static int32_t kLocalInteropServerOverhead = 10; [GRPCCall useInsecureConnectionsForHost:kLocalCleartextHost]; } ++ (GRPCTransportType)transportType { + return GRPCTransportTypeInsecure; +} + @end diff --git a/src/objective-c/tests/InteropTestsLocalSSL.m b/src/objective-c/tests/InteropTestsLocalSSL.m index a8c4dc7dfd1..e8222f602f4 100644 --- a/src/objective-c/tests/InteropTestsLocalSSL.m +++ b/src/objective-c/tests/InteropTestsLocalSSL.m @@ -40,15 +40,31 @@ static int32_t kLocalInteropServerOverhead = 10; return kLocalSSLHost; } ++ (NSString *)PEMRootCertificates { + NSBundle *bundle = [NSBundle bundleForClass:[self class]]; + NSString *certsPath = + [bundle pathForResource:@"TestCertificates.bundle/test-certificates" ofType:@"pem"]; + NSError *error; + return [NSString stringWithContentsOfFile:certsPath encoding:NSUTF8StringEncoding error:&error]; +} + ++ (NSString *)hostNameOverride { + return @"foo.test.google.fr"; +} + - (int32_t)encodingOverhead { return kLocalInteropServerOverhead; // bytes } ++ (GRPCTransportType)transportType { + return GRPCTransportTypeChttp2BoringSSL; +} + - (void)setUp { [super setUp]; // Register test server certificates and name. - NSBundle *bundle = [NSBundle bundleForClass:self.class]; + NSBundle *bundle = [NSBundle bundleForClass:[self class]]; NSString *certsPath = [bundle pathForResource:@"TestCertificates.bundle/test-certificates" ofType:@"pem"]; [GRPCCall useTestCertsPath:certsPath testName:@"foo.test.google.fr" forHost:kLocalSSLHost]; diff --git a/src/objective-c/tests/InteropTestsMultipleChannels/Info.plist b/src/objective-c/tests/InteropTestsMultipleChannels/Info.plist new file mode 100644 index 00000000000..6c40a6cd0c4 --- /dev/null +++ b/src/objective-c/tests/InteropTestsMultipleChannels/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/src/objective-c/tests/InteropTestsMultipleChannels/InteropTestsMultipleChannels.m b/src/objective-c/tests/InteropTestsMultipleChannels/InteropTestsMultipleChannels.m new file mode 100644 index 00000000000..b0d4e4883a3 --- /dev/null +++ b/src/objective-c/tests/InteropTestsMultipleChannels/InteropTestsMultipleChannels.m @@ -0,0 +1,259 @@ +/* + * + * 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. + * + */ + +#import + +#import +#import +#import +#import +#import + +#define NSStringize_helper(x) #x +#define NSStringize(x) @NSStringize_helper(x) +static NSString *const kRemoteSSLHost = NSStringize(HOST_PORT_REMOTE); +static NSString *const kLocalSSLHost = NSStringize(HOST_PORT_LOCALSSL); +static NSString *const kLocalCleartextHost = NSStringize(HOST_PORT_LOCAL); + +static const NSTimeInterval TEST_TIMEOUT = 8000; + +@interface RMTStreamingOutputCallRequest (Constructors) ++ (instancetype)messageWithPayloadSize:(NSNumber *)payloadSize + requestedResponseSize:(NSNumber *)responseSize; +@end + +@implementation RMTStreamingOutputCallRequest (Constructors) ++ (instancetype)messageWithPayloadSize:(NSNumber *)payloadSize + requestedResponseSize:(NSNumber *)responseSize { + RMTStreamingOutputCallRequest *request = [self message]; + RMTResponseParameters *parameters = [RMTResponseParameters message]; + parameters.size = responseSize.intValue; + [request.responseParametersArray addObject:parameters]; + request.payload.body = [NSMutableData dataWithLength:payloadSize.unsignedIntegerValue]; + return request; +} +@end + +@interface RMTStreamingOutputCallResponse (Constructors) ++ (instancetype)messageWithPayloadSize:(NSNumber *)payloadSize; +@end + +@implementation RMTStreamingOutputCallResponse (Constructors) ++ (instancetype)messageWithPayloadSize:(NSNumber *)payloadSize { + RMTStreamingOutputCallResponse *response = [self message]; + response.payload.type = RMTPayloadType_Compressable; + response.payload.body = [NSMutableData dataWithLength:payloadSize.unsignedIntegerValue]; + return response; +} +@end + +@interface InteropTestsMultipleChannels : XCTestCase + +@end + +dispatch_once_t initCronet; + +@implementation InteropTestsMultipleChannels { + RMTTestService *_remoteService; + RMTTestService *_remoteCronetService; + RMTTestService *_localCleartextService; + RMTTestService *_localSSLService; +} + +- (void)setUp { + [super setUp]; + + self.continueAfterFailure = NO; + + // Default stack with remote host + _remoteService = [RMTTestService serviceWithHost:kRemoteSSLHost]; + + // Cronet stack with remote host + _remoteCronetService = [RMTTestService serviceWithHost:kRemoteSSLHost]; + + dispatch_once(&initCronet, ^{ + [Cronet setHttp2Enabled:YES]; + [Cronet start]; + }); + + GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; + options.transportType = GRPCTransportTypeCronet; + options.cronetEngine = [Cronet getGlobalEngine]; + _remoteCronetService.options = options; + + // Local stack with no SSL + _localCleartextService = [RMTTestService serviceWithHost:kLocalCleartextHost]; + options = [[GRPCCallOptions alloc] init]; + options.transportType = GRPCTransportTypeInsecure; + _localCleartextService.options = options; + + // Local stack with SSL + _localSSLService = [RMTTestService serviceWithHost:kLocalSSLHost]; + + NSBundle *bundle = [NSBundle bundleForClass:[self class]]; + NSString *certsPath = + [bundle pathForResource:@"TestCertificates.bundle/test-certificates" ofType:@"pem"]; + NSError *error = nil; + NSString *certs = + [NSString stringWithContentsOfFile:certsPath encoding:NSUTF8StringEncoding error:&error]; + XCTAssertNil(error); + + options = [[GRPCCallOptions alloc] init]; + options.transportType = GRPCTransportTypeChttp2BoringSSL; + options.PEMRootCertificates = certs; + options.hostNameOverride = @"foo.test.google.fr"; + _localSSLService.options = options; +} + +- (void)testEmptyUnaryRPC { + __weak XCTestExpectation *expectRemote = [self expectationWithDescription:@"Remote RPC finish"]; + __weak XCTestExpectation *expectCronetRemote = + [self expectationWithDescription:@"Remote RPC finish"]; + __weak XCTestExpectation *expectCleartext = + [self expectationWithDescription:@"Remote RPC finish"]; + __weak XCTestExpectation *expectSSL = [self expectationWithDescription:@"Remote RPC finish"]; + + GPBEmpty *request = [GPBEmpty message]; + + void (^handler)(GPBEmpty *response, NSError *error) = ^(GPBEmpty *response, NSError *error) { + XCTAssertNil(error, @"Finished with unexpected error: %@", error); + + id expectedResponse = [GPBEmpty message]; + XCTAssertEqualObjects(response, expectedResponse); + }; + + [_remoteService emptyCallWithRequest:request + handler:^(GPBEmpty *response, NSError *error) { + handler(response, error); + [expectRemote fulfill]; + }]; + [_remoteCronetService emptyCallWithRequest:request + handler:^(GPBEmpty *response, NSError *error) { + handler(response, error); + [expectCronetRemote fulfill]; + }]; + [_localCleartextService emptyCallWithRequest:request + handler:^(GPBEmpty *response, NSError *error) { + handler(response, error); + [expectCleartext fulfill]; + }]; + [_localSSLService emptyCallWithRequest:request + handler:^(GPBEmpty *response, NSError *error) { + handler(response, error); + [expectSSL fulfill]; + }]; + + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + +- (void)testFullDuplexRPC { + __weak XCTestExpectation *expectRemote = [self expectationWithDescription:@"Remote RPC finish"]; + __weak XCTestExpectation *expectCronetRemote = + [self expectationWithDescription:@"Remote RPC finish"]; + __weak XCTestExpectation *expectCleartext = + [self expectationWithDescription:@"Remote RPC finish"]; + __weak XCTestExpectation *expectSSL = [self expectationWithDescription:@"Remote RPC finish"]; + + NSArray *requestSizes = @[ @100, @101, @102, @103 ]; + NSArray *responseSizes = @[ @104, @105, @106, @107 ]; + XCTAssertEqual([requestSizes count], [responseSizes count]); + NSUInteger kRounds = [requestSizes count]; + + NSMutableArray *requests = [NSMutableArray arrayWithCapacity:kRounds]; + NSMutableArray *responses = [NSMutableArray arrayWithCapacity:kRounds]; + for (int i = 0; i < kRounds; i++) { + requests[i] = [RMTStreamingOutputCallRequest messageWithPayloadSize:requestSizes[i] + requestedResponseSize:responseSizes[i]]; + responses[i] = [RMTStreamingOutputCallResponse messageWithPayloadSize:responseSizes[i]]; + } + + __block NSMutableArray *steps = [NSMutableArray arrayWithCapacity:4]; + __block NSMutableArray *requestsBuffers = [NSMutableArray arrayWithCapacity:4]; + for (int i = 0; i < 4; i++) { + steps[i] = [NSNumber numberWithUnsignedInteger:0]; + requestsBuffers[i] = [[GRXBufferedPipe alloc] init]; + [requestsBuffers[i] writeValue:requests[0]]; + } + + BOOL (^handler)(int, BOOL, RMTStreamingOutputCallResponse *, NSError *) = + ^(int index, BOOL done, RMTStreamingOutputCallResponse *response, NSError *error) { + XCTAssertNil(error, @"Finished with unexpected error: %@", error); + XCTAssertTrue(done || response, @"Event handler called without an event."); + if (response) { + NSUInteger step = [steps[index] unsignedIntegerValue]; + XCTAssertLessThan(step, kRounds, @"More than %lu responses received.", + (unsigned long)kRounds); + XCTAssertEqualObjects(response, responses[step]); + step++; + steps[index] = [NSNumber numberWithUnsignedInteger:step]; + GRXBufferedPipe *pipe = requestsBuffers[index]; + if (step < kRounds) { + [pipe writeValue:requests[step]]; + } else { + [pipe writesFinishedWithError:nil]; + } + } + if (done) { + NSUInteger step = [steps[index] unsignedIntegerValue]; + XCTAssertEqual(step, kRounds, @"Received %lu responses instead of %lu.", step, kRounds); + return YES; + } + return NO; + }; + + [_remoteService + fullDuplexCallWithRequestsWriter:requestsBuffers[0] + eventHandler:^(BOOL done, + RMTStreamingOutputCallResponse *_Nullable response, + NSError *_Nullable error) { + if (handler(0, done, response, error)) { + [expectRemote fulfill]; + } + }]; + [_remoteCronetService + fullDuplexCallWithRequestsWriter:requestsBuffers[1] + eventHandler:^(BOOL done, + RMTStreamingOutputCallResponse *_Nullable response, + NSError *_Nullable error) { + if (handler(1, done, response, error)) { + [expectCronetRemote fulfill]; + } + }]; + [_localCleartextService + fullDuplexCallWithRequestsWriter:requestsBuffers[2] + eventHandler:^(BOOL done, + RMTStreamingOutputCallResponse *_Nullable response, + NSError *_Nullable error) { + if (handler(2, done, response, error)) { + [expectCleartext fulfill]; + } + }]; + [_localSSLService + fullDuplexCallWithRequestsWriter:requestsBuffers[3] + eventHandler:^(BOOL done, + RMTStreamingOutputCallResponse *_Nullable response, + NSError *_Nullable error) { + if (handler(3, done, response, error)) { + [expectSSL fulfill]; + } + }]; + + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + +@end diff --git a/src/objective-c/tests/InteropTestsRemote.m b/src/objective-c/tests/InteropTestsRemote.m index e5738aac73b..c1cd9b81efc 100644 --- a/src/objective-c/tests/InteropTestsRemote.m +++ b/src/objective-c/tests/InteropTestsRemote.m @@ -41,8 +41,26 @@ static int32_t kRemoteInteropServerOverhead = 12; return kRemoteSSLHost; } ++ (NSString *)PEMRootCertificates { + return nil; +} + ++ (NSString *)hostNameOverride { + return nil; +} + - (int32_t)encodingOverhead { return kRemoteInteropServerOverhead; // bytes } +#ifdef GRPC_COMPILE_WITH_CRONET ++ (GRPCTransportType)transportType { + return GRPCTransportTypeCronet; +} +#else ++ (GRPCTransportType)transportType { + return GRPCTransportTypeChttp2BoringSSL; +} +#endif + @end diff --git a/src/objective-c/tests/MacTests/Info.plist b/src/objective-c/tests/MacTests/Info.plist new file mode 100644 index 00000000000..6c40a6cd0c4 --- /dev/null +++ b/src/objective-c/tests/MacTests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/src/objective-c/tests/MacTests/StressTests.h b/src/objective-c/tests/MacTests/StressTests.h new file mode 100644 index 00000000000..8bee0e66274 --- /dev/null +++ b/src/objective-c/tests/MacTests/StressTests.h @@ -0,0 +1,56 @@ +/* + * + * Copyright 2019 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. + * + */ + +#import + +#import + +@interface StressTests : XCTestCase +/** + * Host to send the RPCs to. The base implementation returns nil, which would make all tests to + * fail. + * Override in a subclass to perform these tests against a specific address. + */ ++ (NSString *)host; + +/** + * Bytes of overhead of test proto responses due to encoding. This is used to excercise the behavior + * when responses are just above or below the max response size. For some reason, the local and + * remote servers enconde responses with different overhead (?), so this is defined per-subclass. + */ +- (int32_t)encodingOverhead; + +/** + * The type of transport to be used. The base implementation returns default. Subclasses should + * override to appropriate settings. + */ ++ (GRPCTransportType)transportType; + +/** + * The root certificates to be used. The base implementation returns nil. Subclasses should override + * to appropriate settings. + */ ++ (NSString *)PEMRootCertificates; + +/** + * The root certificates to be used. The base implementation returns nil. Subclasses should override + * to appropriate settings. + */ ++ (NSString *)hostNameOverride; + +@end diff --git a/src/objective-c/tests/MacTests/StressTests.m b/src/objective-c/tests/MacTests/StressTests.m new file mode 100644 index 00000000000..22174b58665 --- /dev/null +++ b/src/objective-c/tests/MacTests/StressTests.m @@ -0,0 +1,237 @@ +/* + * + * Copyright 2019 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 "StressTests.h" + +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import + +#define TEST_TIMEOUT 32 + +extern const char *kCFStreamVarName; + +// Convenience class to use blocks as callbacks +@interface MacTestsBlockCallbacks : NSObject + +- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback + messageCallback:(void (^)(id))messageCallback + closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback; + +@end + +@implementation MacTestsBlockCallbacks { + void (^_initialMetadataCallback)(NSDictionary *); + void (^_messageCallback)(id); + void (^_closeCallback)(NSDictionary *, NSError *); + dispatch_queue_t _dispatchQueue; +} + +- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback + messageCallback:(void (^)(id))messageCallback + closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback { + if ((self = [super init])) { + _initialMetadataCallback = initialMetadataCallback; + _messageCallback = messageCallback; + _closeCallback = closeCallback; + _dispatchQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL); + } + return self; +} + +- (void)didReceiveInitialMetadata:(NSDictionary *)initialMetadata { + if (_initialMetadataCallback) { + _initialMetadataCallback(initialMetadata); + } +} + +- (void)didReceiveProtoMessage:(GPBMessage *)message { + if (_messageCallback) { + _messageCallback(message); + } +} + +- (void)didCloseWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { + if (_closeCallback) { + _closeCallback(trailingMetadata, error); + } +} + +- (dispatch_queue_t)dispatchQueue { + return _dispatchQueue; +} + +@end + +@implementation StressTests { + RMTTestService *_service; +} + ++ (NSString *)host { + return nil; +} + ++ (NSString *)hostAddress { + return nil; +} + ++ (NSString *)PEMRootCertificates { + return nil; +} + ++ (NSString *)hostNameOverride { + return nil; +} + +- (int32_t)encodingOverhead { + return 0; +} + ++ (void)setUp { + setenv(kCFStreamVarName, "1", 1); +} + +- (void)setUp { + self.continueAfterFailure = NO; + + [GRPCCall resetHostSettings]; + + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = [[self class] transportType]; + options.PEMRootCertificates = [[self class] PEMRootCertificates]; + options.hostNameOverride = [[self class] hostNameOverride]; + _service = [RMTTestService serviceWithHost:[[self class] host] callOptions:options]; + system([[NSString stringWithFormat:@"sudo ifconfig lo0 alias %@", [[self class] hostAddress]] + UTF8String]); +} + +- (void)tearDown { + system([[NSString stringWithFormat:@"sudo ifconfig lo0 -alias %@", [[self class] hostAddress]] + UTF8String]); +} + ++ (GRPCTransportType)transportType { + return GRPCTransportTypeChttp2BoringSSL; +} + +- (void)testNetworkFlapWithV2API { + NSMutableArray *completeExpectations = [NSMutableArray array]; + NSMutableArray *calls = [NSMutableArray array]; + int num_rpcs = 100; + __block BOOL address_removed = FALSE; + __block BOOL address_readded = FALSE; + for (int i = 0; i < num_rpcs; ++i) { + [completeExpectations + addObject:[self expectationWithDescription: + [NSString stringWithFormat:@"Received trailer for RPC %d", i]]]; + + RMTSimpleRequest *request = [RMTSimpleRequest message]; + request.responseType = RMTPayloadType_Compressable; + request.responseSize = 314159; + request.payload.body = [NSMutableData dataWithLength:271828]; + + GRPCUnaryProtoCall *call = [_service + unaryCallWithMessage:request + responseHandler:[[MacTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:^(id message) { + if (message) { + RMTSimpleResponse *expectedResponse = + [RMTSimpleResponse message]; + expectedResponse.payload.type = RMTPayloadType_Compressable; + expectedResponse.payload.body = + [NSMutableData dataWithLength:314159]; + XCTAssertEqualObjects(message, expectedResponse); + } + } + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + + @synchronized(self) { + if (error == nil && !address_removed) { + system([[NSString + stringWithFormat:@"sudo ifconfig lo0 -alias %@", + [[self class] hostAddress]] + UTF8String]); + address_removed = YES; + } else if (error != nil && !address_readded) { + system([ + [NSString stringWithFormat:@"sudo ifconfig lo0 alias %@", + [[self class] hostAddress]] + UTF8String]); + address_readded = YES; + } + } + [completeExpectations[i] fulfill]; + }] + callOptions:nil]; + [calls addObject:call]; + } + + for (int i = 0; i < num_rpcs; ++i) { + GRPCUnaryProtoCall *call = calls[i]; + [call start]; + [NSThread sleepForTimeInterval:0.1f]; + } + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + +- (void)testNetworkFlapWithV1API { + NSMutableArray *completeExpectations = [NSMutableArray array]; + int num_rpcs = 100; + __block BOOL address_removed = FALSE; + __block BOOL address_readded = FALSE; + for (int i = 0; i < num_rpcs; ++i) { + [completeExpectations + addObject:[self expectationWithDescription: + [NSString stringWithFormat:@"Received response for RPC %d", i]]]; + + RMTSimpleRequest *request = [RMTSimpleRequest message]; + request.responseType = RMTPayloadType_Compressable; + request.responseSize = 314159; + request.payload.body = [NSMutableData dataWithLength:271828]; + + [_service unaryCallWithRequest:request + handler:^(RMTSimpleResponse *response, NSError *error) { + @synchronized(self) { + if (error == nil && !address_removed) { + system([[NSString stringWithFormat:@"sudo ifconfig lo0 -alias %@", + [[self class] hostAddress]] + UTF8String]); + address_removed = YES; + } else if (error != nil && !address_readded) { + system([[NSString stringWithFormat:@"sudo ifconfig lo0 alias %@", + [[self class] hostAddress]] + UTF8String]); + address_readded = YES; + } + } + + [completeExpectations[i] fulfill]; + }]; + + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; + } +} + +@end diff --git a/src/objective-c/tests/MacTests/StressTestsCleartext.m b/src/objective-c/tests/MacTests/StressTestsCleartext.m new file mode 100644 index 00000000000..2b3a8614705 --- /dev/null +++ b/src/objective-c/tests/MacTests/StressTestsCleartext.m @@ -0,0 +1,68 @@ + +/* + * + * Copyright 2019 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. + * + */ + +#import +#import + +#import "StressTests.h" + +static NSString *const kHostAddress = @"10.0.0.1"; + +// The Protocol Buffers encoding overhead of local interop server. Acquired +// by experiment. Adjust this when server's proto file changes. +static int32_t kLocalInteropServerOverhead = 10; + +/** Tests in InteropTests.m, sending the RPCs to a local cleartext server. */ +@interface StressTestsCleartext : StressTests +@end + +@implementation StressTestsCleartext + ++ (NSString *)host { + return [NSString stringWithFormat:@"%@:5050", kHostAddress]; +} + ++ (NSString *)hostAddress { + return kHostAddress; +} + ++ (NSString *)PEMRootCertificates { + return nil; +} + ++ (NSString *)hostNameOverride { + return nil; +} + +- (int32_t)encodingOverhead { + return kLocalInteropServerOverhead; // bytes +} + +- (void)setUp { + [super setUp]; + + // Register test server as non-SSL. + [GRPCCall useInsecureConnectionsForHost:[[self class] host]]; +} + ++ (GRPCTransportType)transportType { + return GRPCTransportTypeInsecure; +} + +@end diff --git a/src/objective-c/tests/MacTests/StressTestsSSL.m b/src/objective-c/tests/MacTests/StressTestsSSL.m new file mode 100644 index 00000000000..c5d79fe0ae8 --- /dev/null +++ b/src/objective-c/tests/MacTests/StressTestsSSL.m @@ -0,0 +1,71 @@ +/* + * + * Copyright 2019 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. + * + */ + +#import +#import + +#include "StressTests.h" + +static NSString *const kHostAddress = @"10.0.0.1"; +// The Protocol Buffers encoding overhead of local interop server. Acquired +// by experiment. Adjust this when server's proto file changes. +static int32_t kLocalInteropServerOverhead = 10; + +@interface StressTestsSSL : StressTests +@end + +@implementation StressTestsSSL + ++ (NSString *)host { + return [NSString stringWithFormat:@"%@:5051", kHostAddress]; +} + ++ (NSString *)hostAddress { + return kHostAddress; +} + ++ (NSString *)PEMRootCertificates { + NSBundle *bundle = [NSBundle bundleForClass:[self class]]; + NSString *certsPath = + [bundle pathForResource:@"TestCertificates.bundle/test-certificates" ofType:@"pem"]; + NSError *error; + return [NSString stringWithContentsOfFile:certsPath encoding:NSUTF8StringEncoding error:&error]; +} + ++ (NSString *)hostNameOverride { + return @"foo.test.google.fr"; +} + +- (int32_t)encodingOverhead { + return kLocalInteropServerOverhead; // bytes +} + ++ (GRPCTransportType)transportType { + return GRPCTransportTypeChttp2BoringSSL; +} + +- (void)setUp { + [super setUp]; + + // Register test server certificates and name. + NSBundle *bundle = [NSBundle bundleForClass:[self class]]; + NSString *certsPath = + [bundle pathForResource:@"TestCertificates.bundle/test-certificates" ofType:@"pem"]; + [GRPCCall useTestCertsPath:certsPath testName:@"foo.test.google.fr" forHost:[[self class] host]]; +} +@end diff --git a/src/objective-c/tests/Podfile b/src/objective-c/tests/Podfile index 5d2f1340daa..34ed6680195 100644 --- a/src/objective-c/tests/Podfile +++ b/src/objective-c/tests/Podfile @@ -1,5 +1,4 @@ source 'https://github.com/CocoaPods/Specs.git' -platform :ios, '8.0' install! 'cocoapods', :deterministic_uuids => false @@ -14,9 +13,16 @@ GRPC_LOCAL_SRC = '../../..' InteropTestsLocalSSL InteropTestsLocalCleartext InteropTestsRemoteWithCronet + InteropTestsMultipleChannels + InteropTestsCallOptions UnitTests + InteropTestsRemoteCFStream + InteropTestsLocalSSLCFStream + InteropTestsLocalCleartextCFStream + APIv2Tests ).each do |target_name| target target_name do + platform :ios, '8.0' pod 'Protobuf', :path => "#{GRPC_LOCAL_SRC}/third_party/protobuf", :inhibit_warnings => true pod '!ProtoCompiler', :path => "#{GRPC_LOCAL_SRC}/src/objective-c" @@ -30,32 +36,27 @@ GRPC_LOCAL_SRC = '../../..' pod 'gRPC-ProtoRPC', :path => GRPC_LOCAL_SRC, :inhibit_warnings => true pod 'RemoteTest', :path => "RemoteTestClient", :inhibit_warnings => true - if target_name == 'InteropTestsRemoteWithCronet' + if target_name == 'InteropTestsRemoteWithCronet' or target_name == 'InteropTestsMultipleChannels' pod 'gRPC-Core/Cronet-Implementation', :path => GRPC_LOCAL_SRC pod 'CronetFramework', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c" end end end -%w( - InteropTestsRemoteCFStream - InteropTestsLocalSSLCFStream - InteropTestsLocalCleartextCFStream -).each do |target_name| - target target_name do - pod 'Protobuf', :path => "#{GRPC_LOCAL_SRC}/third_party/protobuf", :inhibit_warnings => true +target 'MacTests' do + platform :osx, '10.13' + pod 'Protobuf', :path => "#{GRPC_LOCAL_SRC}/third_party/protobuf", :inhibit_warnings => true - pod '!ProtoCompiler', :path => "#{GRPC_LOCAL_SRC}/src/objective-c" - pod '!ProtoCompiler-gRPCPlugin', :path => "#{GRPC_LOCAL_SRC}/src/objective-c" + pod '!ProtoCompiler', :path => "#{GRPC_LOCAL_SRC}/src/objective-c" + pod '!ProtoCompiler-gRPCPlugin', :path => "#{GRPC_LOCAL_SRC}/src/objective-c" - pod 'BoringSSL-GRPC', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c", :inhibit_warnings => true + pod 'BoringSSL-GRPC', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c", :inhibit_warnings => true - pod 'gRPC/CFStream', :path => GRPC_LOCAL_SRC - pod 'gRPC-Core/CFStream-Implementation', :path => GRPC_LOCAL_SRC - pod 'gRPC-RxLibrary', :path => GRPC_LOCAL_SRC - pod 'gRPC-ProtoRPC', :path => GRPC_LOCAL_SRC, :inhibit_warnings => true - pod 'RemoteTest', :path => "RemoteTestClient", :inhibit_warnings => true - end + 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, :inhibit_warnings => true + pod 'RemoteTest', :path => "RemoteTestClient", :inhibit_warnings => true end %w( @@ -63,6 +64,7 @@ end CronetUnitTests ).each do |target_name| target target_name do + platform :ios, '8.0' pod 'BoringSSL-GRPC', :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 @@ -72,6 +74,13 @@ end end end +target 'ChannelTests' do + platform :ios, '8.0' + pod 'gRPC', :path => GRPC_LOCAL_SRC + pod 'gRPC-Core', :path => GRPC_LOCAL_SRC + pod 'BoringSSL-GRPC', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c", :inhibit_warnings => true +end + # gRPC-Core.podspec needs to be modified to be successfully used for local development. A Podfile's # pre_install hook lets us do that. The block passed to it runs after the podspecs are downloaded # and before they are installed in the user project. @@ -118,11 +127,7 @@ post_install do |installer| # GPR_UNREACHABLE_CODE causes "Control may reach end of non-void # function" warning config.build_settings['GCC_WARN_ABOUT_RETURN_TYPE'] = 'NO' - if target.name.include?('CFStream') - config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] = '$(inherited) COCOAPODS=1 GRPC_CFSTREAM=1' - else - config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] = '$(inherited) COCOAPODS=1 GRPC_CRONET_WITH_PACKET_COALESCING=1' - end + config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] = '$(inherited) COCOAPODS=1 GRPC_CRONET_WITH_PACKET_COALESCING=1 GRPC_CFSTREAM=1' end end @@ -130,7 +135,7 @@ post_install do |installer| # the test target 'InteropTestsRemoteWithCronet' # Activate GRPCCall+InternalTests functions for the dedicated build configuration 'Test', which will # be used by all test targets using it. - if target.name == 'gRPC' || target.name.start_with?('gRPC.') + if /gRPC-(mac|i)OS/.match(target.name) target.build_configurations.each do |config| if config.name == 'Cronet' config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] = '$(inherited) COCOAPODS=1 GRPC_COMPILE_WITH_CRONET=1 GRPC_TEST_OBJC=1' @@ -139,5 +144,14 @@ post_install do |installer| end end end + + # Enable NSAssert on gRPC + if /(gRPC|ProtoRPC|RxLibrary)-(mac|i)OS/.match(target.name) + target.build_configurations.each do |config| + if config.name != 'Release' + config.build_settings['ENABLE_NS_ASSERTIONS'] = 'YES' + end + end + end end end diff --git a/src/objective-c/tests/RemoteTestClient/RemoteTest.podspec b/src/objective-c/tests/RemoteTestClient/RemoteTest.podspec index ad834815951..93b56d56059 100644 --- a/src/objective-c/tests/RemoteTestClient/RemoteTest.podspec +++ b/src/objective-c/tests/RemoteTestClient/RemoteTest.podspec @@ -14,20 +14,34 @@ Pod::Spec.new do |s| s.dependency "!ProtoCompiler-gRPCPlugin" repo_root = '../../../..' - bin_dir = "#{repo_root}/bins/$CONFIG" + config = ENV['CONFIG'] || 'opt' + bin_dir = "#{repo_root}/bins/#{config}" protoc = "#{bin_dir}/protobuf/protoc" well_known_types_dir = "#{repo_root}/third_party/protobuf/src" plugin = "#{bin_dir}/grpc_objective_c_plugin" s.prepare_command = <<-CMD - #{protoc} \ - --plugin=protoc-gen-grpc=#{plugin} \ - --objc_out=. \ - --grpc_out=. \ - -I . \ - -I #{well_known_types_dir} \ - *.proto + if [ -f #{protoc} ]; then + #{protoc} \ + --plugin=protoc-gen-grpc=#{plugin} \ + --objc_out=. \ + --grpc_out=. \ + -I . \ + -I #{well_known_types_dir} \ + *.proto + else + # protoc was not found bin_dir, use installed version instead + (>&2 echo "\nWARNING: Using installed version of protoc. It might be incompatible with gRPC") + + protoc \ + --plugin=protoc-gen-grpc=#{plugin} \ + --objc_out=. \ + --grpc_out=. \ + -I . \ + -I #{well_known_types_dir} \ + *.proto + fi CMD s.subspec "Messages" do |ms| diff --git a/src/objective-c/tests/RxLibraryUnitTests.m b/src/objective-c/tests/RxLibraryUnitTests.m index ecd914c9b5f..2faf57ef938 100644 --- a/src/objective-c/tests/RxLibraryUnitTests.m +++ b/src/objective-c/tests/RxLibraryUnitTests.m @@ -16,7 +16,6 @@ * */ -#import #import #import @@ -44,9 +43,9 @@ - (GRXSingleHandler)block { return ^(id value, NSError *errorOrNil) { - ++_timesCalled; - _value = value; - _errorOrNil = errorOrNil; + ++self->_timesCalled; + self->_value = value; + self->_errorOrNil = errorOrNil; }; } @end diff --git a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj index f0d81232635..27a617c83b4 100644 --- a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj +++ b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj @@ -11,14 +11,24 @@ 09B76D9585ACE7403804D9DC /* libPods-InteropTestsRemoteWithCronet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 9E9444C764F0FFF64A7EB58E /* libPods-InteropTestsRemoteWithCronet.a */; }; 0F9232F984C08643FD40C34F /* libPods-InteropTestsRemote.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DBE059B4AC7A51919467EEC0 /* libPods-InteropTestsRemote.a */; }; 16A9E77B6E336B3C0B9BA6E0 /* libPods-InteropTestsLocalSSL.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DBEDE45BDA60DF1E1C8950C0 /* libPods-InteropTestsLocalSSL.a */; }; + 1A0FB7F8C95A2F82538BC950 /* libPods-ChannelTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 48F1841C9A920626995DC28C /* libPods-ChannelTests.a */; }; 20DFDF829DD993A4A00D5662 /* libPods-RxLibraryUnitTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A58BE6DF1C62D1739EBB2C78 /* libPods-RxLibraryUnitTests.a */; }; 333E8FC01C8285B7C547D799 /* libPods-InteropTestsLocalCleartext.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FD346DB2C23F676C4842F3FF /* libPods-InteropTestsLocalCleartext.a */; }; 5E0282E9215AA697007AC99D /* UnitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E0282E8215AA697007AC99D /* UnitTests.m */; }; 5E0282EB215AA697007AC99D /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; }; + 5E3B95A521CAC6C500C0A151 /* APIv2Tests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E3B95A421CAC6C500C0A151 /* APIv2Tests.m */; }; + 5E7D71AD210954A8001EA6BA /* TestCertificates.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 63E240CF1B6C63DC005F3B0E /* TestCertificates.bundle */; }; + 5E7D71B5210B9EC9001EA6BA /* InteropTestsCallOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E7D71B4210B9EC9001EA6BA /* InteropTestsCallOptions.m */; }; + 5E7D71B7210B9EC9001EA6BA /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; }; 5E8A5DA71D3840B4000F8BC4 /* CoreCronetEnd2EndTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5E8A5DA61D3840B4000F8BC4 /* CoreCronetEnd2EndTests.mm */; }; 5E8A5DA91D3840B4000F8BC4 /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; }; 5EAD6D271E27047400002378 /* CronetUnitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EAD6D261E27047400002378 /* CronetUnitTests.m */; }; 5EAD6D291E27047400002378 /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; }; + 5EB2A2E72107DED300EB4B69 /* ChannelTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EB2A2E62107DED300EB4B69 /* ChannelTests.m */; }; + 5EB2A2E92107DED300EB4B69 /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; }; + 5EB2A2F82109284500EB4B69 /* InteropTestsMultipleChannels.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EB2A2F72109284500EB4B69 /* InteropTestsMultipleChannels.m */; }; + 5EB2A2FA2109284500EB4B69 /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; }; + 5EB5C3AA21656CEA00ADC300 /* ChannelPoolTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EB5C3A921656CEA00ADC300 /* ChannelPoolTest.m */; }; 5EC5E42B2081782C000EF4AD /* InteropTestsRemote.m in Sources */ = {isa = PBXBuildFile; fileRef = 6379CC4F1BE16703001BC0A1 /* InteropTestsRemote.m */; }; 5EC5E42C20817832000EF4AD /* InteropTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 635ED2EB1B1A3BC400FDE5C3 /* InteropTests.m */; }; 5EC5E43B208185A7000EF4AD /* InteropTestsLocalCleartext.m in Sources */ = {isa = PBXBuildFile; fileRef = 63715F551B780C020029CB0B /* InteropTestsLocalCleartext.m */; }; @@ -53,7 +63,23 @@ 63DC84501BE153AA000708E8 /* GRPCClientTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6312AE4D1B1BF49B00341DEE /* GRPCClientTests.m */; }; 63E240CE1B6C4E2B005F3B0E /* InteropTestsLocalSSL.m in Sources */ = {isa = PBXBuildFile; fileRef = 63E240CD1B6C4E2B005F3B0E /* InteropTestsLocalSSL.m */; }; 63E240D01B6C63DC005F3B0E /* TestCertificates.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 63E240CF1B6C63DC005F3B0E /* TestCertificates.bundle */; }; + 6C1A3F81CCF7C998B4813EFD /* libPods-InteropTestsCallOptions.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AF3FC2CFFE7B0961823BC740 /* libPods-InteropTestsCallOptions.a */; }; + 886717A79EFF774F356798E6 /* libPods-InteropTestsMultipleChannels.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 355D0E30AD224763BC9519F4 /* libPods-InteropTestsMultipleChannels.a */; }; 91D4B3C85B6D8562F409CB48 /* libPods-InteropTestsLocalSSLCFStream.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F3AB031E0E26AC8EF30A2A2A /* libPods-InteropTestsLocalSSLCFStream.a */; }; + 953CD2942A3A6D6CE695BE87 /* libPods-MacTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 276873A05AC5479B60DF6079 /* libPods-MacTests.a */; }; + 98478C9F42329DF769A45B6C /* libPods-APIv2Tests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B6AD69CACF67505B0F028E92 /* libPods-APIv2Tests.a */; }; + B071230B22669EED004B64A1 /* StressTests.m in Sources */ = {isa = PBXBuildFile; fileRef = B071230A22669EED004B64A1 /* StressTests.m */; }; + B0BB3F02225E7A3C008DA580 /* InteropTestsLocalSSL.m in Sources */ = {isa = PBXBuildFile; fileRef = 63E240CD1B6C4E2B005F3B0E /* InteropTestsLocalSSL.m */; }; + B0BB3F03225E7A44008DA580 /* InteropTestsLocalCleartext.m in Sources */ = {isa = PBXBuildFile; fileRef = 63715F551B780C020029CB0B /* InteropTestsLocalCleartext.m */; }; + B0BB3F04225E7A8D008DA580 /* RxLibraryUnitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 63423F501B151B77006CF63C /* RxLibraryUnitTests.m */; }; + B0BB3F05225E7A9F008DA580 /* InteropTestsRemote.m in Sources */ = {isa = PBXBuildFile; fileRef = 6379CC4F1BE16703001BC0A1 /* InteropTestsRemote.m */; }; + B0BB3F06225E7AAD008DA580 /* GRPCClientTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6312AE4D1B1BF49B00341DEE /* GRPCClientTests.m */; }; + B0BB3F07225E7AB5008DA580 /* APIv2Tests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E3B95A421CAC6C500C0A151 /* APIv2Tests.m */; }; + B0BB3F08225E7ABA008DA580 /* UnitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E0282E8215AA697007AC99D /* UnitTests.m */; }; + B0BB3F0A225EA511008DA580 /* TestCertificates.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 63E240CF1B6C63DC005F3B0E /* TestCertificates.bundle */; }; + B0BB3F0B225EB110008DA580 /* InteropTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 635ED2EB1B1A3BC400FDE5C3 /* InteropTests.m */; }; + B0D39B9A2266F3CB00A4078D /* StressTestsSSL.m in Sources */ = {isa = PBXBuildFile; fileRef = B0D39B992266F3CB00A4078D /* StressTestsSSL.m */; }; + B0D39B9C2266FF9800A4078D /* StressTestsCleartext.m in Sources */ = {isa = PBXBuildFile; fileRef = B0D39B9B2266FF9800A4078D /* StressTestsCleartext.m */; }; BC111C80CBF7068B62869352 /* libPods-InteropTestsRemoteCFStream.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F44AC3F44E3491A8C0D890FE /* libPods-InteropTestsRemoteCFStream.a */; }; C3D6F4270A2FFF634D8849ED /* libPods-InteropTestsLocalCleartextCFStream.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 0BDA4BA011779D5D25B5618C /* libPods-InteropTestsLocalCleartextCFStream.a */; }; CCF5C0719EF608276AE16374 /* libPods-UnitTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 22A3EBB488699C8CEA19707B /* libPods-UnitTests.a */; }; @@ -68,6 +94,13 @@ remoteGlobalIDString = 635697C61B14FC11007A7283; remoteInfo = Tests; }; + 5E7D71B8210B9EC9001EA6BA /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 635697BF1B14FC11007A7283 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 635697C61B14FC11007A7283; + remoteInfo = Tests; + }; 5E8A5DAA1D3840B4000F8BC4 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 635697BF1B14FC11007A7283 /* Project object */; @@ -82,6 +115,20 @@ remoteGlobalIDString = 635697C61B14FC11007A7283; remoteInfo = Tests; }; + 5EB2A2EA2107DED300EB4B69 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 635697BF1B14FC11007A7283 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 635697C61B14FC11007A7283; + remoteInfo = Tests; + }; + 5EB2A2FB2109284500EB4B69 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 635697BF1B14FC11007A7283 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 635697C61B14FC11007A7283; + remoteInfo = Tests; + }; 5EE84BF71D4717E40050C6CC /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 635697BF1B14FC11007A7283 /* Project object */; @@ -144,24 +191,37 @@ 0A4F89D9C90E9C30990218F0 /* Pods.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.release.xcconfig; path = "Pods/Target Support Files/Pods/Pods.release.xcconfig"; sourceTree = ""; }; 0BDA4BA011779D5D25B5618C /* libPods-InteropTestsLocalCleartextCFStream.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-InteropTestsLocalCleartextCFStream.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 0D2284C3DF7E57F0ED504E39 /* Pods-CoreCronetEnd2EndTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CoreCronetEnd2EndTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests.debug.xcconfig"; sourceTree = ""; }; + 1286B30AD74CB64CD91FB17D /* Pods-APIv2Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-APIv2Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-APIv2Tests/Pods-APIv2Tests.debug.xcconfig"; sourceTree = ""; }; + 1295CCBD1082B4A7CFCED95F /* Pods-InteropTestsMultipleChannels.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsMultipleChannels.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsMultipleChannels/Pods-InteropTestsMultipleChannels.cronet.xcconfig"; sourceTree = ""; }; + 12B238CD1702393C2BA5DE80 /* Pods-APIv2Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-APIv2Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-APIv2Tests/Pods-APIv2Tests.release.xcconfig"; sourceTree = ""; }; 14B09A58FEE53A7A6B838920 /* Pods-InteropTestsLocalSSL.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalSSL.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL.cronet.xcconfig"; sourceTree = ""; }; 1588C85DEAF7FC0ACDEA4C02 /* Pods-InteropTestsLocalCleartext.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartext.test.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartext/Pods-InteropTestsLocalCleartext.test.xcconfig"; sourceTree = ""; }; + 16A2E4C5839C83FBDA63881F /* Pods-MacTests.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MacTests.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-MacTests/Pods-MacTests.cronet.xcconfig"; sourceTree = ""; }; 17F60BF2871F6AF85FB3FA12 /* Pods-InteropTestsRemoteWithCronet.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemoteWithCronet.debug.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemoteWithCronet/Pods-InteropTestsRemoteWithCronet.debug.xcconfig"; sourceTree = ""; }; + 1E43EAE443CBB4482B1EB071 /* Pods-MacTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MacTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-MacTests/Pods-MacTests.release.xcconfig"; sourceTree = ""; }; + 1F5E788FBF9A4A06EB9E1ACD /* Pods-MacTests.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MacTests.test.xcconfig"; path = "Pods/Target Support Files/Pods-MacTests/Pods-MacTests.test.xcconfig"; sourceTree = ""; }; 20DFF2F3C97EF098FE5A3171 /* libPods-Tests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Tests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 22A3EBB488699C8CEA19707B /* libPods-UnitTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-UnitTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 2650FEF00956E7924772F9D9 /* Pods-InteropTestsMultipleChannels.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsMultipleChannels.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsMultipleChannels/Pods-InteropTestsMultipleChannels.release.xcconfig"; sourceTree = ""; }; + 276873A05AC5479B60DF6079 /* libPods-MacTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-MacTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 2B89F3037963E6EDDD48D8C3 /* Pods-InteropTestsRemoteWithCronet.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemoteWithCronet.test.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemoteWithCronet/Pods-InteropTestsRemoteWithCronet.test.xcconfig"; sourceTree = ""; }; 303F4A17EB1650FC44603D17 /* Pods-InteropTestsRemoteCFStream.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemoteCFStream.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemoteCFStream/Pods-InteropTestsRemoteCFStream.release.xcconfig"; sourceTree = ""; }; 32748C4078AEB05F8F954361 /* Pods-InteropTestsRemoteCFStream.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemoteCFStream.debug.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemoteCFStream/Pods-InteropTestsRemoteCFStream.debug.xcconfig"; sourceTree = ""; }; + 355D0E30AD224763BC9519F4 /* libPods-InteropTestsMultipleChannels.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-InteropTestsMultipleChannels.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 35F2B6BF3BAE8F0DC4AFD76E /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; }; 386712AEACF7C2190C4B8B3F /* Pods-CronetUnitTests.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CronetUnitTests.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-CronetUnitTests/Pods-CronetUnitTests.cronet.xcconfig"; sourceTree = ""; }; + 3A98DF08852F60AF1D96481D /* Pods-InteropTestsCallOptions.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsCallOptions.debug.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsCallOptions/Pods-InteropTestsCallOptions.debug.xcconfig"; sourceTree = ""; }; 3B0861FC805389C52DB260D4 /* Pods-RxLibraryUnitTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RxLibraryUnitTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-RxLibraryUnitTests/Pods-RxLibraryUnitTests.release.xcconfig"; sourceTree = ""; }; + 3CADF86203B9D03EA96C359D /* Pods-InteropTestsMultipleChannels.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsMultipleChannels.debug.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsMultipleChannels/Pods-InteropTestsMultipleChannels.debug.xcconfig"; sourceTree = ""; }; 3EB55EF291706E3DDE23C3B7 /* Pods-InteropTestsLocalSSLCFStream.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalSSLCFStream.debug.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalSSLCFStream/Pods-InteropTestsLocalSSLCFStream.debug.xcconfig"; sourceTree = ""; }; 3F27B2E744482771EB93C394 /* Pods-InteropTestsRemoteWithCronet.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemoteWithCronet.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemoteWithCronet/Pods-InteropTestsRemoteWithCronet.cronet.xcconfig"; sourceTree = ""; }; 41AA59529240A6BBBD3DB904 /* Pods-InteropTestsLocalSSLCFStream.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalSSLCFStream.test.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalSSLCFStream/Pods-InteropTestsLocalSSLCFStream.test.xcconfig"; sourceTree = ""; }; + 48F1841C9A920626995DC28C /* libPods-ChannelTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ChannelTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 4A1A42B2E941CCD453489E5B /* Pods-InteropTestsRemoteCFStream.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemoteCFStream.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemoteCFStream/Pods-InteropTestsRemoteCFStream.cronet.xcconfig"; sourceTree = ""; }; 4AD97096D13D7416DC91A72A /* Pods-CoreCronetEnd2EndTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CoreCronetEnd2EndTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests.release.xcconfig"; sourceTree = ""; }; 4ADEA1C8BBE10D90940AC68E /* Pods-InteropTestsRemote.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemote.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemote/Pods-InteropTestsRemote.cronet.xcconfig"; sourceTree = ""; }; 51A275E86C141416ED63FF76 /* Pods-InteropTestsLocalCleartext.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartext.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartext/Pods-InteropTestsLocalCleartext.release.xcconfig"; sourceTree = ""; }; + 51F2A64B7AADBA1B225B132E /* Pods-APIv2Tests.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-APIv2Tests.test.xcconfig"; path = "Pods/Target Support Files/Pods-APIv2Tests/Pods-APIv2Tests.test.xcconfig"; sourceTree = ""; }; 553BBBED24E4162D1F769D65 /* Pods-InteropTestsLocalSSL.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalSSL.debug.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL.debug.xcconfig"; sourceTree = ""; }; 55B630C1FF8C36D1EFC4E0A4 /* Pods-InteropTestsLocalSSLCFStream.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalSSLCFStream.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalSSLCFStream/Pods-InteropTestsLocalSSLCFStream.cronet.xcconfig"; sourceTree = ""; }; 573450F334B331D0BED8B961 /* Pods-CoreCronetEnd2EndTests.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CoreCronetEnd2EndTests.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests.cronet.xcconfig"; sourceTree = ""; }; @@ -169,6 +229,12 @@ 5E0282E6215AA697007AC99D /* UnitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = UnitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 5E0282E8215AA697007AC99D /* UnitTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = UnitTests.m; sourceTree = ""; }; 5E0282EA215AA697007AC99D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 5E3B95A221CAC6C500C0A151 /* APIv2Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = APIv2Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 5E3B95A421CAC6C500C0A151 /* APIv2Tests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = APIv2Tests.m; sourceTree = ""; }; + 5E3B95A621CAC6C500C0A151 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 5E7D71B2210B9EC8001EA6BA /* InteropTestsCallOptions.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = InteropTestsCallOptions.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 5E7D71B4210B9EC9001EA6BA /* InteropTestsCallOptions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = InteropTestsCallOptions.m; sourceTree = ""; }; + 5E7D71B6210B9EC9001EA6BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 5E8A5DA41D3840B4000F8BC4 /* CoreCronetEnd2EndTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CoreCronetEnd2EndTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 5E8A5DA61D3840B4000F8BC4 /* CoreCronetEnd2EndTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = CoreCronetEnd2EndTests.mm; sourceTree = ""; }; 5EA908CF4CDA4CE218352A06 /* Pods-InteropTestsLocalSSLCFStream.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalSSLCFStream.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalSSLCFStream/Pods-InteropTestsLocalSSLCFStream.release.xcconfig"; sourceTree = ""; }; @@ -176,6 +242,13 @@ 5EAD6D261E27047400002378 /* CronetUnitTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CronetUnitTests.m; sourceTree = ""; }; 5EAD6D281E27047400002378 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 5EAFE8271F8EFB87007F2189 /* version.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = version.h; sourceTree = ""; }; + 5EB2A2E42107DED300EB4B69 /* ChannelTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ChannelTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 5EB2A2E62107DED300EB4B69 /* ChannelTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ChannelTests.m; sourceTree = ""; }; + 5EB2A2E82107DED300EB4B69 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 5EB2A2F52109284500EB4B69 /* InteropTestsMultipleChannels.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = InteropTestsMultipleChannels.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 5EB2A2F72109284500EB4B69 /* InteropTestsMultipleChannels.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = InteropTestsMultipleChannels.m; sourceTree = ""; }; + 5EB2A2F92109284500EB4B69 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 5EB5C3A921656CEA00ADC300 /* ChannelPoolTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ChannelPoolTest.m; sourceTree = ""; }; 5EC5E421208177CC000EF4AD /* InteropTestsRemoteCFStream.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = InteropTestsRemoteCFStream.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 5EC5E4312081856B000EF4AD /* InteropTestsLocalCleartextCFStream.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = InteropTestsLocalCleartextCFStream.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 5EC5E442208185CE000EF4AD /* InteropTestsLocalSSLCFStream.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = InteropTestsLocalSSLCFStream.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -200,37 +273,55 @@ 63E240CF1B6C63DC005F3B0E /* TestCertificates.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = TestCertificates.bundle; sourceTree = ""; }; 64F68A9A6A63CC930DD30A6E /* Pods-CronetUnitTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CronetUnitTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-CronetUnitTests/Pods-CronetUnitTests.debug.xcconfig"; sourceTree = ""; }; 6793C9D019CB268C5BB491A2 /* Pods-CoreCronetEnd2EndTests.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CoreCronetEnd2EndTests.test.xcconfig"; path = "Pods/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests.test.xcconfig"; sourceTree = ""; }; + 73D2DF07027835BA0FB0B1C0 /* Pods-InteropTestsCallOptions.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsCallOptions.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsCallOptions/Pods-InteropTestsCallOptions.cronet.xcconfig"; sourceTree = ""; }; 781089FAE980F51F88A3BE0B /* Pods-RxLibraryUnitTests.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RxLibraryUnitTests.test.xcconfig"; path = "Pods/Target Support Files/Pods-RxLibraryUnitTests/Pods-RxLibraryUnitTests.test.xcconfig"; sourceTree = ""; }; 79C68EFFCB5533475D810B79 /* Pods-RxLibraryUnitTests.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RxLibraryUnitTests.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-RxLibraryUnitTests/Pods-RxLibraryUnitTests.cronet.xcconfig"; sourceTree = ""; }; 7A2E97E3F469CC2A758D77DE /* Pods-InteropTestsLocalSSL.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalSSL.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL.release.xcconfig"; sourceTree = ""; }; 7BA53C6D224288D5870FE6F3 /* Pods-InteropTestsLocalCleartextCFStream.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartextCFStream.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartextCFStream/Pods-InteropTestsLocalCleartextCFStream.release.xcconfig"; sourceTree = ""; }; 8B498B05C6DA0818B2FA91D4 /* Pods-InteropTestsLocalCleartextCFStream.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartextCFStream.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartextCFStream/Pods-InteropTestsLocalCleartextCFStream.cronet.xcconfig"; sourceTree = ""; }; + 8C233E85C3EB45B3CAE52EDF /* Pods-APIv2Tests.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-APIv2Tests.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-APIv2Tests/Pods-APIv2Tests.cronet.xcconfig"; sourceTree = ""; }; + 90E63AD3C4A1E3E6BC745096 /* Pods-ChannelTests.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ChannelTests.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-ChannelTests/Pods-ChannelTests.cronet.xcconfig"; sourceTree = ""; }; 943138072A9605B5B8DC1FC0 /* Pods-InteropTestsLocalCleartextCFStream.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartextCFStream.debug.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartextCFStream/Pods-InteropTestsLocalCleartextCFStream.debug.xcconfig"; sourceTree = ""; }; 94D7A5FAA13480E9A5166D7A /* Pods-UnitTests.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-UnitTests.test.xcconfig"; path = "Pods/Target Support Files/Pods-UnitTests/Pods-UnitTests.test.xcconfig"; sourceTree = ""; }; 9E9444C764F0FFF64A7EB58E /* libPods-InteropTestsRemoteWithCronet.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-InteropTestsRemoteWithCronet.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + A25967A0D40ED14B3287AD81 /* Pods-InteropTestsCallOptions.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsCallOptions.test.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsCallOptions/Pods-InteropTestsCallOptions.test.xcconfig"; sourceTree = ""; }; A2DCF2570BE515B62CB924CA /* Pods-UnitTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-UnitTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-UnitTests/Pods-UnitTests.debug.xcconfig"; sourceTree = ""; }; A58BE6DF1C62D1739EBB2C78 /* libPods-RxLibraryUnitTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RxLibraryUnitTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; A6F832FCEFA6F6881E620F12 /* Pods-InteropTestsRemote.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemote.test.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemote/Pods-InteropTestsRemote.test.xcconfig"; sourceTree = ""; }; AA7CB64B4DD9915AE7C03163 /* Pods-InteropTestsLocalCleartext.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartext.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartext/Pods-InteropTestsLocalCleartext.cronet.xcconfig"; sourceTree = ""; }; AC414EF7A6BF76ED02B6E480 /* Pods-InteropTestsRemoteWithCronet.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemoteWithCronet.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemoteWithCronet/Pods-InteropTestsRemoteWithCronet.release.xcconfig"; sourceTree = ""; }; + AF3FC2CFFE7B0961823BC740 /* libPods-InteropTestsCallOptions.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-InteropTestsCallOptions.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + B071230A22669EED004B64A1 /* StressTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = StressTests.m; sourceTree = ""; }; + B0BB3EF7225E795F008DA580 /* MacTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MacTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + B0BB3EFB225E795F008DA580 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + B0C5FC172267C77200F192BE /* StressTests.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = StressTests.h; sourceTree = ""; }; + B0D39B992266F3CB00A4078D /* StressTestsSSL.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = StressTestsSSL.m; sourceTree = ""; }; + B0D39B9B2266FF9800A4078D /* StressTestsCleartext.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = StressTestsCleartext.m; sourceTree = ""; }; B226619DC4E709E0FFFF94B8 /* Pods-CronetUnitTests.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CronetUnitTests.test.xcconfig"; path = "Pods/Target Support Files/Pods-CronetUnitTests/Pods-CronetUnitTests.test.xcconfig"; sourceTree = ""; }; + B6AD69CACF67505B0F028E92 /* libPods-APIv2Tests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-APIv2Tests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; B94C27C06733CF98CE1B2757 /* Pods-AllTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AllTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-AllTests/Pods-AllTests.debug.xcconfig"; sourceTree = ""; }; + BED74BC8ABF9917C66175879 /* Pods-ChannelTests.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ChannelTests.test.xcconfig"; path = "Pods/Target Support Files/Pods-ChannelTests/Pods-ChannelTests.test.xcconfig"; sourceTree = ""; }; C17F57E5BCB989AB1C2F1F25 /* Pods-InteropTestsRemoteCFStream.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemoteCFStream.test.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemoteCFStream/Pods-InteropTestsRemoteCFStream.test.xcconfig"; sourceTree = ""; }; C6134277D2EB8B380862A03F /* libPods-CronetUnitTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-CronetUnitTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + C9172F9020E8C97A470D7250 /* Pods-InteropTestsCallOptions.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsCallOptions.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsCallOptions/Pods-InteropTestsCallOptions.release.xcconfig"; sourceTree = ""; }; CAE086D5B470DA367D415AB0 /* libPods-AllTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-AllTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; D13BEC8181B8E678A1B52F54 /* Pods-InteropTestsLocalSSL.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalSSL.test.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL.test.xcconfig"; sourceTree = ""; }; + D52B92A7108602F170DA8091 /* Pods-ChannelTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ChannelTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-ChannelTests/Pods-ChannelTests.release.xcconfig"; sourceTree = ""; }; DB1F4391AF69D20D38D74B67 /* Pods-AllTests.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AllTests.test.xcconfig"; path = "Pods/Target Support Files/Pods-AllTests/Pods-AllTests.test.xcconfig"; sourceTree = ""; }; DBE059B4AC7A51919467EEC0 /* libPods-InteropTestsRemote.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-InteropTestsRemote.a"; sourceTree = BUILT_PRODUCTS_DIR; }; DBEDE45BDA60DF1E1C8950C0 /* libPods-InteropTestsLocalSSL.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-InteropTestsLocalSSL.a"; sourceTree = BUILT_PRODUCTS_DIR; }; DC3CA1D948F068E76957A861 /* Pods-InteropTestsRemote.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemote.debug.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemote/Pods-InteropTestsRemote.debug.xcconfig"; sourceTree = ""; }; E1486220285AF123EB124008 /* Pods-InteropTestsLocalCleartext.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartext.debug.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartext/Pods-InteropTestsLocalCleartext.debug.xcconfig"; sourceTree = ""; }; E1E7660656D902104F728892 /* Pods-UnitTests.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-UnitTests.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-UnitTests/Pods-UnitTests.cronet.xcconfig"; sourceTree = ""; }; + E3ACD4D5902745976D9C2229 /* Pods-MacTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MacTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-MacTests/Pods-MacTests.debug.xcconfig"; sourceTree = ""; }; E4275A759BDBDF143B9B438F /* Pods-InteropTestsRemote.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemote.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemote/Pods-InteropTestsRemote.release.xcconfig"; sourceTree = ""; }; E4FD4606D4AB8D5A314D72F0 /* Pods-InteropTestsLocalCleartextCFStream.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartextCFStream.test.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartextCFStream/Pods-InteropTestsLocalCleartextCFStream.test.xcconfig"; sourceTree = ""; }; E7E4D3FD76E3B745D992AF5F /* Pods-AllTests.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AllTests.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-AllTests/Pods-AllTests.cronet.xcconfig"; sourceTree = ""; }; + EA8B122ACDE73E3AAA0E4A19 /* Pods-InteropTestsMultipleChannels.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsMultipleChannels.test.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsMultipleChannels/Pods-InteropTestsMultipleChannels.test.xcconfig"; sourceTree = ""; }; EBFFEC04B514CB0D4922DC40 /* Pods-UnitTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-UnitTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-UnitTests/Pods-UnitTests.release.xcconfig"; sourceTree = ""; }; F3AB031E0E26AC8EF30A2A2A /* libPods-InteropTestsLocalSSLCFStream.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-InteropTestsLocalSSLCFStream.a"; sourceTree = BUILT_PRODUCTS_DIR; }; F44AC3F44E3491A8C0D890FE /* libPods-InteropTestsRemoteCFStream.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-InteropTestsRemoteCFStream.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + F9E48EF5ACB1F38825171C5F /* Pods-ChannelTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ChannelTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-ChannelTests/Pods-ChannelTests.debug.xcconfig"; sourceTree = ""; }; FBD98AC417B9882D32B19F28 /* libPods-CoreCronetEnd2EndTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-CoreCronetEnd2EndTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; FD346DB2C23F676C4842F3FF /* libPods-InteropTestsLocalCleartext.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-InteropTestsLocalCleartext.a"; sourceTree = BUILT_PRODUCTS_DIR; }; FF7B5489BCFE40111D768DD0 /* Pods.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.debug.xcconfig; path = "Pods/Target Support Files/Pods/Pods.debug.xcconfig"; sourceTree = ""; }; @@ -246,6 +337,23 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 5E3B959F21CAC6C500C0A151 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 98478C9F42329DF769A45B6C /* libPods-APIv2Tests.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5E7D71AF210B9EC8001EA6BA /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 5E7D71B7210B9EC9001EA6BA /* libTests.a in Frameworks */, + 6C1A3F81CCF7C998B4813EFD /* libPods-InteropTestsCallOptions.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 5E8A5DA11D3840B4000F8BC4 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -264,6 +372,24 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 5EB2A2E12107DED300EB4B69 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 5EB2A2E92107DED300EB4B69 /* libTests.a in Frameworks */, + 1A0FB7F8C95A2F82538BC950 /* libPods-ChannelTests.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5EB2A2F22109284500EB4B69 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 5EB2A2FA2109284500EB4B69 /* libTests.a in Frameworks */, + 886717A79EFF774F356798E6 /* libPods-InteropTestsMultipleChannels.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 5EC5E41E208177CC000EF4AD /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -349,6 +475,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + B0BB3EF4225E795F008DA580 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 953CD2942A3A6D6CE695BE87 /* libPods-MacTests.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ @@ -368,7 +502,12 @@ F44AC3F44E3491A8C0D890FE /* libPods-InteropTestsRemoteCFStream.a */, 0BDA4BA011779D5D25B5618C /* libPods-InteropTestsLocalCleartextCFStream.a */, F3AB031E0E26AC8EF30A2A2A /* libPods-InteropTestsLocalSSLCFStream.a */, + 48F1841C9A920626995DC28C /* libPods-ChannelTests.a */, + 355D0E30AD224763BC9519F4 /* libPods-InteropTestsMultipleChannels.a */, + AF3FC2CFFE7B0961823BC740 /* libPods-InteropTestsCallOptions.a */, 22A3EBB488699C8CEA19707B /* libPods-UnitTests.a */, + B6AD69CACF67505B0F028E92 /* libPods-APIv2Tests.a */, + 276873A05AC5479B60DF6079 /* libPods-MacTests.a */, ); name = Frameworks; sourceTree = ""; @@ -422,10 +561,30 @@ 41AA59529240A6BBBD3DB904 /* Pods-InteropTestsLocalSSLCFStream.test.xcconfig */, 55B630C1FF8C36D1EFC4E0A4 /* Pods-InteropTestsLocalSSLCFStream.cronet.xcconfig */, 5EA908CF4CDA4CE218352A06 /* Pods-InteropTestsLocalSSLCFStream.release.xcconfig */, + F9E48EF5ACB1F38825171C5F /* Pods-ChannelTests.debug.xcconfig */, + BED74BC8ABF9917C66175879 /* Pods-ChannelTests.test.xcconfig */, + 90E63AD3C4A1E3E6BC745096 /* Pods-ChannelTests.cronet.xcconfig */, + D52B92A7108602F170DA8091 /* Pods-ChannelTests.release.xcconfig */, + 3CADF86203B9D03EA96C359D /* Pods-InteropTestsMultipleChannels.debug.xcconfig */, + EA8B122ACDE73E3AAA0E4A19 /* Pods-InteropTestsMultipleChannels.test.xcconfig */, + 1295CCBD1082B4A7CFCED95F /* Pods-InteropTestsMultipleChannels.cronet.xcconfig */, + 2650FEF00956E7924772F9D9 /* Pods-InteropTestsMultipleChannels.release.xcconfig */, + 3A98DF08852F60AF1D96481D /* Pods-InteropTestsCallOptions.debug.xcconfig */, + A25967A0D40ED14B3287AD81 /* Pods-InteropTestsCallOptions.test.xcconfig */, + 73D2DF07027835BA0FB0B1C0 /* Pods-InteropTestsCallOptions.cronet.xcconfig */, + C9172F9020E8C97A470D7250 /* Pods-InteropTestsCallOptions.release.xcconfig */, A2DCF2570BE515B62CB924CA /* Pods-UnitTests.debug.xcconfig */, 94D7A5FAA13480E9A5166D7A /* Pods-UnitTests.test.xcconfig */, E1E7660656D902104F728892 /* Pods-UnitTests.cronet.xcconfig */, EBFFEC04B514CB0D4922DC40 /* Pods-UnitTests.release.xcconfig */, + 1286B30AD74CB64CD91FB17D /* Pods-APIv2Tests.debug.xcconfig */, + 51F2A64B7AADBA1B225B132E /* Pods-APIv2Tests.test.xcconfig */, + 8C233E85C3EB45B3CAE52EDF /* Pods-APIv2Tests.cronet.xcconfig */, + 12B238CD1702393C2BA5DE80 /* Pods-APIv2Tests.release.xcconfig */, + E3ACD4D5902745976D9C2229 /* Pods-MacTests.debug.xcconfig */, + 1F5E788FBF9A4A06EB9E1ACD /* Pods-MacTests.test.xcconfig */, + 16A2E4C5839C83FBDA63881F /* Pods-MacTests.cronet.xcconfig */, + 1E43EAE443CBB4482B1EB071 /* Pods-MacTests.release.xcconfig */, ); name = Pods; sourceTree = ""; @@ -439,6 +598,24 @@ path = UnitTests; sourceTree = ""; }; + 5E3B95A321CAC6C500C0A151 /* APIv2Tests */ = { + isa = PBXGroup; + children = ( + 5E3B95A421CAC6C500C0A151 /* APIv2Tests.m */, + 5E3B95A621CAC6C500C0A151 /* Info.plist */, + ); + path = APIv2Tests; + sourceTree = ""; + }; + 5E7D71B3210B9EC9001EA6BA /* InteropTestsCallOptions */ = { + isa = PBXGroup; + children = ( + 5E7D71B4210B9EC9001EA6BA /* InteropTestsCallOptions.m */, + 5E7D71B6210B9EC9001EA6BA /* Info.plist */, + ); + path = InteropTestsCallOptions; + sourceTree = ""; + }; 5E8A5DA51D3840B4000F8BC4 /* CoreCronetEnd2EndTests */ = { isa = PBXGroup; children = ( @@ -456,6 +633,25 @@ path = CronetUnitTests; sourceTree = ""; }; + 5EB2A2E52107DED300EB4B69 /* ChannelTests */ = { + isa = PBXGroup; + children = ( + 5EB5C3A921656CEA00ADC300 /* ChannelPoolTest.m */, + 5EB2A2E62107DED300EB4B69 /* ChannelTests.m */, + 5EB2A2E82107DED300EB4B69 /* Info.plist */, + ); + path = ChannelTests; + sourceTree = ""; + }; + 5EB2A2F62109284500EB4B69 /* InteropTestsMultipleChannels */ = { + isa = PBXGroup; + children = ( + 5EB2A2F72109284500EB4B69 /* InteropTestsMultipleChannels.m */, + 5EB2A2F92109284500EB4B69 /* Info.plist */, + ); + path = InteropTestsMultipleChannels; + sourceTree = ""; + }; 5EE84BF21D4717E40050C6CC /* InteropTestsRemoteWithCronet */ = { isa = PBXGroup; children = ( @@ -473,7 +669,12 @@ 5E8A5DA51D3840B4000F8BC4 /* CoreCronetEnd2EndTests */, 5EE84BF21D4717E40050C6CC /* InteropTestsRemoteWithCronet */, 5EAD6D251E27047400002378 /* CronetUnitTests */, + 5EB2A2E52107DED300EB4B69 /* ChannelTests */, + 5EB2A2F62109284500EB4B69 /* InteropTestsMultipleChannels */, + 5E7D71B3210B9EC9001EA6BA /* InteropTestsCallOptions */, 5E0282E7215AA697007AC99D /* UnitTests */, + 5E3B95A321CAC6C500C0A151 /* APIv2Tests */, + B0BB3EF8225E795F008DA580 /* MacTests */, 635697C81B14FC11007A7283 /* Products */, 51E4650F34F854F41FF053B3 /* Pods */, 136D535E19727099B941D7B1 /* Frameworks */, @@ -495,7 +696,12 @@ 5EC5E421208177CC000EF4AD /* InteropTestsRemoteCFStream.xctest */, 5EC5E4312081856B000EF4AD /* InteropTestsLocalCleartextCFStream.xctest */, 5EC5E442208185CE000EF4AD /* InteropTestsLocalSSLCFStream.xctest */, + 5EB2A2E42107DED300EB4B69 /* ChannelTests.xctest */, + 5EB2A2F52109284500EB4B69 /* InteropTestsMultipleChannels.xctest */, + 5E7D71B2210B9EC8001EA6BA /* InteropTestsCallOptions.xctest */, 5E0282E6215AA697007AC99D /* UnitTests.xctest */, + 5E3B95A221CAC6C500C0A151 /* APIv2Tests.xctest */, + B0BB3EF7225E795F008DA580 /* MacTests.xctest */, ); name = Products; sourceTree = ""; @@ -525,6 +731,18 @@ name = "Supporting Files"; sourceTree = ""; }; + B0BB3EF8225E795F008DA580 /* MacTests */ = { + isa = PBXGroup; + children = ( + B0BB3EFB225E795F008DA580 /* Info.plist */, + B071230A22669EED004B64A1 /* StressTests.m */, + B0D39B992266F3CB00A4078D /* StressTestsSSL.m */, + B0D39B9B2266FF9800A4078D /* StressTestsCleartext.m */, + B0C5FC172267C77200F192BE /* StressTests.h */, + ); + path = MacTests; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -548,6 +766,45 @@ productReference = 5E0282E6215AA697007AC99D /* UnitTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; + 5E3B95A121CAC6C500C0A151 /* APIv2Tests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5E3B95A721CAC6C500C0A151 /* Build configuration list for PBXNativeTarget "APIv2Tests" */; + buildPhases = ( + EDDD3FA856BCA3443ED36D1E /* [CP] Check Pods Manifest.lock */, + 5E3B959E21CAC6C500C0A151 /* Sources */, + 5E3B959F21CAC6C500C0A151 /* Frameworks */, + 5E3B95A021CAC6C500C0A151 /* Resources */, + C17B826BBD02FDD4A5F355AF /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = APIv2Tests; + productName = APIv2Tests; + productReference = 5E3B95A221CAC6C500C0A151 /* APIv2Tests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 5E7D71B1210B9EC8001EA6BA /* InteropTestsCallOptions */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5E7D71BA210B9EC9001EA6BA /* Build configuration list for PBXNativeTarget "InteropTestsCallOptions" */; + buildPhases = ( + 2865C6386D677998F861E183 /* [CP] Check Pods Manifest.lock */, + 5E7D71AE210B9EC8001EA6BA /* Sources */, + 5E7D71AF210B9EC8001EA6BA /* Frameworks */, + 5E7D71B0210B9EC8001EA6BA /* Resources */, + 6BA6D00B1816306453BF82D4 /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + 5E7D71B9210B9EC9001EA6BA /* PBXTargetDependency */, + ); + name = InteropTestsCallOptions; + productName = InteropTestsCallOptions; + productReference = 5E7D71B2210B9EC8001EA6BA /* InteropTestsCallOptions.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; 5E8A5DA31D3840B4000F8BC4 /* CoreCronetEnd2EndTests */ = { isa = PBXNativeTarget; buildConfigurationList = 5E8A5DAE1D3840B4000F8BC4 /* Build configuration list for PBXNativeTarget "CoreCronetEnd2EndTests" */; @@ -588,6 +845,47 @@ productReference = 5EAD6D241E27047400002378 /* CronetUnitTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; + 5EB2A2E32107DED300EB4B69 /* ChannelTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5EB2A2F02107DED300EB4B69 /* Build configuration list for PBXNativeTarget "ChannelTests" */; + buildPhases = ( + 021B3B1F545989843EBC9A4B /* [CP] Check Pods Manifest.lock */, + 5EB2A2E02107DED300EB4B69 /* Sources */, + 5EB2A2E12107DED300EB4B69 /* Frameworks */, + 5EB2A2E22107DED300EB4B69 /* Resources */, + 1EAF0CBDBFAB18D4DA64535D /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + 5EB2A2EB2107DED300EB4B69 /* PBXTargetDependency */, + ); + name = ChannelTests; + productName = ChannelTests; + productReference = 5EB2A2E42107DED300EB4B69 /* ChannelTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 5EB2A2F42109284500EB4B69 /* InteropTestsMultipleChannels */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5EB2A3012109284500EB4B69 /* Build configuration list for PBXNativeTarget "InteropTestsMultipleChannels" */; + buildPhases = ( + 8C1ED025E07C4D457C355336 /* [CP] Check Pods Manifest.lock */, + 5EB2A2F12109284500EB4B69 /* Sources */, + 5EB2A2F22109284500EB4B69 /* Frameworks */, + 5EB2A2F32109284500EB4B69 /* Resources */, + 8D685CB612835DB3F7A6F14A /* [CP] Embed Pods Frameworks */, + 0617B5294978A95BEBBFF733 /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + 5EB2A2FC2109284500EB4B69 /* PBXTargetDependency */, + ); + name = InteropTestsMultipleChannels; + productName = InteropTestsMultipleChannels; + productReference = 5EB2A2F52109284500EB4B69 /* InteropTestsMultipleChannels.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; 5EC5E420208177CC000EF4AD /* InteropTestsRemoteCFStream */ = { isa = PBXNativeTarget; buildConfigurationList = 5EC5E42A208177CD000EF4AD /* Build configuration list for PBXNativeTarget "InteropTestsRemoteCFStream" */; @@ -783,6 +1081,25 @@ productReference = 63DC84431BE152B5000708E8 /* InteropTestsLocalCleartext.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; + B0BB3EF6225E795F008DA580 /* MacTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = B0BB3EFC225E795F008DA580 /* Build configuration list for PBXNativeTarget "MacTests" */; + buildPhases = ( + E5B20F69559C6AE299DFEA7C /* [CP] Check Pods Manifest.lock */, + B0BB3EF3225E795F008DA580 /* Sources */, + B0BB3EF4225E795F008DA580 /* Frameworks */, + B0BB3EF5225E795F008DA580 /* Resources */, + 452FDC3918FEC23ECAFD31EC /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = MacTests; + productName = MacTests; + productReference = B0BB3EF7225E795F008DA580 /* MacTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -796,12 +1113,28 @@ CreatedOnToolsVersion = 9.2; ProvisioningStyle = Automatic; }; + 5E3B95A121CAC6C500C0A151 = { + CreatedOnToolsVersion = 10.0; + ProvisioningStyle = Automatic; + }; + 5E7D71B1210B9EC8001EA6BA = { + CreatedOnToolsVersion = 9.3; + ProvisioningStyle = Automatic; + }; 5E8A5DA31D3840B4000F8BC4 = { CreatedOnToolsVersion = 7.3.1; }; 5EAD6D231E27047400002378 = { CreatedOnToolsVersion = 7.3.1; }; + 5EB2A2E32107DED300EB4B69 = { + CreatedOnToolsVersion = 9.3; + ProvisioningStyle = Automatic; + }; + 5EB2A2F42109284500EB4B69 = { + CreatedOnToolsVersion = 9.3; + ProvisioningStyle = Automatic; + }; 5EC5E420208177CC000EF4AD = { CreatedOnToolsVersion = 9.2; ProvisioningStyle = Automatic; @@ -835,6 +1168,10 @@ 63DC84421BE152B5000708E8 = { CreatedOnToolsVersion = 7.0.1; }; + B0BB3EF6225E795F008DA580 = { + CreatedOnToolsVersion = 10.1; + ProvisioningStyle = Automatic; + }; }; }; buildConfigurationList = 635697C21B14FC11007A7283 /* Build configuration list for PBXProject "Tests" */; @@ -861,7 +1198,12 @@ 5EC5E420208177CC000EF4AD /* InteropTestsRemoteCFStream */, 5EC5E4302081856B000EF4AD /* InteropTestsLocalCleartextCFStream */, 5EC5E441208185CE000EF4AD /* InteropTestsLocalSSLCFStream */, + 5EB2A2E32107DED300EB4B69 /* ChannelTests */, + 5EB2A2F42109284500EB4B69 /* InteropTestsMultipleChannels */, + 5E7D71B1210B9EC8001EA6BA /* InteropTestsCallOptions */, 5E0282E5215AA697007AC99D /* UnitTests */, + 5E3B95A121CAC6C500C0A151 /* APIv2Tests */, + B0BB3EF6225E795F008DA580 /* MacTests */, ); }; /* End PBXProject section */ @@ -874,6 +1216,20 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 5E3B95A021CAC6C500C0A151 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5E7D71B0210B9EC8001EA6BA /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 5E8A5DA21D3840B4000F8BC4 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -888,6 +1244,21 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 5EB2A2E22107DED300EB4B69 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5EB2A2F32109284500EB4B69 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5E7D71AD210954A8001EA6BA /* TestCertificates.bundle in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 5EC5E41F208177CC000EF4AD /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -954,9 +1325,71 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + B0BB3EF5225E795F008DA580 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B0BB3F0A225EA511008DA580 /* TestCertificates.bundle in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ + 021B3B1F545989843EBC9A4B /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-ChannelTests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + 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; + }; + 0617B5294978A95BEBBFF733 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsMultipleChannels/Pods-InteropTestsMultipleChannels-resources.sh", + "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-iOS/gRPCCertificates.bundle", + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/gRPCCertificates.bundle", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsMultipleChannels/Pods-InteropTestsMultipleChannels-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; + 1EAF0CBDBFAB18D4DA64535D /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${SRCROOT}/Pods/Target Support Files/Pods-ChannelTests/Pods-ChannelTests-resources.sh", + "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-iOS/gRPCCertificates.bundle", + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/gRPCCertificates.bundle", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ChannelTests/Pods-ChannelTests-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; 252A376345E38FD452A89C3D /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -975,6 +1408,24 @@ 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; }; + 2865C6386D677998F861E183 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-InteropTestsCallOptions-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + 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; + }; 31F8D1C407195CBF0C02929B /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -993,6 +1444,28 @@ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsRemoteWithCronet/Pods-InteropTestsRemoteWithCronet-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; + 452FDC3918FEC23ECAFD31EC /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${SRCROOT}/Pods/Target Support Files/Pods-MacTests/Pods-MacTests-resources.sh", + "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-macOS/gRPCCertificates.bundle", + ); + name = "[CP] Copy Pods Resources"; + outputFileListPaths = ( + ); + outputPaths = ( + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/gRPCCertificates.bundle", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-MacTests/Pods-MacTests-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; 483CDBBAEAEFCB530ADDDDD5 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -1036,7 +1509,7 @@ ); inputPaths = ( "${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsLocalSSLCFStream/Pods-InteropTestsLocalSSLCFStream-resources.sh", - "${PODS_CONFIGURATION_BUILD_DIR}/gRPC.default-CFStream/gRPCCertificates.bundle", + "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-iOS/gRPCCertificates.bundle", ); name = "[CP] Copy Pods Resources"; outputPaths = ( @@ -1072,7 +1545,7 @@ ); inputPaths = ( "${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL-resources.sh", - "${PODS_CONFIGURATION_BUILD_DIR}/gRPC/gRPCCertificates.bundle", + "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-iOS/gRPCCertificates.bundle", ); name = "[CP] Copy Pods Resources"; outputPaths = ( @@ -1083,6 +1556,24 @@ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL-resources.sh\"\n"; showEnvVarsInLog = 0; }; + 6BA6D00B1816306453BF82D4 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsCallOptions/Pods-InteropTestsCallOptions-resources.sh", + "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-iOS/gRPCCertificates.bundle", + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/gRPCCertificates.bundle", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsCallOptions/Pods-InteropTestsCallOptions-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; 7418AC7B3844B29E48D24FC7 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -1126,7 +1617,7 @@ ); inputPaths = ( "${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsLocalCleartext/Pods-InteropTestsLocalCleartext-resources.sh", - "${PODS_CONFIGURATION_BUILD_DIR}/gRPC/gRPCCertificates.bundle", + "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-iOS/gRPCCertificates.bundle", ); name = "[CP] Copy Pods Resources"; outputPaths = ( @@ -1137,6 +1628,42 @@ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsLocalCleartext/Pods-InteropTestsLocalCleartext-resources.sh\"\n"; showEnvVarsInLog = 0; }; + 8C1ED025E07C4D457C355336 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-InteropTestsMultipleChannels-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + 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; + }; + 8D685CB612835DB3F7A6F14A /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsMultipleChannels/Pods-InteropTestsMultipleChannels-frameworks.sh", + "${PODS_ROOT}/CronetFramework/Cronet.framework", + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Cronet.framework", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsMultipleChannels/Pods-InteropTestsMultipleChannels-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; 914ADDD7106BA9BB8A7E569F /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -1162,7 +1689,7 @@ ); inputPaths = ( "${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsRemoteCFStream/Pods-InteropTestsRemoteCFStream-resources.sh", - "${PODS_CONFIGURATION_BUILD_DIR}/gRPC.default-CFStream/gRPCCertificates.bundle", + "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-iOS/gRPCCertificates.bundle", ); name = "[CP] Copy Pods Resources"; outputPaths = ( @@ -1180,7 +1707,7 @@ ); inputPaths = ( "${SRCROOT}/Pods/Target Support Files/Pods-UnitTests/Pods-UnitTests-resources.sh", - "${PODS_CONFIGURATION_BUILD_DIR}/gRPC/gRPCCertificates.bundle", + "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-iOS/gRPCCertificates.bundle", ); name = "[CP] Copy Pods Resources"; outputPaths = ( @@ -1198,7 +1725,7 @@ ); inputPaths = ( "${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsLocalCleartextCFStream/Pods-InteropTestsLocalCleartextCFStream-resources.sh", - "${PODS_CONFIGURATION_BUILD_DIR}/gRPC.default-CFStream/gRPCCertificates.bundle", + "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-iOS/gRPCCertificates.bundle", ); name = "[CP] Copy Pods Resources"; outputPaths = ( @@ -1216,7 +1743,7 @@ ); inputPaths = ( "${SRCROOT}/Pods/Target Support Files/Pods-AllTests/Pods-AllTests-resources.sh", - "${PODS_CONFIGURATION_BUILD_DIR}/gRPC/gRPCCertificates.bundle", + "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-iOS/gRPCCertificates.bundle", ); name = "[CP] Copy Pods Resources"; outputPaths = ( @@ -1281,6 +1808,28 @@ 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; }; + C17B826BBD02FDD4A5F355AF /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${SRCROOT}/Pods/Target Support Files/Pods-APIv2Tests/Pods-APIv2Tests-resources.sh", + "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-iOS/gRPCCertificates.bundle", + ); + name = "[CP] Copy Pods Resources"; + outputFileListPaths = ( + ); + outputPaths = ( + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/gRPCCertificates.bundle", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-APIv2Tests/Pods-APIv2Tests-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; C2E09DC4BD239F71160F0CC1 /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -1288,7 +1837,7 @@ ); inputPaths = ( "${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsRemote/Pods-InteropTestsRemote-resources.sh", - "${PODS_CONFIGURATION_BUILD_DIR}/gRPC/gRPCCertificates.bundle", + "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-iOS/gRPCCertificates.bundle", ); name = "[CP] Copy Pods Resources"; outputPaths = ( @@ -1306,7 +1855,7 @@ ); inputPaths = ( "${SRCROOT}/Pods/Target Support Files/Pods-RxLibraryUnitTests/Pods-RxLibraryUnitTests-resources.sh", - "${PODS_CONFIGURATION_BUILD_DIR}/gRPC/gRPCCertificates.bundle", + "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-iOS/gRPCCertificates.bundle", ); name = "[CP] Copy Pods Resources"; outputPaths = ( @@ -1324,7 +1873,7 @@ ); inputPaths = ( "${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsRemoteWithCronet/Pods-InteropTestsRemoteWithCronet-resources.sh", - "${PODS_CONFIGURATION_BUILD_DIR}/gRPC/gRPCCertificates.bundle", + "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-iOS/gRPCCertificates.bundle", ); name = "[CP] Copy Pods Resources"; outputPaths = ( @@ -1335,6 +1884,28 @@ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsRemoteWithCronet/Pods-InteropTestsRemoteWithCronet-resources.sh\"\n"; showEnvVarsInLog = 0; }; + E5B20F69559C6AE299DFEA7C /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-MacTests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + 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; + }; E63468C760D0724F18861822 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -1353,6 +1924,28 @@ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; + EDDD3FA856BCA3443ED36D1E /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-APIv2Tests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + 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; + }; F07941C0BAF6A7C67AA60C48 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -1418,6 +2011,22 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 5E3B959E21CAC6C500C0A151 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5E3B95A521CAC6C500C0A151 /* APIv2Tests.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5E7D71AE210B9EC8001EA6BA /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5E7D71B5210B9EC9001EA6BA /* InteropTestsCallOptions.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 5E8A5DA01D3840B4000F8BC4 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -1434,6 +2043,23 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 5EB2A2E02107DED300EB4B69 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5EB2A2E72107DED300EB4B69 /* ChannelTests.m in Sources */, + 5EB5C3AA21656CEA00ADC300 /* ChannelPoolTest.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5EB2A2F12109284500EB4B69 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5EB2A2F82109284500EB4B69 /* InteropTestsMultipleChannels.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 5EC5E41D208177CC000EF4AD /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -1528,6 +2154,24 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + B0BB3EF3225E795F008DA580 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B0BB3F07225E7AB5008DA580 /* APIv2Tests.m in Sources */, + B0BB3F08225E7ABA008DA580 /* UnitTests.m in Sources */, + B071230B22669EED004B64A1 /* StressTests.m in Sources */, + B0BB3F05225E7A9F008DA580 /* InteropTestsRemote.m in Sources */, + B0D39B9A2266F3CB00A4078D /* StressTestsSSL.m in Sources */, + B0BB3F03225E7A44008DA580 /* InteropTestsLocalCleartext.m in Sources */, + B0BB3F04225E7A8D008DA580 /* RxLibraryUnitTests.m in Sources */, + B0D39B9C2266FF9800A4078D /* StressTestsCleartext.m in Sources */, + B0BB3F0B225EB110008DA580 /* InteropTests.m in Sources */, + B0BB3F02225E7A3C008DA580 /* InteropTestsLocalSSL.m in Sources */, + B0BB3F06225E7AAD008DA580 /* GRPCClientTests.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ @@ -1536,6 +2180,11 @@ target = 635697C61B14FC11007A7283 /* Tests */; targetProxy = 5E0282EC215AA697007AC99D /* PBXContainerItemProxy */; }; + 5E7D71B9210B9EC9001EA6BA /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 635697C61B14FC11007A7283 /* Tests */; + targetProxy = 5E7D71B8210B9EC9001EA6BA /* PBXContainerItemProxy */; + }; 5E8A5DAB1D3840B4000F8BC4 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 635697C61B14FC11007A7283 /* Tests */; @@ -1546,6 +2195,16 @@ target = 635697C61B14FC11007A7283 /* Tests */; targetProxy = 5EAD6D2A1E27047400002378 /* PBXContainerItemProxy */; }; + 5EB2A2EB2107DED300EB4B69 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 635697C61B14FC11007A7283 /* Tests */; + targetProxy = 5EB2A2EA2107DED300EB4B69 /* PBXContainerItemProxy */; + }; + 5EB2A2FC2109284500EB4B69 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 635697C61B14FC11007A7283 /* Tests */; + targetProxy = 5EB2A2FB2109284500EB4B69 /* PBXContainerItemProxy */; + }; 5EE84BF81D4717E40050C6CC /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 635697C61B14FC11007A7283 /* Tests */; @@ -1909,6 +2568,271 @@ }; name = Test; }; + 5E3B95A821CAC6C500C0A151 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 1286B30AD74CB64CD91FB17D /* Pods-APIv2Tests.debug.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = APIv2Tests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.2; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.APIv2Tests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 5E3B95A921CAC6C500C0A151 /* Test */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 51F2A64B7AADBA1B225B132E /* Pods-APIv2Tests.test.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = APIv2Tests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.2; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.APIv2Tests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Test; + }; + 5E3B95AA21CAC6C500C0A151 /* Cronet */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 8C233E85C3EB45B3CAE52EDF /* Pods-APIv2Tests.cronet.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = APIv2Tests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.2; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.APIv2Tests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Cronet; + }; + 5E3B95AB21CAC6C500C0A151 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 12B238CD1702393C2BA5DE80 /* Pods-APIv2Tests.release.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = APIv2Tests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.2; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.APIv2Tests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + 5E7D71BB210B9EC9001EA6BA /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 3A98DF08852F60AF1D96481D /* Pods-InteropTestsCallOptions.debug.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = InteropTestsCallOptions/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsCallOptions; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 5E7D71BC210B9EC9001EA6BA /* Test */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = A25967A0D40ED14B3287AD81 /* Pods-InteropTestsCallOptions.test.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = InteropTestsCallOptions/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsCallOptions; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Test; + }; + 5E7D71BD210B9EC9001EA6BA /* Cronet */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 73D2DF07027835BA0FB0B1C0 /* Pods-InteropTestsCallOptions.cronet.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = InteropTestsCallOptions/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsCallOptions; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Cronet; + }; + 5E7D71BE210B9EC9001EA6BA /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = C9172F9020E8C97A470D7250 /* Pods-InteropTestsCallOptions.release.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = InteropTestsCallOptions/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsCallOptions; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; 5E8A5DAC1D3840B4000F8BC4 /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 0D2284C3DF7E57F0ED504E39 /* Pods-CoreCronetEnd2EndTests.debug.xcconfig */; @@ -2011,6 +2935,266 @@ }; name = Release; }; + 5EB2A2EC2107DED300EB4B69 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = F9E48EF5ACB1F38825171C5F /* Pods-ChannelTests.debug.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = ChannelTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.ChannelTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 5EB2A2ED2107DED300EB4B69 /* Test */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = BED74BC8ABF9917C66175879 /* Pods-ChannelTests.test.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = ChannelTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.ChannelTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Test; + }; + 5EB2A2EE2107DED300EB4B69 /* Cronet */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 90E63AD3C4A1E3E6BC745096 /* Pods-ChannelTests.cronet.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = ChannelTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.ChannelTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Cronet; + }; + 5EB2A2EF2107DED300EB4B69 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = D52B92A7108602F170DA8091 /* Pods-ChannelTests.release.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = ChannelTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.ChannelTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + 5EB2A2FD2109284500EB4B69 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 3CADF86203B9D03EA96C359D /* Pods-InteropTestsMultipleChannels.debug.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = InteropTestsMultipleChannels/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsMultipleChannels; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 5EB2A2FE2109284500EB4B69 /* Test */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = EA8B122ACDE73E3AAA0E4A19 /* Pods-InteropTestsMultipleChannels.test.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = InteropTestsMultipleChannels/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsMultipleChannels; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Test; + }; + 5EB2A2FF2109284500EB4B69 /* Cronet */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 1295CCBD1082B4A7CFCED95F /* Pods-InteropTestsMultipleChannels.cronet.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = InteropTestsMultipleChannels/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsMultipleChannels; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Cronet; + }; + 5EB2A3002109284500EB4B69 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 2650FEF00956E7924772F9D9 /* Pods-InteropTestsMultipleChannels.release.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = InteropTestsMultipleChannels/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsMultipleChannels; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; 5EC3C7A01D4FC18C000330E2 /* Cronet */ = { isa = XCBuildConfiguration; buildSettings = { @@ -2039,6 +3223,8 @@ "DEBUG=1", "$(inherited)", "HOST_PORT_REMOTE=$(HOST_PORT_REMOTE)", + "HOST_PORT_LOCALSSL=$(HOST_PORT_LOCALSSL)", + "HOST_PORT_LOCAL=$(HOST_PORT_LOCAL)", ); GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_TREAT_WARNINGS_AS_ERRORS = YES; @@ -2845,6 +4031,154 @@ }; name = Release; }; + B0BB3EFD225E795F008DA580 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E3ACD4D5902745976D9C2229 /* Pods-MacTests.debug.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "-"; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = MacTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 10.13; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.MacTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + }; + name = Debug; + }; + B0BB3EFE225E795F008DA580 /* Test */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 1F5E788FBF9A4A06EB9E1ACD /* Pods-MacTests.test.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "-"; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + "COCOAPODS=1", + "GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1", + "PB_FIELD_32BIT=1", + "PB_NO_PACKED_STRUCTS=1", + "PB_ENABLE_MALLOC=1", + "GRPC_TEST_OBJC=1", + ); + INFOPLIST_FILE = MacTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 10.13; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.MacTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + }; + name = Test; + }; + B0BB3EFF225E795F008DA580 /* Cronet */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 16A2E4C5839C83FBDA63881F /* Pods-MacTests.cronet.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "-"; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = MacTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 10.13; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.MacTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + }; + name = Cronet; + }; + B0BB3F00225E795F008DA580 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 1E43EAE443CBB4482B1EB071 /* Pods-MacTests.release.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "-"; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = MacTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 10.13; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.MacTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + }; + name = Release; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -2859,6 +4193,28 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 5E3B95A721CAC6C500C0A151 /* Build configuration list for PBXNativeTarget "APIv2Tests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5E3B95A821CAC6C500C0A151 /* Debug */, + 5E3B95A921CAC6C500C0A151 /* Test */, + 5E3B95AA21CAC6C500C0A151 /* Cronet */, + 5E3B95AB21CAC6C500C0A151 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 5E7D71BA210B9EC9001EA6BA /* Build configuration list for PBXNativeTarget "InteropTestsCallOptions" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5E7D71BB210B9EC9001EA6BA /* Debug */, + 5E7D71BC210B9EC9001EA6BA /* Test */, + 5E7D71BD210B9EC9001EA6BA /* Cronet */, + 5E7D71BE210B9EC9001EA6BA /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 5E8A5DAE1D3840B4000F8BC4 /* Build configuration list for PBXNativeTarget "CoreCronetEnd2EndTests" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -2881,6 +4237,28 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 5EB2A2F02107DED300EB4B69 /* Build configuration list for PBXNativeTarget "ChannelTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5EB2A2EC2107DED300EB4B69 /* Debug */, + 5EB2A2ED2107DED300EB4B69 /* Test */, + 5EB2A2EE2107DED300EB4B69 /* Cronet */, + 5EB2A2EF2107DED300EB4B69 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 5EB2A3012109284500EB4B69 /* Build configuration list for PBXNativeTarget "InteropTestsMultipleChannels" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5EB2A2FD2109284500EB4B69 /* Debug */, + 5EB2A2FE2109284500EB4B69 /* Test */, + 5EB2A2FF2109284500EB4B69 /* Cronet */, + 5EB2A3002109284500EB4B69 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 5EC5E42A208177CD000EF4AD /* Build configuration list for PBXNativeTarget "InteropTestsRemoteCFStream" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -3002,6 +4380,17 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + B0BB3EFC225E795F008DA580 /* Build configuration list for PBXNativeTarget "MacTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B0BB3EFD225E795F008DA580 /* Debug */, + B0BB3EFE225E795F008DA580 /* Test */, + B0BB3EFF225E795F008DA580 /* Cronet */, + B0BB3F00225E795F008DA580 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; /* End XCConfigurationList section */ }; rootObject = 635697BF1B14FC11007A7283 /* Project object */; diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/APIv2Tests.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/APIv2Tests.xcscheme new file mode 100644 index 00000000000..e0d1d1fdcac --- /dev/null +++ b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/APIv2Tests.xcscheme @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/AllTests.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/AllTests.xcscheme index b0bb9337640..a2560fee029 100644 --- a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/AllTests.xcscheme +++ b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/AllTests.xcscheme @@ -26,7 +26,6 @@ buildConfiguration = "Test" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - language = "" shouldUseLaunchSchemeArgsEnv = "YES"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsCallOptions.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsCallOptions.xcscheme new file mode 100644 index 00000000000..dd83282190f --- /dev/null +++ b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsCallOptions.xcscheme @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsLocalCleartext.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsLocalCleartext.xcscheme index 510115fc757..11b41c92140 100644 --- a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsLocalCleartext.xcscheme +++ b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsLocalCleartext.xcscheme @@ -26,7 +26,6 @@ buildConfiguration = "Test" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - language = "" shouldUseLaunchSchemeArgsEnv = "YES"> - - - - @@ -58,7 +51,6 @@ buildConfiguration = "Test" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - language = "" launchStyle = "0" useCustomWorkingDirectory = "NO" ignoresPersistentStateOnLaunch = "NO" diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsMultipleChannels.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsMultipleChannels.xcscheme new file mode 100644 index 00000000000..1b4c1f5e51c --- /dev/null +++ b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsMultipleChannels.xcscheme @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsRemote.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsRemote.xcscheme index 48837e57f9a..412bf6a0143 100644 --- a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsRemote.xcscheme +++ b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsRemote.xcscheme @@ -26,7 +26,6 @@ buildConfiguration = "Test" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - language = "" shouldUseLaunchSchemeArgsEnv = "YES"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/Tests.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/Tests.xcscheme new file mode 100644 index 00000000000..77f567db3d4 --- /dev/null +++ b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/Tests.xcscheme @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/objective-c/tests/UnitTests/UnitTests.m b/src/objective-c/tests/UnitTests/UnitTests.m index 57e686d1b67..4dcb8c08d28 100644 --- a/src/objective-c/tests/UnitTests/UnitTests.m +++ b/src/objective-c/tests/UnitTests/UnitTests.m @@ -20,7 +20,7 @@ #import -#import "src/objective-c/GRPCClient/private/NSError+GRPC.h" +#import "../../GRPCClient/private/NSError+GRPC.h" @interface UnitTests : XCTestCase diff --git a/src/objective-c/tests/run_tests.sh b/src/objective-c/tests/run_tests.sh index f37c6cf9f62..8c768cb85be 100755 --- a/src/objective-c/tests/run_tests.sh +++ b/src/objective-c/tests/run_tests.sh @@ -173,4 +173,39 @@ xcodebuild \ | egrep -v '^$' \ | egrep -v "(GPBDictionary|GPBArray)" - +echo "TIME: $(date)" +xcodebuild \ + -workspace Tests.xcworkspace \ + -scheme ChannelTests \ + -destination name="iPhone 8" \ + test \ + | egrep -v "$XCODEBUILD_FILTER" \ + | egrep -v '^$' \ + | egrep -v "(GPBDictionary|GPBArray)" - + +echo "TIME: $(date)" +xcodebuild \ + -workspace Tests.xcworkspace \ + -scheme APIv2Tests \ + -destination name="iPhone 8" \ + HOST_PORT_LOCAL=localhost:5050 \ + HOST_PORT_REMOTE=grpc-test.sandbox.googleapis.com \ + test \ + | egrep -v "$XCODEBUILD_FILTER" \ + | egrep -v '^$' \ + | egrep -v "(GPBDictionary|GPBArray)" - + +echo "TIME: $(date)" +xcodebuild \ + -workspace Tests.xcworkspace \ + -scheme MacTests \ + -destination platform=macOS \ + HOST_PORT_LOCALSSL=localhost:5051 \ + HOST_PORT_LOCAL=localhost:5050 \ + HOST_PORT_REMOTE=grpc-test.sandbox.googleapis.com \ + test \ + | egrep -v "$XCODEBUILD_FILTER" \ + | egrep -v '^$' \ + | egrep -v "(GPBDictionary|GPBArray)" - + exit 0 diff --git a/src/objective-c/tests/version.h b/src/objective-c/tests/version.h index ca27c03b3c7..c835c1da190 100644 --- a/src/objective-c/tests/version.h +++ b/src/objective-c/tests/version.h @@ -22,5 +22,5 @@ // instead. This file can be regenerated from the template by running // `tools/buildgen/generate_projects.sh`. -#define GRPC_OBJC_VERSION_STRING @"1.17.0-dev" -#define GRPC_C_VERSION_STRING @"7.0.0-dev" +#define GRPC_OBJC_VERSION_STRING @"1.22.0-dev" +#define GRPC_C_VERSION_STRING @"7.0.0" diff --git a/src/php/bin/run_tests.sh b/src/php/bin/run_tests.sh index 295bcb2430c..a78dd259e2f 100755 --- a/src/php/bin/run_tests.sh +++ b/src/php/bin/run_tests.sh @@ -22,9 +22,17 @@ 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 -php $extension_dir -d max_execution_time=300 $(which phpunit) -v --debug \ +$(which php) $extension_dir -d max_execution_time=300 $(which phpunit) -v --debug \ --exclude-group persistent_list_bound_tests ../tests/unit_tests -php $extension_dir -d max_execution_time=300 $(which phpunit) -v --debug \ +$(which php) $extension_dir -d max_execution_time=300 $(which phpunit) -v --debug \ ../tests/unit_tests/PersistentChannelTests +export ZEND_DONT_UNLOAD_MODULES=1 +export USE_ZEND_ALLOC=0 +# Detect whether valgrind is executable +if [ -x "$(command -v valgrind)" ]; then + $(which valgrind) --error-exitcode=10 --leak-check=yes \ + $(which php) $extension_dir -d max_execution_time=300 \ + ../tests/MemoryLeakTest/MemoryLeakTest.php +fi diff --git a/src/php/composer.json b/src/php/composer.json index d54db91b5fb..ca1001b6d2b 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.17.0", + "version": "1.22.0", "require": { "php": ">=5.5.0", "google/protobuf": "^v3.3.0" diff --git a/src/php/ext/grpc/call.c b/src/php/ext/grpc/call.c index a7942262987..46d1e22f1f8 100644 --- a/src/php/ext/grpc/call.c +++ b/src/php/ext/grpc/call.c @@ -217,6 +217,12 @@ PHP_METHOD(Call, __construct) { } wrapped_grpc_channel *channel = PHP_GRPC_GET_WRAPPED_OBJECT(wrapped_grpc_channel, channel_obj); + if (channel->wrapper == NULL) { + zend_throw_exception(spl_ce_InvalidArgumentException, + "Call cannot be constructed from a closed Channel", + 1 TSRMLS_CC); + return; + } gpr_mu_lock(&channel->wrapper->mu); if (channel->wrapper == NULL || channel->wrapper->wrapped == NULL) { zend_throw_exception(spl_ce_InvalidArgumentException, diff --git a/src/php/ext/grpc/php_grpc.c b/src/php/ext/grpc/php_grpc.c index cbc7f63be07..f6c2f85ed47 100644 --- a/src/php/ext/grpc/php_grpc.c +++ b/src/php/ext/grpc/php_grpc.c @@ -67,27 +67,22 @@ ZEND_GET_MODULE(grpc) /* {{{ PHP_INI */ -/* Remove comments and fill if you need to have entries in php.ini PHP_INI_BEGIN() - STD_PHP_INI_ENTRY("grpc.global_value", "42", PHP_INI_ALL, OnUpdateLong, - global_value, zend_grpc_globals, grpc_globals) - STD_PHP_INI_ENTRY("grpc.global_string", "foobar", PHP_INI_ALL, - OnUpdateString, global_string, zend_grpc_globals, - grpc_globals) + STD_PHP_INI_ENTRY("grpc.enable_fork_support", "0", PHP_INI_SYSTEM, OnUpdateBool, + enable_fork_support, zend_grpc_globals, grpc_globals) + STD_PHP_INI_ENTRY("grpc.poll_strategy", NULL, PHP_INI_SYSTEM, OnUpdateString, + poll_strategy, zend_grpc_globals, grpc_globals) PHP_INI_END() -*/ /* }}} */ /* {{{ php_grpc_init_globals */ -/* Uncomment this function if you have INI entries - static void php_grpc_init_globals(zend_grpc_globals *grpc_globals) - { - grpc_globals->global_value = 0; - grpc_globals->global_string = NULL; - } -*/ +static void php_grpc_init_globals(zend_grpc_globals *grpc_globals) { + grpc_globals->enable_fork_support = 0; + grpc_globals->poll_strategy = NULL; +} /* }}} */ + void create_new_channel( wrapped_grpc_channel *channel, char *target, @@ -171,14 +166,16 @@ void prefork() { } void postfork_child() { + TSRMLS_FETCH(); + // loop through persistant list and destroy all underlying grpc_channel objs destroy_grpc_channels(); // clear completion queue - grpc_php_shutdown_completion_queue(); + grpc_php_shutdown_completion_queue(TSRMLS_C); // clean-up grpc_core - grpc_shutdown(); + grpc_shutdown_blocking(); if (grpc_is_initialized() > 0) { zend_throw_exception(spl_ce_UnexpectedValueException, "Oops, failed to shutdown gRPC Core after fork()", @@ -187,7 +184,7 @@ void postfork_child() { // restart grpc_core grpc_init(); - grpc_php_init_completion_queue(); + grpc_php_init_completion_queue(TSRMLS_C); // re-create grpc_channel and point wrapped to it // unlock wrapped grpc channel mutex @@ -200,16 +197,32 @@ void postfork_parent() { void register_fork_handlers() { if (getenv("GRPC_ENABLE_FORK_SUPPORT")) { +#ifdef GRPC_POSIX_FORK_ALLOW_PTHREAD_ATFORK pthread_atfork(&prefork, &postfork_parent, &postfork_child); +#endif // GRPC_POSIX_FORK_ALLOW_PTHREAD_ATFORK + } +} + +void apply_ini_settings() { + if (GRPC_G(enable_fork_support)) { + putenv("GRPC_ENABLE_FORK_SUPPORT=1"); + } + + if (GRPC_G(poll_strategy)) { + char *poll_str = malloc(sizeof("GRPC_POLL_STRATEGY=") + + strlen(GRPC_G(poll_strategy))); + strcpy(poll_str, "GRPC_POLL_STRATEGY="); + strcat(poll_str, GRPC_G(poll_strategy)); + putenv(poll_str); } } /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(grpc) { - /* If you have INI entries, uncomment these lines - REGISTER_INI_ENTRIES(); - */ + ZEND_INIT_MODULE_GLOBALS(grpc, php_grpc_init_globals, NULL); + REGISTER_INI_ENTRIES(); + /* Register call error constants */ REGISTER_LONG_CONSTANT("Grpc\\CALL_OK", GRPC_CALL_OK, CONST_CS | CONST_PERSISTENT); @@ -345,9 +358,7 @@ PHP_MINIT_FUNCTION(grpc) { /* {{{ PHP_MSHUTDOWN_FUNCTION */ PHP_MSHUTDOWN_FUNCTION(grpc) { - /* uncomment this line if you have INI entries - UNREGISTER_INI_ENTRIES(); - */ + UNREGISTER_INI_ENTRIES(); // WARNING: This function IS being called by PHP when the extension // is unloaded but the logs were somehow suppressed. if (GRPC_G(initialized)) { @@ -357,7 +368,7 @@ PHP_MSHUTDOWN_FUNCTION(grpc) { zend_hash_destroy(&grpc_target_upper_bound_map); grpc_shutdown_timeval(TSRMLS_C); grpc_php_shutdown_completion_queue(TSRMLS_C); - grpc_shutdown(); + grpc_shutdown_blocking(); GRPC_G(initialized) = 0; } return SUCCESS; @@ -371,9 +382,7 @@ PHP_MINFO_FUNCTION(grpc) { 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(); - */ + DISPLAY_INI_ENTRIES(); } /* }}} */ @@ -381,6 +390,7 @@ PHP_MINFO_FUNCTION(grpc) { */ PHP_RINIT_FUNCTION(grpc) { if (!GRPC_G(initialized)) { + apply_ini_settings(); grpc_init(); register_fork_handlers(); grpc_php_init_completion_queue(TSRMLS_C); diff --git a/src/php/ext/grpc/php_grpc.h b/src/php/ext/grpc/php_grpc.h index ecf5ebaa05b..2629b1bbd78 100644 --- a/src/php/ext/grpc/php_grpc.h +++ b/src/php/ext/grpc/php_grpc.h @@ -66,6 +66,8 @@ PHP_RINIT_FUNCTION(grpc); */ ZEND_BEGIN_MODULE_GLOBALS(grpc) zend_bool initialized; + zend_bool enable_fork_support; + char *poll_strategy; ZEND_END_MODULE_GLOBALS(grpc) /* In every utility function you add that needs to use variables diff --git a/src/php/ext/grpc/tests/grpc-default-ini.phpt b/src/php/ext/grpc/tests/grpc-default-ini.phpt new file mode 100644 index 00000000000..0fbcc1f119e --- /dev/null +++ b/src/php/ext/grpc/tests/grpc-default-ini.phpt @@ -0,0 +1,15 @@ +--TEST-- +Ensure default ini settings +--SKIPIF-- + +--FILE-- + +--INI-- +grpc.enable_fork_support = 1 +grpc.poll_strategy = epoll1 +--FILE-- + "v1"]; +} + +function assertConnecting($state) +{ + assert(($state == GRPC\CHANNEL_CONNECTING || $state == GRPC\CHANNEL_TRANSIENT_FAILURE) == true); +} + +function waitUntilNotIdle($channel) { + for ($i = 0; $i < 10; $i++) { + $now = Grpc\Timeval::now(); + $deadline = $now->add(new Grpc\Timeval(10000)); + if ($channel->watchConnectivityState(GRPC\CHANNEL_IDLE, + $deadline)) { + return true; + } + } + assert(true == false); +} + +// Set up +$channel = new Grpc\Channel('localhost:0', ['credentials' => Grpc\ChannelCredentials::createInsecure()]); + +// Test InsecureCredentials +assert('Grpc\Channel' == get_class($channel)); + +// Test ConnectivityState +$state = $channel->getConnectivityState(); +assert(0 == $state); + +// Test GetConnectivityStateWithInt +$state = $channel->getConnectivityState(123); +assert(0 == $state); + +// Test GetConnectivityStateWithString +$state = $channel->getConnectivityState('hello'); +assert(0 == $state); + +// Test GetConnectivityStateWithBool +$state = $channel->getConnectivityState(true); +assert(0 == $state); + +$channel->close(); + +// Test GetTarget +$channel = new Grpc\Channel('localhost:8888', ['credentials' => Grpc\ChannelCredentials::createInsecure()]); +$target = $channel->getTarget(); +assert(is_string($target) == true); +$channel->close(); + +// Test WatchConnectivityState +$channel = new Grpc\Channel('localhost:0', ['credentials' => Grpc\ChannelCredentials::createInsecure()]); +$now = Grpc\Timeval::now(); +$deadline = $now->add(new Grpc\Timeval(100*1000)); + +$state = $channel->watchConnectivityState(1, $deadline); +assert($state == true); + +unset($now); +unset($deadline); + +$channel->close(); diff --git a/src/php/tests/interop/interop_client.php b/src/php/tests/interop/interop_client.php index c865678f704..19cbf21bc2b 100755 --- a/src/php/tests/interop/interop_client.php +++ b/src/php/tests/interop/interop_client.php @@ -530,7 +530,7 @@ function _makeStub($args) throw new Exception('Missing argument: --test_case is required'); } - if ($args['server_port'] === 443) { + if ($args['server_port'] === '443') { $server_address = $args['server_host']; } else { $server_address = $args['server_host'].':'.$args['server_port']; @@ -538,7 +538,7 @@ function _makeStub($args) $test_case = $args['test_case']; - $host_override = 'foo.test.google.fr'; + $host_override = ''; if (array_key_exists('server_host_override', $args)) { $host_override = $args['server_host_override']; } @@ -565,7 +565,9 @@ function _makeStub($args) $ssl_credentials = Grpc\ChannelCredentials::createSsl(); } $opts['credentials'] = $ssl_credentials; - $opts['grpc.ssl_target_name_override'] = $host_override; + if (!empty($host_override)) { + $opts['grpc.ssl_target_name_override'] = $host_override; + } } else { $opts['credentials'] = Grpc\ChannelCredentials::createInsecure(); } diff --git a/src/php/tests/qps/composer.json b/src/php/tests/qps/composer.json index 0f4b0c04ba4..c2d73f00ed9 100644 --- a/src/php/tests/qps/composer.json +++ b/src/php/tests/qps/composer.json @@ -1,7 +1,7 @@ { "require": { "grpc/grpc": "dev-master", - "google/protobuf": "v3.5.1.1" + "google/protobuf": "^v3.3.0" }, "autoload": { "psr-4": { diff --git a/src/php/tests/unit_tests/CallTest.php b/src/php/tests/unit_tests/CallTest.php index be1d77fe7ad..927fac6622b 100644 --- a/src/php/tests/unit_tests/CallTest.php +++ b/src/php/tests/unit_tests/CallTest.php @@ -86,6 +86,16 @@ class CallTest extends PHPUnit_Framework_TestCase $this->assertTrue($result->send_metadata); } + public function testAddMultiAndMultiValueMetadata() + { + $batch = [ + Grpc\OP_SEND_INITIAL_METADATA => ['key1' => ['value1', 'value2'], + 'key2' => ['value3', 'value4'],], + ]; + $result = $this->call->startBatch($batch); + $this->assertTrue($result->send_metadata); + } + public function testGetPeer() { $this->assertTrue(is_string($this->call->getPeer())); diff --git a/src/php/tests/unit_tests/InterceptorTest.php b/src/php/tests/unit_tests/InterceptorTest.php index 0ad49fc2bd1..acd68fc45a2 100644 --- a/src/php/tests/unit_tests/InterceptorTest.php +++ b/src/php/tests/unit_tests/InterceptorTest.php @@ -103,7 +103,11 @@ class ChangeMetadataInterceptor extends Grpc\Interceptor $metadata["foo"] = array('interceptor_from_unary_request'); return $continuation($method, $argument, $deserialize, $metadata, $options); } - public function interceptStreamUnary($method, $deserialize, array $metadata = [], array $options = [], $continuation) + public function interceptStreamUnary($method, + $deserialize, + array $metadata = [], + array $options = [], + $continuation) { $metadata["foo"] = array('interceptor_from_stream_request'); return $continuation($method, $deserialize, $metadata, $options); @@ -178,7 +182,11 @@ class ChangeRequestInterceptor extends Grpc\Interceptor $argument->setData('intercepted_unary_request'); return $continuation($method, $argument, $deserialize, $metadata, $options); } - public function interceptStreamUnary($method, $deserialize, array $metadata = [], array $options = [], $continuation) + public function interceptStreamUnary($method, + $deserialize, + array $metadata = [], + array $options = [], + $continuation) { return new ChangeRequestCall( $continuation($method, $deserialize, $metadata, $options) @@ -190,6 +198,7 @@ class StopCallInterceptor extends Grpc\Interceptor { public function interceptUnaryUnary($method, $argument, + $deserialize, array $metadata = [], array $options = [], $continuation) @@ -197,6 +206,7 @@ class StopCallInterceptor extends Grpc\Interceptor $metadata["foo"] = array('interceptor_from_request_response'); } public function interceptStreamUnary($method, + $deserialize, array $metadata = [], array $options = [], $continuation) diff --git a/src/proto/grpc/channelz/BUILD b/src/proto/grpc/channelz/BUILD index bdb03d5e2d0..1d80ec23af1 100644 --- a/src/proto/grpc/channelz/BUILD +++ b/src/proto/grpc/channelz/BUILD @@ -24,3 +24,15 @@ grpc_proto_library( has_services = True, well_known_protos = True, ) + +proto_library( + name = "channelz_proto_descriptors", + srcs = ["channelz.proto"], +) + +filegroup( + name = "channelz_proto_file", + srcs = [ + "channelz.proto", + ], +) diff --git a/src/proto/grpc/channelz/channelz.proto b/src/proto/grpc/channelz/channelz.proto index 6202e5e817d..20de23f7fa3 100644 --- a/src/proto/grpc/channelz/channelz.proto +++ b/src/proto/grpc/channelz/channelz.proto @@ -177,6 +177,7 @@ message SubchannelRef { // SocketRef is a reference to a Socket. message SocketRef { + // The globally unique id for this socket. Must be a positive number. int64 socket_id = 3; // An optional name associated with the socket. string name = 4; @@ -288,7 +289,8 @@ message SocketData { // include stream level or TCP level flow control info. google.protobuf.Int64Value remote_flow_control_window = 12; - // Socket options set on this socket. May be absent. + // Socket options set on this socket. May be absent if 'summary' is set + // on GetSocketRequest. repeated SocketOption option = 13; } @@ -439,12 +441,21 @@ service Channelz { message GetTopChannelsRequest { // start_channel_id indicates that only channels at or above this id should be // included in the results. + // To request the first page, this should be set to 0. To request + // subsequent pages, the client generates this value by adding 1 to + // the highest seen result ID. int64 start_channel_id = 1; + + // If non-zero, the server will return a page of results containing + // at most this many items. If zero, the server will choose a + // reasonable page size. Must never be negative. + int64 max_results = 2; } message GetTopChannelsResponse { // list of channels that the connection detail service knows about. Sorted in // ascending channel_id order. + // Must contain at least 1 result, otherwise 'end' must be true. repeated Channel channel = 1; // If set, indicates that the list of channels is the final list. Requesting // more channels can only return more if they are created after this RPC @@ -455,12 +466,21 @@ message GetTopChannelsResponse { message GetServersRequest { // start_server_id indicates that only servers at or above this id should be // included in the results. + // To request the first page, this must be set to 0. To request + // subsequent pages, the client generates this value by adding 1 to + // the highest seen result ID. int64 start_server_id = 1; + + // If non-zero, the server will return a page of results containing + // at most this many items. If zero, the server will choose a + // reasonable page size. Must never be negative. + int64 max_results = 2; } message GetServersResponse { // list of servers that the connection detail service knows about. Sorted in // ascending server_id order. + // Must contain at least 1 result, otherwise 'end' must be true. repeated Server server = 1; // If set, indicates that the list of servers is the final list. Requesting // more servers will only return more if they are created after this RPC @@ -483,12 +503,21 @@ message GetServerSocketsRequest { int64 server_id = 1; // start_socket_id indicates that only sockets at or above this id should be // included in the results. + // To request the first page, this must be set to 0. To request + // subsequent pages, the client generates this value by adding 1 to + // the highest seen result ID. int64 start_socket_id = 2; + + // If non-zero, the server will return a page of results containing + // at most this many items. If zero, the server will choose a + // reasonable page size. Must never be negative. + int64 max_results = 3; } message GetServerSocketsResponse { // list of socket refs that the connection detail service knows about. Sorted in // ascending socket_id order. + // Must contain at least 1 result, otherwise 'end' must be true. repeated SocketRef socket_ref = 1; // If set, indicates that the list of sockets is the final list. Requesting // more sockets will only return more if they are created after this RPC @@ -521,6 +550,11 @@ message GetSubchannelResponse { message GetSocketRequest { // socket_id is the identifier of the specific socket to get. int64 socket_id = 1; + + // If true, the response will contain only high level information + // that is inexpensive to obtain. Fields thay may be omitted are + // documented. + bool summary = 2; } message GetSocketResponse { diff --git a/src/proto/grpc/health/v1/BUILD b/src/proto/grpc/health/v1/BUILD index 97642985c9d..fc58e8a1770 100644 --- a/src/proto/grpc/health/v1/BUILD +++ b/src/proto/grpc/health/v1/BUILD @@ -23,10 +23,14 @@ grpc_proto_library( srcs = ["health.proto"], ) +proto_library( + name = "health_proto_descriptor", + srcs = ["health.proto"], +) + filegroup( name = "health_proto_file", srcs = [ "health.proto", ], ) - diff --git a/src/proto/grpc/reflection/v1alpha/BUILD b/src/proto/grpc/reflection/v1alpha/BUILD index 4d919d029ee..5424c0d867e 100644 --- a/src/proto/grpc/reflection/v1alpha/BUILD +++ b/src/proto/grpc/reflection/v1alpha/BUILD @@ -23,6 +23,11 @@ grpc_proto_library( srcs = ["reflection.proto"], ) +proto_library( + name = "reflection_proto_descriptor", + srcs = ["reflection.proto"], +) + filegroup( name = "reflection_proto_file", srcs = [ diff --git a/src/proto/grpc/testing/BUILD b/src/proto/grpc/testing/BUILD index 7048911b9ae..727c99cf99c 100644 --- a/src/proto/grpc/testing/BUILD +++ b/src/proto/grpc/testing/BUILD @@ -16,7 +16,7 @@ licenses(["notice"]) # Apache v2 load("//bazel:grpc_build_system.bzl", "grpc_proto_library", "grpc_package") load("@grpc_python_dependencies//:requirements.bzl", "requirement") -load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_library") +load("//bazel:python_rules.bzl", "py_proto_library") grpc_package(name = "testing", visibility = "public") @@ -50,7 +50,8 @@ grpc_proto_library( grpc_proto_library( name = "echo_proto", srcs = ["echo.proto"], - deps = ["echo_messages_proto"], + deps = ["echo_messages_proto", + "simple_messages_proto"], generate_mocks = True, ) @@ -60,13 +61,14 @@ grpc_proto_library( has_services = False, ) +proto_library( + name = "empty_proto_descriptor", + srcs = ["empty.proto"], +) + py_proto_library( name = "py_empty_proto", - protos = ["empty.proto",], - with_grpc = True, - deps = [ - requirement('protobuf'), - ], + deps = [":empty_proto_descriptor"], ) grpc_proto_library( @@ -75,13 +77,14 @@ grpc_proto_library( has_services = False, ) +proto_library( + name = "messages_proto_descriptor", + srcs = ["messages.proto"], +) + py_proto_library( name = "py_messages_proto", - protos = ["messages.proto",], - with_grpc = True, - deps = [ - requirement('protobuf'), - ], + deps = [":messages_proto_descriptor"], ) grpc_proto_library( @@ -119,6 +122,12 @@ grpc_proto_library( ], ) +grpc_proto_library( + name = "simple_messages_proto", + srcs = ["simple_messages.proto"], + has_services = False, +) + grpc_proto_library( name = "stats_proto", srcs = ["stats.proto"], @@ -137,16 +146,50 @@ grpc_proto_library( ], ) +# Test that grpc_proto_library/cc_grpc_library can consume generated files +genrule( + name = "messages_gen_proto_file", + srcs = ["messages.proto"], + outs = ["messages_gen.proto"], + cmd = "cp $< $@", +) + +grpc_proto_library( + name = "messages_gen_proto", + srcs = ["messages_gen_proto_file"], + has_services = False, +) + +genrule( + name = "test_gen_proto_file", + srcs = ["test.proto"], + outs = ["test_gen.proto"], + cmd = "sed 's/messages.proto/messages_gen.proto/' $< > $@", +) + +# Consume generated files in srcs and in deps +grpc_proto_library( + name = "test_gen_proto", + srcs = ["test_gen_proto_file"], + deps = [ + "empty_proto", + "messages_gen_proto", + ], +) + +proto_library( + name = "test_proto_descriptor", + srcs = ["test.proto"], + deps = [ + ":empty_proto_descriptor", + ":messages_proto_descriptor", + ], +) + py_proto_library( name = "py_test_proto", - protos = ["test.proto",], - with_grpc = True, deps = [ - requirement('protobuf'), - ], - proto_deps = [ - ":py_empty_proto", - ":py_messages_proto", + ":test_proto_descriptor", ] ) diff --git a/src/proto/grpc/testing/compiler_test.proto b/src/proto/grpc/testing/compiler_test.proto index db5ca483312..9fa5590a594 100644 --- a/src/proto/grpc/testing/compiler_test.proto +++ b/src/proto/grpc/testing/compiler_test.proto @@ -20,6 +20,9 @@ syntax = "proto3"; // Ignored detached comment +// The comments in this file are not meant for readability +// but rather to test to make sure that the code generator +// properly preserves comments on files, services, and RPCs // Ignored package leading comment package grpc.testing; diff --git a/src/proto/grpc/testing/echo.proto b/src/proto/grpc/testing/echo.proto index 13e28320fc9..977858f6bc5 100644 --- a/src/proto/grpc/testing/echo.proto +++ b/src/proto/grpc/testing/echo.proto @@ -16,11 +16,15 @@ syntax = "proto3"; import "src/proto/grpc/testing/echo_messages.proto"; +import "src/proto/grpc/testing/simple_messages.proto"; package grpc.testing; service EchoTestService { rpc Echo(EchoRequest) returns (EchoResponse); + // A service which checks that the initial metadata sent over contains some + // expected key value pair + rpc CheckClientInitialMetadata(SimpleRequest) returns (SimpleResponse); rpc RequestStream(stream EchoRequest) returns (EchoResponse); rpc ResponseStream(EchoRequest) returns (stream EchoResponse); rpc BidiStream(stream EchoRequest) returns (stream EchoResponse); diff --git a/src/proto/grpc/testing/echo_messages.proto b/src/proto/grpc/testing/echo_messages.proto index 2f935304ab2..2c773ea0aaa 100644 --- a/src/proto/grpc/testing/echo_messages.proto +++ b/src/proto/grpc/testing/echo_messages.proto @@ -17,6 +17,8 @@ syntax = "proto3"; package grpc.testing; +option cc_enable_arenas = true; + // Message to be echoed back serialized in trailer. message DebugInfo { repeated string stack_entries = 1; @@ -47,6 +49,7 @@ message RequestParams { ErrorStatus expected_error = 14; int32 server_sleep_us = 15; // Amount to sleep when invoking server int32 backend_channel_idx = 16; // which backend to send request to + bool echo_metadata_initially = 17; } message EchoRequest { diff --git a/src/proto/grpc/testing/proto2/BUILD.bazel b/src/proto/grpc/testing/proto2/BUILD.bazel index c4c4f004efb..e939c523a64 100644 --- a/src/proto/grpc/testing/proto2/BUILD.bazel +++ b/src/proto/grpc/testing/proto2/BUILD.bazel @@ -1,30 +1,32 @@ load("@grpc_python_dependencies//:requirements.bzl", "requirement") -load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_library") package(default_visibility = ["//visibility:public"]) +load("//bazel:python_rules.bzl", "py_proto_library") + +proto_library( + name = "empty2_proto_descriptor", + srcs = ["empty2.proto"], +) py_proto_library( name = "empty2_proto", - protos = [ - "empty2.proto", - ], - with_grpc = True, deps = [ - requirement('protobuf'), + ":empty2_proto_descriptor", ], ) +proto_library( + name = "empty2_extensions_proto_descriptor", + srcs = ["empty2_extensions.proto"], + deps = [ + ":empty2_proto_descriptor", + ] +) + py_proto_library( name = "empty2_extensions_proto", - protos = [ - "empty2_extensions.proto", - ], - proto_deps = [ - ":empty2_proto", - ], - with_grpc = True, deps = [ - requirement('protobuf'), + ":empty2_extensions_proto_descriptor", ], ) diff --git a/src/proto/grpc/testing/simple_messages.proto b/src/proto/grpc/testing/simple_messages.proto new file mode 100644 index 00000000000..4b65d18909d --- /dev/null +++ b/src/proto/grpc/testing/simple_messages.proto @@ -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. + +syntax = "proto3"; + +package grpc.testing; + +message SimpleRequest { +} + +message SimpleResponse { +} diff --git a/src/python/grpcio/_parallel_compile_patch.py b/src/python/grpcio/_parallel_compile_patch.py index 4d03ef49ba0..b34aa17fd0b 100644 --- a/src/python/grpcio/_parallel_compile_patch.py +++ b/src/python/grpcio/_parallel_compile_patch.py @@ -40,7 +40,7 @@ def _parallel_compile(self, # setup the same way as distutils.ccompiler.CCompiler # https://github.com/python/cpython/blob/31368a4f0e531c19affe2a1becd25fc316bc7501/Lib/distutils/ccompiler.py#L564 macros, objects, extra_postargs, pp_opts, build = self._setup_compile( - output_dir, macros, include_dirs, sources, depends, extra_postargs) + str(output_dir), macros, include_dirs, sources, depends, extra_postargs) cc_args = self._get_cc_args(pp_opts, debug, extra_preargs) def _compile_single_file(obj): diff --git a/src/python/grpcio/commands.py b/src/python/grpcio/commands.py index b805f4277b0..d189c2869d0 100644 --- a/src/python/grpcio/commands.py +++ b/src/python/grpcio/commands.py @@ -212,50 +212,40 @@ class BuildExt(build_ext.build_ext): LINK_OPTIONS = {} def build_extensions(self): + + def compiler_ok_with_extra_std(): + """Test if default compiler is okay with specifying c++ version + when invoked in C mode. GCC is okay with this, while clang is not. + """ + cc_test = subprocess.Popen( + ['cc', '-x', 'c', '-std=c++11', '-'], + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + _, cc_err = cc_test.communicate(input=b'int main(){return 0;}') + return not 'invalid argument' in str(cc_err) + # This special conditioning is here due to difference of compiler # behavior in gcc and clang. The clang doesn't take --stdc++11 # flags but gcc does. Since the setuptools of Python only support # all C or all C++ compilation, the mix of C and C++ will crash. - # *By default*, the macOS use clang and Linux use gcc, that's why - # the special condition here is checking platform. - if "darwin" in sys.platform: - config = os.environ.get('CONFIG', 'opt') - target_path = os.path.abspath( - os.path.join( - os.path.dirname(os.path.realpath(__file__)), '..', '..', - '..', 'libs', config)) - targets = [ - os.path.join(target_path, 'libboringssl.a'), - os.path.join(target_path, 'libares.a'), - os.path.join(target_path, 'libgpr.a'), - os.path.join(target_path, 'libgrpc.a') - ] - # Running make separately for Mac means we lose all - # Extension.define_macros configured in setup.py. Re-add the macro - # for gRPC Core's fork handlers. - # TODO(ericgribkoff) Decide what to do about the other missing core - # macros, including GRPC_ENABLE_FORK_SUPPORT, which defaults to 1 - # on Linux but remains unset on Mac. - extra_defines = [ - 'EXTRA_DEFINES="GRPC_POSIX_FORK_ALLOW_PTHREAD_ATFORK=1"' - ] - # Ensure the BoringSSL are built instead of using system provided - # libraries. It prevents dependency issues while distributing to - # Mac users who use MacPorts to manage their libraries. #17002 - mod_env = dict(os.environ) - mod_env['REQUIRE_CUSTOM_LIBRARIES_opt'] = '1' - make_process = subprocess.Popen( - ['make'] + extra_defines + targets, - env=mod_env, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - make_out, make_err = make_process.communicate() - if make_out and make_process.returncode != 0: - sys.stdout.write(str(make_out) + '\n') - if make_err: - sys.stderr.write(str(make_err) + '\n') - if make_process.returncode != 0: - raise Exception("make command failed!") + # *By default*, macOS and FreBSD use clang and Linux use gcc + # + # If we are not using a permissive compiler that's OK with being + # passed wrong std flags, swap out compile function by adding a filter + # for it. + if not compiler_ok_with_extra_std(): + old_compile = self.compiler._compile + + def new_compile(obj, src, ext, cc_args, extra_postargs, pp_opts): + if src[-2:] == '.c': + extra_postargs = [ + arg for arg in extra_postargs if not '-std=c++' in arg + ] + return old_compile(obj, src, ext, cc_args, extra_postargs, + pp_opts) + + self.compiler._compile = new_compile compiler = self.compiler.compiler_type if compiler in BuildExt.C_OPTIONS: diff --git a/src/python/grpcio/grpc/BUILD.bazel b/src/python/grpcio/grpc/BUILD.bazel index 2e6839ef2d8..a2bedae4bea 100644 --- a/src/python/grpcio/grpc/BUILD.bazel +++ b/src/python/grpcio/grpc/BUILD.bazel @@ -12,13 +12,15 @@ py_library( ":channel", ":interceptor", ":server", + ":compression", "//src/python/grpcio/grpc/_cython:cygrpc", - "//src/python/grpcio/grpc/beta", "//src/python/grpcio/grpc/experimental", "//src/python/grpcio/grpc/framework", - requirement('enum34'), requirement('six'), - ], + ] + select({ + "//conditions:default": [requirement('enum34'),], + "//:python3": [], + }), data = [ "//:grpc", ], @@ -30,12 +32,18 @@ py_library( srcs = ["_auth.py"], ) +py_library( + name = "compression", + srcs = ["_compression.py"], +) + py_library( name = "channel", srcs = ["_channel.py"], deps = [ ":common", ":grpcio_metadata", + ":compression", ], ) @@ -67,6 +75,7 @@ py_library( srcs = ["_server.py"], deps = [ ":common", + ":compression", ":interceptor", ], ) diff --git a/src/python/grpcio/grpc/__init__.py b/src/python/grpcio/grpc/__init__.py index 88c5b6d5be5..6175180e92a 100644 --- a/src/python/grpcio/grpc/__init__.py +++ b/src/python/grpcio/grpc/__init__.py @@ -14,15 +14,22 @@ """gRPC's Python API.""" import abc +import contextlib import enum import logging import sys import six from grpc._cython import cygrpc as _cygrpc +from grpc import _compression logging.getLogger(__name__).addHandler(logging.NullHandler()) +try: + from grpc._grpcio_metadata import __version__ +except ImportError: + __version__ = "dev0" + ############################## Future Interface ############################### @@ -266,6 +273,22 @@ class StatusCode(enum.Enum): UNAUTHENTICATED = (_cygrpc.StatusCode.unauthenticated, 'unauthenticated') +############################# gRPC Status ################################ + + +class Status(six.with_metaclass(abc.ABCMeta)): + """Describes the status of an RPC. + + This is an EXPERIMENTAL API. + + Attributes: + code: A StatusCode object to be sent to the client. + details: A UTF-8-encodable string to be sent to the client upon + termination of the RPC. + trailing_metadata: The trailing :term:`metadata` in the RPC. + """ + + ############################# gRPC Exceptions ################################ @@ -391,6 +414,8 @@ class ClientCallDetails(six.with_metaclass(abc.ABCMeta)): credentials: An optional CallCredentials for the RPC. wait_for_ready: This is an EXPERIMENTAL argument. An optional flag t enable wait for ready mechanism. + compression: An element of grpc.compression, e.g. + grpc.compression.Gzip. This is an EXPERIMENTAL option. """ @@ -647,7 +672,8 @@ class UnaryUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)): timeout=None, metadata=None, credentials=None, - wait_for_ready=None): + wait_for_ready=None, + compression=None): """Synchronously invokes the underlying RPC. Args: @@ -659,6 +685,8 @@ class UnaryUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)): credentials: An optional CallCredentials for the RPC. wait_for_ready: This is an EXPERIMENTAL argument. An optional flag to enable wait for ready mechanism + compression: An element of grpc.compression, e.g. + grpc.compression.Gzip. This is an EXPERIMENTAL option. Returns: The response value for the RPC. @@ -676,7 +704,8 @@ class UnaryUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)): timeout=None, metadata=None, credentials=None, - wait_for_ready=None): + wait_for_ready=None, + compression=None): """Synchronously invokes the underlying RPC. Args: @@ -688,6 +717,8 @@ class UnaryUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)): credentials: An optional CallCredentials for the RPC. wait_for_ready: This is an EXPERIMENTAL argument. An optional flag to enable wait for ready mechanism + compression: An element of grpc.compression, e.g. + grpc.compression.Gzip. This is an EXPERIMENTAL option. Returns: The response value for the RPC and a Call value for the RPC. @@ -705,7 +736,8 @@ class UnaryUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)): timeout=None, metadata=None, credentials=None, - wait_for_ready=None): + wait_for_ready=None, + compression=None): """Asynchronously invokes the underlying RPC. Args: @@ -717,6 +749,8 @@ class UnaryUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)): credentials: An optional CallCredentials for the RPC. wait_for_ready: This is an EXPERIMENTAL argument. An optional flag to enable wait for ready mechanism + compression: An element of grpc.compression, e.g. + grpc.compression.Gzip. This is an EXPERIMENTAL option. Returns: An object that is both a Call for the RPC and a Future. @@ -737,7 +771,8 @@ class UnaryStreamMultiCallable(six.with_metaclass(abc.ABCMeta)): timeout=None, metadata=None, credentials=None, - wait_for_ready=None): + wait_for_ready=None, + compression=None): """Invokes the underlying RPC. Args: @@ -749,6 +784,8 @@ class UnaryStreamMultiCallable(six.with_metaclass(abc.ABCMeta)): credentials: An optional CallCredentials for the RPC. wait_for_ready: This is an EXPERIMENTAL argument. An optional flag to enable wait for ready mechanism + compression: An element of grpc.compression, e.g. + grpc.compression.Gzip. This is an EXPERIMENTAL option. Returns: An object that is both a Call for the RPC and an iterator of @@ -768,7 +805,8 @@ class StreamUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)): timeout=None, metadata=None, credentials=None, - wait_for_ready=None): + wait_for_ready=None, + compression=None): """Synchronously invokes the underlying RPC. Args: @@ -781,6 +819,8 @@ class StreamUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)): credentials: An optional CallCredentials for the RPC. wait_for_ready: This is an EXPERIMENTAL argument. An optional flag to enable wait for ready mechanism + compression: An element of grpc.compression, e.g. + grpc.compression.Gzip. This is an EXPERIMENTAL option. Returns: The response value for the RPC. @@ -798,7 +838,8 @@ class StreamUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)): timeout=None, metadata=None, credentials=None, - wait_for_ready=None): + wait_for_ready=None, + compression=None): """Synchronously invokes the underlying RPC on the client. Args: @@ -811,6 +852,8 @@ class StreamUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)): credentials: An optional CallCredentials for the RPC. wait_for_ready: This is an EXPERIMENTAL argument. An optional flag to enable wait for ready mechanism + compression: An element of grpc.compression, e.g. + grpc.compression.Gzip. This is an EXPERIMENTAL option. Returns: The response value for the RPC and a Call object for the RPC. @@ -828,7 +871,8 @@ class StreamUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)): timeout=None, metadata=None, credentials=None, - wait_for_ready=None): + wait_for_ready=None, + compression=None): """Asynchronously invokes the underlying RPC on the client. Args: @@ -840,6 +884,8 @@ class StreamUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)): credentials: An optional CallCredentials for the RPC. wait_for_ready: This is an EXPERIMENTAL argument. An optional flag to enable wait for ready mechanism + compression: An element of grpc.compression, e.g. + grpc.compression.Gzip. This is an EXPERIMENTAL option. Returns: An object that is both a Call for the RPC and a Future. @@ -860,7 +906,8 @@ class StreamStreamMultiCallable(six.with_metaclass(abc.ABCMeta)): timeout=None, metadata=None, credentials=None, - wait_for_ready=None): + wait_for_ready=None, + compression=None): """Invokes the underlying RPC on the client. Args: @@ -872,6 +919,8 @@ class StreamStreamMultiCallable(six.with_metaclass(abc.ABCMeta)): credentials: An optional CallCredentials for the RPC. wait_for_ready: This is an EXPERIMENTAL argument. An optional flag to enable wait for ready mechanism + compression: An element of grpc.compression, e.g. + grpc.compression.Gzip. This is an EXPERIMENTAL option. Returns: An object that is both a Call for the RPC and an iterator of @@ -1075,6 +1124,17 @@ class ServicerContext(six.with_metaclass(abc.ABCMeta, RpcContext)): """ raise NotImplementedError() + def set_compression(self, compression): + """Set the compression algorithm to be used for the entire call. + + This is an EXPERIMENTAL method. + + Args: + compression: An element of grpc.compression, e.g. + grpc.compression.Gzip. + """ + raise NotImplementedError() + @abc.abstractmethod def send_initial_metadata(self, initial_metadata): """Sends the initial metadata value to the client. @@ -1109,7 +1169,7 @@ class ServicerContext(six.with_metaclass(abc.ABCMeta, RpcContext)): Args: code: A StatusCode object to be sent to the client. It must not be StatusCode.OK. - details: An ASCII-encodable string to be sent to the client upon + details: A UTF-8-encodable string to be sent to the client upon termination of the RPC. Raises: @@ -1118,6 +1178,25 @@ class ServicerContext(six.with_metaclass(abc.ABCMeta, RpcContext)): """ raise NotImplementedError() + @abc.abstractmethod + def abort_with_status(self, status): + """Raises an exception to terminate the RPC with a non-OK status. + + The status passed as argument will supercede any existing status code, + status message and trailing metadata. + + This is an EXPERIMENTAL API. + + Args: + status: A grpc.Status object. The status code in it must not be + StatusCode.OK. + + Raises: + Exception: An exception is always raised to signal the abortion the + RPC to the gRPC runtime. + """ + raise NotImplementedError() + @abc.abstractmethod def set_code(self, code): """Sets the value to be used as status code upon RPC completion. @@ -1138,11 +1217,21 @@ class ServicerContext(six.with_metaclass(abc.ABCMeta, RpcContext)): no details to transmit. Args: - details: An ASCII-encodable string to be sent to the client upon + details: A UTF-8-encodable string to be sent to the client upon termination of the RPC. """ raise NotImplementedError() + def disable_next_message_compression(self): + """Disables compression for the next response message. + + This is an EXPERIMENTAL method. + + This method will override any compression configuration set during + server creation or set on the call. + """ + raise NotImplementedError() + ##################### Service-Side Handler Interfaces ######################## @@ -1641,7 +1730,7 @@ def channel_ready_future(channel): return _utilities.channel_ready_future(channel) -def insecure_channel(target, options=None): +def insecure_channel(target, options=None, compression=None): """Creates an insecure Channel to a server. The returned Channel is thread-safe. @@ -1650,15 +1739,18 @@ def insecure_channel(target, options=None): target: The server address options: An optional list of key-value pairs (channel args in gRPC Core runtime) to configure the channel. + compression: An optional value indicating the compression method to be + used over the lifetime of the channel. This is an EXPERIMENTAL option. Returns: A Channel. """ from grpc import _channel # pylint: disable=cyclic-import - return _channel.Channel(target, () if options is None else options, None) + return _channel.Channel(target, () + if options is None else options, None, compression) -def secure_channel(target, credentials, options=None): +def secure_channel(target, credentials, options=None, compression=None): """Creates a secure Channel to a server. The returned Channel is thread-safe. @@ -1668,13 +1760,15 @@ def secure_channel(target, credentials, options=None): credentials: A ChannelCredentials instance. options: An optional list of key-value pairs (channel args in gRPC Core runtime) to configure the channel. + compression: An optional value indicating the compression method to be + used over the lifetime of the channel. This is an EXPERIMENTAL option. Returns: A Channel. """ from grpc import _channel # pylint: disable=cyclic-import return _channel.Channel(target, () if options is None else options, - credentials._credentials) + credentials._credentials, compression) def intercept_channel(channel, *interceptors): @@ -1709,7 +1803,8 @@ def server(thread_pool, handlers=None, interceptors=None, options=None, - maximum_concurrent_rpcs=None): + maximum_concurrent_rpcs=None, + compression=None): """Creates a Server with which RPCs can be serviced. Args: @@ -1723,10 +1818,13 @@ def server(thread_pool, handlers. The interceptors are given control in the order they are specified. This is an EXPERIMENTAL API. options: An optional list of key-value pairs (channel args in gRPC runtime) - to configure the channel. + to configure the channel. maximum_concurrent_rpcs: The maximum number of concurrent RPCs this server will service before returning RESOURCE_EXHAUSTED status, or None to indicate no limit. + compression: An element of grpc.compression, e.g. + grpc.compression.Gzip. This compression algorithm will be used for the + lifetime of the server unless overridden. This is an EXPERIMENTAL option. Returns: A Server object. @@ -1736,7 +1834,25 @@ def server(thread_pool, if handlers is None else handlers, () if interceptors is None else interceptors, () if options is None else options, - maximum_concurrent_rpcs) + maximum_concurrent_rpcs, compression) + + +@contextlib.contextmanager +def _create_servicer_context(rpc_event, state, request_deserializer): + from grpc import _server # pylint: disable=cyclic-import + context = _server._Context(rpc_event, state, request_deserializer) + yield context + context._finalize_state() # pylint: disable=protected-access + + +class Compression(enum.IntEnum): + """Indicates the compression method to be used for an RPC. + + This enumeration is part of an EXPERIMENTAL API. + """ + NoCompression = _compression.NoCompression + Deflate = _compression.Deflate + Gzip = _compression.Gzip ################################### __all__ ################################# @@ -1747,6 +1863,7 @@ __all__ = ( 'Future', 'ChannelConnectivity', 'StatusCode', + 'Status', 'RpcError', 'RpcContext', 'Call', @@ -1755,6 +1872,7 @@ __all__ = ( 'AuthMetadataContext', 'AuthMetadataPluginCallback', 'AuthMetadataPlugin', + 'Compression', 'ClientCallDetails', 'ServerCertificateConfiguration', 'ServerCredentials', diff --git a/src/python/grpcio/grpc/_auth.py b/src/python/grpcio/grpc/_auth.py index c17824563d7..9b990f490de 100644 --- a/src/python/grpcio/grpc/_auth.py +++ b/src/python/grpcio/grpc/_auth.py @@ -46,7 +46,7 @@ class GoogleCallCredentials(grpc.AuthMetadataPlugin): # Hack to determine if these are JWT creds and we need to pass # additional_claims when getting a token - self._is_jwt = 'additional_claims' in inspect.getargspec( + self._is_jwt = 'additional_claims' in inspect.getargspec( # pylint: disable=deprecated-method credentials.get_access_token).args def __call__(self, context, callback): diff --git a/src/python/grpcio/grpc/_channel.py b/src/python/grpcio/grpc/_channel.py index ab154d85121..1272ee802bc 100644 --- a/src/python/grpcio/grpc/_channel.py +++ b/src/python/grpcio/grpc/_channel.py @@ -19,10 +19,10 @@ import threading import time import grpc +from grpc import _compression from grpc import _common from grpc import _grpcio_metadata from grpc._cython import cygrpc -from grpc.framework.foundation import callable_util _LOGGER = logging.getLogger(__name__) @@ -175,6 +175,7 @@ def _event_handler(state, response_deserializer): return handle_event +#pylint: disable=too-many-statements def _consume_request_iterator(request_iterator, state, call, request_serializer, event_handler): if cygrpc.is_fork_support_enabled(): @@ -247,7 +248,7 @@ def _consume_request_iterator(request_iterator, state, call, request_serializer, consumption_thread.start() -class _Rendezvous(grpc.RpcError, grpc.Future, grpc.Call): +class _Rendezvous(grpc.RpcError, grpc.Future, grpc.Call): # pylint: disable=too-many-ancestors def __init__(self, state, call, response_deserializer, deadline): super(_Rendezvous, self).__init__() @@ -488,6 +489,18 @@ def _stream_unary_invocation_operationses_and_tags(metadata, metadata, initial_metadata_flags)) +def _determine_deadline(user_deadline): + parent_deadline = cygrpc.get_deadline_from_context() + if parent_deadline is None and user_deadline is None: + return None + elif parent_deadline is not None and user_deadline is None: + return parent_deadline + elif user_deadline is not None and parent_deadline is None: + return user_deadline + else: + return min(parent_deadline, user_deadline) + + class _UnaryUnaryMultiCallable(grpc.UnaryUnaryMultiCallable): # pylint: disable=too-many-arguments @@ -498,18 +511,21 @@ class _UnaryUnaryMultiCallable(grpc.UnaryUnaryMultiCallable): self._method = method self._request_serializer = request_serializer self._response_deserializer = response_deserializer + self._context = cygrpc.build_census_context() - def _prepare(self, request, timeout, metadata, wait_for_ready): + def _prepare(self, request, timeout, metadata, wait_for_ready, compression): deadline, serialized_request, rendezvous = _start_unary_request( request, timeout, self._request_serializer) initial_metadata_flags = _InitialMetadataFlags().with_wait_for_ready( wait_for_ready) + augmented_metadata = _compression.augment_metadata( + metadata, compression) if serialized_request is None: return None, None, None, rendezvous else: state = _RPCState(_UNARY_UNARY_INITIAL_DUE, None, None, None, None) operations = ( - cygrpc.SendInitialMetadataOperation(metadata, + cygrpc.SendInitialMetadataOperation(augmented_metadata, initial_metadata_flags), cygrpc.SendMessageOperation(serialized_request, _EMPTY_FLAGS), cygrpc.SendCloseFromClientOperation(_EMPTY_FLAGS), @@ -519,31 +535,33 @@ class _UnaryUnaryMultiCallable(grpc.UnaryUnaryMultiCallable): ) return state, operations, deadline, None - def _blocking(self, request, timeout, metadata, credentials, - wait_for_ready): + def _blocking(self, request, timeout, metadata, credentials, wait_for_ready, + compression): state, operations, deadline, rendezvous = self._prepare( - request, timeout, metadata, wait_for_ready) + request, timeout, metadata, wait_for_ready, compression) if state is None: - raise rendezvous + raise rendezvous # pylint: disable-msg=raising-bad-type else: call = self._channel.segregated_call( - 0, self._method, None, deadline, metadata, None - if credentials is None else credentials._credentials, (( + cygrpc.PropagationConstants.GRPC_PROPAGATE_DEFAULTS, + self._method, None, _determine_deadline(deadline), metadata, + None if credentials is None else credentials._credentials, (( operations, None, - ),)) + ),), self._context) event = call.next_event() _handle_event(event, state, self._response_deserializer) - return state, call, + return state, call def __call__(self, request, timeout=None, metadata=None, credentials=None, - wait_for_ready=None): + wait_for_ready=None, + compression=None): state, call, = self._blocking(request, timeout, metadata, credentials, - wait_for_ready) + wait_for_ready, compression) return _end_unary_response_blocking(state, call, False, None) def with_call(self, @@ -551,9 +569,10 @@ class _UnaryUnaryMultiCallable(grpc.UnaryUnaryMultiCallable): timeout=None, metadata=None, credentials=None, - wait_for_ready=None): + wait_for_ready=None, + compression=None): state, call, = self._blocking(request, timeout, metadata, credentials, - wait_for_ready) + wait_for_ready, compression) return _end_unary_response_blocking(state, call, True, None) def future(self, @@ -561,17 +580,19 @@ class _UnaryUnaryMultiCallable(grpc.UnaryUnaryMultiCallable): timeout=None, metadata=None, credentials=None, - wait_for_ready=None): + wait_for_ready=None, + compression=None): state, operations, deadline, rendezvous = self._prepare( - request, timeout, metadata, wait_for_ready) + request, timeout, metadata, wait_for_ready, compression) if state is None: - raise rendezvous + raise rendezvous # pylint: disable-msg=raising-bad-type else: event_handler = _event_handler(state, self._response_deserializer) call = self._managed_call( - 0, self._method, None, deadline, metadata, None + cygrpc.PropagationConstants.GRPC_PROPAGATE_DEFAULTS, + self._method, None, deadline, metadata, None if credentials is None else credentials._credentials, - (operations,), event_handler) + (operations,), event_handler, self._context) return _Rendezvous(state, call, self._response_deserializer, deadline) @@ -586,24 +607,29 @@ class _UnaryStreamMultiCallable(grpc.UnaryStreamMultiCallable): self._method = method self._request_serializer = request_serializer self._response_deserializer = response_deserializer + self._context = cygrpc.build_census_context() - def __call__(self, - request, - timeout=None, - metadata=None, - credentials=None, - wait_for_ready=None): + def __call__( # pylint: disable=too-many-locals + self, + request, + timeout=None, + metadata=None, + credentials=None, + wait_for_ready=None, + compression=None): deadline, serialized_request, rendezvous = _start_unary_request( request, timeout, self._request_serializer) initial_metadata_flags = _InitialMetadataFlags().with_wait_for_ready( wait_for_ready) if serialized_request is None: - raise rendezvous + raise rendezvous # pylint: disable-msg=raising-bad-type else: + augmented_metadata = _compression.augment_metadata( + metadata, compression) state = _RPCState(_UNARY_STREAM_INITIAL_DUE, None, None, None, None) operationses = ( ( - cygrpc.SendInitialMetadataOperation(metadata, + cygrpc.SendInitialMetadataOperation(augmented_metadata, initial_metadata_flags), cygrpc.SendMessageOperation(serialized_request, _EMPTY_FLAGS), @@ -612,11 +638,13 @@ class _UnaryStreamMultiCallable(grpc.UnaryStreamMultiCallable): ), (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) + cygrpc.PropagationConstants.GRPC_PROPAGATE_DEFAULTS, + self._method, None, _determine_deadline(deadline), metadata, + None if credentials is None else + credentials._credentials, operationses, + _event_handler(state, + self._response_deserializer), self._context) return _Rendezvous(state, call, self._response_deserializer, deadline) @@ -631,18 +659,22 @@ class _StreamUnaryMultiCallable(grpc.StreamUnaryMultiCallable): self._method = method self._request_serializer = request_serializer self._response_deserializer = response_deserializer + self._context = cygrpc.build_census_context() def _blocking(self, request_iterator, timeout, metadata, credentials, - wait_for_ready): + wait_for_ready, compression): deadline = _deadline(timeout) state = _RPCState(_STREAM_UNARY_INITIAL_DUE, None, None, None, None) initial_metadata_flags = _InitialMetadataFlags().with_wait_for_ready( wait_for_ready) + augmented_metadata = _compression.augment_metadata( + metadata, compression) call = self._channel.segregated_call( - 0, self._method, None, deadline, metadata, None + cygrpc.PropagationConstants.GRPC_PROPAGATE_DEFAULTS, self._method, + None, _determine_deadline(deadline), augmented_metadata, None if credentials is None else credentials._credentials, _stream_unary_invocation_operationses_and_tags( - metadata, initial_metadata_flags)) + augmented_metadata, initial_metadata_flags), self._context) _consume_request_iterator(request_iterator, state, call, self._request_serializer, None) while True: @@ -652,16 +684,17 @@ class _StreamUnaryMultiCallable(grpc.StreamUnaryMultiCallable): state.condition.notify_all() if not state.due: break - return state, call, + return state, call def __call__(self, request_iterator, timeout=None, metadata=None, credentials=None, - wait_for_ready=None): + wait_for_ready=None, + compression=None): state, call, = self._blocking(request_iterator, timeout, metadata, - credentials, wait_for_ready) + credentials, wait_for_ready, compression) return _end_unary_response_blocking(state, call, False, None) def with_call(self, @@ -669,9 +702,10 @@ class _StreamUnaryMultiCallable(grpc.StreamUnaryMultiCallable): timeout=None, metadata=None, credentials=None, - wait_for_ready=None): + wait_for_ready=None, + compression=None): state, call, = self._blocking(request_iterator, timeout, metadata, - credentials, wait_for_ready) + credentials, wait_for_ready, compression) return _end_unary_response_blocking(state, call, True, None) def future(self, @@ -679,17 +713,21 @@ class _StreamUnaryMultiCallable(grpc.StreamUnaryMultiCallable): timeout=None, metadata=None, credentials=None, - wait_for_ready=None): + wait_for_ready=None, + compression=None): deadline = _deadline(timeout) state = _RPCState(_STREAM_UNARY_INITIAL_DUE, None, None, None, None) event_handler = _event_handler(state, self._response_deserializer) initial_metadata_flags = _InitialMetadataFlags().with_wait_for_ready( wait_for_ready) + augmented_metadata = _compression.augment_metadata( + metadata, compression) call = self._managed_call( - 0, self._method, None, deadline, metadata, None + cygrpc.PropagationConstants.GRPC_PROPAGATE_DEFAULTS, self._method, + None, deadline, augmented_metadata, None if credentials is None else credentials._credentials, _stream_unary_invocation_operationses( - metadata, initial_metadata_flags), event_handler) + metadata, initial_metadata_flags), event_handler, self._context) _consume_request_iterator(request_iterator, state, call, self._request_serializer, event_handler) return _Rendezvous(state, call, self._response_deserializer, deadline) @@ -705,20 +743,24 @@ class _StreamStreamMultiCallable(grpc.StreamStreamMultiCallable): self._method = method self._request_serializer = request_serializer self._response_deserializer = response_deserializer + self._context = cygrpc.build_census_context() def __call__(self, request_iterator, timeout=None, metadata=None, credentials=None, - wait_for_ready=None): + wait_for_ready=None, + compression=None): deadline = _deadline(timeout) state = _RPCState(_STREAM_STREAM_INITIAL_DUE, None, None, None, None) initial_metadata_flags = _InitialMetadataFlags().with_wait_for_ready( wait_for_ready) + augmented_metadata = _compression.augment_metadata( + metadata, compression) operationses = ( ( - cygrpc.SendInitialMetadataOperation(metadata, + cygrpc.SendInitialMetadataOperation(augmented_metadata, initial_metadata_flags), cygrpc.ReceiveStatusOnClientOperation(_EMPTY_FLAGS), ), @@ -726,9 +768,10 @@ class _StreamStreamMultiCallable(grpc.StreamStreamMultiCallable): ) event_handler = _event_handler(state, self._response_deserializer) call = self._managed_call( - 0, self._method, None, deadline, metadata, None + cygrpc.PropagationConstants.GRPC_PROPAGATE_DEFAULTS, self._method, + None, _determine_deadline(deadline), augmented_metadata, None if credentials is None else credentials._credentials, operationses, - event_handler) + event_handler, self._context) _consume_request_iterator(request_iterator, state, call, self._request_serializer, event_handler) return _Rendezvous(state, call, self._response_deserializer, deadline) @@ -744,10 +787,10 @@ class _InitialMetadataFlags(int): def with_wait_for_ready(self, wait_for_ready): if wait_for_ready is not None: if wait_for_ready: - self = self.__class__(self | cygrpc.InitialMetadataFlags.wait_for_ready | \ + return self.__class__(self | cygrpc.InitialMetadataFlags.wait_for_ready | \ cygrpc.InitialMetadataFlags.wait_for_ready_explicitly_set) elif not wait_for_ready: - self = self.__class__(self & ~cygrpc.InitialMetadataFlags.wait_for_ready | \ + return self.__class__(self & ~cygrpc.InitialMetadataFlags.wait_for_ready | \ cygrpc.InitialMetadataFlags.wait_for_ready_explicitly_set) return self @@ -788,7 +831,7 @@ def _channel_managed_call_management(state): # pylint: disable=too-many-arguments def create(flags, method, host, deadline, metadata, credentials, - operationses, event_handler): + operationses, event_handler, context): """Creates a cygrpc.IntegratedCall. Args: @@ -803,7 +846,7 @@ def _channel_managed_call_management(state): started on the call. event_handler: A behavior to call to handle the events resultant from the operations on the call. - + context: Context object for distributed tracing. Returns: A cygrpc.IntegratedCall with which to conduct an RPC. """ @@ -814,7 +857,7 @@ def _channel_managed_call_management(state): with state.lock: call = state.channel.integrated_call(flags, method, host, deadline, metadata, credentials, - operationses_and_tags) + operationses_and_tags, context) if state.managed_calls == 0: state.managed_calls = 1 _run_channel_spin_thread(state) @@ -860,9 +903,11 @@ def _deliver(state, initial_connectivity, initial_callbacks): while True: for callback in callbacks: cygrpc.block_if_fork_in_progress(state) - callable_util.call_logging_exceptions( - callback, _CHANNEL_SUBSCRIPTION_CALLBACK_ERROR_LOG_MESSAGE, - connectivity) + try: + callback(connectivity) + except Exception: # pylint: disable=broad-except + _LOGGER.exception( + _CHANNEL_SUBSCRIPTION_CALLBACK_ERROR_LOG_MESSAGE) with state.lock: callbacks = _deliveries(state) if callbacks: @@ -955,28 +1000,30 @@ def _unsubscribe(state, callback): break -def _options(options): - return list(options) + [ - ( - cygrpc.ChannelArgKey.primary_user_agent_string, - _USER_AGENT, - ), - ] +def _augment_options(base_options, compression): + compression_option = _compression.create_channel_option(compression) + return tuple(base_options) + compression_option + (( + cygrpc.ChannelArgKey.primary_user_agent_string, + _USER_AGENT, + ),) class Channel(grpc.Channel): """A cygrpc.Channel-backed implementation of grpc.Channel.""" - def __init__(self, target, options, credentials): + def __init__(self, target, options, credentials, compression): """Constructor. Args: target: The target to which to connect. options: Configuration options for the channel. credentials: A cygrpc.ChannelCredentials or None. + compression: An optional value indicating the compression method to be + used over the lifetime of the channel. """ self._channel = cygrpc.Channel( - _common.encode(target), _options(options), credentials) + _common.encode(target), _augment_options(options, compression), + credentials) self._call_state = _ChannelCallState(self._channel) self._connectivity_state = _ChannelConnectivityState(self._channel) cygrpc.fork_register_channel(self) @@ -1021,6 +1068,7 @@ class Channel(grpc.Channel): def _close(self): self._channel.close(cygrpc.StatusCode.cancelled, 'Channel closed!') + cygrpc.fork_unregister_channel(self) _moot(self._connectivity_state) def _close_on_fork(self): @@ -1048,9 +1096,7 @@ class Channel(grpc.Channel): # 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. - if cygrpc is not None: # Globals may have already been collected. - cygrpc.fork_unregister_channel(self) # This prevent the failed-at-initializing object removal from failing. # Though the __init__ failed, the removal will still trigger __del__. - if _moot is not None and hasattr(self, "_connectivity_state"): + if _moot is not None and hasattr(self, '_connectivity_state'): _moot(self._connectivity_state) diff --git a/src/python/grpcio/grpc/_compression.py b/src/python/grpcio/grpc/_compression.py new file mode 100644 index 00000000000..45339c3afe2 --- /dev/null +++ b/src/python/grpcio/grpc/_compression.py @@ -0,0 +1,55 @@ +# Copyright 2019 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. +# 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 grpc._cython import cygrpc + +NoCompression = cygrpc.CompressionAlgorithm.none +Deflate = cygrpc.CompressionAlgorithm.deflate +Gzip = cygrpc.CompressionAlgorithm.gzip + +_METADATA_STRING_MAPPING = { + NoCompression: 'identity', + Deflate: 'deflate', + Gzip: 'gzip', +} + + +def _compression_algorithm_to_metadata_value(compression): + return _METADATA_STRING_MAPPING[compression] + + +def compression_algorithm_to_metadata(compression): + return (cygrpc.GRPC_COMPRESSION_REQUEST_ALGORITHM_MD_KEY, + _compression_algorithm_to_metadata_value(compression)) + + +def create_channel_option(compression): + return ((cygrpc.GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM, + int(compression)),) if compression else () + + +def augment_metadata(metadata, compression): + if not metadata and not compression: + return None + base_metadata = tuple(metadata) if metadata else () + compression_metadata = ( + compression_algorithm_to_metadata(compression),) if compression else () + return base_metadata + compression_metadata + + +__all__ = ( + "NoCompression", + "Deflate", + "Gzip", +) diff --git a/src/python/grpcio/grpc/_cython/BUILD.bazel b/src/python/grpcio/grpc/_cython/BUILD.bazel index cfd3a51d9bb..18b1c92b9a7 100644 --- a/src/python/grpcio/grpc/_cython/BUILD.bazel +++ b/src/python/grpcio/grpc/_cython/BUILD.bazel @@ -6,45 +6,49 @@ pyx_library( name = "cygrpc", srcs = [ "__init__.py", + "_cygrpc/_hooks.pxd.pxi", + "_cygrpc/_hooks.pyx.pxi", + "_cygrpc/arguments.pxd.pxi", + "_cygrpc/arguments.pyx.pxi", + "_cygrpc/call.pxd.pxi", + "_cygrpc/call.pyx.pxi", + "_cygrpc/channel.pxd.pxi", + "_cygrpc/channel.pyx.pxi", + "_cygrpc/channelz.pyx.pxi", + "_cygrpc/completion_queue.pxd.pxi", + "_cygrpc/completion_queue.pyx.pxi", + "_cygrpc/credentials.pxd.pxi", + "_cygrpc/credentials.pyx.pxi", + "_cygrpc/event.pxd.pxi", + "_cygrpc/event.pyx.pxi", + "_cygrpc/fork_posix.pxd.pxi", + "_cygrpc/fork_posix.pyx.pxi", + "_cygrpc/grpc.pxi", + "_cygrpc/grpc_gevent.pxd.pxi", + "_cygrpc/grpc_gevent.pyx.pxi", + "_cygrpc/grpc_string.pyx.pxi", + "_cygrpc/metadata.pxd.pxi", + "_cygrpc/metadata.pyx.pxi", + "_cygrpc/operation.pxd.pxi", + "_cygrpc/operation.pyx.pxi", + "_cygrpc/propagation_bits.pxd.pxi", + "_cygrpc/propagation_bits.pyx.pxi", + "_cygrpc/records.pxd.pxi", + "_cygrpc/records.pyx.pxi", + "_cygrpc/security.pxd.pxi", + "_cygrpc/security.pyx.pxi", + "_cygrpc/server.pxd.pxi", + "_cygrpc/server.pyx.pxi", + "_cygrpc/tag.pxd.pxi", + "_cygrpc/tag.pyx.pxi", + "_cygrpc/time.pxd.pxi", + "_cygrpc/time.pyx.pxi", + "_cygrpc/vtable.pxd.pxi", + "_cygrpc/vtable.pyx.pxi", "cygrpc.pxd", "cygrpc.pyx", - "_cygrpc/_hooks.pyx.pxi", - "_cygrpc/grpc_string.pyx.pxi", - "_cygrpc/arguments.pyx.pxi", - "_cygrpc/call.pyx.pxi", - "_cygrpc/channel.pyx.pxi", - "_cygrpc/credentials.pyx.pxi", - "_cygrpc/completion_queue.pyx.pxi", - "_cygrpc/event.pyx.pxi", - "_cygrpc/fork_posix.pyx.pxi", - "_cygrpc/metadata.pyx.pxi", - "_cygrpc/operation.pyx.pxi", - "_cygrpc/records.pyx.pxi", - "_cygrpc/security.pyx.pxi", - "_cygrpc/server.pyx.pxi", - "_cygrpc/tag.pyx.pxi", - "_cygrpc/time.pyx.pxi", - "_cygrpc/grpc_gevent.pyx.pxi", - "_cygrpc/grpc.pxi", - "_cygrpc/_hooks.pxd.pxi", - "_cygrpc/arguments.pxd.pxi", - "_cygrpc/call.pxd.pxi", - "_cygrpc/channel.pxd.pxi", - "_cygrpc/credentials.pxd.pxi", - "_cygrpc/completion_queue.pxd.pxi", - "_cygrpc/event.pxd.pxi", - "_cygrpc/fork_posix.pxd.pxi", - "_cygrpc/metadata.pxd.pxi", - "_cygrpc/operation.pxd.pxi", - "_cygrpc/records.pxd.pxi", - "_cygrpc/security.pxd.pxi", - "_cygrpc/server.pxd.pxi", - "_cygrpc/tag.pxd.pxi", - "_cygrpc/time.pxd.pxi", - "_cygrpc/grpc_gevent.pxd.pxi", ], deps = [ - "//:grpc", + "//:grpc", ], ) - diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/_hooks.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/_hooks.pyx.pxi index 38cf629dc24..de4d71b8196 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/_hooks.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/_hooks.pyx.pxi @@ -15,3 +15,21 @@ cdef object _custom_op_on_c_call(int op, grpc_call *call): raise NotImplementedError("No custom hooks are implemented") + +def install_context_from_request_call_event(RequestCallEvent event): + pass + +def uninstall_context(): + pass + +def build_census_context(): + pass + +cdef class CensusContext: + pass + +def set_census_context_on_call(_CallState call_state, CensusContext census_ctx): + pass + +def get_deadline_from_context(): + return None diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/arguments.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/arguments.pxd.pxi index e0e068e4524..9415b16344a 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/arguments.pxd.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/arguments.pxd.pxi @@ -13,34 +13,24 @@ # limitations under the License. -cdef void* _copy_pointer(void* pointer) - - -cdef void _destroy_pointer(void* pointer) - - -cdef int _compare_pointer(void* first_pointer, void* second_pointer) - - cdef tuple _wrap_grpc_arg(grpc_arg arg) cdef grpc_arg _unwrap_grpc_arg(tuple wrapped_arg) -cdef class _ArgumentProcessor: +cdef class _ChannelArg: cdef grpc_arg c_argument - cdef void c(self, argument, grpc_arg_pointer_vtable *vtable, references) except * + cdef void c(self, argument, _VTable vtable, references) except * -cdef class _ArgumentsProcessor: +cdef class _ChannelArgs: cdef readonly tuple _arguments - cdef list _argument_processors + cdef list _channel_args cdef readonly list _references cdef grpc_channel_args _c_arguments - cdef grpc_channel_args *c(self, grpc_arg_pointer_vtable *vtable) except * - cdef un_c(self) + cdef grpc_channel_args *c_args(self) except * diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/arguments.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/arguments.pyx.pxi index b7a4277ff64..9211354b1ca 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/arguments.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/arguments.pyx.pxi @@ -15,25 +15,6 @@ cimport cpython -# TODO(https://github.com/grpc/grpc/issues/15662): Reform this. -cdef void* _copy_pointer(void* pointer): - return pointer - - -# TODO(https://github.com/grpc/grpc/issues/15662): Reform this. -cdef void _destroy_pointer(void* pointer): - pass - - -cdef int _compare_pointer(void* first_pointer, void* second_pointer): - if first_pointer < second_pointer: - return -1 - elif first_pointer > second_pointer: - return 1 - else: - return 0 - - cdef class _GrpcArgWrapper: cdef grpc_arg arg @@ -50,9 +31,9 @@ cdef grpc_arg _unwrap_grpc_arg(tuple wrapped_arg): return wrapped.arg -cdef class _ArgumentProcessor: +cdef class _ChannelArg: - cdef void c(self, argument, grpc_arg_pointer_vtable *vtable, references) except *: + cdef void c(self, argument, _VTable vtable, references) except *: key, value = argument cdef bytes encoded_key = _encode(key) if encoded_key is not key: @@ -75,34 +56,32 @@ cdef class _ArgumentProcessor: # lifecycle of the pointer is fixed to the lifecycle of the # python object wrapping it. self.c_argument.type = GRPC_ARG_POINTER - self.c_argument.value.pointer.vtable = vtable + self.c_argument.value.pointer.vtable = &vtable.c_vtable self.c_argument.value.pointer.address = (int(value)) else: raise TypeError( 'Expected int, bytes, or behavior, got {}'.format(type(value))) -cdef class _ArgumentsProcessor: +cdef class _ChannelArgs: - def __cinit__(self, arguments): + def __cinit__(self, arguments, _VTable vtable not None): self._arguments = () if arguments is None else tuple(arguments) - self._argument_processors = [] + self._channel_args = [] self._references = [] - - cdef grpc_channel_args *c(self, grpc_arg_pointer_vtable *vtable) except *: self._c_arguments.arguments_length = len(self._arguments) - if self._c_arguments.arguments_length == 0: - return NULL - else: + if self._c_arguments.arguments_length != 0: self._c_arguments.arguments = gpr_malloc( self._c_arguments.arguments_length * sizeof(grpc_arg)) for index, argument in enumerate(self._arguments): - argument_processor = _ArgumentProcessor() - argument_processor.c(argument, vtable, self._references) - self._c_arguments.arguments[index] = argument_processor.c_argument - self._argument_processors.append(argument_processor) - return &self._c_arguments + channel_arg = _ChannelArg() + channel_arg.c(argument, vtable, self._references) + self._c_arguments.arguments[index] = channel_arg.c_argument + self._channel_args.append(channel_arg) - cdef un_c(self): - if self._arguments: + cdef grpc_channel_args *c_args(self) except *: + return &self._c_arguments + + def __dealloc__(self): + if self._c_arguments.arguments != NULL: gpr_free(self._c_arguments.arguments) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi index 24e85b08e72..84934db4d60 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi @@ -17,11 +17,11 @@ cimport cpython cdef class Call: - def __cinit__(self): + def __cinit__(self, _VTable vtable not None): # Create an *empty* call fork_handlers_and_grpc_init() self.c_call = NULL - self.references = [] + self.references = [vtable] def _start_batch(self, operations, tag, retain_self): if not self.is_valid: @@ -85,9 +85,10 @@ cdef class Call: return result def __dealloc__(self): - if self.c_call != NULL: - grpc_call_unref(self.c_call) - grpc_shutdown() + with nogil: + if self.c_call != NULL: + grpc_call_unref(self.c_call) + grpc_shutdown_blocking() # The object *should* always be valid from Python. Used for debugging. @property diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pxd.pxi index ced32abba14..13c0c02ab21 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pxd.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pxd.pxi @@ -68,8 +68,8 @@ cdef class SegregatedCall: cdef class Channel: - cdef grpc_arg_pointer_vtable _vtable cdef _ChannelState _state + cdef _VTable _vtable # TODO(https://github.com/grpc/grpc/issues/15662): Eliminate this. cdef tuple _arguments diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi index a81ff4d823b..ca637094353 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi @@ -159,7 +159,8 @@ 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 *: + object operationses_and_user_tags, object metadata, + object context) except *: """Invokes an RPC. Args: @@ -185,6 +186,7 @@ cdef void _call( 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. + context: Context object for distributed tracing. """ cdef grpc_slice method_slice cdef grpc_slice host_slice @@ -208,6 +210,8 @@ cdef void _call( grpc_slice_unref(method_slice) if host_slice_ptr: grpc_slice_unref(host_slice) + if context is not None: + set_census_context_on_call(call_state, context) if credentials is not None: c_call_credentials = credentials.c() c_call_error = grpc_call_set_credentials( @@ -257,7 +261,8 @@ cdef class IntegratedCall: cdef IntegratedCall _integrated_call( _ChannelState state, int flags, method, host, object deadline, - object metadata, CallCredentials credentials, operationses_and_user_tags): + object metadata, CallCredentials credentials, operationses_and_user_tags, + object context): call_state = _CallState() def on_success(started_tags): @@ -266,7 +271,7 @@ cdef IntegratedCall _integrated_call( _call( state, call_state, state.c_call_completion_queue, on_success, flags, - method, host, deadline, credentials, operationses_and_user_tags, metadata) + method, host, deadline, credentials, operationses_and_user_tags, metadata, context) return IntegratedCall(state, call_state) @@ -308,7 +313,8 @@ cdef class SegregatedCall: cdef SegregatedCall _segregated_call( _ChannelState state, int flags, method, host, object deadline, - object metadata, CallCredentials credentials, operationses_and_user_tags): + object metadata, CallCredentials credentials, operationses_and_user_tags, + object context): cdef _CallState call_state = _CallState() cdef SegregatedCall segregated_call cdef grpc_completion_queue *c_completion_queue @@ -325,7 +331,8 @@ cdef SegregatedCall _segregated_call( try: _call( state, call_state, c_completion_queue, on_success, flags, method, host, - deadline, credentials, operationses_and_user_tags, metadata) + deadline, credentials, operationses_and_user_tags, metadata, + context) except: _destroy_c_completion_queue(c_completion_queue) raise @@ -392,7 +399,7 @@ cdef _close(Channel channel, grpc_status_code code, object details, _destroy_c_completion_queue(state.c_connectivity_completion_queue) grpc_channel_destroy(state.c_channel) state.c_channel = NULL - grpc_shutdown() + grpc_shutdown_blocking() state.condition.notify_all() else: # Another call to close already completed in the past or is currently @@ -413,25 +420,22 @@ cdef class Channel: arguments = () if arguments is None else tuple(arguments) fork_handlers_and_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) - if channel_credentials is None: - self._state.c_channel = grpc_insecure_channel_create( - target, c_arguments, NULL) - else: - c_channel_credentials = channel_credentials.c() - self._state.c_channel = grpc_secure_channel_create( - c_channel_credentials, target, c_arguments, NULL) - grpc_channel_credentials_release(c_channel_credentials) 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)) self._arguments = arguments + self._vtable = _VTable() + cdef _ChannelArgs channel_args = _ChannelArgs( + arguments, self._vtable) + if channel_credentials is None: + self._state.c_channel = grpc_insecure_channel_create( + target, channel_args.c_args(), NULL) + else: + c_channel_credentials = channel_credentials.c() + self._state.c_channel = grpc_secure_channel_create( + c_channel_credentials, target, channel_args.c_args(), NULL) + grpc_channel_credentials_release(c_channel_credentials) def target(self): cdef char *c_target @@ -443,10 +447,11 @@ cdef class Channel: def integrated_call( self, int flags, method, host, object deadline, object metadata, - CallCredentials credentials, operationses_and_tags): + CallCredentials credentials, operationses_and_tags, + object context = None): return _integrated_call( self._state, flags, method, host, deadline, metadata, credentials, - operationses_and_tags) + operationses_and_tags, context) def next_call_event(self): def on_success(tag): @@ -461,10 +466,11 @@ cdef class Channel: def segregated_call( self, int flags, method, host, object deadline, object metadata, - CallCredentials credentials, operationses_and_tags): + CallCredentials credentials, operationses_and_tags, + object context = None): return _segregated_call( self._state, flags, method, host, deadline, metadata, credentials, - operationses_and_tags) + operationses_and_tags, context) def check_connectivity_state(self, bint try_to_connect): with self._state.condition: diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/channelz.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/channelz.pyx.pxi new file mode 100644 index 00000000000..36c8cd121c7 --- /dev/null +++ b/src/python/grpcio/grpc/_cython/_cygrpc/channelz.pyx.pxi @@ -0,0 +1,71 @@ +# Copyright 2018 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. +# 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. + + +def channelz_get_top_channels(start_channel_id): + cdef char *c_returned_str = grpc_channelz_get_top_channels( + start_channel_id, + ) + if c_returned_str == NULL: + raise ValueError('Failed to get top channels, please ensure your' \ + ' start_channel_id==%s is valid' % start_channel_id) + return c_returned_str + +def channelz_get_servers(start_server_id): + cdef char *c_returned_str = grpc_channelz_get_servers(start_server_id) + if c_returned_str == NULL: + raise ValueError('Failed to get servers, please ensure your' \ + ' start_server_id==%s is valid' % start_server_id) + return c_returned_str + +def channelz_get_server(server_id): + cdef char *c_returned_str = grpc_channelz_get_server(server_id) + if c_returned_str == NULL: + raise ValueError('Failed to get the server, please ensure your' \ + ' server_id==%s is valid' % server_id) + return c_returned_str + +def channelz_get_server_sockets(server_id, start_socket_id, max_results): + cdef char *c_returned_str = grpc_channelz_get_server_sockets( + server_id, + start_socket_id, + max_results, + ) + if c_returned_str == NULL: + raise ValueError('Failed to get server sockets, please ensure your' \ + ' server_id==%s and start_socket_id==%s and' \ + ' max_results==%s is valid' % + (server_id, start_socket_id, max_results)) + return c_returned_str + +def channelz_get_channel(channel_id): + cdef char *c_returned_str = grpc_channelz_get_channel(channel_id) + if c_returned_str == NULL: + raise ValueError('Failed to get the channel, please ensure your' \ + ' channel_id==%s is valid' % (channel_id)) + return c_returned_str + +def channelz_get_subchannel(subchannel_id): + cdef char *c_returned_str = grpc_channelz_get_subchannel(subchannel_id) + if c_returned_str == NULL: + raise ValueError('Failed to get the subchannel, please ensure your' \ + ' subchannel_id==%s is valid' % (subchannel_id)) + return c_returned_str + +def channelz_get_socket(socket_id): + cdef char *c_returned_str = grpc_channelz_get_socket(socket_id) + if c_returned_str == NULL: + raise ValueError('Failed to get the socket, please ensure your' \ + ' socket_id==%s is valid' % (socket_id)) + return c_returned_str 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 9f06ce086ee..0307f74cbef 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pxd.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pxd.pxi @@ -13,7 +13,7 @@ # limitations under the License. -cdef grpc_event _next(grpc_completion_queue *c_completion_queue, deadline) +cdef grpc_event _next(grpc_completion_queue *c_completion_queue, deadline) except * cdef _interpret_event(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 141116df5dd..325e72afa0a 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi @@ -20,7 +20,7 @@ import time cdef int _INTERRUPT_CHECK_PERIOD_MS = 200 -cdef grpc_event _next(grpc_completion_queue *c_completion_queue, deadline): +cdef grpc_event _next(grpc_completion_queue *c_completion_queue, deadline) except *: cdef gpr_timespec c_increment cdef gpr_timespec c_timeout cdef gpr_timespec c_deadline @@ -30,26 +30,27 @@ cdef grpc_event _next(grpc_completion_queue *c_completion_queue, deadline): else: c_deadline = _timespec_from_time(deadline) - with nogil: - while True: + while True: + with nogil: 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() + # Handle any signals + 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. + # TODO(ericgribkoff) Do not 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. @@ -118,4 +119,4 @@ cdef class CompletionQueue: self.c_completion_queue, c_deadline, NULL) self._interpret_event(event) grpc_completion_queue_destroy(self.c_completion_queue) - grpc_shutdown() + grpc_shutdown_blocking() diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pxd.pxi index 8d732152478..af069acc287 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pxd.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pxd.pxi @@ -15,7 +15,7 @@ cdef class CallCredentials: - cdef grpc_call_credentials *c(self) + cdef grpc_call_credentials *c(self) except * # TODO(https://github.com/grpc/grpc/issues/12531): remove. cdef grpc_call_credentials *c_credentials @@ -36,7 +36,7 @@ cdef class MetadataPluginCallCredentials(CallCredentials): cdef readonly object _metadata_plugin cdef readonly bytes _name - cdef grpc_call_credentials *c(self) + cdef grpc_call_credentials *c(self) except * cdef grpc_call_credentials *_composition(call_credentialses) @@ -46,15 +46,12 @@ cdef class CompositeCallCredentials(CallCredentials): cdef readonly tuple _call_credentialses - cdef grpc_call_credentials *c(self) + cdef grpc_call_credentials *c(self) except * cdef class ChannelCredentials: - cdef grpc_channel_credentials *c(self) - - # TODO(https://github.com/grpc/grpc/issues/12531): remove. - cdef grpc_channel_credentials *c_credentials + cdef grpc_channel_credentials *c(self) except * cdef class SSLSessionCacheLRU: @@ -68,7 +65,7 @@ cdef class SSLChannelCredentials(ChannelCredentials): cdef readonly object _private_key cdef readonly object _certificate_chain - cdef grpc_channel_credentials *c(self) + cdef grpc_channel_credentials *c(self) except * cdef class CompositeChannelCredentials(ChannelCredentials): @@ -76,7 +73,7 @@ cdef class CompositeChannelCredentials(ChannelCredentials): cdef readonly tuple _call_credentialses cdef readonly ChannelCredentials _channel_credentials - cdef grpc_channel_credentials *c(self) + cdef grpc_channel_credentials *c(self) except * cdef class ServerCertificateConfig: diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi index 63048e8da0d..52ca92f2e9f 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi @@ -17,8 +17,6 @@ cimport cpython import grpc import threading -from libc.stdint cimport uintptr_t - def _spawn_callback_in_thread(cb_func, args): ForkManagedThread(target=cb_func, args=args).start() @@ -35,7 +33,7 @@ def _spawn_callback_async(callback, args): cdef class CallCredentials: - cdef grpc_call_credentials *c(self): + cdef grpc_call_credentials *c(self) except *: raise NotImplementedError() @@ -61,6 +59,7 @@ cdef int _get_metadata( cdef void _destroy(void *state) with gil: cpython.Py_DECREF(state) + grpc_shutdown_blocking() cdef class MetadataPluginCallCredentials(CallCredentials): @@ -69,13 +68,14 @@ cdef class MetadataPluginCallCredentials(CallCredentials): self._metadata_plugin = metadata_plugin self._name = name - cdef grpc_call_credentials *c(self): + cdef grpc_call_credentials *c(self) except *: cdef grpc_metadata_credentials_plugin c_metadata_plugin c_metadata_plugin.get_metadata = _get_metadata c_metadata_plugin.destroy = _destroy c_metadata_plugin.state = self._metadata_plugin c_metadata_plugin.type = self._name cpython.Py_INCREF(self._metadata_plugin) + fork_handlers_and_grpc_init() return grpc_metadata_credentials_create_from_plugin(c_metadata_plugin, NULL) @@ -101,13 +101,13 @@ cdef class CompositeCallCredentials(CallCredentials): def __cinit__(self, call_credentialses): self._call_credentialses = call_credentialses - cdef grpc_call_credentials *c(self): + cdef grpc_call_credentials *c(self) except *: return _composition(self._call_credentialses) cdef class ChannelCredentials: - cdef grpc_channel_credentials *c(self): + cdef grpc_channel_credentials *c(self) except *: raise NotImplementedError() @@ -123,17 +123,19 @@ cdef class SSLSessionCacheLRU: def __dealloc__(self): if self._cache != NULL: grpc_ssl_session_cache_destroy(self._cache) - grpc_shutdown() + grpc_shutdown_blocking() cdef class SSLChannelCredentials(ChannelCredentials): def __cinit__(self, pem_root_certificates, private_key, certificate_chain): + if pem_root_certificates is not None and not isinstance(pem_root_certificates, bytes): + raise TypeError('expected certificate to be bytes, got %s' % (type(pem_root_certificates))) self._pem_root_certificates = pem_root_certificates self._private_key = private_key self._certificate_chain = certificate_chain - cdef grpc_channel_credentials *c(self): + cdef grpc_channel_credentials *c(self) except *: cdef const char *c_pem_root_certificates cdef grpc_ssl_pem_key_cert_pair c_pem_key_certificate_pair if self._pem_root_certificates is None: @@ -162,7 +164,7 @@ cdef class CompositeChannelCredentials(ChannelCredentials): self._call_credentialses = call_credentialses self._channel_credentials = channel_credentials - cdef grpc_channel_credentials *c(self): + cdef grpc_channel_credentials *c(self) except *: cdef grpc_channel_credentials *c_channel_credentials c_channel_credentials = self._channel_credentials.c() cdef grpc_call_credentials *c_call_credentials_composition = _composition( @@ -187,7 +189,7 @@ cdef class ServerCertificateConfig: def __dealloc__(self): grpc_ssl_server_certificate_config_destroy(self.c_cert_config) gpr_free(self.c_ssl_pem_key_cert_pairs) - grpc_shutdown() + grpc_shutdown_blocking() cdef class ServerCredentials: @@ -203,7 +205,7 @@ cdef class ServerCredentials: def __dealloc__(self): if self.c_credentials != NULL: grpc_server_credentials_release(self.c_credentials) - grpc_shutdown() + grpc_shutdown_blocking() cdef const char* _get_c_pem_root_certs(pem_root_certs): if pem_root_certs is None: diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/fork_posix.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/fork_posix.pyx.pxi index 433ae1f374f..6dbd6a985e3 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/fork_posix.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/fork_posix.pyx.pxi @@ -12,7 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. - import logging import os import threading @@ -37,8 +36,12 @@ _GRPC_ENABLE_FORK_SUPPORT = ( os.environ.get('GRPC_ENABLE_FORK_SUPPORT', '0') .lower() in _TRUE_VALUES) +_fork_handler_failed = False + cdef void __prefork() nogil: with gil: + global _fork_handler_failed + _fork_handler_failed = False with _fork_state.fork_in_progress_condition: _fork_state.fork_in_progress = True if not _fork_state.active_thread_count.await_zero_threads( @@ -46,6 +49,7 @@ cdef void __prefork() nogil: _LOGGER.error( 'Failed to shutdown gRPC Python threads prior to fork. ' 'Behavior after fork will be undefined.') + _fork_handler_failed = True cdef void __postfork_parent() nogil: @@ -57,20 +61,28 @@ cdef void __postfork_parent() nogil: cdef void __postfork_child() nogil: with gil: - # Thread could be holding the fork_in_progress_condition inside of - # block_if_fork_in_progress() when fork occurs. Reset the lock here. - _fork_state.fork_in_progress_condition = threading.Condition() - # A thread in return_from_user_request_generator() may hold this lock - # when fork occurs. - _fork_state.active_thread_count = _ActiveThreadCount() - for state_to_reset in _fork_state.postfork_states_to_reset: - state_to_reset.reset_postfork_child() - _fork_state.fork_epoch += 1 - for channel in _fork_state.channels: - channel._close_on_fork() - # TODO(ericgribkoff) Check and abort if core is not shutdown - with _fork_state.fork_in_progress_condition: - _fork_state.fork_in_progress = False + try: + if _fork_handler_failed: + return + # Thread could be holding the fork_in_progress_condition inside of + # block_if_fork_in_progress() when fork occurs. Reset the lock here. + _fork_state.fork_in_progress_condition = threading.Condition() + # A thread in return_from_user_request_generator() may hold this lock + # when fork occurs. + _fork_state.active_thread_count = _ActiveThreadCount() + for state_to_reset in _fork_state.postfork_states_to_reset: + state_to_reset.reset_postfork_child() + _fork_state.postfork_states_to_reset = [] + _fork_state.fork_epoch += 1 + for channel in _fork_state.channels: + channel._close_on_fork() + with _fork_state.fork_in_progress_condition: + _fork_state.fork_in_progress = False + except: + _LOGGER.error('Exiting child due to raised exception') + _LOGGER.error(sys.exc_info()[0]) + os._exit(os.EX_USAGE) + if grpc_is_initialized() > 0: with gil: _LOGGER.error('Failed to shutdown gRPC Core after fork()') @@ -148,7 +160,7 @@ def fork_register_channel(channel): def fork_unregister_channel(channel): if _GRPC_ENABLE_FORK_SUPPORT: - _fork_state.channels.remove(channel) + _fork_state.channels.discard(channel) class _ActiveThreadCount(object): diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi index 23428f0b0c0..057d0776983 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi @@ -14,13 +14,16 @@ cimport libc.time - -# Typedef types with approximately the same semantics to provide their names to -# Cython -ctypedef unsigned char uint8_t -ctypedef int int32_t -ctypedef unsigned uint32_t -ctypedef long int64_t +ctypedef ssize_t intptr_t +ctypedef size_t uintptr_t +ctypedef signed char int8_t +ctypedef signed short int16_t +ctypedef signed int int32_t +ctypedef signed long long int64_t +ctypedef unsigned char uint8_t +ctypedef unsigned short uint16_t +ctypedef unsigned int uint32_t +ctypedef unsigned long long uint64_t cdef extern from "grpc/support/alloc.h": @@ -60,6 +63,10 @@ cdef extern from "grpc/grpc.h": void *grpc_slice_start_ptr "GRPC_SLICE_START_PTR" (grpc_slice s) nogil size_t grpc_slice_length "GRPC_SLICE_LENGTH" (grpc_slice s) nogil + const int GPR_MS_PER_SEC + const int GPR_US_PER_SEC + const int GPR_NS_PER_SEC + ctypedef enum gpr_clock_type: GPR_CLOCK_MONOTONIC GPR_CLOCK_REALTIME @@ -81,6 +88,8 @@ cdef extern from "grpc/grpc.h": gpr_clock_type target_clock) nogil gpr_timespec gpr_time_from_millis(int64_t ms, gpr_clock_type type) nogil + gpr_timespec gpr_time_from_nanos(int64_t ns, gpr_clock_type type) nogil + double gpr_timespec_to_micros(gpr_timespec t) nogil gpr_timespec gpr_time_add(gpr_timespec a, gpr_timespec b) nogil @@ -121,7 +130,6 @@ cdef extern from "grpc/grpc.h": GRPC_STATUS_DATA_LOSS GRPC_STATUS__DO_NOT_USE - const char *GRPC_ARG_PRIMARY_USER_AGENT_STRING const char *GRPC_ARG_ENABLE_CENSUS const char *GRPC_ARG_MAX_CONCURRENT_STREAMS const char *GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH @@ -132,7 +140,8 @@ cdef extern from "grpc/grpc.h": const char *GRPC_ARG_SECONDARY_USER_AGENT_STRING const char *GRPC_SSL_TARGET_NAME_OVERRIDE_ARG const char *GRPC_SSL_SESSION_CACHE_ARG - const char *GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM + const char *_GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM \ + "GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM" const char *GRPC_COMPRESSION_CHANNEL_DEFAULT_LEVEL const char *GRPC_COMPRESSION_CHANNEL_ENABLED_ALGORITHMS_BITSET @@ -190,12 +199,6 @@ cdef extern from "grpc/grpc.h": size_t arguments_length "num_args" grpc_arg *arguments "args" - ctypedef enum grpc_compression_level: - GRPC_COMPRESS_LEVEL_NONE - GRPC_COMPRESS_LEVEL_LOW - GRPC_COMPRESS_LEVEL_MED - GRPC_COMPRESS_LEVEL_HIGH - ctypedef enum grpc_stream_compression_level: GRPC_STREAM_COMPRESS_LEVEL_NONE GRPC_STREAM_COMPRESS_LEVEL_LOW @@ -325,7 +328,7 @@ cdef extern from "grpc/grpc.h": grpc_op_data data void grpc_init() nogil - void grpc_shutdown() nogil + void grpc_shutdown_blocking() nogil int grpc_is_initialized() nogil ctypedef struct grpc_completion_queue_factory: @@ -391,6 +394,16 @@ cdef extern from "grpc/grpc.h": void grpc_server_cancel_all_calls(grpc_server *server) nogil void grpc_server_destroy(grpc_server *server) nogil + char* grpc_channelz_get_top_channels(intptr_t start_channel_id) + char* grpc_channelz_get_servers(intptr_t start_server_id) + char* grpc_channelz_get_server(intptr_t server_id) + char* grpc_channelz_get_server_sockets(intptr_t server_id, + intptr_t start_socket_id, + intptr_t max_results) + char* grpc_channelz_get_channel(intptr_t channel_id) + char* grpc_channelz_get_subchannel(intptr_t subchannel_id) + char* grpc_channelz_get_socket(intptr_t socket_id) + cdef extern from "grpc/grpc_security.h": @@ -606,3 +619,8 @@ cdef extern from "grpc/compression.h": int grpc_compression_options_is_algorithm_enabled( const grpc_compression_options *opts, grpc_compression_algorithm algorithm) nogil + +cdef extern from "grpc/impl/codegen/compression_types.h": + + const char *_GRPC_COMPRESSION_REQUEST_ALGORITHM_MD_KEY \ + "GRPC_COMPRESSION_REQUEST_ALGORITHM_MD_KEY" diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pxd.pxi index f5688d08cdc..30fdf6a7600 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pxd.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pxd.pxi @@ -13,8 +13,6 @@ # 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 diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pyx.pxi index f9a1b2856d7..a1618d04d0e 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pyx.pxi @@ -266,7 +266,7 @@ cdef grpc_error* socket_listen(grpc_custom_socket* socket) with gil: (socket.impl).socket.listen(50) return grpc_error_none() -cdef void accept_callback_cython(SocketWrapper s): +cdef void accept_callback_cython(SocketWrapper s) except *: try: conn, address = s.socket.accept() sw = SocketWrapper() diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/metadata.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/metadata.pxd.pxi index a18c3658077..fc72ac1576b 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/metadata.pxd.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/metadata.pxd.pxi @@ -14,10 +14,10 @@ cdef void _store_c_metadata( - metadata, grpc_metadata **c_metadata, size_t *c_count) + metadata, grpc_metadata **c_metadata, size_t *c_count) except * -cdef void _release_c_metadata(grpc_metadata *c_metadata, int count) +cdef void _release_c_metadata(grpc_metadata *c_metadata, int count) except * cdef tuple _metadatum(grpc_slice key_slice, grpc_slice value_slice) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/metadata.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/metadata.pyx.pxi index 53f0c7f0bbe..caf867b5696 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/metadata.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/metadata.pyx.pxi @@ -25,7 +25,7 @@ _Metadatum = collections.namedtuple('_Metadatum', ('key', 'value',)) cdef void _store_c_metadata( - metadata, grpc_metadata **c_metadata, size_t *c_count): + metadata, grpc_metadata **c_metadata, size_t *c_count) except *: if metadata is None: c_count[0] = 0 c_metadata[0] = NULL @@ -45,7 +45,7 @@ cdef void _store_c_metadata( c_metadata[0][index].value = _slice_from_bytes(encoded_value) -cdef void _release_c_metadata(grpc_metadata *c_metadata, int count): +cdef void _release_c_metadata(grpc_metadata *c_metadata, int count) except *: if 0 < count: for index in range(count): grpc_slice_unref(c_metadata[index].key) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/operation.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/operation.pxd.pxi index 69a2a4989ed..c9df32dadf5 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/operation.pxd.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/operation.pxd.pxi @@ -15,8 +15,8 @@ cdef class Operation: - cdef void c(self) - cdef void un_c(self) + cdef void c(self) except * + cdef void un_c(self) except * # TODO(https://github.com/grpc/grpc/issues/7950): Eliminate this! cdef grpc_op c_op @@ -29,8 +29,8 @@ cdef class SendInitialMetadataOperation(Operation): cdef grpc_metadata *_c_initial_metadata cdef size_t _c_initial_metadata_count - cdef void c(self) - cdef void un_c(self) + cdef void c(self) except * + cdef void un_c(self) except * cdef class SendMessageOperation(Operation): @@ -39,16 +39,16 @@ cdef class SendMessageOperation(Operation): cdef readonly int _flags cdef grpc_byte_buffer *_c_message_byte_buffer - cdef void c(self) - cdef void un_c(self) + cdef void c(self) except * + cdef void un_c(self) except * cdef class SendCloseFromClientOperation(Operation): cdef readonly int _flags - cdef void c(self) - cdef void un_c(self) + cdef void c(self) except * + cdef void un_c(self) except * cdef class SendStatusFromServerOperation(Operation): @@ -61,8 +61,8 @@ cdef class SendStatusFromServerOperation(Operation): cdef size_t _c_trailing_metadata_count cdef grpc_slice _c_details - cdef void c(self) - cdef void un_c(self) + cdef void c(self) except * + cdef void un_c(self) except * cdef class ReceiveInitialMetadataOperation(Operation): @@ -71,8 +71,8 @@ cdef class ReceiveInitialMetadataOperation(Operation): cdef tuple _initial_metadata cdef grpc_metadata_array _c_initial_metadata - cdef void c(self) - cdef void un_c(self) + cdef void c(self) except * + cdef void un_c(self) except * cdef class ReceiveMessageOperation(Operation): @@ -81,8 +81,8 @@ cdef class ReceiveMessageOperation(Operation): cdef grpc_byte_buffer *_c_message_byte_buffer cdef bytes _message - cdef void c(self) - cdef void un_c(self) + cdef void c(self) except * + cdef void un_c(self) except * cdef class ReceiveStatusOnClientOperation(Operation): @@ -97,8 +97,8 @@ cdef class ReceiveStatusOnClientOperation(Operation): cdef str _details cdef str _error_string - cdef void c(self) - cdef void un_c(self) + cdef void c(self) except * + cdef void un_c(self) except * cdef class ReceiveCloseOnServerOperation(Operation): @@ -107,5 +107,5 @@ cdef class ReceiveCloseOnServerOperation(Operation): cdef object _cancelled cdef int _c_cancelled - cdef void c(self) - cdef void un_c(self) + cdef void c(self) except * + cdef void un_c(self) except * diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/operation.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/operation.pyx.pxi index 454627f570a..c8a390106a8 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/operation.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/operation.pyx.pxi @@ -15,10 +15,10 @@ cdef class Operation: - cdef void c(self): + cdef void c(self) except *: raise NotImplementedError() - cdef void un_c(self): + cdef void un_c(self) except *: raise NotImplementedError() @@ -31,7 +31,7 @@ cdef class SendInitialMetadataOperation(Operation): def type(self): return GRPC_OP_SEND_INITIAL_METADATA - cdef void c(self): + cdef void c(self) except *: self.c_op.type = GRPC_OP_SEND_INITIAL_METADATA self.c_op.flags = self._flags _store_c_metadata( @@ -41,7 +41,7 @@ cdef class SendInitialMetadataOperation(Operation): self.c_op.data.send_initial_metadata.count = self._c_initial_metadata_count self.c_op.data.send_initial_metadata.maybe_compression_level.is_set = 0 - cdef void un_c(self): + cdef void un_c(self) except *: _release_c_metadata( self._c_initial_metadata, self._c_initial_metadata_count) @@ -55,7 +55,7 @@ cdef class SendMessageOperation(Operation): def type(self): return GRPC_OP_SEND_MESSAGE - cdef void c(self): + cdef void c(self) except *: self.c_op.type = GRPC_OP_SEND_MESSAGE self.c_op.flags = self._flags cdef grpc_slice message_slice = grpc_slice_from_copied_buffer( @@ -65,7 +65,7 @@ cdef class SendMessageOperation(Operation): grpc_slice_unref(message_slice) self.c_op.data.send_message.send_message = self._c_message_byte_buffer - cdef void un_c(self): + cdef void un_c(self) except *: grpc_byte_buffer_destroy(self._c_message_byte_buffer) @@ -77,11 +77,11 @@ cdef class SendCloseFromClientOperation(Operation): def type(self): return GRPC_OP_SEND_CLOSE_FROM_CLIENT - cdef void c(self): + cdef void c(self) except *: self.c_op.type = GRPC_OP_SEND_CLOSE_FROM_CLIENT self.c_op.flags = self._flags - cdef void un_c(self): + cdef void un_c(self) except *: pass @@ -96,7 +96,7 @@ cdef class SendStatusFromServerOperation(Operation): def type(self): return GRPC_OP_SEND_STATUS_FROM_SERVER - cdef void c(self): + cdef void c(self) except *: self.c_op.type = GRPC_OP_SEND_STATUS_FROM_SERVER self.c_op.flags = self._flags _store_c_metadata( @@ -110,7 +110,7 @@ cdef class SendStatusFromServerOperation(Operation): self._c_details = _slice_from_bytes(_encode(self._details)) self.c_op.data.send_status_from_server.status_details = &self._c_details - cdef void un_c(self): + cdef void un_c(self) except *: grpc_slice_unref(self._c_details) _release_c_metadata( self._c_trailing_metadata, self._c_trailing_metadata_count) @@ -124,14 +124,14 @@ cdef class ReceiveInitialMetadataOperation(Operation): def type(self): return GRPC_OP_RECV_INITIAL_METADATA - cdef void c(self): + cdef void c(self) except *: self.c_op.type = GRPC_OP_RECV_INITIAL_METADATA self.c_op.flags = self._flags grpc_metadata_array_init(&self._c_initial_metadata) self.c_op.data.receive_initial_metadata.receive_initial_metadata = ( &self._c_initial_metadata) - cdef void un_c(self): + cdef void un_c(self) except *: self._initial_metadata = _metadata(&self._c_initial_metadata) grpc_metadata_array_destroy(&self._c_initial_metadata) @@ -147,13 +147,13 @@ cdef class ReceiveMessageOperation(Operation): def type(self): return GRPC_OP_RECV_MESSAGE - cdef void c(self): + cdef void c(self) except *: self.c_op.type = GRPC_OP_RECV_MESSAGE self.c_op.flags = self._flags self.c_op.data.receive_message.receive_message = ( &self._c_message_byte_buffer) - cdef void un_c(self): + cdef void un_c(self) except *: cdef grpc_byte_buffer_reader message_reader cdef bint message_reader_status cdef grpc_slice message_slice @@ -189,7 +189,7 @@ cdef class ReceiveStatusOnClientOperation(Operation): def type(self): return GRPC_OP_RECV_STATUS_ON_CLIENT - cdef void c(self): + cdef void c(self) except *: self.c_op.type = GRPC_OP_RECV_STATUS_ON_CLIENT self.c_op.flags = self._flags grpc_metadata_array_init(&self._c_trailing_metadata) @@ -202,7 +202,7 @@ cdef class ReceiveStatusOnClientOperation(Operation): self.c_op.data.receive_status_on_client.error_string = ( &self._c_error_string) - cdef void un_c(self): + cdef void un_c(self) except *: self._trailing_metadata = _metadata(&self._c_trailing_metadata) grpc_metadata_array_destroy(&self._c_trailing_metadata) self._code = self._c_code @@ -235,12 +235,12 @@ cdef class ReceiveCloseOnServerOperation(Operation): def type(self): return GRPC_OP_RECV_CLOSE_ON_SERVER - cdef void c(self): + cdef void c(self) except *: self.c_op.type = GRPC_OP_RECV_CLOSE_ON_SERVER self.c_op.flags = self._flags self.c_op.data.receive_close_on_server.cancelled = &self._c_cancelled - cdef void un_c(self): + cdef void un_c(self) except *: self._cancelled = bool(self._c_cancelled) def cancelled(self): diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/propagation_bits.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/propagation_bits.pxd.pxi new file mode 100644 index 00000000000..cd6e94c816c --- /dev/null +++ b/src/python/grpcio/grpc/_cython/_cygrpc/propagation_bits.pxd.pxi @@ -0,0 +1,20 @@ +# Copyright 2018 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. +# 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. + +cdef extern from "grpc/impl/codegen/propagation_bits.h": + cdef int _GRPC_PROPAGATE_DEADLINE "GRPC_PROPAGATE_DEADLINE" + cdef int _GRPC_PROPAGATE_CENSUS_STATS_CONTEXT "GRPC_PROPAGATE_CENSUS_STATS_CONTEXT" + cdef int _GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT "GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT" + cdef int _GRPC_PROPAGATE_CANCELLATION "GRPC_PROPAGATE_CANCELLATION" + cdef int _GRPC_PROPAGATE_DEFAULTS "GRPC_PROPAGATE_DEFAULTS" diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/propagation_bits.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/propagation_bits.pyx.pxi new file mode 100644 index 00000000000..2dcc76a2db2 --- /dev/null +++ b/src/python/grpcio/grpc/_cython/_cygrpc/propagation_bits.pyx.pxi @@ -0,0 +1,20 @@ +# Copyright 2018 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. +# 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. + +class PropagationConstants: + GRPC_PROPAGATE_DEADLINE = _GRPC_PROPAGATE_DEADLINE + GRPC_PROPAGATE_CENSUS_STATS_CONTEXT = _GRPC_PROPAGATE_CENSUS_STATS_CONTEXT + GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT = _GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT + GRPC_PROPAGATE_CANCELLATION = _GRPC_PROPAGATE_CANCELLATION + GRPC_PROPAGATE_DEFAULTS = _GRPC_PROPAGATE_DEFAULTS diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi index fe98d559f34..308d677695f 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi @@ -12,8 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -from libc.stdint cimport intptr_t - cdef bytes _slice_bytes(grpc_slice slice): cdef void *start = grpc_slice_start_ptr(slice) @@ -110,6 +108,11 @@ class OperationType: receive_status_on_client = GRPC_OP_RECV_STATUS_ON_CLIENT receive_close_on_server = GRPC_OP_RECV_CLOSE_ON_SERVER +GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM= ( + _GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM) + +GRPC_COMPRESSION_REQUEST_ALGORITHM_MD_KEY = ( + _GRPC_COMPRESSION_REQUEST_ALGORITHM_MD_KEY) class CompressionAlgorithm: none = GRPC_COMPRESS_NONE @@ -134,7 +137,7 @@ cdef class CallDetails: def __dealloc__(self): with nogil: grpc_call_details_destroy(&self.c_details) - grpc_shutdown() + grpc_shutdown_blocking() @property def method(self): diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/server.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/server.pxd.pxi index 52cfccb6779..b3fadcdc62d 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/server.pxd.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/server.pxd.pxi @@ -12,12 +12,11 @@ # See the License for the specific language governing permissions and # limitations under the License. - cdef class Server: - cdef grpc_arg_pointer_vtable _vtable - cdef readonly _ArgumentsProcessor _arguments_processor cdef grpc_server *c_server + + cdef _VTable _vtable cdef bint is_started # start has been called cdef bint is_shutting_down # shutdown has been called cdef bint is_shutdown # notification of complete shutdown received diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi index ce701724fd3..2369371cabe 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi @@ -20,24 +20,21 @@ import grpc _LOGGER = logging.getLogger(__name__) + cdef class Server: def __cinit__(self, object arguments): fork_handlers_and_grpc_init() self.references = [] self.registered_completion_queues = [] - 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.c_server = grpc_server_create(c_arguments, NULL) - arguments_processor.un_c() - self.references.append(arguments) self.is_started = False self.is_shutting_down = False self.is_shutdown = False + self.c_server = NULL + self._vtable = _VTable() + cdef _ChannelArgs channel_args = _ChannelArgs(arguments, self._vtable) + self.c_server = grpc_server_create(channel_args.c_args(), NULL) + self.references.append(arguments) def request_call( self, CompletionQueue call_queue not None, @@ -46,7 +43,7 @@ cdef class Server: raise ValueError("server must be started and not shutting down") if server_queue not in self.registered_completion_queues: raise ValueError("server_queue must be a registered completion queue") - cdef _RequestCallTag request_call_tag = _RequestCallTag(tag) + cdef _RequestCallTag request_call_tag = _RequestCallTag(tag, self._vtable) request_call_tag.prepare() cpython.Py_INCREF(request_call_tag) return grpc_server_request_call( @@ -128,7 +125,10 @@ cdef class Server: with nogil: grpc_server_cancel_all_calls(self.c_server) - def __dealloc__(self): + # TODO(https://github.com/grpc/grpc/issues/17515) Determine what, if any, + # portion of this is safe to call from __dealloc__, and potentially remove + # backup_shutdown_queue. + def destroy(self): if self.c_server != NULL: if not self.is_started: pass @@ -146,4 +146,8 @@ cdef class Server: while not self.is_shutdown: time.sleep(0) grpc_server_destroy(self.c_server) - grpc_shutdown() + self.c_server = NULL + + def __dealloc__(self): + if self.c_server == NULL: + grpc_shutdown_blocking() diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/tag.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/tag.pxd.pxi index f9a3b5e8f40..c77beb28194 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/tag.pxd.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/tag.pxd.pxi @@ -29,10 +29,11 @@ cdef class _RequestCallTag(_Tag): cdef readonly object _user_tag cdef Call call + cdef _VTable _vtable cdef CallDetails call_details cdef grpc_metadata_array c_invocation_metadata - cdef void prepare(self) + cdef void prepare(self) except * cdef RequestCallEvent event(self, grpc_event c_event) @@ -44,7 +45,7 @@ cdef class _BatchOperationTag(_Tag): cdef grpc_op *c_ops cdef size_t c_nops - cdef void prepare(self) + cdef void prepare(self) except * cdef BatchOperationEvent event(self, grpc_event c_event) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/tag.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/tag.pyx.pxi index aaca458442f..d1280ef4948 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/tag.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/tag.pyx.pxi @@ -30,13 +30,14 @@ cdef class _ConnectivityTag(_Tag): cdef class _RequestCallTag(_Tag): - def __cinit__(self, user_tag): + def __cinit__(self, user_tag, _VTable vtable not None): self._user_tag = user_tag self.call = None self.call_details = None + self._vtable = vtable - cdef void prepare(self): - self.call = Call() + cdef void prepare(self) except *: + self.call = Call(self._vtable) self.call_details = CallDetails() grpc_metadata_array_init(&self.c_invocation_metadata) @@ -55,19 +56,20 @@ cdef class _BatchOperationTag: self._operations = operations self._retained_call = call - cdef void prepare(self): + cdef void prepare(self) except *: + cdef Operation operation self.c_nops = 0 if self._operations is None else len(self._operations) if 0 < self.c_nops: self.c_ops = gpr_malloc(sizeof(grpc_op) * self.c_nops) for index, operation in enumerate(self._operations): - (operation).c() - self.c_ops[index] = (operation).c_op + operation.c() + self.c_ops[index] = operation.c_op cdef BatchOperationEvent event(self, grpc_event c_event): + cdef Operation operation if 0 < self.c_nops: - for index, operation in enumerate(self._operations): - (operation).c_op = self.c_ops[index] - (operation).un_c() + for operation in self._operations: + operation.un_c() gpr_free(self.c_ops) return BatchOperationEvent( c_event.type, c_event.success, self._user_tag, self._operations) @@ -84,4 +86,4 @@ cdef class _ServerShutdownTag(_Tag): cdef ServerShutdownEvent event(self, grpc_event c_event): self._shutting_down_server.notify_shutdown_complete() - return ServerShutdownEvent(c_event.type, c_event.success, self._user_tag) \ No newline at end of file + return ServerShutdownEvent(c_event.type, c_event.success, self._user_tag) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/time.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/time.pxd.pxi index ce67c61eaf6..c46e8a98b04 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/time.pxd.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/time.pxd.pxi @@ -13,7 +13,7 @@ # limitations under the License. -cdef gpr_timespec _timespec_from_time(object time) +cdef gpr_timespec _timespec_from_time(object time) except * -cdef double _time_from_timespec(gpr_timespec timespec) +cdef double _time_from_timespec(gpr_timespec timespec) except * diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/time.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/time.pyx.pxi index 7a668680b8f..6d181bb1d60 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/time.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/time.pyx.pxi @@ -13,18 +13,17 @@ # limitations under the License. -cdef gpr_timespec _timespec_from_time(object time): - cdef gpr_timespec timespec +cdef gpr_timespec _timespec_from_time(object time) except *: if time is None: return gpr_inf_future(GPR_CLOCK_REALTIME) else: - timespec.seconds = time - timespec.nanoseconds = (time - float(timespec.seconds)) * 1e9 - timespec.clock_type = GPR_CLOCK_REALTIME - return timespec + return gpr_time_from_nanos( + (time * GPR_NS_PER_SEC), + GPR_CLOCK_REALTIME, + ) -cdef double _time_from_timespec(gpr_timespec timespec): +cdef double _time_from_timespec(gpr_timespec timespec) except *: cdef gpr_timespec real_timespec = gpr_convert_clock_type( timespec, GPR_CLOCK_REALTIME) - return real_timespec.seconds + real_timespec.nanoseconds / 1e9 + return gpr_timespec_to_micros(real_timespec) / GPR_US_PER_SEC diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/vtable.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/vtable.pxd.pxi new file mode 100644 index 00000000000..1799b6e1f14 --- /dev/null +++ b/src/python/grpcio/grpc/_cython/_cygrpc/vtable.pxd.pxi @@ -0,0 +1,26 @@ +# Copyright 2019 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. + + +cdef void* _copy_pointer(void* pointer) + + +cdef void _destroy_pointer(void* pointer) + + +cdef int _compare_pointer(void* first_pointer, void* second_pointer) + + +cdef class _VTable: + cdef grpc_arg_pointer_vtable c_vtable diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/vtable.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/vtable.pyx.pxi new file mode 100644 index 00000000000..98cb60c10e3 --- /dev/null +++ b/src/python/grpcio/grpc/_cython/_cygrpc/vtable.pyx.pxi @@ -0,0 +1,39 @@ +# Copyright 2019 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. + +# TODO(https://github.com/grpc/grpc/issues/15662): Reform this. +cdef void* _copy_pointer(void* pointer): + return pointer + + +# TODO(https://github.com/grpc/grpc/issues/15662): Reform this. +cdef void _destroy_pointer(void* pointer): + pass + + +cdef int _compare_pointer(void* first_pointer, void* second_pointer): + if first_pointer < second_pointer: + return -1 + elif first_pointer > second_pointer: + return 1 + else: + return 0 + + +cdef class _VTable: + def __cinit__(self): + self.c_vtable.copy = &_copy_pointer + self.c_vtable.destroy = &_destroy_pointer + self.c_vtable.cmp = &_compare_pointer + diff --git a/src/python/grpcio/grpc/_cython/cygrpc.pxd b/src/python/grpcio/grpc/_cython/cygrpc.pxd index 8258b857bc4..e29f7aee97a 100644 --- a/src/python/grpcio/grpc/_cython/cygrpc.pxd +++ b/src/python/grpcio/grpc/_cython/cygrpc.pxd @@ -23,11 +23,13 @@ include "_cygrpc/completion_queue.pxd.pxi" include "_cygrpc/event.pxd.pxi" include "_cygrpc/metadata.pxd.pxi" include "_cygrpc/operation.pxd.pxi" +include "_cygrpc/propagation_bits.pxd.pxi" include "_cygrpc/records.pxd.pxi" include "_cygrpc/security.pxd.pxi" include "_cygrpc/server.pxd.pxi" include "_cygrpc/tag.pxd.pxi" include "_cygrpc/time.pxd.pxi" +include "_cygrpc/vtable.pxd.pxi" include "_cygrpc/_hooks.pxd.pxi" include "_cygrpc/grpc_gevent.pxd.pxi" diff --git a/src/python/grpcio/grpc/_cython/cygrpc.pyx b/src/python/grpcio/grpc/_cython/cygrpc.pyx index ae5c07bfc82..f2dd0df89d4 100644 --- a/src/python/grpcio/grpc/_cython/cygrpc.pyx +++ b/src/python/grpcio/grpc/_cython/cygrpc.pyx @@ -24,16 +24,19 @@ include "_cygrpc/grpc_string.pyx.pxi" include "_cygrpc/arguments.pyx.pxi" include "_cygrpc/call.pyx.pxi" include "_cygrpc/channel.pyx.pxi" +include "_cygrpc/channelz.pyx.pxi" include "_cygrpc/credentials.pyx.pxi" include "_cygrpc/completion_queue.pyx.pxi" include "_cygrpc/event.pyx.pxi" include "_cygrpc/metadata.pyx.pxi" include "_cygrpc/operation.pyx.pxi" +include "_cygrpc/propagation_bits.pyx.pxi" include "_cygrpc/records.pyx.pxi" include "_cygrpc/security.pyx.pxi" include "_cygrpc/server.pyx.pxi" include "_cygrpc/tag.pyx.pxi" include "_cygrpc/time.pyx.pxi" +include "_cygrpc/vtable.pyx.pxi" include "_cygrpc/_hooks.pyx.pxi" include "_cygrpc/grpc_gevent.pyx.pxi" diff --git a/src/python/grpcio/grpc/_grpcio_metadata.py b/src/python/grpcio/grpc/_grpcio_metadata.py index 42b3a1ad498..9f7ca9d5603 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.17.0.dev0""" +__version__ = """1.22.0.dev0""" diff --git a/src/python/grpcio/grpc/_interceptor.py b/src/python/grpcio/grpc/_interceptor.py index 43451140265..4ec2e6bb733 100644 --- a/src/python/grpcio/grpc/_interceptor.py +++ b/src/python/grpcio/grpc/_interceptor.py @@ -44,9 +44,9 @@ def service_pipeline(interceptors): class _ClientCallDetails( - collections.namedtuple( - '_ClientCallDetails', - ('method', 'timeout', 'metadata', 'credentials', 'wait_for_ready')), + collections.namedtuple('_ClientCallDetails', + ('method', 'timeout', 'metadata', 'credentials', + 'wait_for_ready', 'compression')), grpc.ClientCallDetails): pass @@ -77,10 +77,15 @@ def _unwrap_client_call_details(call_details, default_details): except AttributeError: wait_for_ready = default_details.wait_for_ready - return method, timeout, metadata, credentials, wait_for_ready + try: + compression = call_details.compression + except AttributeError: + compression = default_details.compression + + return method, timeout, metadata, credentials, wait_for_ready, compression -class _FailureOutcome(grpc.RpcError, grpc.Future, grpc.Call): +class _FailureOutcome(grpc.RpcError, grpc.Future, grpc.Call): # pylint: disable=too-many-ancestors def __init__(self, exception, traceback): super(_FailureOutcome, self).__init__() @@ -126,7 +131,7 @@ class _FailureOutcome(grpc.RpcError, grpc.Future, grpc.Call): def traceback(self, ignored_timeout=None): return self._traceback - def add_callback(self, callback): + def add_callback(self, unused_callback): return False def add_done_callback(self, fn): @@ -135,9 +140,12 @@ class _FailureOutcome(grpc.RpcError, grpc.Future, grpc.Call): def __iter__(self): return self - def next(self): + def __next__(self): raise self._exception + def next(self): + return self.__next__() + class _UnaryOutcome(grpc.Call, grpc.Future): @@ -203,13 +211,15 @@ class _UnaryUnaryMultiCallable(grpc.UnaryUnaryMultiCallable): timeout=None, metadata=None, credentials=None, - wait_for_ready=None): + wait_for_ready=None, + compression=None): response, ignored_call = self._with_call( request, timeout=timeout, metadata=metadata, credentials=credentials, - wait_for_ready=wait_for_ready) + wait_for_ready=wait_for_ready, + compression=compression) return response def _with_call(self, @@ -217,23 +227,28 @@ class _UnaryUnaryMultiCallable(grpc.UnaryUnaryMultiCallable): timeout=None, metadata=None, credentials=None, - wait_for_ready=None): - client_call_details = _ClientCallDetails( - self._method, timeout, metadata, credentials, wait_for_ready) + wait_for_ready=None, + compression=None): + client_call_details = _ClientCallDetails(self._method, timeout, + metadata, credentials, + wait_for_ready, compression) def continuation(new_details, request): - new_method, new_timeout, new_metadata, new_credentials, new_wait_for_ready = ( - _unwrap_client_call_details(new_details, client_call_details)) + (new_method, new_timeout, new_metadata, new_credentials, + new_wait_for_ready, + new_compression) = (_unwrap_client_call_details( + new_details, client_call_details)) try: response, call = self._thunk(new_method).with_call( request, timeout=new_timeout, metadata=new_metadata, credentials=new_credentials, - wait_for_ready=new_wait_for_ready) + wait_for_ready=new_wait_for_ready, + compression=new_compression) return _UnaryOutcome(response, call) - except grpc.RpcError: - raise + except grpc.RpcError as rpc_error: + return rpc_error except Exception as exception: # pylint:disable=broad-except return _FailureOutcome(exception, sys.exc_info()[2]) @@ -246,32 +261,39 @@ class _UnaryUnaryMultiCallable(grpc.UnaryUnaryMultiCallable): timeout=None, metadata=None, credentials=None, - wait_for_ready=None): + wait_for_ready=None, + compression=None): return self._with_call( request, timeout=timeout, metadata=metadata, credentials=credentials, - wait_for_ready=wait_for_ready) + wait_for_ready=wait_for_ready, + compression=compression) def future(self, request, timeout=None, metadata=None, credentials=None, - wait_for_ready=None): - client_call_details = _ClientCallDetails( - self._method, timeout, metadata, credentials, wait_for_ready) + wait_for_ready=None, + compression=None): + client_call_details = _ClientCallDetails(self._method, timeout, + metadata, credentials, + wait_for_ready, compression) def continuation(new_details, request): - new_method, new_timeout, new_metadata, new_credentials, new_wait_for_ready = ( - _unwrap_client_call_details(new_details, client_call_details)) + (new_method, new_timeout, new_metadata, new_credentials, + new_wait_for_ready, + new_compression) = (_unwrap_client_call_details( + new_details, client_call_details)) return self._thunk(new_method).future( request, timeout=new_timeout, metadata=new_metadata, credentials=new_credentials, - wait_for_ready=new_wait_for_ready) + wait_for_ready=new_wait_for_ready, + compression=new_compression) try: return self._interceptor.intercept_unary_unary( @@ -292,19 +314,24 @@ class _UnaryStreamMultiCallable(grpc.UnaryStreamMultiCallable): timeout=None, metadata=None, credentials=None, - wait_for_ready=None): - client_call_details = _ClientCallDetails( - self._method, timeout, metadata, credentials, wait_for_ready) + wait_for_ready=None, + compression=None): + client_call_details = _ClientCallDetails(self._method, timeout, + metadata, credentials, + wait_for_ready, compression) def continuation(new_details, request): - new_method, new_timeout, new_metadata, new_credentials, new_wait_for_ready = ( - _unwrap_client_call_details(new_details, client_call_details)) + (new_method, new_timeout, new_metadata, new_credentials, + new_wait_for_ready, + new_compression) = (_unwrap_client_call_details( + new_details, client_call_details)) return self._thunk(new_method)( request, timeout=new_timeout, metadata=new_metadata, credentials=new_credentials, - wait_for_ready=new_wait_for_ready) + wait_for_ready=new_wait_for_ready, + compression=new_compression) try: return self._interceptor.intercept_unary_stream( @@ -325,13 +352,15 @@ class _StreamUnaryMultiCallable(grpc.StreamUnaryMultiCallable): timeout=None, metadata=None, credentials=None, - wait_for_ready=None): + wait_for_ready=None, + compression=None): response, ignored_call = self._with_call( request_iterator, timeout=timeout, metadata=metadata, credentials=credentials, - wait_for_ready=wait_for_ready) + wait_for_ready=wait_for_ready, + compression=compression) return response def _with_call(self, @@ -339,23 +368,28 @@ class _StreamUnaryMultiCallable(grpc.StreamUnaryMultiCallable): timeout=None, metadata=None, credentials=None, - wait_for_ready=None): - client_call_details = _ClientCallDetails( - self._method, timeout, metadata, credentials, wait_for_ready) + wait_for_ready=None, + compression=None): + client_call_details = _ClientCallDetails(self._method, timeout, + metadata, credentials, + wait_for_ready, compression) def continuation(new_details, request_iterator): - new_method, new_timeout, new_metadata, new_credentials, new_wait_for_ready = ( - _unwrap_client_call_details(new_details, client_call_details)) + (new_method, new_timeout, new_metadata, new_credentials, + new_wait_for_ready, + new_compression) = (_unwrap_client_call_details( + new_details, client_call_details)) try: response, call = self._thunk(new_method).with_call( request_iterator, timeout=new_timeout, metadata=new_metadata, credentials=new_credentials, - wait_for_ready=new_wait_for_ready) + wait_for_ready=new_wait_for_ready, + compression=new_compression) return _UnaryOutcome(response, call) - except grpc.RpcError: - raise + except grpc.RpcError as rpc_error: + return rpc_error except Exception as exception: # pylint:disable=broad-except return _FailureOutcome(exception, sys.exc_info()[2]) @@ -368,32 +402,39 @@ class _StreamUnaryMultiCallable(grpc.StreamUnaryMultiCallable): timeout=None, metadata=None, credentials=None, - wait_for_ready=None): + wait_for_ready=None, + compression=None): return self._with_call( request_iterator, timeout=timeout, metadata=metadata, credentials=credentials, - wait_for_ready=wait_for_ready) + wait_for_ready=wait_for_ready, + compression=compression) def future(self, request_iterator, timeout=None, metadata=None, credentials=None, - wait_for_ready=None): - client_call_details = _ClientCallDetails( - self._method, timeout, metadata, credentials, wait_for_ready) + wait_for_ready=None, + compression=None): + client_call_details = _ClientCallDetails(self._method, timeout, + metadata, credentials, + wait_for_ready, compression) def continuation(new_details, request_iterator): - new_method, new_timeout, new_metadata, new_credentials, new_wait_for_ready = ( - _unwrap_client_call_details(new_details, client_call_details)) + (new_method, new_timeout, new_metadata, new_credentials, + new_wait_for_ready, + new_compression) = (_unwrap_client_call_details( + new_details, client_call_details)) return self._thunk(new_method).future( request_iterator, timeout=new_timeout, metadata=new_metadata, credentials=new_credentials, - wait_for_ready=new_wait_for_ready) + wait_for_ready=new_wait_for_ready, + compression=new_compression) try: return self._interceptor.intercept_stream_unary( @@ -414,19 +455,24 @@ class _StreamStreamMultiCallable(grpc.StreamStreamMultiCallable): timeout=None, metadata=None, credentials=None, - wait_for_ready=None): - client_call_details = _ClientCallDetails( - self._method, timeout, metadata, credentials, wait_for_ready) + wait_for_ready=None, + compression=None): + client_call_details = _ClientCallDetails(self._method, timeout, + metadata, credentials, + wait_for_ready, compression) def continuation(new_details, request_iterator): - new_method, new_timeout, new_metadata, new_credentials, new_wait_for_ready = ( - _unwrap_client_call_details(new_details, client_call_details)) + (new_method, new_timeout, new_metadata, new_credentials, + new_wait_for_ready, + new_compression) = (_unwrap_client_call_details( + new_details, client_call_details)) return self._thunk(new_method)( request_iterator, timeout=new_timeout, metadata=new_metadata, credentials=new_credentials, - wait_for_ready=new_wait_for_ready) + wait_for_ready=new_wait_for_ready, + compression=new_compression) try: return self._interceptor.intercept_stream_stream( diff --git a/src/python/grpcio/grpc/_server.py b/src/python/grpcio/grpc/_server.py index 7276a7fd90e..370c81100af 100644 --- a/src/python/grpcio/grpc/_server.py +++ b/src/python/grpcio/grpc/_server.py @@ -19,13 +19,14 @@ import logging import threading import time +from concurrent import futures import six import grpc from grpc import _common +from grpc import _compression from grpc import _interceptor from grpc._cython import cygrpc -from grpc.framework.foundation import callable_util _LOGGER = logging.getLogger(__name__) @@ -48,7 +49,7 @@ _CANCELLED = 'cancelled' _EMPTY_FLAGS = 0 -_UNEXPECTED_EXIT_SERVER_GRACE = 1.0 +_DEALLOCATED_SERVER_CHECK_PERIOD_S = 1.0 def _serialized_request(request_event): @@ -94,6 +95,7 @@ class _RPCState(object): self.request = None self.client = _OPEN self.initial_metadata_allowed = True + self.compression_algorithm = None self.disable_next_compression = False self.trailing_metadata = None self.code = None @@ -101,7 +103,7 @@ class _RPCState(object): self.statused = False self.rpc_errors = [] self.callbacks = [] - self.abortion = None + self.aborted = False def _raise_rpc_error(state): @@ -112,7 +114,7 @@ def _raise_rpc_error(state): def _possibly_finish_call(state, token): state.due.remove(token) - if (state.client is _CANCELLED or state.statused) and not state.due: + if not _is_rpc_state_active(state) and not state.due: callbacks = state.callbacks state.callbacks = None return state, callbacks @@ -129,13 +131,33 @@ def _send_status_from_server(state, token): return send_status_from_server +def _get_initial_metadata(state, metadata): + with state.condition: + if state.compression_algorithm: + compression_metadata = ( + _compression.compression_algorithm_to_metadata( + state.compression_algorithm),) + if metadata is None: + return compression_metadata + else: + return compression_metadata + tuple(metadata) + else: + return metadata + + +def _get_initial_metadata_operation(state, metadata): + operation = cygrpc.SendInitialMetadataOperation( + _get_initial_metadata(state, metadata), _EMPTY_FLAGS) + return operation + + def _abort(state, call, code, details): if state.client is not _CANCELLED: effective_code = _abortion_code(state, code) effective_details = details if state.details is None else state.details if state.initial_metadata_allowed: operations = ( - cygrpc.SendInitialMetadataOperation(None, _EMPTY_FLAGS), + _get_initial_metadata_operation(state, None), cygrpc.SendStatusFromServerOperation( state.trailing_metadata, effective_code, effective_details, _EMPTY_FLAGS), @@ -219,7 +241,7 @@ class _Context(grpc.ServicerContext): def is_active(self): with self._state.condition: - return self._state.client is not _CANCELLED and not self._state.statused + return _is_rpc_state_active(self._state) def time_remaining(self): return max(self._rpc_event.call_details.deadline - time.time(), 0) @@ -259,14 +281,18 @@ class _Context(grpc.ServicerContext): cygrpc.auth_context(self._rpc_event.call)) } + def set_compression(self, compression): + with self._state.condition: + self._state.compression_algorithm = compression + def send_initial_metadata(self, initial_metadata): with self._state.condition: if self._state.client is _CANCELLED: _raise_rpc_error(self._state) else: if self._state.initial_metadata_allowed: - operation = cygrpc.SendInitialMetadataOperation( - initial_metadata, _EMPTY_FLAGS) + operation = _get_initial_metadata_operation( + self._state, initial_metadata) self._rpc_event.call.start_server_batch( (operation,), _send_initial_metadata(self._state)) self._state.initial_metadata_allowed = False @@ -288,8 +314,12 @@ class _Context(grpc.ServicerContext): with self._state.condition: self._state.code = code self._state.details = _common.encode(details) - self._state.abortion = Exception() - raise self._state.abortion + self._state.aborted = True + raise Exception() + + def abort_with_status(self, status): + self._state.trailing_metadata = status.trailing_metadata + self.abort(status.code, status.details) def set_code(self, code): with self._state.condition: @@ -299,6 +329,9 @@ class _Context(grpc.ServicerContext): with self._state.condition: self._state.details = _common.encode(details) + def _finalize_state(self): + pass + class _RequestIterator(object): @@ -310,7 +343,7 @@ class _RequestIterator(object): def _raise_or_start_receive_message(self): if self._state.client is _CANCELLED: _raise_rpc_error(self._state) - elif self._state.client is _CLOSED or self._state.statused: + elif not _is_rpc_state_active(self._state): raise StopIteration() else: self._call.start_server_batch( @@ -355,7 +388,7 @@ def _unary_request(rpc_event, state, request_deserializer): def unary_request(): with state.condition: - if state.client is _CANCELLED or state.statused: + if not _is_rpc_state_active(state): return None else: rpc_event.call.start_server_batch( @@ -383,21 +416,35 @@ def _unary_request(rpc_event, state, request_deserializer): return unary_request -def _call_behavior(rpc_event, state, behavior, argument, request_deserializer): - context = _Context(rpc_event, state, request_deserializer) - try: - return behavior(argument, context), True - except Exception as exception: # pylint: disable=broad-except - with state.condition: - if exception is state.abortion: - _abort(state, rpc_event.call, cygrpc.StatusCode.unknown, - b'RPC Aborted') - elif exception not in state.rpc_errors: - details = 'Exception calling application: {}'.format(exception) - _LOGGER.exception(details) - _abort(state, rpc_event.call, cygrpc.StatusCode.unknown, - _common.encode(details)) - return None, False +def _call_behavior(rpc_event, + state, + behavior, + argument, + request_deserializer, + send_response_callback=None): + from grpc import _create_servicer_context + with _create_servicer_context(rpc_event, state, + request_deserializer) as context: + try: + response_or_iterator = None + if send_response_callback is not None: + response_or_iterator = behavior(argument, context, + send_response_callback) + else: + response_or_iterator = behavior(argument, context) + return response_or_iterator, True + except Exception as exception: # pylint: disable=broad-except + with state.condition: + if state.aborted: + _abort(state, rpc_event.call, cygrpc.StatusCode.unknown, + b'RPC Aborted') + elif exception not in state.rpc_errors: + details = 'Exception calling application: {}'.format( + exception) + _LOGGER.exception(details) + _abort(state, rpc_event.call, cygrpc.StatusCode.unknown, + _common.encode(details)) + return None, False def _take_response_from_response_iterator(rpc_event, state, response_iterator): @@ -407,7 +454,7 @@ def _take_response_from_response_iterator(rpc_event, state, response_iterator): return None, True except Exception as exception: # pylint: disable=broad-except with state.condition: - if exception is state.abortion: + if state.aborted: _abort(state, rpc_event.call, cygrpc.StatusCode.unknown, b'RPC Aborted') elif exception not in state.rpc_errors: @@ -429,30 +476,45 @@ def _serialize_response(rpc_event, state, response, response_serializer): return serialized_response +def _get_send_message_op_flags_from_state(state): + if state.disable_next_compression: + return cygrpc.WriteFlag.no_compress + else: + return _EMPTY_FLAGS + + +def _reset_per_message_state(state): + with state.condition: + state.disable_next_compression = False + + def _send_response(rpc_event, state, serialized_response): with state.condition: - if state.client is _CANCELLED or state.statused: + if not _is_rpc_state_active(state): return False else: if state.initial_metadata_allowed: operations = ( - cygrpc.SendInitialMetadataOperation(None, _EMPTY_FLAGS), - cygrpc.SendMessageOperation(serialized_response, - _EMPTY_FLAGS), + _get_initial_metadata_operation(state, None), + cygrpc.SendMessageOperation( + serialized_response, + _get_send_message_op_flags_from_state(state)), ) state.initial_metadata_allowed = False token = _SEND_INITIAL_METADATA_AND_SEND_MESSAGE_TOKEN else: operations = (cygrpc.SendMessageOperation( - serialized_response, _EMPTY_FLAGS),) + serialized_response, + _get_send_message_op_flags_from_state(state)),) token = _SEND_MESSAGE_TOKEN rpc_event.call.start_server_batch(operations, _send_message(state, token)) state.due.add(token) + _reset_per_message_state(state) while True: state.condition.wait() if token not in state.due: - return state.client is not _CANCELLED and not state.statused + return _is_rpc_state_active(state) def _status(rpc_event, state, serialized_response): @@ -465,90 +527,136 @@ def _status(rpc_event, state, serialized_response): state.trailing_metadata, code, details, _EMPTY_FLAGS), ] if state.initial_metadata_allowed: - operations.append( - cygrpc.SendInitialMetadataOperation(None, _EMPTY_FLAGS)) + operations.append(_get_initial_metadata_operation(state, None)) if serialized_response is not None: operations.append( - cygrpc.SendMessageOperation(serialized_response, - _EMPTY_FLAGS)) + cygrpc.SendMessageOperation( + serialized_response, + _get_send_message_op_flags_from_state(state))) rpc_event.call.start_server_batch( operations, _send_status_from_server(state, _SEND_STATUS_FROM_SERVER_TOKEN)) state.statused = True + _reset_per_message_state(state) state.due.add(_SEND_STATUS_FROM_SERVER_TOKEN) def _unary_response_in_pool(rpc_event, state, behavior, argument_thunk, request_deserializer, response_serializer): - argument = argument_thunk() - if argument is not None: - response, proceed = _call_behavior(rpc_event, state, behavior, argument, - request_deserializer) - if proceed: - serialized_response = _serialize_response( - rpc_event, state, response, response_serializer) - if serialized_response is not None: - _status(rpc_event, state, serialized_response) + cygrpc.install_context_from_request_call_event(rpc_event) + try: + argument = argument_thunk() + if argument is not None: + response, proceed = _call_behavior(rpc_event, state, behavior, + argument, request_deserializer) + if proceed: + serialized_response = _serialize_response( + rpc_event, state, response, response_serializer) + if serialized_response is not None: + _status(rpc_event, state, serialized_response) + finally: + cygrpc.uninstall_context() def _stream_response_in_pool(rpc_event, state, behavior, argument_thunk, request_deserializer, response_serializer): - argument = argument_thunk() - if argument is not None: - response_iterator, proceed = _call_behavior( - rpc_event, state, behavior, argument, request_deserializer) - if proceed: - while True: - response, proceed = _take_response_from_response_iterator( - rpc_event, state, response_iterator) + cygrpc.install_context_from_request_call_event(rpc_event) + + def send_response(response): + if response is None: + _status(rpc_event, state, None) + else: + serialized_response = _serialize_response( + rpc_event, state, response, response_serializer) + if serialized_response is not None: + _send_response(rpc_event, state, serialized_response) + + try: + argument = argument_thunk() + if argument is not None: + if hasattr(behavior, 'experimental_non_blocking' + ) and behavior.experimental_non_blocking: + _call_behavior( + rpc_event, + state, + behavior, + argument, + request_deserializer, + send_response_callback=send_response) + else: + response_iterator, proceed = _call_behavior( + rpc_event, state, behavior, argument, request_deserializer) if proceed: - if response is None: - _status(rpc_event, state, None) - break - else: - serialized_response = _serialize_response( - rpc_event, state, response, response_serializer) - if serialized_response is not None: - proceed = _send_response(rpc_event, state, - serialized_response) - if not proceed: - break - else: - break - else: - break + _send_message_callback_to_blocking_iterator_adapter( + rpc_event, state, send_response, response_iterator) + finally: + cygrpc.uninstall_context() -def _handle_unary_unary(rpc_event, state, method_handler, thread_pool): +def _is_rpc_state_active(state): + return state.client is not _CANCELLED and not state.statused + + +def _send_message_callback_to_blocking_iterator_adapter( + rpc_event, state, send_response_callback, response_iterator): + while True: + response, proceed = _take_response_from_response_iterator( + rpc_event, state, response_iterator) + if proceed: + send_response_callback(response) + if not _is_rpc_state_active(state): + break + else: + break + + +def _select_thread_pool_for_behavior(behavior, default_thread_pool): + if hasattr(behavior, 'experimental_thread_pool') and isinstance( + behavior.experimental_thread_pool, futures.ThreadPoolExecutor): + return behavior.experimental_thread_pool + else: + return default_thread_pool + + +def _handle_unary_unary(rpc_event, state, method_handler, default_thread_pool): unary_request = _unary_request(rpc_event, state, method_handler.request_deserializer) + thread_pool = _select_thread_pool_for_behavior(method_handler.unary_unary, + default_thread_pool) return thread_pool.submit(_unary_response_in_pool, rpc_event, state, method_handler.unary_unary, unary_request, method_handler.request_deserializer, method_handler.response_serializer) -def _handle_unary_stream(rpc_event, state, method_handler, thread_pool): +def _handle_unary_stream(rpc_event, state, method_handler, default_thread_pool): unary_request = _unary_request(rpc_event, state, method_handler.request_deserializer) + thread_pool = _select_thread_pool_for_behavior(method_handler.unary_stream, + default_thread_pool) return thread_pool.submit(_stream_response_in_pool, rpc_event, state, method_handler.unary_stream, unary_request, method_handler.request_deserializer, method_handler.response_serializer) -def _handle_stream_unary(rpc_event, state, method_handler, thread_pool): +def _handle_stream_unary(rpc_event, state, method_handler, default_thread_pool): request_iterator = _RequestIterator(state, rpc_event.call, method_handler.request_deserializer) + thread_pool = _select_thread_pool_for_behavior(method_handler.stream_unary, + default_thread_pool) return thread_pool.submit( _unary_response_in_pool, rpc_event, state, method_handler.stream_unary, lambda: request_iterator, method_handler.request_deserializer, method_handler.response_serializer) -def _handle_stream_stream(rpc_event, state, method_handler, thread_pool): +def _handle_stream_stream(rpc_event, state, method_handler, + default_thread_pool): request_iterator = _RequestIterator(state, rpc_event.call, method_handler.request_deserializer) + thread_pool = _select_thread_pool_for_behavior(method_handler.stream_stream, + default_thread_pool) return thread_pool.submit( _stream_response_in_pool, rpc_event, state, method_handler.stream_stream, lambda: request_iterator, @@ -576,13 +684,13 @@ def _find_method_handler(rpc_event, generic_handlers, interceptor_pipeline): def _reject_rpc(rpc_event, status, details): + rpc_state = _RPCState() operations = ( - cygrpc.SendInitialMetadataOperation(None, _EMPTY_FLAGS), + _get_initial_metadata_operation(rpc_state, None), cygrpc.ReceiveCloseOnServerOperation(_EMPTY_FLAGS), cygrpc.SendStatusFromServerOperation(None, status, details, _EMPTY_FLAGS), ) - rpc_state = _RPCState() rpc_event.call.start_server_batch(operations, lambda ignored_event: (rpc_state, (),)) return rpc_state @@ -664,6 +772,9 @@ class _ServerState(object): self.rpc_states = set() self.due = set() + # A "volatile" flag to interrupt the daemon serving thread + self.server_deallocated = False + def _add_generic_handlers(state, generic_handlers): with state.lock: @@ -690,6 +801,7 @@ def _request_call(state): # TODO(https://github.com/grpc/grpc/issues/6597): delete this function. def _stop_serving(state): if not state.rpc_states and not state.due: + state.server.destroy() for shutdown_event in state.shutdown_events: shutdown_event.set() state.stage = _ServerStage.STOPPED @@ -703,49 +815,71 @@ def _on_call_completed(state): state.active_rpc_count -= 1 +def _process_event_and_continue(state, event): + should_continue = True + if event.tag is _SHUTDOWN_TAG: + with state.lock: + state.due.remove(_SHUTDOWN_TAG) + if _stop_serving(state): + should_continue = False + elif event.tag is _REQUEST_CALL_TAG: + with state.lock: + state.due.remove(_REQUEST_CALL_TAG) + concurrency_exceeded = ( + state.maximum_concurrent_rpcs is not None and + state.active_rpc_count >= state.maximum_concurrent_rpcs) + rpc_state, rpc_future = _handle_call( + event, state.generic_handlers, state.interceptor_pipeline, + state.thread_pool, concurrency_exceeded) + if rpc_state is not None: + state.rpc_states.add(rpc_state) + if rpc_future is not None: + state.active_rpc_count += 1 + rpc_future.add_done_callback( + lambda unused_future: _on_call_completed(state)) + if state.stage is _ServerStage.STARTED: + _request_call(state) + elif _stop_serving(state): + should_continue = False + else: + rpc_state, callbacks = event.tag(event) + for callback in callbacks: + try: + callback() + except Exception: # pylint: disable=broad-except + _LOGGER.exception('Exception calling callback!') + if rpc_state is not None: + with state.lock: + state.rpc_states.remove(rpc_state) + if _stop_serving(state): + should_continue = False + return should_continue + + def _serve(state): while True: - event = state.completion_queue.poll() - if event.tag is _SHUTDOWN_TAG: - with state.lock: - state.due.remove(_SHUTDOWN_TAG) - if _stop_serving(state): - return - elif event.tag is _REQUEST_CALL_TAG: - with state.lock: - state.due.remove(_REQUEST_CALL_TAG) - concurrency_exceeded = ( - state.maximum_concurrent_rpcs is not None and - state.active_rpc_count >= state.maximum_concurrent_rpcs) - rpc_state, rpc_future = _handle_call( - event, state.generic_handlers, state.interceptor_pipeline, - state.thread_pool, concurrency_exceeded) - if rpc_state is not None: - state.rpc_states.add(rpc_state) - if rpc_future is not None: - state.active_rpc_count += 1 - rpc_future.add_done_callback( - lambda unused_future: _on_call_completed(state)) - if state.stage is _ServerStage.STARTED: - _request_call(state) - elif _stop_serving(state): - return - else: - rpc_state, callbacks = event.tag(event) - for callback in callbacks: - callable_util.call_logging_exceptions( - callback, 'Exception calling callback!') - if rpc_state is not None: - with state.lock: - state.rpc_states.remove(rpc_state) - if _stop_serving(state): - return + timeout = time.time() + _DEALLOCATED_SERVER_CHECK_PERIOD_S + event = state.completion_queue.poll(timeout) + if state.server_deallocated: + _begin_shutdown_once(state) + if event.completion_type != cygrpc.CompletionType.queue_timeout: + if not _process_event_and_continue(state, event): + return # We want to force the deletion of the previous event # ~before~ we poll again; if the event has a reference # to a shutdown Call object, this can induce spinlock. event = None +def _begin_shutdown_once(state): + with state.lock: + if state.stage is _ServerStage.STARTED: + state.server.shutdown(state.completion_queue, _SHUTDOWN_TAG) + state.stage = _ServerStage.GRACE + state.shutdown_events = [] + state.due.add(_SHUTDOWN_TAG) + + def _stop(state, grace): with state.lock: if state.stage is _ServerStage.STOPPED: @@ -753,11 +887,7 @@ def _stop(state, grace): shutdown_event.set() return shutdown_event else: - if state.stage is _ServerStage.STARTED: - state.server.shutdown(state.completion_queue, _SHUTDOWN_TAG) - state.stage = _ServerStage.GRACE - state.shutdown_events = [] - state.due.add(_SHUTDOWN_TAG) + _begin_shutdown_once(state) shutdown_event = threading.Event() state.shutdown_events.append(shutdown_event) if grace is None: @@ -798,13 +928,18 @@ def _validate_generic_rpc_handlers(generic_rpc_handlers): 'not have "service" method!'.format(generic_rpc_handler)) +def _augment_options(base_options, compression): + compression_option = _compression.create_channel_option(compression) + return tuple(base_options) + compression_option + + class _Server(grpc.Server): # pylint: disable=too-many-arguments def __init__(self, thread_pool, generic_handlers, interceptors, options, - maximum_concurrent_rpcs): + maximum_concurrent_rpcs, compression): completion_queue = cygrpc.CompletionQueue() - server = cygrpc.Server(options) + server = cygrpc.Server(_augment_options(options, compression)) server.register_completion_queue(completion_queue) self._state = _ServerState(completion_queue, server, generic_handlers, _interceptor.service_pipeline(interceptors), @@ -828,11 +963,14 @@ class _Server(grpc.Server): return _stop(self._state, grace) def __del__(self): - _stop(self._state, None) + if hasattr(self, '_state'): + # We can not grab a lock in __del__(), so set a flag to signal the + # serving daemon thread (if it exists) to initiate shutdown. + self._state.server_deallocated = True def create_server(thread_pool, generic_rpc_handlers, interceptors, options, - maximum_concurrent_rpcs): + maximum_concurrent_rpcs, compression): _validate_generic_rpc_handlers(generic_rpc_handlers) return _Server(thread_pool, generic_rpc_handlers, interceptors, options, - maximum_concurrent_rpcs) + maximum_concurrent_rpcs, compression) diff --git a/src/python/grpcio/grpc/_utilities.py b/src/python/grpcio/grpc/_utilities.py index d90b34bcbd4..c48aaf60a2f 100644 --- a/src/python/grpcio/grpc/_utilities.py +++ b/src/python/grpcio/grpc/_utilities.py @@ -16,12 +16,14 @@ import collections import threading import time +import logging import six import grpc from grpc import _common -from grpc.framework.foundation import callable_util + +_LOGGER = logging.getLogger(__name__) _DONE_CALLBACK_EXCEPTION_LOG_MESSAGE = ( 'Exception calling connectivity future "done" callback!') @@ -98,8 +100,10 @@ class _ChannelReadyFuture(grpc.Future): return for done_callback in done_callbacks: - callable_util.call_logging_exceptions( - done_callback, _DONE_CALLBACK_EXCEPTION_LOG_MESSAGE, self) + try: + done_callback(self) + except Exception: # pylint: disable=broad-except + _LOGGER.exception(_DONE_CALLBACK_EXCEPTION_LOG_MESSAGE) def cancel(self): with self._condition: @@ -113,8 +117,10 @@ class _ChannelReadyFuture(grpc.Future): return False for done_callback in done_callbacks: - callable_util.call_logging_exceptions( - done_callback, _DONE_CALLBACK_EXCEPTION_LOG_MESSAGE, self) + try: + done_callback(self) + except Exception: # pylint: disable=broad-except + _LOGGER.exception(_DONE_CALLBACK_EXCEPTION_LOG_MESSAGE) return True @@ -132,15 +138,12 @@ class _ChannelReadyFuture(grpc.Future): def result(self, timeout=None): self._block(timeout) - return None def exception(self, timeout=None): self._block(timeout) - return None def traceback(self, timeout=None): self._block(timeout) - return None def add_done_callback(self, fn): with self._condition: diff --git a/src/python/grpcio/grpc/beta/BUILD.bazel b/src/python/grpcio/grpc/beta/BUILD.bazel deleted file mode 100644 index 731be5cb25b..00000000000 --- a/src/python/grpcio/grpc/beta/BUILD.bazel +++ /dev/null @@ -1,58 +0,0 @@ -load("@grpc_python_dependencies//:requirements.bzl", "requirement") -package(default_visibility = ["//visibility:public"]) - -py_library( - name = "beta", - srcs = ["__init__.py",], - deps = [ - ":client_adaptations", - ":metadata", - ":server_adaptations", - ":implementations", - ":interfaces", - ":utilities", - ], -) - -py_library( - name = "client_adaptations", - srcs = ["_client_adaptations.py"], - imports=["../../",] -) - -py_library( - name = "metadata", - srcs = ["_metadata.py"], -) - -py_library( - name = "server_adaptations", - srcs = ["_server_adaptations.py"], - imports=["../../",], -) - -py_library( - name = "implementations", - srcs = ["implementations.py"], - imports=["../../",], -) - -py_library( - name = "interfaces", - srcs = ["interfaces.py"], - deps = [ - requirement("six"), - ], - imports=["../../",], -) - -py_library( - name = "utilities", - srcs = ["utilities.py"], - deps = [ - ":implementations", - ":interfaces", - "//src/python/grpcio/grpc/framework/foundation", - ], -) - diff --git a/src/python/grpcio/grpc/framework/common/BUILD.bazel b/src/python/grpcio/grpc/framework/common/BUILD.bazel index 9d9ef682c90..52fbb2b516c 100644 --- a/src/python/grpcio/grpc/framework/common/BUILD.bazel +++ b/src/python/grpcio/grpc/framework/common/BUILD.bazel @@ -13,15 +13,17 @@ py_library( py_library( name = "cardinality", srcs = ["cardinality.py"], - deps = [ - requirement("enum34"), - ], + deps = select({ + "//conditions:default": [requirement('enum34'),], + "//:python3": [], + }), ) py_library( name = "style", srcs = ["style.py"], - deps = [ - requirement("enum34"), - ], + deps = select({ + "//conditions:default": [requirement('enum34'),], + "//:python3": [], + }), ) diff --git a/src/python/grpcio/grpc/framework/foundation/BUILD.bazel b/src/python/grpcio/grpc/framework/foundation/BUILD.bazel index 1287fdd44ed..a447ecded49 100644 --- a/src/python/grpcio/grpc/framework/foundation/BUILD.bazel +++ b/src/python/grpcio/grpc/framework/foundation/BUILD.bazel @@ -23,9 +23,11 @@ py_library( name = "callable_util", srcs = ["callable_util.py"], deps = [ - requirement("enum34"), requirement("six"), - ], + ] + select({ + "//conditions:default": [requirement('enum34'),], + "//:python3": [], + }), ) py_library( @@ -39,9 +41,10 @@ py_library( py_library( name = "logging_pool", srcs = ["logging_pool.py"], - deps = [ - requirement("futures"), - ], + deps = select({ + "//conditions:default": [requirement('futures'),], + "//:python3": [], + }), ) py_library( diff --git a/src/python/grpcio/grpc/framework/interfaces/base/BUILD.bazel b/src/python/grpcio/grpc/framework/interfaces/base/BUILD.bazel index 408a66a6310..35cfe877f34 100644 --- a/src/python/grpcio/grpc/framework/interfaces/base/BUILD.bazel +++ b/src/python/grpcio/grpc/framework/interfaces/base/BUILD.bazel @@ -15,15 +15,18 @@ py_library( srcs = ["base.py"], deps = [ "//src/python/grpcio/grpc/framework/foundation:abandonment", - requirement("enum34"), requirement("six"), - ], + ] + select({ + "//conditions:default": [requirement('enum34'),], + "//:python3": [], + }), ) py_library( name = "utilities", srcs = ["utilities.py"], - deps = [ - requirement("enum34"), - ], + deps = select({ + "//conditions:default": [requirement('enum34'),], + "//:python3": [], + }), ) diff --git a/src/python/grpcio/grpc/framework/interfaces/face/BUILD.bazel b/src/python/grpcio/grpc/framework/interfaces/face/BUILD.bazel index e683e7cc426..83fadb6372e 100644 --- a/src/python/grpcio/grpc/framework/interfaces/face/BUILD.bazel +++ b/src/python/grpcio/grpc/framework/interfaces/face/BUILD.bazel @@ -16,9 +16,11 @@ py_library( deps = [ "//src/python/grpcio/grpc/framework/foundation", "//src/python/grpcio/grpc/framework/common", - requirement("enum34"), requirement("six"), - ], + ] + select({ + "//conditions:default": [requirement('enum34'),], + "//:python3": [], + }), ) py_library( diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index a82d6e1ec7c..97c9f2f7c94 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -19,7 +19,6 @@ CORE_SOURCE_FILES = [ 'third_party/address_sorting/address_sorting_posix.c', 'third_party/address_sorting/address_sorting_windows.c', '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', @@ -52,7 +51,9 @@ CORE_SOURCE_FILES = [ '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/arena.cc', 'src/core/lib/gprpp/fork.cc', + 'src/core/lib/gprpp/global_config_env.cc', 'src/core/lib/gprpp/thd_posix.cc', 'src/core/lib/gprpp/thd_windows.cc', 'src/core/lib/profiling/basic_timers.cc', @@ -68,10 +69,10 @@ CORE_SOURCE_FILES = [ 'src/core/lib/channel/channelz_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_args.cc', 'src/core/lib/compression/compression_internal.cc', 'src/core/lib/compression/message_compress.cc', 'src/core/lib/compression/stream_compression.cc', @@ -84,12 +85,15 @@ CORE_SOURCE_FILES = [ 'src/core/lib/http/parser.cc', 'src/core/lib/iomgr/buffer_list.cc', 'src/core/lib/iomgr/call_combiner.cc', + 'src/core/lib/iomgr/cfstream_handle.cc', 'src/core/lib/iomgr/combiner.cc', 'src/core/lib/iomgr/endpoint.cc', + 'src/core/lib/iomgr/endpoint_cfstream.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/error_cfstream.cc', 'src/core/lib/iomgr/ev_epoll1_linux.cc', 'src/core/lib/iomgr/ev_epollex_linux.cc', 'src/core/lib/iomgr/ev_poll_posix.cc', @@ -102,18 +106,20 @@ CORE_SOURCE_FILES = [ '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/grpc_if_nametoindex_posix.cc', + 'src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc', 'src/core/lib/iomgr/internal_errqueue.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_posix_cfstream.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', @@ -137,6 +143,7 @@ CORE_SOURCE_FILES = [ '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_cfstream.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', @@ -161,7 +168,6 @@ CORE_SOURCE_FILES = [ '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', @@ -201,7 +207,6 @@ CORE_SOURCE_FILES = [ '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', @@ -215,6 +220,7 @@ CORE_SOURCE_FILES = [ '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/context_list.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', @@ -255,6 +261,8 @@ CORE_SOURCE_FILES = [ '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/tls/grpc_tls_credentials_options.cc', + 'src/core/lib/security/credentials/tls/spiffe_credentials.cc', 'src/core/lib/security/security_connector/alts/alts_security_connector.cc', 'src/core/lib/security/security_connector/fake/fake_security_connector.cc', 'src/core/lib/security/security_connector/load_system_roots_fallback.cc', @@ -263,6 +271,7 @@ CORE_SOURCE_FILES = [ 'src/core/lib/security/security_connector/security_connector.cc', 'src/core/lib/security/security_connector/ssl/ssl_security_connector.cc', 'src/core/lib/security/security_connector/ssl_utils.cc', + 'src/core/lib/security/security_connector/tls/spiffe_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', @@ -317,21 +326,25 @@ CORE_SOURCE_FILES = [ '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/global_subchannel_pool.cc', 'src/core/ext/filters/client_channel/health/health_check_client.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/local_subchannel_pool.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/resolver_result_parsing.cc', + 'src/core/ext/filters/client_channel/resolving_lb_policy.cc', 'src/core/ext/filters/client_channel/retry_throttle.cc', + 'src/core/ext/filters/client_channel/server_address.cc', + 'src/core/ext/filters/client_channel/service_config.cc', 'src/core/ext/filters/client_channel/subchannel.cc', - 'src/core/ext/filters/client_channel/subchannel_index.cc', + 'src/core/ext/filters/client_channel/subchannel_pool_interface.cc', 'src/core/ext/filters/deadline/deadline_filter.cc', 'src/core/ext/filters/client_channel/health/health.pb.c', 'src/core/tsi/fake_transport_security.cc', @@ -364,10 +377,13 @@ CORE_SOURCE_FILES = [ '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.cc', + 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc', + 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc', + 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc', 'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc', @@ -693,6 +709,7 @@ CORE_SOURCE_FILES = [ 'third_party/cares/cares/ares_strcasecmp.c', 'third_party/cares/cares/ares_strdup.c', 'third_party/cares/cares/ares_strerror.c', + 'third_party/cares/cares/ares_strsplit.c', 'third_party/cares/cares/ares_timeout.c', 'third_party/cares/cares/ares_version.c', 'third_party/cares/cares/ares_writev.c', diff --git a/src/python/grpcio/grpc_version.py b/src/python/grpcio/grpc_version.py index 71113e68d99..971fd37afb6 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.17.0.dev0' +VERSION = '1.22.0.dev0' diff --git a/src/python/grpcio_channelz/.gitignore b/src/python/grpcio_channelz/.gitignore new file mode 100644 index 00000000000..0c5da6b5af1 --- /dev/null +++ b/src/python/grpcio_channelz/.gitignore @@ -0,0 +1,6 @@ +*.proto +*_pb2.py +*_pb2_grpc.py +build/ +grpcio_channelz.egg-info/ +dist/ diff --git a/src/python/grpcio_channelz/MANIFEST.in b/src/python/grpcio_channelz/MANIFEST.in new file mode 100644 index 00000000000..ee93e21a69b --- /dev/null +++ b/src/python/grpcio_channelz/MANIFEST.in @@ -0,0 +1,4 @@ +include grpc_version.py +recursive-include grpc_channelz *.py +global-exclude *.pyc +include LICENSE diff --git a/src/python/grpcio_channelz/README.rst b/src/python/grpcio_channelz/README.rst new file mode 100644 index 00000000000..efeaa560646 --- /dev/null +++ b/src/python/grpcio_channelz/README.rst @@ -0,0 +1,9 @@ +gRPC Python Channelz package +============================== + +Channelz is a live debug tool in gRPC Python. + +Dependencies +------------ + +Depends on the `grpcio` package, available from PyPI via `pip install grpcio`. diff --git a/src/python/grpcio_channelz/channelz_commands.py b/src/python/grpcio_channelz/channelz_commands.py new file mode 100644 index 00000000000..7f158c2a4bf --- /dev/null +++ b/src/python/grpcio_channelz/channelz_commands.py @@ -0,0 +1,67 @@ +# Copyright 2018 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. +# 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. +"""Provides distutils command classes for the GRPC Python setup process.""" + +import os +import shutil + +import setuptools + +ROOT_DIR = os.path.abspath(os.path.dirname(os.path.abspath(__file__))) +CHANNELZ_PROTO = os.path.join(ROOT_DIR, + '../../proto/grpc/channelz/channelz.proto') +LICENSE = os.path.join(ROOT_DIR, '../../../LICENSE') + + +class Preprocess(setuptools.Command): + """Command to copy proto modules from grpc/src/proto and LICENSE from + the root directory""" + + description = '' + user_options = [] + + def initialize_options(self): + pass + + def finalize_options(self): + pass + + def run(self): + if os.path.isfile(CHANNELZ_PROTO): + shutil.copyfile(CHANNELZ_PROTO, + os.path.join(ROOT_DIR, + 'grpc_channelz/v1/channelz.proto')) + if os.path.isfile(LICENSE): + shutil.copyfile(LICENSE, os.path.join(ROOT_DIR, 'LICENSE')) + + +class BuildPackageProtos(setuptools.Command): + """Command to generate project *_pb2.py modules from proto files.""" + + description = 'build grpc protobuf modules' + user_options = [] + + def initialize_options(self): + pass + + def finalize_options(self): + pass + + def run(self): + # due to limitations of the proto generator, we require that only *one* + # directory is provided as an 'include' directory. We assume it's the '' key + # to `self.distribution.package_dir` (and get a key error if it's not + # there). + from grpc_tools import command + command.build_package_protos(self.distribution.package_dir['']) diff --git a/src/python/grpcio_channelz/grpc_channelz/__init__.py b/src/python/grpcio_channelz/grpc_channelz/__init__.py new file mode 100644 index 00000000000..38fdfc9c5cf --- /dev/null +++ b/src/python/grpcio_channelz/grpc_channelz/__init__.py @@ -0,0 +1,13 @@ +# Copyright 2018 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. +# 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. diff --git a/src/python/grpcio_channelz/grpc_channelz/v1/BUILD.bazel b/src/python/grpcio_channelz/grpc_channelz/v1/BUILD.bazel new file mode 100644 index 00000000000..eccc166577d --- /dev/null +++ b/src/python/grpcio_channelz/grpc_channelz/v1/BUILD.bazel @@ -0,0 +1,18 @@ +load("//bazel:python_rules.bzl", "py_proto_library") +package(default_visibility = ["//visibility:public"]) + +py_proto_library( + name = "py_channelz_proto", + well_known_protos = True, + deps = ["//src/proto/grpc/channelz:channelz_proto_descriptors"], +) + +py_library( + name = "grpc_channelz", + srcs = ["channelz.py",], + deps = [ + ":py_channelz_proto", + "//src/python/grpcio/grpc:grpcio", + ], + imports=["../../",], +) diff --git a/src/python/grpcio_channelz/grpc_channelz/v1/__init__.py b/src/python/grpcio_channelz/grpc_channelz/v1/__init__.py new file mode 100644 index 00000000000..38fdfc9c5cf --- /dev/null +++ b/src/python/grpcio_channelz/grpc_channelz/v1/__init__.py @@ -0,0 +1,13 @@ +# Copyright 2018 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. +# 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. diff --git a/src/python/grpcio_channelz/grpc_channelz/v1/channelz.py b/src/python/grpcio_channelz/grpc_channelz/v1/channelz.py new file mode 100644 index 00000000000..00eca311dc1 --- /dev/null +++ b/src/python/grpcio_channelz/grpc_channelz/v1/channelz.py @@ -0,0 +1,142 @@ +# Copyright 2018 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. +# 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. +"""Channelz debug service implementation in gRPC Python.""" + +import grpc +from grpc._cython import cygrpc + +import grpc_channelz.v1.channelz_pb2 as _channelz_pb2 +import grpc_channelz.v1.channelz_pb2_grpc as _channelz_pb2_grpc + +from google.protobuf import json_format + + +class ChannelzServicer(_channelz_pb2_grpc.ChannelzServicer): + """Servicer handling RPCs for service statuses.""" + + @staticmethod + def GetTopChannels(request, context): + try: + return json_format.Parse( + cygrpc.channelz_get_top_channels(request.start_channel_id), + _channelz_pb2.GetTopChannelsResponse(), + ) + except (ValueError, json_format.ParseError) as e: + context.set_code(grpc.StatusCode.INTERNAL) + context.set_details(str(e)) + + @staticmethod + def GetServers(request, context): + try: + return json_format.Parse( + cygrpc.channelz_get_servers(request.start_server_id), + _channelz_pb2.GetServersResponse(), + ) + except (ValueError, json_format.ParseError) as e: + context.set_code(grpc.StatusCode.INTERNAL) + context.set_details(str(e)) + + @staticmethod + def GetServer(request, context): + try: + return json_format.Parse( + cygrpc.channelz_get_server(request.server_id), + _channelz_pb2.GetServerResponse(), + ) + except ValueError as e: + context.set_code(grpc.StatusCode.NOT_FOUND) + context.set_details(str(e)) + except json_format.ParseError as e: + context.set_code(grpc.StatusCode.INTERNAL) + context.set_details(str(e)) + + @staticmethod + def GetServerSockets(request, context): + try: + return json_format.Parse( + cygrpc.channelz_get_server_sockets(request.server_id, + request.start_socket_id, + request.max_results), + _channelz_pb2.GetServerSocketsResponse(), + ) + except ValueError as e: + context.set_code(grpc.StatusCode.NOT_FOUND) + context.set_details(str(e)) + except json_format.ParseError as e: + context.set_code(grpc.StatusCode.INTERNAL) + context.set_details(str(e)) + + @staticmethod + def GetChannel(request, context): + try: + return json_format.Parse( + cygrpc.channelz_get_channel(request.channel_id), + _channelz_pb2.GetChannelResponse(), + ) + except ValueError as e: + context.set_code(grpc.StatusCode.NOT_FOUND) + context.set_details(str(e)) + except json_format.ParseError as e: + context.set_code(grpc.StatusCode.INTERNAL) + context.set_details(str(e)) + + @staticmethod + def GetSubchannel(request, context): + try: + return json_format.Parse( + cygrpc.channelz_get_subchannel(request.subchannel_id), + _channelz_pb2.GetSubchannelResponse(), + ) + except ValueError as e: + context.set_code(grpc.StatusCode.NOT_FOUND) + context.set_details(str(e)) + except json_format.ParseError as e: + context.set_code(grpc.StatusCode.INTERNAL) + context.set_details(str(e)) + + @staticmethod + def GetSocket(request, context): + try: + return json_format.Parse( + cygrpc.channelz_get_socket(request.socket_id), + _channelz_pb2.GetSocketResponse(), + ) + except ValueError as e: + context.set_code(grpc.StatusCode.NOT_FOUND) + context.set_details(str(e)) + except json_format.ParseError as e: + context.set_code(grpc.StatusCode.INTERNAL) + context.set_details(str(e)) + + +def add_channelz_servicer(server): + """Add Channelz servicer to a server. Channelz servicer is in charge of + pulling information from C-Core for entire process. It will allow the + server to response to Channelz queries. + + The Channelz statistic is enabled by default inside C-Core. Whether the + statistic is enabled or not is isolated from adding Channelz servicer. + That means you can query Channelz info with a Channelz-disabled channel, + and you can add Channelz servicer to a Channelz-disabled server. + + The Channelz statistic can be enabled or disabled by channel option + 'grpc.enable_channelz'. Set to 1 to enable, set to 0 to disable. + + This is an EXPERIMENTAL API. + + Args: + server: grpc.Server to which Channelz service will be added. + """ + _channelz_pb2_grpc.add_ChannelzServicer_to_server(ChannelzServicer(), + server) diff --git a/src/python/grpcio_channelz/grpc_version.py b/src/python/grpcio_channelz/grpc_version.py new file mode 100644 index 00000000000..52baab4c30f --- /dev/null +++ b/src/python/grpcio_channelz/grpc_version.py @@ -0,0 +1,17 @@ +# Copyright 2018 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. +# 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. + +# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_channelz/grpc_version.py.template`!!! + +VERSION = '1.22.0.dev0' diff --git a/src/python/grpcio_channelz/setup.py b/src/python/grpcio_channelz/setup.py new file mode 100644 index 00000000000..f8c0e93913d --- /dev/null +++ b/src/python/grpcio_channelz/setup.py @@ -0,0 +1,96 @@ +# Copyright 2018 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. +# 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. +"""Setup module for the GRPC Python package's Channelz.""" + +import os +import sys + +import setuptools + +# Ensure we're in the proper directory whether or not we're being used by pip. +os.chdir(os.path.dirname(os.path.abspath(__file__))) + +# Break import-style to ensure we can actually find our local modules. +import grpc_version + + +class _NoOpCommand(setuptools.Command): + """No-op command.""" + + description = '' + user_options = [] + + def initialize_options(self): + pass + + def finalize_options(self): + pass + + def run(self): + pass + + +CLASSIFIERS = [ + 'Development Status :: 5 - Production/Stable', + 'Programming Language :: Python', + 'Programming Language :: Python :: 2', + 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.4', + 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.6', + 'License :: OSI Approved :: Apache Software License', +] + +PACKAGE_DIRECTORIES = { + '': '.', +} + +INSTALL_REQUIRES = ( + 'protobuf>=3.6.0', + 'grpcio>={version}'.format(version=grpc_version.VERSION), +) + +try: + import channelz_commands as _channelz_commands + # we are in the build environment, otherwise the above import fails + SETUP_REQUIRES = ( + 'grpcio-tools=={version}'.format(version=grpc_version.VERSION),) + COMMAND_CLASS = { + # Run preprocess from the repository *before* doing any packaging! + 'preprocess': _channelz_commands.Preprocess, + 'build_package_protos': _channelz_commands.BuildPackageProtos, + } +except ImportError: + SETUP_REQUIRES = () + COMMAND_CLASS = { + # wire up commands to no-op not to break the external dependencies + 'preprocess': _NoOpCommand, + 'build_package_protos': _NoOpCommand, + } + +setuptools.setup( + name='grpcio-channelz', + version=grpc_version.VERSION, + license='Apache License 2.0', + description='Channel Level Live Debug Information Service for gRPC', + author='The gRPC Authors', + author_email='grpc-io@googlegroups.com', + classifiers=CLASSIFIERS, + url='https://grpc.io', + package_dir=PACKAGE_DIRECTORIES, + packages=setuptools.find_packages('.'), + install_requires=INSTALL_REQUIRES, + setup_requires=SETUP_REQUIRES, + cmdclass=COMMAND_CLASS) diff --git a/src/python/grpcio_health_checking/MANIFEST.in b/src/python/grpcio_health_checking/MANIFEST.in index 996c74a9d49..3a22311b8e7 100644 --- a/src/python/grpcio_health_checking/MANIFEST.in +++ b/src/python/grpcio_health_checking/MANIFEST.in @@ -1,3 +1,4 @@ include grpc_version.py recursive-include grpc_health *.py global-exclude *.pyc +include LICENSE diff --git a/src/python/grpcio_health_checking/grpc_health/v1/BUILD.bazel b/src/python/grpcio_health_checking/grpc_health/v1/BUILD.bazel index ce3121fa90e..9e4fff34581 100644 --- a/src/python/grpcio_health_checking/grpc_health/v1/BUILD.bazel +++ b/src/python/grpcio_health_checking/grpc_health/v1/BUILD.bazel @@ -1,24 +1,9 @@ -load("@grpc_python_dependencies//:requirements.bzl", "requirement") -load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_library") - +load("//bazel:python_rules.bzl", "py_proto_library") package(default_visibility = ["//visibility:public"]) -genrule( - name = "mv_health_proto", - srcs = [ - "//src/proto/grpc/health/v1:health_proto_file", - ], - outs = ["health.proto",], - cmd = "cp $< $@", -) - py_proto_library( name = "py_health_proto", - protos = [":mv_health_proto",], - with_grpc = True, - deps = [ - requirement('protobuf'), - ], + deps = ["//src/proto/grpc/health/v1:health_proto_descriptor",], ) py_library( diff --git a/src/python/grpcio_health_checking/grpc_health/v1/health.py b/src/python/grpcio_health_checking/grpc_health/v1/health.py index 05836594281..15494fafdbc 100644 --- a/src/python/grpcio_health_checking/grpc_health/v1/health.py +++ b/src/python/grpcio_health_checking/grpc_health/v1/health.py @@ -13,6 +13,7 @@ # limitations under the License. """Reference implementation for health checking in gRPC Python.""" +import collections import threading import grpc @@ -23,15 +24,78 @@ from grpc_health.v1 import health_pb2_grpc as _health_pb2_grpc SERVICE_NAME = _health_pb2.DESCRIPTOR.services_by_name['Health'].full_name +class _Watcher(): + + def __init__(self): + self._condition = threading.Condition() + self._responses = collections.deque() + self._open = True + + def __iter__(self): + return self + + def _next(self): + with self._condition: + while not self._responses and self._open: + self._condition.wait() + if self._responses: + return self._responses.popleft() + else: + raise StopIteration() + + def next(self): + return self._next() + + def __next__(self): + return self._next() + + def add(self, response): + with self._condition: + self._responses.append(response) + self._condition.notify() + + def close(self): + with self._condition: + self._open = False + self._condition.notify() + + +def _watcher_to_send_response_callback_adapter(watcher): + + def send_response_callback(response): + if response is None: + watcher.close() + else: + watcher.add(response) + + return send_response_callback + + class HealthServicer(_health_pb2_grpc.HealthServicer): """Servicer handling RPCs for service statuses.""" - def __init__(self): - self._server_status_lock = threading.Lock() + def __init__(self, + experimental_non_blocking=True, + experimental_thread_pool=None): + self._lock = threading.RLock() self._server_status = {} + self._send_response_callbacks = {} + self.Watch.__func__.experimental_non_blocking = experimental_non_blocking + self.Watch.__func__.experimental_thread_pool = experimental_thread_pool + self._gracefully_shutting_down = False + + def _on_close_callback(self, send_response_callback, service): + + def callback(): + with self._lock: + self._send_response_callbacks[service].remove( + send_response_callback) + send_response_callback(None) + + return callback def Check(self, request, context): - with self._server_status_lock: + with self._lock: status = self._server_status.get(request.service) if status is None: context.set_code(grpc.StatusCode.NOT_FOUND) @@ -39,14 +103,63 @@ class HealthServicer(_health_pb2_grpc.HealthServicer): else: return _health_pb2.HealthCheckResponse(status=status) + # pylint: disable=arguments-differ + def Watch(self, request, context, send_response_callback=None): + blocking_watcher = None + if send_response_callback is None: + # The server does not support the experimental_non_blocking + # parameter. For backwards compatibility, return a blocking response + # generator. + blocking_watcher = _Watcher() + send_response_callback = _watcher_to_send_response_callback_adapter( + blocking_watcher) + service = request.service + with self._lock: + status = self._server_status.get(service) + if status is None: + status = _health_pb2.HealthCheckResponse.SERVICE_UNKNOWN # pylint: disable=no-member + send_response_callback( + _health_pb2.HealthCheckResponse(status=status)) + if service not in self._send_response_callbacks: + self._send_response_callbacks[service] = set() + self._send_response_callbacks[service].add(send_response_callback) + context.add_callback( + self._on_close_callback(send_response_callback, service)) + return blocking_watcher + def set(self, service, status): """Sets the status of a service. - Args: - service: string, the name of the service. - NOTE, '' must be set. - status: HealthCheckResponse.status enum value indicating - the status of the service - """ - with self._server_status_lock: - self._server_status[service] = status + Args: + service: string, the name of the service. NOTE, '' must be set. + status: HealthCheckResponse.status enum value indicating the status of + the service + """ + with self._lock: + if self._gracefully_shutting_down: + return + else: + self._server_status[service] = status + if service in self._send_response_callbacks: + for send_response_callback in self._send_response_callbacks[ + service]: + send_response_callback( + _health_pb2.HealthCheckResponse(status=status)) + + def enter_graceful_shutdown(self): + """Permanently sets the status of all services to NOT_SERVING. + + This should be invoked when the server is entering a graceful shutdown + period. After this method is invoked, future attempts to set the status + of a service will be ignored. + + This is an EXPERIMENTAL API. + """ + with self._lock: + if self._gracefully_shutting_down: + return + else: + for service in self._server_status: + self.set(service, + _health_pb2.HealthCheckResponse.NOT_SERVING) # pylint: disable=no-member + self._gracefully_shutting_down = True diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py index a30aac2e0b8..be4ca841361 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.17.0.dev0' +VERSION = '1.22.0.dev0' diff --git a/src/python/grpcio_health_checking/health_commands.py b/src/python/grpcio_health_checking/health_commands.py index 933f965aa2d..3820ef0bbad 100644 --- a/src/python/grpcio_health_checking/health_commands.py +++ b/src/python/grpcio_health_checking/health_commands.py @@ -20,10 +20,12 @@ import setuptools ROOT_DIR = os.path.abspath(os.path.dirname(os.path.abspath(__file__))) HEALTH_PROTO = os.path.join(ROOT_DIR, '../../proto/grpc/health/v1/health.proto') +LICENSE = os.path.join(ROOT_DIR, '../../../LICENSE') -class CopyProtoModules(setuptools.Command): - """Command to copy proto modules from grpc/src/proto.""" +class Preprocess(setuptools.Command): + """Command to copy proto modules from grpc/src/proto and LICENSE from + the root directory""" description = '' user_options = [] @@ -39,6 +41,8 @@ class CopyProtoModules(setuptools.Command): shutil.copyfile(HEALTH_PROTO, os.path.join(ROOT_DIR, 'grpc_health/v1/health.proto')) + if os.path.isfile(LICENSE): + shutil.copyfile(LICENSE, os.path.join(ROOT_DIR, 'LICENSE')) class BuildPackageProtos(setuptools.Command): diff --git a/src/python/grpcio_health_checking/setup.py b/src/python/grpcio_health_checking/setup.py index db2edae2cea..5a09a80f6ae 100644 --- a/src/python/grpcio_health_checking/setup.py +++ b/src/python/grpcio_health_checking/setup.py @@ -68,7 +68,7 @@ try: 'grpcio-tools=={version}'.format(version=grpc_version.VERSION),) COMMAND_CLASS = { # Run preprocess from the repository *before* doing any packaging! - 'preprocess': _health_commands.CopyProtoModules, + 'preprocess': _health_commands.Preprocess, 'build_package_protos': _health_commands.BuildPackageProtos, } except ImportError: diff --git a/src/python/grpcio_reflection/MANIFEST.in b/src/python/grpcio_reflection/MANIFEST.in index d6fb6ce73aa..10b01fa41de 100644 --- a/src/python/grpcio_reflection/MANIFEST.in +++ b/src/python/grpcio_reflection/MANIFEST.in @@ -1,3 +1,4 @@ include grpc_version.py recursive-include grpc_reflection *.py global-exclude *.pyc +include LICENSE diff --git a/src/python/grpcio_reflection/grpc_reflection/v1alpha/BUILD.bazel b/src/python/grpcio_reflection/grpc_reflection/v1alpha/BUILD.bazel index 3a2ba263715..6aaa4dd3bdd 100644 --- a/src/python/grpcio_reflection/grpc_reflection/v1alpha/BUILD.bazel +++ b/src/python/grpcio_reflection/grpc_reflection/v1alpha/BUILD.bazel @@ -1,24 +1,11 @@ +load("//bazel:python_rules.bzl", "py_proto_library") load("@grpc_python_dependencies//:requirements.bzl", "requirement") -load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_library") package(default_visibility = ["//visibility:public"]) -genrule( - name = "mv_reflection_proto", - srcs = [ - "//src/proto/grpc/reflection/v1alpha:reflection_proto_file", - ], - outs = ["reflection.proto",], - cmd = "cp $< $@", -) - py_proto_library( name = "py_reflection_proto", - protos = [":mv_reflection_proto",], - with_grpc = True, - deps = [ - requirement('protobuf'), - ], + deps = ["//src/proto/grpc/reflection/v1alpha:reflection_proto_descriptor",], ) py_library( diff --git a/src/python/grpcio_reflection/grpc_version.py b/src/python/grpcio_reflection/grpc_version.py index aafea9fe76b..1efc4ee2c8d 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.17.0.dev0' +VERSION = '1.22.0.dev0' diff --git a/src/python/grpcio_reflection/reflection_commands.py b/src/python/grpcio_reflection/reflection_commands.py index 6f91f6b8751..311ca4c4dba 100644 --- a/src/python/grpcio_reflection/reflection_commands.py +++ b/src/python/grpcio_reflection/reflection_commands.py @@ -21,10 +21,12 @@ import setuptools ROOT_DIR = os.path.abspath(os.path.dirname(os.path.abspath(__file__))) REFLECTION_PROTO = os.path.join( ROOT_DIR, '../../proto/grpc/reflection/v1alpha/reflection.proto') +LICENSE = os.path.join(ROOT_DIR, '../../../LICENSE') -class CopyProtoModules(setuptools.Command): - """Command to copy proto modules from grpc/src/proto.""" +class Preprocess(setuptools.Command): + """Command to copy proto modules from grpc/src/proto and LICENSE from + the root directory""" description = '' user_options = [] @@ -41,6 +43,8 @@ class CopyProtoModules(setuptools.Command): REFLECTION_PROTO, os.path.join(ROOT_DIR, 'grpc_reflection/v1alpha/reflection.proto')) + if os.path.isfile(LICENSE): + shutil.copyfile(LICENSE, os.path.join(ROOT_DIR, 'LICENSE')) class BuildPackageProtos(setuptools.Command): diff --git a/src/python/grpcio_reflection/setup.py b/src/python/grpcio_reflection/setup.py index b4087d87b49..f205069acd5 100644 --- a/src/python/grpcio_reflection/setup.py +++ b/src/python/grpcio_reflection/setup.py @@ -69,7 +69,7 @@ try: 'grpcio-tools=={version}'.format(version=grpc_version.VERSION),) COMMAND_CLASS = { # Run preprocess from the repository *before* doing any packaging! - 'preprocess': _reflection_commands.CopyProtoModules, + 'preprocess': _reflection_commands.Preprocess, 'build_package_protos': _reflection_commands.BuildPackageProtos, } except ImportError: diff --git a/src/python/grpcio_status/.gitignore b/src/python/grpcio_status/.gitignore new file mode 100644 index 00000000000..19d1523efde --- /dev/null +++ b/src/python/grpcio_status/.gitignore @@ -0,0 +1,3 @@ +build/ +grpcio_status.egg-info/ +dist/ diff --git a/src/python/grpcio_status/MANIFEST.in b/src/python/grpcio_status/MANIFEST.in new file mode 100644 index 00000000000..09b8ea721e8 --- /dev/null +++ b/src/python/grpcio_status/MANIFEST.in @@ -0,0 +1,4 @@ +include grpc_version.py +recursive-include grpc_status *.py +global-exclude *.pyc +include LICENSE diff --git a/src/python/grpcio_status/README.rst b/src/python/grpcio_status/README.rst new file mode 100644 index 00000000000..dc2f7b1dab1 --- /dev/null +++ b/src/python/grpcio_status/README.rst @@ -0,0 +1,9 @@ +gRPC Python Status Proto +=========================== + +Reference package for GRPC Python status proto mapping. + +Dependencies +------------ + +Depends on the `grpcio` package, available from PyPI via `pip install grpcio`. diff --git a/src/python/grpcio_status/grpc_status/BUILD.bazel b/src/python/grpcio_status/grpc_status/BUILD.bazel new file mode 100644 index 00000000000..223a077c3f2 --- /dev/null +++ b/src/python/grpcio_status/grpc_status/BUILD.bazel @@ -0,0 +1,14 @@ +load("@grpc_python_dependencies//:requirements.bzl", "requirement") + +package(default_visibility = ["//visibility:public"]) + +py_library( + name = "grpc_status", + srcs = ["rpc_status.py",], + deps = [ + "//src/python/grpcio/grpc:grpcio", + requirement('protobuf'), + requirement('googleapis-common-protos'), + ], + imports=["../",], +) diff --git a/src/python/grpcio_status/grpc_status/__init__.py b/src/python/grpcio_status/grpc_status/__init__.py new file mode 100644 index 00000000000..38fdfc9c5cf --- /dev/null +++ b/src/python/grpcio_status/grpc_status/__init__.py @@ -0,0 +1,13 @@ +# Copyright 2018 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. +# 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. diff --git a/src/python/grpcio_status/grpc_status/rpc_status.py b/src/python/grpcio_status/grpc_status/rpc_status.py new file mode 100644 index 00000000000..76891e2422e --- /dev/null +++ b/src/python/grpcio_status/grpc_status/rpc_status.py @@ -0,0 +1,87 @@ +# Copyright 2018 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. +# 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. +"""Reference implementation for status mapping in gRPC Python.""" + +import collections + +import grpc + +from google.rpc import status_pb2 + +_CODE_TO_GRPC_CODE_MAPPING = {x.value[0]: x for x in grpc.StatusCode} + +_GRPC_DETAILS_METADATA_KEY = 'grpc-status-details-bin' + + +class _Status( + collections.namedtuple( + '_Status', ('code', 'details', 'trailing_metadata')), grpc.Status): + pass + + +def _code_to_grpc_status_code(code): + try: + return _CODE_TO_GRPC_CODE_MAPPING[code] + except KeyError: + raise ValueError('Invalid status code %s' % code) + + +def from_call(call): + """Returns a google.rpc.status.Status message corresponding to a given grpc.Call. + + This is an EXPERIMENTAL API. + + Args: + call: A grpc.Call instance. + + Returns: + A google.rpc.status.Status message representing the status of the RPC. + + Raises: + ValueError: If the gRPC call's code or details are inconsistent with the + status code and message inside of the google.rpc.status.Status. + """ + for key, value in call.trailing_metadata(): + if key == _GRPC_DETAILS_METADATA_KEY: + rich_status = status_pb2.Status.FromString(value) + if call.code().value[0] != rich_status.code: + raise ValueError( + 'Code in Status proto (%s) doesn\'t match status code (%s)' + % (_code_to_grpc_status_code(rich_status.code), + call.code())) + if call.details() != rich_status.message: + raise ValueError( + 'Message in Status proto (%s) doesn\'t match status details (%s)' + % (rich_status.message, call.details())) + return rich_status + return None + + +def to_status(status): + """Convert a google.rpc.status.Status message to grpc.Status. + + This is an EXPERIMENTAL API. + + Args: + status: a google.rpc.status.Status message representing the non-OK status + to terminate the RPC with and communicate it to the client. + + Returns: + A grpc.Status instance representing the input google.rpc.status.Status message. + """ + return _Status( + code=_code_to_grpc_status_code(status.code), + details=status.message, + trailing_metadata=((_GRPC_DETAILS_METADATA_KEY, + status.SerializeToString()),)) diff --git a/src/python/grpcio_status/grpc_version.py b/src/python/grpcio_status/grpc_version.py new file mode 100644 index 00000000000..9e443087755 --- /dev/null +++ b/src/python/grpcio_status/grpc_version.py @@ -0,0 +1,17 @@ +# Copyright 2018 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. +# 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. + +# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_status/grpc_version.py.template`!!! + +VERSION = '1.22.0.dev0' diff --git a/src/python/grpcio_status/setup.py b/src/python/grpcio_status/setup.py new file mode 100644 index 00000000000..983d3ea430b --- /dev/null +++ b/src/python/grpcio_status/setup.py @@ -0,0 +1,93 @@ +# Copyright 2018 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. +# 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. +"""Setup module for the GRPC Python package's status mapping.""" + +import os + +import setuptools + +# Ensure we're in the proper directory whether or not we're being used by pip. +os.chdir(os.path.dirname(os.path.abspath(__file__))) + +# Break import-style to ensure we can actually find our local modules. +import grpc_version + + +class _NoOpCommand(setuptools.Command): + """No-op command.""" + + description = '' + user_options = [] + + def initialize_options(self): + pass + + def finalize_options(self): + pass + + def run(self): + pass + + +CLASSIFIERS = [ + 'Development Status :: 5 - Production/Stable', + 'Programming Language :: Python', + 'Programming Language :: Python :: 2', + 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.4', + 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', + 'License :: OSI Approved :: Apache Software License', +] + +PACKAGE_DIRECTORIES = { + '': '.', +} + +INSTALL_REQUIRES = ( + 'protobuf>=3.6.0', + 'grpcio>={version}'.format(version=grpc_version.VERSION), + 'googleapis-common-protos>=1.5.5', +) + +try: + import status_commands as _status_commands + # we are in the build environment, otherwise the above import fails + COMMAND_CLASS = { + # Run preprocess from the repository *before* doing any packaging! + 'preprocess': _status_commands.Preprocess, + 'build_package_protos': _NoOpCommand, + } +except ImportError: + COMMAND_CLASS = { + # wire up commands to no-op not to break the external dependencies + 'preprocess': _NoOpCommand, + 'build_package_protos': _NoOpCommand, + } + +setuptools.setup( + name='grpcio-status', + version=grpc_version.VERSION, + description='Status proto mapping for gRPC', + author='The gRPC Authors', + author_email='grpc-io@googlegroups.com', + url='https://grpc.io', + license='Apache License 2.0', + classifiers=CLASSIFIERS, + package_dir=PACKAGE_DIRECTORIES, + packages=setuptools.find_packages('.'), + install_requires=INSTALL_REQUIRES, + cmdclass=COMMAND_CLASS) diff --git a/src/python/grpcio_status/status_commands.py b/src/python/grpcio_status/status_commands.py new file mode 100644 index 00000000000..78cd497f622 --- /dev/null +++ b/src/python/grpcio_status/status_commands.py @@ -0,0 +1,39 @@ +# Copyright 2018 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. +# 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. +"""Provides distutils command classes for the GRPC Python setup process.""" + +import os +import shutil + +import setuptools + +ROOT_DIR = os.path.abspath(os.path.dirname(os.path.abspath(__file__))) +LICENSE = os.path.join(ROOT_DIR, '../../../LICENSE') + + +class Preprocess(setuptools.Command): + """Command to copy LICENSE from root directory.""" + + description = '' + user_options = [] + + def initialize_options(self): + pass + + def finalize_options(self): + pass + + def run(self): + if os.path.isfile(LICENSE): + shutil.copyfile(LICENSE, os.path.join(ROOT_DIR, 'LICENSE')) diff --git a/src/python/grpcio_testing/MANIFEST.in b/src/python/grpcio_testing/MANIFEST.in index 39b35652173..559dfaf786f 100644 --- a/src/python/grpcio_testing/MANIFEST.in +++ b/src/python/grpcio_testing/MANIFEST.in @@ -1,3 +1,4 @@ include grpc_version.py recursive-include grpc_testing *.py global-exclude *.pyc +include LICENSE diff --git a/src/python/grpcio_testing/grpc_testing/_server/_handler.py b/src/python/grpcio_testing/grpc_testing/_server/_handler.py index 0e3404b0d06..100d8195f62 100644 --- a/src/python/grpcio_testing/grpc_testing/_server/_handler.py +++ b/src/python/grpcio_testing/grpc_testing/_server/_handler.py @@ -185,7 +185,7 @@ class _Handler(Handler): elif self._code is None: self._condition.wait() else: - return self._trailing_metadata, self._code, self._details, + return self._trailing_metadata, self._code, self._details def expire(self): with self._condition: diff --git a/src/python/grpcio_testing/grpc_testing/_server/_servicer_context.py b/src/python/grpcio_testing/grpc_testing/_server/_servicer_context.py index 90eeb130d30..63a1b1aec95 100644 --- a/src/python/grpcio_testing/grpc_testing/_server/_servicer_context.py +++ b/src/python/grpcio_testing/grpc_testing/_server/_servicer_context.py @@ -56,6 +56,9 @@ class ServicerContext(grpc.ServicerContext): def auth_context(self): raise NotImplementedError() + def set_compression(self): + raise NotImplementedError() + def send_initial_metadata(self, initial_metadata): initial_metadata_sent = self._rpc.send_initial_metadata( _common.fuss_with_metadata(initial_metadata)) @@ -63,6 +66,9 @@ class ServicerContext(grpc.ServicerContext): raise ValueError( 'ServicerContext.send_initial_metadata called too late!') + def disable_next_message_compression(self): + raise NotImplementedError() + def set_trailing_metadata(self, trailing_metadata): self._rpc.set_trailing_metadata( _common.fuss_with_metadata(trailing_metadata)) @@ -70,6 +76,9 @@ class ServicerContext(grpc.ServicerContext): def abort(self, code, details): raise NotImplementedError() + def abort_with_status(self, status): + raise NotImplementedError() + def set_code(self, code): self._rpc.set_code(code) diff --git a/src/python/grpcio_testing/grpc_version.py b/src/python/grpcio_testing/grpc_version.py index 876acd3142f..18d17e40464 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.17.0.dev0' +VERSION = '1.22.0.dev0' diff --git a/src/python/grpcio_testing/setup.py b/src/python/grpcio_testing/setup.py index 6ceb1fc5c9d..18db71e0f09 100644 --- a/src/python/grpcio_testing/setup.py +++ b/src/python/grpcio_testing/setup.py @@ -24,6 +24,23 @@ os.chdir(os.path.dirname(os.path.abspath(__file__))) # Break import style to ensure that we can find same-directory modules. import grpc_version + +class _NoOpCommand(setuptools.Command): + """No-op command.""" + + description = '' + user_options = [] + + def initialize_options(self): + pass + + def finalize_options(self): + pass + + def run(self): + pass + + PACKAGE_DIRECTORIES = { '': '.', } @@ -33,6 +50,19 @@ INSTALL_REQUIRES = ( 'grpcio>={version}'.format(version=grpc_version.VERSION), ) +try: + import testing_commands as _testing_commands + # we are in the build environment, otherwise the above import fails + COMMAND_CLASS = { + # Run preprocess from the repository *before* doing any packaging! + 'preprocess': _testing_commands.Preprocess, + } +except ImportError: + COMMAND_CLASS = { + # wire up commands to no-op not to break the external dependencies + 'preprocess': _NoOpCommand, + } + setuptools.setup( name='grpcio-testing', version=grpc_version.VERSION, @@ -43,4 +73,5 @@ setuptools.setup( url='https://grpc.io', package_dir=PACKAGE_DIRECTORIES, packages=setuptools.find_packages('.'), - install_requires=INSTALL_REQUIRES) + install_requires=INSTALL_REQUIRES, + cmdclass=COMMAND_CLASS) diff --git a/src/python/grpcio_testing/testing_commands.py b/src/python/grpcio_testing/testing_commands.py new file mode 100644 index 00000000000..fb40d37efb6 --- /dev/null +++ b/src/python/grpcio_testing/testing_commands.py @@ -0,0 +1,39 @@ +# 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. +"""Provides distutils command classes for the GRPC Python setup process.""" + +import os +import shutil + +import setuptools + +ROOT_DIR = os.path.abspath(os.path.dirname(os.path.abspath(__file__))) +LICENSE = os.path.join(ROOT_DIR, '../../../LICENSE') + + +class Preprocess(setuptools.Command): + """Command to copy LICENSE from root directory.""" + + description = '' + user_options = [] + + def initialize_options(self): + pass + + def finalize_options(self): + pass + + def run(self): + if os.path.isfile(LICENSE): + shutil.copyfile(LICENSE, os.path.join(ROOT_DIR, 'LICENSE')) diff --git a/src/python/grpcio_tests/commands.py b/src/python/grpcio_tests/commands.py index d163f6fb68e..dc0795d4a12 100644 --- a/src/python/grpcio_tests/commands.py +++ b/src/python/grpcio_tests/commands.py @@ -22,7 +22,6 @@ import re import shutil import subprocess import sys -import traceback import setuptools from setuptools.command import build_ext @@ -112,10 +111,13 @@ class TestGevent(setuptools.Command): """Command to run tests w/gevent.""" BANNED_TESTS = ( + # Fork support is not compatible with gevent + 'fork._fork_interop_test.ForkInteropTest', # 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', + 'unit._compression_test', # TODO(https://github.com/grpc/grpc/issues/16890) enable this test 'unit._cython._channel_test.ChannelTest.test_multiple_channels_lonely_connectivity', # I have no idea why this doesn't work in gevent, but it shouldn't even be @@ -132,7 +134,29 @@ class TestGevent(setuptools.Command): 'unit.beta._beta_features_test', # TODO(https://github.com/grpc/grpc/issues/15411) unpin gevent version # This test will stuck while running higher version of gevent - 'unit._auth_context_test.AuthContextTest.testSessionResumption') + 'unit._auth_context_test.AuthContextTest.testSessionResumption', + # TODO(https://github.com/grpc/grpc/issues/15411) enable these tests + 'unit._channel_ready_future_test.ChannelReadyFutureTest.test_immediately_connectable_channel_connectivity', + "unit._cython._channel_test.ChannelTest.test_single_channel_lonely_connectivity", + 'unit._exit_test.ExitTest.test_in_flight_unary_unary_call', + 'unit._exit_test.ExitTest.test_in_flight_unary_stream_call', + 'unit._exit_test.ExitTest.test_in_flight_stream_unary_call', + 'unit._exit_test.ExitTest.test_in_flight_stream_stream_call', + 'unit._exit_test.ExitTest.test_in_flight_partial_unary_stream_call', + 'unit._exit_test.ExitTest.test_in_flight_partial_stream_unary_call', + 'unit._exit_test.ExitTest.test_in_flight_partial_stream_stream_call', + 'unit._metadata_flags_test', + 'health_check._health_servicer_test.HealthServicerTest.test_cancelled_watch_removed_from_watch_list', + # TODO(https://github.com/grpc/grpc/issues/17330) enable these three tests + 'channelz._channelz_servicer_test.ChannelzServicerTest.test_many_subchannels', + 'channelz._channelz_servicer_test.ChannelzServicerTest.test_many_subchannels_and_sockets', + 'channelz._channelz_servicer_test.ChannelzServicerTest.test_streaming_rpc', + # TODO(https://github.com/grpc/grpc/issues/15411) enable this test + 'unit._cython._channel_test.ChannelTest.test_negative_deadline_connectivity' + ) + BANNED_WINDOWS_TESTS = ( + # TODO(https://github.com/grpc/grpc/pull/15411) enable this test + 'unit._dns_resolver_test.DNSResolverTest.test_connect_loopback',) description = 'run tests with gevent. Assumes grpc/gevent are installed' user_options = [] @@ -158,7 +182,10 @@ class TestGevent(setuptools.Command): loader = tests.Loader() loader.loadTestsFromNames(['tests']) runner = tests.Runner() - runner.skip_tests(self.BANNED_TESTS) + if sys.platform == 'win32': + runner.skip_tests(self.BANNED_TESTS + self.BANNED_WINDOWS_TESTS) + else: + runner.skip_tests(self.BANNED_TESTS) result = gevent.spawn(runner.run, loader.suite) result.join() if not result.value.wasSuccessful(): diff --git a/src/python/grpcio_tests/grpc_version.py b/src/python/grpcio_tests/grpc_version.py index cc9b41587ca..401b0bd9697 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.17.0.dev0' +VERSION = '1.22.0.dev0' diff --git a/src/python/grpcio_tests/setup.py b/src/python/grpcio_tests/setup.py index 61c98fa038b..f9cb9d0cec9 100644 --- a/src/python/grpcio_tests/setup.py +++ b/src/python/grpcio_tests/setup.py @@ -39,6 +39,8 @@ PACKAGE_DIRECTORIES = { INSTALL_REQUIRES = ( 'coverage>=4.0', 'enum34>=1.0.4', 'grpcio>={version}'.format(version=grpc_version.VERSION), + 'grpcio-channelz>={version}'.format(version=grpc_version.VERSION), + 'grpcio-status>={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.6.0', 'six>=1.10', 'google-auth>=1.0.0', diff --git a/src/python/grpcio_tests/tests/BUILD.bazel b/src/python/grpcio_tests/tests/BUILD.bazel new file mode 100644 index 00000000000..b2b36ad10f3 --- /dev/null +++ b/src/python/grpcio_tests/tests/BUILD.bazel @@ -0,0 +1,9 @@ +py_library( + name = "bazel_namespace_package_hack", + srcs = ["bazel_namespace_package_hack.py"], + visibility = [ + "//src/python/grpcio_tests/tests/status:__subpackages__", + "//src/python/grpcio_tests/tests/interop:__subpackages__", + "//examples/python/errors:__subpackages__", + ], +) diff --git a/src/python/grpcio_tests/tests/_runner.py b/src/python/grpcio_tests/tests/_runner.py index eaaa027e61f..9ef0f176840 100644 --- a/src/python/grpcio_tests/tests/_runner.py +++ b/src/python/grpcio_tests/tests/_runner.py @@ -203,7 +203,7 @@ class Runner(object): check_kill_self() time.sleep(0) case_thread.join() - except: + except: # pylint: disable=try-except-raise # re-raise the exception after forcing the with-block to end raise result.set_output(augmented_case.case, stdout_pipe.output(), diff --git a/src/python/grpcio_tests/tests/bazel_namespace_package_hack.py b/src/python/grpcio_tests/tests/bazel_namespace_package_hack.py new file mode 100644 index 00000000000..c6b72c327b1 --- /dev/null +++ b/src/python/grpcio_tests/tests/bazel_namespace_package_hack.py @@ -0,0 +1,32 @@ +# Copyright 2019 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. +# 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. + +import os +import site +import sys + + +# TODO(https://github.com/bazelbuild/bazel/issues/6844) Bazel failed to +# interpret namespace packages correctly. This monkey patch will force the +# Python process to parse the .pth file in the sys.path to resolve namespace +# package in the right place. +# Analysis in depth: https://github.com/bazelbuild/rules_python/issues/55 +def sys_path_to_site_dir_hack(): + """Add valid sys.path item to site directory to parse the .pth files.""" + for item in sys.path: + if os.path.exists(item): + # The only difference between sys.path and site-directory is + # whether the .pth file will be parsed or not. A site-directory + # will always exist in sys.path, but not another way around. + site.addsitedir(item) diff --git a/src/python/grpcio_tests/tests/channelz/BUILD.bazel b/src/python/grpcio_tests/tests/channelz/BUILD.bazel new file mode 100644 index 00000000000..63513616e77 --- /dev/null +++ b/src/python/grpcio_tests/tests/channelz/BUILD.bazel @@ -0,0 +1,15 @@ +package(default_visibility = ["//visibility:public"]) + +py_test( + name = "channelz_servicer_test", + srcs = ["_channelz_servicer_test.py"], + main = "_channelz_servicer_test.py", + size = "small", + deps = [ + "//src/python/grpcio/grpc:grpcio", + "//src/python/grpcio_channelz/grpc_channelz/v1:grpc_channelz", + "//src/python/grpcio_tests/tests/unit:test_common", + "//src/python/grpcio_tests/tests/unit/framework/common:common", + ], + imports = ["../../",], +) diff --git a/src/python/grpcio_tests/tests/channelz/__init__.py b/src/python/grpcio_tests/tests/channelz/__init__.py new file mode 100644 index 00000000000..38fdfc9c5cf --- /dev/null +++ b/src/python/grpcio_tests/tests/channelz/__init__.py @@ -0,0 +1,13 @@ +# Copyright 2018 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. +# 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. diff --git a/src/python/grpcio_tests/tests/channelz/_channelz_servicer_test.py b/src/python/grpcio_tests/tests/channelz/_channelz_servicer_test.py new file mode 100644 index 00000000000..5265911a0be --- /dev/null +++ b/src/python/grpcio_tests/tests/channelz/_channelz_servicer_test.py @@ -0,0 +1,468 @@ +# Copyright 2018 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. +# 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 of grpc_channelz.v1.channelz.""" + +import unittest + +from concurrent import futures + +import grpc +from grpc_channelz.v1 import channelz +from grpc_channelz.v1 import channelz_pb2 +from grpc_channelz.v1 import channelz_pb2_grpc + +from tests.unit import test_common +from tests.unit.framework.common import test_constants + +_SUCCESSFUL_UNARY_UNARY = '/test/SuccessfulUnaryUnary' +_FAILED_UNARY_UNARY = '/test/FailedUnaryUnary' +_SUCCESSFUL_STREAM_STREAM = '/test/SuccessfulStreamStream' + +_REQUEST = b'\x00\x00\x00' +_RESPONSE = b'\x01\x01\x01' + +_DISABLE_REUSE_PORT = (('grpc.so_reuseport', 0),) +_ENABLE_CHANNELZ = (('grpc.enable_channelz', 1),) +_DISABLE_CHANNELZ = (('grpc.enable_channelz', 0),) + + +def _successful_unary_unary(request, servicer_context): + return _RESPONSE + + +def _failed_unary_unary(request, servicer_context): + servicer_context.set_code(grpc.StatusCode.INTERNAL) + servicer_context.set_details("Channelz Test Intended Failure") + + +def _successful_stream_stream(request_iterator, servicer_context): + for _ in request_iterator: + yield _RESPONSE + + +class _GenericHandler(grpc.GenericRpcHandler): + + def service(self, handler_call_details): + if handler_call_details.method == _SUCCESSFUL_UNARY_UNARY: + return grpc.unary_unary_rpc_method_handler(_successful_unary_unary) + elif handler_call_details.method == _FAILED_UNARY_UNARY: + return grpc.unary_unary_rpc_method_handler(_failed_unary_unary) + elif handler_call_details.method == _SUCCESSFUL_STREAM_STREAM: + return grpc.stream_stream_rpc_method_handler( + _successful_stream_stream) + else: + return None + + +class _ChannelServerPair(object): + + def __init__(self): + # Server will enable channelz service + self.server = grpc.server( + futures.ThreadPoolExecutor(max_workers=3), + options=_DISABLE_REUSE_PORT + _ENABLE_CHANNELZ) + port = self.server.add_insecure_port('[::]:0') + self.server.add_generic_rpc_handlers((_GenericHandler(),)) + self.server.start() + + # Channel will enable channelz service... + self.channel = grpc.insecure_channel('localhost:%d' % port, + _ENABLE_CHANNELZ) + + +def _generate_channel_server_pairs(n): + return [_ChannelServerPair() for i in range(n)] + + +def _close_channel_server_pairs(pairs): + for pair in pairs: + pair.server.stop(None) + pair.channel.close() + + +class ChannelzServicerTest(unittest.TestCase): + + def _send_successful_unary_unary(self, idx): + _, r = self._pairs[idx].channel.unary_unary( + _SUCCESSFUL_UNARY_UNARY).with_call(_REQUEST) + self.assertEqual(r.code(), grpc.StatusCode.OK) + + def _send_failed_unary_unary(self, idx): + try: + self._pairs[idx].channel.unary_unary(_FAILED_UNARY_UNARY).with_call( + _REQUEST) + except grpc.RpcError: + return + else: + self.fail("This call supposed to fail") + + def _send_successful_stream_stream(self, idx): + response_iterator = self._pairs[idx].channel.stream_stream( + _SUCCESSFUL_STREAM_STREAM).__call__( + iter([_REQUEST] * test_constants.STREAM_LENGTH)) + cnt = 0 + for _ in response_iterator: + cnt += 1 + self.assertEqual(cnt, test_constants.STREAM_LENGTH) + + def _get_channel_id(self, idx): + """Channel id may not be consecutive""" + resp = self._channelz_stub.GetTopChannels( + channelz_pb2.GetTopChannelsRequest(start_channel_id=0)) + self.assertGreater(len(resp.channel), idx) + return resp.channel[idx].ref.channel_id + + def setUp(self): + self._pairs = [] + # This server is for Channelz info fetching only + # It self should not enable Channelz + self._server = grpc.server( + futures.ThreadPoolExecutor(max_workers=3), + options=_DISABLE_REUSE_PORT + _DISABLE_CHANNELZ) + port = self._server.add_insecure_port('[::]:0') + channelz.add_channelz_servicer(self._server) + self._server.start() + + # This channel is used to fetch Channelz info only + # Channelz should not be enabled + self._channel = grpc.insecure_channel('localhost:%d' % port, + _DISABLE_CHANNELZ) + self._channelz_stub = channelz_pb2_grpc.ChannelzStub(self._channel) + + def tearDown(self): + self._server.stop(None) + self._channel.close() + _close_channel_server_pairs(self._pairs) + + def test_get_top_channels_basic(self): + self._pairs = _generate_channel_server_pairs(1) + resp = self._channelz_stub.GetTopChannels( + channelz_pb2.GetTopChannelsRequest(start_channel_id=0)) + self.assertEqual(len(resp.channel), 1) + self.assertEqual(resp.end, True) + + def test_get_top_channels_high_start_id(self): + self._pairs = _generate_channel_server_pairs(1) + resp = self._channelz_stub.GetTopChannels( + channelz_pb2.GetTopChannelsRequest(start_channel_id=10000)) + self.assertEqual(len(resp.channel), 0) + self.assertEqual(resp.end, True) + + def test_successful_request(self): + self._pairs = _generate_channel_server_pairs(1) + self._send_successful_unary_unary(0) + resp = self._channelz_stub.GetChannel( + channelz_pb2.GetChannelRequest(channel_id=self._get_channel_id(0))) + self.assertEqual(resp.channel.data.calls_started, 1) + self.assertEqual(resp.channel.data.calls_succeeded, 1) + self.assertEqual(resp.channel.data.calls_failed, 0) + + def test_failed_request(self): + self._pairs = _generate_channel_server_pairs(1) + self._send_failed_unary_unary(0) + resp = self._channelz_stub.GetChannel( + channelz_pb2.GetChannelRequest(channel_id=self._get_channel_id(0))) + self.assertEqual(resp.channel.data.calls_started, 1) + self.assertEqual(resp.channel.data.calls_succeeded, 0) + self.assertEqual(resp.channel.data.calls_failed, 1) + + def test_many_requests(self): + self._pairs = _generate_channel_server_pairs(1) + k_success = 7 + k_failed = 9 + for i in range(k_success): + self._send_successful_unary_unary(0) + for i in range(k_failed): + self._send_failed_unary_unary(0) + resp = self._channelz_stub.GetChannel( + channelz_pb2.GetChannelRequest(channel_id=self._get_channel_id(0))) + self.assertEqual(resp.channel.data.calls_started, k_success + k_failed) + self.assertEqual(resp.channel.data.calls_succeeded, k_success) + self.assertEqual(resp.channel.data.calls_failed, k_failed) + + def test_many_channel(self): + k_channels = 4 + self._pairs = _generate_channel_server_pairs(k_channels) + resp = self._channelz_stub.GetTopChannels( + channelz_pb2.GetTopChannelsRequest(start_channel_id=0)) + self.assertEqual(len(resp.channel), k_channels) + + def test_many_requests_many_channel(self): + k_channels = 4 + self._pairs = _generate_channel_server_pairs(k_channels) + k_success = 11 + k_failed = 13 + for i in range(k_success): + self._send_successful_unary_unary(0) + self._send_successful_unary_unary(2) + for i in range(k_failed): + self._send_failed_unary_unary(1) + self._send_failed_unary_unary(2) + + # The first channel saw only successes + resp = self._channelz_stub.GetChannel( + channelz_pb2.GetChannelRequest(channel_id=self._get_channel_id(0))) + self.assertEqual(resp.channel.data.calls_started, k_success) + self.assertEqual(resp.channel.data.calls_succeeded, k_success) + self.assertEqual(resp.channel.data.calls_failed, 0) + + # The second channel saw only failures + resp = self._channelz_stub.GetChannel( + channelz_pb2.GetChannelRequest(channel_id=self._get_channel_id(1))) + self.assertEqual(resp.channel.data.calls_started, k_failed) + self.assertEqual(resp.channel.data.calls_succeeded, 0) + self.assertEqual(resp.channel.data.calls_failed, k_failed) + + # The third channel saw both successes and failures + resp = self._channelz_stub.GetChannel( + channelz_pb2.GetChannelRequest(channel_id=self._get_channel_id(2))) + self.assertEqual(resp.channel.data.calls_started, k_success + k_failed) + self.assertEqual(resp.channel.data.calls_succeeded, k_success) + self.assertEqual(resp.channel.data.calls_failed, k_failed) + + # The fourth channel saw nothing + resp = self._channelz_stub.GetChannel( + channelz_pb2.GetChannelRequest(channel_id=self._get_channel_id(3))) + self.assertEqual(resp.channel.data.calls_started, 0) + self.assertEqual(resp.channel.data.calls_succeeded, 0) + self.assertEqual(resp.channel.data.calls_failed, 0) + + def test_many_subchannels(self): + k_channels = 4 + self._pairs = _generate_channel_server_pairs(k_channels) + k_success = 17 + k_failed = 19 + for i in range(k_success): + self._send_successful_unary_unary(0) + self._send_successful_unary_unary(2) + for i in range(k_failed): + self._send_failed_unary_unary(1) + self._send_failed_unary_unary(2) + + gtc_resp = self._channelz_stub.GetTopChannels( + channelz_pb2.GetTopChannelsRequest(start_channel_id=0)) + self.assertEqual(len(gtc_resp.channel), k_channels) + for i in range(k_channels): + # If no call performed in the channel, there shouldn't be any subchannel + if gtc_resp.channel[i].data.calls_started == 0: + self.assertEqual(len(gtc_resp.channel[i].subchannel_ref), 0) + continue + + # Otherwise, the subchannel should exist + self.assertGreater(len(gtc_resp.channel[i].subchannel_ref), 0) + gsc_resp = self._channelz_stub.GetSubchannel( + channelz_pb2.GetSubchannelRequest( + subchannel_id=gtc_resp.channel[i].subchannel_ref[ + 0].subchannel_id)) + self.assertEqual(gtc_resp.channel[i].data.calls_started, + gsc_resp.subchannel.data.calls_started) + self.assertEqual(gtc_resp.channel[i].data.calls_succeeded, + gsc_resp.subchannel.data.calls_succeeded) + self.assertEqual(gtc_resp.channel[i].data.calls_failed, + gsc_resp.subchannel.data.calls_failed) + + def test_server_basic(self): + self._pairs = _generate_channel_server_pairs(1) + resp = self._channelz_stub.GetServers( + channelz_pb2.GetServersRequest(start_server_id=0)) + self.assertEqual(len(resp.server), 1) + + def test_get_one_server(self): + self._pairs = _generate_channel_server_pairs(1) + gss_resp = self._channelz_stub.GetServers( + channelz_pb2.GetServersRequest(start_server_id=0)) + self.assertEqual(len(gss_resp.server), 1) + gs_resp = self._channelz_stub.GetServer( + channelz_pb2.GetServerRequest( + server_id=gss_resp.server[0].ref.server_id)) + self.assertEqual(gss_resp.server[0].ref.server_id, + gs_resp.server.ref.server_id) + + def test_server_call(self): + self._pairs = _generate_channel_server_pairs(1) + k_success = 23 + k_failed = 29 + for i in range(k_success): + self._send_successful_unary_unary(0) + for i in range(k_failed): + self._send_failed_unary_unary(0) + + resp = self._channelz_stub.GetServers( + channelz_pb2.GetServersRequest(start_server_id=0)) + self.assertEqual(len(resp.server), 1) + self.assertEqual(resp.server[0].data.calls_started, + k_success + k_failed) + self.assertEqual(resp.server[0].data.calls_succeeded, k_success) + self.assertEqual(resp.server[0].data.calls_failed, k_failed) + + def test_many_subchannels_and_sockets(self): + k_channels = 4 + self._pairs = _generate_channel_server_pairs(k_channels) + k_success = 3 + k_failed = 5 + for i in range(k_success): + self._send_successful_unary_unary(0) + self._send_successful_unary_unary(2) + for i in range(k_failed): + self._send_failed_unary_unary(1) + self._send_failed_unary_unary(2) + + gtc_resp = self._channelz_stub.GetTopChannels( + channelz_pb2.GetTopChannelsRequest(start_channel_id=0)) + self.assertEqual(len(gtc_resp.channel), k_channels) + for i in range(k_channels): + # If no call performed in the channel, there shouldn't be any subchannel + if gtc_resp.channel[i].data.calls_started == 0: + self.assertEqual(len(gtc_resp.channel[i].subchannel_ref), 0) + continue + + # Otherwise, the subchannel should exist + self.assertGreater(len(gtc_resp.channel[i].subchannel_ref), 0) + gsc_resp = self._channelz_stub.GetSubchannel( + channelz_pb2.GetSubchannelRequest( + subchannel_id=gtc_resp.channel[i].subchannel_ref[ + 0].subchannel_id)) + self.assertEqual(len(gsc_resp.subchannel.socket_ref), 1) + + gs_resp = self._channelz_stub.GetSocket( + channelz_pb2.GetSocketRequest( + socket_id=gsc_resp.subchannel.socket_ref[0].socket_id)) + self.assertEqual(gsc_resp.subchannel.data.calls_started, + gs_resp.socket.data.streams_started) + self.assertEqual(gsc_resp.subchannel.data.calls_started, + gs_resp.socket.data.streams_succeeded) + # Calls started == messages sent, only valid for unary calls + self.assertEqual(gsc_resp.subchannel.data.calls_started, + gs_resp.socket.data.messages_sent) + # Only receive responses when the RPC was successful + self.assertEqual(gsc_resp.subchannel.data.calls_succeeded, + gs_resp.socket.data.messages_received) + + def test_streaming_rpc(self): + self._pairs = _generate_channel_server_pairs(1) + # In C++, the argument for _send_successful_stream_stream is message length. + # Here the argument is still channel idx, to be consistent with the other two. + self._send_successful_stream_stream(0) + + gc_resp = self._channelz_stub.GetChannel( + channelz_pb2.GetChannelRequest(channel_id=self._get_channel_id(0))) + self.assertEqual(gc_resp.channel.data.calls_started, 1) + self.assertEqual(gc_resp.channel.data.calls_succeeded, 1) + self.assertEqual(gc_resp.channel.data.calls_failed, 0) + # Subchannel exists + self.assertGreater(len(gc_resp.channel.subchannel_ref), 0) + + gsc_resp = self._channelz_stub.GetSubchannel( + channelz_pb2.GetSubchannelRequest( + subchannel_id=gc_resp.channel.subchannel_ref[0].subchannel_id)) + self.assertEqual(gsc_resp.subchannel.data.calls_started, 1) + self.assertEqual(gsc_resp.subchannel.data.calls_succeeded, 1) + self.assertEqual(gsc_resp.subchannel.data.calls_failed, 0) + # Socket exists + self.assertEqual(len(gsc_resp.subchannel.socket_ref), 1) + + gs_resp = self._channelz_stub.GetSocket( + channelz_pb2.GetSocketRequest( + socket_id=gsc_resp.subchannel.socket_ref[0].socket_id)) + self.assertEqual(gs_resp.socket.data.streams_started, 1) + self.assertEqual(gs_resp.socket.data.streams_succeeded, 1) + self.assertEqual(gs_resp.socket.data.streams_failed, 0) + self.assertEqual(gs_resp.socket.data.messages_sent, + test_constants.STREAM_LENGTH) + self.assertEqual(gs_resp.socket.data.messages_received, + test_constants.STREAM_LENGTH) + + def test_server_sockets(self): + self._pairs = _generate_channel_server_pairs(1) + self._send_successful_unary_unary(0) + self._send_failed_unary_unary(0) + + gs_resp = self._channelz_stub.GetServers( + channelz_pb2.GetServersRequest(start_server_id=0)) + self.assertEqual(len(gs_resp.server), 1) + self.assertEqual(gs_resp.server[0].data.calls_started, 2) + self.assertEqual(gs_resp.server[0].data.calls_succeeded, 1) + self.assertEqual(gs_resp.server[0].data.calls_failed, 1) + + gss_resp = self._channelz_stub.GetServerSockets( + channelz_pb2.GetServerSocketsRequest( + server_id=gs_resp.server[0].ref.server_id, start_socket_id=0)) + # If the RPC call failed, it will raise a grpc.RpcError + # So, if there is no exception raised, considered pass + + def test_server_listen_sockets(self): + self._pairs = _generate_channel_server_pairs(1) + + gss_resp = self._channelz_stub.GetServers( + channelz_pb2.GetServersRequest(start_server_id=0)) + self.assertEqual(len(gss_resp.server), 1) + self.assertEqual(len(gss_resp.server[0].listen_socket), 1) + + gs_resp = self._channelz_stub.GetSocket( + channelz_pb2.GetSocketRequest( + socket_id=gss_resp.server[0].listen_socket[0].socket_id)) + # If the RPC call failed, it will raise a grpc.RpcError + # So, if there is no exception raised, considered pass + + def test_invalid_query_get_server(self): + try: + self._channelz_stub.GetServer( + channelz_pb2.GetServerRequest(server_id=10000)) + except BaseException as e: + self.assertIn('StatusCode.NOT_FOUND', str(e)) + else: + self.fail('Invalid query not detected') + + def test_invalid_query_get_channel(self): + try: + self._channelz_stub.GetChannel( + channelz_pb2.GetChannelRequest(channel_id=10000)) + except BaseException as e: + self.assertIn('StatusCode.NOT_FOUND', str(e)) + else: + self.fail('Invalid query not detected') + + def test_invalid_query_get_subchannel(self): + try: + self._channelz_stub.GetSubchannel( + channelz_pb2.GetSubchannelRequest(subchannel_id=10000)) + except BaseException as e: + self.assertIn('StatusCode.NOT_FOUND', str(e)) + else: + self.fail('Invalid query not detected') + + def test_invalid_query_get_socket(self): + try: + self._channelz_stub.GetSocket( + channelz_pb2.GetSocketRequest(socket_id=10000)) + except BaseException as e: + self.assertIn('StatusCode.NOT_FOUND', str(e)) + else: + self.fail('Invalid query not detected') + + def test_invalid_query_get_server_sockets(self): + try: + self._channelz_stub.GetServerSockets( + channelz_pb2.GetServerSocketsRequest( + server_id=10000, + start_socket_id=0, + )) + except BaseException as e: + self.assertIn('StatusCode.NOT_FOUND', str(e)) + else: + self.fail('Invalid query not detected') + + +if __name__ == '__main__': + unittest.main(verbosity=2) diff --git a/src/python/grpcio_tests/tests/fork/_fork_interop_test.py b/src/python/grpcio_tests/tests/fork/_fork_interop_test.py new file mode 100644 index 00000000000..602786c5e0d --- /dev/null +++ b/src/python/grpcio_tests/tests/fork/_fork_interop_test.py @@ -0,0 +1,152 @@ +# Copyright 2019 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. +"""Client-side fork interop tests as a unit test.""" + +import six +import subprocess +import sys +import threading +import unittest +from grpc._cython import cygrpc +from tests.fork import methods + +# New instance of multiprocessing.Process using fork without exec can and will +# hang if the Python process has any other threads running. This includes the +# additional thread spawned by our _runner.py class. So in order to test our +# compatibility with multiprocessing, we first fork+exec a new process to ensure +# we don't have any conflicting background threads. +_CLIENT_FORK_SCRIPT_TEMPLATE = """if True: + import os + import sys + from grpc._cython import cygrpc + from tests.fork import methods + + cygrpc._GRPC_ENABLE_FORK_SUPPORT = True + os.environ['GRPC_POLL_STRATEGY'] = 'epoll1' + methods.TestCase.%s.run_test({ + 'server_host': 'localhost', + 'server_port': %d, + 'use_tls': False + }) +""" +_SUBPROCESS_TIMEOUT_S = 30 + + +@unittest.skipUnless( + sys.platform.startswith("linux"), + "not supported on windows, and fork+exec networking blocked on mac") +@unittest.skipUnless(six.PY2, "https://github.com/grpc/grpc/issues/18075") +class ForkInteropTest(unittest.TestCase): + + def setUp(self): + start_server_script = """if True: + import sys + import time + + import grpc + from src.proto.grpc.testing import test_pb2_grpc + from tests.interop import service as interop_service + from tests.unit import test_common + + server = test_common.test_server() + test_pb2_grpc.add_TestServiceServicer_to_server( + interop_service.TestService(), server) + port = server.add_insecure_port('[::]:0') + server.start() + print(port) + sys.stdout.flush() + while True: + time.sleep(1) + """ + self._server_process = subprocess.Popen( + [sys.executable, '-c', start_server_script], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + timer = threading.Timer(_SUBPROCESS_TIMEOUT_S, + self._server_process.kill) + try: + timer.start() + self._port = int(self._server_process.stdout.readline()) + except ValueError: + raise Exception('Failed to get port from server') + finally: + timer.cancel() + + def testConnectivityWatch(self): + self._verifyTestCase(methods.TestCase.CONNECTIVITY_WATCH) + + def testCloseChannelBeforeFork(self): + self._verifyTestCase(methods.TestCase.CLOSE_CHANNEL_BEFORE_FORK) + + def testAsyncUnarySameChannel(self): + self._verifyTestCase(methods.TestCase.ASYNC_UNARY_SAME_CHANNEL) + + def testAsyncUnaryNewChannel(self): + self._verifyTestCase(methods.TestCase.ASYNC_UNARY_NEW_CHANNEL) + + def testBlockingUnarySameChannel(self): + self._verifyTestCase(methods.TestCase.BLOCKING_UNARY_SAME_CHANNEL) + + def testBlockingUnaryNewChannel(self): + self._verifyTestCase(methods.TestCase.BLOCKING_UNARY_NEW_CHANNEL) + + def testInProgressBidiContinueCall(self): + self._verifyTestCase(methods.TestCase.IN_PROGRESS_BIDI_CONTINUE_CALL) + + def testInProgressBidiSameChannelAsyncCall(self): + self._verifyTestCase( + methods.TestCase.IN_PROGRESS_BIDI_SAME_CHANNEL_ASYNC_CALL) + + def testInProgressBidiSameChannelBlockingCall(self): + self._verifyTestCase( + methods.TestCase.IN_PROGRESS_BIDI_SAME_CHANNEL_BLOCKING_CALL) + + def testInProgressBidiNewChannelAsyncCall(self): + self._verifyTestCase( + methods.TestCase.IN_PROGRESS_BIDI_NEW_CHANNEL_ASYNC_CALL) + + def testInProgressBidiNewChannelBlockingCall(self): + self._verifyTestCase( + methods.TestCase.IN_PROGRESS_BIDI_NEW_CHANNEL_BLOCKING_CALL) + + def tearDown(self): + self._server_process.kill() + + def _verifyTestCase(self, test_case): + script = _CLIENT_FORK_SCRIPT_TEMPLATE % (test_case.name, self._port) + process = subprocess.Popen( + [sys.executable, '-c', script], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + timer = threading.Timer(_SUBPROCESS_TIMEOUT_S, process.kill) + try: + timer.start() + try: + out, err = process.communicate(timeout=_SUBPROCESS_TIMEOUT_S) + except TypeError: + # The timeout parameter was added in Python 3.3. + out, err = process.communicate() + except subprocess.TimeoutExpired: + process.kill() + raise RuntimeError('Process failed to terminate') + finally: + timer.cancel() + self.assertEqual( + 0, process.returncode, + 'process failed with exit code %d (stdout: %s, stderr: %s)' % + (process.returncode, out, err)) + + +if __name__ == '__main__': + unittest.main(verbosity=2) diff --git a/src/python/grpcio_tests/tests/fork/client.py b/src/python/grpcio_tests/tests/fork/client.py index 9a32629ed5a..94a20b33714 100644 --- a/src/python/grpcio_tests/tests/fork/client.py +++ b/src/python/grpcio_tests/tests/fork/client.py @@ -63,12 +63,12 @@ def _test_case_from_arg(test_case_arg): def test_fork(): logging.basicConfig(level=logging.INFO) - args = _args() - if args.test_case == "all": + args = vars(_args()) + if args['test_case'] == "all": for test_case in methods.TestCase: test_case.run_test(args) else: - test_case = _test_case_from_arg(args.test_case) + test_case = _test_case_from_arg(args['test_case']) test_case.run_test(args) diff --git a/src/python/grpcio_tests/tests/fork/methods.py b/src/python/grpcio_tests/tests/fork/methods.py index 889ef13cb28..a060ba6e581 100644 --- a/src/python/grpcio_tests/tests/fork/methods.py +++ b/src/python/grpcio_tests/tests/fork/methods.py @@ -30,11 +30,13 @@ from src.proto.grpc.testing import messages_pb2 from src.proto.grpc.testing import test_pb2_grpc _LOGGER = logging.getLogger(__name__) +_RPC_TIMEOUT_S = 10 +_CHILD_FINISH_TIMEOUT_S = 60 def _channel(args): - target = '{}:{}'.format(args.server_host, args.server_port) - if args.use_tls: + target = '{}:{}'.format(args['server_host'], args['server_port']) + if args['use_tls']: channel_credentials = grpc.ssl_channel_credentials() channel = grpc.secure_channel(target, channel_credentials) else: @@ -57,7 +59,7 @@ def _async_unary(stub): response_type=messages_pb2.COMPRESSABLE, response_size=size, payload=messages_pb2.Payload(body=b'\x00' * 271828)) - response_future = stub.UnaryCall.future(request) + response_future = stub.UnaryCall.future(request, timeout=_RPC_TIMEOUT_S) response = response_future.result() _validate_payload_type_and_length(response, messages_pb2.COMPRESSABLE, size) @@ -68,7 +70,7 @@ def _blocking_unary(stub): response_type=messages_pb2.COMPRESSABLE, response_size=size, payload=messages_pb2.Payload(body=b'\x00' * 271828)) - response = stub.UnaryCall(request) + response = stub.UnaryCall(request, timeout=_RPC_TIMEOUT_S) _validate_payload_type_and_length(response, messages_pb2.COMPRESSABLE, size) @@ -121,6 +123,8 @@ class _ChildProcess(object): def record_exceptions(): try: task(*args) + except grpc.RpcError as rpc_error: + self._exceptions.put('RpcError: %s' % rpc_error) except Exception as e: # pylint: disable=broad-except self._exceptions.put(e) @@ -130,7 +134,9 @@ class _ChildProcess(object): self._process.start() def finish(self): - self._process.join() + self._process.join(timeout=_CHILD_FINISH_TIMEOUT_S) + if self._process.is_alive(): + raise RuntimeError('Child process did not terminate') if self._process.exitcode != 0: raise ValueError('Child process failed with exitcode %d' % self._process.exitcode) @@ -162,10 +168,10 @@ def _async_unary_same_channel(channel): def _async_unary_new_channel(channel, args): def child_target(): - child_channel = _channel(args) - child_stub = test_pb2_grpc.TestServiceStub(child_channel) - _async_unary(child_stub) - child_channel.close() + with _channel(args) as child_channel: + child_stub = test_pb2_grpc.TestServiceStub(child_channel) + _async_unary(child_stub) + child_channel.close() stub = test_pb2_grpc.TestServiceStub(channel) _async_unary(stub) @@ -195,10 +201,9 @@ def _blocking_unary_same_channel(channel): def _blocking_unary_new_channel(channel, args): def child_target(): - child_channel = _channel(args) - child_stub = test_pb2_grpc.TestServiceStub(child_channel) - _blocking_unary(child_stub) - child_channel.close() + with _channel(args) as child_channel: + child_stub = test_pb2_grpc.TestServiceStub(child_channel) + _blocking_unary(child_stub) stub = test_pb2_grpc.TestServiceStub(channel) _blocking_unary(stub) @@ -213,63 +218,62 @@ def _close_channel_before_fork(channel, args): def child_target(): new_channel.close() - child_channel = _channel(args) - child_stub = test_pb2_grpc.TestServiceStub(child_channel) - _blocking_unary(child_stub) - child_channel.close() + with _channel(args) as child_channel: + child_stub = test_pb2_grpc.TestServiceStub(child_channel) + _blocking_unary(child_stub) stub = test_pb2_grpc.TestServiceStub(channel) _blocking_unary(stub) channel.close() - new_channel = _channel(args) - new_stub = test_pb2_grpc.TestServiceStub(new_channel) - child_process = _ChildProcess(child_target) - child_process.start() - _blocking_unary(new_stub) - child_process.finish() + with _channel(args) as new_channel: + new_stub = test_pb2_grpc.TestServiceStub(new_channel) + child_process = _ChildProcess(child_target) + child_process.start() + _blocking_unary(new_stub) + child_process.finish() def _connectivity_watch(channel, args): + parent_states = [] + parent_channel_ready_event = threading.Event() + def child_target(): - def child_connectivity_callback(state): - child_states.append(state) + child_channel_ready_event = threading.Event() - child_states = [] - child_channel = _channel(args) - child_stub = test_pb2_grpc.TestServiceStub(child_channel) - child_channel.subscribe(child_connectivity_callback) - _async_unary(child_stub) - if len(child_states - ) < 2 or child_states[-1] != grpc.ChannelConnectivity.READY: - raise ValueError('Channel did not move to READY') - if len(parent_states) > 1: - raise ValueError('Received connectivity updates on parent callback') - child_channel.unsubscribe(child_connectivity_callback) - child_channel.close() + def child_connectivity_callback(state): + if state is grpc.ChannelConnectivity.READY: + child_channel_ready_event.set() + + with _channel(args) as child_channel: + child_stub = test_pb2_grpc.TestServiceStub(child_channel) + child_channel.subscribe(child_connectivity_callback) + _async_unary(child_stub) + if not child_channel_ready_event.wait(timeout=_RPC_TIMEOUT_S): + raise ValueError('Channel did not move to READY') + if len(parent_states) > 1: + raise ValueError( + 'Received connectivity updates on parent callback', + parent_states) + child_channel.unsubscribe(child_connectivity_callback) def parent_connectivity_callback(state): parent_states.append(state) + if state is grpc.ChannelConnectivity.READY: + parent_channel_ready_event.set() - parent_states = [] channel.subscribe(parent_connectivity_callback) stub = test_pb2_grpc.TestServiceStub(channel) child_process = _ChildProcess(child_target) child_process.start() _async_unary(stub) - if len(parent_states - ) < 2 or parent_states[-1] != grpc.ChannelConnectivity.READY: + if not parent_channel_ready_event.wait(timeout=_RPC_TIMEOUT_S): raise ValueError('Channel did not move to READY') channel.unsubscribe(parent_connectivity_callback) child_process.finish() - # Need to unsubscribe or _channel.py in _poll_connectivity triggers a - # "Cannot invoke RPC on closed channel!" error. - # TODO(ericgribkoff) Fix issue with channel.close() and connectivity polling - channel.unsubscribe(parent_connectivity_callback) - def _ping_pong_with_child_processes_after_first_response( channel, args, child_target, run_after_close=True): @@ -380,9 +384,9 @@ def _in_progress_bidi_same_channel_blocking_call(channel): def _in_progress_bidi_new_channel_async_call(channel, args): def child_target(parent_bidi_call, parent_channel, args): - channel = _channel(args) - stub = test_pb2_grpc.TestServiceStub(channel) - _async_unary(stub) + with _channel(args) as channel: + stub = test_pb2_grpc.TestServiceStub(channel) + _async_unary(stub) _ping_pong_with_child_processes_after_first_response( channel, args, child_target) @@ -391,9 +395,9 @@ def _in_progress_bidi_new_channel_async_call(channel, args): def _in_progress_bidi_new_channel_blocking_call(channel, args): def child_target(parent_bidi_call, parent_channel, args): - channel = _channel(args) - stub = test_pb2_grpc.TestServiceStub(channel) - _blocking_unary(stub) + with _channel(args) as channel: + stub = test_pb2_grpc.TestServiceStub(channel) + _blocking_unary(stub) _ping_pong_with_child_processes_after_first_response( channel, args, child_target) diff --git a/src/python/grpcio_tests/tests/health_check/BUILD.bazel b/src/python/grpcio_tests/tests/health_check/BUILD.bazel index 19e1e1b2e1e..49f076be9a1 100644 --- a/src/python/grpcio_tests/tests/health_check/BUILD.bazel +++ b/src/python/grpcio_tests/tests/health_check/BUILD.bazel @@ -9,6 +9,8 @@ py_test( "//src/python/grpcio/grpc:grpcio", "//src/python/grpcio_health_checking/grpc_health/v1:grpc_health", "//src/python/grpcio_tests/tests/unit:test_common", + "//src/python/grpcio_tests/tests/unit:thread_pool", + "//src/python/grpcio_tests/tests/unit/framework/common:common", ], imports = ["../../",], ) diff --git a/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py b/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py index 350b5eebe5b..7a332b8390f 100644 --- a/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py +++ b/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py @@ -13,6 +13,8 @@ # limitations under the License. """Tests of grpc_health.v1.health.""" +import threading +import time import unittest import grpc @@ -21,52 +23,241 @@ from grpc_health.v1 import health_pb2 from grpc_health.v1 import health_pb2_grpc from tests.unit import test_common +from tests.unit import thread_pool +from tests.unit.framework.common import test_constants + +from six.moves import queue + +_SERVING_SERVICE = 'grpc.test.TestServiceServing' +_UNKNOWN_SERVICE = 'grpc.test.TestServiceUnknown' +_NOT_SERVING_SERVICE = 'grpc.test.TestServiceNotServing' +_WATCH_SERVICE = 'grpc.test.WatchService' -class HealthServicerTest(unittest.TestCase): +def _consume_responses(response_iterator, response_queue): + for response in response_iterator: + response_queue.put(response) + + +class BaseWatchTests(object): + + class WatchTests(unittest.TestCase): + + def start_server(self, non_blocking=False, thread_pool=None): + self._thread_pool = thread_pool + self._servicer = health.HealthServicer( + experimental_non_blocking=non_blocking, + experimental_thread_pool=thread_pool) + self._servicer.set('', health_pb2.HealthCheckResponse.SERVING) + self._servicer.set(_SERVING_SERVICE, + health_pb2.HealthCheckResponse.SERVING) + self._servicer.set(_UNKNOWN_SERVICE, + health_pb2.HealthCheckResponse.UNKNOWN) + self._servicer.set(_NOT_SERVING_SERVICE, + health_pb2.HealthCheckResponse.NOT_SERVING) + self._server = test_common.test_server() + port = self._server.add_insecure_port('[::]:0') + health_pb2_grpc.add_HealthServicer_to_server( + self._servicer, self._server) + self._server.start() + + self._channel = grpc.insecure_channel('localhost:%d' % port) + self._stub = health_pb2_grpc.HealthStub(self._channel) + + def tearDown(self): + self._server.stop(None) + self._channel.close() + + def test_watch_empty_service(self): + request = health_pb2.HealthCheckRequest(service='') + response_queue = queue.Queue() + rendezvous = self._stub.Watch(request) + thread = threading.Thread( + target=_consume_responses, args=(rendezvous, response_queue)) + thread.start() + + response = response_queue.get(timeout=test_constants.SHORT_TIMEOUT) + self.assertEqual(health_pb2.HealthCheckResponse.SERVING, + response.status) + + rendezvous.cancel() + thread.join() + self.assertTrue(response_queue.empty()) + + if self._thread_pool is not None: + self.assertTrue(self._thread_pool.was_used()) + + def test_watch_new_service(self): + request = health_pb2.HealthCheckRequest(service=_WATCH_SERVICE) + response_queue = queue.Queue() + rendezvous = self._stub.Watch(request) + thread = threading.Thread( + target=_consume_responses, args=(rendezvous, response_queue)) + thread.start() + + response = response_queue.get(timeout=test_constants.SHORT_TIMEOUT) + self.assertEqual(health_pb2.HealthCheckResponse.SERVICE_UNKNOWN, + response.status) + + self._servicer.set(_WATCH_SERVICE, + health_pb2.HealthCheckResponse.SERVING) + response = response_queue.get(timeout=test_constants.SHORT_TIMEOUT) + self.assertEqual(health_pb2.HealthCheckResponse.SERVING, + response.status) + + self._servicer.set(_WATCH_SERVICE, + health_pb2.HealthCheckResponse.NOT_SERVING) + response = response_queue.get(timeout=test_constants.SHORT_TIMEOUT) + self.assertEqual(health_pb2.HealthCheckResponse.NOT_SERVING, + response.status) + + rendezvous.cancel() + thread.join() + self.assertTrue(response_queue.empty()) + + def test_watch_service_isolation(self): + request = health_pb2.HealthCheckRequest(service=_WATCH_SERVICE) + response_queue = queue.Queue() + rendezvous = self._stub.Watch(request) + thread = threading.Thread( + target=_consume_responses, args=(rendezvous, response_queue)) + thread.start() + + response = response_queue.get(timeout=test_constants.SHORT_TIMEOUT) + self.assertEqual(health_pb2.HealthCheckResponse.SERVICE_UNKNOWN, + response.status) + + self._servicer.set('some-other-service', + health_pb2.HealthCheckResponse.SERVING) + with self.assertRaises(queue.Empty): + response_queue.get(timeout=test_constants.SHORT_TIMEOUT) + + rendezvous.cancel() + thread.join() + self.assertTrue(response_queue.empty()) + + def test_two_watchers(self): + request = health_pb2.HealthCheckRequest(service=_WATCH_SERVICE) + response_queue1 = queue.Queue() + response_queue2 = queue.Queue() + rendezvous1 = self._stub.Watch(request) + rendezvous2 = self._stub.Watch(request) + thread1 = threading.Thread( + target=_consume_responses, args=(rendezvous1, response_queue1)) + thread2 = threading.Thread( + target=_consume_responses, args=(rendezvous2, response_queue2)) + thread1.start() + thread2.start() + + response1 = response_queue1.get( + timeout=test_constants.SHORT_TIMEOUT) + response2 = response_queue2.get( + timeout=test_constants.SHORT_TIMEOUT) + self.assertEqual(health_pb2.HealthCheckResponse.SERVICE_UNKNOWN, + response1.status) + self.assertEqual(health_pb2.HealthCheckResponse.SERVICE_UNKNOWN, + response2.status) + + self._servicer.set(_WATCH_SERVICE, + health_pb2.HealthCheckResponse.SERVING) + response1 = response_queue1.get( + timeout=test_constants.SHORT_TIMEOUT) + response2 = response_queue2.get( + timeout=test_constants.SHORT_TIMEOUT) + self.assertEqual(health_pb2.HealthCheckResponse.SERVING, + response1.status) + self.assertEqual(health_pb2.HealthCheckResponse.SERVING, + response2.status) + + rendezvous1.cancel() + rendezvous2.cancel() + thread1.join() + thread2.join() + self.assertTrue(response_queue1.empty()) + self.assertTrue(response_queue2.empty()) + + @unittest.skip("https://github.com/grpc/grpc/issues/18127") + def test_cancelled_watch_removed_from_watch_list(self): + request = health_pb2.HealthCheckRequest(service=_WATCH_SERVICE) + response_queue = queue.Queue() + rendezvous = self._stub.Watch(request) + thread = threading.Thread( + target=_consume_responses, args=(rendezvous, response_queue)) + thread.start() + + response = response_queue.get(timeout=test_constants.SHORT_TIMEOUT) + self.assertEqual(health_pb2.HealthCheckResponse.SERVICE_UNKNOWN, + response.status) + + rendezvous.cancel() + self._servicer.set(_WATCH_SERVICE, + health_pb2.HealthCheckResponse.SERVING) + thread.join() + + # Wait, if necessary, for serving thread to process client cancellation + timeout = time.time() + test_constants.TIME_ALLOWANCE + while time.time( + ) < timeout and self._servicer._send_response_callbacks[_WATCH_SERVICE]: + time.sleep(1) + self.assertFalse( + self._servicer._send_response_callbacks[_WATCH_SERVICE], + 'watch set should be empty') + self.assertTrue(response_queue.empty()) + + def test_graceful_shutdown(self): + request = health_pb2.HealthCheckRequest(service='') + response_queue = queue.Queue() + rendezvous = self._stub.Watch(request) + thread = threading.Thread( + target=_consume_responses, args=(rendezvous, response_queue)) + thread.start() + + response = response_queue.get(timeout=test_constants.SHORT_TIMEOUT) + self.assertEqual(health_pb2.HealthCheckResponse.SERVING, + response.status) + + self._servicer.enter_graceful_shutdown() + response = response_queue.get(timeout=test_constants.SHORT_TIMEOUT) + self.assertEqual(health_pb2.HealthCheckResponse.NOT_SERVING, + response.status) + + # This should be a no-op. + self._servicer.set('', health_pb2.HealthCheckResponse.SERVING) + + rendezvous.cancel() + thread.join() + self.assertTrue(response_queue.empty()) + + +class HealthServicerTest(BaseWatchTests.WatchTests): def setUp(self): - servicer = health.HealthServicer() - servicer.set('', health_pb2.HealthCheckResponse.SERVING) - servicer.set('grpc.test.TestServiceServing', - health_pb2.HealthCheckResponse.SERVING) - servicer.set('grpc.test.TestServiceUnknown', - health_pb2.HealthCheckResponse.UNKNOWN) - servicer.set('grpc.test.TestServiceNotServing', - health_pb2.HealthCheckResponse.NOT_SERVING) - self._server = test_common.test_server() - port = self._server.add_insecure_port('[::]:0') - health_pb2_grpc.add_HealthServicer_to_server(servicer, self._server) - self._server.start() + self._thread_pool = thread_pool.RecordingThreadPool(max_workers=None) + super(HealthServicerTest, self).start_server( + non_blocking=True, thread_pool=self._thread_pool) - channel = grpc.insecure_channel('localhost:%d' % port) - self._stub = health_pb2_grpc.HealthStub(channel) - - def test_empty_service(self): + def test_check_empty_service(self): request = health_pb2.HealthCheckRequest() resp = self._stub.Check(request) self.assertEqual(health_pb2.HealthCheckResponse.SERVING, resp.status) - def test_serving_service(self): - request = health_pb2.HealthCheckRequest( - service='grpc.test.TestServiceServing') + def test_check_serving_service(self): + request = health_pb2.HealthCheckRequest(service=_SERVING_SERVICE) resp = self._stub.Check(request) self.assertEqual(health_pb2.HealthCheckResponse.SERVING, resp.status) - def test_unknown_serivce(self): - request = health_pb2.HealthCheckRequest( - service='grpc.test.TestServiceUnknown') + def test_check_unknown_service(self): + request = health_pb2.HealthCheckRequest(service=_UNKNOWN_SERVICE) resp = self._stub.Check(request) self.assertEqual(health_pb2.HealthCheckResponse.UNKNOWN, resp.status) - def test_not_serving_service(self): - request = health_pb2.HealthCheckRequest( - service='grpc.test.TestServiceNotServing') + def test_check_not_serving_service(self): + request = health_pb2.HealthCheckRequest(service=_NOT_SERVING_SERVICE) resp = self._stub.Check(request) self.assertEqual(health_pb2.HealthCheckResponse.NOT_SERVING, resp.status) - def test_not_found_service(self): + def test_check_not_found_service(self): request = health_pb2.HealthCheckRequest(service='not-found') with self.assertRaises(grpc.RpcError) as context: resp = self._stub.Check(request) @@ -77,5 +268,12 @@ class HealthServicerTest(unittest.TestCase): self.assertEqual(health.SERVICE_NAME, 'grpc.health.v1.Health') +class HealthServicerBackwardsCompatibleWatchTest(BaseWatchTests.WatchTests): + + def setUp(self): + super(HealthServicerBackwardsCompatibleWatchTest, self).start_server( + non_blocking=False, thread_pool=None) + + if __name__ == '__main__': unittest.main(verbosity=2) diff --git a/src/python/grpcio_tests/tests/interop/BUILD.bazel b/src/python/grpcio_tests/tests/interop/BUILD.bazel index aebdbf67ebf..fd636556074 100644 --- a/src/python/grpcio_tests/tests/interop/BUILD.bazel +++ b/src/python/grpcio_tests/tests/interop/BUILD.bazel @@ -5,42 +5,45 @@ package(default_visibility = ["//visibility:public"]) py_library( name = "_intraop_test_case", srcs = ["_intraop_test_case.py"], + imports = ["../../"], deps = [ ":methods", ], - imports=["../../",], ) py_library( name = "client", srcs = ["client.py"], + imports = ["../../"], deps = [ - "//src/python/grpcio/grpc:grpcio", ":methods", ":resources", "//src/proto/grpc/testing:py_test_proto", - requirement('google-auth'), + "//src/python/grpcio/grpc:grpcio", + requirement("google-auth"), ], - imports=["../../",], ) py_library( name = "methods", srcs = ["methods.py"], + imports = ["../../"], deps = [ "//src/python/grpcio/grpc:grpcio", + "//src/python/grpcio_tests/tests:bazel_namespace_package_hack", "//src/proto/grpc/testing:py_empty_proto", "//src/proto/grpc/testing:py_messages_proto", "//src/proto/grpc/testing:py_test_proto", - requirement('google-auth'), - requirement('requests'), - requirement('enum34'), - requirement('urllib3'), - requirement('chardet'), - requirement('certifi'), - requirement('idna'), - ], - imports=["../../",], + requirement("google-auth"), + requirement("requests"), + requirement("urllib3"), + requirement("chardet"), + requirement("certifi"), + requirement("idna"), + ] + select({ + "//conditions:default": [requirement("enum34")], + "//:python3": [], + }), ) py_library( @@ -51,51 +54,62 @@ py_library( ], ) +py_library( + name = "service", + srcs = ["service.py"], + imports = ["../../"], + deps = [ + "//src/proto/grpc/testing:py_empty_proto", + "//src/proto/grpc/testing:py_messages_proto", + "//src/proto/grpc/testing:py_test_proto", + "//src/python/grpcio/grpc:grpcio", + ], +) + py_library( name = "server", srcs = ["server.py"], + imports = ["../../"], deps = [ - "//src/python/grpcio/grpc:grpcio", - ":methods", ":resources", - "//src/python/grpcio_tests/tests/unit:test_common", + ":service", "//src/proto/grpc/testing:py_test_proto", + "//src/python/grpcio/grpc:grpcio", + "//src/python/grpcio_tests/tests/unit:test_common", ], - imports=["../../",], ) py_test( - name="_insecure_intraop_test", - size="small", - srcs=["_insecure_intraop_test.py",], - main="_insecure_intraop_test.py", - deps=[ - "//src/python/grpcio/grpc:grpcio", - ":_intraop_test_case", - ":methods", - ":server", - "//src/python/grpcio_tests/tests/unit:test_common", - "//src/proto/grpc/testing:py_test_proto", - ], - imports=["../../",], - data=[ + name = "_insecure_intraop_test", + size = "small", + srcs = ["_insecure_intraop_test.py"], + data = [ "//src/python/grpcio_tests/tests/unit/credentials", ], + imports = ["../../"], + main = "_insecure_intraop_test.py", + deps = [ + ":_intraop_test_case", + ":server", + ":service", + "//src/proto/grpc/testing:py_test_proto", + "//src/python/grpcio/grpc:grpcio", + "//src/python/grpcio_tests/tests/unit:test_common", + ], ) py_test( - name="_secure_intraop_test", - size="small", - srcs=["_secure_intraop_test.py",], - main="_secure_intraop_test.py", - deps=[ - "//src/python/grpcio/grpc:grpcio", + name = "_secure_intraop_test", + size = "small", + srcs = ["_secure_intraop_test.py"], + imports = ["../../"], + main = "_secure_intraop_test.py", + deps = [ ":_intraop_test_case", - ":methods", ":server", - "//src/python/grpcio_tests/tests/unit:test_common", + ":service", "//src/proto/grpc/testing:py_test_proto", + "//src/python/grpcio/grpc:grpcio", + "//src/python/grpcio_tests/tests/unit:test_common", ], - imports=["../../",], ) - 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 ace15bea585..fecf31767a7 100644 --- a/src/python/grpcio_tests/tests/interop/_insecure_intraop_test.py +++ b/src/python/grpcio_tests/tests/interop/_insecure_intraop_test.py @@ -19,7 +19,7 @@ import grpc from src.proto.grpc.testing import test_pb2_grpc from tests.interop import _intraop_test_case -from tests.interop import methods +from tests.interop import service from tests.interop import server from tests.unit import test_common @@ -29,7 +29,7 @@ class InsecureIntraopTest(_intraop_test_case.IntraopTestCase, def setUp(self): self.server = test_common.test_server() - test_pb2_grpc.add_TestServiceServicer_to_server(methods.TestService(), + test_pb2_grpc.add_TestServiceServicer_to_server(service.TestService(), self.server) port = self.server.add_insecure_port('[::]:0') self.server.start() 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 e27e551ecb0..1b5e5cfd2dd 100644 --- a/src/python/grpcio_tests/tests/interop/_secure_intraop_test.py +++ b/src/python/grpcio_tests/tests/interop/_secure_intraop_test.py @@ -19,7 +19,7 @@ import grpc from src.proto.grpc.testing import test_pb2_grpc from tests.interop import _intraop_test_case -from tests.interop import methods +from tests.interop import service from tests.interop import resources from tests.unit import test_common @@ -30,7 +30,7 @@ class SecureIntraopTest(_intraop_test_case.IntraopTestCase, unittest.TestCase): def setUp(self): self.server = test_common.test_server() - test_pb2_grpc.add_TestServiceServicer_to_server(methods.TestService(), + test_pb2_grpc.add_TestServiceServicer_to_server(service.TestService(), self.server) port = self.server.add_secure_port( '[::]:0', diff --git a/src/python/grpcio_tests/tests/interop/client.py b/src/python/grpcio_tests/tests/interop/client.py index 698c37017f5..56cb29477c8 100644 --- a/src/python/grpcio_tests/tests/interop/client.py +++ b/src/python/grpcio_tests/tests/interop/client.py @@ -54,7 +54,6 @@ def _args(): help='replace platform root CAs with ca.pem') parser.add_argument( '--server_host_override', - default="foo.test.google.fr", type=str, help='the server host to which to claim to connect') parser.add_argument( @@ -100,10 +99,13 @@ def _stub(args): channel_credentials = grpc.composite_channel_credentials( channel_credentials, call_credentials) - channel = grpc.secure_channel(target, channel_credentials, (( - 'grpc.ssl_target_name_override', - args.server_host_override, - ),)) + channel_opts = None + if args.server_host_override: + channel_opts = (( + 'grpc.ssl_target_name_override', + args.server_host_override, + ),) + channel = grpc.secure_channel(target, channel_credentials, channel_opts) else: channel = grpc.insecure_channel(target) if args.test_case == "unimplemented_service": diff --git a/src/python/grpcio_tests/tests/interop/methods.py b/src/python/grpcio_tests/tests/interop/methods.py index 721dedf0b75..250db8bb385 100644 --- a/src/python/grpcio_tests/tests/interop/methods.py +++ b/src/python/grpcio_tests/tests/interop/methods.py @@ -13,92 +13,33 @@ # limitations under the License. """Implementations of interoperability test methods.""" +# NOTE(lidiz) This module only exists in Bazel BUILD file, for more details +# please refer to comments in the "bazel_namespace_package_hack" module. +try: + from tests import bazel_namespace_package_hack + bazel_namespace_package_hack.sys_path_to_site_dir_hack() +except ImportError: + pass + import enum import json import os import threading +import time from google import auth as google_auth from google.auth import environment_vars as google_auth_environment_vars from google.auth.transport import grpc as google_auth_transport_grpc from google.auth.transport import requests as google_auth_transport_requests import grpc -from grpc.beta import implementations from src.proto.grpc.testing import empty_pb2 from src.proto.grpc.testing import messages_pb2 -from src.proto.grpc.testing import test_pb2_grpc _INITIAL_METADATA_KEY = "x-grpc-test-echo-initial" _TRAILING_METADATA_KEY = "x-grpc-test-echo-trailing-bin" -def _maybe_echo_metadata(servicer_context): - """Copies metadata from request to response if it is present.""" - invocation_metadata = dict(servicer_context.invocation_metadata()) - if _INITIAL_METADATA_KEY in invocation_metadata: - initial_metadatum = (_INITIAL_METADATA_KEY, - invocation_metadata[_INITIAL_METADATA_KEY]) - servicer_context.send_initial_metadata((initial_metadatum,)) - if _TRAILING_METADATA_KEY in invocation_metadata: - trailing_metadatum = (_TRAILING_METADATA_KEY, - invocation_metadata[_TRAILING_METADATA_KEY]) - servicer_context.set_trailing_metadata((trailing_metadatum,)) - - -def _maybe_echo_status_and_message(request, servicer_context): - """Sets the response context code and details if the request asks for them""" - if request.HasField('response_status'): - servicer_context.set_code(request.response_status.code) - servicer_context.set_details(request.response_status.message) - - -class TestService(test_pb2_grpc.TestServiceServicer): - - def EmptyCall(self, request, context): - _maybe_echo_metadata(context) - return empty_pb2.Empty() - - def UnaryCall(self, request, context): - _maybe_echo_metadata(context) - _maybe_echo_status_and_message(request, context) - return messages_pb2.SimpleResponse( - payload=messages_pb2.Payload( - type=messages_pb2.COMPRESSABLE, - body=b'\x00' * request.response_size)) - - def StreamingOutputCall(self, request, context): - _maybe_echo_status_and_message(request, context) - for response_parameters in request.response_parameters: - yield messages_pb2.StreamingOutputCallResponse( - payload=messages_pb2.Payload( - type=request.response_type, - body=b'\x00' * response_parameters.size)) - - def StreamingInputCall(self, request_iterator, context): - aggregate_size = 0 - for request in request_iterator: - if request.payload is not None and request.payload.body: - aggregate_size += len(request.payload.body) - return messages_pb2.StreamingInputCallResponse( - aggregated_payload_size=aggregate_size) - - def FullDuplexCall(self, request_iterator, context): - _maybe_echo_metadata(context) - for request in request_iterator: - _maybe_echo_status_and_message(request, context) - for response_parameters in request.response_parameters: - yield messages_pb2.StreamingOutputCallResponse( - payload=messages_pb2.Payload( - type=request.payload.type, - body=b'\x00' * response_parameters.size)) - - # NOTE(nathaniel): Apparently this is the same as the full-duplex call? - # NOTE(atash): It isn't even called in the interop spec (Oct 22 2015)... - def HalfDuplexCall(self, request_iterator, context): - return self.FullDuplexCall(request_iterator, context) - - def _expect_status_code(call, expected_code): if call.code() != expected_code: raise ValueError('expected code %s, got %s' % (expected_code, @@ -377,7 +318,7 @@ def _unimplemented_service(unimplemented_service_stub): def _custom_metadata(stub): initial_metadata_value = "test_initial_metadata_value" - trailing_metadata_value = "\x0a\x0b\x0a\x0b\x0a\x0b" + trailing_metadata_value = b"\x0a\x0b\x0a\x0b\x0a\x0b" metadata = ((_INITIAL_METADATA_KEY, initial_metadata_value), (_TRAILING_METADATA_KEY, trailing_metadata_value)) @@ -391,7 +332,7 @@ def _custom_metadata(stub): if trailing_metadata[_TRAILING_METADATA_KEY] != trailing_metadata_value: raise ValueError('expected trailing metadata %s, got %s' % (trailing_metadata_value, - initial_metadata[_TRAILING_METADATA_KEY])) + trailing_metadata[_TRAILING_METADATA_KEY])) # Testing with UnaryCall request = messages_pb2.SimpleRequest( @@ -422,7 +363,7 @@ def _compute_engine_creds(stub, args): def _oauth2_auth_token(stub, args): json_key_filename = os.environ[google_auth_environment_vars.CREDENTIALS] - wanted_email = json.load(open(json_key_filename, 'rb'))['client_email'] + wanted_email = json.load(open(json_key_filename, 'r'))['client_email'] response = _large_unary_common_behavior(stub, True, True, None) if wanted_email != response.username: raise ValueError('expected username %s, got %s' % (wanted_email, @@ -435,7 +376,7 @@ def _oauth2_auth_token(stub, args): def _jwt_token_creds(stub, args): json_key_filename = os.environ[google_auth_environment_vars.CREDENTIALS] - wanted_email = json.load(open(json_key_filename, 'rb'))['client_email'] + wanted_email = json.load(open(json_key_filename, 'r'))['client_email'] response = _large_unary_common_behavior(stub, True, False, None) if wanted_email != response.username: raise ValueError('expected username %s, got %s' % (wanted_email, @@ -444,7 +385,7 @@ def _jwt_token_creds(stub, args): def _per_rpc_creds(stub, args): json_key_filename = os.environ[google_auth_environment_vars.CREDENTIALS] - wanted_email = json.load(open(json_key_filename, 'rb'))['client_email'] + wanted_email = json.load(open(json_key_filename, 'r'))['client_email'] google_credentials, unused_project_id = google_auth.default( scopes=[args.oauth_scope]) call_credentials = grpc.metadata_call_credentials( diff --git a/src/python/grpcio_tests/tests/interop/server.py b/src/python/grpcio_tests/tests/interop/server.py index 72f88a1c989..3611ffdbb2f 100644 --- a/src/python/grpcio_tests/tests/interop/server.py +++ b/src/python/grpcio_tests/tests/interop/server.py @@ -21,7 +21,7 @@ import time import grpc from src.proto.grpc.testing import test_pb2_grpc -from tests.interop import methods +from tests.interop import service from tests.interop import resources from tests.unit import test_common @@ -42,7 +42,7 @@ def serve(): args = parser.parse_args() server = test_common.test_server() - test_pb2_grpc.add_TestServiceServicer_to_server(methods.TestService(), + test_pb2_grpc.add_TestServiceServicer_to_server(service.TestService(), server) if args.use_tls: private_key = resources.private_key() diff --git a/src/python/grpcio_tests/tests/interop/service.py b/src/python/grpcio_tests/tests/interop/service.py new file mode 100644 index 00000000000..37e4404c141 --- /dev/null +++ b/src/python/grpcio_tests/tests/interop/service.py @@ -0,0 +1,97 @@ +# Copyright 2019 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. +# 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. +"""The Python implementation of the TestServicer.""" + +import time + +import grpc + +from src.proto.grpc.testing import empty_pb2 +from src.proto.grpc.testing import messages_pb2 +from src.proto.grpc.testing import test_pb2_grpc + +_INITIAL_METADATA_KEY = "x-grpc-test-echo-initial" +_TRAILING_METADATA_KEY = "x-grpc-test-echo-trailing-bin" +_US_IN_A_SECOND = 1000 * 1000 + + +def _maybe_echo_metadata(servicer_context): + """Copies metadata from request to response if it is present.""" + invocation_metadata = dict(servicer_context.invocation_metadata()) + if _INITIAL_METADATA_KEY in invocation_metadata: + initial_metadatum = (_INITIAL_METADATA_KEY, + invocation_metadata[_INITIAL_METADATA_KEY]) + servicer_context.send_initial_metadata((initial_metadatum,)) + if _TRAILING_METADATA_KEY in invocation_metadata: + trailing_metadatum = (_TRAILING_METADATA_KEY, + invocation_metadata[_TRAILING_METADATA_KEY]) + servicer_context.set_trailing_metadata((trailing_metadatum,)) + + +def _maybe_echo_status_and_message(request, servicer_context): + """Sets the response context code and details if the request asks for them""" + if request.HasField('response_status'): + servicer_context.set_code(request.response_status.code) + servicer_context.set_details(request.response_status.message) + + +class TestService(test_pb2_grpc.TestServiceServicer): + + def EmptyCall(self, request, context): + _maybe_echo_metadata(context) + return empty_pb2.Empty() + + def UnaryCall(self, request, context): + _maybe_echo_metadata(context) + _maybe_echo_status_and_message(request, context) + return messages_pb2.SimpleResponse( + payload=messages_pb2.Payload( + type=messages_pb2.COMPRESSABLE, + body=b'\x00' * request.response_size)) + + def StreamingOutputCall(self, request, context): + _maybe_echo_status_and_message(request, context) + for response_parameters in request.response_parameters: + if response_parameters.interval_us != 0: + time.sleep(response_parameters.interval_us / _US_IN_A_SECOND) + yield messages_pb2.StreamingOutputCallResponse( + payload=messages_pb2.Payload( + type=request.response_type, + body=b'\x00' * response_parameters.size)) + + def StreamingInputCall(self, request_iterator, context): + aggregate_size = 0 + for request in request_iterator: + if request.payload is not None and request.payload.body: + aggregate_size += len(request.payload.body) + return messages_pb2.StreamingInputCallResponse( + aggregated_payload_size=aggregate_size) + + def FullDuplexCall(self, request_iterator, context): + _maybe_echo_metadata(context) + for request in request_iterator: + _maybe_echo_status_and_message(request, context) + for response_parameters in request.response_parameters: + if response_parameters.interval_us != 0: + time.sleep( + response_parameters.interval_us / _US_IN_A_SECOND) + yield messages_pb2.StreamingOutputCallResponse( + payload=messages_pb2.Payload( + type=request.payload.type, + body=b'\x00' * response_parameters.size)) + + # NOTE(nathaniel): Apparently this is the same as the full-duplex call? + # NOTE(atash): It isn't even called in the interop spec (Oct 22 2015)... + def HalfDuplexCall(self, request_iterator, context): + return self.FullDuplexCall(request_iterator, context) 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 e21ea0010ad..2b735526cb0 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 @@ -144,7 +144,7 @@ class _ProtoBeforeGrpcProtocStyle(object): absolute_proto_file_names) pb2_grpc_protoc_exit_code = _protoc( proto_path, None, 'grpc_2_0', python_out, absolute_proto_file_names) - return pb2_protoc_exit_code, pb2_grpc_protoc_exit_code, + return pb2_protoc_exit_code, pb2_grpc_protoc_exit_code class _GrpcBeforeProtoProtocStyle(object): @@ -160,7 +160,7 @@ class _GrpcBeforeProtoProtocStyle(object): proto_path, None, 'grpc_2_0', python_out, absolute_proto_file_names) pb2_protoc_exit_code = _protoc(proto_path, python_out, None, None, absolute_proto_file_names) - return pb2_grpc_protoc_exit_code, pb2_protoc_exit_code, + return pb2_grpc_protoc_exit_code, pb2_protoc_exit_code _PROTOC_STYLES = ( @@ -243,9 +243,9 @@ class _Test(six.with_metaclass(abc.ABCMeta, unittest.TestCase)): def _services_modules(self): if self.PROTOC_STYLE.grpc_in_pb2_expected(): - return self._services_pb2, self._services_pb2_grpc, + return self._services_pb2, self._services_pb2_grpc else: - return self._services_pb2_grpc, + return (self._services_pb2_grpc,) def test_imported_attributes(self): self._protoc() 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 b46e53315e6..56f6871e5c2 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 @@ -195,7 +195,7 @@ def _CreateService(payload_pb2, responses_pb2, service_pb2): Yields: A (servicer_methods, stub) pair where servicer_methods is the back-end of - the service bound to the stub and and stub is the stub on which to invoke + the service bound to the stub and stub is the stub on which to invoke RPCs. """ servicer_methods = _ServicerMethods(payload_pb2, responses_pb2) @@ -223,7 +223,7 @@ def _CreateService(payload_pb2, responses_pb2, service_pb2): server.start() channel = implementations.insecure_channel('localhost', port) stub = getattr(service_pb2, STUB_FACTORY_IDENTIFIER)(channel) - yield servicer_methods, stub, + yield servicer_methods, stub server.stop(0) @@ -237,7 +237,7 @@ def _CreateIncompleteService(service_pb2): service_pb2: The service_pb2 module generated by this test. Yields: A (servicer_methods, stub) pair where servicer_methods is the back-end of - the service bound to the stub and and stub is the stub on which to invoke + the service bound to the stub and stub is the stub on which to invoke RPCs. """ diff --git a/src/python/grpcio_tests/tests/qps/benchmark_client.py b/src/python/grpcio_tests/tests/qps/benchmark_client.py index 0488450740a..fac0e44e5a4 100644 --- a/src/python/grpcio_tests/tests/qps/benchmark_client.py +++ b/src/python/grpcio_tests/tests/qps/benchmark_client.py @@ -180,7 +180,7 @@ class StreamingSyncBenchmarkClient(BenchmarkClient): self._streams = [ _SyncStream(self._stub, self._generic, self._request, self._handle_response) - for _ in xrange(config.outstanding_rpcs_per_channel) + for _ in range(config.outstanding_rpcs_per_channel) ] self._curr_stream = 0 diff --git a/src/python/grpcio_tests/tests/qps/client_runner.py b/src/python/grpcio_tests/tests/qps/client_runner.py index e79abab3c71..a57524c74e3 100644 --- a/src/python/grpcio_tests/tests/qps/client_runner.py +++ b/src/python/grpcio_tests/tests/qps/client_runner.py @@ -77,7 +77,7 @@ class ClosedLoopClientRunner(ClientRunner): def start(self): self._is_running = True self._client.start() - for _ in xrange(self._request_count): + for _ in range(self._request_count): self._client.send_request() def stop(self): diff --git a/src/python/grpcio_tests/tests/qps/worker_server.py b/src/python/grpcio_tests/tests/qps/worker_server.py index 740bdcf1eb3..a03367ec63a 100644 --- a/src/python/grpcio_tests/tests/qps/worker_server.py +++ b/src/python/grpcio_tests/tests/qps/worker_server.py @@ -39,7 +39,7 @@ class WorkerServer(worker_service_pb2_grpc.WorkerServiceServicer): self._quit_event = threading.Event() def RunServer(self, request_iterator, context): - config = next(request_iterator).setup + config = next(request_iterator).setup #pylint: disable=stop-iteration-return server, port = self._create_server(config) cores = multiprocessing.cpu_count() server.start() @@ -102,14 +102,14 @@ class WorkerServer(worker_service_pb2_grpc.WorkerServiceServicer): return (server, port) def RunClient(self, request_iterator, context): - config = next(request_iterator).setup + config = next(request_iterator).setup #pylint: disable=stop-iteration-return client_runners = [] qps_data = histogram.Histogram(config.histogram_params.resolution, config.histogram_params.max_possible) start_time = time.time() # Create a client for each channel - for i in xrange(config.client_channels): + for i in range(config.client_channels): server = config.server_targets[i % len(config.server_targets)] runner = self._create_client_runner(server, config, qps_data) client_runners.append(runner) diff --git a/src/python/grpcio_tests/tests/reflection/BUILD.bazel b/src/python/grpcio_tests/tests/reflection/BUILD.bazel index c0efb0b7cef..b635b721631 100644 --- a/src/python/grpcio_tests/tests/reflection/BUILD.bazel +++ b/src/python/grpcio_tests/tests/reflection/BUILD.bazel @@ -14,6 +14,7 @@ py_test( "//src/python/grpcio_tests/tests/unit:test_common", "//src/proto/grpc/testing:py_empty_proto", "//src/proto/grpc/testing/proto2:empty2_extensions_proto", + "//src/proto/grpc/testing/proto2:empty2_proto", requirement('protobuf'), ], imports=["../../",], diff --git a/src/python/grpcio_tests/tests/reflection/_reflection_servicer_test.py b/src/python/grpcio_tests/tests/reflection/_reflection_servicer_test.py index bcd9e14a386..29bb292c913 100644 --- a/src/python/grpcio_tests/tests/reflection/_reflection_servicer_test.py +++ b/src/python/grpcio_tests/tests/reflection/_reflection_servicer_test.py @@ -50,14 +50,28 @@ def _file_descriptor_to_proto(descriptor): class ReflectionServicerTest(unittest.TestCase): + # TODO(https://github.com/grpc/grpc/issues/17844) + # Bazel + Python 3 will result in creating two different instance of + # DESCRIPTOR for each message. So, the equal comparison between protobuf + # returned by stub and manually crafted protobuf will always fail. + def _assert_sequence_of_proto_equal(self, x, y): + self.assertSequenceEqual( + tuple(proto.SerializeToString() for proto in x), + tuple(proto.SerializeToString() for proto in y), + ) + def setUp(self): self._server = test_common.test_server() reflection.enable_server_reflection(_SERVICE_NAMES, self._server) port = self._server.add_insecure_port('[::]:0') self._server.start() - channel = grpc.insecure_channel('localhost:%d' % port) - self._stub = reflection_pb2_grpc.ServerReflectionStub(channel) + self._channel = grpc.insecure_channel('localhost:%d' % port) + self._stub = reflection_pb2_grpc.ServerReflectionStub(self._channel) + + def tearDown(self): + self._server.stop(None) + self._channel.close() def testFileByName(self): requests = ( @@ -80,7 +94,7 @@ class ReflectionServicerTest(unittest.TestCase): error_message=grpc.StatusCode.NOT_FOUND.value[1].encode(), )), ) - self.assertSequenceEqual(expected_responses, responses) + self._assert_sequence_of_proto_equal(expected_responses, responses) def testFileBySymbol(self): requests = ( @@ -104,7 +118,7 @@ class ReflectionServicerTest(unittest.TestCase): error_message=grpc.StatusCode.NOT_FOUND.value[1].encode(), )), ) - self.assertSequenceEqual(expected_responses, responses) + self._assert_sequence_of_proto_equal(expected_responses, responses) def testFileContainingExtension(self): requests = ( @@ -133,7 +147,7 @@ class ReflectionServicerTest(unittest.TestCase): error_message=grpc.StatusCode.NOT_FOUND.value[1].encode(), )), ) - self.assertSequenceEqual(expected_responses, responses) + self._assert_sequence_of_proto_equal(expected_responses, responses) def testExtensionNumbersOfType(self): requests = ( @@ -158,7 +172,7 @@ class ReflectionServicerTest(unittest.TestCase): error_message=grpc.StatusCode.NOT_FOUND.value[1].encode(), )), ) - self.assertSequenceEqual(expected_responses, responses) + self._assert_sequence_of_proto_equal(expected_responses, responses) def testListServices(self): requests = (reflection_pb2.ServerReflectionRequest(list_services='',),) @@ -169,7 +183,7 @@ class ReflectionServicerTest(unittest.TestCase): service=tuple( reflection_pb2.ServiceResponse(name=name) for name in _SERVICE_NAMES))),) - self.assertSequenceEqual(expected_responses, responses) + self._assert_sequence_of_proto_equal(expected_responses, responses) def testReflectionServiceName(self): self.assertEqual(reflection.SERVICE_NAME, diff --git a/src/python/grpcio_tests/tests/status/BUILD.bazel b/src/python/grpcio_tests/tests/status/BUILD.bazel new file mode 100644 index 00000000000..b163fe3975e --- /dev/null +++ b/src/python/grpcio_tests/tests/status/BUILD.bazel @@ -0,0 +1,20 @@ +load("@grpc_python_dependencies//:requirements.bzl", "requirement") + +package(default_visibility = ["//visibility:public"]) + +py_test( + name = "grpc_status_test", + srcs = ["_grpc_status_test.py"], + main = "_grpc_status_test.py", + size = "small", + deps = [ + "//src/python/grpcio/grpc:grpcio", + "//src/python/grpcio_status/grpc_status:grpc_status", + "//src/python/grpcio_tests/tests:bazel_namespace_package_hack", + "//src/python/grpcio_tests/tests/unit:test_common", + "//src/python/grpcio_tests/tests/unit/framework/common:common", + requirement('protobuf'), + requirement('googleapis-common-protos'), + ], + imports = ["../../",], +) diff --git a/src/python/grpcio_tests/tests/status/__init__.py b/src/python/grpcio_tests/tests/status/__init__.py new file mode 100644 index 00000000000..38fdfc9c5cf --- /dev/null +++ b/src/python/grpcio_tests/tests/status/__init__.py @@ -0,0 +1,13 @@ +# Copyright 2018 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. +# 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. diff --git a/src/python/grpcio_tests/tests/status/_grpc_status_test.py b/src/python/grpcio_tests/tests/status/_grpc_status_test.py new file mode 100644 index 00000000000..d1e9773b495 --- /dev/null +++ b/src/python/grpcio_tests/tests/status/_grpc_status_test.py @@ -0,0 +1,181 @@ +# Copyright 2018 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. +# 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 of grpc_status.""" + +# NOTE(lidiz) This module only exists in Bazel BUILD file, for more details +# please refer to comments in the "bazel_namespace_package_hack" module. +try: + from tests import bazel_namespace_package_hack + bazel_namespace_package_hack.sys_path_to_site_dir_hack() +except ImportError: + pass + +import unittest + +import logging +import traceback + +import grpc +from grpc_status import rpc_status + +from tests.unit import test_common + +from google.protobuf import any_pb2 +from google.rpc import code_pb2, status_pb2, error_details_pb2 + +_STATUS_OK = '/test/StatusOK' +_STATUS_NOT_OK = '/test/StatusNotOk' +_ERROR_DETAILS = '/test/ErrorDetails' +_INCONSISTENT = '/test/Inconsistent' +_INVALID_CODE = '/test/InvalidCode' + +_REQUEST = b'\x00\x00\x00' +_RESPONSE = b'\x01\x01\x01' + +_GRPC_DETAILS_METADATA_KEY = 'grpc-status-details-bin' + +_STATUS_DETAILS = 'This is an error detail' +_STATUS_DETAILS_ANOTHER = 'This is another error detail' + + +def _ok_unary_unary(request, servicer_context): + return _RESPONSE + + +def _not_ok_unary_unary(request, servicer_context): + servicer_context.abort(grpc.StatusCode.INTERNAL, _STATUS_DETAILS) + + +def _error_details_unary_unary(request, servicer_context): + details = any_pb2.Any() + details.Pack( + error_details_pb2.DebugInfo( + stack_entries=traceback.format_stack(), + detail='Intentionally invoked')) + rich_status = status_pb2.Status( + code=code_pb2.INTERNAL, + message=_STATUS_DETAILS, + details=[details], + ) + servicer_context.abort_with_status(rpc_status.to_status(rich_status)) + + +def _inconsistent_unary_unary(request, servicer_context): + rich_status = status_pb2.Status( + code=code_pb2.INTERNAL, + message=_STATUS_DETAILS, + ) + servicer_context.set_code(grpc.StatusCode.NOT_FOUND) + servicer_context.set_details(_STATUS_DETAILS_ANOTHER) + # User put inconsistent status information in trailing metadata + servicer_context.set_trailing_metadata(((_GRPC_DETAILS_METADATA_KEY, + rich_status.SerializeToString()),)) + + +def _invalid_code_unary_unary(request, servicer_context): + rich_status = status_pb2.Status( + code=42, + message='Invalid code', + ) + servicer_context.abort_with_status(rpc_status.to_status(rich_status)) + + +class _GenericHandler(grpc.GenericRpcHandler): + + def service(self, handler_call_details): + if handler_call_details.method == _STATUS_OK: + return grpc.unary_unary_rpc_method_handler(_ok_unary_unary) + elif handler_call_details.method == _STATUS_NOT_OK: + return grpc.unary_unary_rpc_method_handler(_not_ok_unary_unary) + elif handler_call_details.method == _ERROR_DETAILS: + return grpc.unary_unary_rpc_method_handler( + _error_details_unary_unary) + elif handler_call_details.method == _INCONSISTENT: + return grpc.unary_unary_rpc_method_handler( + _inconsistent_unary_unary) + elif handler_call_details.method == _INVALID_CODE: + return grpc.unary_unary_rpc_method_handler( + _invalid_code_unary_unary) + else: + return None + + +class StatusTest(unittest.TestCase): + + def setUp(self): + self._server = test_common.test_server() + self._server.add_generic_rpc_handlers((_GenericHandler(),)) + port = self._server.add_insecure_port('[::]:0') + self._server.start() + + self._channel = grpc.insecure_channel('localhost:%d' % port) + + def tearDown(self): + self._server.stop(None) + self._channel.close() + + def test_status_ok(self): + _, call = self._channel.unary_unary(_STATUS_OK).with_call(_REQUEST) + + # Succeed RPC doesn't have status + status = rpc_status.from_call(call) + self.assertIs(status, None) + + def test_status_not_ok(self): + with self.assertRaises(grpc.RpcError) as exception_context: + self._channel.unary_unary(_STATUS_NOT_OK).with_call(_REQUEST) + rpc_error = exception_context.exception + + self.assertEqual(rpc_error.code(), grpc.StatusCode.INTERNAL) + # Failed RPC doesn't automatically generate status + status = rpc_status.from_call(rpc_error) + self.assertIs(status, None) + + def test_error_details(self): + with self.assertRaises(grpc.RpcError) as exception_context: + self._channel.unary_unary(_ERROR_DETAILS).with_call(_REQUEST) + rpc_error = exception_context.exception + + status = rpc_status.from_call(rpc_error) + self.assertEqual(rpc_error.code(), grpc.StatusCode.INTERNAL) + self.assertEqual(status.code, code_pb2.Code.Value('INTERNAL')) + + # Check if the underlying proto message is intact + self.assertEqual(status.details[0].Is( + error_details_pb2.DebugInfo.DESCRIPTOR), True) + info = error_details_pb2.DebugInfo() + status.details[0].Unpack(info) + self.assertIn('_error_details_unary_unary', info.stack_entries[-1]) + + def test_code_message_validation(self): + with self.assertRaises(grpc.RpcError) as exception_context: + self._channel.unary_unary(_INCONSISTENT).with_call(_REQUEST) + rpc_error = exception_context.exception + self.assertEqual(rpc_error.code(), grpc.StatusCode.NOT_FOUND) + + # Code/Message validation failed + self.assertRaises(ValueError, rpc_status.from_call, rpc_error) + + def test_invalid_code(self): + with self.assertRaises(grpc.RpcError) as exception_context: + self._channel.unary_unary(_INVALID_CODE).with_call(_REQUEST) + rpc_error = exception_context.exception + self.assertEqual(rpc_error.code(), grpc.StatusCode.UNKNOWN) + # Invalid status code exception raised during coversion + self.assertIn('Invalid status code', rpc_error.details()) + + +if __name__ == '__main__': + logging.basicConfig() + unittest.main(verbosity=2) diff --git a/src/python/grpcio_tests/tests/stress/client.py b/src/python/grpcio_tests/tests/stress/client.py index 41f2e1b6c2d..11e46d4e720 100644 --- a/src/python/grpcio_tests/tests/stress/client.py +++ b/src/python/grpcio_tests/tests/stress/client.py @@ -34,12 +34,12 @@ def _args(): description='gRPC Python stress test client') parser.add_argument( '--server_addresses', - help='comma seperated list of hostname:port to run servers on', + help='comma separated list of hostname:port to run servers on', default='localhost:8080', type=str) parser.add_argument( '--test_cases', - help='comma seperated list of testcase:weighting of tests to run', + help='comma separated list of testcase:weighting of tests to run', default='large_unary:100', type=str) parser.add_argument( @@ -71,7 +71,6 @@ def _args(): '--use_tls', help='Whether to use TLS', default=False, type=bool) parser.add_argument( '--server_host_override', - default="foo.test.google.fr", help='the server host to which to claim to connect', type=str) return parser.parse_args() @@ -132,9 +131,9 @@ def run_test(args): server.start() for test_server_target in test_server_targets: - for _ in xrange(args.num_channels_per_server): + for _ in range(args.num_channels_per_server): channel = _get_channel(test_server_target, args) - for _ in xrange(args.num_stubs_per_channel): + for _ in range(args.num_stubs_per_channel): stub = test_pb2_grpc.TestServiceStub(channel) runner = test_runner.TestRunner(stub, test_cases, hist, exception_queue, stop_event) diff --git a/src/python/grpcio_tests/tests/testing/_client_application.py b/src/python/grpcio_tests/tests/testing/_client_application.py index 3ddeba23735..4d42df03897 100644 --- a/src/python/grpcio_tests/tests/testing/_client_application.py +++ b/src/python/grpcio_tests/tests/testing/_client_application.py @@ -130,9 +130,9 @@ def _run_stream_stream(stub): request_pipe = _Pipe() response_iterator = stub.StreStre(iter(request_pipe)) request_pipe.add(_application_common.STREAM_STREAM_REQUEST) - first_responses = next(response_iterator), next(response_iterator), + first_responses = next(response_iterator), next(response_iterator) request_pipe.add(_application_common.STREAM_STREAM_REQUEST) - second_responses = next(response_iterator), next(response_iterator), + second_responses = next(response_iterator), next(response_iterator) request_pipe.close() try: next(response_iterator) diff --git a/src/python/grpcio_tests/tests/tests.json b/src/python/grpcio_tests/tests/tests.json index a3006d9afc2..cc08d56248a 100644 --- a/src/python/grpcio_tests/tests/tests.json +++ b/src/python/grpcio_tests/tests/tests.json @@ -1,5 +1,8 @@ [ "_sanity._sanity_test.SanityTest", + "channelz._channelz_servicer_test.ChannelzServicerTest", + "fork._fork_interop_test.ForkInteropTest", + "health_check._health_servicer_test.HealthServicerBackwardsCompatibleWatchTest", "health_check._health_servicer_test.HealthServicerTest", "interop._insecure_intraop_test.InsecureIntraopTest", "interop._secure_intraop_test.SecureIntraopTest", @@ -14,10 +17,12 @@ "protoc_plugin._split_definitions_test.SplitProtoSingleProtocExecutionProtocStyleTest", "protoc_plugin.beta_python_plugin_test.PythonPluginTest", "reflection._reflection_servicer_test.ReflectionServicerTest", + "status._grpc_status_test.StatusTest", "testing._client_test.ClientTest", "testing._server_test.FirstServiceServicerTest", "testing._time_test.StrictFakeTimeTest", "testing._time_test.StrictRealTimeTest", + "unit._abort_test.AbortTest", "unit._api_test.AllTest", "unit._api_test.ChannelConnectivityTest", "unit._api_test.ChannelTest", @@ -41,6 +46,7 @@ "unit._cython.cygrpc_test.InsecureServerInsecureClient", "unit._cython.cygrpc_test.SecureServerSecureClient", "unit._cython.cygrpc_test.TypeSmokeTest", + "unit._dns_resolver_test.DNSResolverTest", "unit._empty_message_test.EmptyMessageTest", "unit._error_message_encoding_test.ErrorMessageEncodingTest", "unit._exit_test.ExitTest", @@ -54,12 +60,14 @@ "unit._reconnect_test.ReconnectTest", "unit._resource_exhausted_test.ResourceExhaustedTest", "unit._rpc_test.RPCTest", + "unit._server_shutdown_test.ServerShutdown", "unit._server_ssl_cert_config_test.ServerSSLCertConfigFetcherParamsChecks", "unit._server_ssl_cert_config_test.ServerSSLCertReloadTestCertConfigReuse", "unit._server_ssl_cert_config_test.ServerSSLCertReloadTestWithClientAuth", "unit._server_ssl_cert_config_test.ServerSSLCertReloadTestWithoutClientAuth", "unit._server_test.ServerTest", "unit._session_cache_test.SSLSessionCacheTest", + "unit._version_test.VersionTest", "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/BUILD.bazel b/src/python/grpcio_tests/tests/unit/BUILD.bazel index de33b81e325..a161794f8be 100644 --- a/src/python/grpcio_tests/tests/unit/BUILD.bazel +++ b/src/python/grpcio_tests/tests/unit/BUILD.bazel @@ -3,15 +3,18 @@ load("@grpc_python_dependencies//:requirements.bzl", "requirement") package(default_visibility = ["//visibility:public"]) GRPCIO_TESTS_UNIT = [ + "_abort_test.py", "_api_test.py", "_auth_context_test.py", "_auth_test.py", + "_version_test.py", "_channel_args_test.py", "_channel_close_test.py", "_channel_connectivity_test.py", "_channel_ready_future_test.py", "_compression_test.py", "_credentials_test.py", + "_dns_resolver_test.py", "_empty_message_test.py", "_exit_test.py", "_interceptor_test.py", @@ -27,9 +30,15 @@ GRPCIO_TESTS_UNIT = [ # TODO(ghostwriternr): To be added later. # "_server_ssl_cert_config_test.py", "_server_test.py", + "_server_shutdown_test.py", "_session_cache_test.py", ] +py_library( + name = "_tcp_proxy", + srcs = ["_tcp_proxy.py"], +) + py_library( name = "resources", srcs = ["resources.py"], @@ -43,14 +52,19 @@ py_library( srcs = ["test_common.py"], ) +py_library( + name = "thread_pool", + srcs = ["thread_pool.py"], +) + py_library( name = "_exit_scenarios", srcs = ["_exit_scenarios.py"], ) py_library( - name = "_thread_pool", - srcs = ["_thread_pool.py"], + name = "_server_shutdown_scenarios", + srcs = ["_server_shutdown_scenarios.py"], ) py_library( @@ -68,9 +82,11 @@ py_library( "//src/python/grpcio/grpc:grpcio", ":resources", ":test_common", + ":thread_pool", ":_exit_scenarios", - ":_thread_pool", + ":_server_shutdown_scenarios", ":_from_grpc_import_star", + ":_tcp_proxy", "//src/python/grpcio_tests/tests/unit/framework/common", "//src/python/grpcio_tests/tests/testing", requirement('six'), diff --git a/src/python/grpcio_tests/tests/unit/_abort_test.py b/src/python/grpcio_tests/tests/unit/_abort_test.py new file mode 100644 index 00000000000..2c83e0dab38 --- /dev/null +++ b/src/python/grpcio_tests/tests/unit/_abort_test.py @@ -0,0 +1,153 @@ +# 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 context abort mechanism""" + +import unittest +import collections +import gc +import logging +import weakref + +import grpc + +from tests.unit import test_common +from tests.unit.framework.common import test_constants + +_ABORT = '/test/abort' +_ABORT_WITH_STATUS = '/test/AbortWithStatus' +_INVALID_CODE = '/test/InvalidCode' + +_REQUEST = b'\x00\x00\x00' +_RESPONSE = b'\x00\x00\x00' + +_ABORT_DETAILS = 'Abandon ship!' +_ABORT_METADATA = (('a-trailing-metadata', '42'),) + + +class _Status( + collections.namedtuple( + '_Status', ('code', 'details', 'trailing_metadata')), grpc.Status): + pass + + +class _Object(object): + pass + + +do_not_leak_me = _Object() + + +def abort_unary_unary(request, servicer_context): + this_should_not_be_leaked = do_not_leak_me + servicer_context.abort( + grpc.StatusCode.INTERNAL, + _ABORT_DETAILS, + ) + raise Exception('This line should not be executed!') + + +def abort_with_status_unary_unary(request, servicer_context): + servicer_context.abort_with_status( + _Status( + code=grpc.StatusCode.INTERNAL, + details=_ABORT_DETAILS, + trailing_metadata=_ABORT_METADATA, + )) + raise Exception('This line should not be executed!') + + +def invalid_code_unary_unary(request, servicer_context): + servicer_context.abort( + 42, + _ABORT_DETAILS, + ) + + +class _GenericHandler(grpc.GenericRpcHandler): + + def service(self, handler_call_details): + if handler_call_details.method == _ABORT: + return grpc.unary_unary_rpc_method_handler(abort_unary_unary) + elif handler_call_details.method == _ABORT_WITH_STATUS: + return grpc.unary_unary_rpc_method_handler( + abort_with_status_unary_unary) + elif handler_call_details.method == _INVALID_CODE: + return grpc.stream_stream_rpc_method_handler( + invalid_code_unary_unary) + else: + return None + + +class AbortTest(unittest.TestCase): + + def setUp(self): + self._server = test_common.test_server() + port = self._server.add_insecure_port('[::]:0') + self._server.add_generic_rpc_handlers((_GenericHandler(),)) + self._server.start() + + self._channel = grpc.insecure_channel('localhost:%d' % port) + + def tearDown(self): + self._channel.close() + self._server.stop(0) + + def test_abort(self): + with self.assertRaises(grpc.RpcError) as exception_context: + self._channel.unary_unary(_ABORT)(_REQUEST) + rpc_error = exception_context.exception + + self.assertEqual(rpc_error.code(), grpc.StatusCode.INTERNAL) + self.assertEqual(rpc_error.details(), _ABORT_DETAILS) + + # This test ensures that abort() does not store the raised exception, which + # on Python 3 (via the `__traceback__` attribute) holds a reference to + # all local vars. Storing the raised exception can prevent GC and stop the + # grpc_call from being unref'ed, even after server shutdown. + @unittest.skip("https://github.com/grpc/grpc/issues/17927") + def test_abort_does_not_leak_local_vars(self): + global do_not_leak_me # pylint: disable=global-statement + weak_ref = weakref.ref(do_not_leak_me) + + # Servicer will abort() after creating a local ref to do_not_leak_me. + with self.assertRaises(grpc.RpcError): + self._channel.unary_unary(_ABORT)(_REQUEST) + + # Server may still have a stack frame reference to the exception even + # after client sees error, so ensure server has shutdown. + self._server.stop(None) + do_not_leak_me = None + self.assertIsNone(weak_ref()) + + def test_abort_with_status(self): + with self.assertRaises(grpc.RpcError) as exception_context: + self._channel.unary_unary(_ABORT_WITH_STATUS)(_REQUEST) + rpc_error = exception_context.exception + + self.assertEqual(rpc_error.code(), grpc.StatusCode.INTERNAL) + self.assertEqual(rpc_error.details(), _ABORT_DETAILS) + self.assertEqual(rpc_error.trailing_metadata(), _ABORT_METADATA) + + def test_invalid_code(self): + with self.assertRaises(grpc.RpcError) as exception_context: + self._channel.unary_unary(_INVALID_CODE)(_REQUEST) + rpc_error = exception_context.exception + + self.assertEqual(rpc_error.code(), grpc.StatusCode.UNKNOWN) + self.assertEqual(rpc_error.details(), _ABORT_DETAILS) + + +if __name__ == '__main__': + logging.basicConfig() + unittest.main(verbosity=2) diff --git a/src/python/grpcio_tests/tests/unit/_api_test.py b/src/python/grpcio_tests/tests/unit/_api_test.py index 38072861a49..127dab336bf 100644 --- a/src/python/grpcio_tests/tests/unit/_api_test.py +++ b/src/python/grpcio_tests/tests/unit/_api_test.py @@ -31,7 +31,9 @@ class AllTest(unittest.TestCase): 'FutureCancelledError', 'Future', 'ChannelConnectivity', + 'Compression', 'StatusCode', + 'Status', 'RpcError', 'RpcContext', 'Call', @@ -100,6 +102,7 @@ class ChannelTest(unittest.TestCase): def test_secure_channel(self): channel_credentials = grpc.ssl_channel_credentials() channel = grpc.secure_channel('google.com:443', channel_credentials) + channel.close() if __name__ == '__main__': diff --git a/src/python/grpcio_tests/tests/unit/_auth_context_test.py b/src/python/grpcio_tests/tests/unit/_auth_context_test.py index b1b5bbdcab3..96c4e9ec76a 100644 --- a/src/python/grpcio_tests/tests/unit/_auth_context_test.py +++ b/src/python/grpcio_tests/tests/unit/_auth_context_test.py @@ -71,8 +71,8 @@ class AuthContextTest(unittest.TestCase): port = server.add_insecure_port('[::]:0') server.start() - channel = grpc.insecure_channel('localhost:%d' % port) - response = channel.unary_unary(_UNARY_UNARY)(_REQUEST) + with grpc.insecure_channel('localhost:%d' % port) as channel: + response = channel.unary_unary(_UNARY_UNARY)(_REQUEST) server.stop(None) auth_data = pickle.loads(response) @@ -98,6 +98,7 @@ class AuthContextTest(unittest.TestCase): channel_creds, options=_PROPERTY_OPTIONS) response = channel.unary_unary(_UNARY_UNARY)(_REQUEST) + channel.close() server.stop(None) auth_data = pickle.loads(response) @@ -132,6 +133,7 @@ class AuthContextTest(unittest.TestCase): options=_PROPERTY_OPTIONS) response = channel.unary_unary(_UNARY_UNARY)(_REQUEST) + channel.close() server.stop(None) auth_data = pickle.loads(response) diff --git a/src/python/grpcio_tests/tests/unit/_channel_connectivity_test.py b/src/python/grpcio_tests/tests/unit/_channel_connectivity_test.py index 727fb7d65fe..78cd09712bc 100644 --- a/src/python/grpcio_tests/tests/unit/_channel_connectivity_test.py +++ b/src/python/grpcio_tests/tests/unit/_channel_connectivity_test.py @@ -20,7 +20,7 @@ import unittest import grpc from tests.unit.framework.common import test_constants -from tests.unit import _thread_pool +from tests.unit import thread_pool def _ready_in_connectivities(connectivities): @@ -75,6 +75,8 @@ class ChannelConnectivityTest(unittest.TestCase): channel.unsubscribe(callback.update) fifth_connectivities = callback.connectivities() + channel.close() + self.assertSequenceEqual((grpc.ChannelConnectivity.IDLE,), first_connectivities) self.assertNotIn(grpc.ChannelConnectivity.READY, second_connectivities) @@ -83,8 +85,10 @@ class ChannelConnectivityTest(unittest.TestCase): self.assertNotIn(grpc.ChannelConnectivity.READY, fifth_connectivities) def test_immediately_connectable_channel_connectivity(self): - thread_pool = _thread_pool.RecordingThreadPool(max_workers=None) - server = grpc.server(thread_pool, options=(('grpc.so_reuseport', 0),)) + recording_thread_pool = thread_pool.RecordingThreadPool( + max_workers=None) + server = grpc.server( + recording_thread_pool, options=(('grpc.so_reuseport', 0),)) port = server.add_insecure_port('[::]:0') server.start() first_callback = _Callback() @@ -108,7 +112,8 @@ class ChannelConnectivityTest(unittest.TestCase): _ready_in_connectivities) second_callback.block_until_connectivities_satisfy( _ready_in_connectivities) - del channel + channel.close() + server.stop(None) self.assertSequenceEqual((grpc.ChannelConnectivity.IDLE,), first_connectivities) @@ -122,11 +127,13 @@ class ChannelConnectivityTest(unittest.TestCase): fourth_connectivities) self.assertNotIn(grpc.ChannelConnectivity.SHUTDOWN, fourth_connectivities) - self.assertFalse(thread_pool.was_used()) + self.assertFalse(recording_thread_pool.was_used()) def test_reachable_then_unreachable_channel_connectivity(self): - thread_pool = _thread_pool.RecordingThreadPool(max_workers=None) - server = grpc.server(thread_pool, options=(('grpc.so_reuseport', 0),)) + recording_thread_pool = thread_pool.RecordingThreadPool( + max_workers=None) + server = grpc.server( + recording_thread_pool, options=(('grpc.so_reuseport', 0),)) port = server.add_insecure_port('[::]:0') server.start() callback = _Callback() @@ -139,7 +146,8 @@ class ChannelConnectivityTest(unittest.TestCase): callback.block_until_connectivities_satisfy( _last_connectivity_is_not_ready) channel.unsubscribe(callback.update) - self.assertFalse(thread_pool.was_used()) + channel.close() + self.assertFalse(recording_thread_pool.was_used()) if __name__ == '__main__': diff --git a/src/python/grpcio_tests/tests/unit/_channel_ready_future_test.py b/src/python/grpcio_tests/tests/unit/_channel_ready_future_test.py index 345460ef40d..cda157d5c56 100644 --- a/src/python/grpcio_tests/tests/unit/_channel_ready_future_test.py +++ b/src/python/grpcio_tests/tests/unit/_channel_ready_future_test.py @@ -19,7 +19,7 @@ import logging import grpc from tests.unit.framework.common import test_constants -from tests.unit import _thread_pool +from tests.unit import thread_pool class _Callback(object): @@ -60,9 +60,13 @@ class ChannelReadyFutureTest(unittest.TestCase): self.assertTrue(ready_future.done()) self.assertFalse(ready_future.running()) + channel.close() + def test_immediately_connectable_channel_connectivity(self): - thread_pool = _thread_pool.RecordingThreadPool(max_workers=None) - server = grpc.server(thread_pool, options=(('grpc.so_reuseport', 0),)) + recording_thread_pool = thread_pool.RecordingThreadPool( + max_workers=None) + server = grpc.server( + recording_thread_pool, options=(('grpc.so_reuseport', 0),)) port = server.add_insecure_port('[::]:0') server.start() channel = grpc.insecure_channel('localhost:{}'.format(port)) @@ -82,7 +86,10 @@ class ChannelReadyFutureTest(unittest.TestCase): self.assertFalse(ready_future.cancelled()) self.assertTrue(ready_future.done()) self.assertFalse(ready_future.running()) - self.assertFalse(thread_pool.was_used()) + self.assertFalse(recording_thread_pool.was_used()) + + channel.close() + server.stop(None) if __name__ == '__main__': diff --git a/src/python/grpcio_tests/tests/unit/_compression_test.py b/src/python/grpcio_tests/tests/unit/_compression_test.py index 876d8e827ea..f9cf8ebb141 100644 --- a/src/python/grpcio_tests/tests/unit/_compression_test.py +++ b/src/python/grpcio_tests/tests/unit/_compression_test.py @@ -15,35 +15,124 @@ import unittest +import contextlib +from concurrent import futures +import functools +import itertools import logging +import os + import grpc from grpc import _grpcio_metadata from tests.unit import test_common from tests.unit.framework.common import test_constants +from tests.unit import _tcp_proxy _UNARY_UNARY = '/test/UnaryUnary' +_UNARY_STREAM = '/test/UnaryStream' +_STREAM_UNARY = '/test/StreamUnary' _STREAM_STREAM = '/test/StreamStream' +# Cut down on test time. +_STREAM_LENGTH = test_constants.STREAM_LENGTH // 16 -def handle_unary(request, servicer_context): - servicer_context.send_initial_metadata([('grpc-internal-encoding-request', - 'gzip')]) - return request +_HOST = 'localhost' + +_REQUEST = b'\x00' * 100 +_COMPRESSION_RATIO_THRESHOLD = 0.05 +_COMPRESSION_METHODS = ( + None, + # Disabled for test tractability. + # grpc.Compression.NoCompression, + # grpc.Compression.Deflate, + grpc.Compression.Gzip, +) +_COMPRESSION_NAMES = { + None: 'Uncompressed', + grpc.Compression.NoCompression: 'NoCompression', + grpc.Compression.Deflate: 'DeflateCompression', + grpc.Compression.Gzip: 'GzipCompression', +} + +_TEST_OPTIONS = { + 'client_streaming': (True, False), + 'server_streaming': (True, False), + 'channel_compression': _COMPRESSION_METHODS, + 'multicallable_compression': _COMPRESSION_METHODS, + 'server_compression': _COMPRESSION_METHODS, + 'server_call_compression': _COMPRESSION_METHODS, +} -def handle_stream(request_iterator, servicer_context): - # TODO(issue:#6891) We should be able to remove this loop, - # and replace with return; yield - servicer_context.send_initial_metadata([('grpc-internal-encoding-request', - 'gzip')]) - for request in request_iterator: - yield request +def _make_handle_unary_unary(pre_response_callback): + + def _handle_unary(request, servicer_context): + if pre_response_callback: + pre_response_callback(request, servicer_context) + return request + + return _handle_unary + + +def _make_handle_unary_stream(pre_response_callback): + + def _handle_unary_stream(request, servicer_context): + if pre_response_callback: + pre_response_callback(request, servicer_context) + for _ in range(_STREAM_LENGTH): + yield request + + return _handle_unary_stream + + +def _make_handle_stream_unary(pre_response_callback): + + def _handle_stream_unary(request_iterator, servicer_context): + if pre_response_callback: + pre_response_callback(request_iterator, servicer_context) + response = None + for request in request_iterator: + if not response: + response = request + return response + + return _handle_stream_unary + + +def _make_handle_stream_stream(pre_response_callback): + + def _handle_stream(request_iterator, servicer_context): + # TODO(issue:#6891) We should be able to remove this loop, + # and replace with return; yield + for request in request_iterator: + if pre_response_callback: + pre_response_callback(request, servicer_context) + yield request + + return _handle_stream + + +def set_call_compression(compression_method, request_or_iterator, + servicer_context): + del request_or_iterator + servicer_context.set_compression(compression_method) + + +def disable_next_compression(request, servicer_context): + del request + servicer_context.disable_next_message_compression() + + +def disable_first_compression(request, servicer_context): + if int(request.decode('ascii')) == 0: + servicer_context.disable_next_message_compression() class _MethodHandler(grpc.RpcMethodHandler): - def __init__(self, request_streaming, response_streaming): + def __init__(self, request_streaming, response_streaming, + pre_response_callback): self.request_streaming = request_streaming self.response_streaming = response_streaming self.request_deserializer = None @@ -52,70 +141,239 @@ class _MethodHandler(grpc.RpcMethodHandler): self.unary_stream = None self.stream_unary = None self.stream_stream = None + if self.request_streaming and self.response_streaming: - self.stream_stream = handle_stream + self.stream_stream = _make_handle_stream_stream( + pre_response_callback) elif not self.request_streaming and not self.response_streaming: - self.unary_unary = handle_unary + self.unary_unary = _make_handle_unary_unary(pre_response_callback) + elif not self.request_streaming and self.response_streaming: + self.unary_stream = _make_handle_unary_stream(pre_response_callback) + else: + self.stream_unary = _make_handle_stream_unary(pre_response_callback) class _GenericHandler(grpc.GenericRpcHandler): + def __init__(self, pre_response_callback): + self._pre_response_callback = pre_response_callback + def service(self, handler_call_details): if handler_call_details.method == _UNARY_UNARY: - return _MethodHandler(False, False) + return _MethodHandler(False, False, self._pre_response_callback) + elif handler_call_details.method == _UNARY_STREAM: + return _MethodHandler(False, True, self._pre_response_callback) + elif handler_call_details.method == _STREAM_UNARY: + return _MethodHandler(True, False, self._pre_response_callback) elif handler_call_details.method == _STREAM_STREAM: - return _MethodHandler(True, True) + return _MethodHandler(True, True, self._pre_response_callback) else: return None +@contextlib.contextmanager +def _instrumented_client_server_pair(channel_kwargs, server_kwargs, + server_handler): + server = grpc.server(futures.ThreadPoolExecutor(), **server_kwargs) + server.add_generic_rpc_handlers((server_handler,)) + server_port = server.add_insecure_port('{}:0'.format(_HOST)) + server.start() + with _tcp_proxy.TcpProxy(_HOST, _HOST, server_port) as proxy: + proxy_port = proxy.get_port() + with grpc.insecure_channel('{}:{}'.format(_HOST, proxy_port), + **channel_kwargs) as client_channel: + try: + yield client_channel, proxy, server + finally: + server.stop(None) + + +def _get_byte_counts(channel_kwargs, multicallable_kwargs, client_function, + server_kwargs, server_handler, message): + with _instrumented_client_server_pair(channel_kwargs, server_kwargs, + server_handler) as pipeline: + client_channel, proxy, server = pipeline + client_function(client_channel, multicallable_kwargs, message) + return proxy.get_byte_count() + + +def _get_compression_ratios(client_function, first_channel_kwargs, + first_multicallable_kwargs, first_server_kwargs, + first_server_handler, second_channel_kwargs, + second_multicallable_kwargs, second_server_kwargs, + second_server_handler, message): + try: + # This test requires the byte length of each connection to be deterministic. As + # it turns out, flow control puts bytes on the wire in a nondeterministic + # manner. We disable it here in order to measure compression ratios + # deterministically. + os.environ['GRPC_EXPERIMENTAL_DISABLE_FLOW_CONTROL'] = 'true' + first_bytes_sent, first_bytes_received = _get_byte_counts( + first_channel_kwargs, first_multicallable_kwargs, client_function, + first_server_kwargs, first_server_handler, message) + second_bytes_sent, second_bytes_received = _get_byte_counts( + second_channel_kwargs, second_multicallable_kwargs, client_function, + second_server_kwargs, second_server_handler, message) + return (( + second_bytes_sent - first_bytes_sent) / float(first_bytes_sent), + (second_bytes_received - first_bytes_received) / + float(first_bytes_received)) + finally: + del os.environ['GRPC_EXPERIMENTAL_DISABLE_FLOW_CONTROL'] + + +def _unary_unary_client(channel, multicallable_kwargs, message): + multi_callable = channel.unary_unary(_UNARY_UNARY) + response = multi_callable(message, **multicallable_kwargs) + if response != message: + raise RuntimeError("Request '{}' != Response '{}'".format( + message, response)) + + +def _unary_stream_client(channel, multicallable_kwargs, message): + multi_callable = channel.unary_stream(_UNARY_STREAM) + response_iterator = multi_callable(message, **multicallable_kwargs) + for response in response_iterator: + if response != message: + raise RuntimeError("Request '{}' != Response '{}'".format( + message, response)) + + +def _stream_unary_client(channel, multicallable_kwargs, message): + multi_callable = channel.stream_unary(_STREAM_UNARY) + requests = (_REQUEST for _ in range(_STREAM_LENGTH)) + response = multi_callable(requests, **multicallable_kwargs) + if response != message: + raise RuntimeError("Request '{}' != Response '{}'".format( + message, response)) + + +def _stream_stream_client(channel, multicallable_kwargs, message): + multi_callable = channel.stream_stream(_STREAM_STREAM) + request_prefix = str(0).encode('ascii') * 100 + requests = ( + request_prefix + str(i).encode('ascii') for i in range(_STREAM_LENGTH)) + response_iterator = multi_callable(requests, **multicallable_kwargs) + for i, response in enumerate(response_iterator): + if int(response.decode('ascii')) != i: + raise RuntimeError("Request '{}' != Response '{}'".format( + i, response)) + + class CompressionTest(unittest.TestCase): - def setUp(self): - self._server = test_common.test_server() - self._server.add_generic_rpc_handlers((_GenericHandler(),)) - self._port = self._server.add_insecure_port('[::]:0') - self._server.start() + def assertCompressed(self, compression_ratio): + self.assertLess( + compression_ratio, + -1.0 * _COMPRESSION_RATIO_THRESHOLD, + msg='Actual compression ratio: {}'.format(compression_ratio)) - def testUnary(self): - request = b'\x00' * 100 + def assertNotCompressed(self, compression_ratio): + self.assertGreaterEqual( + compression_ratio, + -1.0 * _COMPRESSION_RATIO_THRESHOLD, + msg='Actual compession ratio: {}'.format(compression_ratio)) - # Client -> server compressed through default client channel compression - # settings. Server -> client compressed via server-side metadata setting. - # TODO(https://github.com/grpc/grpc/issues/4078): replace the "1" integer - # literal with proper use of the public API. - compressed_channel = grpc.insecure_channel( - 'localhost:%d' % self._port, - options=[('grpc.default_compression_algorithm', 1)]) - multi_callable = compressed_channel.unary_unary(_UNARY_UNARY) - response = multi_callable(request) - self.assertEqual(request, response) + def assertConfigurationCompressed( + self, client_streaming, server_streaming, channel_compression, + multicallable_compression, server_compression, + server_call_compression): + client_side_compressed = channel_compression or multicallable_compression + server_side_compressed = server_compression or server_call_compression + channel_kwargs = { + 'compression': channel_compression, + } if channel_compression else {} + multicallable_kwargs = { + 'compression': multicallable_compression, + } if multicallable_compression else {} - # Client -> server compressed through client metadata setting. Server -> - # client compressed via server-side metadata setting. - # TODO(https://github.com/grpc/grpc/issues/4078): replace the "0" integer - # literal with proper use of the public API. - uncompressed_channel = grpc.insecure_channel( - 'localhost:%d' % self._port, - options=[('grpc.default_compression_algorithm', 0)]) - multi_callable = compressed_channel.unary_unary(_UNARY_UNARY) - response = multi_callable( - request, metadata=[('grpc-internal-encoding-request', 'gzip')]) - self.assertEqual(request, response) + client_function = None + if not client_streaming and not server_streaming: + client_function = _unary_unary_client + elif not client_streaming and server_streaming: + client_function = _unary_stream_client + elif client_streaming and not server_streaming: + client_function = _stream_unary_client + else: + client_function = _stream_stream_client - def testStreaming(self): - request = b'\x00' * 100 + server_kwargs = { + 'compression': server_compression, + } if server_compression else {} + server_handler = _GenericHandler( + functools.partial(set_call_compression, grpc.Compression.Gzip) + ) if server_call_compression else _GenericHandler(None) + sent_ratio, received_ratio = _get_compression_ratios( + client_function, {}, {}, {}, _GenericHandler(None), channel_kwargs, + multicallable_kwargs, server_kwargs, server_handler, _REQUEST) - # TODO(https://github.com/grpc/grpc/issues/4078): replace the "1" integer - # literal with proper use of the public API. - compressed_channel = grpc.insecure_channel( - 'localhost:%d' % self._port, - options=[('grpc.default_compression_algorithm', 1)]) - multi_callable = compressed_channel.stream_stream(_STREAM_STREAM) - call = multi_callable(iter([request] * test_constants.STREAM_LENGTH)) - for response in call: - self.assertEqual(request, response) + if client_side_compressed: + self.assertCompressed(sent_ratio) + else: + self.assertNotCompressed(sent_ratio) + if server_side_compressed: + self.assertCompressed(received_ratio) + else: + self.assertNotCompressed(received_ratio) + + def testDisableNextCompressionStreaming(self): + server_kwargs = { + 'compression': grpc.Compression.Deflate, + } + _, received_ratio = _get_compression_ratios( + _stream_stream_client, {}, {}, {}, _GenericHandler(None), {}, {}, + server_kwargs, _GenericHandler(disable_next_compression), _REQUEST) + self.assertNotCompressed(received_ratio) + + def testDisableNextCompressionStreamingResets(self): + server_kwargs = { + 'compression': grpc.Compression.Deflate, + } + _, received_ratio = _get_compression_ratios( + _stream_stream_client, {}, {}, {}, _GenericHandler(None), {}, {}, + server_kwargs, _GenericHandler(disable_first_compression), _REQUEST) + self.assertCompressed(received_ratio) + + +def _get_compression_str(name, value): + return '{}{}'.format(name, _COMPRESSION_NAMES[value]) + + +def _get_compression_test_name(client_streaming, server_streaming, + channel_compression, multicallable_compression, + server_compression, server_call_compression): + client_arity = 'Stream' if client_streaming else 'Unary' + server_arity = 'Stream' if server_streaming else 'Unary' + arity = '{}{}'.format(client_arity, server_arity) + channel_compression_str = _get_compression_str('Channel', + channel_compression) + multicallable_compression_str = _get_compression_str( + 'Multicallable', multicallable_compression) + server_compression_str = _get_compression_str('Server', server_compression) + server_call_compression_str = _get_compression_str('ServerCall', + server_call_compression) + return 'test{}{}{}{}{}'.format( + arity, channel_compression_str, multicallable_compression_str, + server_compression_str, server_call_compression_str) + + +def _test_options(): + for test_parameters in itertools.product(*_TEST_OPTIONS.values()): + yield dict(zip(_TEST_OPTIONS.keys(), test_parameters)) + + +for options in _test_options(): + + def test_compression(**kwargs): + + def _test_compression(self): + self.assertConfigurationCompressed(**kwargs) + + return _test_compression + + setattr(CompressionTest, _get_compression_test_name(**options), + test_compression(**options)) if __name__ == '__main__': logging.basicConfig() diff --git a/src/python/grpcio_tests/tests/unit/_credentials_test.py b/src/python/grpcio_tests/tests/unit/_credentials_test.py index be7378ecbce..187a6f03881 100644 --- a/src/python/grpcio_tests/tests/unit/_credentials_test.py +++ b/src/python/grpcio_tests/tests/unit/_credentials_test.py @@ -15,6 +15,7 @@ import unittest import logging +import six import grpc @@ -53,6 +54,16 @@ class CredentialsTest(unittest.TestCase): self.assertIsInstance(channel_first_second_and_third, grpc.ChannelCredentials) + @unittest.skipIf(six.PY2, 'only invalid in Python3') + def test_invalid_string_certificate(self): + self.assertRaises( + TypeError, + grpc.ssl_channel_credentials, + root_certificates='A Certificate', + private_key=None, + certificate_chain=None, + ) + if __name__ == '__main__': logging.basicConfig() 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 d95286071d5..54f620523ea 100644 --- a/src/python/grpcio_tests/tests/unit/_cython/_channel_test.py +++ b/src/python/grpcio_tests/tests/unit/_cython/_channel_test.py @@ -57,6 +57,14 @@ class ChannelTest(unittest.TestCase): def test_multiple_channels_lonely_connectivity(self): _in_parallel(_create_loop_destroy, ()) + def test_negative_deadline_connectivity(self): + channel = _channel() + connectivity = channel.check_connectivity_state(True) + channel.watch_connectivity_state(connectivity, -3.14) + channel.close(cygrpc.StatusCode.ok, 'Channel close!') + # NOTE(lidiz) The negative timeout should not trigger SIGABRT. + # Bug report: https://github.com/grpc/grpc/issues/18244 + if __name__ == '__main__': unittest.main(verbosity=2) diff --git a/src/python/grpcio_tests/tests/unit/_cython/_fork_test.py b/src/python/grpcio_tests/tests/unit/_cython/_fork_test.py index aeb02458a7e..5a5dedd5f26 100644 --- a/src/python/grpcio_tests/tests/unit/_cython/_fork_test.py +++ b/src/python/grpcio_tests/tests/unit/_cython/_fork_test.py @@ -27,6 +27,7 @@ def _get_number_active_threads(): class ForkPosixTester(unittest.TestCase): def setUp(self): + self._saved_fork_support_flag = cygrpc._GRPC_ENABLE_FORK_SUPPORT cygrpc._GRPC_ENABLE_FORK_SUPPORT = True def testForkManagedThread(self): @@ -50,6 +51,9 @@ class ForkPosixTester(unittest.TestCase): thread.join() self.assertEqual(0, _get_number_active_threads()) + def tearDown(self): + cygrpc._GRPC_ENABLE_FORK_SUPPORT = self._saved_fork_support_flag + @unittest.skipUnless(os.name == 'nt', 'Windows-specific tests') class ForkWindowsTester(unittest.TestCase): diff --git a/src/python/grpcio_tests/tests/unit/_dns_resolver_test.py b/src/python/grpcio_tests/tests/unit/_dns_resolver_test.py new file mode 100644 index 00000000000..d119707b19d --- /dev/null +++ b/src/python/grpcio_tests/tests/unit/_dns_resolver_test.py @@ -0,0 +1,63 @@ +# Copyright 2019 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. +# 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 an actual dns resolution.""" + +import unittest +import logging +import six + +import grpc +from tests.unit import test_common +from tests.unit.framework.common import test_constants + +_METHOD = '/ANY/METHOD' +_REQUEST = b'\x00\x00\x00' +_RESPONSE = _REQUEST + + +class GenericHandler(grpc.GenericRpcHandler): + + def service(self, unused_handler_details): + return grpc.unary_unary_rpc_method_handler( + lambda request, unused_context: request, + ) + + +class DNSResolverTest(unittest.TestCase): + + def setUp(self): + self._server = test_common.test_server() + self._server.add_generic_rpc_handlers((GenericHandler(),)) + self._port = self._server.add_insecure_port('[::]:0') + self._server.start() + + def tearDown(self): + self._server.stop(None) + + def test_connect_loopback(self): + # NOTE(https://github.com/grpc/grpc/issues/18422) + # In short, Gevent + C-Ares = Segfault. The C-Ares driver is not + # supported by custom io manager like "gevent" or "libuv". + with grpc.insecure_channel( + 'loopback4.unittest.grpc.io:%d' % self._port) as channel: + self.assertEqual( + channel.unary_unary(_METHOD)( + _REQUEST, + timeout=test_constants.SHORT_TIMEOUT, + ), _RESPONSE) + + +if __name__ == '__main__': + logging.basicConfig() + unittest.main(verbosity=2) diff --git a/src/python/grpcio_tests/tests/unit/_empty_message_test.py b/src/python/grpcio_tests/tests/unit/_empty_message_test.py index 3e8393b53c3..f27ea422d0c 100644 --- a/src/python/grpcio_tests/tests/unit/_empty_message_test.py +++ b/src/python/grpcio_tests/tests/unit/_empty_message_test.py @@ -96,6 +96,7 @@ class EmptyMessageTest(unittest.TestCase): def tearDown(self): self._server.stop(0) + self._channel.close() def testUnaryUnary(self): response = self._channel.unary_unary(_UNARY_UNARY)(_REQUEST) diff --git a/src/python/grpcio_tests/tests/unit/_error_message_encoding_test.py b/src/python/grpcio_tests/tests/unit/_error_message_encoding_test.py index 6c551df3ec4..81de1dae1d1 100644 --- a/src/python/grpcio_tests/tests/unit/_error_message_encoding_test.py +++ b/src/python/grpcio_tests/tests/unit/_error_message_encoding_test.py @@ -71,6 +71,7 @@ class ErrorMessageEncodingTest(unittest.TestCase): def tearDown(self): self._server.stop(0) + self._channel.close() def testMessageEncoding(self): for message in _UNICODE_ERROR_MESSAGES: diff --git a/src/python/grpcio_tests/tests/unit/_exit_scenarios.py b/src/python/grpcio_tests/tests/unit/_exit_scenarios.py index f489db12cb3..d1263c2c56c 100644 --- a/src/python/grpcio_tests/tests/unit/_exit_scenarios.py +++ b/src/python/grpcio_tests/tests/unit/_exit_scenarios.py @@ -87,7 +87,7 @@ def hang_stream_stream(request_iterator, servicer_context): def hang_partial_stream_stream(request_iterator, servicer_context): for _ in range(test_constants.STREAM_LENGTH // 2): - yield next(request_iterator) + yield next(request_iterator) #pylint: disable=stop-iteration-return time.sleep(WAIT_TIME) diff --git a/src/python/grpcio_tests/tests/unit/_exit_test.py b/src/python/grpcio_tests/tests/unit/_exit_test.py index 52265375799..b429ee089f7 100644 --- a/src/python/grpcio_tests/tests/unit/_exit_test.py +++ b/src/python/grpcio_tests/tests/unit/_exit_test.py @@ -71,7 +71,6 @@ def wait(process): process.wait() -@unittest.skip('https://github.com/grpc/grpc/issues/7311') class ExitTest(unittest.TestCase): def test_unstarted_server(self): @@ -130,6 +129,8 @@ class ExitTest(unittest.TestCase): stderr=sys.stderr) interrupt_and_wait(process) + @unittest.skipIf(os.name == 'nt', + 'os.kill does not have required permission on Windows') def test_in_flight_unary_unary_call(self): process = subprocess.Popen( BASE_COMMAND + [_exit_scenarios.IN_FLIGHT_UNARY_UNARY_CALL], @@ -138,6 +139,8 @@ class ExitTest(unittest.TestCase): interrupt_and_wait(process) @unittest.skipIf(six.PY2, 'https://github.com/grpc/grpc/issues/6999') + @unittest.skipIf(os.name == 'nt', + 'os.kill does not have required permission on Windows') def test_in_flight_unary_stream_call(self): process = subprocess.Popen( BASE_COMMAND + [_exit_scenarios.IN_FLIGHT_UNARY_STREAM_CALL], @@ -145,6 +148,8 @@ class ExitTest(unittest.TestCase): stderr=sys.stderr) interrupt_and_wait(process) + @unittest.skipIf(os.name == 'nt', + 'os.kill does not have required permission on Windows') def test_in_flight_stream_unary_call(self): process = subprocess.Popen( BASE_COMMAND + [_exit_scenarios.IN_FLIGHT_STREAM_UNARY_CALL], @@ -153,6 +158,8 @@ class ExitTest(unittest.TestCase): interrupt_and_wait(process) @unittest.skipIf(six.PY2, 'https://github.com/grpc/grpc/issues/6999') + @unittest.skipIf(os.name == 'nt', + 'os.kill does not have required permission on Windows') def test_in_flight_stream_stream_call(self): process = subprocess.Popen( BASE_COMMAND + [_exit_scenarios.IN_FLIGHT_STREAM_STREAM_CALL], @@ -161,6 +168,8 @@ class ExitTest(unittest.TestCase): interrupt_and_wait(process) @unittest.skipIf(six.PY2, 'https://github.com/grpc/grpc/issues/6999') + @unittest.skipIf(os.name == 'nt', + 'os.kill does not have required permission on Windows') def test_in_flight_partial_unary_stream_call(self): process = subprocess.Popen( BASE_COMMAND + @@ -169,6 +178,8 @@ class ExitTest(unittest.TestCase): stderr=sys.stderr) interrupt_and_wait(process) + @unittest.skipIf(os.name == 'nt', + 'os.kill does not have required permission on Windows') def test_in_flight_partial_stream_unary_call(self): process = subprocess.Popen( BASE_COMMAND + @@ -178,6 +189,8 @@ class ExitTest(unittest.TestCase): interrupt_and_wait(process) @unittest.skipIf(six.PY2, 'https://github.com/grpc/grpc/issues/6999') + @unittest.skipIf(os.name == 'nt', + 'os.kill does not have required permission on Windows') def test_in_flight_partial_stream_stream_call(self): process = subprocess.Popen( BASE_COMMAND + 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 ad847ae03eb..1ada25382de 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 * # pylint: disable=wildcard-import +from grpc import * # pylint: disable=wildcard-import,unused-wildcard-import _AFTER_IMPORT = tuple(globals()) diff --git a/src/python/grpcio_tests/tests/unit/_interceptor_test.py b/src/python/grpcio_tests/tests/unit/_interceptor_test.py index 99db0ac58b1..a647e5e720c 100644 --- a/src/python/grpcio_tests/tests/unit/_interceptor_test.py +++ b/src/python/grpcio_tests/tests/unit/_interceptor_test.py @@ -337,6 +337,7 @@ class InterceptorTest(unittest.TestCase): def tearDown(self): self._server.stop(None) self._server_pool.shutdown(wait=True) + self._channel.close() def testTripleRequestMessagesClientInterceptor(self): 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 9771764635c..7ed7c838936 100644 --- a/src/python/grpcio_tests/tests/unit/_invalid_metadata_test.py +++ b/src/python/grpcio_tests/tests/unit/_invalid_metadata_test.py @@ -62,6 +62,9 @@ class InvalidMetadataTest(unittest.TestCase): self._stream_unary = _stream_unary_multi_callable(self._channel) self._stream_stream = _stream_stream_multi_callable(self._channel) + def tearDown(self): + self._channel.close() + def testUnaryRequestBlockingUnaryResponse(self): request = b'\x07\x08' metadata = (('InVaLiD', 'UnaryRequestBlockingUnaryResponse'),) @@ -130,6 +133,9 @@ class InvalidMetadataTest(unittest.TestCase): self._stream_stream(request_iterator, metadata=metadata) self.assertIn(expected_error_details, str(exception_context.exception)) + def testInvalidMetadata(self): + self.assertRaises(TypeError, self._unary_unary, b'', metadata=42) + if __name__ == '__main__': logging.basicConfig() 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 00949e22366..e89b521cc5c 100644 --- a/src/python/grpcio_tests/tests/unit/_invocation_defects_test.py +++ b/src/python/grpcio_tests/tests/unit/_invocation_defects_test.py @@ -215,6 +215,7 @@ class InvocationDefectsTest(unittest.TestCase): def tearDown(self): self._server.stop(0) + self._channel.close() def testIterableStreamRequestBlockingUnaryResponse(self): requests = [b'\x07\x08' for _ in range(test_constants.STREAM_LENGTH)] diff --git a/src/python/grpcio_tests/tests/unit/_logging_test.py b/src/python/grpcio_tests/tests/unit/_logging_test.py index 631b9de9db5..8ff127f5062 100644 --- a/src/python/grpcio_tests/tests/unit/_logging_test.py +++ b/src/python/grpcio_tests/tests/unit/_logging_test.py @@ -14,66 +14,86 @@ """Test of gRPC Python's interaction with the python logging module""" import unittest -import six -from six.moves import reload_module import logging import grpc -import functools +import subprocess import sys - -def patch_stderr(f): - - @functools.wraps(f) - def _impl(*args, **kwargs): - old_stderr = sys.stderr - sys.stderr = six.StringIO() - try: - f(*args, **kwargs) - finally: - sys.stderr = old_stderr - - return _impl - - -def isolated_logging(f): - - @functools.wraps(f) - def _impl(*args, **kwargs): - reload_module(logging) - reload_module(grpc) - try: - f(*args, **kwargs) - finally: - reload_module(logging) - - return _impl +INTERPRETER = sys.executable class LoggingTest(unittest.TestCase): - @isolated_logging def test_logger_not_occupied(self): - self.assertEqual(0, len(logging.getLogger().handlers)) + script = """if True: + import logging + + import grpc + + if len(logging.getLogger().handlers) != 0: + raise Exception('expected 0 logging handlers') + + """ + self._verifyScriptSucceeds(script) - @patch_stderr - @isolated_logging def test_handler_found(self): - self.assertEqual(0, len(sys.stderr.getvalue())) + script = """if True: + import logging + + import grpc + """ + out, err = self._verifyScriptSucceeds(script) + self.assertEqual(0, len(err), 'unexpected output to stderr') - @isolated_logging def test_can_configure_logger(self): - intended_stream = six.StringIO() - logging.basicConfig(stream=intended_stream) - self.assertEqual(1, len(logging.getLogger().handlers)) - self.assertIs(logging.getLogger().handlers[0].stream, intended_stream) + script = """if True: + import logging + import six + + import grpc + + + intended_stream = six.StringIO() + logging.basicConfig(stream=intended_stream) + + if len(logging.getLogger().handlers) != 1: + raise Exception('expected 1 logging handler') + + if logging.getLogger().handlers[0].stream is not intended_stream: + raise Exception('wrong handler stream') + + """ + self._verifyScriptSucceeds(script) - @isolated_logging def test_grpc_logger(self): - self.assertIn("grpc", logging.Logger.manager.loggerDict) - root_logger = logging.getLogger("grpc") - self.assertEqual(1, len(root_logger.handlers)) - self.assertIsInstance(root_logger.handlers[0], logging.NullHandler) + script = """if True: + import logging + + import grpc + + if "grpc" not in logging.Logger.manager.loggerDict: + raise Exception('grpc logger not found') + + root_logger = logging.getLogger("grpc") + if len(root_logger.handlers) != 1: + raise Exception('expected 1 root logger handler') + if not isinstance(root_logger.handlers[0], logging.NullHandler): + raise Exception('expected logging.NullHandler') + + """ + self._verifyScriptSucceeds(script) + + def _verifyScriptSucceeds(self, script): + process = subprocess.Popen( + [INTERPRETER, '-c', script], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + out, err = process.communicate() + self.assertEqual( + 0, process.returncode, + 'process failed with exit code %d (stdout: %s, stderr: %s)' % + (process.returncode, out, err)) + return out, err if __name__ == '__main__': diff --git a/src/python/grpcio_tests/tests/unit/_metadata_code_details_test.py b/src/python/grpcio_tests/tests/unit/_metadata_code_details_test.py index 0dafab827a8..a63664ac5d0 100644 --- a/src/python/grpcio_tests/tests/unit/_metadata_code_details_test.py +++ b/src/python/grpcio_tests/tests/unit/_metadata_code_details_test.py @@ -198,8 +198,8 @@ class MetadataCodeDetailsTest(unittest.TestCase): port = self._server.add_insecure_port('[::]:0') self._server.start() - channel = grpc.insecure_channel('localhost:{}'.format(port)) - self._unary_unary = channel.unary_unary( + self._channel = grpc.insecure_channel('localhost:{}'.format(port)) + self._unary_unary = self._channel.unary_unary( '/'.join(( '', _SERVICE, @@ -208,17 +208,17 @@ class MetadataCodeDetailsTest(unittest.TestCase): request_serializer=_REQUEST_SERIALIZER, response_deserializer=_RESPONSE_DESERIALIZER, ) - self._unary_stream = channel.unary_stream('/'.join(( + self._unary_stream = self._channel.unary_stream('/'.join(( '', _SERVICE, _UNARY_STREAM, )),) - self._stream_unary = channel.stream_unary('/'.join(( + self._stream_unary = self._channel.stream_unary('/'.join(( '', _SERVICE, _STREAM_UNARY, )),) - self._stream_stream = channel.stream_stream( + self._stream_stream = self._channel.stream_stream( '/'.join(( '', _SERVICE, @@ -228,6 +228,10 @@ class MetadataCodeDetailsTest(unittest.TestCase): response_deserializer=_RESPONSE_DESERIALIZER, ) + def tearDown(self): + self._server.stop(None) + self._channel.close() + def testSuccessfulUnaryUnary(self): self._servicer.set_details(_DETAILS) diff --git a/src/python/grpcio_tests/tests/unit/_metadata_flags_test.py b/src/python/grpcio_tests/tests/unit/_metadata_flags_test.py index 2d352e99d4a..7b32b5b5f3e 100644 --- a/src/python/grpcio_tests/tests/unit/_metadata_flags_test.py +++ b/src/python/grpcio_tests/tests/unit/_metadata_flags_test.py @@ -187,13 +187,14 @@ class MetadataFlagsTest(unittest.TestCase): def test_call_wait_for_ready_default(self): for perform_call in _ALL_CALL_CASES: - self.check_connection_does_failfast(perform_call, - create_dummy_channel()) + with create_dummy_channel() as channel: + self.check_connection_does_failfast(perform_call, channel) def test_call_wait_for_ready_disabled(self): for perform_call in _ALL_CALL_CASES: - self.check_connection_does_failfast( - perform_call, create_dummy_channel(), wait_for_ready=False) + with create_dummy_channel() as channel: + self.check_connection_does_failfast( + perform_call, channel, wait_for_ready=False) def test_call_wait_for_ready_enabled(self): # To test the wait mechanism, Python thread is required to make @@ -210,16 +211,16 @@ class MetadataFlagsTest(unittest.TestCase): wg.done() def test_call(perform_call): - try: - channel = grpc.insecure_channel(addr) - channel.subscribe(wait_for_transient_failure) - perform_call(channel, wait_for_ready=True) - except BaseException as e: # pylint: disable=broad-except - # If the call failed, the thread would be destroyed. The channel - # object can be collected before calling the callback, which - # will result in a deadlock. - wg.done() - unhandled_exceptions.put(e, True) + with grpc.insecure_channel(addr) as channel: + try: + channel.subscribe(wait_for_transient_failure) + perform_call(channel, wait_for_ready=True) + except BaseException as e: # pylint: disable=broad-except + # If the call failed, the thread would be destroyed. The + # channel object can be collected before calling the + # callback, which will result in a deadlock. + wg.done() + unhandled_exceptions.put(e, True) test_threads = [] for perform_call in _ALL_CALL_CASES: diff --git a/src/python/grpcio_tests/tests/unit/_metadata_test.py b/src/python/grpcio_tests/tests/unit/_metadata_test.py index 777ab683e36..892df3df08f 100644 --- a/src/python/grpcio_tests/tests/unit/_metadata_test.py +++ b/src/python/grpcio_tests/tests/unit/_metadata_test.py @@ -186,6 +186,7 @@ class MetadataTest(unittest.TestCase): def tearDown(self): self._server.stop(0) + self._channel.close() def testUnaryUnary(self): multi_callable = self._channel.unary_unary(_UNARY_UNARY) diff --git a/src/python/grpcio_tests/tests/unit/_reconnect_test.py b/src/python/grpcio_tests/tests/unit/_reconnect_test.py index f6d4fcbd0a5..d4ea126e2b5 100644 --- a/src/python/grpcio_tests/tests/unit/_reconnect_test.py +++ b/src/python/grpcio_tests/tests/unit/_reconnect_test.py @@ -98,6 +98,8 @@ class ReconnectTest(unittest.TestCase): server.add_insecure_port('[::]:{}'.format(port)) server.start() self.assertEqual(_RESPONSE, multi_callable(_REQUEST)) + server.stop(None) + channel.close() if __name__ == '__main__': diff --git a/src/python/grpcio_tests/tests/unit/_resource_exhausted_test.py b/src/python/grpcio_tests/tests/unit/_resource_exhausted_test.py index 4fead8fcd54..ecd2ccadbde 100644 --- a/src/python/grpcio_tests/tests/unit/_resource_exhausted_test.py +++ b/src/python/grpcio_tests/tests/unit/_resource_exhausted_test.py @@ -42,7 +42,7 @@ class _TestTrigger(object): self._finish_condition = threading.Condition() self._start_condition = threading.Condition() - # Wait for all calls be be blocked in their handler + # Wait for all calls be blocked in their handler def await_calls(self): with self._start_condition: while self._pending_calls < self._total_call_count: @@ -148,6 +148,7 @@ class ResourceExhaustedTest(unittest.TestCase): def tearDown(self): self._server.stop(0) + self._channel.close() def testUnaryUnary(self): multi_callable = self._channel.unary_unary(_UNARY_UNARY) diff --git a/src/python/grpcio_tests/tests/unit/_rpc_test.py b/src/python/grpcio_tests/tests/unit/_rpc_test.py index a768d6c7c1c..3f3f87adf9c 100644 --- a/src/python/grpcio_tests/tests/unit/_rpc_test.py +++ b/src/python/grpcio_tests/tests/unit/_rpc_test.py @@ -23,6 +23,7 @@ import grpc from grpc.framework.foundation import logging_pool from tests.unit import test_common +from tests.unit import thread_pool from tests.unit.framework.common import test_constants from tests.unit.framework.common import test_control @@ -33,8 +34,10 @@ _DESERIALIZE_RESPONSE = lambda bytestring: bytestring[:len(bytestring) // 3] _UNARY_UNARY = '/test/UnaryUnary' _UNARY_STREAM = '/test/UnaryStream' +_UNARY_STREAM_NON_BLOCKING = '/test/UnaryStreamNonBlocking' _STREAM_UNARY = '/test/StreamUnary' _STREAM_STREAM = '/test/StreamStream' +_STREAM_STREAM_NON_BLOCKING = '/test/StreamStreamNonBlocking' class _Callback(object): @@ -59,8 +62,14 @@ class _Callback(object): class _Handler(object): - def __init__(self, control): + def __init__(self, control, thread_pool): self._control = control + self._thread_pool = thread_pool + non_blocking_functions = (self.handle_unary_stream_non_blocking, + self.handle_stream_stream_non_blocking) + for non_blocking_function in non_blocking_functions: + non_blocking_function.__func__.experimental_non_blocking = True + non_blocking_function.__func__.experimental_thread_pool = self._thread_pool def handle_unary_unary(self, request, servicer_context): self._control.control() @@ -87,6 +96,19 @@ class _Handler(object): 'testvalue', ),)) + def handle_unary_stream_non_blocking(self, request, servicer_context, + on_next): + for _ in range(test_constants.STREAM_LENGTH): + self._control.control() + on_next(request) + self._control.control() + if servicer_context is not None: + servicer_context.set_trailing_metadata((( + 'testkey', + 'testvalue', + ),)) + on_next(None) + def handle_stream_unary(self, request_iterator, servicer_context): if servicer_context is not None: servicer_context.invocation_metadata() @@ -115,6 +137,20 @@ class _Handler(object): yield request self._control.control() + def handle_stream_stream_non_blocking(self, request_iterator, + servicer_context, on_next): + self._control.control() + if servicer_context is not None: + servicer_context.set_trailing_metadata((( + 'testkey', + 'testvalue', + ),)) + for request in request_iterator: + self._control.control() + on_next(request) + self._control.control() + on_next(None) + class _MethodHandler(grpc.RpcMethodHandler): @@ -145,6 +181,10 @@ class _GenericHandler(grpc.GenericRpcHandler): return _MethodHandler(False, True, _DESERIALIZE_REQUEST, _SERIALIZE_RESPONSE, None, self._handler.handle_unary_stream, None, None) + elif handler_call_details.method == _UNARY_STREAM_NON_BLOCKING: + return _MethodHandler( + False, True, _DESERIALIZE_REQUEST, _SERIALIZE_RESPONSE, None, + self._handler.handle_unary_stream_non_blocking, None, None) elif handler_call_details.method == _STREAM_UNARY: return _MethodHandler(True, False, _DESERIALIZE_REQUEST, _SERIALIZE_RESPONSE, None, None, @@ -152,6 +192,10 @@ class _GenericHandler(grpc.GenericRpcHandler): elif handler_call_details.method == _STREAM_STREAM: return _MethodHandler(True, True, None, None, None, None, None, self._handler.handle_stream_stream) + elif handler_call_details.method == _STREAM_STREAM_NON_BLOCKING: + return _MethodHandler( + True, True, None, None, None, None, None, + self._handler.handle_stream_stream_non_blocking) else: return None @@ -167,6 +211,13 @@ def _unary_stream_multi_callable(channel): response_deserializer=_DESERIALIZE_RESPONSE) +def _unary_stream_non_blocking_multi_callable(channel): + return channel.unary_stream( + _UNARY_STREAM_NON_BLOCKING, + request_serializer=_SERIALIZE_REQUEST, + response_deserializer=_DESERIALIZE_RESPONSE) + + def _stream_unary_multi_callable(channel): return channel.stream_unary( _STREAM_UNARY, @@ -178,11 +229,16 @@ def _stream_stream_multi_callable(channel): return channel.stream_stream(_STREAM_STREAM) +def _stream_stream_non_blocking_multi_callable(channel): + return channel.stream_stream(_STREAM_STREAM_NON_BLOCKING) + + class RPCTest(unittest.TestCase): def setUp(self): self._control = test_control.PauseFailControl() - self._handler = _Handler(self._control) + self._thread_pool = thread_pool.RecordingThreadPool(max_workers=None) + self._handler = _Handler(self._control, self._thread_pool) self._server = test_common.test_server() port = self._server.add_insecure_port('[::]:0') @@ -193,6 +249,17 @@ class RPCTest(unittest.TestCase): def tearDown(self): self._server.stop(None) + self._channel.close() + + def testDefaultThreadPoolIsUsed(self): + self._consume_one_stream_response_unary_request( + _unary_stream_multi_callable(self._channel)) + self.assertFalse(self._thread_pool.was_used()) + + def testExperimentalThreadPoolIsUsed(self): + self._consume_one_stream_response_unary_request( + _unary_stream_non_blocking_multi_callable(self._channel)) + self.assertTrue(self._thread_pool.was_used()) def testUnrecognizedMethod(self): request = b'abc' @@ -226,7 +293,7 @@ class RPCTest(unittest.TestCase): self.assertEqual(expected_response, response) self.assertIs(grpc.StatusCode.OK, call.code()) - self.assertEqual("", call.debug_error_string()) + self.assertEqual('', call.debug_error_string()) def testSuccessfulUnaryRequestFutureUnaryResponse(self): request = b'\x07\x08' @@ -309,6 +376,7 @@ class RPCTest(unittest.TestCase): def testSuccessfulStreamRequestStreamResponse(self): requests = tuple( b'\x77\x58' for _ in range(test_constants.STREAM_LENGTH)) + expected_responses = tuple( self._handler.handle_stream_stream(iter(requests), None)) request_iterator = iter(requests) @@ -424,58 +492,36 @@ class RPCTest(unittest.TestCase): test_is_running_cell[0] = False def testConsumingOneStreamResponseUnaryRequest(self): - request = b'\x57\x38' + self._consume_one_stream_response_unary_request( + _unary_stream_multi_callable(self._channel)) - multi_callable = _unary_stream_multi_callable(self._channel) - response_iterator = multi_callable( - request, - metadata=(('test', 'ConsumingOneStreamResponseUnaryRequest'),)) - next(response_iterator) + def testConsumingOneStreamResponseUnaryRequestNonBlocking(self): + self._consume_one_stream_response_unary_request( + _unary_stream_non_blocking_multi_callable(self._channel)) def testConsumingSomeButNotAllStreamResponsesUnaryRequest(self): - request = b'\x57\x38' + self._consume_some_but_not_all_stream_responses_unary_request( + _unary_stream_multi_callable(self._channel)) - multi_callable = _unary_stream_multi_callable(self._channel) - response_iterator = multi_callable( - request, - metadata=(('test', - 'ConsumingSomeButNotAllStreamResponsesUnaryRequest'),)) - for _ in range(test_constants.STREAM_LENGTH // 2): - next(response_iterator) + def testConsumingSomeButNotAllStreamResponsesUnaryRequestNonBlocking(self): + self._consume_some_but_not_all_stream_responses_unary_request( + _unary_stream_non_blocking_multi_callable(self._channel)) def testConsumingSomeButNotAllStreamResponsesStreamRequest(self): - requests = tuple( - b'\x67\x88' for _ in range(test_constants.STREAM_LENGTH)) - request_iterator = iter(requests) + self._consume_some_but_not_all_stream_responses_stream_request( + _stream_stream_multi_callable(self._channel)) - multi_callable = _stream_stream_multi_callable(self._channel) - response_iterator = multi_callable( - request_iterator, - metadata=(('test', - 'ConsumingSomeButNotAllStreamResponsesStreamRequest'),)) - for _ in range(test_constants.STREAM_LENGTH // 2): - next(response_iterator) + def testConsumingSomeButNotAllStreamResponsesStreamRequestNonBlocking(self): + self._consume_some_but_not_all_stream_responses_stream_request( + _stream_stream_non_blocking_multi_callable(self._channel)) def testConsumingTooManyStreamResponsesStreamRequest(self): - requests = tuple( - b'\x67\x88' for _ in range(test_constants.STREAM_LENGTH)) - request_iterator = iter(requests) + self._consume_too_many_stream_responses_stream_request( + _stream_stream_multi_callable(self._channel)) - multi_callable = _stream_stream_multi_callable(self._channel) - response_iterator = multi_callable( - request_iterator, - metadata=(('test', - 'ConsumingTooManyStreamResponsesStreamRequest'),)) - for _ in range(test_constants.STREAM_LENGTH): - next(response_iterator) - for _ in range(test_constants.STREAM_LENGTH): - with self.assertRaises(StopIteration): - next(response_iterator) - - self.assertIsNotNone(response_iterator.initial_metadata()) - self.assertIs(grpc.StatusCode.OK, response_iterator.code()) - self.assertIsNotNone(response_iterator.details()) - self.assertIsNotNone(response_iterator.trailing_metadata()) + def testConsumingTooManyStreamResponsesStreamRequestNonBlocking(self): + self._consume_too_many_stream_responses_stream_request( + _stream_stream_non_blocking_multi_callable(self._channel)) def testCancelledUnaryRequestUnaryResponse(self): request = b'\x07\x17' @@ -497,24 +543,12 @@ class RPCTest(unittest.TestCase): self.assertIs(grpc.StatusCode.CANCELLED, response_future.code()) def testCancelledUnaryRequestStreamResponse(self): - request = b'\x07\x19' + self._cancelled_unary_request_stream_response( + _unary_stream_multi_callable(self._channel)) - multi_callable = _unary_stream_multi_callable(self._channel) - with self._control.pause(): - response_iterator = multi_callable( - request, - metadata=(('test', 'CancelledUnaryRequestStreamResponse'),)) - self._control.block_until_paused() - response_iterator.cancel() - - with self.assertRaises(grpc.RpcError) as exception_context: - next(response_iterator) - self.assertIs(grpc.StatusCode.CANCELLED, - exception_context.exception.code()) - self.assertIsNotNone(response_iterator.initial_metadata()) - self.assertIs(grpc.StatusCode.CANCELLED, response_iterator.code()) - self.assertIsNotNone(response_iterator.details()) - self.assertIsNotNone(response_iterator.trailing_metadata()) + def testCancelledUnaryRequestStreamResponseNonBlocking(self): + self._cancelled_unary_request_stream_response( + _unary_stream_non_blocking_multi_callable(self._channel)) def testCancelledStreamRequestUnaryResponse(self): requests = tuple( @@ -542,23 +576,12 @@ class RPCTest(unittest.TestCase): self.assertIsNotNone(response_future.trailing_metadata()) def testCancelledStreamRequestStreamResponse(self): - requests = tuple( - b'\x07\x08' for _ in range(test_constants.STREAM_LENGTH)) - request_iterator = iter(requests) + self._cancelled_stream_request_stream_response( + _stream_stream_multi_callable(self._channel)) - multi_callable = _stream_stream_multi_callable(self._channel) - with self._control.pause(): - response_iterator = multi_callable( - request_iterator, - metadata=(('test', 'CancelledStreamRequestStreamResponse'),)) - response_iterator.cancel() - - with self.assertRaises(grpc.RpcError): - next(response_iterator) - self.assertIsNotNone(response_iterator.initial_metadata()) - self.assertIs(grpc.StatusCode.CANCELLED, response_iterator.code()) - self.assertIsNotNone(response_iterator.details()) - self.assertIsNotNone(response_iterator.trailing_metadata()) + def testCancelledStreamRequestStreamResponseNonBlocking(self): + self._cancelled_stream_request_stream_response( + _stream_stream_non_blocking_multi_callable(self._channel)) def testExpiredUnaryRequestBlockingUnaryResponse(self): request = b'\x07\x17' @@ -607,21 +630,12 @@ class RPCTest(unittest.TestCase): response_future.exception().code()) def testExpiredUnaryRequestStreamResponse(self): - request = b'\x07\x19' + self._expired_unary_request_stream_response( + _unary_stream_multi_callable(self._channel)) - multi_callable = _unary_stream_multi_callable(self._channel) - with self._control.pause(): - with self.assertRaises(grpc.RpcError) as exception_context: - response_iterator = multi_callable( - request, - timeout=test_constants.SHORT_TIMEOUT, - metadata=(('test', 'ExpiredUnaryRequestStreamResponse'),)) - next(response_iterator) - - self.assertIs(grpc.StatusCode.DEADLINE_EXCEEDED, - exception_context.exception.code()) - self.assertIs(grpc.StatusCode.DEADLINE_EXCEEDED, - response_iterator.code()) + def testExpiredUnaryRequestStreamResponseNonBlocking(self): + self._expired_unary_request_stream_response( + _unary_stream_non_blocking_multi_callable(self._channel)) def testExpiredStreamRequestBlockingUnaryResponse(self): requests = tuple( @@ -677,23 +691,12 @@ class RPCTest(unittest.TestCase): self.assertIsNotNone(response_future.trailing_metadata()) def testExpiredStreamRequestStreamResponse(self): - requests = tuple( - b'\x67\x18' for _ in range(test_constants.STREAM_LENGTH)) - request_iterator = iter(requests) + self._expired_stream_request_stream_response( + _stream_stream_multi_callable(self._channel)) - multi_callable = _stream_stream_multi_callable(self._channel) - with self._control.pause(): - with self.assertRaises(grpc.RpcError) as exception_context: - response_iterator = multi_callable( - request_iterator, - timeout=test_constants.SHORT_TIMEOUT, - metadata=(('test', 'ExpiredStreamRequestStreamResponse'),)) - next(response_iterator) - - self.assertIs(grpc.StatusCode.DEADLINE_EXCEEDED, - exception_context.exception.code()) - self.assertIs(grpc.StatusCode.DEADLINE_EXCEEDED, - response_iterator.code()) + def testExpiredStreamRequestStreamResponseNonBlocking(self): + self._expired_stream_request_stream_response( + _stream_stream_non_blocking_multi_callable(self._channel)) def testFailedUnaryRequestBlockingUnaryResponse(self): request = b'\x37\x17' @@ -711,10 +714,10 @@ class RPCTest(unittest.TestCase): # sanity checks on to make sure returned string contains default members # of the error debug_error_string = exception_context.exception.debug_error_string() - self.assertIn("created", debug_error_string) - self.assertIn("description", debug_error_string) - self.assertIn("file", debug_error_string) - self.assertIn("file_line", debug_error_string) + self.assertIn('created', debug_error_string) + self.assertIn('description', debug_error_string) + self.assertIn('file', debug_error_string) + self.assertIn('file_line', debug_error_string) def testFailedUnaryRequestFutureUnaryResponse(self): request = b'\x37\x17' @@ -741,18 +744,12 @@ class RPCTest(unittest.TestCase): self.assertIs(response_future, value_passed_to_callback) def testFailedUnaryRequestStreamResponse(self): - request = b'\x37\x17' + self._failed_unary_request_stream_response( + _unary_stream_multi_callable(self._channel)) - multi_callable = _unary_stream_multi_callable(self._channel) - with self.assertRaises(grpc.RpcError) as exception_context: - with self._control.fail(): - response_iterator = multi_callable( - request, - metadata=(('test', 'FailedUnaryRequestStreamResponse'),)) - next(response_iterator) - - self.assertIs(grpc.StatusCode.UNKNOWN, - exception_context.exception.code()) + def testFailedUnaryRequestStreamResponseNonBlocking(self): + self._failed_unary_request_stream_response( + _unary_stream_non_blocking_multi_callable(self._channel)) def testFailedStreamRequestBlockingUnaryResponse(self): requests = tuple( @@ -794,21 +791,12 @@ class RPCTest(unittest.TestCase): self.assertIs(response_future, value_passed_to_callback) def testFailedStreamRequestStreamResponse(self): - requests = tuple( - b'\x67\x88' for _ in range(test_constants.STREAM_LENGTH)) - request_iterator = iter(requests) + self._failed_stream_request_stream_response( + _stream_stream_multi_callable(self._channel)) - multi_callable = _stream_stream_multi_callable(self._channel) - with self._control.fail(): - with self.assertRaises(grpc.RpcError) as exception_context: - response_iterator = multi_callable( - request_iterator, - metadata=(('test', 'FailedStreamRequestStreamResponse'),)) - tuple(response_iterator) - - self.assertIs(grpc.StatusCode.UNKNOWN, - exception_context.exception.code()) - self.assertIs(grpc.StatusCode.UNKNOWN, response_iterator.code()) + def testFailedStreamRequestStreamResponseNonBlocking(self): + self._failed_stream_request_stream_response( + _stream_stream_non_blocking_multi_callable(self._channel)) def testIgnoredUnaryRequestFutureUnaryResponse(self): request = b'\x37\x17' @@ -819,11 +807,12 @@ class RPCTest(unittest.TestCase): metadata=(('test', 'IgnoredUnaryRequestFutureUnaryResponse'),)) def testIgnoredUnaryRequestStreamResponse(self): - request = b'\x37\x17' + self._ignored_unary_stream_request_future_unary_response( + _unary_stream_multi_callable(self._channel)) - multi_callable = _unary_stream_multi_callable(self._channel) - multi_callable( - request, metadata=(('test', 'IgnoredUnaryRequestStreamResponse'),)) + def testIgnoredUnaryRequestStreamResponseNonBlocking(self): + self._ignored_unary_stream_request_future_unary_response( + _unary_stream_non_blocking_multi_callable(self._channel)) def testIgnoredStreamRequestFutureUnaryResponse(self): requests = tuple( @@ -836,11 +825,177 @@ class RPCTest(unittest.TestCase): metadata=(('test', 'IgnoredStreamRequestFutureUnaryResponse'),)) def testIgnoredStreamRequestStreamResponse(self): + self._ignored_stream_request_stream_response( + _stream_stream_multi_callable(self._channel)) + + def testIgnoredStreamRequestStreamResponseNonBlocking(self): + self._ignored_stream_request_stream_response( + _stream_stream_non_blocking_multi_callable(self._channel)) + + def _consume_one_stream_response_unary_request(self, multi_callable): + request = b'\x57\x38' + + response_iterator = multi_callable( + request, + metadata=(('test', 'ConsumingOneStreamResponseUnaryRequest'),)) + next(response_iterator) + + def _consume_some_but_not_all_stream_responses_unary_request( + self, multi_callable): + request = b'\x57\x38' + + response_iterator = multi_callable( + request, + metadata=(('test', + 'ConsumingSomeButNotAllStreamResponsesUnaryRequest'),)) + for _ in range(test_constants.STREAM_LENGTH // 2): + next(response_iterator) + + def _consume_some_but_not_all_stream_responses_stream_request( + self, multi_callable): + requests = tuple( + b'\x67\x88' for _ in range(test_constants.STREAM_LENGTH)) + request_iterator = iter(requests) + + response_iterator = multi_callable( + request_iterator, + metadata=(('test', + 'ConsumingSomeButNotAllStreamResponsesStreamRequest'),)) + for _ in range(test_constants.STREAM_LENGTH // 2): + next(response_iterator) + + def _consume_too_many_stream_responses_stream_request(self, multi_callable): + requests = tuple( + b'\x67\x88' for _ in range(test_constants.STREAM_LENGTH)) + request_iterator = iter(requests) + + response_iterator = multi_callable( + request_iterator, + metadata=(('test', + 'ConsumingTooManyStreamResponsesStreamRequest'),)) + for _ in range(test_constants.STREAM_LENGTH): + next(response_iterator) + for _ in range(test_constants.STREAM_LENGTH): + with self.assertRaises(StopIteration): + next(response_iterator) + + self.assertIsNotNone(response_iterator.initial_metadata()) + self.assertIs(grpc.StatusCode.OK, response_iterator.code()) + self.assertIsNotNone(response_iterator.details()) + self.assertIsNotNone(response_iterator.trailing_metadata()) + + def _cancelled_unary_request_stream_response(self, multi_callable): + request = b'\x07\x19' + + with self._control.pause(): + response_iterator = multi_callable( + request, + metadata=(('test', 'CancelledUnaryRequestStreamResponse'),)) + self._control.block_until_paused() + response_iterator.cancel() + + with self.assertRaises(grpc.RpcError) as exception_context: + next(response_iterator) + self.assertIs(grpc.StatusCode.CANCELLED, + exception_context.exception.code()) + self.assertIsNotNone(response_iterator.initial_metadata()) + self.assertIs(grpc.StatusCode.CANCELLED, response_iterator.code()) + self.assertIsNotNone(response_iterator.details()) + self.assertIsNotNone(response_iterator.trailing_metadata()) + + def _cancelled_stream_request_stream_response(self, multi_callable): + requests = tuple( + b'\x07\x08' for _ in range(test_constants.STREAM_LENGTH)) + request_iterator = iter(requests) + + with self._control.pause(): + response_iterator = multi_callable( + request_iterator, + metadata=(('test', 'CancelledStreamRequestStreamResponse'),)) + response_iterator.cancel() + + with self.assertRaises(grpc.RpcError): + next(response_iterator) + self.assertIsNotNone(response_iterator.initial_metadata()) + self.assertIs(grpc.StatusCode.CANCELLED, response_iterator.code()) + self.assertIsNotNone(response_iterator.details()) + self.assertIsNotNone(response_iterator.trailing_metadata()) + + def _expired_unary_request_stream_response(self, multi_callable): + request = b'\x07\x19' + + with self._control.pause(): + with self.assertRaises(grpc.RpcError) as exception_context: + response_iterator = multi_callable( + request, + timeout=test_constants.SHORT_TIMEOUT, + metadata=(('test', 'ExpiredUnaryRequestStreamResponse'),)) + next(response_iterator) + + self.assertIs(grpc.StatusCode.DEADLINE_EXCEEDED, + exception_context.exception.code()) + self.assertIs(grpc.StatusCode.DEADLINE_EXCEEDED, + response_iterator.code()) + + def _expired_stream_request_stream_response(self, multi_callable): + requests = tuple( + b'\x67\x18' for _ in range(test_constants.STREAM_LENGTH)) + request_iterator = iter(requests) + + with self._control.pause(): + with self.assertRaises(grpc.RpcError) as exception_context: + response_iterator = multi_callable( + request_iterator, + timeout=test_constants.SHORT_TIMEOUT, + metadata=(('test', 'ExpiredStreamRequestStreamResponse'),)) + next(response_iterator) + + self.assertIs(grpc.StatusCode.DEADLINE_EXCEEDED, + exception_context.exception.code()) + self.assertIs(grpc.StatusCode.DEADLINE_EXCEEDED, + response_iterator.code()) + + def _failed_unary_request_stream_response(self, multi_callable): + request = b'\x37\x17' + + with self.assertRaises(grpc.RpcError) as exception_context: + with self._control.fail(): + response_iterator = multi_callable( + request, + metadata=(('test', 'FailedUnaryRequestStreamResponse'),)) + next(response_iterator) + + self.assertIs(grpc.StatusCode.UNKNOWN, + exception_context.exception.code()) + + def _failed_stream_request_stream_response(self, multi_callable): + requests = tuple( + b'\x67\x88' for _ in range(test_constants.STREAM_LENGTH)) + request_iterator = iter(requests) + + with self._control.fail(): + with self.assertRaises(grpc.RpcError) as exception_context: + response_iterator = multi_callable( + request_iterator, + metadata=(('test', 'FailedStreamRequestStreamResponse'),)) + tuple(response_iterator) + + self.assertIs(grpc.StatusCode.UNKNOWN, + exception_context.exception.code()) + self.assertIs(grpc.StatusCode.UNKNOWN, response_iterator.code()) + + def _ignored_unary_stream_request_future_unary_response( + self, multi_callable): + request = b'\x37\x17' + + multi_callable( + request, metadata=(('test', 'IgnoredUnaryRequestStreamResponse'),)) + + def _ignored_stream_request_stream_response(self, multi_callable): requests = tuple( b'\x67\x88' for _ in range(test_constants.STREAM_LENGTH)) request_iterator = iter(requests) - multi_callable = _stream_stream_multi_callable(self._channel) multi_callable( request_iterator, metadata=(('test', 'IgnoredStreamRequestStreamResponse'),)) diff --git a/src/python/grpcio_tests/tests/unit/_server_shutdown_scenarios.py b/src/python/grpcio_tests/tests/unit/_server_shutdown_scenarios.py new file mode 100644 index 00000000000..1d1fdba11ee --- /dev/null +++ b/src/python/grpcio_tests/tests/unit/_server_shutdown_scenarios.py @@ -0,0 +1,97 @@ +# 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. +"""Defines a number of module-scope gRPC scenarios to test server shutdown.""" + +import argparse +import os +import threading +import time +import logging + +import grpc +from tests.unit import test_common + +from concurrent import futures +from six.moves import queue + +WAIT_TIME = 1000 + +REQUEST = b'request' +RESPONSE = b'response' + +SERVER_RAISES_EXCEPTION = 'server_raises_exception' +SERVER_DEALLOCATED = 'server_deallocated' +SERVER_FORK_CAN_EXIT = 'server_fork_can_exit' + +FORK_EXIT = '/test/ForkExit' + + +def fork_and_exit(request, servicer_context): + pid = os.fork() + if pid == 0: + os._exit(0) + return RESPONSE + + +class GenericHandler(grpc.GenericRpcHandler): + + def service(self, handler_call_details): + if handler_call_details.method == FORK_EXIT: + return grpc.unary_unary_rpc_method_handler(fork_and_exit) + else: + return None + + +def run_server(port_queue): + server = test_common.test_server() + port = server.add_insecure_port('[::]:0') + port_queue.put(port) + server.add_generic_rpc_handlers((GenericHandler(),)) + server.start() + # threading.Event.wait() does not exhibit the bug identified in + # https://github.com/grpc/grpc/issues/17093, sleep instead + time.sleep(WAIT_TIME) + + +def run_test(args): + if args.scenario == SERVER_RAISES_EXCEPTION: + server = test_common.test_server() + server.start() + raise Exception() + elif args.scenario == SERVER_DEALLOCATED: + server = test_common.test_server() + server.start() + server.__del__() + while server._state.stage != grpc._server._ServerStage.STOPPED: + pass + elif args.scenario == SERVER_FORK_CAN_EXIT: + port_queue = queue.Queue() + thread = threading.Thread(target=run_server, args=(port_queue,)) + thread.daemon = True + thread.start() + port = port_queue.get() + channel = grpc.insecure_channel('localhost:%d' % port) + multi_callable = channel.unary_unary(FORK_EXIT) + result, call = multi_callable.with_call(REQUEST, wait_for_ready=True) + os.wait() + else: + raise ValueError('unknown test scenario') + + +if __name__ == '__main__': + logging.basicConfig() + parser = argparse.ArgumentParser() + parser.add_argument('scenario', type=str) + args = parser.parse_args() + run_test(args) diff --git a/src/python/grpcio_tests/tests/unit/_server_shutdown_test.py b/src/python/grpcio_tests/tests/unit/_server_shutdown_test.py new file mode 100644 index 00000000000..47446d65a51 --- /dev/null +++ b/src/python/grpcio_tests/tests/unit/_server_shutdown_test.py @@ -0,0 +1,90 @@ +# 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 clean shutdown of server on various interpreter exit conditions. + +The tests in this module spawn a subprocess for each test case, the +test is considered successful if it doesn't hang/timeout. +""" + +import atexit +import os +import subprocess +import sys +import threading +import unittest +import logging + +from tests.unit import _server_shutdown_scenarios + +SCENARIO_FILE = os.path.abspath( + os.path.join( + os.path.dirname(os.path.realpath(__file__)), + '_server_shutdown_scenarios.py')) +INTERPRETER = sys.executable +BASE_COMMAND = [INTERPRETER, SCENARIO_FILE] + +processes = [] +process_lock = threading.Lock() + + +# Make sure we attempt to clean up any +# processes we may have left running +def cleanup_processes(): + with process_lock: + for process in processes: + try: + process.kill() + except Exception: # pylint: disable=broad-except + pass + + +atexit.register(cleanup_processes) + + +def wait(process): + with process_lock: + processes.append(process) + process.wait() + + +class ServerShutdown(unittest.TestCase): + + # Currently we shut down a server (if possible) after the Python server + # instance is garbage collected. This behavior may change in the future. + def test_deallocated_server_stops(self): + process = subprocess.Popen( + BASE_COMMAND + [_server_shutdown_scenarios.SERVER_DEALLOCATED], + stdout=sys.stdout, + stderr=sys.stderr) + wait(process) + + def test_server_exception_exits(self): + process = subprocess.Popen( + BASE_COMMAND + [_server_shutdown_scenarios.SERVER_RAISES_EXCEPTION], + stdout=sys.stdout, + stderr=sys.stderr) + wait(process) + + @unittest.skipIf(os.name == 'nt', 'fork not supported on windows') + def test_server_fork_can_exit(self): + process = subprocess.Popen( + BASE_COMMAND + [_server_shutdown_scenarios.SERVER_FORK_CAN_EXIT], + stdout=sys.stdout, + stderr=sys.stderr) + wait(process) + + +if __name__ == '__main__': + logging.basicConfig() + unittest.main(verbosity=2) diff --git a/src/python/grpcio_tests/tests/unit/_server_ssl_cert_config_test.py b/src/python/grpcio_tests/tests/unit/_server_ssl_cert_config_test.py index e733a59a5b1..9e4bd618168 100644 --- a/src/python/grpcio_tests/tests/unit/_server_ssl_cert_config_test.py +++ b/src/python/grpcio_tests/tests/unit/_server_ssl_cert_config_test.py @@ -70,18 +70,11 @@ SERVER_CERT_CHAIN_2_PEM = (resources.cert_hier_2_server_1_cert() + Call = collections.namedtuple('Call', ['did_raise', 'returned_cert_config']) -def _create_client_stub( - port, - expect_success, - root_certificates=None, - private_key=None, - certificate_chain=None, -): - channel = grpc.secure_channel('localhost:{}'.format(port), - grpc.ssl_channel_credentials( - root_certificates=root_certificates, - private_key=private_key, - certificate_chain=certificate_chain)) +def _create_channel(port, credentials): + return grpc.secure_channel('localhost:{}'.format(port), credentials) + + +def _create_client_stub(channel, expect_success): if expect_success: # per Nathaniel: there's some robustness issue if we start # using a channel without waiting for it to be actually ready @@ -176,14 +169,13 @@ class _ServerSSLCertReloadTest( root_certificates=None, private_key=None, certificate_chain=None): - client_stub = _create_client_stub( - self.port, - expect_success, + credentials = grpc.ssl_channel_credentials( root_certificates=root_certificates, private_key=private_key, certificate_chain=certificate_chain) - self._perform_rpc(client_stub, expect_success) - del client_stub + with _create_channel(self.port, credentials) as client_channel: + client_stub = _create_client_stub(client_channel, expect_success) + self._perform_rpc(client_stub, expect_success) def _test(self): # things should work... @@ -259,12 +251,13 @@ class _ServerSSLCertReloadTest( # now create the "persistent" clients self.cert_config_fetcher.reset() self.cert_config_fetcher.configure(False, None) - persistent_client_stub_A = _create_client_stub( + channel_A = _create_channel( self.port, - True, - root_certificates=CA_1_PEM, - private_key=CLIENT_KEY_2_PEM, - certificate_chain=CLIENT_CERT_CHAIN_2_PEM) + grpc.ssl_channel_credentials( + root_certificates=CA_1_PEM, + private_key=CLIENT_KEY_2_PEM, + certificate_chain=CLIENT_CERT_CHAIN_2_PEM)) + persistent_client_stub_A = _create_client_stub(channel_A, True) self._perform_rpc(persistent_client_stub_A, True) actual_calls = self.cert_config_fetcher.getCalls() self.assertEqual(len(actual_calls), 1) @@ -273,12 +266,13 @@ class _ServerSSLCertReloadTest( self.cert_config_fetcher.reset() self.cert_config_fetcher.configure(False, None) - persistent_client_stub_B = _create_client_stub( + channel_B = _create_channel( self.port, - True, - root_certificates=CA_1_PEM, - private_key=CLIENT_KEY_2_PEM, - certificate_chain=CLIENT_CERT_CHAIN_2_PEM) + grpc.ssl_channel_credentials( + root_certificates=CA_1_PEM, + private_key=CLIENT_KEY_2_PEM, + certificate_chain=CLIENT_CERT_CHAIN_2_PEM)) + persistent_client_stub_B = _create_client_stub(channel_B, True) self._perform_rpc(persistent_client_stub_B, True) actual_calls = self.cert_config_fetcher.getCalls() self.assertEqual(len(actual_calls), 1) @@ -359,6 +353,9 @@ class _ServerSSLCertReloadTest( actual_calls = self.cert_config_fetcher.getCalls() self.assertEqual(len(actual_calls), 0) + channel_A.close() + channel_B.close() + class ServerSSLCertConfigFetcherParamsChecks(unittest.TestCase): diff --git a/src/python/grpcio_tests/tests/unit/_tcp_proxy.py b/src/python/grpcio_tests/tests/unit/_tcp_proxy.py new file mode 100644 index 00000000000..5ad0bf8f028 --- /dev/null +++ b/src/python/grpcio_tests/tests/unit/_tcp_proxy.py @@ -0,0 +1,164 @@ +# Copyright 2019 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. +# 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. +""" Proxies a TCP connection between a single client-server pair. + +This proxy is not suitable for production, but should work well for cases in +which a test needs to spy on the bytes put on the wire between a server and +a client. +""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import datetime +import select +import socket +import threading + +_TCP_PROXY_BUFFER_SIZE = 1024 +_TCP_PROXY_TIMEOUT = datetime.timedelta(milliseconds=500) + + +def _create_socket_ipv6(bind_address): + listen_socket = socket.socket(socket.AF_INET6, socket.SOCK_STREAM) + listen_socket.bind((bind_address, 0, 0, 0)) + return listen_socket + + +def _create_socket_ipv4(bind_address): + listen_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + listen_socket.bind((bind_address, 0)) + return listen_socket + + +def _init_listen_socket(bind_address): + listen_socket = None + if socket.has_ipv6: + try: + listen_socket = _create_socket_ipv6(bind_address) + except socket.error: + listen_socket = _create_socket_ipv4(bind_address) + else: + listen_socket = _create_socket_ipv4(bind_address) + listen_socket.listen(1) + return listen_socket, listen_socket.getsockname()[1] + + +def _init_proxy_socket(gateway_address, gateway_port): + proxy_socket = socket.create_connection((gateway_address, gateway_port)) + return proxy_socket + + +class TcpProxy(object): + """Proxies a TCP connection between one client and one server.""" + + def __init__(self, bind_address, gateway_address, gateway_port): + self._bind_address = bind_address + self._gateway_address = gateway_address + self._gateway_port = gateway_port + + self._byte_count_lock = threading.RLock() + self._sent_byte_count = 0 + self._received_byte_count = 0 + + self._stop_event = threading.Event() + + self._port = None + self._listen_socket = None + self._proxy_socket = None + + # The following three attributes are owned by the serving thread. + self._northbound_data = b"" + self._southbound_data = b"" + self._client_sockets = [] + + self._thread = threading.Thread(target=self._run_proxy) + + def start(self): + self._listen_socket, self._port = _init_listen_socket( + self._bind_address) + self._proxy_socket = _init_proxy_socket(self._gateway_address, + self._gateway_port) + self._thread.start() + + def get_port(self): + return self._port + + def _handle_reads(self, sockets_to_read): + for socket_to_read in sockets_to_read: + if socket_to_read is self._listen_socket: + client_socket, client_address = socket_to_read.accept() + self._client_sockets.append(client_socket) + elif socket_to_read is self._proxy_socket: + data = socket_to_read.recv(_TCP_PROXY_BUFFER_SIZE) + with self._byte_count_lock: + self._received_byte_count += len(data) + self._northbound_data += data + elif socket_to_read in self._client_sockets: + data = socket_to_read.recv(_TCP_PROXY_BUFFER_SIZE) + if data: + with self._byte_count_lock: + self._sent_byte_count += len(data) + self._southbound_data += data + else: + self._client_sockets.remove(socket_to_read) + else: + raise RuntimeError('Unidentified socket appeared in read set.') + + def _handle_writes(self, sockets_to_write): + for socket_to_write in sockets_to_write: + if socket_to_write is self._proxy_socket: + if self._southbound_data: + self._proxy_socket.sendall(self._southbound_data) + self._southbound_data = b"" + elif socket_to_write in self._client_sockets: + if self._northbound_data: + socket_to_write.sendall(self._northbound_data) + self._northbound_data = b"" + + def _run_proxy(self): + while not self._stop_event.is_set(): + expected_reads = (self._listen_socket, self._proxy_socket) + tuple( + self._client_sockets) + expected_writes = expected_reads + sockets_to_read, sockets_to_write, _ = select.select( + expected_reads, expected_writes, (), + _TCP_PROXY_TIMEOUT.total_seconds()) + self._handle_reads(sockets_to_read) + self._handle_writes(sockets_to_write) + for client_socket in self._client_sockets: + client_socket.close() + + def stop(self): + self._stop_event.set() + self._thread.join() + self._listen_socket.close() + self._proxy_socket.close() + + def get_byte_count(self): + with self._byte_count_lock: + return self._sent_byte_count, self._received_byte_count + + def reset_byte_count(self): + with self._byte_count_lock: + self._byte_count = 0 + self._received_byte_count = 0 + + def __enter__(self): + self.start() + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + self.stop() diff --git a/src/python/grpcio_tests/tests/unit/_version_test.py b/src/python/grpcio_tests/tests/unit/_version_test.py new file mode 100644 index 00000000000..3d37b319e5a --- /dev/null +++ b/src/python/grpcio_tests/tests/unit/_version_test.py @@ -0,0 +1,30 @@ +# 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. +"""Test for grpc.__version__""" + +import unittest +import grpc +import logging +from grpc import _grpcio_metadata + + +class VersionTest(unittest.TestCase): + + def test_get_version(self): + self.assertEqual(grpc.__version__, _grpcio_metadata.__version__) + + +if __name__ == '__main__': + logging.basicConfig() + unittest.main(verbosity=2) diff --git a/src/python/grpcio_tests/tests/unit/beta/BUILD.bazel b/src/python/grpcio_tests/tests/unit/beta/BUILD.bazel deleted file mode 100644 index d3e0fe20eb7..00000000000 --- a/src/python/grpcio_tests/tests/unit/beta/BUILD.bazel +++ /dev/null @@ -1,75 +0,0 @@ -load("@grpc_python_dependencies//:requirements.bzl", "requirement") - -package(default_visibility = ["//visibility:public"]) - -py_library( - name = "test_utilities", - srcs = ["test_utilities.py"], - deps = [ - "//src/python/grpcio/grpc:grpcio", - ], -) - -py_test( - name = "_beta_features_test", - srcs = ["_beta_features_test.py"], - main = "_beta_features_test.py", - size = "small", - deps = [ - "//src/python/grpcio/grpc:grpcio", - "//src/python/grpcio_tests/tests/unit:resources", - "//src/python/grpcio_tests/tests/unit/framework/common", - ":test_utilities", - ], - imports=["../../../",], -) - -py_test( - name = "_connectivity_channel_test", - srcs = ["_connectivity_channel_test.py"], - main = "_connectivity_channel_test.py", - size = "small", - deps = [ - "//src/python/grpcio/grpc:grpcio", - ], -) - -# TODO(ghostwriternr): To be added later. -#py_test( -# name = "_implementations_test", -# srcs = ["_implementations_test.py"], -# main = "_implementations_test.py", -# size = "small", -# deps = [ -# "//src/python/grpcio/grpc:grpcio", -# "//src/python/grpcio_tests/tests/unit:resources", -# requirement('oauth2client'), -# ], -# imports=["../../../",], -#) - -py_test( - name = "_not_found_test", - srcs = ["_not_found_test.py"], - main = "_not_found_test.py", - size = "small", - deps = [ - "//src/python/grpcio/grpc:grpcio", - "//src/python/grpcio_tests/tests/unit/framework/common", - ], - imports=["../../../",], -) - -py_test( - name = "_utilities_test", - srcs = ["_utilities_test.py"], - main = "_utilities_test.py", - size = "small", - deps = [ - "//src/python/grpcio/grpc:grpcio", - "//src/python/grpcio_tests/tests/unit/framework/common", - ], - imports=["../../../",], -) - - diff --git a/src/python/grpcio_tests/tests/unit/_thread_pool.py b/src/python/grpcio_tests/tests/unit/thread_pool.py similarity index 95% rename from src/python/grpcio_tests/tests/unit/_thread_pool.py rename to src/python/grpcio_tests/tests/unit/thread_pool.py index e99efc3e927..bc0f0e523bc 100644 --- a/src/python/grpcio_tests/tests/unit/_thread_pool.py +++ b/src/python/grpcio_tests/tests/unit/thread_pool.py @@ -16,7 +16,7 @@ import threading from concurrent import futures -class RecordingThreadPool(futures.Executor): +class RecordingThreadPool(futures.ThreadPoolExecutor): """A thread pool that records if used.""" def __init__(self, max_workers): diff --git a/src/ruby/bin/math_pb.rb b/src/ruby/bin/math_pb.rb index 60429a15052..ac287c81bcd 100644 --- a/src/ruby/bin/math_pb.rb +++ b/src/ruby/bin/math_pb.rb @@ -4,22 +4,24 @@ require 'google/protobuf' Google::Protobuf::DescriptorPool.generated_pool.build do - add_message "math.DivArgs" do - optional :dividend, :int64, 1 - optional :divisor, :int64, 2 - end - add_message "math.DivReply" do - optional :quotient, :int64, 1 - optional :remainder, :int64, 2 - end - add_message "math.FibArgs" do - optional :limit, :int64, 1 - end - add_message "math.Num" do - optional :num, :int64, 1 - end - add_message "math.FibReply" do - optional :count, :int64, 1 + add_file("math.proto", :syntax => :proto3) do + add_message "math.DivArgs" do + optional :dividend, :int64, 1 + optional :divisor, :int64, 2 + end + add_message "math.DivReply" do + optional :quotient, :int64, 1 + optional :remainder, :int64, 2 + end + add_message "math.FibArgs" do + optional :limit, :int64, 1 + end + add_message "math.Num" do + optional :num, :int64, 1 + end + add_message "math.FibReply" do + optional :count, :int64, 1 + end end end diff --git a/src/ruby/end2end/graceful_sig_handling_client.rb b/src/ruby/end2end/graceful_sig_handling_client.rb new file mode 100755 index 00000000000..14a67a62ccc --- /dev/null +++ b/src/ruby/end2end/graceful_sig_handling_client.rb @@ -0,0 +1,61 @@ +#!/usr/bin/env ruby + +# 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. + +require_relative './end2end_common' + +# Test client. Sends RPC's as normal but process also has signal handlers +class SigHandlingClientController < ClientControl::ClientController::Service + def initialize(stub) + @stub = stub + end + + def do_echo_rpc(req, _) + response = @stub.echo(Echo::EchoRequest.new(request: req.request)) + fail 'bad response' unless response.response == req.request + ClientControl::Void.new + end +end + +def main + client_control_port = '' + server_port = '' + OptionParser.new do |opts| + opts.on('--client_control_port=P', String) do |p| + client_control_port = p + end + opts.on('--server_port=P', String) do |p| + server_port = p + end + end.parse! + + # Allow a few seconds to be safe. + srv = new_rpc_server_for_testing + srv.add_http2_port("0.0.0.0:#{client_control_port}", + :this_port_is_insecure) + stub = Echo::EchoServer::Stub.new("localhost:#{server_port}", + :this_channel_is_insecure) + control_service = SigHandlingClientController.new(stub) + srv.handle(control_service) + server_thread = Thread.new do + srv.run_till_terminated_or_interrupted(['int']) + end + srv.wait_till_running + # send a first RPC to notify the parent process that we've started + stub.echo(Echo::EchoRequest.new(request: 'client/child started')) + server_thread.join +end + +main diff --git a/src/ruby/end2end/graceful_sig_handling_driver.rb b/src/ruby/end2end/graceful_sig_handling_driver.rb new file mode 100755 index 00000000000..e12ae284858 --- /dev/null +++ b/src/ruby/end2end/graceful_sig_handling_driver.rb @@ -0,0 +1,83 @@ +#!/usr/bin/env ruby + +# 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. + +# smoke test for a grpc-using app that receives and +# handles process-ending signals + +require_relative './end2end_common' + +# A service that calls back it's received_rpc_callback +# upon receiving an RPC. Used for synchronization/waiting +# for child process to start. +class ClientStartedService < Echo::EchoServer::Service + def initialize(received_rpc_callback) + @received_rpc_callback = received_rpc_callback + end + + def echo(echo_req, _) + @received_rpc_callback.call unless @received_rpc_callback.nil? + @received_rpc_callback = nil + Echo::EchoReply.new(response: echo_req.request) + end +end + +def main + STDERR.puts 'start server' + client_started = false + client_started_mu = Mutex.new + client_started_cv = ConditionVariable.new + received_rpc_callback = proc do + client_started_mu.synchronize do + client_started = true + client_started_cv.signal + end + end + + client_started_service = ClientStartedService.new(received_rpc_callback) + server_runner = ServerRunner.new(client_started_service) + server_port = server_runner.run + STDERR.puts 'start client' + control_stub, client_pid = start_client('graceful_sig_handling_client.rb', server_port) + + client_started_mu.synchronize do + client_started_cv.wait(client_started_mu) until client_started + end + + control_stub.do_echo_rpc( + ClientControl::DoEchoRpcRequest.new(request: 'hello')) + + STDERR.puts 'killing client' + Process.kill('SIGINT', client_pid) + Process.wait(client_pid) + client_exit_status = $CHILD_STATUS + + if client_exit_status.exited? + if client_exit_status.exitstatus != 0 + STDERR.puts 'Client did not close gracefully' + exit(1) + end + else + STDERR.puts 'Client did not close gracefully' + exit(1) + end + + STDERR.puts 'Client ended gracefully' + + # no need to call cleanup, client should already be dead + server_runner.stop +end + +main diff --git a/src/ruby/end2end/graceful_sig_stop_client.rb b/src/ruby/end2end/graceful_sig_stop_client.rb new file mode 100755 index 00000000000..b672dc3f2ac --- /dev/null +++ b/src/ruby/end2end/graceful_sig_stop_client.rb @@ -0,0 +1,78 @@ +#!/usr/bin/env ruby + +# 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. + +require_relative './end2end_common' + +# Test client. Sends RPC's as normal but process also has signal handlers +class SigHandlingClientController < ClientControl::ClientController::Service + def initialize(srv, stub) + @srv = srv + @stub = stub + end + + def do_echo_rpc(req, _) + response = @stub.echo(Echo::EchoRequest.new(request: req.request)) + fail 'bad response' unless response.response == req.request + ClientControl::Void.new + end + + def shutdown(_, _) + # Spawn a new thread because RpcServer#stop is + # synchronous and blocks until either this RPC has finished, + # or the server's "poll_period" seconds have passed. + @shutdown_thread = Thread.new do + @srv.stop + end + ClientControl::Void.new + end + + def join_shutdown_thread + @shutdown_thread.join + end +end + +def main + client_control_port = '' + server_port = '' + OptionParser.new do |opts| + opts.on('--client_control_port=P', String) do |p| + client_control_port = p + end + opts.on('--server_port=P', String) do |p| + server_port = p + end + end.parse! + + # The "shutdown" RPC should end very quickly. + # Allow a few seconds to be safe. + srv = new_rpc_server_for_testing(poll_period: 3) + srv.add_http2_port("0.0.0.0:#{client_control_port}", + :this_port_is_insecure) + stub = Echo::EchoServer::Stub.new("localhost:#{server_port}", + :this_channel_is_insecure) + control_service = SigHandlingClientController.new(srv, stub) + srv.handle(control_service) + server_thread = Thread.new do + srv.run_till_terminated_or_interrupted(['int']) + end + srv.wait_till_running + # send a first RPC to notify the parent process that we've started + stub.echo(Echo::EchoRequest.new(request: 'client/child started')) + server_thread.join + control_service.join_shutdown_thread +end + +main diff --git a/src/ruby/end2end/graceful_sig_stop_driver.rb b/src/ruby/end2end/graceful_sig_stop_driver.rb new file mode 100755 index 00000000000..7a132403ebf --- /dev/null +++ b/src/ruby/end2end/graceful_sig_stop_driver.rb @@ -0,0 +1,62 @@ +#!/usr/bin/env ruby + +# 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. + +# smoke test for a grpc-using app that receives and +# handles process-ending signals + +require_relative './end2end_common' + +# A service that calls back it's received_rpc_callback +# upon receiving an RPC. Used for synchronization/waiting +# for child process to start. +class ClientStartedService < Echo::EchoServer::Service + def initialize(received_rpc_callback) + @received_rpc_callback = received_rpc_callback + end + + def echo(echo_req, _) + @received_rpc_callback.call unless @received_rpc_callback.nil? + @received_rpc_callback = nil + Echo::EchoReply.new(response: echo_req.request) + end +end + +def main + STDERR.puts 'start server' + client_started = false + client_started_mu = Mutex.new + client_started_cv = ConditionVariable.new + received_rpc_callback = proc do + client_started_mu.synchronize do + client_started = true + client_started_cv.signal + end + end + + client_started_service = ClientStartedService.new(received_rpc_callback) + server_runner = ServerRunner.new(client_started_service) + server_port = server_runner.run + STDERR.puts 'start client' + control_stub, client_pid = start_client('./graceful_sig_stop_client.rb', server_port) + + client_started_mu.synchronize do + client_started_cv.wait(client_started_mu) until client_started + end + + cleanup(control_stub, client_pid, server_runner) +end + +main diff --git a/src/ruby/ext/grpc/extconf.rb b/src/ruby/ext/grpc/extconf.rb index 505357021e0..9950976eeb1 100644 --- a/src/ruby/ext/grpc/extconf.rb +++ b/src/ruby/ext/grpc/extconf.rb @@ -24,10 +24,18 @@ grpc_config = ENV['GRPC_CONFIG'] || 'opt' ENV['MACOSX_DEPLOYMENT_TARGET'] = '10.7' -ENV['AR'] = RbConfig::CONFIG['AR'] + ' rcs' -ENV['CC'] = RbConfig::CONFIG['CC'] -ENV['CXX'] = RbConfig::CONFIG['CXX'] -ENV['LD'] = ENV['CC'] +if ENV['AR'].nil? || ENV['AR'].size == 0 + ENV['AR'] = RbConfig::CONFIG['AR'] + ' rcs' +end +if ENV['CC'].nil? || ENV['CC'].size == 0 + ENV['CC'] = RbConfig::CONFIG['CC'] +end +if ENV['CXX'].nil? || ENV['CXX'].size == 0 + ENV['CXX'] = RbConfig::CONFIG['CXX'] +end +if ENV['LD'].nil? || ENV['LD'].size == 0 + ENV['LD'] = ENV['CC'] +end ENV['AR'] = 'libtool -o' if RUBY_PLATFORM =~ /darwin/ diff --git a/src/ruby/ext/grpc/rb_call_credentials.c b/src/ruby/ext/grpc/rb_call_credentials.c index be325975920..cea9620081f 100644 --- a/src/ruby/ext/grpc/rb_call_credentials.c +++ b/src/ruby/ext/grpc/rb_call_credentials.c @@ -134,8 +134,7 @@ static void grpc_rb_call_credentials_plugin_destroy(void* state) { // Not sure what needs to be done here } -/* Destroys the credentials instances. */ -static void grpc_rb_call_credentials_free(void* p) { +static void grpc_rb_call_credentials_free_internal(void* p) { grpc_rb_call_credentials* wrapper; if (p == NULL) { return; @@ -143,10 +142,15 @@ static void grpc_rb_call_credentials_free(void* p) { wrapper = (grpc_rb_call_credentials*)p; grpc_call_credentials_release(wrapper->wrapped); wrapper->wrapped = NULL; - xfree(p); } +/* Destroys the credentials instances. */ +static void grpc_rb_call_credentials_free(void* p) { + grpc_rb_call_credentials_free_internal(p); + grpc_ruby_shutdown(); +} + /* Protects the mark object from GC */ static void grpc_rb_call_credentials_mark(void* p) { grpc_rb_call_credentials* wrapper = NULL; @@ -175,6 +179,7 @@ static rb_data_type_t grpc_rb_call_credentials_data_type = { /* Allocates CallCredentials instances. Provides safe initial defaults for the instance fields. */ static VALUE grpc_rb_call_credentials_alloc(VALUE cls) { + grpc_ruby_init(); grpc_rb_call_credentials* wrapper = ALLOC(grpc_rb_call_credentials); wrapper->wrapped = NULL; wrapper->mark = Qnil; @@ -212,8 +217,6 @@ static VALUE grpc_rb_call_credentials_init(VALUE self, VALUE proc) { grpc_call_credentials* creds = NULL; grpc_metadata_credentials_plugin plugin; - grpc_ruby_once_init(); - TypedData_Get_Struct(self, grpc_rb_call_credentials, &grpc_rb_call_credentials_data_type, wrapper); diff --git a/src/ruby/ext/grpc/rb_channel.c b/src/ruby/ext/grpc/rb_channel.c index 6d4b2293a24..d789e5a4362 100644 --- a/src/ruby/ext/grpc/rb_channel.c +++ b/src/ruby/ext/grpc/rb_channel.c @@ -143,26 +143,29 @@ static void* channel_safe_destroy_without_gil(void* arg) { return NULL; } -/* Destroys Channel instances. */ -static void grpc_rb_channel_free(void* p) { +static void grpc_rb_channel_free_internal(void* p) { grpc_rb_channel* ch = NULL; if (p == NULL) { return; }; ch = (grpc_rb_channel*)p; - if (ch->bg_wrapped != NULL) { /* assumption made here: it's ok to directly gpr_mu_lock the global - * connection polling mutex becuse we're in a finalizer, + * connection polling mutex because we're in a finalizer, * and we can count on this thread to not be interrupted or * yield the gil. */ grpc_rb_channel_safe_destroy(ch->bg_wrapped); ch->bg_wrapped = NULL; } - xfree(p); } +/* Destroys Channel instances. */ +static void grpc_rb_channel_free(void* p) { + grpc_rb_channel_free_internal(p); + grpc_ruby_shutdown(); +} + /* Protects the mark object from GC */ static void grpc_rb_channel_mark(void* p) { grpc_rb_channel* channel = NULL; @@ -189,6 +192,7 @@ static rb_data_type_t grpc_channel_data_type = {"grpc_channel", /* Allocates grpc_rb_channel instances. */ static VALUE grpc_rb_channel_alloc(VALUE cls) { + grpc_ruby_init(); grpc_rb_channel* wrapper = ALLOC(grpc_rb_channel); wrapper->bg_wrapped = NULL; wrapper->credentials = Qnil; @@ -216,7 +220,6 @@ static VALUE grpc_rb_channel_init(int argc, VALUE* argv, VALUE self) { int stop_waiting_for_thread_start = 0; MEMZERO(&args, grpc_channel_args, 1); - grpc_ruby_once_init(); grpc_ruby_fork_guard(); rb_thread_call_without_gvl( wait_until_channel_polling_thread_started_no_gil, @@ -292,7 +295,7 @@ static void* get_state_without_gil(void* arg) { Indicates the current state of the channel, whose value is one of the constants defined in GRPC::Core::ConnectivityStates. - It also tries to connect if the chennel is idle in the second form. */ + It also tries to connect if the channel is idle in the second form. */ static VALUE grpc_rb_channel_get_connectivity_state(int argc, VALUE* argv, VALUE self) { VALUE try_to_connect_param = Qfalse; @@ -327,8 +330,8 @@ static void* wait_for_watch_state_op_complete_without_gvl(void* arg) { void* success = (void*)0; gpr_mu_lock(&global_connection_polling_mu); - // its unsafe to do a "watch" after "channel polling abort" because the cq has - // been shut down. + // it's unsafe to do a "watch" after "channel polling abort" because the cq + // has been shut down. if (abort_channel_polling || stack->bg_wrapped->channel_destroyed) { gpr_mu_unlock(&global_connection_polling_mu); return (void*)0; @@ -682,9 +685,10 @@ static VALUE run_poll_channels_loop(VALUE arg) { gpr_log( GPR_DEBUG, "GRPC_RUBY: run_poll_channels_loop - create connection polling thread"); + grpc_ruby_init(); rb_thread_call_without_gvl(run_poll_channels_loop_no_gil, NULL, run_poll_channels_loop_unblocking_func, NULL); - + grpc_ruby_shutdown(); return Qnil; } diff --git a/src/ruby/ext/grpc/rb_channel_credentials.c b/src/ruby/ext/grpc/rb_channel_credentials.c index 178224c6e00..970bc4eeb11 100644 --- a/src/ruby/ext/grpc/rb_channel_credentials.c +++ b/src/ruby/ext/grpc/rb_channel_credentials.c @@ -48,8 +48,7 @@ typedef struct grpc_rb_channel_credentials { grpc_channel_credentials* wrapped; } grpc_rb_channel_credentials; -/* Destroys the credentials instances. */ -static void grpc_rb_channel_credentials_free(void* p) { +static void grpc_rb_channel_credentials_free_internal(void* p) { grpc_rb_channel_credentials* wrapper = NULL; if (p == NULL) { return; @@ -61,6 +60,12 @@ static void grpc_rb_channel_credentials_free(void* p) { xfree(p); } +/* Destroys the credentials instances. */ +static void grpc_rb_channel_credentials_free(void* p) { + grpc_rb_channel_credentials_free_internal(p); + grpc_ruby_shutdown(); +} + /* Protects the mark object from GC */ static void grpc_rb_channel_credentials_mark(void* p) { grpc_rb_channel_credentials* wrapper = NULL; @@ -90,6 +95,7 @@ static rb_data_type_t grpc_rb_channel_credentials_data_type = { /* Allocates ChannelCredential instances. Provides safe initial defaults for the instance fields. */ static VALUE grpc_rb_channel_credentials_alloc(VALUE cls) { + grpc_ruby_init(); grpc_rb_channel_credentials* wrapper = ALLOC(grpc_rb_channel_credentials); wrapper->wrapped = NULL; wrapper->mark = Qnil; @@ -147,8 +153,6 @@ static VALUE grpc_rb_channel_credentials_init(int argc, VALUE* argv, const char* pem_root_certs_cstr = NULL; MEMZERO(&key_cert_pair, grpc_ssl_pem_key_cert_pair, 1); - grpc_ruby_once_init(); - /* "03" == no mandatory arg, 3 optional */ rb_scan_args(argc, argv, "03", &pem_root_certs, &pem_private_key, &pem_cert_chain); diff --git a/src/ruby/ext/grpc/rb_compression_options.c b/src/ruby/ext/grpc/rb_compression_options.c index 4ba6991ef66..d10c603460c 100644 --- a/src/ruby/ext/grpc/rb_compression_options.c +++ b/src/ruby/ext/grpc/rb_compression_options.c @@ -52,23 +52,26 @@ typedef struct grpc_rb_compression_options { grpc_compression_options* wrapped; } grpc_rb_compression_options; -/* Destroys the compression options instances and free the - * wrapped grpc compression options. */ -static void grpc_rb_compression_options_free(void* p) { +static void grpc_rb_compression_options_free_internal(void* p) { grpc_rb_compression_options* wrapper = NULL; if (p == NULL) { return; }; wrapper = (grpc_rb_compression_options*)p; - if (wrapper->wrapped != NULL) { gpr_free(wrapper->wrapped); wrapper->wrapped = NULL; } - xfree(p); } +/* Destroys the compression options instances and free the + * wrapped grpc compression options. */ +static void grpc_rb_compression_options_free(void* p) { + grpc_rb_compression_options_free_internal(p); + grpc_ruby_shutdown(); +} + /* Ruby recognized data type for the CompressionOptions class. */ static rb_data_type_t grpc_rb_compression_options_data_type = { "grpc_compression_options", @@ -87,10 +90,9 @@ static rb_data_type_t grpc_rb_compression_options_data_type = { Allocate the wrapped grpc compression options and initialize it here too. */ static VALUE grpc_rb_compression_options_alloc(VALUE cls) { + grpc_ruby_init(); grpc_rb_compression_options* wrapper = NULL; - grpc_ruby_once_init(); - wrapper = gpr_malloc(sizeof(grpc_rb_compression_options)); wrapper->wrapped = NULL; wrapper->wrapped = gpr_malloc(sizeof(grpc_compression_options)); diff --git a/src/ruby/ext/grpc/rb_event_thread.c b/src/ruby/ext/grpc/rb_event_thread.c index 281e41c9a88..c9ca14ed06a 100644 --- a/src/ruby/ext/grpc/rb_event_thread.c +++ b/src/ruby/ext/grpc/rb_event_thread.c @@ -115,6 +115,7 @@ static void grpc_rb_event_unblocking_func(void* arg) { static VALUE grpc_rb_event_thread(VALUE arg) { grpc_rb_event* event; (void)arg; + grpc_ruby_init(); while (true) { event = (grpc_rb_event*)rb_thread_call_without_gvl( grpc_rb_wait_for_event_no_gil, NULL, grpc_rb_event_unblocking_func, @@ -128,6 +129,7 @@ static VALUE grpc_rb_event_thread(VALUE arg) { } } grpc_rb_event_queue_destroy(); + grpc_ruby_shutdown(); return Qnil; } diff --git a/src/ruby/ext/grpc/rb_grpc.c b/src/ruby/ext/grpc/rb_grpc.c index 872aed0cfce..4aa41217251 100644 --- a/src/ruby/ext/grpc/rb_grpc.c +++ b/src/ruby/ext/grpc/rb_grpc.c @@ -276,10 +276,6 @@ static bool grpc_ruby_forked_after_init(void) { } #endif -static void grpc_rb_shutdown(void) { - if (!grpc_ruby_forked_after_init()) grpc_shutdown(); -} - /* Initialize the GRPC module structs */ /* grpc_rb_sNewServerRpc is the struct that holds new server rpc details. */ @@ -298,12 +294,6 @@ VALUE sym_metadata = Qundef; static gpr_once g_once_init = GPR_ONCE_INIT; -static void grpc_ruby_once_init_internal() { - grpc_ruby_set_init_pid(); - grpc_init(); - atexit(grpc_rb_shutdown); -} - void grpc_ruby_fork_guard() { if (grpc_ruby_forked_after_init()) { rb_raise(rb_eRuntimeError, "grpc cannot be used before and after forking"); @@ -313,20 +303,8 @@ void grpc_ruby_fork_guard() { static VALUE bg_thread_init_rb_mu = Qundef; static int bg_thread_init_done = 0; -void grpc_ruby_once_init() { - /* ruby_vm_at_exit doesn't seem to be working. It would crash once every - * blue moon, and some users are getting it repeatedly. See the discussions - * - https://github.com/grpc/grpc/pull/5337 - * - https://bugs.ruby-lang.org/issues/12095 - * - * In order to still be able to handle the (unlikely) situation where the - * extension is loaded by a first Ruby VM that is subsequently destroyed, - * then loaded again by another VM within the same process, we need to - * schedule our initialization and destruction only once. - */ - gpr_once_init(&g_once_init, grpc_ruby_once_init_internal); - - // Avoid calling calling into ruby library (when creating threads here) +static void grpc_ruby_init_threads() { + // Avoid calling into ruby library (when creating threads here) // in gpr_once_init. In general, it appears to be unsafe to call // into the ruby library while holding a non-ruby mutex, because a gil yield // could end up trying to lock onto that same mutex and deadlocking. @@ -339,6 +317,27 @@ void grpc_ruby_once_init() { rb_mutex_unlock(bg_thread_init_rb_mu); } +static int64_t g_grpc_ruby_init_count; + +void grpc_ruby_init() { + gpr_once_init(&g_once_init, grpc_ruby_set_init_pid); + grpc_init(); + grpc_ruby_init_threads(); + // (only gpr_log after logging has been initialized) + gpr_log(GPR_DEBUG, + "GRPC_RUBY: grpc_ruby_init - prev g_grpc_ruby_init_count:%" PRId64, + g_grpc_ruby_init_count++); +} + +void grpc_ruby_shutdown() { + GPR_ASSERT(g_grpc_ruby_init_count > 0); + if (!grpc_ruby_forked_after_init()) grpc_shutdown(); + gpr_log( + GPR_DEBUG, + "GRPC_RUBY: grpc_ruby_shutdown - prev g_grpc_ruby_init_count:%" PRId64, + g_grpc_ruby_init_count--); +} + void Init_grpc_c() { if (!grpc_rb_load_core()) { rb_raise(rb_eLoadError, "Couldn't find or load gRPC's dynamic C core"); diff --git a/src/ruby/ext/grpc/rb_grpc.h b/src/ruby/ext/grpc/rb_grpc.h index 4118435ecf7..2c4675839ac 100644 --- a/src/ruby/ext/grpc/rb_grpc.h +++ b/src/ruby/ext/grpc/rb_grpc.h @@ -67,8 +67,10 @@ VALUE grpc_rb_cannot_init_copy(VALUE copy, VALUE self); /* grpc_rb_time_timeval creates a gpr_timespec from a ruby time object. */ gpr_timespec grpc_rb_time_timeval(VALUE time, int interval); -void grpc_ruby_once_init(); - void grpc_ruby_fork_guard(); +void grpc_ruby_init(); + +void grpc_ruby_shutdown(); + #endif /* GRPC_RB_H_ */ diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.c b/src/ruby/ext/grpc/rb_grpc_imports.generated.c index 18245e91073..f8a31286115 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.c +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.c @@ -39,6 +39,7 @@ grpc_register_plugin_type grpc_register_plugin_import; grpc_init_type grpc_init_import; grpc_shutdown_type grpc_shutdown_import; grpc_is_initialized_type grpc_is_initialized_import; +grpc_shutdown_blocking_type grpc_shutdown_blocking_import; grpc_version_string_type grpc_version_string_import; grpc_g_stands_for_type grpc_g_stands_for_import; grpc_completion_queue_factory_lookup_type grpc_completion_queue_factory_lookup_import; @@ -154,6 +155,15 @@ grpc_alts_credentials_create_type grpc_alts_credentials_create_import; grpc_alts_server_credentials_create_type grpc_alts_server_credentials_create_import; grpc_local_credentials_create_type grpc_local_credentials_create_import; grpc_local_server_credentials_create_type grpc_local_server_credentials_create_import; +grpc_tls_credentials_options_create_type grpc_tls_credentials_options_create_import; +grpc_tls_credentials_options_set_cert_request_type_type grpc_tls_credentials_options_set_cert_request_type_import; +grpc_tls_credentials_options_set_key_materials_config_type grpc_tls_credentials_options_set_key_materials_config_import; +grpc_tls_credentials_options_set_credential_reload_config_type grpc_tls_credentials_options_set_credential_reload_config_import; +grpc_tls_credentials_options_set_server_authorization_check_config_type grpc_tls_credentials_options_set_server_authorization_check_config_import; +grpc_tls_key_materials_config_create_type grpc_tls_key_materials_config_create_import; +grpc_tls_key_materials_config_set_key_materials_type grpc_tls_key_materials_config_set_key_materials_import; +grpc_tls_credential_reload_config_create_type grpc_tls_credential_reload_config_create_import; +grpc_tls_server_authorization_check_config_create_type grpc_tls_server_authorization_check_config_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; @@ -162,6 +172,7 @@ grpc_byte_buffer_destroy_type grpc_byte_buffer_destroy_import; grpc_byte_buffer_reader_init_type grpc_byte_buffer_reader_init_import; grpc_byte_buffer_reader_destroy_type grpc_byte_buffer_reader_destroy_import; grpc_byte_buffer_reader_next_type grpc_byte_buffer_reader_next_import; +grpc_byte_buffer_reader_peek_type grpc_byte_buffer_reader_peek_import; grpc_byte_buffer_reader_readall_type grpc_byte_buffer_reader_readall_import; grpc_raw_byte_buffer_from_reader_type grpc_raw_byte_buffer_from_reader_import; gpr_log_severity_string_type gpr_log_severity_string_import; @@ -297,6 +308,7 @@ void grpc_rb_load_imports(HMODULE library) { grpc_init_import = (grpc_init_type) GetProcAddress(library, "grpc_init"); grpc_shutdown_import = (grpc_shutdown_type) GetProcAddress(library, "grpc_shutdown"); grpc_is_initialized_import = (grpc_is_initialized_type) GetProcAddress(library, "grpc_is_initialized"); + grpc_shutdown_blocking_import = (grpc_shutdown_blocking_type) GetProcAddress(library, "grpc_shutdown_blocking"); grpc_version_string_import = (grpc_version_string_type) GetProcAddress(library, "grpc_version_string"); grpc_g_stands_for_import = (grpc_g_stands_for_type) GetProcAddress(library, "grpc_g_stands_for"); grpc_completion_queue_factory_lookup_import = (grpc_completion_queue_factory_lookup_type) GetProcAddress(library, "grpc_completion_queue_factory_lookup"); @@ -412,6 +424,15 @@ void grpc_rb_load_imports(HMODULE library) { grpc_alts_server_credentials_create_import = (grpc_alts_server_credentials_create_type) GetProcAddress(library, "grpc_alts_server_credentials_create"); grpc_local_credentials_create_import = (grpc_local_credentials_create_type) GetProcAddress(library, "grpc_local_credentials_create"); grpc_local_server_credentials_create_import = (grpc_local_server_credentials_create_type) GetProcAddress(library, "grpc_local_server_credentials_create"); + grpc_tls_credentials_options_create_import = (grpc_tls_credentials_options_create_type) GetProcAddress(library, "grpc_tls_credentials_options_create"); + grpc_tls_credentials_options_set_cert_request_type_import = (grpc_tls_credentials_options_set_cert_request_type_type) GetProcAddress(library, "grpc_tls_credentials_options_set_cert_request_type"); + grpc_tls_credentials_options_set_key_materials_config_import = (grpc_tls_credentials_options_set_key_materials_config_type) GetProcAddress(library, "grpc_tls_credentials_options_set_key_materials_config"); + grpc_tls_credentials_options_set_credential_reload_config_import = (grpc_tls_credentials_options_set_credential_reload_config_type) GetProcAddress(library, "grpc_tls_credentials_options_set_credential_reload_config"); + grpc_tls_credentials_options_set_server_authorization_check_config_import = (grpc_tls_credentials_options_set_server_authorization_check_config_type) GetProcAddress(library, "grpc_tls_credentials_options_set_server_authorization_check_config"); + grpc_tls_key_materials_config_create_import = (grpc_tls_key_materials_config_create_type) GetProcAddress(library, "grpc_tls_key_materials_config_create"); + grpc_tls_key_materials_config_set_key_materials_import = (grpc_tls_key_materials_config_set_key_materials_type) GetProcAddress(library, "grpc_tls_key_materials_config_set_key_materials"); + grpc_tls_credential_reload_config_create_import = (grpc_tls_credential_reload_config_create_type) GetProcAddress(library, "grpc_tls_credential_reload_config_create"); + grpc_tls_server_authorization_check_config_create_import = (grpc_tls_server_authorization_check_config_create_type) GetProcAddress(library, "grpc_tls_server_authorization_check_config_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"); @@ -420,6 +441,7 @@ void grpc_rb_load_imports(HMODULE library) { grpc_byte_buffer_reader_init_import = (grpc_byte_buffer_reader_init_type) GetProcAddress(library, "grpc_byte_buffer_reader_init"); grpc_byte_buffer_reader_destroy_import = (grpc_byte_buffer_reader_destroy_type) GetProcAddress(library, "grpc_byte_buffer_reader_destroy"); grpc_byte_buffer_reader_next_import = (grpc_byte_buffer_reader_next_type) GetProcAddress(library, "grpc_byte_buffer_reader_next"); + grpc_byte_buffer_reader_peek_import = (grpc_byte_buffer_reader_peek_type) GetProcAddress(library, "grpc_byte_buffer_reader_peek"); grpc_byte_buffer_reader_readall_import = (grpc_byte_buffer_reader_readall_type) GetProcAddress(library, "grpc_byte_buffer_reader_readall"); grpc_raw_byte_buffer_from_reader_import = (grpc_raw_byte_buffer_from_reader_type) GetProcAddress(library, "grpc_raw_byte_buffer_from_reader"); gpr_log_severity_string_import = (gpr_log_severity_string_type) GetProcAddress(library, "gpr_log_severity_string"); diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.h b/src/ruby/ext/grpc/rb_grpc_imports.generated.h index 56d222c7ec8..c25d789a95b 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.h +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.h @@ -92,6 +92,9 @@ extern grpc_shutdown_type grpc_shutdown_import; typedef int(*grpc_is_initialized_type)(void); extern grpc_is_initialized_type grpc_is_initialized_import; #define grpc_is_initialized grpc_is_initialized_import +typedef void(*grpc_shutdown_blocking_type)(void); +extern grpc_shutdown_blocking_type grpc_shutdown_blocking_import; +#define grpc_shutdown_blocking grpc_shutdown_blocking_import typedef const char*(*grpc_version_string_type)(void); extern grpc_version_string_type grpc_version_string_import; #define grpc_version_string grpc_version_string_import @@ -272,7 +275,7 @@ extern grpc_channelz_get_servers_type grpc_channelz_get_servers_import; typedef char*(*grpc_channelz_get_server_type)(intptr_t server_id); extern grpc_channelz_get_server_type grpc_channelz_get_server_import; #define grpc_channelz_get_server grpc_channelz_get_server_import -typedef char*(*grpc_channelz_get_server_sockets_type)(intptr_t server_id, intptr_t start_socket_id); +typedef char*(*grpc_channelz_get_server_sockets_type)(intptr_t server_id, intptr_t start_socket_id, intptr_t max_results); extern grpc_channelz_get_server_sockets_type grpc_channelz_get_server_sockets_import; #define grpc_channelz_get_server_sockets grpc_channelz_get_server_sockets_import typedef char*(*grpc_channelz_get_channel_type)(intptr_t channel_id); @@ -437,6 +440,33 @@ extern grpc_local_credentials_create_type grpc_local_credentials_create_import; typedef grpc_server_credentials*(*grpc_local_server_credentials_create_type)(grpc_local_connect_type type); extern grpc_local_server_credentials_create_type grpc_local_server_credentials_create_import; #define grpc_local_server_credentials_create grpc_local_server_credentials_create_import +typedef grpc_tls_credentials_options*(*grpc_tls_credentials_options_create_type)(void); +extern grpc_tls_credentials_options_create_type grpc_tls_credentials_options_create_import; +#define grpc_tls_credentials_options_create grpc_tls_credentials_options_create_import +typedef int(*grpc_tls_credentials_options_set_cert_request_type_type)(grpc_tls_credentials_options* options, grpc_ssl_client_certificate_request_type type); +extern grpc_tls_credentials_options_set_cert_request_type_type grpc_tls_credentials_options_set_cert_request_type_import; +#define grpc_tls_credentials_options_set_cert_request_type grpc_tls_credentials_options_set_cert_request_type_import +typedef int(*grpc_tls_credentials_options_set_key_materials_config_type)(grpc_tls_credentials_options* options, grpc_tls_key_materials_config* config); +extern grpc_tls_credentials_options_set_key_materials_config_type grpc_tls_credentials_options_set_key_materials_config_import; +#define grpc_tls_credentials_options_set_key_materials_config grpc_tls_credentials_options_set_key_materials_config_import +typedef int(*grpc_tls_credentials_options_set_credential_reload_config_type)(grpc_tls_credentials_options* options, grpc_tls_credential_reload_config* config); +extern grpc_tls_credentials_options_set_credential_reload_config_type grpc_tls_credentials_options_set_credential_reload_config_import; +#define grpc_tls_credentials_options_set_credential_reload_config grpc_tls_credentials_options_set_credential_reload_config_import +typedef int(*grpc_tls_credentials_options_set_server_authorization_check_config_type)(grpc_tls_credentials_options* options, grpc_tls_server_authorization_check_config* config); +extern grpc_tls_credentials_options_set_server_authorization_check_config_type grpc_tls_credentials_options_set_server_authorization_check_config_import; +#define grpc_tls_credentials_options_set_server_authorization_check_config grpc_tls_credentials_options_set_server_authorization_check_config_import +typedef grpc_tls_key_materials_config*(*grpc_tls_key_materials_config_create_type)(void); +extern grpc_tls_key_materials_config_create_type grpc_tls_key_materials_config_create_import; +#define grpc_tls_key_materials_config_create grpc_tls_key_materials_config_create_import +typedef int(*grpc_tls_key_materials_config_set_key_materials_type)(grpc_tls_key_materials_config* config, const char* pem_root_certs, const grpc_ssl_pem_key_cert_pair** pem_key_cert_pairs, size_t num_key_cert_pairs); +extern grpc_tls_key_materials_config_set_key_materials_type grpc_tls_key_materials_config_set_key_materials_import; +#define grpc_tls_key_materials_config_set_key_materials grpc_tls_key_materials_config_set_key_materials_import +typedef grpc_tls_credential_reload_config*(*grpc_tls_credential_reload_config_create_type)(const void* config_user_data, int (*schedule)(void* config_user_data, grpc_tls_credential_reload_arg* arg), void (*cancel)(void* config_user_data, grpc_tls_credential_reload_arg* arg), void (*destruct)(void* config_user_data)); +extern grpc_tls_credential_reload_config_create_type grpc_tls_credential_reload_config_create_import; +#define grpc_tls_credential_reload_config_create grpc_tls_credential_reload_config_create_import +typedef grpc_tls_server_authorization_check_config*(*grpc_tls_server_authorization_check_config_create_type)(const void* config_user_data, int (*schedule)(void* config_user_data, grpc_tls_server_authorization_check_arg* arg), void (*cancel)(void* config_user_data, grpc_tls_server_authorization_check_arg* arg), void (*destruct)(void* config_user_data)); +extern grpc_tls_server_authorization_check_config_create_type grpc_tls_server_authorization_check_config_create_import; +#define grpc_tls_server_authorization_check_config_create grpc_tls_server_authorization_check_config_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 @@ -461,6 +491,9 @@ extern grpc_byte_buffer_reader_destroy_type grpc_byte_buffer_reader_destroy_impo typedef int(*grpc_byte_buffer_reader_next_type)(grpc_byte_buffer_reader* reader, grpc_slice* slice); extern grpc_byte_buffer_reader_next_type grpc_byte_buffer_reader_next_import; #define grpc_byte_buffer_reader_next grpc_byte_buffer_reader_next_import +typedef int(*grpc_byte_buffer_reader_peek_type)(grpc_byte_buffer_reader* reader, grpc_slice** slice); +extern grpc_byte_buffer_reader_peek_type grpc_byte_buffer_reader_peek_import; +#define grpc_byte_buffer_reader_peek grpc_byte_buffer_reader_peek_import typedef grpc_slice(*grpc_byte_buffer_reader_readall_type)(grpc_byte_buffer_reader* reader); extern grpc_byte_buffer_reader_readall_type grpc_byte_buffer_reader_readall_import; #define grpc_byte_buffer_reader_readall grpc_byte_buffer_reader_readall_import diff --git a/src/ruby/ext/grpc/rb_server.c b/src/ruby/ext/grpc/rb_server.c index 2931f344092..4396de1c335 100644 --- a/src/ruby/ext/grpc/rb_server.c +++ b/src/ruby/ext/grpc/rb_server.c @@ -86,8 +86,7 @@ static void grpc_rb_server_maybe_destroy(grpc_rb_server* server) { } } -/* Destroys server instances. */ -static void grpc_rb_server_free(void* p) { +static void grpc_rb_server_free_internal(void* p) { grpc_rb_server* svr = NULL; gpr_timespec deadline; if (p == NULL) { @@ -104,6 +103,12 @@ static void grpc_rb_server_free(void* p) { xfree(p); } +/* Destroys server instances. */ +static void grpc_rb_server_free(void* p) { + grpc_rb_server_free_internal(p); + grpc_ruby_shutdown(); +} + static const rb_data_type_t grpc_rb_server_data_type = { "grpc_server", {GRPC_RB_GC_NOT_MARKED, @@ -123,6 +128,7 @@ static const rb_data_type_t grpc_rb_server_data_type = { /* Allocates grpc_rb_server instances. */ static VALUE grpc_rb_server_alloc(VALUE cls) { + grpc_ruby_init(); grpc_rb_server* wrapper = ALLOC(grpc_rb_server); wrapper->wrapped = NULL; wrapper->destroy_done = 0; @@ -142,8 +148,6 @@ static VALUE grpc_rb_server_init(VALUE self, VALUE channel_args) { grpc_channel_args args; MEMZERO(&args, grpc_channel_args, 1); - grpc_ruby_once_init(); - cq = grpc_completion_queue_create_for_pluck(NULL); TypedData_Get_Struct(self, grpc_rb_server, &grpc_rb_server_data_type, wrapper); diff --git a/src/ruby/lib/grpc/errors.rb b/src/ruby/lib/grpc/errors.rb index 0c15c2f3bac..0b27bee1b9c 100644 --- a/src/ruby/lib/grpc/errors.rb +++ b/src/ruby/lib/grpc/errors.rb @@ -42,12 +42,31 @@ module GRPC @metadata = metadata end - # Converts the exception to a GRPC::Status for use in the networking + # Converts the exception to a {Struct::Status} for use in the networking # wrapper layer. # - # @return [Status] with the same code and details + # @return [Struct::Status] with the same code and details def to_status - Struct::Status.new(code, details, @metadata) + Struct::Status.new(code, details, metadata) + end + + # Converts the exception to a deserialized {Google::Rpc::Status} object. + # Returns `nil` if the `grpc-status-details-bin` trailer could not be + # converted to a {Google::Rpc::Status} due to the server not providing + # the necessary trailers. + # + # @return [Google::Rpc::Status, nil] + def to_rpc_status + # Lazily require google_rpc_status_utils to scope + # loading protobuf_c.so to the users of this method. + require_relative './google_rpc_status_utils' + status = to_status + return if status.nil? + GoogleRpcStatusUtils.extract_google_rpc_status(status) + rescue Google::Protobuf::ParseError => parse_error + GRPC.logger.warn('parse error: to_rpc_status failed') + GRPC.logger.warn(parse_error) + nil end def self.new_status_exception(code, details = 'unknown cause', diff --git a/src/ruby/lib/grpc/generic/bidi_call.rb b/src/ruby/lib/grpc/generic/bidi_call.rb index ffb232b8271..a4d4af65ef4 100644 --- a/src/ruby/lib/grpc/generic/bidi_call.rb +++ b/src/ruby/lib/grpc/generic/bidi_call.rb @@ -224,7 +224,7 @@ module GRPC set_input_stream_done.call end GRPC.logger.debug('bidi-read-loop: finished') - # Make sure that the write loop is done done before finishing the call. + # Make sure that the write loop is done before finishing the call. # Note that blocking is ok at this point because we've already received # a status @enq_th.join if is_client diff --git a/src/ruby/lib/grpc/generic/rpc_server.rb b/src/ruby/lib/grpc/generic/rpc_server.rb index 3b5a0ce27f3..3d34419643e 100644 --- a/src/ruby/lib/grpc/generic/rpc_server.rb +++ b/src/ruby/lib/grpc/generic/rpc_server.rb @@ -202,7 +202,7 @@ module GRPC # forcing an abrupt exit to each thread. # # * connect_md_proc: - # when non-nil is a proc for determining metadata to to send back the client + # when non-nil is a proc for determining metadata to send back the client # on receiving an invocation req. The proc signature is: # {key: val, ..} func(method_name, {key: val, ...}) # @@ -217,7 +217,7 @@ module GRPC def initialize(pool_size: DEFAULT_POOL_SIZE, max_waiting_requests: DEFAULT_MAX_WAITING_REQUESTS, poll_period: DEFAULT_POLL_PERIOD, - pool_keep_alive: GRPC::RpcServer::DEFAULT_POOL_SIZE, + pool_keep_alive: Pool::DEFAULT_KEEP_ALIVE, connect_md_proc: nil, server_args: {}, interceptors: []) @@ -240,6 +240,13 @@ module GRPC # the call has no impact if the server is already stopped, otherwise # server's current call loop is it's last. def stop + # if called via run_till_terminated_or_interrupted, + # signal stop_server_thread and dont do anything + if @stop_server.nil? == false && @stop_server == false + @stop_server = true + @stop_server_cv.broadcast + return + end @run_mutex.synchronize do fail 'Cannot stop before starting' if @running_state == :not_started return if @running_state != :running @@ -354,6 +361,60 @@ module GRPC alias_method :run_till_terminated, :run + # runs the server with signal handlers + # @param signals + # List of String, Integer or both representing signals that the user + # would like to send to the server for graceful shutdown + # @param wait_interval (optional) + # Integer seconds that user would like stop_server_thread to poll + # stop_server + def run_till_terminated_or_interrupted(signals, wait_interval = 60) + @stop_server = false + @stop_server_mu = Mutex.new + @stop_server_cv = ConditionVariable.new + + @stop_server_thread = Thread.new do + loop do + break if @stop_server + @stop_server_mu.synchronize do + @stop_server_cv.wait(@stop_server_mu, wait_interval) + end + end + + # stop is surrounded by mutex, should handle multiple calls to stop + # correctly + stop + end + + valid_signals = Signal.list + + # register signal handlers + signals.each do |sig| + # input validation + if sig.class == String + sig.upcase! + if sig.start_with?('SIG') + # cut out the SIG prefix to see if valid signal + sig = sig[3..-1] + end + end + + # register signal traps for all valid signals + if valid_signals.value?(sig) || valid_signals.key?(sig) + Signal.trap(sig) do + @stop_server = true + @stop_server_cv.broadcast + end + else + fail "#{sig} not a valid signal" + end + end + + run + + @stop_server_thread.join + end + # Sends RESOURCE_EXHAUSTED if there are too many unprocessed jobs def available?(an_rpc) return an_rpc if @pool.ready_for_work? diff --git a/src/ruby/lib/grpc/generic/service.rb b/src/ruby/lib/grpc/generic/service.rb index 4764217406b..169a62f11d3 100644 --- a/src/ruby/lib/grpc/generic/service.rb +++ b/src/ruby/lib/grpc/generic/service.rb @@ -95,7 +95,7 @@ module GRPC rpc_descs[name] = RpcDesc.new(name, input, output, marshal_class_method, unmarshal_class_method) - define_method(GenericService.underscore(name.to_s).to_sym) do |_, _| + define_method(GenericService.underscore(name.to_s).to_sym) do |*| fail GRPC::BadStatus.new_status_exception( GRPC::Core::StatusCodes::UNIMPLEMENTED) end diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb index 243d5666451..75e6191216d 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.17.0.dev' + VERSION = '1.22.0.dev' end diff --git a/src/ruby/pb/README.md b/src/ruby/pb/README.md index d9e30bbc854..49327fe31e7 100644 --- a/src/ruby/pb/README.md +++ b/src/ruby/pb/README.md @@ -7,7 +7,7 @@ code to them. PREREQUISITES ------------- -The code is is generated using the protoc (> 3.0.0.alpha.1) and the +The code is generated using the protoc (> 3.0.0.alpha.1) and the grpc_ruby_plugin. These must be installed to regenerate the IDL defined classes, but that's not necessary just to use them. diff --git a/src/ruby/pb/grpc/health/checker.rb b/src/ruby/pb/grpc/health/checker.rb index c492455d8ff..7ad68409dd4 100644 --- a/src/ruby/pb/grpc/health/checker.rb +++ b/src/ruby/pb/grpc/health/checker.rb @@ -14,7 +14,6 @@ require 'grpc' require 'grpc/health/v1/health_services_pb' -require 'thread' module Grpc # Health contains classes and modules that support providing a health check @@ -37,9 +36,9 @@ module Grpc @status_mutex.synchronize do status = @statuses["#{req.service}"] end - if status.nil? + if status.nil? fail GRPC::BadStatus.new_status_exception(StatusCodes::NOT_FOUND) - end + end HealthCheckResponse.new(status: status) end diff --git a/src/ruby/pb/grpc/health/v1/health_pb.rb b/src/ruby/pb/grpc/health/v1/health_pb.rb index aa87a93918b..c11dbf48418 100644 --- a/src/ruby/pb/grpc/health/v1/health_pb.rb +++ b/src/ruby/pb/grpc/health/v1/health_pb.rb @@ -4,16 +4,19 @@ require 'google/protobuf' Google::Protobuf::DescriptorPool.generated_pool.build do - add_message "grpc.health.v1.HealthCheckRequest" do - optional :service, :string, 1 - end - add_message "grpc.health.v1.HealthCheckResponse" do - optional :status, :enum, 1, "grpc.health.v1.HealthCheckResponse.ServingStatus" - end - add_enum "grpc.health.v1.HealthCheckResponse.ServingStatus" do - value :UNKNOWN, 0 - value :SERVING, 1 - value :NOT_SERVING, 2 + add_file("grpc/health/v1/health.proto", :syntax => :proto3) do + add_message "grpc.health.v1.HealthCheckRequest" do + optional :service, :string, 1 + end + add_message "grpc.health.v1.HealthCheckResponse" do + optional :status, :enum, 1, "grpc.health.v1.HealthCheckResponse.ServingStatus" + end + add_enum "grpc.health.v1.HealthCheckResponse.ServingStatus" do + value :UNKNOWN, 0 + value :SERVING, 1 + value :NOT_SERVING, 2 + value :SERVICE_UNKNOWN, 3 + end end end 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 169e160f90f..5992f1c403d 100644 --- a/src/ruby/pb/grpc/health/v1/health_services_pb.rb +++ b/src/ruby/pb/grpc/health/v1/health_services_pb.rb @@ -34,7 +34,25 @@ module Grpc self.unmarshal_class_method = :decode self.service_name = 'grpc.health.v1.Health' + # If the requested service is unknown, the call will fail with status + # NOT_FOUND. rpc :Check, HealthCheckRequest, HealthCheckResponse + # Performs a watch for the serving status of the requested service. + # The server will immediately send back a message indicating the current + # serving status. It will then subsequently send a new message whenever + # the service's serving status changes. + # + # If the requested service is unknown when the call is received, the + # server will send a message setting the serving status to + # SERVICE_UNKNOWN but will *not* terminate the call. If at some + # future point, the serving status of the service becomes known, the + # server will send a new message with the service's serving status. + # + # If the call terminates with status UNIMPLEMENTED, then clients + # should assume this method is not supported and should not retry the + # call. If the call terminates with any other status (including OK), + # clients should retry the call with appropriate exponential backoff. + rpc :Watch, HealthCheckRequest, stream(HealthCheckResponse) end Stub = Service.rpc_stub_class diff --git a/src/ruby/pb/src/proto/grpc/testing/empty_pb.rb b/src/ruby/pb/src/proto/grpc/testing/empty_pb.rb index 9c2568d6053..3e46d8525ed 100644 --- a/src/ruby/pb/src/proto/grpc/testing/empty_pb.rb +++ b/src/ruby/pb/src/proto/grpc/testing/empty_pb.rb @@ -4,7 +4,9 @@ require 'google/protobuf' Google::Protobuf::DescriptorPool.generated_pool.build do - add_message "grpc.testing.Empty" do + add_file("src/proto/grpc/testing/empty.proto", :syntax => :proto3) do + add_message "grpc.testing.Empty" do + end end end diff --git a/src/ruby/pb/src/proto/grpc/testing/messages_pb.rb b/src/ruby/pb/src/proto/grpc/testing/messages_pb.rb index e27ccd0dc04..796d4bb9ae2 100644 --- a/src/ruby/pb/src/proto/grpc/testing/messages_pb.rb +++ b/src/ruby/pb/src/proto/grpc/testing/messages_pb.rb @@ -4,62 +4,64 @@ require 'google/protobuf' Google::Protobuf::DescriptorPool.generated_pool.build do - add_message "grpc.testing.BoolValue" do - optional :value, :bool, 1 - end - add_message "grpc.testing.Payload" do - optional :type, :enum, 1, "grpc.testing.PayloadType" - optional :body, :bytes, 2 - end - add_message "grpc.testing.EchoStatus" do - optional :code, :int32, 1 - optional :message, :string, 2 - end - add_message "grpc.testing.SimpleRequest" do - optional :response_type, :enum, 1, "grpc.testing.PayloadType" - optional :response_size, :int32, 2 - optional :payload, :message, 3, "grpc.testing.Payload" - optional :fill_username, :bool, 4 - optional :fill_oauth_scope, :bool, 5 - optional :response_compressed, :message, 6, "grpc.testing.BoolValue" - optional :response_status, :message, 7, "grpc.testing.EchoStatus" - optional :expect_compressed, :message, 8, "grpc.testing.BoolValue" - end - add_message "grpc.testing.SimpleResponse" do - optional :payload, :message, 1, "grpc.testing.Payload" - optional :username, :string, 2 - optional :oauth_scope, :string, 3 - end - add_message "grpc.testing.StreamingInputCallRequest" do - optional :payload, :message, 1, "grpc.testing.Payload" - optional :expect_compressed, :message, 2, "grpc.testing.BoolValue" - end - add_message "grpc.testing.StreamingInputCallResponse" do - optional :aggregated_payload_size, :int32, 1 - end - add_message "grpc.testing.ResponseParameters" do - optional :size, :int32, 1 - optional :interval_us, :int32, 2 - optional :compressed, :message, 3, "grpc.testing.BoolValue" - end - add_message "grpc.testing.StreamingOutputCallRequest" do - optional :response_type, :enum, 1, "grpc.testing.PayloadType" - repeated :response_parameters, :message, 2, "grpc.testing.ResponseParameters" - optional :payload, :message, 3, "grpc.testing.Payload" - optional :response_status, :message, 7, "grpc.testing.EchoStatus" - end - add_message "grpc.testing.StreamingOutputCallResponse" do - optional :payload, :message, 1, "grpc.testing.Payload" - end - add_message "grpc.testing.ReconnectParams" do - optional :max_reconnect_backoff_ms, :int32, 1 - end - add_message "grpc.testing.ReconnectInfo" do - optional :passed, :bool, 1 - repeated :backoff_ms, :int32, 2 - end - add_enum "grpc.testing.PayloadType" do - value :COMPRESSABLE, 0 + add_file("src/proto/grpc/testing/messages.proto", :syntax => :proto3) do + add_message "grpc.testing.BoolValue" do + optional :value, :bool, 1 + end + add_message "grpc.testing.Payload" do + optional :type, :enum, 1, "grpc.testing.PayloadType" + optional :body, :bytes, 2 + end + add_message "grpc.testing.EchoStatus" do + optional :code, :int32, 1 + optional :message, :string, 2 + end + add_message "grpc.testing.SimpleRequest" do + optional :response_type, :enum, 1, "grpc.testing.PayloadType" + optional :response_size, :int32, 2 + optional :payload, :message, 3, "grpc.testing.Payload" + optional :fill_username, :bool, 4 + optional :fill_oauth_scope, :bool, 5 + optional :response_compressed, :message, 6, "grpc.testing.BoolValue" + optional :response_status, :message, 7, "grpc.testing.EchoStatus" + optional :expect_compressed, :message, 8, "grpc.testing.BoolValue" + end + add_message "grpc.testing.SimpleResponse" do + optional :payload, :message, 1, "grpc.testing.Payload" + optional :username, :string, 2 + optional :oauth_scope, :string, 3 + end + add_message "grpc.testing.StreamingInputCallRequest" do + optional :payload, :message, 1, "grpc.testing.Payload" + optional :expect_compressed, :message, 2, "grpc.testing.BoolValue" + end + add_message "grpc.testing.StreamingInputCallResponse" do + optional :aggregated_payload_size, :int32, 1 + end + add_message "grpc.testing.ResponseParameters" do + optional :size, :int32, 1 + optional :interval_us, :int32, 2 + optional :compressed, :message, 3, "grpc.testing.BoolValue" + end + add_message "grpc.testing.StreamingOutputCallRequest" do + optional :response_type, :enum, 1, "grpc.testing.PayloadType" + repeated :response_parameters, :message, 2, "grpc.testing.ResponseParameters" + optional :payload, :message, 3, "grpc.testing.Payload" + optional :response_status, :message, 7, "grpc.testing.EchoStatus" + end + add_message "grpc.testing.StreamingOutputCallResponse" do + optional :payload, :message, 1, "grpc.testing.Payload" + end + add_message "grpc.testing.ReconnectParams" do + optional :max_reconnect_backoff_ms, :int32, 1 + end + add_message "grpc.testing.ReconnectInfo" do + optional :passed, :bool, 1 + repeated :backoff_ms, :int32, 2 + end + add_enum "grpc.testing.PayloadType" do + value :COMPRESSABLE, 0 + end end end diff --git a/src/ruby/pb/src/proto/grpc/testing/test_pb.rb b/src/ruby/pb/src/proto/grpc/testing/test_pb.rb index 2cc98630314..ed4b5b5e1e7 100644 --- a/src/ruby/pb/src/proto/grpc/testing/test_pb.rb +++ b/src/ruby/pb/src/proto/grpc/testing/test_pb.rb @@ -6,6 +6,8 @@ require 'google/protobuf' require 'src/proto/grpc/testing/empty_pb' require 'src/proto/grpc/testing/messages_pb' Google::Protobuf::DescriptorPool.generated_pool.build do + add_file("src/proto/grpc/testing/test.proto", :syntax => :proto3) do + end end module Grpc diff --git a/src/ruby/pb/test/client.rb b/src/ruby/pb/test/client.rb index b2303c6e142..03f3d9001aa 100755 --- a/src/ruby/pb/test/client.rb +++ b/src/ruby/pb/test/client.rb @@ -111,10 +111,13 @@ def create_stub(opts) if opts.secure creds = ssl_creds(opts.use_test_ca) stub_opts = { - channel_args: { - GRPC::Core::Channel::SSL_TARGET => opts.server_host_override - } + channel_args: {} } + unless opts.server_host_override.empty? + stub_opts[:channel_args].merge!({ + GRPC::Core::Channel::SSL_TARGET => opts.server_host_override + }) + end # Add service account creds if specified wants_creds = %w(all compute_engine_creds service_account_creds) @@ -603,7 +606,7 @@ class NamedTests if not op.metadata.has_key?(initial_metadata_key) fail AssertionError, "Expected initial metadata. None received" elsif op.metadata[initial_metadata_key] != metadata[initial_metadata_key] - fail AssertionError, + fail AssertionError, "Expected initial metadata: #{metadata[initial_metadata_key]}. "\ "Received: #{op.metadata[initial_metadata_key]}" end @@ -611,7 +614,7 @@ class NamedTests fail AssertionError, "Expected trailing metadata. None received" elsif op.trailing_metadata[trailing_metadata_key] != metadata[trailing_metadata_key] - fail AssertionError, + fail AssertionError, "Expected trailing metadata: #{metadata[trailing_metadata_key]}. "\ "Received: #{op.trailing_metadata[trailing_metadata_key]}" end @@ -639,7 +642,7 @@ class NamedTests fail AssertionError, "Expected trailing metadata. None received" elsif duplex_op.trailing_metadata[trailing_metadata_key] != metadata[trailing_metadata_key] - fail AssertionError, + fail AssertionError, "Expected trailing metadata: #{metadata[trailing_metadata_key]}. "\ "Received: #{duplex_op.trailing_metadata[trailing_metadata_key]}" end @@ -710,7 +713,7 @@ Args = Struct.new(:default_service_account, :server_host, :server_host_override, # validates the command line options, returning them as a Hash. def parse_args args = Args.new - args.server_host_override = 'foo.test.google.fr' + args.server_host_override = '' OptionParser.new do |opts| opts.on('--oauth_scope scope', 'Scope for OAuth tokens') { |v| args['oauth_scope'] = v } diff --git a/src/ruby/qps/proxy-worker.rb b/src/ruby/qps/proxy-worker.rb index 5f23d896cc5..f09b5c3475a 100755 --- a/src/ruby/qps/proxy-worker.rb +++ b/src/ruby/qps/proxy-worker.rb @@ -48,7 +48,7 @@ class ProxyBenchmarkClientServiceImpl < Grpc::Testing::ProxyClientService::Servi if @use_c_ext puts "Use protobuf c extension" command = "php -d extension=" + File.expand_path(File.dirname(__FILE__)) + - "/../../php/tests/qps/vendor/google/protobuf/php/ext/google/protobuf/modules/protobuf.so " + + "/../../../third_party/protobuf/php/ext/google/protobuf/modules/protobuf.so " + "-d extension=" + File.expand_path(File.dirname(__FILE__)) + "/../../php/ext/grpc/modules/grpc.so " + File.expand_path(File.dirname(__FILE__)) + "/" + @php_client_bin + " " + @mytarget + " #{chan%@config.server_targets.length}" else diff --git a/src/ruby/qps/src/proto/grpc/core/stats_pb.rb b/src/ruby/qps/src/proto/grpc/core/stats_pb.rb index 59c057820bf..b75ce043fbb 100644 --- a/src/ruby/qps/src/proto/grpc/core/stats_pb.rb +++ b/src/ruby/qps/src/proto/grpc/core/stats_pb.rb @@ -4,22 +4,24 @@ 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" + add_file("src/proto/grpc/core/stats.proto", :syntax => :proto3) 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 - add_message "grpc.core.Stats" do - repeated :metrics, :message, 1, "grpc.core.Metric" end end diff --git a/src/ruby/qps/src/proto/grpc/testing/benchmark_service_pb.rb b/src/ruby/qps/src/proto/grpc/testing/benchmark_service_pb.rb index 0bd3625f3d4..3f14f441730 100644 --- a/src/ruby/qps/src/proto/grpc/testing/benchmark_service_pb.rb +++ b/src/ruby/qps/src/proto/grpc/testing/benchmark_service_pb.rb @@ -5,6 +5,8 @@ require 'google/protobuf' require 'src/proto/grpc/testing/messages_pb' Google::Protobuf::DescriptorPool.generated_pool.build do + add_file("src/proto/grpc/testing/benchmark_service.proto", :syntax => :proto3) do + end end module Grpc 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 5acc7fc0c6b..1053e504621 100644 --- a/src/ruby/qps/src/proto/grpc/testing/control_pb.rb +++ b/src/ruby/qps/src/proto/grpc/testing/control_pb.rb @@ -6,152 +6,157 @@ require 'google/protobuf' require 'src/proto/grpc/testing/payloads_pb' require 'src/proto/grpc/testing/stats_pb' Google::Protobuf::DescriptorPool.generated_pool.build do - add_message "grpc.testing.PoissonParams" do - optional :offered_load, :double, 1 - end - add_message "grpc.testing.ClosedLoopParams" do - end - add_message "grpc.testing.LoadParams" do - oneof :load do - optional :closed_loop, :message, 1, "grpc.testing.ClosedLoopParams" - optional :poisson, :message, 2, "grpc.testing.PoissonParams" + add_file("src/proto/grpc/testing/control.proto", :syntax => :proto3) do + add_message "grpc.testing.PoissonParams" do + optional :offered_load, :double, 1 end - end - 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 + add_message "grpc.testing.ClosedLoopParams" do end - end - add_message "grpc.testing.ClientConfig" do - repeated :server_targets, :string, 1 - optional :client_type, :enum, 2, "grpc.testing.ClientType" - optional :security_params, :message, 3, "grpc.testing.SecurityParams" - optional :outstanding_rpcs_per_channel, :int32, 4 - optional :client_channels, :int32, 5 - optional :async_client_threads, :int32, 7 - optional :rpc_type, :enum, 8, "grpc.testing.RpcType" - optional :load_params, :message, 10, "grpc.testing.LoadParams" - optional :payload_config, :message, 11, "grpc.testing.PayloadConfig" - optional :histogram_params, :message, 12, "grpc.testing.HistogramParams" - 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" - end - add_message "grpc.testing.Mark" do - optional :reset, :bool, 1 - end - add_message "grpc.testing.ClientArgs" do - oneof :argtype do - optional :setup, :message, 1, "grpc.testing.ClientConfig" - optional :mark, :message, 2, "grpc.testing.Mark" + add_message "grpc.testing.LoadParams" do + oneof :load do + optional :closed_loop, :message, 1, "grpc.testing.ClosedLoopParams" + optional :poisson, :message, 2, "grpc.testing.PoissonParams" + end end - end - add_message "grpc.testing.ServerConfig" do - optional :server_type, :enum, 1, "grpc.testing.ServerType" - optional :security_params, :message, 2, "grpc.testing.SecurityParams" - optional :port, :int32, 4 - optional :async_server_threads, :int32, 7 - optional :core_limit, :int32, 8 - 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 - optional :setup, :message, 1, "grpc.testing.ServerConfig" - optional :mark, :message, 2, "grpc.testing.Mark" + 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 + optional :client_type, :enum, 2, "grpc.testing.ClientType" + optional :security_params, :message, 3, "grpc.testing.SecurityParams" + optional :outstanding_rpcs_per_channel, :int32, 4 + optional :client_channels, :int32, 5 + optional :async_client_threads, :int32, 7 + optional :rpc_type, :enum, 8, "grpc.testing.RpcType" + optional :load_params, :message, 10, "grpc.testing.LoadParams" + optional :payload_config, :message, 11, "grpc.testing.PayloadConfig" + optional :histogram_params, :message, 12, "grpc.testing.HistogramParams" + 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 + optional :median_latency_collection_interval_millis, :int32, 20 + end + add_message "grpc.testing.ClientStatus" do + optional :stats, :message, 1, "grpc.testing.ClientStats" + end + add_message "grpc.testing.Mark" do + optional :reset, :bool, 1 + end + add_message "grpc.testing.ClientArgs" do + oneof :argtype do + optional :setup, :message, 1, "grpc.testing.ClientConfig" + optional :mark, :message, 2, "grpc.testing.Mark" + end + end + add_message "grpc.testing.ServerConfig" do + optional :server_type, :enum, 1, "grpc.testing.ServerType" + optional :security_params, :message, 2, "grpc.testing.SecurityParams" + optional :port, :int32, 4 + optional :async_server_threads, :int32, 7 + optional :core_limit, :int32, 8 + 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 + optional :setup, :message, 1, "grpc.testing.ServerConfig" + optional :mark, :message, 2, "grpc.testing.Mark" + end + end + add_message "grpc.testing.ServerStatus" do + optional :stats, :message, 1, "grpc.testing.ServerStats" + optional :port, :int32, 2 + optional :cores, :int32, 3 + end + add_message "grpc.testing.CoreRequest" do + end + add_message "grpc.testing.CoreResponse" do + optional :cores, :int32, 1 + end + add_message "grpc.testing.Void" do + end + add_message "grpc.testing.Scenario" do + optional :name, :string, 1 + optional :client_config, :message, 2, "grpc.testing.ClientConfig" + optional :num_clients, :int32, 3 + optional :server_config, :message, 4, "grpc.testing.ServerConfig" + optional :num_servers, :int32, 5 + optional :warmup_seconds, :int32, 6 + optional :benchmark_seconds, :int32, 7 + optional :spawn_local_worker_count, :int32, 8 + end + add_message "grpc.testing.Scenarios" do + repeated :scenarios, :message, 1, "grpc.testing.Scenario" + end + add_message "grpc.testing.ScenarioResultSummary" do + optional :qps, :double, 1 + optional :qps_per_server_core, :double, 2 + optional :server_system_time, :double, 3 + optional :server_user_time, :double, 4 + optional :client_system_time, :double, 5 + optional :client_user_time, :double, 6 + optional :latency_50, :double, 7 + optional :latency_90, :double, 8 + 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" + optional :latencies, :message, 2, "grpc.testing.HistogramData" + repeated :client_stats, :message, 3, "grpc.testing.ClientStats" + repeated :server_stats, :message, 4, "grpc.testing.ServerStats" + repeated :server_cores, :int32, 5 + 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 + value :ASYNC_CLIENT, 1 + value :OTHER_CLIENT, 2 + value :CALLBACK_CLIENT, 3 + end + add_enum "grpc.testing.ServerType" do + value :SYNC_SERVER, 0 + value :ASYNC_SERVER, 1 + value :ASYNC_GENERIC_SERVER, 2 + value :OTHER_SERVER, 3 + value :CALLBACK_SERVER, 4 + end + 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 - add_message "grpc.testing.ServerStatus" do - optional :stats, :message, 1, "grpc.testing.ServerStats" - optional :port, :int32, 2 - optional :cores, :int32, 3 - end - add_message "grpc.testing.CoreRequest" do - end - add_message "grpc.testing.CoreResponse" do - optional :cores, :int32, 1 - end - add_message "grpc.testing.Void" do - end - add_message "grpc.testing.Scenario" do - optional :name, :string, 1 - optional :client_config, :message, 2, "grpc.testing.ClientConfig" - optional :num_clients, :int32, 3 - optional :server_config, :message, 4, "grpc.testing.ServerConfig" - optional :num_servers, :int32, 5 - optional :warmup_seconds, :int32, 6 - optional :benchmark_seconds, :int32, 7 - optional :spawn_local_worker_count, :int32, 8 - end - add_message "grpc.testing.Scenarios" do - repeated :scenarios, :message, 1, "grpc.testing.Scenario" - end - add_message "grpc.testing.ScenarioResultSummary" do - optional :qps, :double, 1 - optional :qps_per_server_core, :double, 2 - optional :server_system_time, :double, 3 - optional :server_user_time, :double, 4 - optional :client_system_time, :double, 5 - optional :client_user_time, :double, 6 - optional :latency_50, :double, 7 - optional :latency_90, :double, 8 - 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" - optional :latencies, :message, 2, "grpc.testing.HistogramData" - repeated :client_stats, :message, 3, "grpc.testing.ClientStats" - repeated :server_stats, :message, 4, "grpc.testing.ServerStats" - repeated :server_cores, :int32, 5 - 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 - value :ASYNC_CLIENT, 1 - value :OTHER_CLIENT, 2 - end - add_enum "grpc.testing.ServerType" do - value :SYNC_SERVER, 0 - value :ASYNC_SERVER, 1 - value :ASYNC_GENERIC_SERVER, 2 - value :OTHER_SERVER, 3 - end - 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 diff --git a/src/ruby/qps/src/proto/grpc/testing/messages_pb.rb b/src/ruby/qps/src/proto/grpc/testing/messages_pb.rb index e27ccd0dc04..796d4bb9ae2 100644 --- a/src/ruby/qps/src/proto/grpc/testing/messages_pb.rb +++ b/src/ruby/qps/src/proto/grpc/testing/messages_pb.rb @@ -4,62 +4,64 @@ require 'google/protobuf' Google::Protobuf::DescriptorPool.generated_pool.build do - add_message "grpc.testing.BoolValue" do - optional :value, :bool, 1 - end - add_message "grpc.testing.Payload" do - optional :type, :enum, 1, "grpc.testing.PayloadType" - optional :body, :bytes, 2 - end - add_message "grpc.testing.EchoStatus" do - optional :code, :int32, 1 - optional :message, :string, 2 - end - add_message "grpc.testing.SimpleRequest" do - optional :response_type, :enum, 1, "grpc.testing.PayloadType" - optional :response_size, :int32, 2 - optional :payload, :message, 3, "grpc.testing.Payload" - optional :fill_username, :bool, 4 - optional :fill_oauth_scope, :bool, 5 - optional :response_compressed, :message, 6, "grpc.testing.BoolValue" - optional :response_status, :message, 7, "grpc.testing.EchoStatus" - optional :expect_compressed, :message, 8, "grpc.testing.BoolValue" - end - add_message "grpc.testing.SimpleResponse" do - optional :payload, :message, 1, "grpc.testing.Payload" - optional :username, :string, 2 - optional :oauth_scope, :string, 3 - end - add_message "grpc.testing.StreamingInputCallRequest" do - optional :payload, :message, 1, "grpc.testing.Payload" - optional :expect_compressed, :message, 2, "grpc.testing.BoolValue" - end - add_message "grpc.testing.StreamingInputCallResponse" do - optional :aggregated_payload_size, :int32, 1 - end - add_message "grpc.testing.ResponseParameters" do - optional :size, :int32, 1 - optional :interval_us, :int32, 2 - optional :compressed, :message, 3, "grpc.testing.BoolValue" - end - add_message "grpc.testing.StreamingOutputCallRequest" do - optional :response_type, :enum, 1, "grpc.testing.PayloadType" - repeated :response_parameters, :message, 2, "grpc.testing.ResponseParameters" - optional :payload, :message, 3, "grpc.testing.Payload" - optional :response_status, :message, 7, "grpc.testing.EchoStatus" - end - add_message "grpc.testing.StreamingOutputCallResponse" do - optional :payload, :message, 1, "grpc.testing.Payload" - end - add_message "grpc.testing.ReconnectParams" do - optional :max_reconnect_backoff_ms, :int32, 1 - end - add_message "grpc.testing.ReconnectInfo" do - optional :passed, :bool, 1 - repeated :backoff_ms, :int32, 2 - end - add_enum "grpc.testing.PayloadType" do - value :COMPRESSABLE, 0 + add_file("src/proto/grpc/testing/messages.proto", :syntax => :proto3) do + add_message "grpc.testing.BoolValue" do + optional :value, :bool, 1 + end + add_message "grpc.testing.Payload" do + optional :type, :enum, 1, "grpc.testing.PayloadType" + optional :body, :bytes, 2 + end + add_message "grpc.testing.EchoStatus" do + optional :code, :int32, 1 + optional :message, :string, 2 + end + add_message "grpc.testing.SimpleRequest" do + optional :response_type, :enum, 1, "grpc.testing.PayloadType" + optional :response_size, :int32, 2 + optional :payload, :message, 3, "grpc.testing.Payload" + optional :fill_username, :bool, 4 + optional :fill_oauth_scope, :bool, 5 + optional :response_compressed, :message, 6, "grpc.testing.BoolValue" + optional :response_status, :message, 7, "grpc.testing.EchoStatus" + optional :expect_compressed, :message, 8, "grpc.testing.BoolValue" + end + add_message "grpc.testing.SimpleResponse" do + optional :payload, :message, 1, "grpc.testing.Payload" + optional :username, :string, 2 + optional :oauth_scope, :string, 3 + end + add_message "grpc.testing.StreamingInputCallRequest" do + optional :payload, :message, 1, "grpc.testing.Payload" + optional :expect_compressed, :message, 2, "grpc.testing.BoolValue" + end + add_message "grpc.testing.StreamingInputCallResponse" do + optional :aggregated_payload_size, :int32, 1 + end + add_message "grpc.testing.ResponseParameters" do + optional :size, :int32, 1 + optional :interval_us, :int32, 2 + optional :compressed, :message, 3, "grpc.testing.BoolValue" + end + add_message "grpc.testing.StreamingOutputCallRequest" do + optional :response_type, :enum, 1, "grpc.testing.PayloadType" + repeated :response_parameters, :message, 2, "grpc.testing.ResponseParameters" + optional :payload, :message, 3, "grpc.testing.Payload" + optional :response_status, :message, 7, "grpc.testing.EchoStatus" + end + add_message "grpc.testing.StreamingOutputCallResponse" do + optional :payload, :message, 1, "grpc.testing.Payload" + end + add_message "grpc.testing.ReconnectParams" do + optional :max_reconnect_backoff_ms, :int32, 1 + end + add_message "grpc.testing.ReconnectInfo" do + optional :passed, :bool, 1 + repeated :backoff_ms, :int32, 2 + end + add_enum "grpc.testing.PayloadType" do + value :COMPRESSABLE, 0 + end end end diff --git a/src/ruby/qps/src/proto/grpc/testing/payloads_pb.rb b/src/ruby/qps/src/proto/grpc/testing/payloads_pb.rb index ae8855f6850..6d55793fba4 100644 --- a/src/ruby/qps/src/proto/grpc/testing/payloads_pb.rb +++ b/src/ruby/qps/src/proto/grpc/testing/payloads_pb.rb @@ -4,21 +4,23 @@ require 'google/protobuf' Google::Protobuf::DescriptorPool.generated_pool.build do - add_message "grpc.testing.ByteBufferParams" do - optional :req_size, :int32, 1 - optional :resp_size, :int32, 2 - end - add_message "grpc.testing.SimpleProtoParams" do - optional :req_size, :int32, 1 - optional :resp_size, :int32, 2 - end - add_message "grpc.testing.ComplexProtoParams" do - end - add_message "grpc.testing.PayloadConfig" do - oneof :payload do - optional :bytebuf_params, :message, 1, "grpc.testing.ByteBufferParams" - optional :simple_params, :message, 2, "grpc.testing.SimpleProtoParams" - optional :complex_params, :message, 3, "grpc.testing.ComplexProtoParams" + add_file("src/proto/grpc/testing/payloads.proto", :syntax => :proto3) do + add_message "grpc.testing.ByteBufferParams" do + optional :req_size, :int32, 1 + optional :resp_size, :int32, 2 + end + add_message "grpc.testing.SimpleProtoParams" do + optional :req_size, :int32, 1 + optional :resp_size, :int32, 2 + end + add_message "grpc.testing.ComplexProtoParams" do + end + add_message "grpc.testing.PayloadConfig" do + oneof :payload do + optional :bytebuf_params, :message, 1, "grpc.testing.ByteBufferParams" + optional :simple_params, :message, 2, "grpc.testing.SimpleProtoParams" + optional :complex_params, :message, 3, "grpc.testing.ComplexProtoParams" + end end end end diff --git a/src/ruby/qps/src/proto/grpc/testing/report_qps_scenario_service_pb.rb b/src/ruby/qps/src/proto/grpc/testing/report_qps_scenario_service_pb.rb index 1b43e372997..03461a4c556 100644 --- a/src/ruby/qps/src/proto/grpc/testing/report_qps_scenario_service_pb.rb +++ b/src/ruby/qps/src/proto/grpc/testing/report_qps_scenario_service_pb.rb @@ -5,6 +5,8 @@ require 'google/protobuf' require 'src/proto/grpc/testing/control_pb' Google::Protobuf::DescriptorPool.generated_pool.build do + add_file("src/proto/grpc/testing/report_qps_scenario_service.proto", :syntax => :proto3) do + end end module Grpc 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 2069840168a..dd25d3159f3 100644 --- a/src/ruby/qps/src/proto/grpc/testing/stats_pb.rb +++ b/src/ruby/qps/src/proto/grpc/testing/stats_pb.rb @@ -5,39 +5,41 @@ 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 - optional :max_possible, :double, 2 - end - add_message "grpc.testing.HistogramData" do - repeated :bucket, :uint32, 1 - optional :min_seen, :double, 2 - optional :max_seen, :double, 3 - optional :sum, :double, 4 - 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" + add_file("src/proto/grpc/testing/stats.proto", :syntax => :proto3) 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 + optional :max_possible, :double, 2 + end + add_message "grpc.testing.HistogramData" do + repeated :bucket, :uint32, 1 + optional :min_seen, :double, 2 + optional :max_seen, :double, 3 + optional :sum, :double, 4 + 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 end diff --git a/src/ruby/qps/src/proto/grpc/testing/worker_service_pb.rb b/src/ruby/qps/src/proto/grpc/testing/worker_service_pb.rb index 18b63452b6e..2fdef48e933 100644 --- a/src/ruby/qps/src/proto/grpc/testing/worker_service_pb.rb +++ b/src/ruby/qps/src/proto/grpc/testing/worker_service_pb.rb @@ -5,6 +5,8 @@ require 'google/protobuf' require 'src/proto/grpc/testing/control_pb' Google::Protobuf::DescriptorPool.generated_pool.build do + add_file("src/proto/grpc/testing/worker_service.proto", :syntax => :proto3) do + end end module Grpc diff --git a/src/ruby/spec/errors_spec.rb b/src/ruby/spec/errors_spec.rb new file mode 100644 index 00000000000..bf27a537405 --- /dev/null +++ b/src/ruby/spec/errors_spec.rb @@ -0,0 +1,141 @@ +# 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. + +require 'spec_helper' +require 'google/protobuf/well_known_types' +require_relative '../pb/src/proto/grpc/testing/messages_pb' + +describe GRPC::BadStatus do + describe :attributes do + it 'has attributes' do + code = 1 + details = 'details' + metadata = { 'key' => 'val' } + + exception = GRPC::BadStatus.new(code, details, metadata) + + expect(exception.code).to eq code + expect(exception.details).to eq details + expect(exception.metadata).to eq metadata + end + end + + describe :new_status_exception do + let(:codes_and_classes) do + [ + [GRPC::Core::StatusCodes::OK, GRPC::Ok], + [GRPC::Core::StatusCodes::CANCELLED, GRPC::Cancelled], + [GRPC::Core::StatusCodes::UNKNOWN, GRPC::Unknown], + [GRPC::Core::StatusCodes::INVALID_ARGUMENT, GRPC::InvalidArgument], + [GRPC::Core::StatusCodes::DEADLINE_EXCEEDED, GRPC::DeadlineExceeded], + [GRPC::Core::StatusCodes::NOT_FOUND, GRPC::NotFound], + [GRPC::Core::StatusCodes::ALREADY_EXISTS, GRPC::AlreadyExists], + [GRPC::Core::StatusCodes::PERMISSION_DENIED, GRPC::PermissionDenied], + [GRPC::Core::StatusCodes::UNAUTHENTICATED, GRPC::Unauthenticated], + [GRPC::Core::StatusCodes::RESOURCE_EXHAUSTED, GRPC::ResourceExhausted], + [GRPC::Core::StatusCodes::FAILED_PRECONDITION, GRPC::FailedPrecondition], + [GRPC::Core::StatusCodes::ABORTED, GRPC::Aborted], + [GRPC::Core::StatusCodes::OUT_OF_RANGE, GRPC::OutOfRange], + [GRPC::Core::StatusCodes::UNIMPLEMENTED, GRPC::Unimplemented], + [GRPC::Core::StatusCodes::INTERNAL, GRPC::Internal], + [GRPC::Core::StatusCodes::UNAVAILABLE, GRPC::Unavailable], + [GRPC::Core::StatusCodes::DATA_LOSS, GRPC::DataLoss], + [99, GRPC::BadStatus] # Unknown codes default to BadStatus + ] + end + + it 'maps codes to the correct error class' do + codes_and_classes.each do |code, grpc_error_class| + exception = GRPC::BadStatus.new_status_exception(code) + + expect(exception).to be_a grpc_error_class + end + end + end + + describe :to_status do + it 'gets status' do + code = 1 + details = 'details' + metadata = { 'key' => 'val' } + + exception = GRPC::BadStatus.new(code, details, metadata) + status = Struct::Status.new(code, details, metadata) + + expect(exception.to_status).to eq status + end + end + + describe :to_rpc_status do + let(:simple_request_any) do + Google::Protobuf::Any.new.tap do |any| + any.pack( + Grpc::Testing::SimpleRequest.new( + payload: Grpc::Testing::Payload.new(body: 'request') + ) + ) + end + end + let(:simple_response_any) do + Google::Protobuf::Any.new.tap do |any| + any.pack( + Grpc::Testing::SimpleResponse.new( + payload: Grpc::Testing::Payload.new(body: 'response') + ) + ) + end + end + let(:payload_any) do + Google::Protobuf::Any.new.tap do |any| + any.pack(Grpc::Testing::Payload.new(body: 'payload')) + end + end + + it 'decodes proto values' do + rpc_status = Google::Rpc::Status.new( + code: 1, + message: 'matching message', + details: [simple_request_any, simple_response_any, payload_any] + ) + rpc_status_proto = Google::Rpc::Status.encode(rpc_status) + + code = 1 + details = 'details' + metadata = { 'grpc-status-details-bin' => rpc_status_proto } + + exception = GRPC::BadStatus.new(code, details, metadata) + + expect(exception.to_rpc_status).to eq rpc_status + end + + it 'does not raise when decoding a bad proto' do + code = 1 + details = 'details' + metadata = { 'grpc-status-details-bin' => 'notavalidprotostream' } + + exception = GRPC::BadStatus.new(code, details, metadata) + + expect(exception.to_rpc_status).to be nil + + error_msg = 'parse error: to_rpc_status failed' + error_desc = ' ' \ + 'Error occurred during parsing: Invalid wire type' + + # Check that the parse error was logged correctly + log_contents = @log_output.read + expect(log_contents).to include "WARN GRPC : #{error_msg}" + expect(log_contents).to include "WARN GRPC : #{error_desc}" + end + end +end diff --git a/src/ruby/spec/generic/rpc_server_spec.rb b/src/ruby/spec/generic/rpc_server_spec.rb index 44a61340869..924d747a79c 100644 --- a/src/ruby/spec/generic/rpc_server_spec.rb +++ b/src/ruby/spec/generic/rpc_server_spec.rb @@ -342,6 +342,28 @@ describe GRPC::RpcServer do t.join end + it 'should return UNIMPLEMENTED on unimplemented ' \ + 'methods for client_streamer', server: true do + @srv.handle(EchoService) + t = Thread.new { @srv.run } + @srv.wait_till_running + blk = proc do + stub = EchoStub.new(@host, :this_channel_is_insecure, **client_opts) + requests = [EchoMsg.new, EchoMsg.new] + stub.a_client_streaming_rpc_unimplemented(requests) + end + + begin + expect(&blk).to raise_error do |error| + expect(error).to be_a(GRPC::BadStatus) + expect(error.code).to eq(GRPC::Core::StatusCodes::UNIMPLEMENTED) + end + ensure + @srv.stop # should be call not to crash + t.join + end + end + it 'should handle multiple sequential requests', server: true do @srv.handle(EchoService) t = Thread.new { @srv.run } diff --git a/src/ruby/spec/support/services.rb b/src/ruby/spec/support/services.rb index 6e693f1cdec..438459dfd79 100644 --- a/src/ruby/spec/support/services.rb +++ b/src/ruby/spec/support/services.rb @@ -33,6 +33,7 @@ class EchoService rpc :a_client_streaming_rpc, stream(EchoMsg), EchoMsg rpc :a_server_streaming_rpc, EchoMsg, stream(EchoMsg) rpc :a_bidi_rpc, stream(EchoMsg), stream(EchoMsg) + rpc :a_client_streaming_rpc_unimplemented, stream(EchoMsg), EchoMsg attr_reader :received_md def initialize(**kw) diff --git a/src/ruby/tools/version.rb b/src/ruby/tools/version.rb index 92e85eb882b..fbd0041fa35 100644 --- a/src/ruby/tools/version.rb +++ b/src/ruby/tools/version.rb @@ -14,6 +14,6 @@ module GRPC module Tools - VERSION = '1.17.0.dev' + VERSION = '1.22.0.dev' end end diff --git a/src/upb/gen_build_yaml.py b/src/upb/gen_build_yaml.py new file mode 100755 index 00000000000..8b726d374a3 --- /dev/null +++ b/src/upb/gen_build_yaml.py @@ -0,0 +1,66 @@ +#!/usr/bin/env python2.7 + +# 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. + +# TODO: This should ideally be in upb submodule to avoid hardcoding this here. + +import re +import os +import sys +import yaml + +srcs = [ + "third_party/upb/google/protobuf/descriptor.upb.c", + "third_party/upb/upb/decode.c", + "third_party/upb/upb/def.c", + "third_party/upb/upb/encode.c", + "third_party/upb/upb/handlers.c", + "third_party/upb/upb/msg.c", + "third_party/upb/upb/msgfactory.c", + "third_party/upb/upb/sink.c", + "third_party/upb/upb/table.c", + "third_party/upb/upb/upb.c", +] + +hdrs = [ + "third_party/upb/google/protobuf/descriptor.upb.h", + "third_party/upb/upb/decode.h", + "third_party/upb/upb/def.h", + "third_party/upb/upb/encode.h", + "third_party/upb/upb/handlers.h", + "third_party/upb/upb/msg.h", + "third_party/upb/upb/msgfactory.h", + "third_party/upb/upb/sink.h", + "third_party/upb/upb/upb.h", +] + +os.chdir(os.path.dirname(sys.argv[0])+'/../..') + +out = {} + +try: + out['libs'] = [{ + 'name': 'upb', + 'defaults': 'upb', + 'build': 'private', + 'language': 'c', + 'secure': 'no', + 'src': srcs, + 'headers': hdrs, + }] +except: + pass + +print yaml.dump(out) diff --git a/summerofcode/2018/naresh.md b/summerofcode/2018/naresh.md index 0d196bd6001..d471bff5459 100644 --- a/summerofcode/2018/naresh.md +++ b/summerofcode/2018/naresh.md @@ -128,7 +128,7 @@ bazel test --spawn_strategy=standalone --genrule_strategy=standalone //src/pytho - Use `bazel build` with a `-s` flag to see the logs being printed out to standard output while building. -- Similarly, use `bazel test` with a `--test_output=streamed` to see the the +- Similarly, use `bazel test` with a `--test_output=streamed` to see the test logs while testing. Something to know while using this flag is that all tests will be run locally, without sharding, one at a time. diff --git a/templates/BUILD.gn.template b/templates/BUILD.gn.template new file mode 100644 index 00000000000..ab78308d135 --- /dev/null +++ b/templates/BUILD.gn.template @@ -0,0 +1,220 @@ +%YAML 1.2 +--- | + # GRPC Fuchsia GN build file + + # This file has been automatically generated from a template file. + # Please look at the templates directory instead. + # This file can be regenerated from the template by running + # tools/buildgen/generate_projects.sh + + # Copyright 2019 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. + + config("grpc_config") { + include_dirs = [ + ".", + "include/", + ] + defines = [ + "GRPC_USE_PROTO_LITE", + "GPR_SUPPORT_CHANNELS_FROM_FD", + "PB_FIELD_16BIT", + ] + } + <%! + def get_deps(target_dict): + deps = [] + if target_dict.get("secure", False): + deps = ["//third_party/boringssl"] + if target_dict.get("build", None) == "protoc": + deps.append("//third_party/protobuf:protoc_lib") + name = target_dict.get("name", None) + if name in ("grpc++", "grpc++_codegen_lib"): + deps.append("//third_party/protobuf:protobuf_lite") + elif name in ("grpc", "grpc_unsecure"): + deps.append("//third_party/zlib") + for d in target_dict.get("deps", []): + if d.startswith(("//", ":")): + deps.append(d) + else: + deps.append(":%s" % d) + if needs_ares(target_dict.src): + deps.append("//third_party/cares") + deps.append(":address_sorting") + if needs_nanopb(target_dict.src) and target_dict.name != "nanopb": + deps.append(":nanopb") + if needs_health_proto(target_dict.src) and target_dict.name != "health_proto": + deps.append(":health_proto") + return deps + + %><%! + def needs_ares(srcs): + return any("/c_ares/" in f for f in srcs) if srcs else False + + %><%! + def needs_nanopb(srcs): + return any(f.startswith("third_party/nanopb") + or f.endswith(".pb.h") + or f.endswith(".pb.c") + or f.endswith(".pb.cc") + or f.endswith("load_balancer_api.h") + or f.endswith("load_balancer_api.c") + for f in srcs) + + %><%! + def needs_address_sorting(sources): + return needs_ares(sources) or any("address_sorting" in s for s in sources) + + %><%! + def needs_health_proto(srcs): + return any("health.pb" in f for f in srcs) + + %><%! + def get_include_dirs(sources): + dirs = [] + if needs_ares(sources): + dirs = ["third_party/cares"] + if needs_address_sorting(sources): + dirs.append("third_party/address_sorting/include") + if needs_nanopb(sources): + dirs.append("third_party/nanopb") + return dirs + + %><%! + def strip_sources(sources, name): + return [f for f in sources + if "ruby_generator" not in f + and ("third_party/nanopb" not in f or name == "nanopb") + and ("health.pb" not in f or name == "health_proto")] + + %><%! + def get_sources(target): + return ((target.public_headers or []) + + (target.headers or []) + + (target.src or [])) + + %><%! + def get_extra_configs(target_dict): + if target_dict.get("name", "") == "grpc_cpp_plugin": + return ["//third_party/protobuf:protobuf_config"] + return [] + + %><%! + def wanted_lib(lib): + wanted_libs = ("gpr", "grpc", "grpc++", "grpc_plugin_support", "address_sorting") + return lib.build in ("all", "protoc") and lib.get("name", "") in wanted_libs + + %><%! + def wanted_binary(tgt): + wanted_binaries = ("grpc_cpp_plugin",) + return tgt.build == "protoc" and tgt.get("name", "") in wanted_binaries + + %><%! + def only_on_host_toolchain(tgt): + return tgt.get("name", "") in ("grpc_plugin_support", "grpc_cpp_plugin") + + %> + % for lib in filegroups: + % if lib.name in ("nanopb", "health_proto"): + ${cc_library(lib)} + %endif + %endfor + % for lib in libs: + % if wanted_lib(lib): + % if only_on_host_toolchain(lib): + # Only compile the plugin for the host architecture. + if (current_toolchain == host_toolchain) { + ${cc_library(lib)} + } + % else: + ${cc_library(lib)} + % endif + % endif + % endfor + % for tgt in targets: + % if wanted_binary(tgt): + % if only_on_host_toolchain(tgt): + # Only compile the plugin for the host architecture. + if (current_toolchain == host_toolchain) { + ${cc_binary(tgt)} + } + % else: + ${cc_binary(tgt)} + % endif + % endif + % endfor + <%def name="cc_library(lib)"> + <% + sources = get_sources(lib) + include_dirs = get_include_dirs(sources) + sources = strip_sources(sources, lib.name) + sources.sort() + %> + source_set("${lib.name}") { + %if sources: + sources = [ + % for src in sources: + "${src}", + % endfor + ] + %endif + deps = [ + % for dep in get_deps(lib): + "${dep}", + % endfor + ] + <% extra_configs = get_extra_configs(lib) %> + % if extra_configs: + configs += [ + % for config in extra_configs: + "${config}", + % endfor + ] + % endif + public_configs = [ + ":grpc_config", + ] + %if include_dirs: + include_dirs = [ + %for d in include_dirs: + "${d}", + %endfor + ] + %endif + } + + <%def name="cc_binary(tgt)"> + executable("${tgt.name}") { + sources = [ + % for src in tgt.src: + "${src}", + % endfor + ] + deps = [ + % for dep in get_deps(tgt): + "${dep}", + % endfor + ] + <% extra_configs = get_extra_configs(tgt) %> + % if extra_configs: + configs += [ + % for config in extra_configs: + "${config}", + % endfor + ] + % endif + public_configs = [ ":grpc_config" ] + } + + ## vim: set ft=mako:ts=2:et:sw=2 diff --git a/templates/CMakeLists.txt.template b/templates/CMakeLists.txt.template index 1628493d000..4057da40c16 100644 --- a/templates/CMakeLists.txt.template +++ b/templates/CMakeLists.txt.template @@ -53,7 +53,7 @@ deps.append("${_gRPC_BENCHMARK_LIBRARIES}") else: deps.append(d) - if target_dict.build == 'test' and target_dict.language == 'c++': + if (target_dict.build == 'test' or target_dict.build == 'private') and target_dict.language == 'c++': deps.append("${_gRPC_GFLAGS_LIBRARIES}") return deps @@ -143,7 +143,7 @@ ## Some libraries are shared even with BUILD_SHARED_LIBRARIES=OFF set(CMAKE_POSITION_INDEPENDENT_CODE TRUE) - add_definitions(-DPB_FIELD_16BIT) + add_definitions(-DPB_FIELD_32BIT) if (MSVC) include(cmake/msvc_static_runtime.cmake) @@ -239,6 +239,13 @@ get_filename_component(REL_DIR <%text>${REL_FIL} DIRECTORY) set(RELFIL_WE "<%text>${REL_DIR}/${FIL_WE}") + #if cross-compiling, find host plugin + if(CMAKE_CROSSCOMPILING) + find_program(_gRPC_CPP_PLUGIN grpc_cpp_plugin) + else() + set(_gRPC_CPP_PLUGIN $) + endif() + add_custom_command( OUTPUT <%text>"${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.grpc.pb.cc" <%text>"${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.grpc.pb.h" @@ -248,7 +255,7 @@ COMMAND <%text>${_gRPC_PROTOBUF_PROTOC_EXECUTABLE} ARGS --grpc_out=<%text>generate_mock_code=true:${_gRPC_PROTO_GENS_DIR} --cpp_out=<%text>${_gRPC_PROTO_GENS_DIR} - --plugin=protoc-gen-grpc=$ + --plugin=protoc-gen-grpc=<%text>${_gRPC_CPP_PLUGIN} <%text>${_protobuf_include_path} <%text>${REL_FIL} DEPENDS <%text>${ABS_FIL} <%text>${_gRPC_PROTOBUF_PROTOC} grpc_cpp_plugin @@ -324,12 +331,24 @@ % elif lib.name in ['grpc_csharp_ext']: if (gRPC_BUILD_CSHARP_EXT) ${cc_library(lib)} + % if any(proto_re.match(src) for src in lib.src): + if (gRPC_BUILD_CODEGEN) + % endif ${cc_install(lib)} + % if any(proto_re.match(src) for src in lib.src): + endif (gRPC_BUILD_CODEGEN) + % endif endif (gRPC_BUILD_CSHARP_EXT) % else: ${cc_library(lib)} % if not lib.build in ["tool"]: + % if any(proto_re.match(src) for src in lib.src): + if (gRPC_BUILD_CODEGEN) + % endif ${cc_install(lib)} + % if any(proto_re.match(src) for src in lib.src): + endif (gRPC_BUILD_CODEGEN) + % endif % endif % endif % endif diff --git a/templates/Makefile.template b/templates/Makefile.template index 8bb06176bf8..24bea5c2423 100644 --- a/templates/Makefile.template +++ b/templates/Makefile.template @@ -274,6 +274,28 @@ LDFLAGS += -pthread endif + # If we are installing into a non-default prefix, both + # the libraries we build, and the apps users build, + # need to know how to find the libraries they depend on. + # There is much gnashing of teeth about this subject. + # It's tricky to do that without editing images during install, + # as you don't want tests during build to find previously installed and + # now stale libraries, etc. + ifeq ($(SYSTEM),Linux) + ifneq ($(prefix),/usr) + # Linux best practice for rpath on installed files is probably: + # 1) .pc file provides -Wl,-rpath,$(prefix)/lib + # 2) binaries we install into $(prefix)/bin use -Wl,-rpath,$ORIGIN/../lib + # 3) libraries we install into $(prefix)/lib use -Wl,-rpath,$ORIGIN + # cf. https://www.akkadia.org/drepper/dsohowto.pdf + # Doing all of that right is hard, but using -Wl,-rpath,$ORIGIN is always + # safe, and solves problems seen in the wild. Note that $ORIGIN + # is a literal string interpreted much later by ld.so. Escape it + # here with a dollar sign so Make doesn't expand $O. + LDFLAGS += '-Wl,-rpath,$$ORIGIN' + endif + endif + # # The steps for cross-compiling are as follows: # First, clone and make install of grpc using the native compilers for the host. @@ -323,11 +345,11 @@ ${arg} += $(EXTRA_${arg}) % endfor - HOST_CPPFLAGS = $(CPPFLAGS) - HOST_CFLAGS = $(CFLAGS) - HOST_CXXFLAGS = $(CXXFLAGS) - HOST_LDFLAGS = $(LDFLAGS) - HOST_LDLIBS = $(LDLIBS) + HOST_CPPFLAGS += $(CPPFLAGS) + HOST_CFLAGS += $(CFLAGS) + HOST_CXXFLAGS += $(CXXFLAGS) + HOST_LDFLAGS += $(LDFLAGS) + HOST_LDLIBS += $(LDLIBS) # These are automatically computed variables. # There shouldn't be any need to change anything from now on. @@ -715,7 +737,7 @@ ifeq ($(HAS_PKG_CONFIG),true) PROTOBUF_PKG_CONFIG = true PC_REQUIRES_GRPCXX = protobuf - CPPFLAGS := $(shell $(PKG_CONFIG) --cflags protobuf) $(CPPFLAGS) + CPPFLAGS := $(CPPFLAGS) $(shell $(PKG_CONFIG) --cflags protobuf) LDFLAGS_PROTOBUF_PKG_CONFIG = $(shell $(PKG_CONFIG) --libs-only-L protobuf) ifeq ($(SYSTEM),Linux) ifneq ($(LDFLAGS_PROTOBUF_PKG_CONFIG),) diff --git a/templates/README.md b/templates/README.md index a7aeec26c7c..a8104b1ace6 100644 --- a/templates/README.md +++ b/templates/README.md @@ -41,7 +41,7 @@ filegroups: # groups of files that are automatically expanded ... libs: # list of libraries to build ... -target: # list of targets to build +targets: # list of targets to build ... ``` diff --git a/templates/gRPC-C++.podspec.template b/templates/gRPC-C++.podspec.template index ab330415af2..43cb6db66c6 100644 --- a/templates/gRPC-C++.podspec.template +++ b/templates/gRPC-C++.podspec.template @@ -96,11 +96,11 @@ return out def grpc_test_util_files(libs): - out = grpc_lib_files(libs, ("grpc_test_util", "gpr_test_util"), ("src", "headers")) + out = grpc_lib_files(libs, ("grpc_test_util",), ("src", "headers")) return out def grpc_test_util_headers(libs): - out = grpc_lib_files(libs, ("grpc_test_util", "gpr_test_util"), ("headers",)) + out = grpc_lib_files(libs, ("grpc_test_util",), ("headers",)) return out # Tests subspec is currently disabled since the tests currently use `grpc++` include style instead of `grpcpp`. @@ -127,12 +127,20 @@ def ruby_multiline_list(files, indent): return (',\n' + indent*' ').join('\'%s\'' % f for f in files) + + def modify_podspec_version_string(pod_version, grpc_version): + # Append -preX when it is a pre-release + if len(str(grpc_version).split('-')) > 1: + return pod_version + '-' + str(grpc_version).split('-')[-1] + else: + return pod_version + %> Pod::Spec.new do |s| s.name = 'gRPC-C++' # TODO (mxyan): use version that match gRPC version when pod is stabilized # version = '${settings.version}' - version = '0.0.4' + version = '${modify_podspec_version_string('0.0.8', settings.version)}' s.version = version s.summary = 'gRPC C++ library' s.homepage = 'https://grpc.io' @@ -148,6 +156,8 @@ s.ios.deployment_target = '7.0' s.osx.deployment_target = '10.9' + s.tvos.deployment_target = '10.0' + s.requires_arc = false name = 'grpcpp' diff --git a/templates/gRPC-Core.podspec.template b/templates/gRPC-Core.podspec.template index 98b6344a4bf..89a1e9188ff 100644 --- a/templates/gRPC-Core.podspec.template +++ b/templates/gRPC-Core.podspec.template @@ -59,8 +59,10 @@ 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")) + out = grpc_lib_files(libs, ("grpc_test_util",), ("src", "headers")) excl = grpc_private_files(libs) + # Subprocess is not supported in tvOS and not needed by our tests. + excl += ["test/core/util/subprocess_posix.cc"] return [file for file in out if not file in excl] def end2end_tests_files(libs): @@ -68,14 +70,6 @@ excl = grpc_private_files(libs) return [file for file in out if not file in excl] - def cfstream_private_headers(libs): - out = grpc_lib_files(libs, ("grpc_cfstream",), ("own_headers",)) - return out - - def cfstream_private_files(libs): - out = grpc_lib_files(libs, ("grpc_cfstream",), ("own_src", "own_headers")) - return out - def ruby_multiline_list(files, indent): return (',\n' + indent*' ').join('\'%s\'' % f for f in files) %> @@ -99,6 +93,8 @@ s.ios.deployment_target = '7.0' s.osx.deployment_target = '10.9' + s.tvos.deployment_target = '10.0' + s.requires_arc = false name = 'grpc' @@ -152,7 +148,7 @@ } s.default_subspecs = 'Interface', 'Implementation' - s.compiler_flags = '-DGRPC_ARES=0', '-DPB_FIELD_16BIT' + s.compiler_flags = '-DGRPC_ARES=0', '-DPB_FIELD_32BIT' s.libraries = 'c++' # Like many other C libraries, gRPC-Core has its public headers under `include//` and its @@ -174,7 +170,7 @@ ss.header_mappings_dir = '.' ss.libraries = 'z' ss.dependency "#{s.name}/Interface", version - ss.dependency 'BoringSSL-GRPC', '0.0.2' + ss.dependency 'BoringSSL-GRPC', '0.0.3' ss.dependency 'nanopb', '~> 0.3' ss.compiler_flags = '-DGRPC_SHADOW_BORINGSSL_SYMBOLS' @@ -184,14 +180,9 @@ ss.private_header_files = ${ruby_multiline_list(grpc_private_headers(libs), 30)} end + # CFStream is now default. Leaving this subspec only for compatibility purpose. s.subspec 'CFStream-Implementation' do |ss| - ss.header_mappings_dir = '.' ss.dependency "#{s.name}/Implementation", version - ss.pod_target_xcconfig = { - 'GCC_PREPROCESSOR_DEFINITIONS' => 'GRPC_CFSTREAM=1' - } - ss.source_files = ${ruby_multiline_list(cfstream_private_files(filegroups), 22)} - ss.private_header_files = ${ruby_multiline_list(cfstream_private_headers(filegroups), 30)} end s.subspec 'Cronet-Interface' do |ss| diff --git a/templates/gRPC-ProtoRPC.podspec.template b/templates/gRPC-ProtoRPC.podspec.template index 96966784f18..e4d5f3ffd3d 100644 --- a/templates/gRPC-ProtoRPC.podspec.template +++ b/templates/gRPC-ProtoRPC.podspec.template @@ -37,6 +37,7 @@ s.ios.deployment_target = '7.0' s.osx.deployment_target = '10.9' + s.tvos.deployment_target = '10.0' name = 'ProtoRPC' s.module_name = name @@ -54,12 +55,10 @@ ss.source_files = "#{src_dir}/*.{h,m}" end + + # CFStream is now default. Leaving this subspec only for compatibility purpose. s.subspec 'CFStream' do |ss| - ss.dependency 'gRPC/CFStream', version ss.dependency "#{s.name}/Main", version - ss.pod_target_xcconfig = { - 'GCC_PREPROCESSOR_DEFINITIONS' => 'GRPC_CFSTREAM=1' - } end s.pod_target_xcconfig = { diff --git a/templates/gRPC-RxLibrary.podspec.template b/templates/gRPC-RxLibrary.podspec.template index 14147d7dc1b..0973b6551db 100644 --- a/templates/gRPC-RxLibrary.podspec.template +++ b/templates/gRPC-RxLibrary.podspec.template @@ -37,6 +37,7 @@ s.ios.deployment_target = '7.0' s.osx.deployment_target = '10.9' + s.tvos.deployment_target = '10.0' name = 'RxLibrary' s.module_name = name diff --git a/templates/gRPC.podspec.template b/templates/gRPC.podspec.template index a3190c2d8e6..c9723933fcd 100644 --- a/templates/gRPC.podspec.template +++ b/templates/gRPC.podspec.template @@ -36,6 +36,7 @@ s.ios.deployment_target = '7.0' s.osx.deployment_target = '10.9' + s.tvos.deployment_target = '10.0' name = 'GRPCClient' s.module_name = name @@ -60,19 +61,14 @@ ss.source_files = "#{src_dir}/*.{h,m}", "#{src_dir}/**/*.{h,m}" ss.exclude_files = "#{src_dir}/GRPCCall+GID.{h,m}" - ss.private_header_files = "#{src_dir}/private/*.h" + ss.private_header_files = "#{src_dir}/private/*.h", "#{src_dir}/internal/*.h" ss.dependency 'gRPC-Core', version end - # This subspec is mutually exclusive with the `Main` subspec + # CFStream is now default. Leaving this subspec only for compatibility purpose. s.subspec 'CFStream' do |ss| - ss.dependency 'gRPC-Core/CFStream-Implementation', version ss.dependency "#{s.name}/Main", version - - ss.pod_target_xcconfig = { - 'GCC_PREPROCESSOR_DEFINITIONS' => 'GRPC_CFSTREAM=1' - } end s.subspec 'GID' do |ss| diff --git a/templates/grpc.gemspec.template b/templates/grpc.gemspec.template index 842035b664f..d2b54a9c2f5 100644 --- a/templates/grpc.gemspec.template +++ b/templates/grpc.gemspec.template @@ -31,8 +31,8 @@ s.require_paths = %w( src/ruby/lib src/ruby/bin src/ruby/pb ) s.platform = Gem::Platform::RUBY - s.add_dependency 'google-protobuf', '~> 3.1' - s.add_dependency 'googleapis-common-protos-types', '~> 1.0.0' + s.add_dependency 'google-protobuf', '~> 3.7' + s.add_dependency 'googleapis-common-protos-types', '~> 1.0' s.add_development_dependency 'bundler', '~> 1.9' s.add_development_dependency 'facter', '~> 2.4' @@ -43,8 +43,8 @@ s.add_development_dependency 'rake-compiler-dock', '~> 0.5.1' s.add_development_dependency 'rspec', '~> 3.6' s.add_development_dependency 'rubocop', '~> 0.49.1' - s.add_development_dependency 'signet', '~> 0.7.0' - s.add_development_dependency 'googleauth', '>= 0.5.1', '< 0.7' + s.add_development_dependency 'signet', '~> 0.7' + s.add_development_dependency 'googleauth', '>= 0.5.1', '< 0.10' s.extensions = %w(src/ruby/ext/grpc/extconf.rb) diff --git a/templates/src/csharp/Grpc.Core/VersionInfo.cs.template b/templates/src/csharp/Grpc.Core.Api/VersionInfo.cs.template similarity index 100% rename from templates/src/csharp/Grpc.Core/VersionInfo.cs.template rename to templates/src/csharp/Grpc.Core.Api/VersionInfo.cs.template diff --git a/templates/src/csharp/Grpc.Core/Internal/NativeMethods.Generated.cs.template b/templates/src/csharp/Grpc.Core/Internal/NativeMethods.Generated.cs.template index 774fc2c56fe..4e6913803dd 100644 --- a/templates/src/csharp/Grpc.Core/Internal/NativeMethods.Generated.cs.template +++ b/templates/src/csharp/Grpc.Core/Internal/NativeMethods.Generated.cs.template @@ -1,112 +1,6 @@ %YAML 1.2 --- | - <% - native_method_signatures = [ - 'void grpcsharp_init()', - 'void grpcsharp_shutdown()', - 'IntPtr grpcsharp_version_string() // returns not-owned const char*', - 'BatchContextSafeHandle grpcsharp_batch_context_create()', - 'IntPtr grpcsharp_batch_context_recv_initial_metadata(BatchContextSafeHandle ctx)', - 'IntPtr grpcsharp_batch_context_recv_message_length(BatchContextSafeHandle ctx)', - 'void grpcsharp_batch_context_recv_message_to_buffer(BatchContextSafeHandle ctx, byte[] buffer, UIntPtr bufferLen)', - 'StatusCode grpcsharp_batch_context_recv_status_on_client_status(BatchContextSafeHandle ctx)', - 'IntPtr grpcsharp_batch_context_recv_status_on_client_details(BatchContextSafeHandle ctx, out UIntPtr detailsLength)', - 'IntPtr grpcsharp_batch_context_recv_status_on_client_trailing_metadata(BatchContextSafeHandle ctx)', - 'int grpcsharp_batch_context_recv_close_on_server_cancelled(BatchContextSafeHandle ctx)', - 'void grpcsharp_batch_context_reset(BatchContextSafeHandle ctx)', - 'void grpcsharp_batch_context_destroy(IntPtr ctx)', - 'RequestCallContextSafeHandle grpcsharp_request_call_context_create()', - 'CallSafeHandle grpcsharp_request_call_context_call(RequestCallContextSafeHandle ctx)', - 'IntPtr grpcsharp_request_call_context_method(RequestCallContextSafeHandle ctx, out UIntPtr methodLength)', - 'IntPtr grpcsharp_request_call_context_host(RequestCallContextSafeHandle ctx, out UIntPtr hostLength)', - 'Timespec grpcsharp_request_call_context_deadline(RequestCallContextSafeHandle ctx)', - 'IntPtr grpcsharp_request_call_context_request_metadata(RequestCallContextSafeHandle ctx)', - 'void grpcsharp_request_call_context_reset(RequestCallContextSafeHandle ctx)', - 'void grpcsharp_request_call_context_destroy(IntPtr ctx)', - 'CallCredentialsSafeHandle grpcsharp_composite_call_credentials_create(CallCredentialsSafeHandle creds1, CallCredentialsSafeHandle creds2)', - 'void grpcsharp_call_credentials_release(IntPtr credentials)', - 'CallError grpcsharp_call_cancel(CallSafeHandle call)', - 'CallError grpcsharp_call_cancel_with_status(CallSafeHandle call, StatusCode status, string description)', - 'CallError grpcsharp_call_start_unary(CallSafeHandle call, BatchContextSafeHandle ctx, byte[] sendBuffer, UIntPtr sendBufferLen, WriteFlags writeFlags, MetadataArraySafeHandle metadataArray, CallFlags metadataFlags)', - 'CallError grpcsharp_call_start_client_streaming(CallSafeHandle call, BatchContextSafeHandle ctx, MetadataArraySafeHandle metadataArray, CallFlags metadataFlags)', - 'CallError grpcsharp_call_start_server_streaming(CallSafeHandle call, BatchContextSafeHandle ctx, byte[] sendBuffer, UIntPtr sendBufferLen, WriteFlags writeFlags, MetadataArraySafeHandle metadataArray, CallFlags metadataFlags)', - 'CallError grpcsharp_call_start_duplex_streaming(CallSafeHandle call, BatchContextSafeHandle ctx, MetadataArraySafeHandle metadataArray, CallFlags metadataFlags)', - 'CallError grpcsharp_call_send_message(CallSafeHandle call, BatchContextSafeHandle ctx, byte[] sendBuffer, UIntPtr sendBufferLen, WriteFlags writeFlags, int sendEmptyInitialMetadata)', - 'CallError grpcsharp_call_send_close_from_client(CallSafeHandle call, BatchContextSafeHandle ctx)', - 'CallError grpcsharp_call_send_status_from_server(CallSafeHandle call, BatchContextSafeHandle ctx, StatusCode statusCode, byte[] statusMessage, UIntPtr statusMessageLen, MetadataArraySafeHandle metadataArray, int sendEmptyInitialMetadata, byte[] optionalSendBuffer, UIntPtr optionalSendBufferLen, WriteFlags writeFlags)', - 'CallError grpcsharp_call_recv_message(CallSafeHandle call, BatchContextSafeHandle ctx)', - 'CallError grpcsharp_call_recv_initial_metadata(CallSafeHandle call, BatchContextSafeHandle ctx)', - 'CallError grpcsharp_call_start_serverside(CallSafeHandle call, BatchContextSafeHandle ctx)', - 'CallError grpcsharp_call_send_initial_metadata(CallSafeHandle call, BatchContextSafeHandle ctx, MetadataArraySafeHandle metadataArray)', - 'CallError grpcsharp_call_set_credentials(CallSafeHandle call, CallCredentialsSafeHandle credentials)', - 'CStringSafeHandle grpcsharp_call_get_peer(CallSafeHandle call)', - 'void grpcsharp_call_destroy(IntPtr call)', - 'ChannelArgsSafeHandle grpcsharp_channel_args_create(UIntPtr numArgs)', - 'void grpcsharp_channel_args_set_string(ChannelArgsSafeHandle args, UIntPtr index, string key, string value)', - 'void grpcsharp_channel_args_set_integer(ChannelArgsSafeHandle args, UIntPtr index, string key, int value)', - 'void grpcsharp_channel_args_destroy(IntPtr args)', - 'void grpcsharp_override_default_ssl_roots(string pemRootCerts)', - 'ChannelCredentialsSafeHandle grpcsharp_ssl_credentials_create(string pemRootCerts, string keyCertPairCertChain, string keyCertPairPrivateKey)', - 'ChannelCredentialsSafeHandle grpcsharp_composite_channel_credentials_create(ChannelCredentialsSafeHandle channelCreds, CallCredentialsSafeHandle callCreds)', - 'void grpcsharp_channel_credentials_release(IntPtr credentials)', - 'ChannelSafeHandle grpcsharp_insecure_channel_create(string target, ChannelArgsSafeHandle channelArgs)', - 'ChannelSafeHandle grpcsharp_secure_channel_create(ChannelCredentialsSafeHandle credentials, string target, ChannelArgsSafeHandle channelArgs)', - 'CallSafeHandle grpcsharp_channel_create_call(ChannelSafeHandle channel, CallSafeHandle parentCall, ContextPropagationFlags propagationMask, CompletionQueueSafeHandle cq, string method, string host, Timespec deadline)', - 'ChannelState grpcsharp_channel_check_connectivity_state(ChannelSafeHandle channel, int tryToConnect)', - 'void grpcsharp_channel_watch_connectivity_state(ChannelSafeHandle channel, ChannelState lastObservedState, Timespec deadline, CompletionQueueSafeHandle cq, BatchContextSafeHandle ctx)', - 'CStringSafeHandle grpcsharp_channel_get_target(ChannelSafeHandle call)', - 'void grpcsharp_channel_destroy(IntPtr channel)', - 'int grpcsharp_sizeof_grpc_event()', - 'CompletionQueueSafeHandle grpcsharp_completion_queue_create_async()', - 'CompletionQueueSafeHandle grpcsharp_completion_queue_create_sync()', - 'void grpcsharp_completion_queue_shutdown(CompletionQueueSafeHandle cq)', - 'CompletionQueueEvent grpcsharp_completion_queue_next(CompletionQueueSafeHandle cq)', - 'CompletionQueueEvent grpcsharp_completion_queue_pluck(CompletionQueueSafeHandle cq, IntPtr tag)', - 'void grpcsharp_completion_queue_destroy(IntPtr cq)', - 'void gprsharp_free(IntPtr ptr)', - 'MetadataArraySafeHandle grpcsharp_metadata_array_create(UIntPtr capacity)', - 'void grpcsharp_metadata_array_add(MetadataArraySafeHandle array, string key, byte[] value, UIntPtr valueLength)', - 'UIntPtr grpcsharp_metadata_array_count(IntPtr metadataArray)', - 'IntPtr grpcsharp_metadata_array_get_key(IntPtr metadataArray, UIntPtr index, out UIntPtr keyLength)', - 'IntPtr grpcsharp_metadata_array_get_value(IntPtr metadataArray, UIntPtr index, out UIntPtr valueLength)', - 'void grpcsharp_metadata_array_destroy_full(IntPtr array)', - 'void grpcsharp_redirect_log(GprLogDelegate callback)', - 'CallCredentialsSafeHandle grpcsharp_metadata_credentials_create_from_plugin(NativeMetadataInterceptor interceptor)', - 'void grpcsharp_metadata_credentials_notify_from_plugin(IntPtr callbackPtr, IntPtr userData, MetadataArraySafeHandle metadataArray, StatusCode statusCode, string errorDetails)', - 'ServerCredentialsSafeHandle grpcsharp_ssl_server_credentials_create(string pemRootCerts, string[] keyCertPairCertChainArray, string[] keyCertPairPrivateKeyArray, UIntPtr numKeyCertPairs, SslClientCertificateRequestType clientCertificateRequest)', - 'void grpcsharp_server_credentials_release(IntPtr credentials)', - 'ServerSafeHandle grpcsharp_server_create(ChannelArgsSafeHandle args)', - 'void grpcsharp_server_register_completion_queue(ServerSafeHandle server, CompletionQueueSafeHandle cq)', - 'int grpcsharp_server_add_insecure_http2_port(ServerSafeHandle server, string addr)', - 'int grpcsharp_server_add_secure_http2_port(ServerSafeHandle server, string addr, ServerCredentialsSafeHandle creds)', - 'void grpcsharp_server_start(ServerSafeHandle server)', - 'CallError grpcsharp_server_request_call(ServerSafeHandle server, CompletionQueueSafeHandle cq, RequestCallContextSafeHandle ctx)', - 'void grpcsharp_server_cancel_all_calls(ServerSafeHandle server)', - 'void grpcsharp_server_shutdown_and_notify_callback(ServerSafeHandle server, CompletionQueueSafeHandle cq, BatchContextSafeHandle ctx)', - 'void grpcsharp_server_destroy(IntPtr server)', - 'AuthContextSafeHandle grpcsharp_call_auth_context(CallSafeHandle call)', - 'IntPtr grpcsharp_auth_context_peer_identity_property_name(AuthContextSafeHandle authContext) // returns const char*', - 'AuthContextSafeHandle.NativeAuthPropertyIterator grpcsharp_auth_context_property_iterator(AuthContextSafeHandle authContext)', - 'IntPtr grpcsharp_auth_property_iterator_next(ref AuthContextSafeHandle.NativeAuthPropertyIterator iterator) // returns const auth_property*', - 'void grpcsharp_auth_context_release(IntPtr authContext)', - 'Timespec gprsharp_now(ClockType clockType)', - 'Timespec gprsharp_inf_future(ClockType clockType)', - 'Timespec gprsharp_inf_past(ClockType clockType)', - 'Timespec gprsharp_convert_clock_type(Timespec t, ClockType targetClock)', - 'int gprsharp_sizeof_timespec()', - 'CallError grpcsharp_test_callback([MarshalAs(UnmanagedType.FunctionPtr)] NativeCallbackTestDelegate callback)', - 'IntPtr grpcsharp_test_nop(IntPtr ptr)', - 'void grpcsharp_test_override_method(string methodName, string variant)', - ] - - import re - native_methods = [] - for signature in native_method_signatures: - match = re.match('([A-Za-z0-9_.]+) +([A-Za-z0-9_]+)\\((.*)\\)(.*)', signature) - if not match: - raise Exception('Malformed signature "%s"' % signature) - native_methods.append({'returntype': match.group(1), 'name': match.group(2), 'params': match.group(3), 'comment': match.group(4)}) - %> + <%namespace file="native_methods.include" import="get_native_methods"/> #region Copyright notice and license // Copyright 2015 gRPC authors. @@ -142,7 +36,7 @@ { #region Native methods - % for method in native_methods: + % for method in get_native_methods(): public readonly Delegates.${method['name']}_delegate ${method['name']}; % endfor @@ -150,21 +44,21 @@ public NativeMethods(UnmanagedLibrary library) { - % for method in native_methods: + % for method in get_native_methods(): this.${method['name']} = GetMethodDelegate(library); % endfor } public NativeMethods(DllImportsFromStaticLib unusedInstance) { - % for method in native_methods: + % for method in get_native_methods(): this.${method['name']} = DllImportsFromStaticLib.${method['name']}; % endfor } public NativeMethods(DllImportsFromSharedLib unusedInstance) { - % for method in native_methods: + % for method in get_native_methods(): this.${method['name']} = DllImportsFromSharedLib.${method['name']}; % endfor } @@ -174,7 +68,7 @@ /// public class Delegates { - % for method in native_methods: + % for method in get_native_methods(): public delegate ${method['returntype']} ${method['name']}_delegate(${method['params']});${method['comment']} % endfor } @@ -185,7 +79,7 @@ internal class DllImportsFromStaticLib { private const string ImportName = "__Internal"; - % for method in native_methods: + % for method in get_native_methods(): [DllImport(ImportName)] public static extern ${method['returntype']} ${method['name']}(${method['params']}); @@ -198,7 +92,7 @@ internal class DllImportsFromSharedLib { private const string ImportName = "grpc_csharp_ext"; - % for method in native_methods: + % for method in get_native_methods(): [DllImport(ImportName)] public static extern ${method['returntype']} ${method['name']}(${method['params']}); diff --git a/templates/src/csharp/Grpc.Core/Internal/native_methods.include b/templates/src/csharp/Grpc.Core/Internal/native_methods.include new file mode 100644 index 00000000000..4a31171aa27 --- /dev/null +++ b/templates/src/csharp/Grpc.Core/Internal/native_methods.include @@ -0,0 +1,110 @@ +<%def name="get_native_methods()"><% +native_method_signatures = [ + 'void grpcsharp_init()', + 'void grpcsharp_shutdown()', + 'IntPtr grpcsharp_version_string() // returns not-owned const char*', + 'BatchContextSafeHandle grpcsharp_batch_context_create()', + 'IntPtr grpcsharp_batch_context_recv_initial_metadata(BatchContextSafeHandle ctx)', + 'IntPtr grpcsharp_batch_context_recv_message_length(BatchContextSafeHandle ctx)', + 'int grpcsharp_batch_context_recv_message_next_slice_peek(BatchContextSafeHandle ctx, out UIntPtr sliceLen, out IntPtr sliceDataPtr)', + 'StatusCode grpcsharp_batch_context_recv_status_on_client_status(BatchContextSafeHandle ctx)', + 'IntPtr grpcsharp_batch_context_recv_status_on_client_details(BatchContextSafeHandle ctx, out UIntPtr detailsLength)', + 'IntPtr grpcsharp_batch_context_recv_status_on_client_trailing_metadata(BatchContextSafeHandle ctx)', + 'int grpcsharp_batch_context_recv_close_on_server_cancelled(BatchContextSafeHandle ctx)', + 'void grpcsharp_batch_context_reset(BatchContextSafeHandle ctx)', + 'void grpcsharp_batch_context_destroy(IntPtr ctx)', + 'RequestCallContextSafeHandle grpcsharp_request_call_context_create()', + 'CallSafeHandle grpcsharp_request_call_context_call(RequestCallContextSafeHandle ctx)', + 'IntPtr grpcsharp_request_call_context_method(RequestCallContextSafeHandle ctx, out UIntPtr methodLength)', + 'IntPtr grpcsharp_request_call_context_host(RequestCallContextSafeHandle ctx, out UIntPtr hostLength)', + 'Timespec grpcsharp_request_call_context_deadline(RequestCallContextSafeHandle ctx)', + 'IntPtr grpcsharp_request_call_context_request_metadata(RequestCallContextSafeHandle ctx)', + 'void grpcsharp_request_call_context_reset(RequestCallContextSafeHandle ctx)', + 'void grpcsharp_request_call_context_destroy(IntPtr ctx)', + 'CallCredentialsSafeHandle grpcsharp_composite_call_credentials_create(CallCredentialsSafeHandle creds1, CallCredentialsSafeHandle creds2)', + 'void grpcsharp_call_credentials_release(IntPtr credentials)', + 'CallError grpcsharp_call_cancel(CallSafeHandle call)', + 'CallError grpcsharp_call_cancel_with_status(CallSafeHandle call, StatusCode status, string description)', + 'CallError grpcsharp_call_start_unary(CallSafeHandle call, BatchContextSafeHandle ctx, byte[] sendBuffer, UIntPtr sendBufferLen, WriteFlags writeFlags, MetadataArraySafeHandle metadataArray, CallFlags metadataFlags)', + 'CallError grpcsharp_call_start_client_streaming(CallSafeHandle call, BatchContextSafeHandle ctx, MetadataArraySafeHandle metadataArray, CallFlags metadataFlags)', + 'CallError grpcsharp_call_start_server_streaming(CallSafeHandle call, BatchContextSafeHandle ctx, byte[] sendBuffer, UIntPtr sendBufferLen, WriteFlags writeFlags, MetadataArraySafeHandle metadataArray, CallFlags metadataFlags)', + 'CallError grpcsharp_call_start_duplex_streaming(CallSafeHandle call, BatchContextSafeHandle ctx, MetadataArraySafeHandle metadataArray, CallFlags metadataFlags)', + 'CallError grpcsharp_call_send_message(CallSafeHandle call, BatchContextSafeHandle ctx, byte[] sendBuffer, UIntPtr sendBufferLen, WriteFlags writeFlags, int sendEmptyInitialMetadata)', + 'CallError grpcsharp_call_send_close_from_client(CallSafeHandle call, BatchContextSafeHandle ctx)', + 'CallError grpcsharp_call_send_status_from_server(CallSafeHandle call, BatchContextSafeHandle ctx, StatusCode statusCode, byte[] statusMessage, UIntPtr statusMessageLen, MetadataArraySafeHandle metadataArray, int sendEmptyInitialMetadata, byte[] optionalSendBuffer, UIntPtr optionalSendBufferLen, WriteFlags writeFlags)', + 'CallError grpcsharp_call_recv_message(CallSafeHandle call, BatchContextSafeHandle ctx)', + 'CallError grpcsharp_call_recv_initial_metadata(CallSafeHandle call, BatchContextSafeHandle ctx)', + 'CallError grpcsharp_call_start_serverside(CallSafeHandle call, BatchContextSafeHandle ctx)', + 'CallError grpcsharp_call_send_initial_metadata(CallSafeHandle call, BatchContextSafeHandle ctx, MetadataArraySafeHandle metadataArray)', + 'CallError grpcsharp_call_set_credentials(CallSafeHandle call, CallCredentialsSafeHandle credentials)', + 'CStringSafeHandle grpcsharp_call_get_peer(CallSafeHandle call)', + 'void grpcsharp_call_destroy(IntPtr call)', + 'ChannelArgsSafeHandle grpcsharp_channel_args_create(UIntPtr numArgs)', + 'void grpcsharp_channel_args_set_string(ChannelArgsSafeHandle args, UIntPtr index, string key, string value)', + 'void grpcsharp_channel_args_set_integer(ChannelArgsSafeHandle args, UIntPtr index, string key, int value)', + 'void grpcsharp_channel_args_destroy(IntPtr args)', + 'void grpcsharp_override_default_ssl_roots(string pemRootCerts)', + 'ChannelCredentialsSafeHandle grpcsharp_ssl_credentials_create(string pemRootCerts, string keyCertPairCertChain, string keyCertPairPrivateKey, IntPtr verifyPeerCallbackTag)', + 'ChannelCredentialsSafeHandle grpcsharp_composite_channel_credentials_create(ChannelCredentialsSafeHandle channelCreds, CallCredentialsSafeHandle callCreds)', + 'void grpcsharp_channel_credentials_release(IntPtr credentials)', + 'ChannelSafeHandle grpcsharp_insecure_channel_create(string target, ChannelArgsSafeHandle channelArgs)', + 'ChannelSafeHandle grpcsharp_secure_channel_create(ChannelCredentialsSafeHandle credentials, string target, ChannelArgsSafeHandle channelArgs)', + 'CallSafeHandle grpcsharp_channel_create_call(ChannelSafeHandle channel, CallSafeHandle parentCall, ContextPropagationFlags propagationMask, CompletionQueueSafeHandle cq, string method, string host, Timespec deadline)', + 'ChannelState grpcsharp_channel_check_connectivity_state(ChannelSafeHandle channel, int tryToConnect)', + 'void grpcsharp_channel_watch_connectivity_state(ChannelSafeHandle channel, ChannelState lastObservedState, Timespec deadline, CompletionQueueSafeHandle cq, BatchContextSafeHandle ctx)', + 'CStringSafeHandle grpcsharp_channel_get_target(ChannelSafeHandle call)', + 'void grpcsharp_channel_destroy(IntPtr channel)', + 'int grpcsharp_sizeof_grpc_event()', + 'CompletionQueueSafeHandle grpcsharp_completion_queue_create_async()', + 'CompletionQueueSafeHandle grpcsharp_completion_queue_create_sync()', + 'void grpcsharp_completion_queue_shutdown(CompletionQueueSafeHandle cq)', + 'CompletionQueueEvent grpcsharp_completion_queue_next(CompletionQueueSafeHandle cq)', + 'CompletionQueueEvent grpcsharp_completion_queue_pluck(CompletionQueueSafeHandle cq, IntPtr tag)', + 'void grpcsharp_completion_queue_destroy(IntPtr cq)', + 'void gprsharp_free(IntPtr ptr)', + 'MetadataArraySafeHandle grpcsharp_metadata_array_create(UIntPtr capacity)', + 'void grpcsharp_metadata_array_add(MetadataArraySafeHandle array, string key, byte[] value, UIntPtr valueLength)', + 'UIntPtr grpcsharp_metadata_array_count(IntPtr metadataArray)', + 'IntPtr grpcsharp_metadata_array_get_key(IntPtr metadataArray, UIntPtr index, out UIntPtr keyLength)', + 'IntPtr grpcsharp_metadata_array_get_value(IntPtr metadataArray, UIntPtr index, out UIntPtr valueLength)', + 'void grpcsharp_metadata_array_destroy_full(IntPtr array)', + 'void grpcsharp_redirect_log(GprLogDelegate callback)', + 'void grpcsharp_native_callback_dispatcher_init(NativeCallbackDispatcherCallback dispatcher)', + 'CallCredentialsSafeHandle grpcsharp_metadata_credentials_create_from_plugin(IntPtr nativeCallbackTag)', + 'void grpcsharp_metadata_credentials_notify_from_plugin(IntPtr callbackPtr, IntPtr userData, MetadataArraySafeHandle metadataArray, StatusCode statusCode, string errorDetails)', + 'ServerCredentialsSafeHandle grpcsharp_ssl_server_credentials_create(string pemRootCerts, string[] keyCertPairCertChainArray, string[] keyCertPairPrivateKeyArray, UIntPtr numKeyCertPairs, SslClientCertificateRequestType clientCertificateRequest)', + 'void grpcsharp_server_credentials_release(IntPtr credentials)', + 'ServerSafeHandle grpcsharp_server_create(ChannelArgsSafeHandle args)', + 'void grpcsharp_server_register_completion_queue(ServerSafeHandle server, CompletionQueueSafeHandle cq)', + 'int grpcsharp_server_add_insecure_http2_port(ServerSafeHandle server, string addr)', + 'int grpcsharp_server_add_secure_http2_port(ServerSafeHandle server, string addr, ServerCredentialsSafeHandle creds)', + 'void grpcsharp_server_start(ServerSafeHandle server)', + 'CallError grpcsharp_server_request_call(ServerSafeHandle server, CompletionQueueSafeHandle cq, RequestCallContextSafeHandle ctx)', + 'void grpcsharp_server_cancel_all_calls(ServerSafeHandle server)', + 'void grpcsharp_server_shutdown_and_notify_callback(ServerSafeHandle server, CompletionQueueSafeHandle cq, BatchContextSafeHandle ctx)', + 'void grpcsharp_server_destroy(IntPtr server)', + 'AuthContextSafeHandle grpcsharp_call_auth_context(CallSafeHandle call)', + 'IntPtr grpcsharp_auth_context_peer_identity_property_name(AuthContextSafeHandle authContext) // returns const char*', + 'AuthContextSafeHandle.NativeAuthPropertyIterator grpcsharp_auth_context_property_iterator(AuthContextSafeHandle authContext)', + 'IntPtr grpcsharp_auth_property_iterator_next(ref AuthContextSafeHandle.NativeAuthPropertyIterator iterator) // returns const auth_property*', + 'void grpcsharp_auth_context_release(IntPtr authContext)', + 'Timespec gprsharp_now(ClockType clockType)', + 'Timespec gprsharp_inf_future(ClockType clockType)', + 'Timespec gprsharp_inf_past(ClockType clockType)', + 'Timespec gprsharp_convert_clock_type(Timespec t, ClockType targetClock)', + 'int gprsharp_sizeof_timespec()', + 'CallError grpcsharp_test_callback([MarshalAs(UnmanagedType.FunctionPtr)] NativeCallbackTestDelegate callback)', + 'IntPtr grpcsharp_test_nop(IntPtr ptr)', + 'void grpcsharp_test_override_method(string methodName, string variant)', +] + +import re +native_methods = [] +for signature in native_method_signatures: + match = re.match('([A-Za-z0-9_.]+) +([A-Za-z0-9_]+)\\((.*)\\)(.*)', signature) + if not match: + raise Exception('Malformed signature "%s"' % signature) + native_methods.append({'returntype': match.group(1), 'name': match.group(2), 'params': match.group(3), 'comment': match.group(4)}) + +return list(native_methods) +%> \ No newline at end of file diff --git a/templates/src/csharp/Grpc.Core/Version.csproj.include.template b/templates/src/csharp/build/dependencies.props.template similarity index 76% rename from templates/src/csharp/Grpc.Core/Version.csproj.include.template rename to templates/src/csharp/build/dependencies.props.template index 0ec0a08c499..0ed9018a49e 100755 --- a/templates/src/csharp/Grpc.Core/Version.csproj.include.template +++ b/templates/src/csharp/build/dependencies.props.template @@ -4,6 +4,6 @@ ${settings.csharp_version} - 3.6.1 + 3.7.0 diff --git a/templates/src/csharp/build_packages_dotnetcli.bat.template b/templates/src/csharp/build_packages_dotnetcli.bat.template deleted file mode 100755 index 877899c7bd9..00000000000 --- a/templates/src/csharp/build_packages_dotnetcli.bat.template +++ /dev/null @@ -1,60 +0,0 @@ -%YAML 1.2 ---- | - @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 Current package versions - set VERSION=${settings.csharp_version} - - @rem Adjust the location of nuget.exe - set NUGET=C:\nuget\nuget.exe - set DOTNET=dotnet - - mkdir ..\..\artifacts - - @rem Collect the artifacts built by the previous build step - mkdir nativelibs - powershell -Command "cp -r ..\..\input_artifacts\csharp_ext_* nativelibs" - - @rem Collect protoc artifacts built by the previous build step - mkdir protoc_plugins - powershell -Command "cp -r ..\..\input_artifacts\protoc_* protoc_plugins" - - %%DOTNET% restore Grpc.sln || goto :error - - @rem To be able to build, we also need to put grpc_csharp_ext to its normal location - xcopy /Y /I nativelibs\csharp_ext_windows_x64\grpc_csharp_ext.dll ..\..\cmake\build\x64\Release${"\\"} - - %%DOTNET% pack --configuration Release Grpc.Core --output ..\..\..\artifacts || goto :error - %%DOTNET% pack --configuration Release Grpc.Core.Testing --output ..\..\..\artifacts || goto :error - %%DOTNET% pack --configuration Release Grpc.Auth --output ..\..\..\artifacts || goto :error - %%DOTNET% pack --configuration Release Grpc.HealthCheck --output ..\..\..\artifacts || goto :error - %%DOTNET% pack --configuration Release Grpc.Reflection --output ..\..\..\artifacts || goto :error - %%DOTNET% pack --configuration Release Grpc.Tools --output ..\..\..\artifacts || goto :error - - %%NUGET% pack Grpc.nuspec -Version %VERSION% -OutputDirectory ..\..\artifacts || goto :error - %%NUGET% pack Grpc.Core.NativeDebug.nuspec -Version %VERSION% -OutputDirectory ..\..\artifacts - - @rem copy resulting nuget packages to artifacts directory - xcopy /Y /I *.nupkg ..\..\artifacts\ || goto :error - - @rem create a zipfile with the artifacts as well - powershell -Command "Add-Type -Assembly 'System.IO.Compression.FileSystem'; [System.IO.Compression.ZipFile]::CreateFromDirectory('..\..\artifacts', 'csharp_nugets_windows_dotnetcli.zip');" - xcopy /Y /I csharp_nugets_windows_dotnetcli.zip ..\..\artifacts\ || goto :error - - goto :EOF - - :error - echo Failed! - exit /b %errorlevel% diff --git a/templates/src/csharp/build_unitypackage.bat.template b/templates/src/csharp/build_unitypackage.bat.template index 76ec10dbd90..d6f2e3c7f0d 100755 --- a/templates/src/csharp/build_unitypackage.bat.template +++ b/templates/src/csharp/build_unitypackage.bat.template @@ -42,6 +42,9 @@ @rem copy Grpc assemblies to the unity package skeleton @rem TODO(jtattermusch): Add Grpc.Auth assembly and its dependencies + copy /Y Grpc.Core.Api\bin\Release\net45\Grpc.Core.Api.dll unitypackage\unitypackage_skeleton\Plugins\Grpc.Core.Api\lib\net45\Grpc.Core.Api.dll || goto :error + copy /Y Grpc.Core.Api\bin\Release\net45\Grpc.Core.Api.pdb unitypackage\unitypackage_skeleton\Plugins\Grpc.Core.Api\lib\net45\Grpc.Core.Api.pdb || goto :error + copy /Y Grpc.Core.Api\bin\Release\net45\Grpc.Core.Api.xml unitypackage\unitypackage_skeleton\Plugins\Grpc.Core.Api\lib\net45\Grpc.Core.Api.xml || goto :error copy /Y Grpc.Core\bin\Release\net45\Grpc.Core.dll unitypackage\unitypackage_skeleton\Plugins\Grpc.Core\lib\net45\Grpc.Core.dll || goto :error copy /Y Grpc.Core\bin\Release\net45\Grpc.Core.pdb unitypackage\unitypackage_skeleton\Plugins\Grpc.Core\lib\net45\Grpc.Core.pdb || goto :error copy /Y Grpc.Core\bin\Release\net45\Grpc.Core.xml unitypackage\unitypackage_skeleton\Plugins\Grpc.Core\lib\net45\Grpc.Core.xml || goto :error diff --git a/templates/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/grpc_csharp_ext_dummy_stubs.c.template b/templates/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/grpc_csharp_ext_dummy_stubs.c.template new file mode 100644 index 00000000000..a38ae2bf4ed --- /dev/null +++ b/templates/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/grpc_csharp_ext_dummy_stubs.c.template @@ -0,0 +1,32 @@ +%YAML 1.2 +--- | + <%namespace file="../../../../../Grpc.Core/Internal/native_methods.include" import="get_native_methods"/> + // Copyright 2019 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. + // 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. + + // When building for Unity Android with il2cpp backend, Unity tries to link + // the __Internal PInvoke definitions (which are required by iOS) even though + // the .so/.dll will be actually used. This file provides dummy stubs to + // make il2cpp happy. + // See https://github.com/grpc/grpc/issues/16012 + + #include + #include + + % for method in get_native_methods(): + void ${method['name']}() { + fprintf(stderr, "Should never reach here"); + abort(); + } + % endfor diff --git a/templates/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec.template b/templates/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec.template index 30b6c5684cc..741f9b7e54d 100644 --- a/templates/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec.template +++ b/templates/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec.template @@ -103,10 +103,11 @@ s.preserve_paths = plugin # Restrict the protoc version to the one supported by this plugin. - s.dependency '!ProtoCompiler', '3.6.0' + s.dependency '!ProtoCompiler', '3.7.0' # For the Protobuf dependency not to complain: s.ios.deployment_target = '7.0' s.osx.deployment_target = '10.9' + s.tvos.deployment_target = '10.0' # Restrict the gRPC runtime version to the one supported by this plugin. s.dependency 'gRPC-ProtoRPC', v diff --git a/templates/src/objective-c/BoringSSL-GRPC.podspec.template b/templates/src/objective-c/BoringSSL-GRPC.podspec.template index 2b3bb8d97a4..408970e25e3 100644 --- a/templates/src/objective-c/BoringSSL-GRPC.podspec.template +++ b/templates/src/objective-c/BoringSSL-GRPC.podspec.template @@ -4,6 +4,7 @@ def expand_symbol_list(symbol_list): return ',\n '.join("'#define %s GRPC_SHADOW_%s'" % (symbol, symbol) for symbol in symbol_list) %> + # This file has been automatically generated from a template file. # Please make modifications to # `templates/src/objective-c/BoringSSL-GRPC.podspec.template` instead. This @@ -43,7 +44,7 @@ Pod::Spec.new do |s| s.name = 'BoringSSL-GRPC' - version = '0.0.2' + version = '0.0.3' s.version = version s.summary = 'BoringSSL is a fork of OpenSSL that is designed to meet Google\'s needs.' # Adapted from the homepage: @@ -83,8 +84,9 @@ :commit => "b29b21a81b32ec273f118f589f46d56ad3332420", } - s.ios.deployment_target = '5.0' + s.ios.deployment_target = '7.0' s.osx.deployment_target = '10.7' + s.tvos.deployment_target = '10.0' name = 'openssl_grpc' diff --git a/templates/src/python/grpcio_channelz/grpc_version.py.template b/templates/src/python/grpcio_channelz/grpc_version.py.template new file mode 100644 index 00000000000..75d510cd17b --- /dev/null +++ b/templates/src/python/grpcio_channelz/grpc_version.py.template @@ -0,0 +1,19 @@ +%YAML 1.2 +--- | + # Copyright 2018 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. + # 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. + + # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_channelz/grpc_version.py.template`!!! + + VERSION = '${settings.python_version.pep440()}' diff --git a/templates/src/python/grpcio_status/grpc_version.py.template b/templates/src/python/grpcio_status/grpc_version.py.template new file mode 100644 index 00000000000..727e01edb93 --- /dev/null +++ b/templates/src/python/grpcio_status/grpc_version.py.template @@ -0,0 +1,19 @@ +%YAML 1.2 +--- | + # Copyright 2018 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. + # 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. + + # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_status/grpc_version.py.template`!!! + + VERSION = '${settings.python_version.pep440()}' diff --git a/templates/test/cpp/naming/resolver_component_tests_defs.include b/templates/test/cpp/naming/resolver_component_tests_defs.include index b34845e01a3..d38316cbe68 100644 --- a/templates/test/cpp/naming/resolver_component_tests_defs.include +++ b/templates/test/cpp/naming/resolver_component_tests_defs.include @@ -55,7 +55,6 @@ if cur_resolver and cur_resolver != 'ares': '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'}) os.environ.update({'GRPC_TRACE': 'cares_resolver'}) def wait_until_dns_server_is_up(args, diff --git a/templates/tools/dockerfile/bazel.include b/templates/tools/dockerfile/bazel.include index c7714f56630..8888e938f43 100644 --- a/templates/tools/dockerfile/bazel.include +++ b/templates/tools/dockerfile/bazel.include @@ -2,5 +2,6 @@ # Bazel installation RUN apt-get update && apt-get install -y wget && apt-get clean -RUN wget -q https://github.com/bazelbuild/bazel/releases/download/0.17.1/bazel-0.17.1-linux-x86_64 -O /usr/local/bin/bazel -RUN chmod 755 /usr/local/bin/bazel +RUN wget https://github.com/bazelbuild/bazel/releases/download/0.23.2/bazel-0.23.2-installer-linux-x86_64.sh && ${'\\'} + bash ./bazel-0.23.2-installer-linux-x86_64.sh && ${'\\'} + rm bazel-0.23.2-installer-linux-x86_64.sh diff --git a/templates/tools/dockerfile/cmake_jessie_backports.include b/templates/tools/dockerfile/cmake_jessie_backports.include index 2fc49dc8d60..7deaccde428 100644 --- a/templates/tools/dockerfile/cmake_jessie_backports.include +++ b/templates/tools/dockerfile/cmake_jessie_backports.include @@ -2,5 +2,7 @@ # Use cmake 3.6 from jessie-backports # should only be used for images based on debian jessie. -RUN echo "deb http://ftp.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list +RUN echo "deb http://archive.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list +RUN echo 'Acquire::Check-Valid-Until "false";' > /etc/apt/apt.conf +RUN sed -i '/deb http:\/\/deb.debian.org\/debian jessie-updates main/d' /etc/apt/sources.list RUN apt-get update && apt-get install -t jessie-backports -y cmake && apt-get clean diff --git a/templates/tools/dockerfile/csharp_deps.include b/templates/tools/dockerfile/csharp_deps.include index 7ed00748670..fdede9e840b 100644 --- a/templates/tools/dockerfile/csharp_deps.include +++ b/templates/tools/dockerfile/csharp_deps.include @@ -1,24 +1,15 @@ #================ # C# dependencies -# Update to a newer version of mono -RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF -RUN echo "deb http://download.mono-project.com/repo/debian jessie main" | tee /etc/apt/sources.list.d/mono-official.list -RUN echo "deb http://download.mono-project.com/repo/debian wheezy-apache24-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list -RUN echo "deb http://download.mono-project.com/repo/debian wheezy-libjpeg62-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list +# cmake >=3.6 needed to build grpc_csharp_ext +RUN apt-get update && apt-get install -y cmake && apt-get clean -# Install dependencies -RUN apt-get update && apt-get -y dist-upgrade && apt-get install -y ${'\\'} +# Install mono +RUN apt-get update && apt-get install -y apt-transport-https dirmngr && apt-get clean +RUN apt-key adv --no-tty --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF +RUN echo "deb https://download.mono-project.com/repo/debian stable-stretch main" | tee /etc/apt/sources.list.d/mono-official-stable.list +RUN apt-get update && apt-get install -y ${'\\'} mono-devel ${'\\'} ca-certificates-mono ${'\\'} nuget ${'\\'} && apt-get clean - -RUN nuget update -self - -#================= -# Use cmake 3.6 from jessie-backports -# needed to build grpc_csharp_ext with cmake - -RUN echo "deb http://ftp.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list -RUN apt-get update && apt-get install -t jessie-backports -y cmake && apt-get clean diff --git a/templates/tools/dockerfile/csharp_dotnetcli_deps.include b/templates/tools/dockerfile/csharp_dotnetcli_deps.include index bc88d2bfa39..f3335926402 100644 --- a/templates/tools/dockerfile/csharp_dotnetcli_deps.include +++ b/templates/tools/dockerfile/csharp_dotnetcli_deps.include @@ -1,12 +1,20 @@ -# Install dotnet SDK based on https://www.microsoft.com/net/core#debian -RUN apt-get update && apt-get install -y curl libunwind8 gettext -# dotnet-dev-1.0.0-preview2-003131 -RUN curl -sSL -o dotnet100.tar.gz https://go.microsoft.com/fwlink/?LinkID=827530 -RUN mkdir -p /opt/dotnet && tar zxf dotnet100.tar.gz -C /opt/dotnet -# dotnet-dev-1.0.1 -RUN curl -sSL -o dotnet101.tar.gz https://go.microsoft.com/fwlink/?LinkID=843453 -RUN mkdir -p /opt/dotnet && tar zxf dotnet101.tar.gz -C /opt/dotnet -RUN ln -s /opt/dotnet/dotnet /usr/local/bin +# Install dotnet SDK +ENV DOTNET_SDK_VERSION 2.1.500 +RUN curl -sSL -o dotnet.tar.gz https://dotnetcli.blob.core.windows.net/dotnet/Sdk/$DOTNET_SDK_VERSION/dotnet-sdk-$DOTNET_SDK_VERSION-linux-x64.tar.gz ${'\\'} + && mkdir -p /usr/share/dotnet ${'\\'} + && tar -zxf dotnet.tar.gz -C /usr/share/dotnet ${'\\'} + && rm dotnet.tar.gz ${'\\'} + && ln -s /usr/share/dotnet/dotnet /usr/bin/dotnet + + +# Install .NET Core 1.1.10 runtime (required to run netcoreapp1.1) +RUN curl -sSL -o dotnet_old.tar.gz https://dotnetcli.blob.core.windows.net/dotnet/Runtime/1.1.10/dotnet-debian.9-x64.1.1.10.tar.gz ${'\\'} + && mkdir -p dotnet_old ${'\\'} + && tar zxf dotnet_old.tar.gz -C dotnet_old ${'\\'} + && cp -r dotnet_old/shared/Microsoft.NETCore.App/1.1.10/ /usr/share/dotnet/shared/Microsoft.NETCore.App/ ${'\\'} + && rm -rf dotnet_old/ dotnet_old.tar.gz +RUN apt-get update && apt-get install -y libunwind8 && apt-get clean + # Trigger the population of the local package cache ENV NUGET_XMLDOC_MODE skip diff --git a/templates/tools/dockerfile/debian_jessie_header.include b/templates/tools/dockerfile/debian_jessie_header.include new file mode 100644 index 00000000000..f71f98626f3 --- /dev/null +++ b/templates/tools/dockerfile/debian_jessie_header.include @@ -0,0 +1 @@ +FROM debian:jessie diff --git a/templates/tools/dockerfile/grpc_clang_format/Dockerfile.template b/templates/tools/dockerfile/grpc_clang_format/Dockerfile.template index c5ec66ae290..55ebe7b1802 100644 --- a/templates/tools/dockerfile/grpc_clang_format/Dockerfile.template +++ b/templates/tools/dockerfile/grpc_clang_format/Dockerfile.template @@ -14,7 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. - FROM debian:jessie + <%include file="../debian_jessie_header.include"/> <%include file="../clang5.include"/> ADD clang_format_all_the_things.sh / diff --git a/templates/tools/dockerfile/grpc_clang_tidy/Dockerfile.template b/templates/tools/dockerfile/grpc_clang_tidy/Dockerfile.template index bbdba700752..044da526feb 100644 --- a/templates/tools/dockerfile/grpc_clang_tidy/Dockerfile.template +++ b/templates/tools/dockerfile/grpc_clang_tidy/Dockerfile.template @@ -14,7 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. - FROM debian:jessie + <%include file="../debian_jessie_header.include"/> <%include file="../clang5.include"/> <%include file="../python_deps.include"/> diff --git a/templates/tools/dockerfile/interoptest/grpc_interop_aspnetcore/Dockerfile.template b/templates/tools/dockerfile/interoptest/grpc_interop_aspnetcore/Dockerfile.template new file mode 100644 index 00000000000..4f6c52b19af --- /dev/null +++ b/templates/tools/dockerfile/interoptest/grpc_interop_aspnetcore/Dockerfile.template @@ -0,0 +1,23 @@ +%YAML 1.2 +--- | + # Copyright 2019 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. + # 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 mcr.microsoft.com/dotnet/core/sdk:3.0.100-preview3-stretch + + # needed by get-dotnet.sh script + RUN apt-get update && apt-get install -y jq && apt-get clean + + # Define the default command. + CMD ["bash"] diff --git a/templates/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh.template b/templates/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh.template new file mode 100644 index 00000000000..d64286ab03c --- /dev/null +++ b/templates/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh.template @@ -0,0 +1,44 @@ +%YAML 1.2 +--- | + #!/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 Grpc.AspNetCore.Server interop server in a base image. + set -e + + mkdir -p /var/local/git + git clone /var/local/jenkins/grpc-dotnet /var/local/git/grpc-dotnet + + # copy service account keys if available + cp -r /var/local/jenkins/service_account $HOME || true + + cd /var/local/git/grpc-dotnet + + # If needed, update dotnet SDK and put it on path + ./build/get-dotnet.sh + # Normally we would source ./activate.sh + # to add dotnet to PATH, but that would only + # work for the build and not for a subsequent + # dotnet run from a different shell, + # so we create a symlink instead. + # TODO(jtattermusch): Come up with a cleaner solution. + if [ -f $(pwd)/.dotnet/dotnet ] + then + ln -s $(pwd)/.dotnet/dotnet /usr/local/bin/dotnet + fi + + ./build/get-grpc.sh + + dotnet build --configuration Debug Grpc.AspNetCore.sln diff --git a/templates/tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile.template b/templates/tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile.template index a1f1283de0f..abf1a3853d3 100644 --- a/templates/tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile.template +++ b/templates/tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile.template @@ -14,7 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. - FROM debian:jessie + FROM debian:stretch <%include file="../../apt_get_basic.include"/> <%include file="../../python_deps.include"/> diff --git a/templates/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile.template b/templates/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile.template index a1f1283de0f..abf1a3853d3 100644 --- a/templates/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile.template +++ b/templates/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile.template @@ -14,7 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. - FROM debian:jessie + FROM debian:stretch <%include file="../../apt_get_basic.include"/> <%include file="../../python_deps.include"/> diff --git a/templates/tools/dockerfile/interoptest/grpc_interop_cxx/Dockerfile.template b/templates/tools/dockerfile/interoptest/grpc_interop_cxx/Dockerfile.template index 49493e624b3..dbb3ffc9bb2 100644 --- a/templates/tools/dockerfile/interoptest/grpc_interop_cxx/Dockerfile.template +++ b/templates/tools/dockerfile/interoptest/grpc_interop_cxx/Dockerfile.template @@ -14,7 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. - FROM debian:jessie + <%include file="../../debian_jessie_header.include"/> <%include file="../../apt_get_basic.include"/> <%include file="../../python_deps.include"/> diff --git a/templates/tools/dockerfile/interoptest/grpc_interop_go1.11/Dockerfile.template b/templates/tools/dockerfile/interoptest/grpc_interop_go1.11/Dockerfile.template new file mode 100644 index 00000000000..4921d93f499 --- /dev/null +++ b/templates/tools/dockerfile/interoptest/grpc_interop_go1.11/Dockerfile.template @@ -0,0 +1,23 @@ +%YAML 1.2 +--- | + # Copyright 2018 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. + # 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 golang:1.11 + + <%include file="../../go_path.include"/> + <%include file="../../python_deps.include"/> + # Define the default command. + CMD ["bash"] + diff --git a/templates/tools/dockerfile/interoptest/grpc_interop_go1.11/build_interop.sh.template b/templates/tools/dockerfile/interoptest/grpc_interop_go1.11/build_interop.sh.template new file mode 100644 index 00000000000..a08798b1d6b --- /dev/null +++ b/templates/tools/dockerfile/interoptest/grpc_interop_go1.11/build_interop.sh.template @@ -0,0 +1,3 @@ +%YAML 1.2 +--- | + <%include file="../../go_build_interop.sh.include"/> diff --git a/templates/tools/dockerfile/interoptest/grpc_interop_java_oracle8/Dockerfile.include b/templates/tools/dockerfile/interoptest/grpc_interop_java_oracle8/Dockerfile.include index 24b9c59e4c7..7307e29f0a0 100644 --- a/templates/tools/dockerfile/interoptest/grpc_interop_java_oracle8/Dockerfile.include +++ b/templates/tools/dockerfile/interoptest/grpc_interop_java_oracle8/Dockerfile.include @@ -12,16 +12,9 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM debian:jessie +<%include file="../../debian_jessie_header.include"/> <%include file="java_deps.include"/> -<%include file="../../python_deps.include"/> - -# Trigger download of as many Gradle artifacts as possible. -RUN git clone --recursive --depth 1 https://github.com/grpc/grpc-java.git && ${'\\'} - cd grpc-java && ${'\\'} - ./gradlew :grpc-interop-testing:installDist -PskipCodegen=true && ${'\\'} - rm -r "$(pwd)" # Define the default command. -CMD ["bash"] \ No newline at end of file +CMD ["bash"] diff --git a/templates/tools/dockerfile/interoptest/grpc_interop_java_oracle8/java_deps.include b/templates/tools/dockerfile/interoptest/grpc_interop_java_oracle8/java_deps.include index 40d70e06d1a..c05b5642393 100644 --- a/templates/tools/dockerfile/interoptest/grpc_interop_java_oracle8/java_deps.include +++ b/templates/tools/dockerfile/interoptest/grpc_interop_java_oracle8/java_deps.include @@ -1,16 +1,11 @@ -# Install JDK 8 and Git +# Install JDK 8 # 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/ + apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys EEA14886 && ${'\\'} + apt-get update && apt-get -y install 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 diff --git a/templates/tools/dockerfile/interoptest/grpc_interop_node/Dockerfile.template b/templates/tools/dockerfile/interoptest/grpc_interop_node/Dockerfile.template index 6f098eb8266..ec6cd2970b1 100644 --- a/templates/tools/dockerfile/interoptest/grpc_interop_node/Dockerfile.template +++ b/templates/tools/dockerfile/interoptest/grpc_interop_node/Dockerfile.template @@ -14,7 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. - FROM debian:jessie + <%include file="../../debian_jessie_header.include"/> <%include file="../../apt_get_basic.include"/> <%include file="../../python_deps.include"/> diff --git a/templates/tools/dockerfile/interoptest/grpc_interop_nodepurejs/Dockerfile.template b/templates/tools/dockerfile/interoptest/grpc_interop_nodepurejs/Dockerfile.template index e53d863c92d..1b761c3ef05 100644 --- a/templates/tools/dockerfile/interoptest/grpc_interop_nodepurejs/Dockerfile.template +++ b/templates/tools/dockerfile/interoptest/grpc_interop_nodepurejs/Dockerfile.template @@ -14,7 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. - FROM debian:jessie + <%include file="../../debian_jessie_header.include"/> <%include file="../../apt_get_basic.include"/> <%include file="../../node_deps.include"/> diff --git a/templates/tools/dockerfile/interoptest/grpc_interop_php/Dockerfile.template b/templates/tools/dockerfile/interoptest/grpc_interop_php/Dockerfile.template index 06b0a4c0263..7a0ece69ac5 100644 --- a/templates/tools/dockerfile/interoptest/grpc_interop_php/Dockerfile.template +++ b/templates/tools/dockerfile/interoptest/grpc_interop_php/Dockerfile.template @@ -14,7 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. - FROM debian:jessie + <%include file="../../debian_jessie_header.include"/> <%include file="../../apt_get_basic.include"/> <%include file="../../php_deps.include"/> diff --git a/templates/tools/dockerfile/interoptest/grpc_interop_php7/Dockerfile.template b/templates/tools/dockerfile/interoptest/grpc_interop_php7/Dockerfile.template index 466bf6838ab..fe71c76251d 100644 --- a/templates/tools/dockerfile/interoptest/grpc_interop_php7/Dockerfile.template +++ b/templates/tools/dockerfile/interoptest/grpc_interop_php7/Dockerfile.template @@ -14,7 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. - FROM debian:jessie + <%include file="../../debian_jessie_header.include"/> <%include file="../../php7_deps.include"/> <%include file="../../run_tests_addons.include"/> diff --git a/templates/tools/dockerfile/interoptest/grpc_interop_python/Dockerfile.template b/templates/tools/dockerfile/interoptest/grpc_interop_python/Dockerfile.template index bf28796de38..f584a2378eb 100644 --- a/templates/tools/dockerfile/interoptest/grpc_interop_python/Dockerfile.template +++ b/templates/tools/dockerfile/interoptest/grpc_interop_python/Dockerfile.template @@ -14,15 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. - FROM debian:jessie - - <%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="../../python_stretch.include"/> - <%include file="../../run_tests_addons.include"/> - # Define the default command. - CMD ["bash"] - + RUN apt-get update && apt-get -t testing install -y python3.7 python3-all-dev + RUN curl https://bootstrap.pypa.io/get-pip.py | python3.7 diff --git a/templates/tools/dockerfile/interoptest/grpc_interop_ruby/Dockerfile.template b/templates/tools/dockerfile/interoptest/grpc_interop_ruby/Dockerfile.template index 0610a288a68..ae9dd12070f 100644 --- a/templates/tools/dockerfile/interoptest/grpc_interop_ruby/Dockerfile.template +++ b/templates/tools/dockerfile/interoptest/grpc_interop_ruby/Dockerfile.template @@ -14,7 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. - FROM debian:jessie + <%include file="../../debian_jessie_header.include"/> <%include file="../../apt_get_basic.include"/> <%include file="../../python_deps.include"/> diff --git a/templates/tools/dockerfile/java_build_interop.sh.include b/templates/tools/dockerfile/java_build_interop.sh.include index 16d5fb65cf1..e30b53e3f2a 100755 --- a/templates/tools/dockerfile/java_build_interop.sh.include +++ b/templates/tools/dockerfile/java_build_interop.sh.include @@ -16,16 +16,24 @@ # Builds Java interop server and client in a base image. set -e -mkdir -p /var/local/git -git clone --recursive --depth 1 /var/local/jenkins/grpc-java /var/local/git/grpc-java +cp -r /var/local/jenkins/grpc-java /tmp/grpc-java # copy service account keys if available cp -r /var/local/jenkins/service_account $HOME || true -cd /var/local/git/grpc-java - +pushd /tmp/grpc-java ./gradlew :grpc-interop-testing:installDist -PskipCodegen=true +mkdir -p /var/local/git/grpc-java/ +cp -r --parents -t /var/local/git/grpc-java/ ${'\\'} + interop-testing/build/install/ ${'\\'} + run-test-client.sh ${'\\'} + run-test-server.sh + +popd +rm -r /tmp/grpc-java +rm -r "$HOME/.gradle" + # enable extra java logging mkdir -p /var/local/grpc_java_logging echo "handlers = java.util.logging.ConsoleHandler diff --git a/templates/tools/dockerfile/php_valgrind.include b/templates/tools/dockerfile/php_valgrind.include new file mode 100644 index 00000000000..b5e6b534168 --- /dev/null +++ b/templates/tools/dockerfile/php_valgrind.include @@ -0,0 +1,5 @@ +#================= +# PHP Test dependencies + + RUN apt-get update && apt-get install -y ${'\\'} + valgrind diff --git a/templates/tools/dockerfile/ruby_deps.include b/templates/tools/dockerfile/ruby_deps.include index a8ee3ec7dc6..bcbd08c29ea 100644 --- a/templates/tools/dockerfile/ruby_deps.include +++ b/templates/tools/dockerfile/ruby_deps.include @@ -2,13 +2,14 @@ # Ruby dependencies # Install rvm -RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 +RUN apt-get update && apt-get install -y gnupg2 +RUN gpg2 --keyserver hkp://pool.sks-keyservers.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB RUN \curl -sSL https://get.rvm.io | bash -s stable -# Install Ruby 2.1 -RUN /bin/bash -l -c "rvm install ruby-2.1" -RUN /bin/bash -l -c "rvm use --default ruby-2.1" -RUN /bin/bash -l -c "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc" +# Install Ruby 2.5 +RUN /bin/bash -l -c "rvm install ruby-2.5" +RUN /bin/bash -l -c "rvm use --default ruby-2.5" +RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" -RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.1' >> ~/.bashrc" -RUN /bin/bash -l -c "gem install bundler --no-ri --no-rdoc" +RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.5' >> ~/.bashrc" +RUN /bin/bash -l -c "gem install bundler --no-document -v 1.9" diff --git a/templates/tools/dockerfile/test/bazel/Dockerfile.template b/templates/tools/dockerfile/test/bazel/Dockerfile.template index 50aa72edb35..864c9893a14 100644 --- a/templates/tools/dockerfile/test/bazel/Dockerfile.template +++ b/templates/tools/dockerfile/test/bazel/Dockerfile.template @@ -16,6 +16,12 @@ FROM gcr.io/oss-fuzz-base/base-builder + # -------------------------- WARNING -------------------------------------- + # If you are making changes to this file, consider changing + # https://github.com/google/oss-fuzz/blob/master/projects/grpc/Dockerfile + # accordingly. + # ------------------------------------------------------------------------- + # Install basic packages and Bazel dependencies. RUN apt-get update && apt-get install -y software-properties-common python-software-properties RUN add-apt-repository ppa:webupd8team/java diff --git a/templates/tools/dockerfile/test/csharp_jessie_x64/Dockerfile.template b/templates/tools/dockerfile/test/csharp_stretch_x64/Dockerfile.template similarity index 94% rename from templates/tools/dockerfile/test/csharp_jessie_x64/Dockerfile.template rename to templates/tools/dockerfile/test/csharp_stretch_x64/Dockerfile.template index 432f05442c2..1526d07fc63 100644 --- a/templates/tools/dockerfile/test/csharp_jessie_x64/Dockerfile.template +++ b/templates/tools/dockerfile/test/csharp_stretch_x64/Dockerfile.template @@ -1,6 +1,6 @@ %YAML 1.2 --- | - # Copyright 2015 gRPC authors. + # Copyright 2018 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. @@ -14,7 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. - FROM debian:jessie + FROM debian:stretch <%include file="../../apt_get_basic.include"/> <%include file="../../gcp_api_libraries.include"/> diff --git a/templates/tools/dockerfile/test/cxx_jessie_x64/Dockerfile.template b/templates/tools/dockerfile/test/cxx_jessie_x64/Dockerfile.template index 01e22cce4c4..f65ed9e58b7 100644 --- a/templates/tools/dockerfile/test/cxx_jessie_x64/Dockerfile.template +++ b/templates/tools/dockerfile/test/cxx_jessie_x64/Dockerfile.template @@ -14,7 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. - FROM debian:jessie + <%include file="../../debian_jessie_header.include"/> <%include file="../../apt_get_basic.include"/> <%include file="../../gcp_api_libraries.include"/> diff --git a/templates/tools/dockerfile/test/cxx_jessie_x86/Dockerfile.template b/templates/tools/dockerfile/test/cxx_jessie_x86/Dockerfile.template index b9cd1e98285..36f243c3405 100644 --- a/templates/tools/dockerfile/test/cxx_jessie_x86/Dockerfile.template +++ b/templates/tools/dockerfile/test/cxx_jessie_x86/Dockerfile.template @@ -15,6 +15,7 @@ # limitations under the License. FROM 32bit/debian:jessie + RUN sed -i '/deb http:\/\/http.debian.net\/debian jessie-updates main/d' /etc/apt/sources.list <%include file="../../apt_get_basic.include"/> <%include file="../../gcp_api_libraries.include"/> diff --git a/templates/tools/dockerfile/test/cxx_sanitizers_jessie_x64/Dockerfile.template b/templates/tools/dockerfile/test/cxx_sanitizers_jessie_x64/Dockerfile.template index 6070330e919..7d173236ee3 100644 --- a/templates/tools/dockerfile/test/cxx_sanitizers_jessie_x64/Dockerfile.template +++ b/templates/tools/dockerfile/test/cxx_sanitizers_jessie_x64/Dockerfile.template @@ -16,6 +16,7 @@ # This is the base Docker image we use for running tests on RBE FROM gcr.io/cloud-marketplace/google/rbe-debian8@sha256:1ede2a929b44d629ec5abe86eee6d7ffea1d5a4d247489a8867d46cfde3e38bd + RUN sed -i '/deb http:\/\/httpredir.debian.org\/debian jessie-updates main/d' /etc/apt/sources.list <%include file="../../apt_get_basic.include"/> <%include file="../../gcp_api_libraries.include"/> diff --git a/templates/tools/dockerfile/test/fuzzer/Dockerfile.template b/templates/tools/dockerfile/test/fuzzer/Dockerfile.template index 6dcd7b77dec..345da0804ad 100644 --- a/templates/tools/dockerfile/test/fuzzer/Dockerfile.template +++ b/templates/tools/dockerfile/test/fuzzer/Dockerfile.template @@ -14,7 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. - FROM debian:jessie + <%include file="../../debian_jessie_header.include"/> <%include file="../../apt_get_basic.include"/> <%include file="../../gcp_api_libraries.include"/> diff --git a/templates/tools/dockerfile/test/multilang_jessie_x64/Dockerfile.template b/templates/tools/dockerfile/test/multilang_jessie_x64/Dockerfile.template deleted file mode 100644 index ac687b710ff..00000000000 --- a/templates/tools/dockerfile/test/multilang_jessie_x64/Dockerfile.template +++ /dev/null @@ -1,41 +0,0 @@ -%YAML 1.2 ---- | - # Copyright 2016 gRPC authors. - # - # Licensed under the Apache License, Version 2.0 (the "License"); - # you may not use this file except in compliance with the License. - # You may obtain a copy of the License at - # - # http://www.apache.org/licenses/LICENSE-2.0 - # - # Unless required by applicable law or agreed to in writing, software - # distributed under the License is distributed on an "AS IS" BASIS, - # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - # See the License for the specific language governing permissions and - # limitations under the License. - - FROM debian:jessie - - <%include file="../../apt_get_basic.include"/> - <%include file="../../gcp_api_libraries.include"/> - <%include file="../../csharp_deps.include"/> - <%include file="../../csharp_dotnetcli_deps.include"/> - <%include file="../../cxx_deps.include"/> - <%include file="../../node_deps.include"/> - <%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 - - # Install Mako to generate files in grpc/grpc-node - RUN pip install Mako - - <%include file="../../run_tests_addons.include"/> - # Define the default command. - CMD ["bash"] diff --git a/templates/tools/dockerfile/test/node_jessie_x64/Dockerfile.template b/templates/tools/dockerfile/test/node_jessie_x64/Dockerfile.template index af85a542358..cd0513a1a4d 100644 --- a/templates/tools/dockerfile/test/node_jessie_x64/Dockerfile.template +++ b/templates/tools/dockerfile/test/node_jessie_x64/Dockerfile.template @@ -14,7 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. - FROM debian:jessie + <%include file="../../debian_jessie_header.include"/> <%include file="../../apt_get_basic.include"/> <%include file="../../gcp_api_libraries.include"/> diff --git a/templates/tools/dockerfile/test/php7_jessie_x64/Dockerfile.template b/templates/tools/dockerfile/test/php7_jessie_x64/Dockerfile.template index e7b6c0d5f9c..d29cd7e4e59 100644 --- a/templates/tools/dockerfile/test/php7_jessie_x64/Dockerfile.template +++ b/templates/tools/dockerfile/test/php7_jessie_x64/Dockerfile.template @@ -14,11 +14,12 @@ # See the License for the specific language governing permissions and # limitations under the License. - FROM debian:jessie + <%include file="../../debian_jessie_header.include"/> <%include file="../../php7_deps.include"/> <%include file="../../gcp_api_libraries.include"/> <%include file="../../python_deps.include"/> + <%include file="../../php_valgrind.include"/> <%include file="../../run_tests_addons.include"/> # Define the default command. CMD ["bash"] diff --git a/templates/tools/dockerfile/test/php_jessie_x64/Dockerfile.template b/templates/tools/dockerfile/test/php_jessie_x64/Dockerfile.template index fdbad53c391..3bd8f9c7c47 100644 --- a/templates/tools/dockerfile/test/php_jessie_x64/Dockerfile.template +++ b/templates/tools/dockerfile/test/php_jessie_x64/Dockerfile.template @@ -14,7 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. - FROM debian:jessie + <%include file="../../debian_jessie_header.include"/> <%include file="../../apt_get_basic.include"/> <%include file="../../gcp_api_libraries.include"/> diff --git a/templates/tools/dockerfile/test/python_jessie_x64/Dockerfile.template b/templates/tools/dockerfile/test/python_jessie_x64/Dockerfile.template index e73b839a284..dde33a9e1a4 100644 --- a/templates/tools/dockerfile/test/python_jessie_x64/Dockerfile.template +++ b/templates/tools/dockerfile/test/python_jessie_x64/Dockerfile.template @@ -14,7 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. - FROM debian:jessie + <%include file="../../debian_jessie_header.include"/> <%include file="../../apt_get_basic.include"/> <%include file="../../gcp_api_libraries.include"/> diff --git a/templates/tools/dockerfile/test/python_stretch_3.7_x64/Dockerfile.template b/templates/tools/dockerfile/test/python_stretch_3.7_x64/Dockerfile.template index ff342db493b..c3602f6c512 100644 --- a/templates/tools/dockerfile/test/python_stretch_3.7_x64/Dockerfile.template +++ b/templates/tools/dockerfile/test/python_stretch_3.7_x64/Dockerfile.template @@ -18,3 +18,6 @@ RUN apt-get update && apt-get -t testing install -y python3.7 python3-all-dev RUN curl https://bootstrap.pypa.io/get-pip.py | python3.7 + + # for Python test coverage reporting + RUN pip install coverage diff --git a/templates/tools/dockerfile/test/ruby_jessie_x64/Dockerfile.template b/templates/tools/dockerfile/test/ruby_jessie_x64/Dockerfile.template index bf4bb279182..2fed02246bb 100644 --- a/templates/tools/dockerfile/test/ruby_jessie_x64/Dockerfile.template +++ b/templates/tools/dockerfile/test/ruby_jessie_x64/Dockerfile.template @@ -14,7 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. - FROM debian:jessie + <%include file="../../debian_jessie_header.include"/> <%include file="../../apt_get_basic.include"/> <%include file="../../gcp_api_libraries.include"/> diff --git a/templates/tools/dockerfile/test/sanity/Dockerfile.template b/templates/tools/dockerfile/test/sanity/Dockerfile.template index eac7f2ab013..2e4bdf537b7 100644 --- a/templates/tools/dockerfile/test/sanity/Dockerfile.template +++ b/templates/tools/dockerfile/test/sanity/Dockerfile.template @@ -14,28 +14,25 @@ # See the License for the specific language governing permissions and # limitations under the License. - FROM debian:jessie - - <%include file="../../apt_get_basic.include"/> - <%include file="../../gcp_api_libraries.include"/> - <%include file="../../python_deps.include"/> + <%include file="../../python_stretch.include"/> <%include file="../../cxx_deps.include"/> #======================== # Sanity test dependencies + RUN apt-get update && apt-get -t testing install -y python3.7 python3-all-dev + RUN curl https://bootstrap.pypa.io/get-pip.py | python3.7 + # Make Python 3.7 the default Python 3 version + RUN update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.7 1 RUN apt-get update && apt-get install -y ${"\\"} - python-pip ${"\\"} autoconf ${"\\"} automake ${"\\"} libtool ${"\\"} curl ${"\\"} - python-virtualenv ${"\\"} - python-lxml ${"\\"} shellcheck - RUN pip install simplejson mako - + RUN python2 -m pip install simplejson mako virtualenv lxml + RUN python3 -m pip install simplejson mako virtualenv lxml + <%include file="../../clang5.include"/> - <%include file="../../run_tests_addons.include"/> - + <%include file="../../bazel.include"/> + # Define the default command. CMD ["bash"] - diff --git a/test/core/avl/BUILD b/test/core/avl/BUILD index 48f5baeb1a5..c31abebcbe5 100644 --- a/test/core/avl/BUILD +++ b/test/core/avl/BUILD @@ -25,6 +25,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/avl/avl_test.cc b/test/core/avl/avl_test.cc index 01002fec72a..769e67563dc 100644 --- a/test/core/avl/avl_test.cc +++ b/test/core/avl/avl_test.cc @@ -283,7 +283,7 @@ static void test_stress(int amount_of_stress) { } int main(int argc, char* argv[]) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); test_get(); test_ll(); diff --git a/test/core/backoff/BUILD b/test/core/backoff/BUILD index 6fbd6542d49..e4fc2871054 100644 --- a/test/core/backoff/BUILD +++ b/test/core/backoff/BUILD @@ -33,7 +33,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/backoff/backoff_test.cc b/test/core/backoff/backoff_test.cc index 1998a839778..8fd120e0428 100644 --- a/test/core/backoff/backoff_test.cc +++ b/test/core/backoff/backoff_test.cc @@ -171,7 +171,7 @@ TEST(BackOffTest, JitterBackOff) { } // namespace grpc int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/core/bad_client/bad_client.cc b/test/core/bad_client/bad_client.cc index 4f5d2a2862b..26550a2a701 100644 --- a/test/core/bad_client/bad_client.cc +++ b/test/core/bad_client/bad_client.cc @@ -66,7 +66,7 @@ static void server_setup_transport(void* ts, grpc_transport* transport) { thd_args* a = static_cast(ts); grpc_core::ExecCtx exec_ctx; grpc_server_setup_transport(a->server, transport, nullptr, - grpc_server_get_channel_args(a->server), 0); + grpc_server_get_channel_args(a->server), nullptr); } /* Sets the read_done event */ @@ -143,7 +143,8 @@ void grpc_run_client_side_validator(grpc_bad_client_arg* arg, uint32_t flags, grpc_closure read_done_closure; GRPC_CLOSURE_INIT(&read_done_closure, set_read_done, &read_done_event, grpc_schedule_on_exec_ctx); - grpc_endpoint_read(sfd->client, &incoming, &read_done_closure); + grpc_endpoint_read(sfd->client, &incoming, &read_done_closure, + /*urgent=*/true); grpc_core::ExecCtx::Get()->Flush(); do { GPR_ASSERT(gpr_time_cmp(deadline, gpr_now(deadline.clock_type)) > 0); @@ -256,7 +257,7 @@ bool client_connection_preface_validator(grpc_slice_buffer* incoming, return false; } grpc_slice slice = incoming->slices[0]; - /* There should be atleast a settings frame present */ + /* There should be at least one settings frame present */ if (GRPC_SLICE_LENGTH(slice) < MIN_HTTP2_FRAME_SIZE) { return false; } diff --git a/test/core/bad_client/gen_build_yaml.py b/test/core/bad_client/gen_build_yaml.py index 32afba5b1f5..6a40b4e5e9d 100755 --- a/test/core/bad_client/gen_build_yaml.py +++ b/test/core/bad_client/gen_build_yaml.py @@ -56,7 +56,6 @@ def main(): 'deps': [ 'grpc_test_util_unsecure', 'grpc_unsecure', - 'gpr_test_util', 'gpr' ] }], @@ -74,7 +73,6 @@ def main(): 'bad_client_test', 'grpc_test_util_unsecure', 'grpc_unsecure', - 'gpr_test_util', 'gpr' ] } diff --git a/test/core/bad_client/tests/badreq.cc b/test/core/bad_client/tests/badreq.cc index eeaf4c99748..c560dc5561c 100644 --- a/test/core/bad_client/tests/badreq.cc +++ b/test/core/bad_client/tests/badreq.cc @@ -39,7 +39,7 @@ static void verifier(grpc_server* server, grpc_completion_queue* cq, } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); /* invalid content type */ diff --git a/test/core/bad_client/tests/connection_prefix.cc b/test/core/bad_client/tests/connection_prefix.cc index 4aab234d3e5..286a3ccafbb 100644 --- a/test/core/bad_client/tests/connection_prefix.cc +++ b/test/core/bad_client/tests/connection_prefix.cc @@ -29,7 +29,7 @@ static void verifier(grpc_server* server, grpc_completion_queue* cq, } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); GRPC_RUN_BAD_CLIENT_TEST(verifier, nullptr, "X", 0); diff --git a/test/core/bad_client/tests/duplicate_header.cc b/test/core/bad_client/tests/duplicate_header.cc index e3cae8b5952..dfa6e518114 100644 --- a/test/core/bad_client/tests/duplicate_header.cc +++ b/test/core/bad_client/tests/duplicate_header.cc @@ -122,7 +122,7 @@ static void verifier(grpc_server* server, grpc_completion_queue* cq, } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); /* Verify that sending multiple headers doesn't segfault */ diff --git a/test/core/bad_client/tests/head_of_line_blocking.cc b/test/core/bad_client/tests/head_of_line_blocking.cc index 427db464462..c856b9b122c 100644 --- a/test/core/bad_client/tests/head_of_line_blocking.cc +++ b/test/core/bad_client/tests/head_of_line_blocking.cc @@ -109,7 +109,7 @@ static void addbuf(const void* data, size_t len) { int main(int argc, char** argv) { int i; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); #define NUM_FRAMES 10 diff --git a/test/core/bad_client/tests/headers.cc b/test/core/bad_client/tests/headers.cc index 2aa1b280cee..02ea7597502 100644 --- a/test/core/bad_client/tests/headers.cc +++ b/test/core/bad_client/tests/headers.cc @@ -33,7 +33,7 @@ static void verifier(grpc_server* server, grpc_completion_queue* cq, } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); /* partial http2 header prefixes */ diff --git a/test/core/bad_client/tests/initial_settings_frame.cc b/test/core/bad_client/tests/initial_settings_frame.cc index 0220000ecea..fcbb841331f 100644 --- a/test/core/bad_client/tests/initial_settings_frame.cc +++ b/test/core/bad_client/tests/initial_settings_frame.cc @@ -32,7 +32,7 @@ static void verifier(grpc_server* server, grpc_completion_queue* cq, } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); /* various partial prefixes */ diff --git a/test/core/bad_client/tests/large_metadata.cc b/test/core/bad_client/tests/large_metadata.cc index d534753f536..520a1af0c2d 100644 --- a/test/core/bad_client/tests/large_metadata.cc +++ b/test/core/bad_client/tests/large_metadata.cc @@ -141,7 +141,7 @@ static void server_verifier_sends_too_much_metadata(grpc_server* server, int main(int argc, char** argv) { int i; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); // Test sending more metadata than the server will accept. gpr_strvec headers; diff --git a/test/core/bad_client/tests/server_registered_method.cc b/test/core/bad_client/tests/server_registered_method.cc index c2dc9c66af1..834142ac1b4 100644 --- a/test/core/bad_client/tests/server_registered_method.cc +++ b/test/core/bad_client/tests/server_registered_method.cc @@ -76,7 +76,7 @@ static void verifier_fails(grpc_server* server, grpc_completion_queue* cq, } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); /* body generated with diff --git a/test/core/bad_client/tests/simple_request.cc b/test/core/bad_client/tests/simple_request.cc index c80fc5cb4af..614f5869976 100644 --- a/test/core/bad_client/tests/simple_request.cc +++ b/test/core/bad_client/tests/simple_request.cc @@ -123,7 +123,7 @@ static void failure_verifier(grpc_server* server, grpc_completion_queue* cq, } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); /* basic request: check that things are working */ @@ -147,11 +147,12 @@ int main(int argc, char** argv) { /* push a window update with bad flags */ GRPC_RUN_BAD_CLIENT_TEST(failure_verifier, nullptr, PFX_STR "\x00\x00\x00\x08\x10\x00\x00\x00\x01", 0); - /* push a window update with bad data */ + /* push a window update with bad data (0 is not legal window size increment) + */ GRPC_RUN_BAD_CLIENT_TEST(failure_verifier, nullptr, PFX_STR "\x00\x00\x04\x08\x00\x00\x00\x00\x01" - "\xff\xff\xff\xff", + "\x00\x00\x00\x00", 0); /* push a short goaway */ GRPC_RUN_BAD_CLIENT_TEST(failure_verifier, nullptr, diff --git a/test/core/bad_client/tests/unknown_frame.cc b/test/core/bad_client/tests/unknown_frame.cc index b1b618a43f3..9e0cf3f6a90 100644 --- a/test/core/bad_client/tests/unknown_frame.cc +++ b/test/core/bad_client/tests/unknown_frame.cc @@ -34,7 +34,7 @@ static void verifier(grpc_server* server, grpc_completion_queue* cq, int main(int argc, char** argv) { grpc_init(); - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); /* test adding prioritization data */ GRPC_RUN_BAD_CLIENT_TEST(verifier, nullptr, diff --git a/test/core/bad_client/tests/window_overflow.cc b/test/core/bad_client/tests/window_overflow.cc index b552704e9c5..87042a46f20 100644 --- a/test/core/bad_client/tests/window_overflow.cc +++ b/test/core/bad_client/tests/window_overflow.cc @@ -71,7 +71,7 @@ int main(int argc, char** argv) { #define FRAME_SIZE (MESSAGES_PER_FRAME * 5) #define SEND_SIZE (4 * 1024 * 1024) #define NUM_FRAMES (SEND_SIZE / FRAME_SIZE + 1) - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); addbuf(PFX_STR, sizeof(PFX_STR) - 1); diff --git a/test/core/bad_connection/BUILD b/test/core/bad_connection/BUILD new file mode 100644 index 00000000000..82b38ccc469 --- /dev/null +++ b/test/core/bad_connection/BUILD @@ -0,0 +1,33 @@ +# 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. + +load("//bazel:grpc_build_system.bzl", "grpc_cc_library", "grpc_cc_test", "grpc_cc_binary", "grpc_package") + +licenses(["notice"]) # Apache v2 + +grpc_package(name = "test/core/bad_connection") + +grpc_cc_binary( + name = "close_fd_test", + srcs = [ + "close_fd_test.cc", + ], + language = "C++", + deps = [ + "//:gpr", + "//:grpc", + "//test/core/util:grpc_test_util", + ], + tags = ["no_windows"], +) diff --git a/test/core/bad_connection/close_fd_test.cc b/test/core/bad_connection/close_fd_test.cc new file mode 100644 index 00000000000..e8f297e77ea --- /dev/null +++ b/test/core/bad_connection/close_fd_test.cc @@ -0,0 +1,759 @@ +/* + * + * Copyright 2019 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. + * + * close_fd_test tests the behavior of grpc core when the transport gets + * disconnected. + * The test creates an http2 transport over a socket pair and closes the + * client or server file descriptor to simulate connection breakage while + * an RPC call is in progress. + * + */ +#include "src/core/lib/iomgr/port.h" + +// This test won't work except with posix sockets enabled +#ifdef GRPC_POSIX_SOCKET + +#include "test/core/util/test_config.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" +#include "src/core/lib/gpr/env.h" +#include "src/core/lib/iomgr/endpoint_pair.h" +#include "src/core/lib/surface/channel.h" +#include "src/core/lib/surface/completion_queue.h" +#include "src/core/lib/surface/server.h" + +static void* tag(intptr_t t) { return (void*)t; } + +typedef struct test_ctx test_ctx; + +struct test_ctx { + /* completion queue for call notifications on the server */ + grpc_completion_queue* cq; + /* completion queue registered to server for shutdown events */ + grpc_completion_queue* shutdown_cq; + /* client's completion queue */ + grpc_completion_queue* client_cq; + /* completion queue bound to call on the server */ + grpc_completion_queue* bound_cq; + /* Server responds to client calls */ + grpc_server* server; + /* Client calls are sent over the channel */ + grpc_channel* client; + /* encapsulates client, server endpoints */ + grpc_endpoint_pair* ep; +}; + +static test_ctx g_ctx; + +/* chttp2 transport that is immediately available (used for testing + connected_channel without a client_channel */ + +static void server_setup_transport(grpc_transport* transport) { + grpc_core::ExecCtx exec_ctx; + grpc_endpoint_add_to_pollset(g_ctx.ep->server, grpc_cq_pollset(g_ctx.cq)); + grpc_server_setup_transport(g_ctx.server, transport, nullptr, + grpc_server_get_channel_args(g_ctx.server), + nullptr); +} + +static void client_setup_transport(grpc_transport* transport) { + grpc_core::ExecCtx exec_ctx; + grpc_endpoint_add_to_pollset(g_ctx.ep->client, + grpc_cq_pollset(g_ctx.client_cq)); + grpc_arg authority_arg = grpc_channel_arg_string_create( + const_cast(GRPC_ARG_DEFAULT_AUTHORITY), + const_cast("test-authority")); + grpc_channel_args* args = + grpc_channel_args_copy_and_add(nullptr, &authority_arg, 1); + /* TODO (pjaikumar): use GRPC_CLIENT_CHANNEL instead of + * GRPC_CLIENT_DIRECT_CHANNEL */ + g_ctx.client = grpc_channel_create("socketpair-target", args, + GRPC_CLIENT_DIRECT_CHANNEL, transport); + grpc_channel_args_destroy(args); +} + +static void init_client() { + grpc_core::ExecCtx exec_ctx; + grpc_transport* transport; + transport = grpc_create_chttp2_transport(nullptr, g_ctx.ep->client, true); + client_setup_transport(transport); + GPR_ASSERT(g_ctx.client); + grpc_chttp2_transport_start_reading(transport, nullptr, nullptr); +} + +static void init_server() { + grpc_core::ExecCtx exec_ctx; + grpc_transport* transport; + GPR_ASSERT(!g_ctx.server); + g_ctx.server = grpc_server_create(nullptr, nullptr); + grpc_server_register_completion_queue(g_ctx.server, g_ctx.cq, nullptr); + grpc_server_start(g_ctx.server); + transport = grpc_create_chttp2_transport(nullptr, g_ctx.ep->server, false); + server_setup_transport(transport); + grpc_chttp2_transport_start_reading(transport, nullptr, nullptr); +} + +static void test_init() { + grpc_endpoint_pair* sfd = + static_cast(gpr_malloc(sizeof(grpc_endpoint_pair))); + memset(&g_ctx, 0, sizeof(g_ctx)); + g_ctx.ep = sfd; + g_ctx.cq = grpc_completion_queue_create_for_next(nullptr); + g_ctx.shutdown_cq = grpc_completion_queue_create_for_pluck(nullptr); + g_ctx.bound_cq = grpc_completion_queue_create_for_next(nullptr); + g_ctx.client_cq = grpc_completion_queue_create_for_next(nullptr); + + /* Create endpoints */ + *sfd = grpc_iomgr_create_endpoint_pair("fixture", nullptr); + /* Create client, server and setup transport over endpoint pair */ + init_server(); + init_client(); +} + +static void drain_cq(grpc_completion_queue* cq) { + grpc_event event; + do { + event = grpc_completion_queue_next(cq, grpc_timeout_seconds_to_deadline(1), + nullptr); + } while (event.type != GRPC_QUEUE_SHUTDOWN); +} + +static void drain_and_destroy_cq(grpc_completion_queue* cq) { + grpc_completion_queue_shutdown(cq); + drain_cq(cq); + grpc_completion_queue_destroy(cq); +} + +static void shutdown_server() { + if (!g_ctx.server) return; + grpc_server_shutdown_and_notify(g_ctx.server, g_ctx.shutdown_cq, tag(1000)); + GPR_ASSERT(grpc_completion_queue_pluck(g_ctx.shutdown_cq, tag(1000), + grpc_timeout_seconds_to_deadline(1), + nullptr) + .type == GRPC_OP_COMPLETE); + grpc_server_destroy(g_ctx.server); + g_ctx.server = nullptr; +} + +static void shutdown_client() { + if (!g_ctx.client) return; + grpc_channel_destroy(g_ctx.client); + g_ctx.client = nullptr; +} + +static void end_test() { + shutdown_server(); + shutdown_client(); + + drain_and_destroy_cq(g_ctx.cq); + drain_and_destroy_cq(g_ctx.client_cq); + drain_and_destroy_cq(g_ctx.bound_cq); + grpc_completion_queue_destroy(g_ctx.shutdown_cq); + gpr_free(g_ctx.ep); +} + +typedef enum fd_type { CLIENT_FD, SERVER_FD } fd_type; + +static const char* fd_type_str(fd_type fdtype) { + if (fdtype == CLIENT_FD) { + return "client"; + } else if (fdtype == SERVER_FD) { + return "server"; + } else { + gpr_log(GPR_ERROR, "Unexpected fd_type %d", fdtype); + abort(); + } +} + +static void _test_close_before_server_recv(fd_type fdtype) { + grpc_core::ExecCtx exec_ctx; + grpc_call* call; + grpc_call* server_call; + grpc_event event; + grpc_slice request_payload_slice = + grpc_slice_from_copied_string("hello world"); + grpc_slice response_payload_slice = + grpc_slice_from_copied_string("hello you"); + 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); + gpr_log(GPR_INFO, "Running test: test_close_%s_before_server_recv", + fd_type_str(fdtype)); + test_init(); + + 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_byte_buffer* request_payload_recv = nullptr; + grpc_byte_buffer* response_payload_recv = nullptr; + grpc_call_details call_details; + grpc_status_code status = GRPC_STATUS__DO_NOT_USE; + grpc_call_error error; + grpc_slice details; + + gpr_timespec deadline = grpc_timeout_seconds_to_deadline(1); + call = grpc_channel_create_call( + g_ctx.client, nullptr, GRPC_PROPAGATE_DEFAULTS, g_ctx.client_cq, + grpc_slice_from_static_string("/foo"), nullptr, deadline, nullptr); + GPR_ASSERT(call); + + 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_MESSAGE; + op->data.send_message.send_message = request_payload; + 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_MESSAGE; + op->data.recv_message.recv_message = &response_payload_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(call, ops, static_cast(op - ops), + tag(1), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + error = grpc_server_request_call(g_ctx.server, &server_call, &call_details, + &request_metadata_recv, g_ctx.bound_cq, + g_ctx.cq, tag(101)); + GPR_ASSERT(GRPC_CALL_OK == error); + event = grpc_completion_queue_next( + g_ctx.cq, grpc_timeout_milliseconds_to_deadline(100), nullptr); + GPR_ASSERT(event.success == 1); + GPR_ASSERT(event.tag == tag(101)); + GPR_ASSERT(event.type == GRPC_OP_COMPLETE); + + 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_RECV_MESSAGE; + op->data.recv_message.recv_message = &request_payload_recv; + op->flags = 0; + op->reserved = nullptr; + op++; + + grpc_endpoint_pair* sfd = g_ctx.ep; + int fd; + if (fdtype == SERVER_FD) { + fd = sfd->server->vtable->get_fd(sfd->server); + } else { + GPR_ASSERT(fdtype == CLIENT_FD); + fd = sfd->client->vtable->get_fd(sfd->client); + } + /* Connection is closed before the server receives the client's message. */ + close(fd); + + error = grpc_call_start_batch(server_call, ops, static_cast(op - ops), + tag(102), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + event = grpc_completion_queue_next( + g_ctx.bound_cq, grpc_timeout_milliseconds_to_deadline(100), nullptr); + + /* Batch operation completes on the server side. + * event.success will be true if the op completes successfully. + * event.success will be false if the op completes with an error. This can + * happen due to a race with closing the fd resulting in pending writes + * failing due to stream closure. + * */ + GPR_ASSERT(event.type == GRPC_OP_COMPLETE); + GPR_ASSERT(event.tag == tag(102)); + + event = grpc_completion_queue_next( + g_ctx.client_cq, grpc_timeout_milliseconds_to_deadline(100), nullptr); + /* When the client fd is closed, the server gets EPIPE. + * When server fd is closed, server gets EBADF. + * In both cases server sends GRPC_STATUS_UNAVALABLE to the client. However, + * the client may not receive this grpc_status as it's socket is being closed. + * If the client didn't get grpc_status from the server it will time out + * waiting on the completion queue. So there 2 2 possibilities: + * 1. client times out waiting for server's response + * 2. client receives GRPC_STATUS_UNAVAILABLE from server + */ + if (event.type == GRPC_QUEUE_TIMEOUT) { + GPR_ASSERT(event.success == 0); + /* status is not initialized */ + GPR_ASSERT(status == GRPC_STATUS__DO_NOT_USE); + } else { + GPR_ASSERT(event.type == GRPC_OP_COMPLETE); + GPR_ASSERT(event.success == 1); + GPR_ASSERT(event.tag == tag(1)); + GPR_ASSERT(status == GRPC_STATUS_UNAVAILABLE); + } + + 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(call); + grpc_call_unref(server_call); + + 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); + + end_test(); +} + +static void test_close_before_server_recv() { + /* Close client side of the connection before server receives message from + * client */ + _test_close_before_server_recv(CLIENT_FD); + /* Close server side of the connection before server receives message from + * client */ + _test_close_before_server_recv(SERVER_FD); +} + +static void _test_close_before_server_send(fd_type fdtype) { + grpc_core::ExecCtx exec_ctx; + grpc_call* call; + grpc_call* server_call; + grpc_event event; + grpc_slice request_payload_slice = + grpc_slice_from_copied_string("hello world"); + grpc_slice response_payload_slice = + grpc_slice_from_copied_string("hello you"); + 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); + gpr_log(GPR_INFO, "Running test: test_close_%s_before_server_send", + fd_type_str(fdtype)); + test_init(); + + 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_byte_buffer* request_payload_recv = nullptr; + grpc_byte_buffer* response_payload_recv = nullptr; + grpc_call_details call_details; + grpc_status_code status = GRPC_STATUS__DO_NOT_USE; + grpc_call_error error; + grpc_slice details; + int was_cancelled = 2; + + gpr_timespec deadline = grpc_timeout_seconds_to_deadline(1); + call = grpc_channel_create_call( + g_ctx.client, nullptr, GRPC_PROPAGATE_DEFAULTS, g_ctx.client_cq, + grpc_slice_from_static_string("/foo"), nullptr, deadline, nullptr); + GPR_ASSERT(call); + + 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_MESSAGE; + op->data.send_message.send_message = request_payload; + 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_MESSAGE; + op->data.recv_message.recv_message = &response_payload_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(call, ops, static_cast(op - ops), + tag(1), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + error = grpc_server_request_call(g_ctx.server, &server_call, &call_details, + &request_metadata_recv, g_ctx.bound_cq, + g_ctx.cq, tag(101)); + GPR_ASSERT(GRPC_CALL_OK == error); + event = grpc_completion_queue_next( + g_ctx.cq, grpc_timeout_milliseconds_to_deadline(100), nullptr); + GPR_ASSERT(event.success == 1); + GPR_ASSERT(event.tag == tag(101)); + GPR_ASSERT(event.type == GRPC_OP_COMPLETE); + + 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_RECV_MESSAGE; + op->data.recv_message.recv_message = &request_payload_recv; + op->flags = 0; + op->reserved = nullptr; + op++; + error = grpc_call_start_batch(server_call, ops, static_cast(op - ops), + tag(102), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + event = grpc_completion_queue_next( + g_ctx.bound_cq, grpc_timeout_milliseconds_to_deadline(100), nullptr); + GPR_ASSERT(event.type == GRPC_OP_COMPLETE); + GPR_ASSERT(event.success == 1); + GPR_ASSERT(event.tag == tag(102)); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; + op->data.recv_close_on_server.cancelled = &was_cancelled; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_SEND_MESSAGE; + op->data.send_message.send_message = response_payload; + 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_OK; + 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++; + + grpc_endpoint_pair* sfd = g_ctx.ep; + int fd; + if (fdtype == SERVER_FD) { + fd = sfd->server->vtable->get_fd(sfd->server); + } else { + GPR_ASSERT(fdtype == CLIENT_FD); + fd = sfd->client->vtable->get_fd(sfd->client); + } + + /* Connection is closed before the server sends message and status to the + * client. */ + close(fd); + error = grpc_call_start_batch(server_call, ops, static_cast(op - ops), + tag(103), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + /* Batch operation succeeds on the server side */ + event = grpc_completion_queue_next( + g_ctx.bound_cq, grpc_timeout_milliseconds_to_deadline(100), nullptr); + GPR_ASSERT(event.type == GRPC_OP_COMPLETE); + GPR_ASSERT(event.success == 1); + GPR_ASSERT(event.tag == tag(103)); + + event = grpc_completion_queue_next( + g_ctx.client_cq, grpc_timeout_milliseconds_to_deadline(100), nullptr); + /* In both cases server sends GRPC_STATUS_UNAVALABLE to the client. However, + * the client may not receive this grpc_status as it's socket is being closed. + * If the client didn't get grpc_status from the server it will time out + * waiting on the completion queue + */ + if (event.type == GRPC_OP_COMPLETE) { + GPR_ASSERT(event.success == 1); + GPR_ASSERT(event.tag == tag(1)); + GPR_ASSERT(status == GRPC_STATUS_UNAVAILABLE); + } else { + GPR_ASSERT(event.type == GRPC_QUEUE_TIMEOUT); + GPR_ASSERT(event.success == 0); + /* status is not initialized */ + GPR_ASSERT(status == GRPC_STATUS__DO_NOT_USE); + } + GPR_ASSERT(was_cancelled == 0); + + 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(call); + grpc_call_unref(server_call); + + 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); + + end_test(); +} + +static void test_close_before_server_send() { + /* Close client side of the connection before server sends message to client + * */ + _test_close_before_server_send(CLIENT_FD); + /* Close server side of the connection before server sends message to client + * */ + _test_close_before_server_send(SERVER_FD); +} + +static void _test_close_before_client_send(fd_type fdtype) { + grpc_core::ExecCtx exec_ctx; + grpc_call* call; + grpc_event event; + grpc_slice request_payload_slice = + grpc_slice_from_copied_string("hello world"); + grpc_slice response_payload_slice = + grpc_slice_from_copied_string("hello you"); + 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); + gpr_log(GPR_INFO, "Running test: test_close_%s_before_client_send", + fd_type_str(fdtype)); + test_init(); + + 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_byte_buffer* request_payload_recv = nullptr; + grpc_byte_buffer* response_payload_recv = nullptr; + grpc_call_details call_details; + grpc_status_code status; + grpc_call_error error; + grpc_slice details; + + gpr_timespec deadline = grpc_timeout_seconds_to_deadline(1); + call = grpc_channel_create_call( + g_ctx.client, nullptr, GRPC_PROPAGATE_DEFAULTS, g_ctx.client_cq, + grpc_slice_from_static_string("/foo"), nullptr, deadline, nullptr); + GPR_ASSERT(call); + + 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_MESSAGE; + op->data.send_message.send_message = request_payload; + 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_MESSAGE; + op->data.recv_message.recv_message = &response_payload_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++; + + grpc_endpoint_pair* sfd = g_ctx.ep; + int fd; + if (fdtype == SERVER_FD) { + fd = sfd->server->vtable->get_fd(sfd->server); + } else { + GPR_ASSERT(fdtype == CLIENT_FD); + fd = sfd->client->vtable->get_fd(sfd->client); + } + /* Connection is closed before the client sends a batch to the server */ + close(fd); + + error = grpc_call_start_batch(call, ops, static_cast(op - ops), + tag(1), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + /* Status unavailable is returned to the client when client or server fd is + * closed */ + event = grpc_completion_queue_next( + g_ctx.client_cq, grpc_timeout_milliseconds_to_deadline(100), nullptr); + GPR_ASSERT(event.success == 1); + GPR_ASSERT(event.type == GRPC_OP_COMPLETE); + GPR_ASSERT(event.tag == tag(1)); + GPR_ASSERT(status == GRPC_STATUS_UNAVAILABLE); + + /* No event is received on the server */ + event = grpc_completion_queue_next( + g_ctx.cq, grpc_timeout_milliseconds_to_deadline(100), nullptr); + GPR_ASSERT(event.success == 0); + GPR_ASSERT(event.type == GRPC_QUEUE_TIMEOUT); + + 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(call); + + 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); + + end_test(); +} +static void test_close_before_client_send() { + /* Close client side of the connection before client sends message to server + * */ + _test_close_before_client_send(CLIENT_FD); + /* Close server side of the connection before client sends message to server + * */ + _test_close_before_client_send(SERVER_FD); +} + +static void _test_close_before_call_create(fd_type fdtype) { + grpc_core::ExecCtx exec_ctx; + grpc_call* call; + grpc_event event; + test_init(); + + gpr_timespec deadline = grpc_timeout_milliseconds_to_deadline(100); + + grpc_endpoint_pair* sfd = g_ctx.ep; + int fd; + if (fdtype == SERVER_FD) { + fd = sfd->server->vtable->get_fd(sfd->server); + } else { + GPR_ASSERT(fdtype == CLIENT_FD); + fd = sfd->client->vtable->get_fd(sfd->client); + } + /* Connection is closed before the client creates a call */ + close(fd); + + call = grpc_channel_create_call( + g_ctx.client, nullptr, GRPC_PROPAGATE_DEFAULTS, g_ctx.client_cq, + grpc_slice_from_static_string("/foo"), nullptr, deadline, nullptr); + GPR_ASSERT(call); + + /* Client and server time out waiting on their completion queues and nothing + * is sent or received */ + event = grpc_completion_queue_next( + g_ctx.client_cq, grpc_timeout_milliseconds_to_deadline(100), nullptr); + GPR_ASSERT(event.type == GRPC_QUEUE_TIMEOUT); + GPR_ASSERT(event.success == 0); + + event = grpc_completion_queue_next( + g_ctx.cq, grpc_timeout_milliseconds_to_deadline(100), nullptr); + GPR_ASSERT(event.type == GRPC_QUEUE_TIMEOUT); + GPR_ASSERT(event.success == 0); + + grpc_call_unref(call); + end_test(); +} + +static void test_close_before_call_create() { + /* Close client side of the connection before client creates a call */ + _test_close_before_call_create(CLIENT_FD); + /* Close server side of the connection before client creates a call */ + _test_close_before_call_create(SERVER_FD); +} + +int main(int argc, char** argv) { + grpc::testing::TestEnvironment env(argc, argv); + /* Init grpc */ + grpc_init(); + int iterations = 10; + + for (int i = 0; i < iterations; ++i) { + test_close_before_call_create(); + test_close_before_client_send(); + test_close_before_server_recv(); + test_close_before_server_send(); + } + + grpc_shutdown(); + + return 0; +} + +#else /* GRPC_POSIX_SOCKET */ + +int main(int argc, char** argv) { return 1; } + +#endif /* GRPC_POSIX_SOCKET */ diff --git a/test/core/bad_ssl/gen_build_yaml.py b/test/core/bad_ssl/gen_build_yaml.py index 6b78e9c7aa4..52f49bea2ad 100755 --- a/test/core/bad_ssl/gen_build_yaml.py +++ b/test/core/bad_ssl/gen_build_yaml.py @@ -45,7 +45,6 @@ def main(): 'deps': [ 'grpc_test_util', 'grpc', - 'gpr_test_util', 'gpr' ] } @@ -63,7 +62,6 @@ def main(): 'bad_ssl_test_server', 'grpc_test_util', 'grpc', - 'gpr_test_util', 'gpr' ] } @@ -79,7 +77,6 @@ def main(): 'deps': [ 'grpc_test_util', 'grpc', - 'gpr_test_util', 'gpr' ] } diff --git a/test/core/channel/BUILD b/test/core/channel/BUILD index da419f00cf9..3249a16edda 100644 --- a/test/core/channel/BUILD +++ b/test/core/channel/BUILD @@ -25,7 +25,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -37,7 +36,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -49,7 +47,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -61,7 +58,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -69,62 +65,59 @@ grpc_cc_test( grpc_cc_test( name = "channel_trace_test", srcs = ["channel_trace_test.cc"], + external_deps = [ + "gtest", + ], language = "C++", deps = [ "//:gpr", "//:grpc", "//:grpc++", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:channel_trace_proto_helper", ], - external_deps = [ - "gtest", - ], ) grpc_cc_test( name = "channelz_test", srcs = ["channelz_test.cc"], + external_deps = [ + "gtest", + ], language = "C++", deps = [ "//:gpr", "//:grpc", "//:grpc++", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:channel_trace_proto_helper", ], - external_deps = [ - "gtest", - ], ) grpc_cc_test( name = "channelz_registry_test", srcs = ["channelz_registry_test.cc"], + external_deps = [ + "gtest", + ], language = "C++", deps = [ "//:gpr", "//:grpc", "//:grpc++", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], - external_deps = [ - "gtest", - ], ) grpc_cc_test( name = "status_util_test", srcs = ["status_util_test.cc"], - language = "C++", - deps = [ - "//:grpc", - "//test/core/util:gpr_test_util", - ], external_deps = [ "gtest", ], + language = "C++", + deps = [ + "//:grpc", + "//test/core/util:grpc_test_util", + ], ) diff --git a/test/core/channel/channel_args_test.cc b/test/core/channel/channel_args_test.cc index 41c62a8f16e..9c47d5dd922 100644 --- a/test/core/channel/channel_args_test.cc +++ b/test/core/channel/channel_args_test.cc @@ -58,96 +58,6 @@ static void test_create(void) { grpc_channel_args_destroy(ch_args); } -static void test_set_compression_algorithm(void) { - grpc_core::ExecCtx exec_ctx; - grpc_channel_args* ch_args; - - ch_args = - grpc_channel_args_set_compression_algorithm(nullptr, GRPC_COMPRESS_GZIP); - GPR_ASSERT(ch_args->num_args == 1); - GPR_ASSERT(strcmp(ch_args->args[0].key, - GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM) == 0); - GPR_ASSERT(ch_args->args[0].type == GRPC_ARG_INTEGER); - - grpc_channel_args_destroy(ch_args); -} - -static void test_compression_algorithm_states(void) { - grpc_core::ExecCtx exec_ctx; - grpc_channel_args *ch_args, *ch_args_wo_gzip, *ch_args_wo_gzip_deflate, - *ch_args_wo_gzip_deflate_gzip; - unsigned states_bitset; - size_t i; - - ch_args = grpc_channel_args_copy_and_add(nullptr, nullptr, 0); - /* by default, all enabled */ - states_bitset = static_cast( - grpc_channel_args_compression_algorithm_get_states(ch_args)); - - for (i = 0; i < GRPC_COMPRESS_ALGORITHMS_COUNT; i++) { - GPR_ASSERT(GPR_BITGET(states_bitset, i)); - } - - /* disable gzip and deflate and stream/gzip */ - ch_args_wo_gzip = grpc_channel_args_compression_algorithm_set_state( - &ch_args, GRPC_COMPRESS_GZIP, 0); - GPR_ASSERT(ch_args == ch_args_wo_gzip); - ch_args_wo_gzip_deflate = grpc_channel_args_compression_algorithm_set_state( - &ch_args_wo_gzip, GRPC_COMPRESS_DEFLATE, 0); - GPR_ASSERT(ch_args_wo_gzip == ch_args_wo_gzip_deflate); - ch_args_wo_gzip_deflate_gzip = - grpc_channel_args_compression_algorithm_set_state( - &ch_args_wo_gzip_deflate, GRPC_COMPRESS_STREAM_GZIP, 0); - GPR_ASSERT(ch_args_wo_gzip_deflate == ch_args_wo_gzip_deflate_gzip); - - states_bitset = - static_cast(grpc_channel_args_compression_algorithm_get_states( - ch_args_wo_gzip_deflate)); - for (i = 0; i < GRPC_COMPRESS_ALGORITHMS_COUNT; i++) { - if (i == GRPC_COMPRESS_GZIP || i == GRPC_COMPRESS_DEFLATE || - i == GRPC_COMPRESS_STREAM_GZIP) { - GPR_ASSERT(GPR_BITGET(states_bitset, i) == 0); - } else { - GPR_ASSERT(GPR_BITGET(states_bitset, i) != 0); - } - } - - /* re-enabled gzip and stream/gzip only */ - ch_args_wo_gzip = grpc_channel_args_compression_algorithm_set_state( - &ch_args_wo_gzip_deflate_gzip, GRPC_COMPRESS_GZIP, 1); - ch_args_wo_gzip = grpc_channel_args_compression_algorithm_set_state( - &ch_args_wo_gzip, GRPC_COMPRESS_STREAM_GZIP, 1); - GPR_ASSERT(ch_args_wo_gzip == ch_args_wo_gzip_deflate_gzip); - - states_bitset = static_cast( - grpc_channel_args_compression_algorithm_get_states(ch_args_wo_gzip)); - for (i = 0; i < GRPC_COMPRESS_ALGORITHMS_COUNT; i++) { - if (i == GRPC_COMPRESS_DEFLATE) { - GPR_ASSERT(GPR_BITGET(states_bitset, i) == 0); - } else { - GPR_ASSERT(GPR_BITGET(states_bitset, i) != 0); - } - } - - grpc_channel_args_destroy(ch_args); -} - -static void test_set_socket_mutator(void) { - grpc_channel_args* ch_args; - grpc_socket_mutator mutator; - grpc_socket_mutator_init(&mutator, nullptr); - - ch_args = grpc_channel_args_set_socket_mutator(nullptr, &mutator); - GPR_ASSERT(ch_args->num_args == 1); - GPR_ASSERT(strcmp(ch_args->args[0].key, GRPC_ARG_SOCKET_MUTATOR) == 0); - GPR_ASSERT(ch_args->args[0].type == GRPC_ARG_POINTER); - - { - grpc_core::ExecCtx exec_ctx; - grpc_channel_args_destroy(ch_args); - } -} - struct fake_class { int foo; }; @@ -231,12 +141,9 @@ static void test_server_create_with_args(void) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); test_create(); - test_set_compression_algorithm(); - test_compression_algorithm_states(); - test_set_socket_mutator(); test_channel_create_with_args(); test_server_create_with_args(); grpc_shutdown(); diff --git a/test/core/channel/channel_stack_builder_test.cc b/test/core/channel/channel_stack_builder_test.cc index aad6d6eee9a..efe616ab7fd 100644 --- a/test/core/channel/channel_stack_builder_test.cc +++ b/test/core/channel/channel_stack_builder_test.cc @@ -45,16 +45,6 @@ static void call_destroy_func(grpc_call_element* elem, const grpc_call_final_info* final_info, grpc_closure* ignored) {} -static void call_func(grpc_call_element* elem, - grpc_transport_stream_op_batch* op) {} - -static void channel_func(grpc_channel_element* elem, grpc_transport_op* op) { - if (op->disconnect_with_error != GRPC_ERROR_NONE) { - GRPC_ERROR_UNREF(op->disconnect_with_error); - } - GRPC_CLOSURE_SCHED(op->on_consumed, GRPC_ERROR_NONE); -} - bool g_replacement_fn_called = false; bool g_original_fn_called = false; void set_arg_once_fn(grpc_channel_stack* channel_stack, @@ -77,8 +67,8 @@ static void test_channel_stack_builder_filter_replace(void) { } const grpc_channel_filter replacement_filter = { - call_func, - channel_func, + grpc_call_next_op, + grpc_channel_next_op, 0, call_init_func, grpc_call_stack_ignore_set_pollset_or_pollset_set, @@ -90,8 +80,8 @@ const grpc_channel_filter replacement_filter = { "filter_name"}; const grpc_channel_filter original_filter = { - call_func, - channel_func, + grpc_call_next_op, + grpc_channel_next_op, 0, call_init_func, grpc_call_stack_ignore_set_pollset_or_pollset_set, @@ -132,7 +122,7 @@ static void init_plugin(void) { static void destroy_plugin(void) {} int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_register_plugin(init_plugin, destroy_plugin); grpc_init(); test_channel_stack_builder_filter_replace(); diff --git a/test/core/channel/channel_stack_test.cc b/test/core/channel/channel_stack_test.cc index 6f0bfa06d21..14726336f92 100644 --- a/test/core/channel/channel_stack_test.cc +++ b/test/core/channel/channel_stack_test.cc @@ -147,7 +147,7 @@ static void test_create_channel_stack(void) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); test_create_channel_stack(); grpc_shutdown(); diff --git a/test/core/channel/channel_trace_test.cc b/test/core/channel/channel_trace_test.cc index 3d8de79e376..b3c0b368982 100644 --- a/test/core/channel/channel_trace_test.cc +++ b/test/core/channel/channel_trace_test.cc @@ -342,7 +342,7 @@ TEST(ChannelTracerTest, TestTotalEviction) { } // namespace grpc_core int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); ::testing::InitGoogleTest(&argc, argv); int ret = RUN_ALL_TESTS(); diff --git a/test/core/channel/channelz_registry_test.cc b/test/core/channel/channelz_registry_test.cc index fdfc8eec94a..31841f9f967 100644 --- a/test/core/channel/channelz_registry_test.cc +++ b/test/core/channel/channelz_registry_test.cc @@ -112,7 +112,7 @@ TEST_F(ChannelzRegistryTest, NullIfNotPresentTest) { } TEST_F(ChannelzRegistryTest, TestCompaction) { - const int kLoopIterations = 100; + const int kLoopIterations = 300; // These channels that will stay in the registry for the duration of the test. std::vector> even_channels; even_channels.reserve(kLoopIterations); @@ -195,7 +195,7 @@ TEST_F(ChannelzRegistryTest, TestAddAfterCompaction) { } // namespace grpc_core int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); int ret = RUN_ALL_TESTS(); return ret; diff --git a/test/core/channel/channelz_test.cc b/test/core/channel/channelz_test.cc index 4d4b0770022..abd1601ad14 100644 --- a/test/core/channel/channelz_test.cc +++ b/test/core/channel/channelz_test.cc @@ -541,7 +541,7 @@ INSTANTIATE_TEST_CASE_P(ChannelzChannelTestSweep, ChannelzChannelTest, } // namespace grpc_core int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); ::testing::InitGoogleTest(&argc, argv); int ret = RUN_ALL_TESTS(); diff --git a/test/core/channel/minimal_stack_is_minimal_test.cc b/test/core/channel/minimal_stack_is_minimal_test.cc index e5953acedcf..bee0bfb41f2 100644 --- a/test/core/channel/minimal_stack_is_minimal_test.cc +++ b/test/core/channel/minimal_stack_is_minimal_test.cc @@ -56,7 +56,7 @@ static int check_stack(const char* file, int line, const char* transport_name, #define CHECK_STACK(...) check_stack(__FILE__, __LINE__, __VA_ARGS__) int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); int errors = 0; diff --git a/test/core/client_channel/BUILD b/test/core/client_channel/BUILD index db98ffab77b..a9cfa961ec2 100644 --- a/test/core/client_channel/BUILD +++ b/test/core/client_channel/BUILD @@ -43,6 +43,18 @@ grpc_cc_test( ], ) +grpc_cc_test( + name = "parse_address_with_named_scope_id_test", + srcs = ["parse_address_with_named_scope_id_test.cc"], + language = "C++", + deps = [ + "//:gpr", + "//:grpc", + "//test/core/util:grpc_test_util", + ], + tags = ["no_windows"], +) + grpc_cc_test( name = "uri_parser_test", srcs = ["uri_parser_test.cc"], @@ -64,7 +76,20 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + ], +) + +grpc_cc_test( + name = "service_config_test", + srcs = ["service_config_test.cc"], + external_deps = [ + "gtest", + ], + language = "C++", + deps = [ + "//:gpr", + "//:grpc", "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/client_channel/parse_address_test.cc b/test/core/client_channel/parse_address_test.cc index 004549fa621..b77a51a9e49 100644 --- a/test/core/client_channel/parse_address_test.cc +++ b/test/core/client_channel/parse_address_test.cc @@ -101,7 +101,7 @@ static void test_grpc_parse_ipv6_invalid(const char* uri_text) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); test_grpc_parse_unix("unix:/path/name", "/path/name"); diff --git a/test/core/client_channel/parse_address_with_named_scope_id_test.cc b/test/core/client_channel/parse_address_with_named_scope_id_test.cc new file mode 100644 index 00000000000..bfafa745178 --- /dev/null +++ b/test/core/client_channel/parse_address_with_named_scope_id_test.cc @@ -0,0 +1,126 @@ +/* + * + * 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 "src/core/ext/filters/client_channel/parse_address.h" +#include "src/core/lib/iomgr/sockaddr.h" +#include "src/core/lib/iomgr/socket_utils.h" + +#include +#include +#ifdef GRPC_HAVE_UNIX_SOCKET +#include +#endif + +#include +#include +#include + +#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/iomgr/exec_ctx.h" +#include "src/core/lib/iomgr/socket_utils.h" +#include "test/core/util/test_config.h" + +static void test_grpc_parse_ipv6_parity_with_getaddrinfo( + const char* target, const struct sockaddr_in6 result_from_getaddrinfo) { + // Get the sockaddr that gRPC's ipv6 resolver resolves this too. + grpc_core::ExecCtx exec_ctx; + grpc_uri* uri = grpc_uri_parse(target, 0); + grpc_resolved_address addr; + GPR_ASSERT(1 == grpc_parse_ipv6(uri, &addr)); + grpc_sockaddr_in6* result_from_grpc_parser = + reinterpret_cast(addr.addr); + // Compare the sockaddr returned from gRPC's ipv6 resolver with that returned + // from getaddrinfo. + GPR_ASSERT(result_from_grpc_parser->sin6_family == AF_INET6); + GPR_ASSERT(result_from_getaddrinfo.sin6_family == AF_INET6); + GPR_ASSERT(memcmp(&result_from_grpc_parser->sin6_addr, + &result_from_getaddrinfo.sin6_addr, sizeof(in6_addr)) == 0); + GPR_ASSERT(result_from_grpc_parser->sin6_scope_id == + result_from_getaddrinfo.sin6_scope_id); + GPR_ASSERT(result_from_grpc_parser->sin6_scope_id != 0); + // TODO: compare sin6_flow_info fields? parse_ipv6 zero's this field as is. + // Cleanup + grpc_uri_destroy(uri); +} + +struct sockaddr_in6 resolve_with_gettaddrinfo(const char* uri_text) { + grpc_uri* uri = grpc_uri_parse(uri_text, 0); + char* host = nullptr; + char* port = nullptr; + gpr_split_host_port(uri->path, &host, &port); + struct addrinfo hints; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET6; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_NUMERICHOST; + struct addrinfo* result; + int res = getaddrinfo(host, port, &hints, &result); + if (res != 0) { + gpr_log(GPR_ERROR, + "getaddrinfo failed to resolve host:%s port:%s. Error: %d.", host, + port, res); + abort(); + } + size_t num_addrs_from_getaddrinfo = 0; + for (struct addrinfo* resp = result; resp != nullptr; resp = resp->ai_next) { + num_addrs_from_getaddrinfo++; + } + GPR_ASSERT(num_addrs_from_getaddrinfo == 1); + GPR_ASSERT(result->ai_family == AF_INET6); + struct sockaddr_in6 out = + *reinterpret_cast(result->ai_addr); + // Cleanup + freeaddrinfo(result); + gpr_free(host); + gpr_free(port); + grpc_uri_destroy(uri); + return out; +} + +int main(int argc, char** argv) { + grpc_test_init(argc, argv); + grpc_init(); + char* arbitrary_interface_name = static_cast(gpr_zalloc(IF_NAMESIZE)); + // Per RFC 3493, an interface index is a "small positive integer starts at 1". + // Probe candidate interface index numbers until we find one that the + // system recognizes, and then use that for the test. + for (size_t i = 1; i < 65536; i++) { + if (if_indextoname(i, arbitrary_interface_name) != nullptr) { + gpr_log( + GPR_DEBUG, + "Found interface at index %d named %s. Will use this for the test", + (int)i, arbitrary_interface_name); + break; + } + } + GPR_ASSERT(strlen(arbitrary_interface_name) > 0); + char* target = nullptr; + gpr_asprintf(&target, "ipv6:[fe80::1234%%%s]:12345", + arbitrary_interface_name); + struct sockaddr_in6 result_from_getaddrinfo = + resolve_with_gettaddrinfo(target); + // Run the test + gpr_log(GPR_DEBUG, + "Run test_grpc_parse_ipv6_parity_with_getaddrinfo with target: %s", + target); + test_grpc_parse_ipv6_parity_with_getaddrinfo(target, result_from_getaddrinfo); + // Cleanup + gpr_free(target); + gpr_free(arbitrary_interface_name); + grpc_shutdown(); +} diff --git a/test/core/client_channel/resolvers/BUILD b/test/core/client_channel/resolvers/BUILD index d8b03958461..3dbee5c9e6d 100644 --- a/test/core/client_channel/resolvers/BUILD +++ b/test/core/client_channel/resolvers/BUILD @@ -25,7 +25,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -37,7 +36,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -49,7 +47,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -61,7 +58,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -74,7 +70,6 @@ grpc_cc_test( "//:gpr", "//:grpc", "//:grpc_resolver_fake", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc b/test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc index eb5a9117484..f8a7729671e 100644 --- a/test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc +++ b/test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc @@ -21,10 +21,10 @@ #include #include -#include "src/core/ext/filters/client_channel/lb_policy_factory.h" #include "src/core/ext/filters/client_channel/resolver.h" #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" #include "src/core/ext/filters/client_channel/resolver_registry.h" +#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/resolve_address.h" @@ -63,7 +63,8 @@ static grpc_address_resolver_vtable test_resolver = {my_resolve_address, static grpc_ares_request* my_dns_lookup_ares_locked( const char* dns_server, const char* addr, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - grpc_lb_addresses** lb_addrs, bool check_grpclb, char** service_config_json, + grpc_core::UniquePtr* addresses, + bool check_grpclb, char** service_config_json, int query_timeout_ms, grpc_combiner* combiner) { gpr_mu_lock(&g_mu); GPR_ASSERT(0 == strcmp("test", addr)); @@ -74,9 +75,11 @@ static grpc_ares_request* my_dns_lookup_ares_locked( error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Forced Failure"); } else { gpr_mu_unlock(&g_mu); - *lb_addrs = grpc_lb_addresses_create(1, nullptr); - grpc_lb_addresses_set_address(*lb_addrs, 0, nullptr, 0, false, nullptr, - nullptr); + *addresses = grpc_core::MakeUnique(); + grpc_resolved_address dummy_resolved_address; + memset(&dummy_resolved_address, 0, sizeof(dummy_resolved_address)); + dummy_resolved_address.len = 123; + (*addresses)->emplace_back(dummy_resolved_address, nullptr); } GRPC_CLOSURE_SCHED(on_done, error); return nullptr; @@ -87,7 +90,8 @@ static void my_cancel_ares_request_locked(grpc_ares_request* request) { } static grpc_core::OrphanablePtr create_resolver( - const char* name) { + const char* name, + grpc_core::UniquePtr result_handler) { grpc_core::ResolverFactory* factory = grpc_core::ResolverRegistry::LookupResolverFactory("dns"); grpc_uri* uri = grpc_uri_parse(name, 0); @@ -95,15 +99,48 @@ static grpc_core::OrphanablePtr create_resolver( grpc_core::ResolverArgs args; args.uri = uri; args.combiner = g_combiner; + args.result_handler = std::move(result_handler); grpc_core::OrphanablePtr resolver = - factory->CreateResolver(args); + factory->CreateResolver(std::move(args)); grpc_uri_destroy(uri); return resolver; } -static void on_done(void* ev, grpc_error* error) { - gpr_event_set(static_cast(ev), (void*)1); -} +class ResultHandler : public grpc_core::Resolver::ResultHandler { + public: + struct ResolverOutput { + grpc_core::Resolver::Result result; + grpc_error* error = nullptr; + gpr_event ev; + + ResolverOutput() { gpr_event_init(&ev); } + ~ResolverOutput() { GRPC_ERROR_UNREF(error); } + }; + + void SetOutput(ResolverOutput* output) { + gpr_atm_rel_store(&output_, reinterpret_cast(output)); + } + + void ReturnResult(grpc_core::Resolver::Result result) override { + ResolverOutput* output = + reinterpret_cast(gpr_atm_acq_load(&output_)); + GPR_ASSERT(output != nullptr); + output->result = std::move(result); + output->error = GRPC_ERROR_NONE; + gpr_event_set(&output->ev, (void*)1); + } + + void ReturnError(grpc_error* error) override { + ResolverOutput* output = + reinterpret_cast(gpr_atm_acq_load(&output_)); + GPR_ASSERT(output != nullptr); + output->error = error; + gpr_event_set(&output->ev, (void*)1); + } + + private: + gpr_atm output_ = 0; // ResolverOutput* +}; // interleave waiting for an event with a timer check static bool wait_loop(int deadline_seconds, gpr_event* ev) { @@ -118,34 +155,8 @@ static bool wait_loop(int deadline_seconds, gpr_event* ev) { return false; } -typedef struct next_args { - grpc_core::Resolver* resolver; - grpc_channel_args** result; - grpc_closure* on_complete; -} next_args; - -static void call_resolver_next_now_lock_taken(void* arg, - grpc_error* error_unused) { - next_args* a = static_cast(arg); - a->resolver->NextLocked(a->result, a->on_complete); - gpr_free(a); -} - -static void call_resolver_next_after_locking(grpc_core::Resolver* resolver, - grpc_channel_args** result, - grpc_closure* on_complete, - grpc_combiner* combiner) { - next_args* a = static_cast(gpr_malloc(sizeof(*a))); - a->resolver = resolver; - a->result = result; - a->on_complete = on_complete; - GRPC_CLOSURE_SCHED(GRPC_CLOSURE_CREATE(call_resolver_next_now_lock_taken, a, - grpc_combiner_scheduler(combiner)), - GRPC_ERROR_NONE); -} - int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); gpr_mu_init(&g_mu); @@ -153,33 +164,28 @@ int main(int argc, char** argv) { grpc_set_resolver_impl(&test_resolver); grpc_dns_lookup_ares_locked = my_dns_lookup_ares_locked; grpc_cancel_ares_request_locked = my_cancel_ares_request_locked; - grpc_channel_args* result = (grpc_channel_args*)1; { grpc_core::ExecCtx exec_ctx; - grpc_core::OrphanablePtr resolver = - create_resolver("dns:test"); - gpr_event ev1; - gpr_event_init(&ev1); - call_resolver_next_after_locking( - resolver.get(), &result, - GRPC_CLOSURE_CREATE(on_done, &ev1, grpc_schedule_on_exec_ctx), - g_combiner); + ResultHandler* result_handler = grpc_core::New(); + grpc_core::OrphanablePtr resolver = create_resolver( + "dns:test", grpc_core::UniquePtr( + result_handler)); + ResultHandler::ResolverOutput output1; + result_handler->SetOutput(&output1); + resolver->StartLocked(); grpc_core::ExecCtx::Get()->Flush(); - GPR_ASSERT(wait_loop(5, &ev1)); - GPR_ASSERT(result == nullptr); + GPR_ASSERT(wait_loop(5, &output1.ev)); + GPR_ASSERT(output1.result.addresses.empty()); + GPR_ASSERT(output1.error != GRPC_ERROR_NONE); - gpr_event ev2; - gpr_event_init(&ev2); - call_resolver_next_after_locking( - resolver.get(), &result, - GRPC_CLOSURE_CREATE(on_done, &ev2, grpc_schedule_on_exec_ctx), - g_combiner); + ResultHandler::ResolverOutput output2; + result_handler->SetOutput(&output2); grpc_core::ExecCtx::Get()->Flush(); - GPR_ASSERT(wait_loop(30, &ev2)); - GPR_ASSERT(result != nullptr); + GPR_ASSERT(wait_loop(30, &output2.ev)); + GPR_ASSERT(!output2.result.addresses.empty()); + GPR_ASSERT(output2.error == GRPC_ERROR_NONE); - grpc_channel_args_destroy(result); GRPC_COMBINER_UNREF(g_combiner, "test"); } 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 1a7db40f598..7b3a4589f5b 100644 --- a/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc +++ b/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc @@ -18,10 +18,12 @@ #include +#include #include #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" #include "src/core/ext/filters/client_channel/resolver_registry.h" +#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gprpp/memory.h" #include "src/core/lib/iomgr/combiner.h" @@ -40,7 +42,8 @@ static grpc_combiner* g_combiner; static grpc_ares_request* (*g_default_dns_lookup_ares_locked)( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json, + grpc_core::UniquePtr* addresses, + bool check_grpclb, char** service_config_json, int query_timeout_ms, grpc_combiner* combiner); // Counter incremented by test_resolve_address_impl indicating the number of @@ -90,11 +93,12 @@ static grpc_address_resolver_vtable test_resolver = { static grpc_ares_request* test_dns_lookup_ares_locked( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json, + grpc_core::UniquePtr* addresses, + bool check_grpclb, char** service_config_json, int query_timeout_ms, grpc_combiner* combiner) { grpc_ares_request* result = g_default_dns_lookup_ares_locked( - dns_server, name, default_port, g_iomgr_args.pollset_set, on_done, addrs, - check_grpclb, service_config_json, combiner); + dns_server, name, default_port, g_iomgr_args.pollset_set, on_done, + addresses, check_grpclb, service_config_json, query_timeout_ms, combiner); ++g_resolution_count; static grpc_millis last_resolution_time = 0; if (last_resolution_time == 0) { @@ -166,19 +170,49 @@ static void poll_pollset_until_request_done(iomgr_args* args) { gpr_event_set(&args->ev, (void*)1); } +struct OnResolutionCallbackArg; + +class ResultHandler : public grpc_core::Resolver::ResultHandler { + public: + using ResultCallback = void (*)(OnResolutionCallbackArg* state); + + void SetCallback(ResultCallback result_cb, OnResolutionCallbackArg* state) { + GPR_ASSERT(result_cb_ == nullptr); + result_cb_ = result_cb; + GPR_ASSERT(state_ == nullptr); + state_ = state; + } + + void ReturnResult(grpc_core::Resolver::Result result) override { + GPR_ASSERT(result_cb_ != nullptr); + GPR_ASSERT(state_ != nullptr); + ResultCallback cb = result_cb_; + OnResolutionCallbackArg* state = state_; + result_cb_ = nullptr; + state_ = nullptr; + cb(state); + } + + void ReturnError(grpc_error* error) override { + gpr_log(GPR_ERROR, "resolver returned error: %s", grpc_error_string(error)); + GPR_ASSERT(false); + } + + private: + ResultCallback result_cb_ = nullptr; + OnResolutionCallbackArg* state_ = nullptr; +}; + struct OnResolutionCallbackArg { const char* uri_str = nullptr; grpc_core::OrphanablePtr resolver; - grpc_channel_args* result = nullptr; + ResultHandler* result_handler; }; // Set to true by the last callback in the resolution chain. static bool g_all_callbacks_invoked; -static void on_second_resolution(void* arg, grpc_error* error) { - OnResolutionCallbackArg* cb_arg = static_cast(arg); - grpc_channel_args_destroy(cb_arg->result); - GPR_ASSERT(error == GRPC_ERROR_NONE); +static void on_second_resolution(OnResolutionCallbackArg* cb_arg) { gpr_log(GPR_INFO, "2nd: g_resolution_count: %d", g_resolution_count); // The resolution callback was not invoked until new data was // available, which was delayed until after the cooldown period. @@ -193,18 +227,12 @@ static void on_second_resolution(void* arg, grpc_error* error) { g_all_callbacks_invoked = true; } -static void on_first_resolution(void* arg, grpc_error* error) { - OnResolutionCallbackArg* cb_arg = static_cast(arg); - grpc_channel_args_destroy(cb_arg->result); - GPR_ASSERT(error == GRPC_ERROR_NONE); +static void on_first_resolution(OnResolutionCallbackArg* cb_arg) { gpr_log(GPR_INFO, "1st: g_resolution_count: %d", g_resolution_count); // There's one initial system-level resolution and one invocation of a // notification callback (the current function). 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->result_handler->SetCallback(on_second_resolution, cb_arg); cb_arg->resolver->RequestReresolutionLocked(); gpr_mu_lock(g_iomgr_args.mu); GRPC_LOG_IF_ERROR("pollset_kick", @@ -216,6 +244,8 @@ static void start_test_under_combiner(void* arg, grpc_error* error) { OnResolutionCallbackArg* res_cb_arg = static_cast(arg); + res_cb_arg->result_handler = grpc_core::New(); + grpc_core::ResolverFactory* factory = grpc_core::ResolverRegistry::LookupResolverFactory("dns"); grpc_uri* uri = grpc_uri_parse(res_cb_arg->uri_str, 0); @@ -225,25 +255,22 @@ static void start_test_under_combiner(void* arg, grpc_error* error) { grpc_core::ResolverArgs args; args.uri = uri; args.combiner = g_combiner; + args.result_handler = + grpc_core::UniquePtr( + res_cb_arg->result_handler); g_resolution_count = 0; - grpc_arg cooldown_arg; - cooldown_arg.key = - const_cast(GRPC_ARG_DNS_MIN_TIME_BETWEEN_RESOLUTIONS_MS); - cooldown_arg.type = GRPC_ARG_INTEGER; - cooldown_arg.value.integer = kMinResolutionPeriodMs; - auto* cooldown_channel_args = - grpc_channel_args_copy_and_add(nullptr, &cooldown_arg, 1); - args.args = cooldown_channel_args; - res_cb_arg->resolver = factory->CreateResolver(args); - grpc_channel_args_destroy(cooldown_channel_args); + grpc_arg cooldown_arg = grpc_channel_arg_integer_create( + const_cast(GRPC_ARG_DNS_MIN_TIME_BETWEEN_RESOLUTIONS_MS), + kMinResolutionPeriodMs); + grpc_channel_args cooldown_args = {1, &cooldown_arg}; + args.args = &cooldown_args; + res_cb_arg->resolver = factory->CreateResolver(std::move(args)); GPR_ASSERT(res_cb_arg->resolver != nullptr); - // First resolution, would incur in system-level resolution. - res_cb_arg->resolver->NextLocked( - &res_cb_arg->result, - GRPC_CLOSURE_CREATE(on_first_resolution, res_cb_arg, - grpc_combiner_scheduler(g_combiner))); grpc_uri_destroy(uri); + // First resolution, would incur in system-level resolution. + res_cb_arg->result_handler->SetCallback(on_first_resolution, res_cb_arg); + res_cb_arg->resolver->StartLocked(); } static void test_cooldown() { @@ -262,7 +289,7 @@ static void test_cooldown() { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); g_combiner = grpc_combiner_create(); @@ -278,7 +305,7 @@ int main(int argc, char** argv) { grpc_core::ExecCtx exec_ctx; GRPC_COMBINER_UNREF(g_combiner, "test"); } - grpc_shutdown(); + grpc_shutdown_blocking(); GPR_ASSERT(g_all_callbacks_invoked); return 0; } diff --git a/test/core/client_channel/resolvers/dns_resolver_test.cc b/test/core/client_channel/resolvers/dns_resolver_test.cc index 103b2916c46..ed3b4e66472 100644 --- a/test/core/client_channel/resolvers/dns_resolver_test.cc +++ b/test/core/client_channel/resolvers/dns_resolver_test.cc @@ -22,6 +22,8 @@ #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" #include "src/core/ext/filters/client_channel/resolver_registry.h" +#include "src/core/lib/gpr/env.h" +#include "src/core/lib/gpr/string.h" #include "src/core/lib/iomgr/combiner.h" #include "test/core/util/test_config.h" @@ -37,8 +39,10 @@ static void test_succeeds(grpc_core::ResolverFactory* factory, grpc_core::ResolverArgs args; args.uri = uri; args.combiner = g_combiner; + args.result_handler = + grpc_core::MakeUnique(); grpc_core::OrphanablePtr resolver = - factory->CreateResolver(args); + factory->CreateResolver(std::move(args)); GPR_ASSERT(resolver != nullptr); grpc_uri_destroy(uri); } @@ -53,14 +57,16 @@ static void test_fails(grpc_core::ResolverFactory* factory, grpc_core::ResolverArgs args; args.uri = uri; args.combiner = g_combiner; + args.result_handler = + grpc_core::MakeUnique(); grpc_core::OrphanablePtr resolver = - factory->CreateResolver(args); + factory->CreateResolver(std::move(args)); GPR_ASSERT(resolver == nullptr); grpc_uri_destroy(uri); } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); g_combiner = grpc_combiner_create(); @@ -72,12 +78,13 @@ int main(int argc, char** argv) { test_succeeds(dns, "dns:10.2.1.1:1234"); 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, "dns://8.8.8.8/8.8.8.8:8888"); - } else { + char* resolver_env = gpr_getenv("GRPC_DNS_RESOLVER"); + if (resolver_env != nullptr && gpr_stricmp(resolver_env, "native") == 0) { test_fails(dns, "dns://8.8.8.8/8.8.8.8:8888"); + } else { + test_succeeds(dns, "dns://8.8.8.8/8.8.8.8:8888"); } - + gpr_free(resolver_env); { grpc_core::ExecCtx exec_ctx; GRPC_COMBINER_UNREF(g_combiner, "test"); diff --git a/test/core/client_channel/resolvers/fake_resolver_test.cc b/test/core/client_channel/resolvers/fake_resolver_test.cc index f6696bf1278..0d34a0b8f2c 100644 --- a/test/core/client_channel/resolvers/fake_resolver_test.cc +++ b/test/core/client_channel/resolvers/fake_resolver_test.cc @@ -22,10 +22,10 @@ #include #include -#include "src/core/ext/filters/client_channel/lb_policy_factory.h" #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h" #include "src/core/ext/filters/client_channel/resolver_registry.h" +#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/combiner.h" @@ -33,9 +33,39 @@ #include "test/core/util/test_config.h" +class ResultHandler : public grpc_core::Resolver::ResultHandler { + public: + void SetExpectedAndEvent(grpc_core::Resolver::Result expected, + gpr_event* ev) { + GPR_ASSERT(ev_ == nullptr); + expected_ = std::move(expected); + ev_ = ev; + } + + void ReturnResult(grpc_core::Resolver::Result actual) override { + GPR_ASSERT(ev_ != nullptr); + // We only check the addresses, because that's the only thing + // explicitly set by the test via + // FakeResolverResponseGenerator::SetResponse(). + GPR_ASSERT(actual.addresses.size() == expected_.addresses.size()); + for (size_t i = 0; i < expected_.addresses.size(); ++i) { + GPR_ASSERT(actual.addresses[i] == expected_.addresses[i]); + } + gpr_event_set(ev_, (void*)1); + ev_ = nullptr; + } + + void ReturnError(grpc_error* error) override {} + + private: + grpc_core::Resolver::Result expected_; + gpr_event* ev_ = nullptr; +}; + static grpc_core::OrphanablePtr build_fake_resolver( grpc_combiner* combiner, - grpc_core::FakeResolverResponseGenerator* response_generator) { + grpc_core::FakeResolverResponseGenerator* response_generator, + grpc_core::UniquePtr result_handler) { grpc_core::ResolverFactory* factory = grpc_core::ResolverRegistry::LookupResolverFactory("fake"); grpc_arg generator_arg = @@ -45,175 +75,142 @@ static grpc_core::OrphanablePtr build_fake_resolver( grpc_core::ResolverArgs args; args.args = &channel_args; args.combiner = combiner; + args.result_handler = std::move(result_handler); grpc_core::OrphanablePtr resolver = - factory->CreateResolver(args); + factory->CreateResolver(std::move(args)); return resolver; } -typedef struct on_resolution_arg { - grpc_channel_args* resolver_result; - grpc_channel_args* expected_resolver_result; - gpr_event ev; -} on_resolution_arg; - -// Callback to check the resolution result is as expected. -void on_resolution_cb(void* arg, grpc_error* error) { - if (error != GRPC_ERROR_NONE) return; - on_resolution_arg* res = static_cast(arg); - // We only check the addresses channel arg because that's the only one - // explicitly set by the test via - // FakeResolverResponseGenerator::SetResponse(). - const grpc_lb_addresses* actual_lb_addresses = - grpc_lb_addresses_find_channel_arg(res->resolver_result); - const grpc_lb_addresses* expected_lb_addresses = - grpc_lb_addresses_find_channel_arg(res->expected_resolver_result); - GPR_ASSERT( - grpc_lb_addresses_cmp(actual_lb_addresses, expected_lb_addresses) == 0); - grpc_channel_args_destroy(res->resolver_result); - grpc_channel_args_destroy(res->expected_resolver_result); - gpr_event_set(&res->ev, (void*)1); -} - // Create a new resolution containing 2 addresses. -static grpc_channel_args* create_new_resolver_result() { +static grpc_core::Resolver::Result create_new_resolver_result() { static size_t test_counter = 0; const size_t num_addresses = 2; char* uri_string; char* balancer_name; - // Create grpc_lb_addresses. - grpc_lb_addresses* addresses = - grpc_lb_addresses_create(num_addresses, nullptr); + // Create address list. + grpc_core::Resolver::Result result; for (size_t i = 0; i < num_addresses; ++i) { gpr_asprintf(&uri_string, "ipv4:127.0.0.1:100%" PRIuPTR, test_counter * num_addresses + i); grpc_uri* uri = grpc_uri_parse(uri_string, true); gpr_asprintf(&balancer_name, "balancer%" PRIuPTR, test_counter * num_addresses + i); - grpc_lb_addresses_set_address_from_uri( - addresses, i, uri, bool(num_addresses % 2), balancer_name, nullptr); + grpc_resolved_address address; + GPR_ASSERT(grpc_parse_uri(uri, &address)); + grpc_core::InlinedVector args_to_add; + const bool is_balancer = num_addresses % 2; + if (is_balancer) { + args_to_add.emplace_back(grpc_channel_arg_integer_create( + const_cast(GRPC_ARG_ADDRESS_IS_BALANCER), 1)); + args_to_add.emplace_back(grpc_channel_arg_string_create( + const_cast(GRPC_ARG_ADDRESS_BALANCER_NAME), balancer_name)); + } + grpc_channel_args* args = grpc_channel_args_copy_and_add( + nullptr, args_to_add.data(), args_to_add.size()); + result.addresses.emplace_back(address.addr, address.len, args); gpr_free(balancer_name); grpc_uri_destroy(uri); gpr_free(uri_string); } - // Convert grpc_lb_addresses to grpc_channel_args. - const grpc_arg addresses_arg = - grpc_lb_addresses_create_channel_arg(addresses); - grpc_channel_args* results = - grpc_channel_args_copy_and_add(nullptr, &addresses_arg, 1); - grpc_lb_addresses_destroy(addresses); ++test_counter; - return results; -} - -static on_resolution_arg create_on_resolution_arg(grpc_channel_args* results) { - on_resolution_arg on_res_arg; - memset(&on_res_arg, 0, sizeof(on_res_arg)); - on_res_arg.expected_resolver_result = results; - gpr_event_init(&on_res_arg.ev); - return on_res_arg; + return result; } static void test_fake_resolver() { grpc_core::ExecCtx exec_ctx; grpc_combiner* combiner = grpc_combiner_create(); // Create resolver. + ResultHandler* result_handler = grpc_core::New(); grpc_core::RefCountedPtr response_generator = grpc_core::MakeRefCounted(); - grpc_core::OrphanablePtr resolver = - build_fake_resolver(combiner, response_generator.get()); + grpc_core::OrphanablePtr resolver = build_fake_resolver( + combiner, response_generator.get(), + grpc_core::UniquePtr(result_handler)); GPR_ASSERT(resolver.get() != nullptr); + resolver->StartLocked(); // Test 1: normal resolution. // next_results != NULL, reresolution_results == NULL. // Expected response is next_results. - grpc_channel_args* results = create_new_resolver_result(); - on_resolution_arg on_res_arg = create_on_resolution_arg(results); - grpc_closure* on_resolution = GRPC_CLOSURE_CREATE( - on_resolution_cb, &on_res_arg, grpc_combiner_scheduler(combiner)); - // Resolution won't be triggered until next_results is set. - resolver->NextLocked(&on_res_arg.resolver_result, on_resolution); - response_generator->SetResponse(results); + gpr_log(GPR_INFO, "TEST 1"); + grpc_core::Resolver::Result result = create_new_resolver_result(); + gpr_event ev1; + gpr_event_init(&ev1); + result_handler->SetExpectedAndEvent(result, &ev1); + response_generator->SetResponse(std::move(result)); grpc_core::ExecCtx::Get()->Flush(); - GPR_ASSERT(gpr_event_wait(&on_res_arg.ev, - grpc_timeout_seconds_to_deadline(5)) != nullptr); + GPR_ASSERT(gpr_event_wait(&ev1, grpc_timeout_seconds_to_deadline(5)) != + nullptr); // Test 2: update resolution. // next_results != NULL, reresolution_results == NULL. // Expected response is next_results. - results = create_new_resolver_result(); - on_res_arg = create_on_resolution_arg(results); - on_resolution = GRPC_CLOSURE_CREATE(on_resolution_cb, &on_res_arg, - grpc_combiner_scheduler(combiner)); - // Resolution won't be triggered until next_results is set. - resolver->NextLocked(&on_res_arg.resolver_result, on_resolution); - response_generator->SetResponse(results); + gpr_log(GPR_INFO, "TEST 2"); + result = create_new_resolver_result(); + gpr_event ev2; + gpr_event_init(&ev2); + result_handler->SetExpectedAndEvent(result, &ev2); + response_generator->SetResponse(std::move(result)); grpc_core::ExecCtx::Get()->Flush(); - GPR_ASSERT(gpr_event_wait(&on_res_arg.ev, - grpc_timeout_seconds_to_deadline(5)) != nullptr); + GPR_ASSERT(gpr_event_wait(&ev2, grpc_timeout_seconds_to_deadline(5)) != + nullptr); // Test 3: normal re-resolution. // next_results == NULL, reresolution_results != NULL. // Expected response is reresolution_results. - grpc_channel_args* reresolution_results = create_new_resolver_result(); - on_res_arg = - create_on_resolution_arg(grpc_channel_args_copy(reresolution_results)); - on_resolution = GRPC_CLOSURE_CREATE(on_resolution_cb, &on_res_arg, - grpc_combiner_scheduler(combiner)); - resolver->NextLocked(&on_res_arg.resolver_result, on_resolution); + gpr_log(GPR_INFO, "TEST 3"); + grpc_core::Resolver::Result reresolution_result = + create_new_resolver_result(); + gpr_event ev3; + gpr_event_init(&ev3); + result_handler->SetExpectedAndEvent(reresolution_result, &ev3); // Set reresolution_results. - response_generator->SetReresolutionResponse(reresolution_results); - // Flush here to guarantee that the response has been set. + // No result will be returned until re-resolution is requested. + response_generator->SetReresolutionResponse(reresolution_result); grpc_core::ExecCtx::Get()->Flush(); // Trigger a re-resolution. resolver->RequestReresolutionLocked(); grpc_core::ExecCtx::Get()->Flush(); - GPR_ASSERT(gpr_event_wait(&on_res_arg.ev, - grpc_timeout_seconds_to_deadline(5)) != nullptr); + GPR_ASSERT(gpr_event_wait(&ev3, grpc_timeout_seconds_to_deadline(5)) != + nullptr); // Test 4: repeat re-resolution. // next_results == NULL, reresolution_results != NULL. // Expected response is reresolution_results. - on_res_arg = create_on_resolution_arg(reresolution_results); - on_resolution = GRPC_CLOSURE_CREATE(on_resolution_cb, &on_res_arg, - grpc_combiner_scheduler(combiner)); - resolver->NextLocked(&on_res_arg.resolver_result, on_resolution); + gpr_log(GPR_INFO, "TEST 4"); + gpr_event ev4; + gpr_event_init(&ev4); + result_handler->SetExpectedAndEvent(std::move(reresolution_result), &ev4); // Trigger a re-resolution. resolver->RequestReresolutionLocked(); grpc_core::ExecCtx::Get()->Flush(); - GPR_ASSERT(gpr_event_wait(&on_res_arg.ev, - grpc_timeout_seconds_to_deadline(5)) != nullptr); + GPR_ASSERT(gpr_event_wait(&ev4, grpc_timeout_seconds_to_deadline(5)) != + nullptr); // Test 5: normal resolution. // next_results != NULL, reresolution_results != NULL. // Expected response is next_results. - results = create_new_resolver_result(); - on_res_arg = create_on_resolution_arg(results); - on_resolution = GRPC_CLOSURE_CREATE(on_resolution_cb, &on_res_arg, - grpc_combiner_scheduler(combiner)); - // Resolution won't be triggered until next_results is set. - resolver->NextLocked(&on_res_arg.resolver_result, on_resolution); - response_generator->SetResponse(results); + gpr_log(GPR_INFO, "TEST 5"); + result = create_new_resolver_result(); + gpr_event ev5; + gpr_event_init(&ev5); + result_handler->SetExpectedAndEvent(result, &ev5); + response_generator->SetResponse(std::move(result)); grpc_core::ExecCtx::Get()->Flush(); - GPR_ASSERT(gpr_event_wait(&on_res_arg.ev, - grpc_timeout_seconds_to_deadline(5)) != nullptr); + GPR_ASSERT(gpr_event_wait(&ev5, grpc_timeout_seconds_to_deadline(5)) != + nullptr); // Test 6: no-op. // Requesting a new resolution without setting the response shouldn't trigger // the resolution callback. - memset(&on_res_arg, 0, sizeof(on_res_arg)); - on_resolution = GRPC_CLOSURE_CREATE(on_resolution_cb, &on_res_arg, - grpc_combiner_scheduler(combiner)); - resolver->NextLocked(&on_res_arg.resolver_result, on_resolution); - grpc_core::ExecCtx::Get()->Flush(); - GPR_ASSERT(gpr_event_wait(&on_res_arg.ev, - grpc_timeout_milliseconds_to_deadline(100)) == + gpr_log(GPR_INFO, "TEST 6"); + gpr_event ev6; + gpr_event_init(&ev6); + result_handler->SetExpectedAndEvent(grpc_core::Resolver::Result(), &ev6); + GPR_ASSERT(gpr_event_wait(&ev6, grpc_timeout_milliseconds_to_deadline(100)) == nullptr); // Clean up. - // Note: Need to explicitly unref the resolver and flush the exec_ctx - // to make sure that the final resolver callback (with error set to - // "Resolver Shutdown") is invoked before on_res_arg goes out of scope. resolver.reset(); - grpc_core::ExecCtx::Get()->Flush(); GRPC_COMBINER_UNREF(combiner, "test_fake_resolver"); } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); test_fake_resolver(); diff --git a/test/core/client_channel/resolvers/sockaddr_resolver_test.cc b/test/core/client_channel/resolvers/sockaddr_resolver_test.cc index b9287c24688..ac3d31b8ff8 100644 --- a/test/core/client_channel/resolvers/sockaddr_resolver_test.cc +++ b/test/core/client_channel/resolvers/sockaddr_resolver_test.cc @@ -30,15 +30,12 @@ static grpc_combiner* g_combiner; -typedef struct on_resolution_arg { - char* expected_server_name; - grpc_channel_args* resolver_result; -} on_resolution_arg; +class ResultHandler : public grpc_core::Resolver::ResultHandler { + public: + void ReturnResult(grpc_core::Resolver::Result result) override {} -void on_resolution_cb(void* arg, grpc_error* error) { - on_resolution_arg* res = static_cast(arg); - grpc_channel_args_destroy(res->resolver_result); -} + void ReturnError(grpc_error* error) override { GRPC_ERROR_UNREF(error); } +}; static void test_succeeds(grpc_core::ResolverFactory* factory, const char* string) { @@ -50,18 +47,14 @@ static void test_succeeds(grpc_core::ResolverFactory* factory, grpc_core::ResolverArgs args; args.uri = uri; args.combiner = g_combiner; + args.result_handler = + grpc_core::UniquePtr( + grpc_core::New()); grpc_core::OrphanablePtr resolver = - factory->CreateResolver(args); + factory->CreateResolver(std::move(args)); GPR_ASSERT(resolver != nullptr); - - on_resolution_arg on_res_arg; - memset(&on_res_arg, 0, sizeof(on_res_arg)); - on_res_arg.expected_server_name = uri->path; - grpc_closure* on_resolution = GRPC_CLOSURE_CREATE( - on_resolution_cb, &on_res_arg, grpc_schedule_on_exec_ctx); - - resolver->NextLocked(&on_res_arg.resolver_result, on_resolution); grpc_uri_destroy(uri); + resolver->StartLocked(); /* Flush ExecCtx to avoid stack-use-after-scope on on_res_arg which is * accessed in the closure on_resolution_cb */ grpc_core::ExecCtx::Get()->Flush(); @@ -77,14 +70,17 @@ static void test_fails(grpc_core::ResolverFactory* factory, grpc_core::ResolverArgs args; args.uri = uri; args.combiner = g_combiner; + args.result_handler = + grpc_core::UniquePtr( + grpc_core::New()); grpc_core::OrphanablePtr resolver = - factory->CreateResolver(args); + factory->CreateResolver(std::move(args)); GPR_ASSERT(resolver == nullptr); grpc_uri_destroy(uri); } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); g_combiner = grpc_combiner_create(); diff --git a/test/core/client_channel/retry_throttle_test.cc b/test/core/client_channel/retry_throttle_test.cc index c6d5d3ebbb8..793e86dc065 100644 --- a/test/core/client_channel/retry_throttle_test.cc +++ b/test/core/client_channel/retry_throttle_test.cc @@ -136,7 +136,7 @@ TEST(ServerRetryThrottleMap, Replacement) { } // namespace grpc_core int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/core/client_channel/service_config_test.cc b/test/core/client_channel/service_config_test.cc new file mode 100644 index 00000000000..9734304c9ac --- /dev/null +++ b/test/core/client_channel/service_config_test.cc @@ -0,0 +1,1045 @@ +/* + * + * Copyright 2019 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 + +#include + +#include +#include "src/core/ext/filters/client_channel/resolver_result_parsing.h" +#include "src/core/ext/filters/client_channel/service_config.h" +#include "src/core/ext/filters/message_size/message_size_filter.h" +#include "src/core/lib/gpr/string.h" +#include "test/core/util/port.h" +#include "test/core/util/test_config.h" + +namespace grpc_core { +namespace testing { + +class TestParsedObject1 : public ServiceConfig::ParsedConfig { + public: + TestParsedObject1(int value) : value_(value) {} + + int value() const { return value_; } + + private: + int value_; +}; + +class TestParser1 : public ServiceConfig::Parser { + public: + UniquePtr ParseGlobalParams( + const grpc_json* json, grpc_error** error) override { + GPR_DEBUG_ASSERT(error != nullptr); + for (grpc_json* field = json->child; field != nullptr; + field = field->next) { + if (strcmp(field->key, "global_param") == 0) { + if (field->type != GRPC_JSON_NUMBER) { + *error = + GRPC_ERROR_CREATE_FROM_STATIC_STRING(InvalidTypeErrorMessage()); + return nullptr; + } + int value = gpr_parse_nonnegative_int(field->value); + if (value == -1) { + *error = + GRPC_ERROR_CREATE_FROM_STATIC_STRING(InvalidValueErrorMessage()); + return nullptr; + } + return UniquePtr( + New(value)); + } + } + return nullptr; + } + + static const char* InvalidTypeErrorMessage() { + return "global_param value type should be a number"; + } + + static const char* InvalidValueErrorMessage() { + return "global_param value type should be non-negative"; + } +}; + +class TestParser2 : public ServiceConfig::Parser { + public: + UniquePtr ParsePerMethodParams( + const grpc_json* json, grpc_error** error) override { + GPR_DEBUG_ASSERT(error != nullptr); + for (grpc_json* field = json->child; field != nullptr; + field = field->next) { + if (field->key == nullptr || strcmp(field->key, "name") == 0) { + continue; + } + if (strcmp(field->key, "method_param") == 0) { + if (field->type != GRPC_JSON_NUMBER) { + *error = + GRPC_ERROR_CREATE_FROM_STATIC_STRING(InvalidTypeErrorMessage()); + return nullptr; + } + int value = gpr_parse_nonnegative_int(field->value); + if (value == -1) { + *error = + GRPC_ERROR_CREATE_FROM_STATIC_STRING(InvalidValueErrorMessage()); + return nullptr; + } + return UniquePtr( + New(value)); + } + } + return nullptr; + } + + static const char* InvalidTypeErrorMessage() { + return "method_param value type should be a number"; + } + + static const char* InvalidValueErrorMessage() { + return "method_param value type should be non-negative"; + } +}; + +// This parser always adds errors +class ErrorParser : public ServiceConfig::Parser { + public: + UniquePtr ParsePerMethodParams( + const grpc_json* json, grpc_error** error) override { + GPR_DEBUG_ASSERT(error != nullptr); + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(MethodError()); + return nullptr; + } + + UniquePtr ParseGlobalParams( + const grpc_json* json, grpc_error** error) override { + GPR_DEBUG_ASSERT(error != nullptr); + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(GlobalError()); + return nullptr; + } + + static const char* MethodError() { return "ErrorParser : methodError"; } + + static const char* GlobalError() { return "ErrorParser : globalError"; } +}; + +void VerifyRegexMatch(grpc_error* error, const std::regex& e) { + std::smatch match; + std::string s(grpc_error_string(error)); + EXPECT_TRUE(std::regex_search(s, match, e)); + GRPC_ERROR_UNREF(error); +} + +class ServiceConfigTest : public ::testing::Test { + protected: + void SetUp() override { + ServiceConfig::Shutdown(); + ServiceConfig::Init(); + EXPECT_TRUE(ServiceConfig::RegisterParser( + UniquePtr(New())) == 0); + EXPECT_TRUE(ServiceConfig::RegisterParser( + UniquePtr(New())) == 1); + } +}; + +TEST_F(ServiceConfigTest, ErrorCheck1) { + const char* test_json = ""; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + std::regex e(std::string("failed to parse JSON for service config")); + VerifyRegexMatch(error, e); +} + +TEST_F(ServiceConfigTest, BasicTest1) { + const char* test_json = "{}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + EXPECT_TRUE(error == GRPC_ERROR_NONE); +} + +TEST_F(ServiceConfigTest, ErrorNoNames) { + const char* test_json = "{\"methodConfig\": [{\"blah\":1}]}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + std::regex e( + std::string("(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Method " + "Params)(.*)(referenced_errors)(.*)(No names " + "found)(.*)(methodConfig)(.*)(referenced_errors)(.*)(No " + "names specified)")); + VerifyRegexMatch(error, e); +} + +TEST_F(ServiceConfigTest, ErrorNoNamesWithMultipleMethodConfigs) { + const char* test_json = + "{\"methodConfig\": [{}, {\"name\":[{\"service\":\"TestServ\"}]}]}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + std::regex e( + std::string("(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Method " + "Params)(.*)(referenced_errors)(.*)(No names " + "found)(.*)(methodConfig)(.*)(referenced_errors)(.*)(No " + "names specified)")); + VerifyRegexMatch(error, e); +} + +TEST_F(ServiceConfigTest, ValidMethodConfig) { + const char* test_json = + "{\"methodConfig\": [{\"name\":[{\"service\":\"TestServ\"}]}]}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + EXPECT_TRUE(error == GRPC_ERROR_NONE); +} + +TEST_F(ServiceConfigTest, Parser1BasicTest1) { + const char* test_json = "{\"global_param\":5}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + ASSERT_TRUE(error == GRPC_ERROR_NONE); + EXPECT_TRUE((static_cast( + svc_cfg->GetParsedGlobalServiceConfigObject(0))) + ->value() == 5); + EXPECT_TRUE(svc_cfg->GetMethodServiceConfigObjectsVector( + grpc_slice_from_static_string("/TestServ/TestMethod")) == + nullptr); +} + +TEST_F(ServiceConfigTest, Parser1BasicTest2) { + const char* test_json = "{\"global_param\":1000}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + ASSERT_TRUE(error == GRPC_ERROR_NONE); + EXPECT_TRUE((static_cast( + svc_cfg->GetParsedGlobalServiceConfigObject(0))) + ->value() == 1000); +} + +TEST_F(ServiceConfigTest, Parser1ErrorInvalidType) { + const char* test_json = "{\"global_param\":\"5\"}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + std::regex e(std::string("(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Global " + "Params)(.*)(referenced_errors)(.*)") + + TestParser1::InvalidTypeErrorMessage()); + VerifyRegexMatch(error, e); +} + +TEST_F(ServiceConfigTest, Parser1ErrorInvalidValue) { + const char* test_json = "{\"global_param\":-5}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + std::regex e(std::string("(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Global " + "Params)(.*)(referenced_errors)(.*)") + + TestParser1::InvalidValueErrorMessage()); + VerifyRegexMatch(error, e); +} + +TEST_F(ServiceConfigTest, Parser2BasicTest) { + const char* test_json = + "{\"methodConfig\": [{\"name\":[{\"service\":\"TestServ\"}], " + "\"method_param\":5}]}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + ASSERT_TRUE(error == GRPC_ERROR_NONE); + const auto* vector_ptr = svc_cfg->GetMethodServiceConfigObjectsVector( + grpc_slice_from_static_string("/TestServ/TestMethod")); + EXPECT_TRUE(vector_ptr != nullptr); + auto parsed_object = ((*vector_ptr)[1]).get(); + EXPECT_TRUE(static_cast(parsed_object)->value() == 5); +} + +TEST_F(ServiceConfigTest, Parser2ErrorInvalidType) { + const char* test_json = + "{\"methodConfig\": [{\"name\":[{\"service\":\"TestServ\"}], " + "\"method_param\":\"5\"}]}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + std::regex e(std::string("(Service config parsing " + "error)(.*)(referenced_errors\":\\[)(.*)(Method " + "Params)(.*)(referenced_errors)(.*)(methodConfig)(" + ".*)(referenced_errors)(.*)") + + TestParser2::InvalidTypeErrorMessage()); + VerifyRegexMatch(error, e); +} + +TEST_F(ServiceConfigTest, Parser2ErrorInvalidValue) { + const char* test_json = + "{\"methodConfig\": [{\"name\":[{\"service\":\"TestServ\"}], " + "\"method_param\":-5}]}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + std::regex e(std::string("(Service config parsing " + "error)(.*)(referenced_errors\":\\[)(.*)(Method " + "Params)(.*)(referenced_errors)()(.*)(methodConfig)(" + ".*)(referenced_errors)(.*)") + + TestParser2::InvalidValueErrorMessage()); + VerifyRegexMatch(error, e); +} + +// Test parsing with ErrorParsers which always add errors +class ErroredParsersScopingTest : public ::testing::Test { + protected: + void SetUp() override { + ServiceConfig::Shutdown(); + ServiceConfig::Init(); + EXPECT_TRUE(ServiceConfig::RegisterParser( + UniquePtr(New())) == 0); + EXPECT_TRUE(ServiceConfig::RegisterParser( + UniquePtr(New())) == 1); + } +}; + +TEST_F(ErroredParsersScopingTest, GlobalParams) { + const char* test_json = "{}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + std::regex e(std::string("(Service config parsing " + "error)(.*)(referenced_errors\":\\[)(.*)(Global " + "Params)(.*)(referenced_errors)()(.*)") + + ErrorParser::GlobalError() + std::string("(.*)") + + ErrorParser::GlobalError()); + VerifyRegexMatch(error, e); +} + +TEST_F(ErroredParsersScopingTest, MethodParams) { + const char* test_json = "{\"methodConfig\": [{}]}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + std::regex e( + std::string("(Service config parsing " + "error)(.*)(referenced_errors\":\\[)(.*)(Global " + "Params)(.*)(referenced_errors)()(.*)") + + ErrorParser::GlobalError() + std::string("(.*)") + + ErrorParser::GlobalError() + + std::string("(.*)(Method " + "Params)(.*)(referenced_errors)(.*)(field:methodConfig " + "error:No names " + "found)(.*)(methodConfig)(.*)(referenced_errors)(.*)") + + ErrorParser::MethodError() + std::string("(.*)") + + ErrorParser::MethodError() + std::string("(.*)(No names specified)")); + VerifyRegexMatch(error, e); +} + +class ClientChannelParserTest : public ::testing::Test { + protected: + void SetUp() override { + ServiceConfig::Shutdown(); + ServiceConfig::Init(); + EXPECT_TRUE( + ServiceConfig::RegisterParser(UniquePtr( + New())) == + 0); + } +}; + +TEST_F(ClientChannelParserTest, ValidLoadBalancingConfigPickFirst) { + const char* test_json = "{\"loadBalancingConfig\": [{\"pick_first\":{}}]}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + ASSERT_TRUE(error == GRPC_ERROR_NONE); + const auto* parsed_object = + static_cast( + svc_cfg->GetParsedGlobalServiceConfigObject(0)); + auto lb_config = parsed_object->parsed_lb_config(); + EXPECT_TRUE(strcmp(lb_config->name(), "pick_first") == 0); +} + +TEST_F(ClientChannelParserTest, ValidLoadBalancingConfigRoundRobin) { + const char* test_json = + "{\"loadBalancingConfig\": [{\"round_robin\":{}}, {}]}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + ASSERT_TRUE(error == GRPC_ERROR_NONE); + auto parsed_object = + static_cast( + svc_cfg->GetParsedGlobalServiceConfigObject(0)); + auto lb_config = parsed_object->parsed_lb_config(); + EXPECT_TRUE(strcmp(lb_config->name(), "round_robin") == 0); +} + +TEST_F(ClientChannelParserTest, ValidLoadBalancingConfigGrpclb) { + const char* test_json = + "{\"loadBalancingConfig\": " + "[{\"grpclb\":{\"childPolicy\":[{\"pick_first\":{}}]}}]}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + ASSERT_TRUE(error == GRPC_ERROR_NONE); + const auto* parsed_object = + static_cast( + svc_cfg->GetParsedGlobalServiceConfigObject(0)); + auto lb_config = parsed_object->parsed_lb_config(); + EXPECT_TRUE(strcmp(lb_config->name(), "grpclb") == 0); +} + +TEST_F(ClientChannelParserTest, ValidLoadBalancingConfigXds) { + const char* test_json = + "{\n" + " \"loadBalancingConfig\":[\n" + " { \"does_not_exist\":{} },\n" + " { \"xds_experimental\":{ \"balancerName\": \"fake:///lb\" } }\n" + " ]\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error == GRPC_ERROR_NONE); + const auto* parsed_object = + static_cast( + svc_cfg->GetParsedGlobalServiceConfigObject(0)); + auto lb_config = parsed_object->parsed_lb_config(); + EXPECT_TRUE(strcmp(lb_config->name(), "xds_experimental") == 0); +} + +TEST_F(ClientChannelParserTest, UnknownLoadBalancingConfig) { + const char* test_json = "{\"loadBalancingConfig\": [{\"unknown\":{}}]}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + std::regex e( + std::string("(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Global " + "Params)(.*)(referenced_errors)(.*)(Client channel global " + "parser)(.*)(referenced_errors)(.*)(field:" + "loadBalancingConfig error:No known policy)")); + VerifyRegexMatch(error, e); +} + +TEST_F(ClientChannelParserTest, InvalidGrpclbLoadBalancingConfig) { + const char* test_json = + "{\"loadBalancingConfig\": " + "[{\"grpclb\":{\"childPolicy\":[{\"unknown\":{}}]}}]}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + std::regex e( + std::string("(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Global " + "Params)(.*)(referenced_errors)(.*)(Client channel global " + "parser)(.*)(referenced_errors)(.*)(GrpcLb " + "Parser)(.*)(referenced_errors)(.*)(field:childPolicy " + "error:No known policy)")); + VerifyRegexMatch(error, e); +} + +TEST_F(ClientChannelParserTest, InalidLoadBalancingConfigXds) { + const char* test_json = + "{\n" + " \"loadBalancingConfig\":[\n" + " { \"does_not_exist\":{} },\n" + " { \"xds_experimental\":{} }\n" + " ]\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + std::regex e( + std::string("(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Global " + "Params)(.*)(referenced_errors)(.*)(Client channel global " + "parser)(.*)(referenced_errors)(.*)(Xds " + "Parser)(.*)(referenced_errors)(.*)(field:balancerName " + "error:not found)")); + VerifyRegexMatch(error, e); +} + +TEST_F(ClientChannelParserTest, ValidLoadBalancingPolicy) { + const char* test_json = "{\"loadBalancingPolicy\":\"pick_first\"}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + ASSERT_TRUE(error == GRPC_ERROR_NONE); + const auto* parsed_object = + static_cast( + svc_cfg->GetParsedGlobalServiceConfigObject(0)); + const auto* lb_policy = parsed_object->parsed_deprecated_lb_policy(); + ASSERT_TRUE(lb_policy != nullptr); + EXPECT_TRUE(strcmp(lb_policy, "pick_first") == 0); +} + +TEST_F(ClientChannelParserTest, ValidLoadBalancingPolicyAllCaps) { + const char* test_json = "{\"loadBalancingPolicy\":\"PICK_FIRST\"}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error == GRPC_ERROR_NONE); + const auto* parsed_object = + static_cast( + svc_cfg->GetParsedGlobalServiceConfigObject(0)); + const auto* lb_policy = parsed_object->parsed_deprecated_lb_policy(); + ASSERT_TRUE(lb_policy != nullptr); + EXPECT_TRUE(strcmp(lb_policy, "pick_first") == 0); +} + +TEST_F(ClientChannelParserTest, UnknownLoadBalancingPolicy) { + const char* test_json = "{\"loadBalancingPolicy\":\"unknown\"}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + std::regex e( + std::string("(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Global " + "Params)(.*)(referenced_errors)(.*)(Client channel global " + "parser)(.*)(referenced_errors)(.*)(field:" + "loadBalancingPolicy error:Unknown lb policy)")); + VerifyRegexMatch(error, e); +} + +TEST_F(ClientChannelParserTest, LoadBalancingPolicyXdsNotAllowed) { + const char* test_json = "{\"loadBalancingPolicy\":\"xds_experimental\"}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + std::regex e( + std::string("(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Global " + "Params)(.*)(referenced_errors)(.*)(Client channel global " + "parser)(.*)(referenced_errors)(.*)(field:" + "loadBalancingPolicy error:xds_experimental requires a " + "config. Please use loadBalancingConfig instead.)")); + VerifyRegexMatch(error, e); +} + +TEST_F(ClientChannelParserTest, ValidRetryThrottling) { + const char* test_json = + "{\n" + " \"retryThrottling\": {\n" + " \"maxTokens\": 2,\n" + " \"tokenRatio\": 1.0\n" + " }\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error == GRPC_ERROR_NONE); + const auto* parsed_object = + static_cast( + svc_cfg->GetParsedGlobalServiceConfigObject(0)); + const auto retryThrottling = parsed_object->retry_throttling(); + ASSERT_TRUE(retryThrottling.has_value()); + EXPECT_EQ(retryThrottling.value().max_milli_tokens, 2000); + EXPECT_EQ(retryThrottling.value().milli_token_ratio, 1000); +} + +TEST_F(ClientChannelParserTest, RetryThrottlingMissingFields) { + const char* test_json = + "{\n" + " \"retryThrottling\": {\n" + " }\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + std::regex e( + std::string("(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Global " + "Params)(.*)(referenced_errors)(.*)(Client channel global " + "parser)(.*)(referenced_errors)(.*)(field:retryThrottling " + "field:maxTokens error:Not found)(.*)(field:retryThrottling " + "field:tokenRatio error:Not found)")); + VerifyRegexMatch(error, e); +} + +TEST_F(ClientChannelParserTest, InvalidRetryThrottlingNegativeMaxTokens) { + const char* test_json = + "{\n" + " \"retryThrottling\": {\n" + " \"maxTokens\": -2,\n" + " \"tokenRatio\": 1.0\n" + " }\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + std::regex e( + std::string("(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Global " + "Params)(.*)(referenced_errors)(.*)(Client channel global " + "parser)(.*)(referenced_errors)(.*)(field:retryThrottling " + "field:maxTokens error:should be greater than zero)")); + VerifyRegexMatch(error, e); +} + +TEST_F(ClientChannelParserTest, InvalidRetryThrottlingInvalidTokenRatio) { + const char* test_json = + "{\n" + " \"retryThrottling\": {\n" + " \"maxTokens\": 2,\n" + " \"tokenRatio\": -1\n" + " }\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + std::regex e( + std::string("(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Global " + "Params)(.*)(referenced_errors)(.*)(Client channel global " + "parser)(.*)(referenced_errors)(.*)(field:retryThrottling " + "field:tokenRatio error:Failed parsing)")); + VerifyRegexMatch(error, e); +} + +TEST_F(ClientChannelParserTest, ValidTimeout) { + const char* test_json = + "{\n" + " \"methodConfig\": [ {\n" + " \"name\": [\n" + " { \"service\": \"TestServ\", \"method\": \"TestMethod\" }\n" + " ],\n" + " \"timeout\": \"5s\"\n" + " } ]\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + ASSERT_TRUE(error == GRPC_ERROR_NONE); + const auto* vector_ptr = svc_cfg->GetMethodServiceConfigObjectsVector( + grpc_slice_from_static_string("/TestServ/TestMethod")); + EXPECT_TRUE(vector_ptr != nullptr); + auto parsed_object = ((*vector_ptr)[0]).get(); + EXPECT_EQ((static_cast( + parsed_object)) + ->timeout(), + 5000); +} + +TEST_F(ClientChannelParserTest, InvalidTimeout) { + const char* test_json = + "{\n" + " \"methodConfig\": [ {\n" + " \"name\": [\n" + " { \"service\": \"service\", \"method\": \"method\" }\n" + " ],\n" + " \"timeout\": \"5sec\"\n" + " } ]\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + std::regex e( + std::string("(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Method " + "Params)(.*)(referenced_errors)(.*)(methodConfig)(.*)(" + "referenced_errors)(.*)(Client channel " + "parser)(.*)(referenced_errors)(.*)(field:timeout " + "error:Failed parsing)")); + VerifyRegexMatch(error, e); +} + +TEST_F(ClientChannelParserTest, ValidWaitForReady) { + const char* test_json = + "{\n" + " \"methodConfig\": [ {\n" + " \"name\": [\n" + " { \"service\": \"TestServ\", \"method\": \"TestMethod\" }\n" + " ],\n" + " \"waitForReady\": true\n" + " } ]\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + ASSERT_TRUE(error == GRPC_ERROR_NONE); + const auto* vector_ptr = svc_cfg->GetMethodServiceConfigObjectsVector( + grpc_slice_from_static_string("/TestServ/TestMethod")); + EXPECT_TRUE(vector_ptr != nullptr); + auto parsed_object = ((*vector_ptr)[0]).get(); + EXPECT_TRUE( + (static_cast( + parsed_object)) + ->wait_for_ready() + .has_value()); + EXPECT_TRUE( + (static_cast( + parsed_object)) + ->wait_for_ready() + .value()); +} + +TEST_F(ClientChannelParserTest, InvalidWaitForReady) { + const char* test_json = + "{\n" + " \"methodConfig\": [ {\n" + " \"name\": [\n" + " { \"service\": \"service\", \"method\": \"method\" }\n" + " ],\n" + " \"waitForReady\": \"true\"\n" + " } ]\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + std::regex e( + std::string("(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Method " + "Params)(.*)(referenced_errors)(.*)(methodConfig)(.*)(" + "referenced_errors)(.*)(Client channel " + "parser)(.*)(referenced_errors)(.*)(field:waitForReady " + "error:Type should be true/false)")); + VerifyRegexMatch(error, e); +} + +TEST_F(ClientChannelParserTest, ValidRetryPolicy) { + const char* test_json = + "{\n" + " \"methodConfig\": [ {\n" + " \"name\": [\n" + " { \"service\": \"TestServ\", \"method\": \"TestMethod\" }\n" + " ],\n" + " \"retryPolicy\": {\n" + " \"maxAttempts\": 3,\n" + " \"initialBackoff\": \"1s\",\n" + " \"maxBackoff\": \"120s\",\n" + " \"backoffMultiplier\": 1.6,\n" + " \"retryableStatusCodes\": [ \"ABORTED\" ]\n" + " }\n" + " } ]\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error == GRPC_ERROR_NONE); + const auto* vector_ptr = svc_cfg->GetMethodServiceConfigObjectsVector( + grpc_slice_from_static_string("/TestServ/TestMethod")); + EXPECT_TRUE(vector_ptr != nullptr); + const auto* parsed_object = + static_cast( + ((*vector_ptr)[0]).get()); + EXPECT_TRUE(parsed_object->retry_policy() != nullptr); + EXPECT_EQ(parsed_object->retry_policy()->max_attempts, 3); + EXPECT_EQ(parsed_object->retry_policy()->initial_backoff, 1000); + EXPECT_EQ(parsed_object->retry_policy()->max_backoff, 120000); + EXPECT_EQ(parsed_object->retry_policy()->backoff_multiplier, 1.6f); + EXPECT_TRUE(parsed_object->retry_policy()->retryable_status_codes.Contains( + GRPC_STATUS_ABORTED)); +} + +TEST_F(ClientChannelParserTest, InvalidRetryPolicyMaxAttempts) { + const char* test_json = + "{\n" + " \"methodConfig\": [ {\n" + " \"name\": [\n" + " { \"service\": \"TestServ\", \"method\": \"TestMethod\" }\n" + " ],\n" + " \"retryPolicy\": {\n" + " \"maxAttempts\": 1,\n" + " \"initialBackoff\": \"1s\",\n" + " \"maxBackoff\": \"120s\",\n" + " \"backoffMultiplier\": 1.6,\n" + " \"retryableStatusCodes\": [ \"ABORTED\" ]\n" + " }\n" + " } ]\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + std::regex e(std::string( + "(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Method " + "Params)(.*)(referenced_errors)(.*)(methodConfig)(.*)(referenced_errors)(" + ".*)(Client channel " + "parser)(.*)(referenced_errors)(.*)(retryPolicy)(.*)(referenced_errors)(." + "*)(field:maxAttempts error:should be at least 2)")); + VerifyRegexMatch(error, e); +} + +TEST_F(ClientChannelParserTest, InvalidRetryPolicyInitialBackoff) { + const char* test_json = + "{\n" + " \"methodConfig\": [ {\n" + " \"name\": [\n" + " { \"service\": \"TestServ\", \"method\": \"TestMethod\" }\n" + " ],\n" + " \"retryPolicy\": {\n" + " \"maxAttempts\": 1,\n" + " \"initialBackoff\": \"1sec\",\n" + " \"maxBackoff\": \"120s\",\n" + " \"backoffMultiplier\": 1.6,\n" + " \"retryableStatusCodes\": [ \"ABORTED\" ]\n" + " }\n" + " } ]\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + std::regex e(std::string( + "(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Method " + "Params)(.*)(referenced_errors)(.*)(methodConfig)(.*)(referenced_errors)(" + ".*)(Client channel " + "parser)(.*)(referenced_errors)(.*)(retryPolicy)(.*)(referenced_errors)(." + "*)(field:initialBackoff error:Failed to parse)")); + VerifyRegexMatch(error, e); +} + +TEST_F(ClientChannelParserTest, InvalidRetryPolicyMaxBackoff) { + const char* test_json = + "{\n" + " \"methodConfig\": [ {\n" + " \"name\": [\n" + " { \"service\": \"TestServ\", \"method\": \"TestMethod\" }\n" + " ],\n" + " \"retryPolicy\": {\n" + " \"maxAttempts\": 1,\n" + " \"initialBackoff\": \"1s\",\n" + " \"maxBackoff\": \"120sec\",\n" + " \"backoffMultiplier\": 1.6,\n" + " \"retryableStatusCodes\": [ \"ABORTED\" ]\n" + " }\n" + " } ]\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + std::regex e(std::string( + "(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Method " + "Params)(.*)(referenced_errors)(.*)(methodConfig)(.*)(referenced_errors)(" + ".*)(Client channel " + "parser)(.*)(referenced_errors)(.*)(retryPolicy)(.*)(referenced_errors)(." + "*)(field:maxBackoff error:failed to parse)")); + VerifyRegexMatch(error, e); +} + +TEST_F(ClientChannelParserTest, InvalidRetryPolicyBackoffMultiplier) { + const char* test_json = + "{\n" + " \"methodConfig\": [ {\n" + " \"name\": [\n" + " { \"service\": \"TestServ\", \"method\": \"TestMethod\" }\n" + " ],\n" + " \"retryPolicy\": {\n" + " \"maxAttempts\": 1,\n" + " \"initialBackoff\": \"1s\",\n" + " \"maxBackoff\": \"120s\",\n" + " \"backoffMultiplier\": \"1.6\",\n" + " \"retryableStatusCodes\": [ \"ABORTED\" ]\n" + " }\n" + " } ]\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + std::regex e(std::string( + "(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Method " + "Params)(.*)(referenced_errors)(.*)(methodConfig)(.*)(referenced_errors)(" + ".*)(Client channel " + "parser)(.*)(referenced_errors)(.*)(retryPolicy)(.*)(referenced_errors)(." + "*)(field:backoffMultiplier error:should be of type number)")); + VerifyRegexMatch(error, e); +} + +TEST_F(ClientChannelParserTest, InvalidRetryPolicyRetryableStatusCodes) { + const char* test_json = + "{\n" + " \"methodConfig\": [ {\n" + " \"name\": [\n" + " { \"service\": \"TestServ\", \"method\": \"TestMethod\" }\n" + " ],\n" + " \"retryPolicy\": {\n" + " \"maxAttempts\": 1,\n" + " \"initialBackoff\": \"1s\",\n" + " \"maxBackoff\": \"120s\",\n" + " \"backoffMultiplier\": \"1.6\",\n" + " \"retryableStatusCodes\": []\n" + " }\n" + " } ]\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + std::regex e(std::string( + "(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Method " + "Params)(.*)(referenced_errors)(.*)(methodConfig)(.*)(referenced_errors)(" + ".*)(Client channel " + "parser)(.*)(referenced_errors)(.*)(retryPolicy)(.*)(referenced_errors)(." + "*)(field:retryableStatusCodes error:should be non-empty)")); + VerifyRegexMatch(error, e); +} + +TEST_F(ClientChannelParserTest, ValidHealthCheck) { + const char* test_json = + "{\n" + " \"healthCheckConfig\": {\n" + " \"serviceName\": \"health_check_service_name\"\n" + " }\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + ASSERT_TRUE(error == GRPC_ERROR_NONE); + const auto* parsed_object = + static_cast( + svc_cfg->GetParsedGlobalServiceConfigObject(0)); + ASSERT_TRUE(parsed_object != nullptr); + EXPECT_EQ(strcmp(parsed_object->health_check_service_name(), + "health_check_service_name"), + 0); +} + +TEST_F(ClientChannelParserTest, InvalidHealthCheckMultipleEntries) { + const char* test_json = + "{\n" + " \"healthCheckConfig\": {\n" + " \"serviceName\": \"health_check_service_name\"\n" + " },\n" + " \"healthCheckConfig\": {\n" + " \"serviceName\": \"health_check_service_name1\"\n" + " }\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + std::regex e( + std::string("(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Global " + "Params)(.*)(referenced_errors)(.*)(field:healthCheckConfig " + "error:Duplicate entry)")); + std::smatch match; + std::string s(grpc_error_string(error)); + EXPECT_TRUE(std::regex_search(s, match, e)); + GRPC_ERROR_UNREF(error); +} + +class MessageSizeParserTest : public ::testing::Test { + protected: + void SetUp() override { + ServiceConfig::Shutdown(); + ServiceConfig::Init(); + EXPECT_TRUE(ServiceConfig::RegisterParser(UniquePtr( + New())) == 0); + } +}; + +TEST_F(MessageSizeParserTest, Valid) { + const char* test_json = + "{\n" + " \"methodConfig\": [ {\n" + " \"name\": [\n" + " { \"service\": \"TestServ\", \"method\": \"TestMethod\" }\n" + " ],\n" + " \"maxRequestMessageBytes\": 1024,\n" + " \"maxResponseMessageBytes\": 1024\n" + " } ]\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error == GRPC_ERROR_NONE); + const auto* vector_ptr = svc_cfg->GetMethodServiceConfigObjectsVector( + grpc_slice_from_static_string("/TestServ/TestMethod")); + EXPECT_TRUE(vector_ptr != nullptr); + auto parsed_object = + static_cast(((*vector_ptr)[0]).get()); + ASSERT_TRUE(parsed_object != nullptr); + EXPECT_EQ(parsed_object->limits().max_send_size, 1024); + EXPECT_EQ(parsed_object->limits().max_recv_size, 1024); +} + +TEST_F(MessageSizeParserTest, InvalidMaxRequestMessageBytes) { + const char* test_json = + "{\n" + " \"methodConfig\": [ {\n" + " \"name\": [\n" + " { \"service\": \"TestServ\", \"method\": \"TestMethod\" }\n" + " ],\n" + " \"maxRequestMessageBytes\": -1024\n" + " } ]\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + std::regex e( + std::string("(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Method " + "Params)(.*)(referenced_errors)(.*)(methodConfig)(.*)(" + "referenced_errors)(.*)(Message size " + "parser)(.*)(referenced_errors)(.*)(field:" + "maxRequestMessageBytes error:should be non-negative)")); + VerifyRegexMatch(error, e); +} + +TEST_F(MessageSizeParserTest, InvalidMaxResponseMessageBytes) { + const char* test_json = + "{\n" + " \"methodConfig\": [ {\n" + " \"name\": [\n" + " { \"service\": \"TestServ\", \"method\": \"TestMethod\" }\n" + " ],\n" + " \"maxResponseMessageBytes\": {}\n" + " } ]\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + std::regex e( + std::string("(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Method " + "Params)(.*)(referenced_errors)(.*)(methodConfig)(.*)(" + "referenced_errors)(.*)(Message size " + "parser)(.*)(referenced_errors)(.*)(field:" + "maxResponseMessageBytes error:should be of type number)")); + VerifyRegexMatch(error, e); +} + +} // namespace testing +} // namespace grpc_core + +int main(int argc, char** argv) { + grpc::testing::TestEnvironment env(argc, argv); + grpc_init(); + ::testing::InitGoogleTest(&argc, argv); + int ret = RUN_ALL_TESTS(); + grpc_shutdown(); + return ret; +} diff --git a/test/core/client_channel/uri_parser_test.cc b/test/core/client_channel/uri_parser_test.cc index ec4f755dda8..713ec32e5e8 100644 --- a/test/core/client_channel/uri_parser_test.cc +++ b/test/core/client_channel/uri_parser_test.cc @@ -119,7 +119,7 @@ static void test_query_parts() { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); test_succeeds("http://www.google.com", "http", "www.google.com", "", "", ""); test_succeeds("dns:///foo", "dns", "", "/foo", "", ""); diff --git a/test/core/compression/BUILD b/test/core/compression/BUILD index 532972c784e..03c82689a85 100644 --- a/test/core/compression/BUILD +++ b/test/core/compression/BUILD @@ -25,7 +25,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -37,7 +36,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -49,7 +47,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -61,7 +58,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/compression/algorithm_test.cc b/test/core/compression/algorithm_test.cc index 8989a419897..24fe83774b8 100644 --- a/test/core/compression/algorithm_test.cc +++ b/test/core/compression/algorithm_test.cc @@ -105,7 +105,7 @@ static void test_algorithm_failure(void) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); test_algorithm_mesh(); diff --git a/test/core/compression/compression_test.cc b/test/core/compression/compression_test.cc index 6522988c66e..cf6d18847e6 100644 --- a/test/core/compression/compression_test.cc +++ b/test/core/compression/compression_test.cc @@ -23,7 +23,10 @@ #include #include +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/compression/compression_args.h" #include "src/core/lib/gpr/useful.h" +#include "src/core/lib/iomgr/exec_ctx.h" #include "test/core/util/test_config.h" static void test_compression_algorithm_parse(void) { @@ -258,12 +261,88 @@ static void test_compression_enable_disable_algorithm(void) { } } +static void test_channel_args_set_compression_algorithm(void) { + grpc_core::ExecCtx exec_ctx; + grpc_channel_args* ch_args; + + ch_args = + grpc_channel_args_set_compression_algorithm(nullptr, GRPC_COMPRESS_GZIP); + GPR_ASSERT(ch_args->num_args == 1); + GPR_ASSERT(strcmp(ch_args->args[0].key, + GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM) == 0); + GPR_ASSERT(ch_args->args[0].type == GRPC_ARG_INTEGER); + + grpc_channel_args_destroy(ch_args); +} + +static void test_channel_args_compression_algorithm_states(void) { + grpc_core::ExecCtx exec_ctx; + grpc_channel_args *ch_args, *ch_args_wo_gzip, *ch_args_wo_gzip_deflate, + *ch_args_wo_gzip_deflate_gzip; + unsigned states_bitset; + size_t i; + + ch_args = grpc_channel_args_copy_and_add(nullptr, nullptr, 0); + /* by default, all enabled */ + states_bitset = static_cast( + grpc_channel_args_compression_algorithm_get_states(ch_args)); + + for (i = 0; i < GRPC_COMPRESS_ALGORITHMS_COUNT; i++) { + GPR_ASSERT(GPR_BITGET(states_bitset, i)); + } + + /* disable gzip and deflate and stream/gzip */ + ch_args_wo_gzip = grpc_channel_args_compression_algorithm_set_state( + &ch_args, GRPC_COMPRESS_GZIP, 0); + GPR_ASSERT(ch_args == ch_args_wo_gzip); + ch_args_wo_gzip_deflate = grpc_channel_args_compression_algorithm_set_state( + &ch_args_wo_gzip, GRPC_COMPRESS_DEFLATE, 0); + GPR_ASSERT(ch_args_wo_gzip == ch_args_wo_gzip_deflate); + ch_args_wo_gzip_deflate_gzip = + grpc_channel_args_compression_algorithm_set_state( + &ch_args_wo_gzip_deflate, GRPC_COMPRESS_STREAM_GZIP, 0); + GPR_ASSERT(ch_args_wo_gzip_deflate == ch_args_wo_gzip_deflate_gzip); + + states_bitset = + static_cast(grpc_channel_args_compression_algorithm_get_states( + ch_args_wo_gzip_deflate)); + for (i = 0; i < GRPC_COMPRESS_ALGORITHMS_COUNT; i++) { + if (i == GRPC_COMPRESS_GZIP || i == GRPC_COMPRESS_DEFLATE || + i == GRPC_COMPRESS_STREAM_GZIP) { + GPR_ASSERT(GPR_BITGET(states_bitset, i) == 0); + } else { + GPR_ASSERT(GPR_BITGET(states_bitset, i) != 0); + } + } + + /* re-enabled gzip and stream/gzip only */ + ch_args_wo_gzip = grpc_channel_args_compression_algorithm_set_state( + &ch_args_wo_gzip_deflate_gzip, GRPC_COMPRESS_GZIP, 1); + ch_args_wo_gzip = grpc_channel_args_compression_algorithm_set_state( + &ch_args_wo_gzip, GRPC_COMPRESS_STREAM_GZIP, 1); + GPR_ASSERT(ch_args_wo_gzip == ch_args_wo_gzip_deflate_gzip); + + states_bitset = static_cast( + grpc_channel_args_compression_algorithm_get_states(ch_args_wo_gzip)); + for (i = 0; i < GRPC_COMPRESS_ALGORITHMS_COUNT; i++) { + if (i == GRPC_COMPRESS_DEFLATE) { + GPR_ASSERT(GPR_BITGET(states_bitset, i) == 0); + } else { + GPR_ASSERT(GPR_BITGET(states_bitset, i) != 0); + } + } + + grpc_channel_args_destroy(ch_args); +} + int main(int argc, char** argv) { grpc_init(); test_compression_algorithm_parse(); test_compression_algorithm_name(); test_compression_algorithm_for_level(); test_compression_enable_disable_algorithm(); + test_channel_args_set_compression_algorithm(); + test_channel_args_compression_algorithm_states(); grpc_shutdown(); return 0; diff --git a/test/core/compression/message_compress_test.cc b/test/core/compression/message_compress_test.cc index e3fe825fdf6..e2abf2d3215 100644 --- a/test/core/compression/message_compress_test.cc +++ b/test/core/compression/message_compress_test.cc @@ -292,7 +292,7 @@ int main(int argc, char** argv) { GRPC_SLICE_SPLIT_IDENTITY, GRPC_SLICE_SPLIT_ONE_BYTE}; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); for (i = 0; i < GRPC_MESSAGE_COMPRESS_ALGORITHMS_COUNT; i++) { diff --git a/test/core/debug/BUILD b/test/core/debug/BUILD index 1592472532b..c4209296702 100644 --- a/test/core/debug/BUILD +++ b/test/core/debug/BUILD @@ -28,7 +28,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/end2end/BUILD b/test/core/end2end/BUILD index 398e8a2d9ad..16f987e847d 100644 --- a/test/core/end2end/BUILD +++ b/test/core/end2end/BUILD @@ -70,6 +70,19 @@ grpc_cc_library( ], ) +grpc_cc_library( + name = "local_util", + srcs = ["fixtures/local_util.cc"], + hdrs = ["fixtures/local_util.h", + "end2end_tests.h"], + language = "C++", + deps = [ + "//:gpr", + "//:grpc", + "//test/core/util:grpc_test_util", + ], +) + grpc_cc_test( name = "bad_server_response_test", srcs = ["bad_server_response_test.cc"], @@ -78,7 +91,6 @@ grpc_cc_test( ":cq_verifier", "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -91,7 +103,6 @@ grpc_cc_test( ":cq_verifier", "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -104,7 +115,6 @@ grpc_cc_test( ":cq_verifier", "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -117,7 +127,6 @@ grpc_cc_test( ":cq_verifier", "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -130,7 +139,6 @@ grpc_cc_test( ":end2end_tests", "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -143,7 +151,6 @@ grpc_cc_test( ":cq_verifier", "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -156,7 +163,6 @@ grpc_cc_test( ":cq_verifier", "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -169,7 +175,6 @@ grpc_cc_test( ":cq_verifier", "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -190,7 +195,6 @@ grpc_cc_test( "//:gpr", "//:grpc", "//:tsi", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/end2end/bad_server_response_test.cc b/test/core/end2end/bad_server_response_test.cc index f7396a16845..2d74b6b77b3 100644 --- a/test/core/end2end/bad_server_response_test.cc +++ b/test/core/end2end/bad_server_response_test.cc @@ -65,7 +65,7 @@ #define HTTP1_DETAIL_MSG "Trying to connect an http1.x server" -/* TODO(zyc) Check the content of incomming data instead of using this length */ +/* TODO(zyc) Check the content of incoming data instead of using this length */ /* The 'bad' server will start sending responses after reading this amount of * data from the client. */ #define SERVER_INCOMING_DATA_LENGTH_LOWER_THRESHOLD (size_t)200 @@ -126,7 +126,8 @@ static void handle_read(void* arg, grpc_error* error) { SERVER_INCOMING_DATA_LENGTH_LOWER_THRESHOLD) { handle_write(); } else { - grpc_endpoint_read(state.tcp, &state.temp_incoming_buffer, &on_read); + grpc_endpoint_read(state.tcp, &state.temp_incoming_buffer, &on_read, + /*urgent=*/false); } } @@ -142,7 +143,8 @@ static void on_connect(void* arg, grpc_endpoint* tcp, state.tcp = tcp; state.incoming_data_length = 0; grpc_endpoint_add_to_pollset(tcp, server->pollset); - grpc_endpoint_read(tcp, &state.temp_incoming_buffer, &on_read); + grpc_endpoint_read(tcp, &state.temp_incoming_buffer, &on_read, + /*urgent=*/false); } static gpr_timespec n_sec_deadline(int seconds) { @@ -248,7 +250,7 @@ static void actually_poll_server(void* arg) { if (done || gpr_time_cmp(time_left, gpr_time_0(GPR_TIMESPAN)) < 0) { break; } - test_tcp_server_poll(pa->server, 1); + test_tcp_server_poll(pa->server, 1000); } gpr_event_set(pa->signal_when_done, (void*)1); gpr_free(pa); @@ -302,7 +304,7 @@ static void run_test(const char* response_payload, } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); /* status defined in hpack static table */ diff --git a/test/core/end2end/connection_refused_test.cc b/test/core/end2end/connection_refused_test.cc index 33812ec8e5e..446e7b045a1 100644 --- a/test/core/end2end/connection_refused_test.cc +++ b/test/core/end2end/connection_refused_test.cc @@ -28,7 +28,6 @@ #include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/transport/metadata.h" -#include "src/core/lib/transport/service_config.h" #include "test/core/end2end/cq_verifier.h" #include "test/core/util/port.h" @@ -142,7 +141,7 @@ static void run_test(bool wait_for_ready, bool use_service_config) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); run_test(false /* wait_for_ready */, false /* use_service_config */); run_test(true /* wait_for_ready */, false /* use_service_config */); run_test(true /* wait_for_ready */, true /* use_service_config */); diff --git a/test/core/end2end/dualstack_socket_test.cc b/test/core/end2end/dualstack_socket_test.cc index eb1d043fb29..330af8fce07 100644 --- a/test/core/end2end/dualstack_socket_test.cc +++ b/test/core/end2end/dualstack_socket_test.cc @@ -303,7 +303,7 @@ int external_dns_works(const char* host) { int main(int argc, char** argv) { int do_ipv6 = 1; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); if (!grpc_ipv6_loopback_available()) { diff --git a/test/core/end2end/end2end_nosec_tests.cc b/test/core/end2end/end2end_nosec_tests.cc index c6a4005fb3e..3ab55527da6 100644 --- a/test/core/end2end/end2end_nosec_tests.cc +++ b/test/core/end2end/end2end_nosec_tests.cc @@ -70,6 +70,8 @@ extern void filter_call_init_fails(grpc_end2end_test_config config); extern void filter_call_init_fails_pre_init(void); extern void filter_causes_close(grpc_end2end_test_config config); extern void filter_causes_close_pre_init(void); +extern void filter_context(grpc_end2end_test_config config); +extern void filter_context_pre_init(void); extern void filter_latency(grpc_end2end_test_config config); extern void filter_latency_pre_init(void); extern void filter_status_code(grpc_end2end_test_config config); @@ -98,8 +100,6 @@ extern void max_message_length(grpc_end2end_test_config config); extern void max_message_length_pre_init(void); extern void negative_deadline(grpc_end2end_test_config config); extern void negative_deadline_pre_init(void); -extern void network_status_change(grpc_end2end_test_config config); -extern void network_status_change_pre_init(void); extern void no_error_on_hotpath(grpc_end2end_test_config config); extern void no_error_on_hotpath_pre_init(void); extern void no_logging(grpc_end2end_test_config config); @@ -209,6 +209,7 @@ void grpc_end2end_tests_pre_init(void) { empty_batch_pre_init(); filter_call_init_fails_pre_init(); filter_causes_close_pre_init(); + filter_context_pre_init(); filter_latency_pre_init(); filter_status_code_pre_init(); graceful_server_shutdown_pre_init(); @@ -223,7 +224,6 @@ void grpc_end2end_tests_pre_init(void) { max_connection_idle_pre_init(); max_message_length_pre_init(); negative_deadline_pre_init(); - network_status_change_pre_init(); no_error_on_hotpath_pre_init(); no_logging_pre_init(); no_op_pre_init(); @@ -295,6 +295,7 @@ void grpc_end2end_tests(int argc, char **argv, empty_batch(config); filter_call_init_fails(config); filter_causes_close(config); + filter_context(config); filter_latency(config); filter_status_code(config); graceful_server_shutdown(config); @@ -309,7 +310,6 @@ void grpc_end2end_tests(int argc, char **argv, max_connection_idle(config); max_message_length(config); negative_deadline(config); - network_status_change(config); no_error_on_hotpath(config); no_logging(config); no_op(config); @@ -436,6 +436,10 @@ void grpc_end2end_tests(int argc, char **argv, filter_causes_close(config); continue; } + if (0 == strcmp("filter_context", argv[i])) { + filter_context(config); + continue; + } if (0 == strcmp("filter_latency", argv[i])) { filter_latency(config); continue; @@ -492,10 +496,6 @@ void grpc_end2end_tests(int argc, char **argv, negative_deadline(config); continue; } - if (0 == strcmp("network_status_change", argv[i])) { - network_status_change(config); - continue; - } if (0 == strcmp("no_error_on_hotpath", argv[i])) { no_error_on_hotpath(config); continue; diff --git a/test/core/end2end/end2end_tests.cc b/test/core/end2end/end2end_tests.cc index 7748a39cb59..b680da4433f 100644 --- a/test/core/end2end/end2end_tests.cc +++ b/test/core/end2end/end2end_tests.cc @@ -72,6 +72,8 @@ extern void filter_call_init_fails(grpc_end2end_test_config config); extern void filter_call_init_fails_pre_init(void); extern void filter_causes_close(grpc_end2end_test_config config); extern void filter_causes_close_pre_init(void); +extern void filter_context(grpc_end2end_test_config config); +extern void filter_context_pre_init(void); extern void filter_latency(grpc_end2end_test_config config); extern void filter_latency_pre_init(void); extern void filter_status_code(grpc_end2end_test_config config); @@ -100,8 +102,6 @@ extern void max_message_length(grpc_end2end_test_config config); extern void max_message_length_pre_init(void); extern void negative_deadline(grpc_end2end_test_config config); extern void negative_deadline_pre_init(void); -extern void network_status_change(grpc_end2end_test_config config); -extern void network_status_change_pre_init(void); extern void no_error_on_hotpath(grpc_end2end_test_config config); extern void no_error_on_hotpath_pre_init(void); extern void no_logging(grpc_end2end_test_config config); @@ -212,6 +212,7 @@ void grpc_end2end_tests_pre_init(void) { empty_batch_pre_init(); filter_call_init_fails_pre_init(); filter_causes_close_pre_init(); + filter_context_pre_init(); filter_latency_pre_init(); filter_status_code_pre_init(); graceful_server_shutdown_pre_init(); @@ -226,7 +227,6 @@ void grpc_end2end_tests_pre_init(void) { max_connection_idle_pre_init(); max_message_length_pre_init(); negative_deadline_pre_init(); - network_status_change_pre_init(); no_error_on_hotpath_pre_init(); no_logging_pre_init(); no_op_pre_init(); @@ -299,6 +299,7 @@ void grpc_end2end_tests(int argc, char **argv, empty_batch(config); filter_call_init_fails(config); filter_causes_close(config); + filter_context(config); filter_latency(config); filter_status_code(config); graceful_server_shutdown(config); @@ -313,7 +314,6 @@ void grpc_end2end_tests(int argc, char **argv, max_connection_idle(config); max_message_length(config); negative_deadline(config); - network_status_change(config); no_error_on_hotpath(config); no_logging(config); no_op(config); @@ -444,6 +444,10 @@ void grpc_end2end_tests(int argc, char **argv, filter_causes_close(config); continue; } + if (0 == strcmp("filter_context", argv[i])) { + filter_context(config); + continue; + } if (0 == strcmp("filter_latency", argv[i])) { filter_latency(config); continue; @@ -500,10 +504,6 @@ void grpc_end2end_tests(int argc, char **argv, negative_deadline(config); continue; } - if (0 == strcmp("network_status_change", argv[i])) { - network_status_change(config); - continue; - } if (0 == strcmp("no_error_on_hotpath", argv[i])) { no_error_on_hotpath(config); continue; diff --git a/test/core/end2end/fixtures/h2_census.cc b/test/core/end2end/fixtures/h2_census.cc index 29b1d6d8839..60442ddcc77 100644 --- a/test/core/end2end/fixtures/h2_census.cc +++ b/test/core/end2end/fixtures/h2_census.cc @@ -118,7 +118,7 @@ static grpc_end2end_test_config configs[] = { int main(int argc, char** argv) { size_t i; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_end2end_tests_pre_init(); grpc_init(); diff --git a/test/core/end2end/fixtures/h2_compress.cc b/test/core/end2end/fixtures/h2_compress.cc index 4aaadf715c0..f97192fecaa 100644 --- a/test/core/end2end/fixtures/h2_compress.cc +++ b/test/core/end2end/fixtures/h2_compress.cc @@ -29,6 +29,7 @@ #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/connected_channel.h" +#include "src/core/lib/compression/compression_args.h" #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/server.h" @@ -118,7 +119,7 @@ static grpc_end2end_test_config configs[] = { int main(int argc, char** argv) { size_t i; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_end2end_tests_pre_init(); grpc_init(); diff --git a/test/core/end2end/fixtures/h2_fakesec.cc b/test/core/end2end/fixtures/h2_fakesec.cc index a653d7c477f..ad83aab39f4 100644 --- a/test/core/end2end/fixtures/h2_fakesec.cc +++ b/test/core/end2end/fixtures/h2_fakesec.cc @@ -142,7 +142,7 @@ static grpc_end2end_test_config configs[] = { int main(int argc, char** argv) { size_t i; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_end2end_tests_pre_init(); grpc_init(); diff --git a/test/core/end2end/fixtures/h2_fd.cc b/test/core/end2end/fixtures/h2_fd.cc index 52be0f7fd51..5d06bd5f3be 100644 --- a/test/core/end2end/fixtures/h2_fd.cc +++ b/test/core/end2end/fixtures/h2_fd.cc @@ -104,7 +104,7 @@ static grpc_end2end_test_config configs[] = { int main(int argc, char** argv) { size_t i; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_end2end_tests_pre_init(); grpc_init(); diff --git a/test/core/end2end/fixtures/h2_full+pipe.cc b/test/core/end2end/fixtures/h2_full+pipe.cc index c5329640dcd..6d559c4e516 100644 --- a/test/core/end2end/fixtures/h2_full+pipe.cc +++ b/test/core/end2end/fixtures/h2_full+pipe.cc @@ -105,7 +105,7 @@ int main(int argc, char** argv) { grpc_allow_specialized_wakeup_fd = 0; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_end2end_tests_pre_init(); grpc_init(); diff --git a/test/core/end2end/fixtures/h2_full+trace.cc b/test/core/end2end/fixtures/h2_full+trace.cc index ba7a7803049..ce8f6bf13a5 100644 --- a/test/core/end2end/fixtures/h2_full+trace.cc +++ b/test/core/end2end/fixtures/h2_full+trace.cc @@ -113,7 +113,16 @@ int main(int argc, char** argv) { g_fixture_slowdown_factor = 10; #endif - grpc_test_init(argc, argv); +#ifdef GPR_WINDOWS + /* on Windows, writing logs to stderr is very slow + when stderr is redirected to a disk file. + The "trace" tests fixtures generates large amount + of logs, so setting a buffer for stderr prevents certain + test cases from timing out. */ + setvbuf(stderr, NULL, _IOLBF, 1024); +#endif + + grpc::testing::TestEnvironment env(argc, argv); grpc_end2end_tests_pre_init(); grpc_init(); diff --git a/test/core/end2end/fixtures/h2_full+workarounds.cc b/test/core/end2end/fixtures/h2_full+workarounds.cc index 78da8418f6c..cb0f7d275b3 100644 --- a/test/core/end2end/fixtures/h2_full+workarounds.cc +++ b/test/core/end2end/fixtures/h2_full+workarounds.cc @@ -114,7 +114,7 @@ static grpc_end2end_test_config configs[] = { int main(int argc, char** argv) { size_t i; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_end2end_tests_pre_init(); grpc_init(); diff --git a/test/core/end2end/fixtures/h2_full.cc b/test/core/end2end/fixtures/h2_full.cc index 0c826b68368..c0d21288c7e 100644 --- a/test/core/end2end/fixtures/h2_full.cc +++ b/test/core/end2end/fixtures/h2_full.cc @@ -97,7 +97,7 @@ static grpc_end2end_test_config configs[] = { int main(int argc, char** argv) { size_t i; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_end2end_tests_pre_init(); grpc_init(); diff --git a/test/core/end2end/fixtures/h2_http_proxy.cc b/test/core/end2end/fixtures/h2_http_proxy.cc index 0af8a29a152..9b6a81494e1 100644 --- a/test/core/end2end/fixtures/h2_http_proxy.cc +++ b/test/core/end2end/fixtures/h2_http_proxy.cc @@ -120,7 +120,7 @@ static grpc_end2end_test_config configs[] = { int main(int argc, char** argv) { size_t i; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_end2end_tests_pre_init(); grpc_init(); diff --git a/test/core/end2end/fixtures/h2_local_ipv4.cc b/test/core/end2end/fixtures/h2_local_ipv4.cc new file mode 100644 index 00000000000..f6996bf6be3 --- /dev/null +++ b/test/core/end2end/fixtures/h2_local_ipv4.cc @@ -0,0 +1,72 @@ +/* + * + * 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 + +#include + +#include "src/core/lib/gpr/host_port.h" +#include "test/core/end2end/end2end_tests.h" +#include "test/core/end2end/fixtures/local_util.h" +#include "test/core/util/port.h" +#include "test/core/util/test_config.h" + +static grpc_end2end_test_fixture chttp2_create_fixture_fullstack_ipv4( + grpc_channel_args* client_args, grpc_channel_args* server_args) { + grpc_end2end_test_fixture f = + grpc_end2end_local_chttp2_create_fixture_fullstack(); + int port = grpc_pick_unused_port_or_die(); + gpr_join_host_port( + &static_cast(f.fixture_data) + ->localaddr, + "127.0.0.1", port); + return f; +} + +static void chttp2_init_client_fullstack_ipv4(grpc_end2end_test_fixture* f, + grpc_channel_args* client_args) { + grpc_end2end_local_chttp2_init_client_fullstack(f, client_args, LOCAL_TCP); +} + +static void chttp2_init_server_fullstack_ipv4(grpc_end2end_test_fixture* f, + grpc_channel_args* client_args) { + grpc_end2end_local_chttp2_init_server_fullstack(f, client_args, LOCAL_TCP); +} + +/* All test configurations */ +static grpc_end2end_test_config configs[] = { + {"chttp2/fullstack_local_ipv4", + FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION | + FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL | + FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER | + FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS, + nullptr, chttp2_create_fixture_fullstack_ipv4, + chttp2_init_client_fullstack_ipv4, chttp2_init_server_fullstack_ipv4, + grpc_end2end_local_chttp2_tear_down_fullstack}}; + +int main(int argc, char** argv) { + size_t i; + grpc::testing::TestEnvironment env(argc, argv); + grpc_end2end_tests_pre_init(); + grpc_init(); + for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) { + grpc_end2end_tests(argc, argv, configs[i]); + } + grpc_shutdown(); + return 0; +} diff --git a/test/core/end2end/fixtures/h2_local_ipv6.cc b/test/core/end2end/fixtures/h2_local_ipv6.cc new file mode 100644 index 00000000000..e360727ca82 --- /dev/null +++ b/test/core/end2end/fixtures/h2_local_ipv6.cc @@ -0,0 +1,72 @@ +/* + * + * 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 + +#include + +#include "src/core/lib/gpr/host_port.h" +#include "test/core/end2end/end2end_tests.h" +#include "test/core/end2end/fixtures/local_util.h" +#include "test/core/util/port.h" +#include "test/core/util/test_config.h" + +static grpc_end2end_test_fixture chttp2_create_fixture_fullstack_ipv6( + grpc_channel_args* client_args, grpc_channel_args* server_args) { + grpc_end2end_test_fixture f = + grpc_end2end_local_chttp2_create_fixture_fullstack(); + int port = grpc_pick_unused_port_or_die(); + gpr_join_host_port( + &static_cast(f.fixture_data) + ->localaddr, + "[::1]", port); + return f; +} + +static void chttp2_init_client_fullstack_ipv6(grpc_end2end_test_fixture* f, + grpc_channel_args* client_args) { + grpc_end2end_local_chttp2_init_client_fullstack(f, client_args, LOCAL_TCP); +} + +static void chttp2_init_server_fullstack_ipv6(grpc_end2end_test_fixture* f, + grpc_channel_args* client_args) { + grpc_end2end_local_chttp2_init_server_fullstack(f, client_args, LOCAL_TCP); +} + +/* All test configurations */ +static grpc_end2end_test_config configs[] = { + {"chttp2/fullstack_local_ipv6", + FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION | + FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL | + FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER | + FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS, + nullptr, chttp2_create_fixture_fullstack_ipv6, + chttp2_init_client_fullstack_ipv6, chttp2_init_server_fullstack_ipv6, + grpc_end2end_local_chttp2_tear_down_fullstack}}; + +int main(int argc, char** argv) { + size_t i; + grpc::testing::TestEnvironment env(argc, argv); + grpc_end2end_tests_pre_init(); + grpc_init(); + for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) { + grpc_end2end_tests(argc, argv, configs[i]); + } + grpc_shutdown(); + return 0; +} diff --git a/test/core/end2end/fixtures/h2_local_uds.cc b/test/core/end2end/fixtures/h2_local_uds.cc new file mode 100644 index 00000000000..f1bce213dc2 --- /dev/null +++ b/test/core/end2end/fixtures/h2_local_uds.cc @@ -0,0 +1,71 @@ +/* + * + * 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 + +#include + +#include "test/core/end2end/end2end_tests.h" +#include "test/core/end2end/fixtures/local_util.h" +#include "test/core/util/test_config.h" + +static int unique = 1; + +static grpc_end2end_test_fixture chttp2_create_fixture_fullstack_uds( + grpc_channel_args* client_args, grpc_channel_args* server_args) { + grpc_end2end_test_fixture f = + grpc_end2end_local_chttp2_create_fixture_fullstack(); + gpr_asprintf( + &static_cast(f.fixture_data) + ->localaddr, + "unix:/tmp/grpc_fullstack_test.%d.%d", getpid(), unique++); + return f; +} + +static void chttp2_init_client_fullstack_uds(grpc_end2end_test_fixture* f, + grpc_channel_args* client_args) { + grpc_end2end_local_chttp2_init_client_fullstack(f, client_args, UDS); +} + +static void chttp2_init_server_fullstack_uds(grpc_end2end_test_fixture* f, + grpc_channel_args* client_args) { + grpc_end2end_local_chttp2_init_server_fullstack(f, client_args, UDS); +} + +/* All test configurations */ +static grpc_end2end_test_config configs[] = { + {"chttp2/fullstack_local_uds", + FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION | + FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL | + FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER | + FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS, + nullptr, chttp2_create_fixture_fullstack_uds, + chttp2_init_client_fullstack_uds, chttp2_init_server_fullstack_uds, + grpc_end2end_local_chttp2_tear_down_fullstack}}; + +int main(int argc, char** argv) { + size_t i; + grpc::testing::TestEnvironment env(argc, argv); + grpc_end2end_tests_pre_init(); + grpc_init(); + for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) { + grpc_end2end_tests(argc, argv, configs[i]); + } + grpc_shutdown(); + return 0; +} diff --git a/test/core/end2end/fixtures/h2_oauth2.cc b/test/core/end2end/fixtures/h2_oauth2.cc index 37397d6450a..113a6b11732 100644 --- a/test/core/end2end/fixtures/h2_oauth2.cc +++ b/test/core/end2end/fixtures/h2_oauth2.cc @@ -224,7 +224,7 @@ static grpc_end2end_test_config configs[] = { int main(int argc, char** argv) { size_t i; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_end2end_tests_pre_init(); grpc_init(); diff --git a/test/core/end2end/fixtures/h2_proxy.cc b/test/core/end2end/fixtures/h2_proxy.cc index a32000061a3..e334396ea7c 100644 --- a/test/core/end2end/fixtures/h2_proxy.cc +++ b/test/core/end2end/fixtures/h2_proxy.cc @@ -124,7 +124,7 @@ static grpc_end2end_test_config configs[] = { int main(int argc, char** argv) { size_t i; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_end2end_tests_pre_init(); grpc_init(); diff --git a/test/core/end2end/fixtures/h2_sockpair+trace.cc b/test/core/end2end/fixtures/h2_sockpair+trace.cc index eb71e24c772..4494d5c4746 100644 --- a/test/core/end2end/fixtures/h2_sockpair+trace.cc +++ b/test/core/end2end/fixtures/h2_sockpair+trace.cc @@ -53,7 +53,7 @@ static void server_setup_transport(void* ts, grpc_transport* transport) { grpc_endpoint_pair* sfd = static_cast(f->fixture_data); grpc_endpoint_add_to_pollset(sfd->server, grpc_cq_pollset(f->cq)); grpc_server_setup_transport(f->server, transport, nullptr, - grpc_server_get_channel_args(f->server), 0); + grpc_server_get_channel_args(f->server), nullptr); } typedef struct { @@ -140,7 +140,16 @@ int main(int argc, char** argv) { g_fixture_slowdown_factor = 10; #endif - grpc_test_init(argc, argv); +#ifdef GPR_WINDOWS + /* on Windows, writing logs to stderr is very slow + when stderr is redirected to a disk file. + The "trace" tests fixtures generates large amount + of logs, so setting a buffer for stderr prevents certain + test cases from timing out. */ + setvbuf(stderr, NULL, _IOLBF, 1024); +#endif + + grpc::testing::TestEnvironment env(argc, argv); grpc_end2end_tests_pre_init(); grpc_init(); diff --git a/test/core/end2end/fixtures/h2_sockpair.cc b/test/core/end2end/fixtures/h2_sockpair.cc index 904bda54586..77bce7ebb30 100644 --- a/test/core/end2end/fixtures/h2_sockpair.cc +++ b/test/core/end2end/fixtures/h2_sockpair.cc @@ -47,7 +47,7 @@ static void server_setup_transport(void* ts, grpc_transport* transport) { grpc_endpoint_pair* sfd = static_cast(f->fixture_data); grpc_endpoint_add_to_pollset(sfd->server, grpc_cq_pollset(f->cq)); grpc_server_setup_transport(f->server, transport, nullptr, - grpc_server_get_channel_args(f->server), 0); + grpc_server_get_channel_args(f->server), nullptr); } typedef struct { @@ -126,7 +126,7 @@ static grpc_end2end_test_config configs[] = { int main(int argc, char** argv) { size_t i; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_end2end_tests_pre_init(); grpc_init(); diff --git a/test/core/end2end/fixtures/h2_sockpair_1byte.cc b/test/core/end2end/fixtures/h2_sockpair_1byte.cc index 45f7f254ac5..ac37841dc48 100644 --- a/test/core/end2end/fixtures/h2_sockpair_1byte.cc +++ b/test/core/end2end/fixtures/h2_sockpair_1byte.cc @@ -47,7 +47,7 @@ static void server_setup_transport(void* ts, grpc_transport* transport) { grpc_endpoint_pair* sfd = static_cast(f->fixture_data); grpc_endpoint_add_to_pollset(sfd->server, grpc_cq_pollset(f->cq)); grpc_server_setup_transport(f->server, transport, nullptr, - grpc_server_get_channel_args(f->server), 0); + grpc_server_get_channel_args(f->server), nullptr); } typedef struct { @@ -140,7 +140,7 @@ int main(int argc, char** argv) { g_fixture_slowdown_factor = 2; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_end2end_tests_pre_init(); grpc_init(); diff --git a/test/core/end2end/fixtures/h2_spiffe.cc b/test/core/end2end/fixtures/h2_spiffe.cc new file mode 100644 index 00000000000..9ab796ea429 --- /dev/null +++ b/test/core/end2end/fixtures/h2_spiffe.cc @@ -0,0 +1,290 @@ +/* + * + * 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 +#include + +#include +#include +#include + +#include +#include "src/core/lib/channel/channel_args.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/gprpp/inlined_vector.h" +#include "src/core/lib/gprpp/thd.h" +#include "src/core/lib/security/credentials/credentials.h" +#include "src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h" +#include "test/core/end2end/data/ssl_test_data.h" +#include "test/core/util/port.h" +#include "test/core/util/test_config.h" + +typedef grpc_core::InlinedVector ThreadList; + +typedef struct fullstack_secure_fixture_data { + char* localaddr; + ThreadList thd_list; +} fullstack_secure_fixture_data; + +static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack( + grpc_channel_args* client_args, grpc_channel_args* server_args) { + grpc_end2end_test_fixture f; + int port = grpc_pick_unused_port_or_die(); + fullstack_secure_fixture_data* ffd = + grpc_core::New(); + memset(&f, 0, sizeof(f)); + gpr_join_host_port(&ffd->localaddr, "localhost", port); + 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; +} + +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 == nullptr); + cb(user_data, nullptr, 0, nullptr, 0, GRPC_STATUS_UNAUTHENTICATED, nullptr); +} + +static void chttp2_init_client_secure_fullstack( + grpc_end2end_test_fixture* f, grpc_channel_args* client_args, + grpc_channel_credentials* creds) { + fullstack_secure_fixture_data* ffd = + static_cast(f->fixture_data); + f->client = + grpc_secure_channel_create(creds, ffd->localaddr, client_args, nullptr); + GPR_ASSERT(f->client != nullptr); + grpc_channel_credentials_release(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 = + static_cast(f->fixture_data); + if (f->server) { + grpc_server_destroy(f->server); + } + f->server = grpc_server_create(server_args, nullptr); + grpc_server_register_completion_queue(f->server, f->cq, nullptr); + 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); +} + +void chttp2_tear_down_secure_fullstack(grpc_end2end_test_fixture* f) { + fullstack_secure_fixture_data* ffd = + static_cast(f->fixture_data); + for (size_t ind = 0; ind < ffd->thd_list.size(); ind++) { + ffd->thd_list[ind].Join(); + } + gpr_free(ffd->localaddr); + grpc_core::Delete(ffd); +} + +// Application-provided callback for server authorization check. +static void server_authz_check_cb(void* user_data) { + grpc_tls_server_authorization_check_arg* check_arg = + static_cast(user_data); + GPR_ASSERT(check_arg != nullptr); + // result = 1 indicates the server authorization check passes. + // Normally, the application code should resort to mapping information + // between server identity and target name to derive the result. + // For this test, we directly return 1 for simplicity. + check_arg->success = 1; + check_arg->status = GRPC_STATUS_OK; + check_arg->cb(check_arg); +} + +// Asynchronous implementation of schedule field in +// grpc_server_authorization_check_config. +static int server_authz_check_async( + void* config_user_data, grpc_tls_server_authorization_check_arg* arg) { + fullstack_secure_fixture_data* ffd = + static_cast(config_user_data); + ffd->thd_list.push_back( + grpc_core::Thread("h2_spiffe_test", &server_authz_check_cb, arg)); + ffd->thd_list[ffd->thd_list.size() - 1].Start(); + return 1; +} + +// Synchronous implementation of schedule field in +// grpc_tls_credential_reload_config instance that is a part of client-side +// grpc_tls_credentials_options instance. +static int client_cred_reload_sync(void* config_user_data, + grpc_tls_credential_reload_arg* arg) { + grpc_ssl_pem_key_cert_pair** key_cert_pair = + static_cast( + gpr_zalloc(sizeof(grpc_ssl_pem_key_cert_pair*))); + key_cert_pair[0] = static_cast( + gpr_zalloc(sizeof(grpc_ssl_pem_key_cert_pair))); + key_cert_pair[0]->private_key = gpr_strdup(test_server1_key); + key_cert_pair[0]->cert_chain = gpr_strdup(test_server1_cert); + if (arg->key_materials_config->pem_key_cert_pair_list().empty()) { + grpc_tls_key_materials_config_set_key_materials( + arg->key_materials_config, gpr_strdup(test_root_cert), + (const grpc_ssl_pem_key_cert_pair**)key_cert_pair, 1); + } + // new credential has been reloaded. + arg->status = GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW; + return 0; +} + +// Synchronous implementation of schedule field in +// grpc_tls_credential_reload_config instance that is a part of server-side +// grpc_tls_credentials_options instance. +static int server_cred_reload_sync(void* config_user_data, + grpc_tls_credential_reload_arg* arg) { + grpc_ssl_pem_key_cert_pair** key_cert_pair = + static_cast( + gpr_zalloc(sizeof(grpc_ssl_pem_key_cert_pair*))); + key_cert_pair[0] = static_cast( + gpr_zalloc(sizeof(grpc_ssl_pem_key_cert_pair))); + key_cert_pair[0]->private_key = gpr_strdup(test_server1_key); + key_cert_pair[0]->cert_chain = gpr_strdup(test_server1_cert); + GPR_ASSERT(arg != nullptr); + GPR_ASSERT(arg->key_materials_config != nullptr); + GPR_ASSERT(arg->key_materials_config->pem_key_cert_pair_list().data() != + nullptr); + if (arg->key_materials_config->pem_key_cert_pair_list().empty()) { + grpc_tls_key_materials_config_set_key_materials( + arg->key_materials_config, gpr_strdup(test_root_cert), + (const grpc_ssl_pem_key_cert_pair**)key_cert_pair, 1); + } + // new credential has been reloaded. + arg->status = GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW; + return 0; +} + +// Create a SPIFFE channel credential. +static grpc_channel_credentials* create_spiffe_channel_credentials( + fullstack_secure_fixture_data* ffd) { + grpc_tls_credentials_options* options = grpc_tls_credentials_options_create(); + /* Set credential reload config. */ + grpc_tls_credential_reload_config* reload_config = + grpc_tls_credential_reload_config_create(nullptr, client_cred_reload_sync, + nullptr, nullptr); + grpc_tls_credentials_options_set_credential_reload_config(options, + reload_config); + /* Set server authorization check config. */ + grpc_tls_server_authorization_check_config* check_config = + grpc_tls_server_authorization_check_config_create( + ffd, server_authz_check_async, nullptr, nullptr); + grpc_tls_credentials_options_set_server_authorization_check_config( + options, check_config); + /* Create SPIFFE channel credentials. */ + grpc_channel_credentials* creds = grpc_tls_spiffe_credentials_create(options); + return creds; +} + +// Create a SPIFFE server credential. +static grpc_server_credentials* create_spiffe_server_credentials() { + grpc_tls_credentials_options* options = grpc_tls_credentials_options_create(); + /* Set credential reload config. */ + grpc_tls_credential_reload_config* reload_config = + grpc_tls_credential_reload_config_create(nullptr, server_cred_reload_sync, + nullptr, nullptr); + grpc_tls_credentials_options_set_credential_reload_config(options, + reload_config); + /* Set client certificate request type. */ + grpc_tls_credentials_options_set_cert_request_type( + options, GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY); + grpc_server_credentials* creds = + grpc_tls_spiffe_server_credentials_create(options); + return creds; +} + +static void chttp2_init_client(grpc_end2end_test_fixture* f, + grpc_channel_args* client_args) { + grpc_channel_credentials* ssl_creds = create_spiffe_channel_credentials( + static_cast(f->fixture_data)); + grpc_arg ssl_name_override = { + GRPC_ARG_STRING, + const_cast(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG), + {const_cast("foo.test.google.fr")}}; + 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_channel_args_destroy(new_client_args); +} + +static int fail_server_auth_check(grpc_channel_args* server_args) { + size_t i; + if (server_args == nullptr) 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) { + return 1; + } + } + return 0; +} + +static void chttp2_init_server(grpc_end2end_test_fixture* f, + grpc_channel_args* server_args) { + grpc_server_credentials* ssl_creds = create_spiffe_server_credentials(); + if (fail_server_auth_check(server_args)) { + grpc_auth_metadata_processor processor = {process_auth_failure, nullptr, + nullptr}; + grpc_server_credentials_set_auth_metadata_processor(ssl_creds, processor); + } + chttp2_init_server_secure_fullstack(f, server_args, ssl_creds); +} + +static grpc_end2end_test_config configs[] = { + /* client sync reload async authz + server sync reload. */ + {"chttp2/simple_ssl_fullstack", + FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION | + FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS | + FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL | + FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER, + "foo.test.google.fr", chttp2_create_fixture_secure_fullstack, + chttp2_init_client, chttp2_init_server, chttp2_tear_down_secure_fullstack}, +}; + +int main(int argc, char** argv) { + FILE* roots_file; + size_t roots_size = strlen(test_root_cert); + char* roots_filename; + grpc_test_init(argc, argv); + grpc_end2end_tests_pre_init(); + /* Set the SSL roots env var. */ + roots_file = gpr_tmpfile("chttp2_simple_ssl_fullstack_test", &roots_filename); + GPR_ASSERT(roots_filename != nullptr); + GPR_ASSERT(roots_file != nullptr); + GPR_ASSERT(fwrite(test_root_cert, 1, roots_size, roots_file) == roots_size); + fclose(roots_file); + gpr_setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, roots_filename); + grpc_init(); + for (size_t ind = 0; ind < sizeof(configs) / sizeof(*configs); ind++) { + grpc_end2end_tests(argc, argv, configs[ind]); + } + grpc_shutdown(); + /* Cleanup. */ + remove(roots_filename); + gpr_free(roots_filename); + return 0; +} diff --git a/test/core/end2end/fixtures/h2_ssl.cc b/test/core/end2end/fixtures/h2_ssl.cc index 4d6c8157164..1fcd785e251 100644 --- a/test/core/end2end/fixtures/h2_ssl.cc +++ b/test/core/end2end/fixtures/h2_ssl.cc @@ -158,7 +158,7 @@ int main(int argc, char** argv) { size_t roots_size = strlen(test_root_cert); char* roots_filename; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_end2end_tests_pre_init(); /* Set the SSL roots env var. */ diff --git a/test/core/end2end/fixtures/h2_ssl_cred_reload.cc b/test/core/end2end/fixtures/h2_ssl_cred_reload.cc new file mode 100644 index 00000000000..04d876ce3cd --- /dev/null +++ b/test/core/end2end/fixtures/h2_ssl_cred_reload.cc @@ -0,0 +1,208 @@ +/* + * + * 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 +#include + +#include +#include + +#include "src/core/lib/channel/channel_args.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" + +typedef struct fullstack_secure_fixture_data { + char* localaddr; + bool server_credential_reloaded; +} fullstack_secure_fixture_data; + +static grpc_ssl_certificate_config_reload_status +ssl_server_certificate_config_callback( + void* user_data, grpc_ssl_server_certificate_config** config) { + if (config == nullptr) { + return GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_FAIL; + } + fullstack_secure_fixture_data* ffd = + static_cast(user_data); + if (!ffd->server_credential_reloaded) { + grpc_ssl_pem_key_cert_pair pem_key_cert_pair = {test_server1_key, + test_server1_cert}; + *config = grpc_ssl_server_certificate_config_create(test_root_cert, + &pem_key_cert_pair, 1); + ffd->server_credential_reloaded = true; + return GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW; + } else { + return GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED; + } +} + +static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack( + grpc_channel_args* client_args, grpc_channel_args* server_args) { + grpc_end2end_test_fixture f; + int port = grpc_pick_unused_port_or_die(); + fullstack_secure_fixture_data* ffd = + static_cast( + gpr_malloc(sizeof(fullstack_secure_fixture_data))); + memset(&f, 0, sizeof(f)); + gpr_join_host_port(&ffd->localaddr, "localhost", port); + + 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; +} + +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 == nullptr); + cb(user_data, nullptr, 0, nullptr, 0, GRPC_STATUS_UNAUTHENTICATED, nullptr); +} + +static void chttp2_init_client_secure_fullstack( + grpc_end2end_test_fixture* f, grpc_channel_args* client_args, + grpc_channel_credentials* creds) { + fullstack_secure_fixture_data* ffd = + static_cast(f->fixture_data); + f->client = + grpc_secure_channel_create(creds, ffd->localaddr, client_args, nullptr); + GPR_ASSERT(f->client != nullptr); + grpc_channel_credentials_release(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 = + static_cast(f->fixture_data); + if (f->server) { + grpc_server_destroy(f->server); + } + ffd->server_credential_reloaded = false; + f->server = grpc_server_create(server_args, nullptr); + grpc_server_register_completion_queue(f->server, f->cq, nullptr); + 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); +} + +void chttp2_tear_down_secure_fullstack(grpc_end2end_test_fixture* f) { + fullstack_secure_fixture_data* ffd = + static_cast(f->fixture_data); + gpr_free(ffd->localaddr); + gpr_free(ffd); +} + +static void chttp2_init_client_simple_ssl_secure_fullstack( + grpc_end2end_test_fixture* f, grpc_channel_args* client_args) { + grpc_channel_credentials* ssl_creds = + grpc_ssl_credentials_create(nullptr, nullptr, nullptr, nullptr); + grpc_arg ssl_name_override = { + GRPC_ARG_STRING, + const_cast(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG), + {const_cast("foo.test.google.fr")}}; + 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_channel_args_destroy(new_client_args); +} + +static int fail_server_auth_check(grpc_channel_args* server_args) { + size_t i; + if (server_args == nullptr) 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) { + 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_server_credentials_options* options = + grpc_ssl_server_credentials_create_options_using_config_fetcher( + GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE, + ssl_server_certificate_config_callback, f->fixture_data); + grpc_server_credentials* ssl_creds = + grpc_ssl_server_credentials_create_with_options(options); + if (fail_server_auth_check(server_args)) { + grpc_auth_metadata_processor processor = {process_auth_failure, nullptr, + nullptr}; + grpc_server_credentials_set_auth_metadata_processor(ssl_creds, processor); + } + chttp2_init_server_secure_fullstack(f, server_args, ssl_creds); +} + +/* All test configurations */ + +static grpc_end2end_test_config configs[] = { + {"chttp2/simple_ssl_fullstack", + FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION | + FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS | + FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL | + FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER, + "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}, +}; + +int main(int argc, char** argv) { + size_t i; + FILE* roots_file; + size_t roots_size = strlen(test_root_cert); + char* roots_filename; + + grpc::testing::TestEnvironment env(argc, argv); + grpc_end2end_tests_pre_init(); + + /* Set the SSL roots env var. */ + roots_file = gpr_tmpfile("chttp2_simple_ssl_fullstack_test", &roots_filename); + GPR_ASSERT(roots_filename != nullptr); + GPR_ASSERT(roots_file != nullptr); + GPR_ASSERT(fwrite(test_root_cert, 1, roots_size, roots_file) == roots_size); + fclose(roots_file); + gpr_setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, roots_filename); + + grpc_init(); + + for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) { + grpc_end2end_tests(argc, argv, configs[i]); + } + + grpc_shutdown(); + + /* Cleanup. */ + remove(roots_filename); + gpr_free(roots_filename); + + return 0; +} diff --git a/test/core/end2end/fixtures/h2_ssl_proxy.cc b/test/core/end2end/fixtures/h2_ssl_proxy.cc index 09cbf974b61..f1858079426 100644 --- a/test/core/end2end/fixtures/h2_ssl_proxy.cc +++ b/test/core/end2end/fixtures/h2_ssl_proxy.cc @@ -199,7 +199,7 @@ int main(int argc, char** argv) { size_t roots_size = strlen(test_root_cert); char* roots_filename; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_end2end_tests_pre_init(); /* Set the SSL roots env var. */ diff --git a/test/core/end2end/fixtures/h2_uds.cc b/test/core/end2end/fixtures/h2_uds.cc index 2c81c3d3622..f251bbd28c5 100644 --- a/test/core/end2end/fixtures/h2_uds.cc +++ b/test/core/end2end/fixtures/h2_uds.cc @@ -102,7 +102,7 @@ static grpc_end2end_test_config configs[] = { int main(int argc, char** argv) { size_t i; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_end2end_tests_pre_init(); grpc_init(); diff --git a/test/core/end2end/fixtures/http_proxy_fixture.cc b/test/core/end2end/fixtures/http_proxy_fixture.cc index b235c101652..6b5513f160e 100644 --- a/test/core/end2end/fixtures/http_proxy_fixture.cc +++ b/test/core/end2end/fixtures/http_proxy_fixture.cc @@ -78,7 +78,7 @@ struct grpc_end2end_http_proxy { // // proxy_connection structure is only accessed in the closures which are all -// scheduled under the same combiner lock. So there is is no need for a mutex to +// scheduled under the same combiner lock. So there is no need for a mutex to // protect this structure. typedef struct proxy_connection { grpc_end2end_http_proxy* proxy; @@ -271,7 +271,7 @@ static void on_client_read_done(void* arg, grpc_error* error) { } // Read more data. grpc_endpoint_read(conn->client_endpoint, &conn->client_read_buffer, - &conn->on_client_read_done); + &conn->on_client_read_done, /*urgent=*/false); } // Callback for reading data from the backend server, which will be @@ -302,7 +302,7 @@ static void on_server_read_done(void* arg, grpc_error* error) { } // Read more data. grpc_endpoint_read(conn->server_endpoint, &conn->server_read_buffer, - &conn->on_server_read_done); + &conn->on_server_read_done, /*urgent=*/false); } // Callback to write the HTTP response for the CONNECT request. @@ -323,9 +323,9 @@ static void on_write_response_done(void* arg, grpc_error* error) { proxy_connection_ref(conn, "server_read"); proxy_connection_unref(conn, "write_response"); grpc_endpoint_read(conn->client_endpoint, &conn->client_read_buffer, - &conn->on_client_read_done); + &conn->on_client_read_done, /*urgent=*/false); grpc_endpoint_read(conn->server_endpoint, &conn->server_read_buffer, - &conn->on_server_read_done); + &conn->on_server_read_done, /*urgent=*/false); } // Callback to connect to the backend server specified by the HTTP @@ -405,7 +405,7 @@ static void on_read_request_done(void* arg, grpc_error* error) { // If we're not done reading the request, read more data. if (conn->http_parser.state != GRPC_HTTP_BODY) { grpc_endpoint_read(conn->client_endpoint, &conn->client_read_buffer, - &conn->on_read_request_done); + &conn->on_read_request_done, /*urgent=*/false); return; } // Make sure we got a CONNECT request. @@ -503,7 +503,7 @@ static void on_accept(void* arg, grpc_endpoint* endpoint, grpc_http_parser_init(&conn->http_parser, GRPC_HTTP_REQUEST, &conn->http_request); grpc_endpoint_read(conn->client_endpoint, &conn->client_read_buffer, - &conn->on_read_request_done); + &conn->on_read_request_done, /*urgent=*/false); } // diff --git a/test/core/end2end/fixtures/inproc.cc b/test/core/end2end/fixtures/inproc.cc index be6eda84836..dadf3ef455d 100644 --- a/test/core/end2end/fixtures/inproc.cc +++ b/test/core/end2end/fixtures/inproc.cc @@ -83,7 +83,7 @@ static grpc_end2end_test_config configs[] = { int main(int argc, char** argv) { size_t i; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_end2end_tests_pre_init(); grpc_init(); diff --git a/test/core/end2end/fixtures/h2_local.cc b/test/core/end2end/fixtures/local_util.cc similarity index 61% rename from test/core/end2end/fixtures/h2_local.cc rename to test/core/end2end/fixtures/local_util.cc index cce8f1745a8..5f0b0300ac0 100644 --- a/test/core/end2end/fixtures/h2_local.cc +++ b/test/core/end2end/fixtures/local_util.cc @@ -1,6 +1,6 @@ /* * - * Copyright 2015 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. @@ -16,11 +16,7 @@ * */ -#include "test/core/end2end/end2end_tests.h" - -#include -#include -#include +#include "test/core/end2end/fixtures/local_util.h" #include #include @@ -34,39 +30,28 @@ #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/security/credentials/credentials.h" -#include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/server.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" -typedef struct fullstack_fixture_data { - char* localaddr; -} fullstack_fixture_data; - -static int unique = 1; - -static grpc_end2end_test_fixture chttp2_create_fixture_fullstack( - grpc_channel_args* client_args, grpc_channel_args* server_args) { +grpc_end2end_test_fixture grpc_end2end_local_chttp2_create_fixture_fullstack() { grpc_end2end_test_fixture f; - fullstack_fixture_data* ffd = static_cast( - gpr_malloc(sizeof(fullstack_fixture_data))); + grpc_end2end_local_fullstack_fixture_data* ffd = + static_cast( + gpr_malloc(sizeof(grpc_end2end_local_fullstack_fixture_data))); memset(&f, 0, sizeof(f)); - - gpr_asprintf(&ffd->localaddr, "unix:/tmp/grpc_fullstack_test.%d.%d", getpid(), - unique++); - 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; } -void chttp2_init_client_fullstack(grpc_end2end_test_fixture* f, - grpc_channel_args* client_args) { - grpc_channel_credentials* creds = grpc_local_credentials_create(UDS); - fullstack_fixture_data* ffd = - static_cast(f->fixture_data); +void grpc_end2end_local_chttp2_init_client_fullstack( + grpc_end2end_test_fixture* f, grpc_channel_args* client_args, + grpc_local_connect_type type) { + grpc_channel_credentials* creds = grpc_local_credentials_create(type); + grpc_end2end_local_fullstack_fixture_data* ffd = + static_cast(f->fixture_data); f->client = grpc_secure_channel_create(creds, ffd->localaddr, client_args, nullptr); GPR_ASSERT(f->client != nullptr); @@ -98,11 +83,12 @@ static void process_auth_failure(void* state, grpc_auth_context* ctx, cb(user_data, nullptr, 0, nullptr, 0, GRPC_STATUS_UNAUTHENTICATED, nullptr); } -void chttp2_init_server_fullstack(grpc_end2end_test_fixture* f, - grpc_channel_args* server_args) { - grpc_server_credentials* creds = grpc_local_server_credentials_create(UDS); - fullstack_fixture_data* ffd = - static_cast(f->fixture_data); +void grpc_end2end_local_chttp2_init_server_fullstack( + grpc_end2end_test_fixture* f, grpc_channel_args* server_args, + grpc_local_connect_type type) { + grpc_server_credentials* creds = grpc_local_server_credentials_create(type); + grpc_end2end_local_fullstack_fixture_data* ffd = + static_cast(f->fixture_data); if (f->server) { grpc_server_destroy(f->server); } @@ -119,36 +105,10 @@ void chttp2_init_server_fullstack(grpc_end2end_test_fixture* f, grpc_server_start(f->server); } -void chttp2_tear_down_fullstack(grpc_end2end_test_fixture* f) { - fullstack_fixture_data* ffd = - static_cast(f->fixture_data); +void grpc_end2end_local_chttp2_tear_down_fullstack( + grpc_end2end_test_fixture* f) { + grpc_end2end_local_fullstack_fixture_data* ffd = + static_cast(f->fixture_data); gpr_free(ffd->localaddr); gpr_free(ffd); } - -/* All test configurations */ -static grpc_end2end_test_config configs[] = { - {"chttp2/fullstack_local", - FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION | - FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL | - FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER | - FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS, - nullptr, chttp2_create_fixture_fullstack, chttp2_init_client_fullstack, - chttp2_init_server_fullstack, chttp2_tear_down_fullstack}, -}; - -int main(int argc, char** argv) { - size_t i; - - grpc_test_init(argc, argv); - grpc_end2end_tests_pre_init(); - grpc_init(); - - for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) { - grpc_end2end_tests(argc, argv, configs[i]); - } - - grpc_shutdown(); - - return 0; -} diff --git a/test/core/end2end/fixtures/local_util.h b/test/core/end2end/fixtures/local_util.h new file mode 100644 index 00000000000..f133b4d977e --- /dev/null +++ b/test/core/end2end/fixtures/local_util.h @@ -0,0 +1,41 @@ +/* + * + * 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 + +#include "src/core/lib/surface/channel.h" + +typedef struct grpc_end2end_local_fullstack_fixture_data { + char* localaddr; +} grpc_end2end_local_fullstack_fixture_data; + +/* Utility functions shared by h2_local tests. */ +grpc_end2end_test_fixture grpc_end2end_local_chttp2_create_fixture_fullstack(); + +void grpc_end2end_local_chttp2_init_client_fullstack( + grpc_end2end_test_fixture* f, grpc_channel_args* client_args, + grpc_local_connect_type type); + +void grpc_end2end_local_chttp2_init_server_fullstack( + grpc_end2end_test_fixture* f, grpc_channel_args* server_args, + grpc_local_connect_type type); + +void grpc_end2end_local_chttp2_tear_down_fullstack( + grpc_end2end_test_fixture* f); diff --git a/test/core/end2end/fuzzers/api_fuzzer.cc b/test/core/end2end/fuzzers/api_fuzzer.cc index e97a544e12c..74a30913b24 100644 --- a/test/core/end2end/fuzzers/api_fuzzer.cc +++ b/test/core/end2end/fuzzers/api_fuzzer.cc @@ -24,8 +24,8 @@ #include #include -#include "src/core/ext/filters/client_channel/lb_policy_factory.h" #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" +#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gpr/env.h" @@ -325,7 +325,7 @@ typedef struct addr_req { char* addr; grpc_closure* on_done; grpc_resolved_addresses** addrs; - grpc_lb_addresses** lb_addrs; + grpc_core::UniquePtr* addresses; } addr_req; static void finish_resolve(void* arg, grpc_error* error) { @@ -340,11 +340,12 @@ static void finish_resolve(void* arg, grpc_error* error) { gpr_malloc(sizeof(*addrs->addrs))); addrs->addrs[0].len = 0; *r->addrs = addrs; - } else if (r->lb_addrs != nullptr) { - grpc_lb_addresses* lb_addrs = grpc_lb_addresses_create(1, nullptr); - grpc_lb_addresses_set_address(lb_addrs, 0, nullptr, 0, false, nullptr, - nullptr); - *r->lb_addrs = lb_addrs; + } else if (r->addresses != nullptr) { + *r->addresses = grpc_core::MakeUnique(); + grpc_resolved_address dummy_resolved_address; + memset(&dummy_resolved_address, 0, sizeof(dummy_resolved_address)); + dummy_resolved_address.len = 0; + (*r->addresses)->emplace_back(dummy_resolved_address, nullptr); } GRPC_CLOSURE_SCHED(r->on_done, GRPC_ERROR_NONE); } else { @@ -354,18 +355,17 @@ static void finish_resolve(void* arg, grpc_error* error) { } gpr_free(r->addr); - gpr_free(r); + grpc_core::Delete(r); } void my_resolve_address(const char* addr, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - grpc_resolved_addresses** addresses) { - addr_req* r = static_cast(gpr_malloc(sizeof(*r))); + grpc_resolved_addresses** addrs) { + addr_req* r = grpc_core::New(); r->addr = gpr_strdup(addr); r->on_done = on_done; - r->addrs = addresses; - r->lb_addrs = nullptr; + r->addrs = addrs; grpc_timer_init( &r->timer, GPR_MS_PER_SEC + grpc_core::ExecCtx::Get()->Now(), GRPC_CLOSURE_CREATE(finish_resolve, r, grpc_schedule_on_exec_ctx)); @@ -377,13 +377,14 @@ static grpc_address_resolver_vtable fuzzer_resolver = {my_resolve_address, grpc_ares_request* my_dns_lookup_ares_locked( const char* dns_server, const char* addr, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - grpc_lb_addresses** lb_addrs, bool check_grpclb, char** service_config_json, + grpc_core::UniquePtr* addresses, + bool check_grpclb, char** service_config_json, int query_timeout, grpc_combiner* combiner) { addr_req* r = static_cast(gpr_malloc(sizeof(*r))); r->addr = gpr_strdup(addr); r->on_done = on_done; r->addrs = nullptr; - r->lb_addrs = lb_addrs; + r->addresses = addresses; grpc_timer_init( &r->timer, GPR_MS_PER_SEC + grpc_core::ExecCtx::Get()->Now(), GRPC_CLOSURE_CREATE(finish_resolve, r, grpc_schedule_on_exec_ctx)); @@ -420,7 +421,7 @@ static void do_connect(void* arg, grpc_error* error) { grpc_transport* transport = grpc_create_chttp2_transport(nullptr, server, false); - grpc_server_setup_transport(g_server, transport, nullptr, nullptr, 0); + grpc_server_setup_transport(g_server, transport, nullptr, nullptr, nullptr); grpc_chttp2_transport_start_reading(transport, nullptr, nullptr); GRPC_CLOSURE_SCHED(fc->closure, GRPC_ERROR_NONE); @@ -705,7 +706,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { grpc_timer_manager_set_threading(false); { grpc_core::ExecCtx exec_ctx; - grpc_executor_set_threading(false); + grpc_core::Executor::SetThreadingAll(false); } grpc_set_resolver_impl(&fuzzer_resolver); grpc_dns_lookup_ares_locked = my_dns_lookup_ares_locked; @@ -1199,6 +1200,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { grpc_resource_quota_unref(g_resource_quota); - grpc_shutdown(); + grpc_shutdown_blocking(); return 0; } diff --git a/test/core/end2end/fuzzers/client_fuzzer.cc b/test/core/end2end/fuzzers/client_fuzzer.cc index e21006bb673..55e6ce695ad 100644 --- a/test/core/end2end/fuzzers/client_fuzzer.cc +++ b/test/core/end2end/fuzzers/client_fuzzer.cc @@ -40,13 +40,12 @@ static void dont_log(gpr_log_func_args* args) {} extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { grpc_test_only_set_slice_hash_seed(0); - struct grpc_memory_counters counters; if (squelch) gpr_set_log_function(dont_log); - if (leak_check) grpc_memory_counters_init(); + grpc_core::testing::LeakDetector leak_detector(leak_check); grpc_init(); { grpc_core::ExecCtx exec_ctx; - grpc_executor_set_threading(false); + grpc_core::Executor::SetThreadingAll(false); grpc_resource_quota* resource_quota = grpc_resource_quota_create("client_fuzzer"); @@ -159,11 +158,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { grpc_byte_buffer_destroy(response_payload_recv); } } - grpc_shutdown(); - if (leak_check) { - counters = grpc_memory_counters_snapshot(); - grpc_memory_counters_destroy(); - GPR_ASSERT(counters.total_size_relative == 0); - } + grpc_shutdown_blocking(); return 0; } diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/clusterfuzz-testcase-minimized-grpc_client_fuzzer-5765697914404864 b/test/core/end2end/fuzzers/client_fuzzer_corpus/clusterfuzz-testcase-minimized-grpc_client_fuzzer-5765697914404864 new file mode 100644 index 00000000000..e8a60f5a9b5 Binary files /dev/null and b/test/core/end2end/fuzzers/client_fuzzer_corpus/clusterfuzz-testcase-minimized-grpc_client_fuzzer-5765697914404864 differ diff --git a/test/core/end2end/fuzzers/hpack.dictionary b/test/core/end2end/fuzzers/hpack.dictionary index a79fe5ad957..0469421c975 100644 --- a/test/core/end2end/fuzzers/hpack.dictionary +++ b/test/core/end2end/fuzzers/hpack.dictionary @@ -35,6 +35,7 @@ "\x1Fgrpc.max_response_message_bytes" "$/grpc.lb.v1.LoadBalancer/BalanceLoad" "\x1C/grpc.health.v1.Health/Watch" +"P/envoy.service.discovery.v2.AggregatedDiscoveryService/StreamAggregatedResources" "\x07deflate" "\x04gzip" "\x0Bstream/gzip" diff --git a/test/core/end2end/fuzzers/server_fuzzer.cc b/test/core/end2end/fuzzers/server_fuzzer.cc index bd686215ddb..f010066ea27 100644 --- a/test/core/end2end/fuzzers/server_fuzzer.cc +++ b/test/core/end2end/fuzzers/server_fuzzer.cc @@ -37,13 +37,12 @@ static void dont_log(gpr_log_func_args* args) {} extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { grpc_test_only_set_slice_hash_seed(0); - struct grpc_memory_counters counters; if (squelch) gpr_set_log_function(dont_log); - if (leak_check) grpc_memory_counters_init(); + grpc_core::testing::LeakDetector leak_detector(leak_check); grpc_init(); { grpc_core::ExecCtx exec_ctx; - grpc_executor_set_threading(false); + grpc_core::Executor::SetThreadingAll(false); grpc_resource_quota* resource_quota = grpc_resource_quota_create("server_fuzzer"); @@ -62,7 +61,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { grpc_server_start(server); grpc_transport* transport = grpc_create_chttp2_transport(nullptr, mock_endpoint, false); - grpc_server_setup_transport(server, transport, nullptr, nullptr, 0); + grpc_server_setup_transport(server, transport, nullptr, nullptr, nullptr); grpc_chttp2_transport_start_reading(transport, nullptr, nullptr); grpc_call* call1 = nullptr; @@ -136,10 +135,5 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { grpc_completion_queue_destroy(cq); } 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/end2end/gen_build_yaml.py b/test/core/end2end/gen_build_yaml.py index 601d3bac387..7bb802aa6d5 100755 --- a/test/core/end2end/gen_build_yaml.py +++ b/test/core/end2end/gen_build_yaml.py @@ -74,7 +74,11 @@ END2END_FIXTURES = { 'h2_sockpair+trace': socketpair_unsecure_fixture_options._replace( ci_mac=False, tracing=True, large_writes=False, exclude_iomgrs=['uv']), 'h2_ssl': default_secure_fixture_options, - 'h2_local': local_fixture_options, + 'h2_ssl_cred_reload': default_secure_fixture_options, + 'h2_spiffe': default_secure_fixture_options, + 'h2_local_uds': local_fixture_options, + 'h2_local_ipv4': local_fixture_options, + 'h2_local_ipv6': local_fixture_options, 'h2_ssl_proxy': default_secure_fixture_options._replace( includes_proxy=True, ci_mac=False, exclude_iomgrs=['uv']), 'h2_uds': uds_fixture_options, @@ -122,6 +126,7 @@ END2END_TESTS = { 'empty_batch': default_test_options._replace(cpu_cost=LOWCPU), 'filter_causes_close': default_test_options._replace(cpu_cost=LOWCPU), 'filter_call_init_fails': default_test_options, + 'filter_context': default_test_options, 'filter_latency': default_test_options._replace(cpu_cost=LOWCPU), 'filter_status_code': default_test_options._replace(cpu_cost=LOWCPU), 'graceful_server_shutdown': default_test_options._replace( @@ -144,7 +149,6 @@ END2END_TESTS = { proxyable=False, exclude_iomgrs=['uv'], cpu_cost=LOWCPU), 'max_message_length': default_test_options._replace(cpu_cost=LOWCPU), 'negative_deadline': default_test_options, - 'network_status_change': default_test_options._replace(cpu_cost=LOWCPU), 'no_error_on_hotpath': default_test_options._replace(proxyable=False), 'no_logging': default_test_options._replace(traceable=False), 'no_op': default_test_options, @@ -281,13 +285,11 @@ def main(): sec_deps = [ 'grpc_test_util', 'grpc', - 'gpr_test_util', 'gpr' ] unsec_deps = [ 'grpc_test_util_unsecure', 'grpc_unsecure', - 'gpr_test_util', 'gpr' ] json = { diff --git a/test/core/end2end/generate_tests.bzl b/test/core/end2end/generate_tests.bzl index 81956db841f..85faca16364 100755 --- a/test/core/end2end/generate_tests.bzl +++ b/test/core/end2end/generate_tests.bzl @@ -17,7 +17,7 @@ load("//bazel:grpc_build_system.bzl", "grpc_cc_binary", "grpc_cc_library") -POLLERS = ["epollex", "epoll1", "poll", "poll-cv"] +POLLERS = ["epollex", "epoll1", "poll"] def _fixture_options( fullstack = True, @@ -31,7 +31,8 @@ def _fixture_options( is_http2 = True, supports_proxy_auth = False, supports_write_buffering = True, - client_channel = True): + client_channel = True, + supports_msvc = True): return struct( fullstack = fullstack, includes_proxy = includes_proxy, @@ -44,6 +45,7 @@ def _fixture_options( supports_proxy_auth = supports_proxy_auth, supports_write_buffering = supports_write_buffering, client_channel = client_channel, + supports_msvc = supports_msvc, #_platforms=_platforms, ) @@ -85,7 +87,11 @@ END2END_FIXTURES = { client_channel = False, ), "h2_ssl": _fixture_options(secure = True), - "h2_local": _fixture_options(secure = True, dns_resolver = False, _platforms = ["linux", "mac", "posix"]), + "h2_ssl_cred_reload": _fixture_options(secure = True), + "h2_spiffe": _fixture_options(secure = True), + "h2_local_uds": _fixture_options(secure = True, dns_resolver = False, _platforms = ["linux", "mac", "posix"]), + "h2_local_ipv4": _fixture_options(secure = True, dns_resolver = False, _platforms = ["linux", "mac", "posix"]), + "h2_local_ipv6": _fixture_options(secure = True, dns_resolver = False, _platforms = ["linux", "mac", "posix"]), "h2_ssl_proxy": _fixture_options(includes_proxy = True, secure = True), "h2_uds": _fixture_options( dns_resolver = False, @@ -117,10 +123,11 @@ END2END_NOSEC_FIXTURES = { client_channel = False, secure = False, _platforms = ["linux", "mac", "posix"], + supports_msvc = False, ), "h2_full": _fixture_options(secure = False), - "h2_full+pipe": _fixture_options(secure = False, _platforms = ["linux"]), - "h2_full+trace": _fixture_options(secure = False, tracing = True), + "h2_full+pipe": _fixture_options(secure = False, _platforms = ["linux"], supports_msvc = False), + "h2_full+trace": _fixture_options(secure = False, tracing = True, supports_msvc = False), "h2_full+workarounds": _fixture_options(secure = False), "h2_http_proxy": _fixture_options(secure = False, supports_proxy_auth = True), "h2_proxy": _fixture_options(secure = False, includes_proxy = True), @@ -144,11 +151,13 @@ END2END_NOSEC_FIXTURES = { client_channel = False, ), "h2_ssl": _fixture_options(secure = False), + "h2_ssl_cred_reload": _fixture_options(secure = False), "h2_ssl_proxy": _fixture_options(includes_proxy = True, secure = False), "h2_uds": _fixture_options( dns_resolver = False, _platforms = ["linux", "mac", "posix"], secure = False, + supports_msvc = False, ), } @@ -213,6 +222,7 @@ END2END_TESTS = { "empty_batch": _test_options(), "filter_causes_close": _test_options(), "filter_call_init_fails": _test_options(), + "filter_context": _test_options(), "graceful_server_shutdown": _test_options(exclude_inproc = True), "hpack_size": _test_options( proxyable = False, @@ -232,7 +242,6 @@ END2END_TESTS = { "max_connection_idle": _test_options(needs_fullstack = True, proxyable = False), "max_message_length": _test_options(), "negative_deadline": _test_options(), - "network_status_change": _test_options(), "no_error_on_hotpath": _test_options(proxyable = False), "no_logging": _test_options(traceable = False), "no_op": _test_options(), @@ -376,7 +385,9 @@ def grpc_end2end_tests(): ":ssl_test_data", ":http_proxy", ":proxy", + ":local_util", ], + tags = ["no_windows"], ) for f, fopt in END2END_FIXTURES.items(): @@ -388,9 +399,9 @@ def grpc_end2end_tests(): ":end2end_tests", "//test/core/util:grpc_test_util", "//:grpc", - "//test/core/util:gpr_test_util", "//:gpr", ], + tags = ["no_windows"], ) for t, topt in END2END_TESTS.items(): #print(_compatible(fopt, topt), f, t, fopt, topt) @@ -406,6 +417,7 @@ def grpc_end2end_tests(): t, poller, ], + tags = ["no_windows"], ) def grpc_end2end_nosec_tests(): @@ -426,7 +438,9 @@ def grpc_end2end_nosec_tests(): ":ssl_test_data", ":http_proxy", ":proxy", + ":local_util", ], + tags = ["no_windows"], ) for f, fopt in END2END_NOSEC_FIXTURES.items(): @@ -440,9 +454,9 @@ def grpc_end2end_nosec_tests(): ":end2end_nosec_tests", "//test/core/util:grpc_test_util_unsecure", "//:grpc_unsecure", - "//test/core/util:gpr_test_util", "//:gpr", ], + tags = ["no_windows"], ) for t, topt in END2END_TESTS.items(): #print(_compatible(fopt, topt), f, t, fopt, topt) @@ -460,4 +474,5 @@ def grpc_end2end_nosec_tests(): t, poller, ], + tags = ["no_windows"], ) diff --git a/test/core/end2end/goaway_server_test.cc b/test/core/end2end/goaway_server_test.cc index 3f1c5596ad9..7e3b418cd94 100644 --- a/test/core/end2end/goaway_server_test.cc +++ b/test/core/end2end/goaway_server_test.cc @@ -28,8 +28,8 @@ #include #include #include -#include "src/core/ext/filters/client_channel/lb_policy_factory.h" #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" +#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/iomgr/resolve_address.h" #include "src/core/lib/iomgr/sockaddr.h" #include "test/core/end2end/cq_verifier.h" @@ -47,8 +47,9 @@ static int g_resolve_port = -1; static grpc_ares_request* (*iomgr_dns_lookup_ares_locked)( const char* dns_server, const char* addr, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - grpc_lb_addresses** addresses, bool check_grpclb, - char** service_config_json, grpc_combiner* combiner); + grpc_core::UniquePtr* addresses, + bool check_grpclb, char** service_config_json, int query_timeout_ms, + grpc_combiner* combiner); static void (*iomgr_cancel_ares_request_locked)(grpc_ares_request* request); @@ -103,12 +104,13 @@ static grpc_address_resolver_vtable test_resolver = { static grpc_ares_request* my_dns_lookup_ares_locked( const char* dns_server, const char* addr, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - grpc_lb_addresses** lb_addrs, bool check_grpclb, char** service_config_json, + grpc_core::UniquePtr* addresses, + bool check_grpclb, char** service_config_json, int query_timeout_ms, grpc_combiner* combiner) { if (0 != strcmp(addr, "test")) { return iomgr_dns_lookup_ares_locked( - dns_server, addr, default_port, interested_parties, on_done, lb_addrs, - check_grpclb, service_config_json, combiner); + dns_server, addr, default_port, interested_parties, on_done, addresses, + check_grpclb, service_config_json, query_timeout_ms, combiner); } grpc_error* error = GRPC_ERROR_NONE; @@ -117,15 +119,12 @@ static grpc_ares_request* my_dns_lookup_ares_locked( gpr_mu_unlock(&g_mu); error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Forced Failure"); } else { - *lb_addrs = grpc_lb_addresses_create(1, nullptr); - grpc_sockaddr_in* sa = - static_cast(gpr_zalloc(sizeof(grpc_sockaddr_in))); - sa->sin_family = GRPC_AF_INET; - sa->sin_addr.s_addr = 0x100007f; - sa->sin_port = grpc_htons(static_cast(g_resolve_port)); - grpc_lb_addresses_set_address(*lb_addrs, 0, sa, sizeof(*sa), false, nullptr, - nullptr); - gpr_free(sa); + *addresses = grpc_core::MakeUnique(); + grpc_sockaddr_in sa; + sa.sin_family = GRPC_AF_INET; + sa.sin_addr.s_addr = 0x100007f; + sa.sin_port = grpc_htons(static_cast(g_resolve_port)); + (*addresses)->emplace_back(&sa, sizeof(sa), nullptr); gpr_mu_unlock(&g_mu); } GRPC_CLOSURE_SCHED(on_done, error); @@ -144,7 +143,7 @@ int main(int argc, char** argv) { grpc_op ops[6]; grpc_op* op; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); gpr_mu_init(&g_mu); grpc_init(); diff --git a/test/core/end2end/h2_ssl_cert_test.cc b/test/core/end2end/h2_ssl_cert_test.cc index 2c5ee3b156e..cb0800bf899 100644 --- a/test/core/end2end/h2_ssl_cert_test.cc +++ b/test/core/end2end/h2_ssl_cert_test.cc @@ -358,7 +358,7 @@ int main(int argc, char** argv) { size_t roots_size = strlen(test_root_cert); char* roots_filename; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); /* Set the SSL roots env var. */ roots_file = gpr_tmpfile("chttp2_simple_ssl_cert_fullstack_test", &roots_filename); diff --git a/test/core/end2end/h2_ssl_session_reuse_test.cc b/test/core/end2end/h2_ssl_session_reuse_test.cc index b2f398625ab..fbcdcc4b3f3 100644 --- a/test/core/end2end/h2_ssl_session_reuse_test.cc +++ b/test/core/end2end/h2_ssl_session_reuse_test.cc @@ -258,7 +258,7 @@ int main(int argc, char** argv) { size_t roots_size = strlen(test_root_cert); char* roots_filename; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); /* Set the SSL roots env var. */ roots_file = gpr_tmpfile("chttp2_ssl_session_reuse_test", &roots_filename); GPR_ASSERT(roots_filename != nullptr); diff --git a/test/core/end2end/inproc_callback_test.cc b/test/core/end2end/inproc_callback_test.cc index 310030046af..550c2c2d69a 100644 --- a/test/core/end2end/inproc_callback_test.cc +++ b/test/core/end2end/inproc_callback_test.cc @@ -65,7 +65,10 @@ class ShutdownCallback : public grpc_experimental_completion_queue_functor { gpr_mu_init(&mu_); gpr_cv_init(&cv_); } - ~ShutdownCallback() {} + ~ShutdownCallback() { + gpr_mu_destroy(&mu_); + gpr_cv_destroy(&cv_); + } static void StaticRun(grpc_experimental_completion_queue_functor* cb, int ok) { auto* callback = static_cast(cb); @@ -495,7 +498,7 @@ static grpc_end2end_test_config configs[] = { }; int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); simple_request_pre_init(); diff --git a/test/core/end2end/invalid_call_argument_test.cc b/test/core/end2end/invalid_call_argument_test.cc index 6cb2e3ee806..bd28d192984 100644 --- a/test/core/end2end/invalid_call_argument_test.cc +++ b/test/core/end2end/invalid_call_argument_test.cc @@ -609,7 +609,7 @@ static void test_invalid_initial_metadata_reserved_key() { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); test_invalid_initial_metadata_reserved_key(); test_non_null_reserved_on_start_batch(); diff --git a/test/core/end2end/multiple_server_queues_test.cc b/test/core/end2end/multiple_server_queues_test.cc index dfa3b48b52d..5ae828c1e39 100644 --- a/test/core/end2end/multiple_server_queues_test.cc +++ b/test/core/end2end/multiple_server_queues_test.cc @@ -27,7 +27,7 @@ int main(int argc, char** argv) { grpc_server* server; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); attr.version = 1; diff --git a/test/core/end2end/no_server_test.cc b/test/core/end2end/no_server_test.cc index e8ce4032e0f..c289e719eea 100644 --- a/test/core/end2end/no_server_test.cc +++ b/test/core/end2end/no_server_test.cc @@ -23,6 +23,7 @@ #include #include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h" +#include "src/core/lib/iomgr/exec_ctx.h" #include "test/core/end2end/cq_verifier.h" #include "test/core/util/test_config.h" @@ -107,7 +108,7 @@ void run_test(bool wait_for_ready) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); run_test(true /* wait_for_ready */); run_test(false /* wait_for_ready */); return 0; diff --git a/test/core/end2end/tests/bad_ping.cc b/test/core/end2end/tests/bad_ping.cc index 98d893f64d9..a07bf16876a 100644 --- a/test/core/end2end/tests/bad_ping.cc +++ b/test/core/end2end/tests/bad_ping.cc @@ -312,7 +312,7 @@ static void test_pings_without_data(grpc_end2end_test_config config) { CQ_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); - // Send too many pings to the server similar to the prevous test case. + // Send too many pings to the server similar to the previous test case. // However, since we set the MAX_PINGS_WITHOUT_DATA at the client side, only // MAX_PING_STRIKES will actually be sent and the rpc will still succeed. int i; diff --git a/test/core/end2end/tests/cancel_after_accept.cc b/test/core/end2end/tests/cancel_after_accept.cc index 788d374baad..510bf3cee5f 100644 --- a/test/core/end2end/tests/cancel_after_accept.cc +++ b/test/core/end2end/tests/cancel_after_accept.cc @@ -30,7 +30,6 @@ #include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/transport/metadata.h" -#include "src/core/lib/transport/service_config.h" #include "test/core/end2end/cq_verifier.h" #include "test/core/end2end/tests/cancel_test_helpers.h" diff --git a/test/core/end2end/tests/cancel_after_round_trip.cc b/test/core/end2end/tests/cancel_after_round_trip.cc index 061b273f18d..609ac570d90 100644 --- a/test/core/end2end/tests/cancel_after_round_trip.cc +++ b/test/core/end2end/tests/cancel_after_round_trip.cc @@ -30,7 +30,6 @@ #include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/transport/metadata.h" -#include "src/core/lib/transport/service_config.h" #include "test/core/end2end/cq_verifier.h" #include "test/core/end2end/tests/cancel_test_helpers.h" diff --git a/test/core/end2end/tests/channelz.cc b/test/core/end2end/tests/channelz.cc index 922783aa0d0..169190eec06 100644 --- a/test/core/end2end/tests/channelz.cc +++ b/test/core/end2end/tests/channelz.cc @@ -259,8 +259,8 @@ static void test_channelz(grpc_end2end_test_config config) { GPR_ASSERT(nullptr == strstr(json, "\"severity\":\"CT_INFO\"")); gpr_free(json); - json = channelz_server->RenderServerSockets(0); - GPR_ASSERT(nullptr != strstr(json, "\"socketRef\":")); + json = channelz_server->RenderServerSockets(0, 100); + GPR_ASSERT(nullptr != strstr(json, "\"end\":true")); gpr_free(json); end_test(&f); diff --git a/test/core/end2end/tests/compressed_payload.cc b/test/core/end2end/tests/compressed_payload.cc index 178d68c608d..2b9ab5d642a 100644 --- a/test/core/end2end/tests/compressed_payload.cc +++ b/test/core/end2end/tests/compressed_payload.cc @@ -30,6 +30,7 @@ #include #include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/compression/compression_args.h" #include "src/core/lib/surface/call.h" #include "src/core/lib/surface/call_test_only.h" #include "src/core/lib/transport/static_metadata.h" diff --git a/test/core/end2end/tests/network_status_change.cc b/test/core/end2end/tests/filter_context.cc similarity index 56% rename from test/core/end2end/tests/network_status_change.cc rename to test/core/end2end/tests/filter_context.cc index 98a95582046..1d5d9e5e46a 100644 --- a/test/core/end2end/tests/network_status_change.cc +++ b/test/core/end2end/tests/filter_context.cc @@ -1,6 +1,6 @@ /* * - * Copyright 2015 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. @@ -18,6 +18,8 @@ #include "test/core/end2end/end2end_tests.h" +#include +#include #include #include @@ -25,10 +27,14 @@ #include #include #include + +#include "src/core/lib/channel/channel_stack_builder.h" +#include "src/core/lib/surface/channel_init.h" #include "test/core/end2end/cq_verifier.h" -/* this is a private API but exposed here for testing*/ -extern void grpc_network_status_shutdown_all_endpoints(); +enum { TIMEOUT = 200000 }; + +static bool g_enable_filter = false; static void* tag(intptr_t t) { return (void*)t; } @@ -49,7 +55,7 @@ static gpr_timespec n_seconds_from_now(int n) { } static gpr_timespec five_seconds_from_now(void) { - return n_seconds_from_now(500); + return n_seconds_from_now(5); } static void drain_cq(grpc_completion_queue* cq) { @@ -86,8 +92,9 @@ static void end_test(grpc_end2end_test_fixture* f) { grpc_completion_queue_destroy(f->shutdown_cq); } -/* Client sends a request with payload, server reads then returns status. */ -static void test_invoke_network_status_change(grpc_end2end_test_config config) { +// Simple request to test that filters see a consistent view of the +// call context. +static void test_request(grpc_end2end_test_config config) { grpc_call* c; grpc_call* s; grpc_slice request_payload_slice = @@ -95,7 +102,7 @@ static void test_invoke_network_status_change(grpc_end2end_test_config config) { grpc_byte_buffer* request_payload = grpc_raw_byte_buffer_create(&request_payload_slice, 1); grpc_end2end_test_fixture f = - begin_test(config, "test_invoke_request_with_payload", nullptr, nullptr); + begin_test(config, "filter_context", nullptr, nullptr); cq_verifier* cqv = cq_verifier_create(f.cq); grpc_op ops[6]; grpc_op* op; @@ -124,6 +131,7 @@ static void test_invoke_network_status_change(grpc_end2end_test_config config) { op = ops; op->op = GRPC_OP_SEND_INITIAL_METADATA; op->data.send_initial_metadata.count = 0; + op->data.send_initial_metadata.metadata = nullptr; op->flags = 0; op->reserved = nullptr; op++; @@ -152,20 +160,31 @@ static void test_invoke_network_status_change(grpc_end2end_test_config config) { nullptr); GPR_ASSERT(GRPC_CALL_OK == error); - GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call( - f.server, &s, &call_details, - &request_metadata_recv, f.cq, f.cq, tag(101))); + 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), 1); cq_verify(cqv); + 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_RECV_MESSAGE; - op->data.recv_message.recv_message = &request_payload_recv; + 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_string = grpc_slice_from_static_string("xyz"); + op->data.send_status_from_server.status_details = &status_string; + 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++; @@ -174,39 +193,11 @@ static void test_invoke_network_status_change(grpc_end2end_test_config config) { GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(102), 1); - cq_verify(cqv); - - // Simulate the network loss event - grpc_network_status_shutdown_all_endpoints(); - - op = ops; - op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; - op->data.recv_close_on_server.cancelled = &was_cancelled; - 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_OK; - 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++; - error = grpc_call_start_batch(s, ops, static_cast(op - ops), tag(103), - nullptr); - GPR_ASSERT(GRPC_CALL_OK == error); - - CQ_EXPECT_COMPLETION(cqv, tag(103), 1); CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); - // TODO(makdharma) Update this when the shutdown_all_endpoints is implemented. - // Expected behavior of a RPC when network is lost. - // GPR_ASSERT(status == GRPC_STATUS_UNAVAILABLE); - GPR_ASSERT(status == GRPC_STATUS_OK); - - GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo")); + GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED); + GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz")); grpc_slice_unref(details); grpc_metadata_array_destroy(&initial_metadata_recv); @@ -214,8 +205,8 @@ static void test_invoke_network_status_change(grpc_end2end_test_config config) { grpc_metadata_array_destroy(&request_metadata_recv); grpc_call_details_destroy(&call_details); - grpc_call_unref(c); grpc_call_unref(s); + grpc_call_unref(c); cq_verifier_destroy(cqv); @@ -226,12 +217,102 @@ static void test_invoke_network_status_change(grpc_end2end_test_config config) { config.tear_down_data(&f); } -void network_status_change(grpc_end2end_test_config config) { - if (config.feature_mask & - FEATURE_MASK_DOES_NOT_SUPPORT_NETWORK_STATUS_CHANGE) { - return; - } - test_invoke_network_status_change(config); +/******************************************************************************* + * Test context filter + */ + +struct call_data { + grpc_call_context_element* context; +}; + +static grpc_error* init_call_elem(grpc_call_element* elem, + const grpc_call_element_args* args) { + call_data* calld = static_cast(elem->call_data); + calld->context = args->context; + gpr_log(GPR_INFO, "init_call_elem(): context=%p", args->context); + return GRPC_ERROR_NONE; } -void network_status_change_pre_init(void) {} +static void start_transport_stream_op_batch( + grpc_call_element* elem, grpc_transport_stream_op_batch* batch) { + call_data* calld = static_cast(elem->call_data); + // If batch payload context is not null (which will happen in some + // cancellation cases), make sure we get the same context here that we + // saw in init_call_elem(). + gpr_log(GPR_INFO, "start_transport_stream_op_batch(): context=%p", + batch->payload->context); + if (batch->payload->context != nullptr) { + GPR_ASSERT(calld->context == batch->payload->context); + } + grpc_call_next_op(elem, batch); +} + +static void destroy_call_elem(grpc_call_element* elem, + const grpc_call_final_info* final_info, + grpc_closure* ignored) {} + +static grpc_error* init_channel_elem(grpc_channel_element* elem, + grpc_channel_element_args* args) { + return GRPC_ERROR_NONE; +} + +static void destroy_channel_elem(grpc_channel_element* elem) {} + +static const grpc_channel_filter test_filter = { + 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, + 0, + init_channel_elem, + destroy_channel_elem, + grpc_channel_next_get_info, + "filter_context"}; + +/******************************************************************************* + * Registration + */ + +static bool maybe_add_filter(grpc_channel_stack_builder* builder, void* arg) { + grpc_channel_filter* filter = static_cast(arg); + if (g_enable_filter) { + // Want to add the filter as close to the end as possible, to make + // sure that all of the filters work well together. However, we + // can't add it at the very end, because the connected channel filter + // must be the last one. So we add it right before the last one. + grpc_channel_stack_builder_iterator* it = + grpc_channel_stack_builder_create_iterator_at_last(builder); + GPR_ASSERT(grpc_channel_stack_builder_move_prev(it)); + const bool retval = grpc_channel_stack_builder_add_filter_before( + it, filter, nullptr, nullptr); + grpc_channel_stack_builder_iterator_destroy(it); + return retval; + } else { + return true; + } +} + +static void init_plugin(void) { + grpc_channel_init_register_stage(GRPC_CLIENT_CHANNEL, INT_MAX, + maybe_add_filter, (void*)&test_filter); + grpc_channel_init_register_stage(GRPC_CLIENT_SUBCHANNEL, INT_MAX, + maybe_add_filter, (void*)&test_filter); + grpc_channel_init_register_stage(GRPC_CLIENT_DIRECT_CHANNEL, INT_MAX, + maybe_add_filter, (void*)&test_filter); + grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, INT_MAX, + maybe_add_filter, (void*)&test_filter); +} + +static void destroy_plugin(void) {} + +void filter_context(grpc_end2end_test_config config) { + g_enable_filter = true; + test_request(config); + g_enable_filter = false; +} + +void filter_context_pre_init(void) { + grpc_register_plugin(init_plugin, destroy_plugin); +} diff --git a/test/core/end2end/tests/filter_status_code.cc b/test/core/end2end/tests/filter_status_code.cc index 5ffc3d00a3f..6d85c1b0724 100644 --- a/test/core/end2end/tests/filter_status_code.cc +++ b/test/core/end2end/tests/filter_status_code.cc @@ -260,6 +260,7 @@ typedef struct final_status_data { static void server_start_transport_stream_op_batch( grpc_call_element* elem, grpc_transport_stream_op_batch* op) { auto* data = static_cast(elem->call_data); + gpr_mu_lock(&g_mu); if (data->call == g_server_call_stack) { if (op->send_initial_metadata) { auto* batch = op->payload->send_initial_metadata.send_initial_metadata; @@ -270,6 +271,7 @@ static void server_start_transport_stream_op_batch( } } } + gpr_mu_unlock(&g_mu); grpc_call_next_op(elem, op); } diff --git a/test/core/end2end/tests/keepalive_timeout.cc b/test/core/end2end/tests/keepalive_timeout.cc index 5f6a36dac44..3c33f0419ad 100644 --- a/test/core/end2end/tests/keepalive_timeout.cc +++ b/test/core/end2end/tests/keepalive_timeout.cc @@ -220,8 +220,221 @@ static void test_keepalive_timeout(grpc_end2end_test_config config) { config.tear_down_data(&f); } +/* Verify that reads reset the keepalive ping timer. The client sends 30 pings + * with a sleep of 10ms in between. It has a configured keepalive timer of + * 200ms. In the success case, each ping ack should reset the keepalive timer so + * that the keepalive ping is never sent. */ +static void test_read_delays_keepalive(grpc_end2end_test_config config) { + char* poller = gpr_getenv("GRPC_POLL_STRATEGY"); + /* It is hard to get the timing right for the polling engine poll. */ + if (poller != nullptr && (0 == strcmp(poller, "poll"))) { + gpr_free(poller); + return; + } + gpr_free(poller); + const int kPingIntervalMS = 100; + grpc_arg keepalive_arg_elems[3]; + keepalive_arg_elems[0].type = GRPC_ARG_INTEGER; + keepalive_arg_elems[0].key = const_cast(GRPC_ARG_KEEPALIVE_TIME_MS); + keepalive_arg_elems[0].value.integer = 20 * kPingIntervalMS; + keepalive_arg_elems[1].type = GRPC_ARG_INTEGER; + keepalive_arg_elems[1].key = const_cast(GRPC_ARG_KEEPALIVE_TIMEOUT_MS); + keepalive_arg_elems[1].value.integer = 0; + keepalive_arg_elems[2].type = GRPC_ARG_INTEGER; + keepalive_arg_elems[2].key = const_cast(GRPC_ARG_HTTP2_BDP_PROBE); + keepalive_arg_elems[2].value.integer = 0; + grpc_channel_args keepalive_args = {GPR_ARRAY_SIZE(keepalive_arg_elems), + keepalive_arg_elems}; + grpc_end2end_test_fixture f = begin_test(config, "test_read_delays_keepalive", + &keepalive_args, nullptr); + /* Disable ping ack to trigger the keepalive timeout */ + grpc_set_disable_ping_ack(true); + 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; + grpc_byte_buffer* request_payload; + grpc_byte_buffer* request_payload_recv; + grpc_byte_buffer* response_payload; + grpc_byte_buffer* response_payload_recv; + int i; + grpc_slice request_payload_slice = + grpc_slice_from_copied_string("hello world"); + grpc_slice response_payload_slice = + 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"), nullptr, + deadline, nullptr); + GPR_ASSERT(c); + + 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_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(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(100)); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(100), 1); + cq_verify(cqv); + + 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_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(op - ops), tag(101), + nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + for (i = 0; i < 30; i++) { + request_payload = grpc_raw_byte_buffer_create(&request_payload_slice, 1); + response_payload = grpc_raw_byte_buffer_create(&response_payload_slice, 1); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_MESSAGE; + op->data.send_message.send_message = request_payload; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_RECV_MESSAGE; + op->data.recv_message.recv_message = &response_payload_recv; + op->flags = 0; + op->reserved = nullptr; + op++; + error = grpc_call_start_batch(c, ops, static_cast(op - ops), tag(2), + nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_RECV_MESSAGE; + op->data.recv_message.recv_message = &request_payload_recv; + op->flags = 0; + op->reserved = nullptr; + op++; + error = grpc_call_start_batch(s, ops, static_cast(op - ops), + tag(102), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(102), 1); + cq_verify(cqv); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_MESSAGE; + op->data.send_message.send_message = response_payload; + op->flags = 0; + op->reserved = nullptr; + op++; + error = grpc_call_start_batch(s, ops, static_cast(op - ops), + tag(103), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(103), 1); + CQ_EXPECT_COMPLETION(cqv, tag(2), 1); + cq_verify(cqv); + + 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); + /* Sleep for a short interval to check if the client sends any pings */ + gpr_sleep_until(grpc_timeout_milliseconds_to_deadline(kPingIntervalMS)); + } + + grpc_slice_unref(request_payload_slice); + grpc_slice_unref(response_payload_slice); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; + op->flags = 0; + op->reserved = nullptr; + op++; + error = grpc_call_start_batch(c, ops, static_cast(op - ops), tag(3), + nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + memset(ops, 0, sizeof(ops)); + op = ops; + 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++; + error = grpc_call_start_batch(s, ops, static_cast(op - ops), tag(104), + nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(3), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(104), 1); + cq_verify(cqv); + + grpc_call_unref(c); + grpc_call_unref(s); + + cq_verifier_destroy(cqv); + + 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_slice_unref(details); + + end_test(&f); + config.tear_down_data(&f); +} + void keepalive_timeout(grpc_end2end_test_config config) { test_keepalive_timeout(config); + test_read_delays_keepalive(config); } void keepalive_timeout_pre_init(void) {} diff --git a/test/core/end2end/tests/max_message_length.cc b/test/core/end2end/tests/max_message_length.cc index 6ac941e0da0..40e752a3d63 100644 --- a/test/core/end2end/tests/max_message_length.cc +++ b/test/core/end2end/tests/max_message_length.cc @@ -30,7 +30,6 @@ #include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/transport/metadata.h" -#include "src/core/lib/transport/service_config.h" #include "test/core/end2end/cq_verifier.h" diff --git a/test/core/end2end/tests/retry_throttled.cc b/test/core/end2end/tests/retry_throttled.cc index f5b28def0ad..0e286c3d17c 100644 --- a/test/core/end2end/tests/retry_throttled.cc +++ b/test/core/end2end/tests/retry_throttled.cc @@ -141,7 +141,7 @@ static void test_retry_throttled(grpc_end2end_test_config config) { // purposes of this test.) " \"retryThrottling\": {\n" " \"maxTokens\": 2,\n" - " \"tokenRatio\": 1.0,\n" + " \"tokenRatio\": 1.0\n" " }\n" "}"); grpc_channel_args client_args = {1, &arg}; diff --git a/test/core/end2end/tests/simple_request.cc b/test/core/end2end/tests/simple_request.cc index 9c018962f83..a8c57899e2c 100644 --- a/test/core/end2end/tests/simple_request.cc +++ b/test/core/end2end/tests/simple_request.cc @@ -86,6 +86,14 @@ static void end_test(grpc_end2end_test_fixture* f) { grpc_completion_queue_destroy(f->shutdown_cq); } +static void check_peer(char* peer_name) { + // If the peer name is a uds path, then check if it is filled + if (strncmp(peer_name, "unix:/", strlen("unix:/")) == 0) { + GPR_ASSERT(strncmp(peer_name, "unix:/tmp/grpc_fullstack_test.", + strlen("unix:/tmp/grpc_fullstack_test.")) == 0); + } +} + static void simple_request_body(grpc_end2end_test_config config, grpc_end2end_test_fixture f) { grpc_call* c; @@ -166,10 +174,12 @@ static void simple_request_body(grpc_end2end_test_config config, peer = grpc_call_get_peer(s); GPR_ASSERT(peer != nullptr); gpr_log(GPR_DEBUG, "server_peer=%s", peer); + check_peer(peer); gpr_free(peer); peer = grpc_call_get_peer(c); GPR_ASSERT(peer != nullptr); gpr_log(GPR_DEBUG, "client_peer=%s", peer); + check_peer(peer); gpr_free(peer); memset(ops, 0, sizeof(ops)); diff --git a/test/core/end2end/tests/stream_compression_compressed_payload.cc b/test/core/end2end/tests/stream_compression_compressed_payload.cc index 839f0912a87..39f95b85baa 100644 --- a/test/core/end2end/tests/stream_compression_compressed_payload.cc +++ b/test/core/end2end/tests/stream_compression_compressed_payload.cc @@ -30,6 +30,7 @@ #include #include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/compression/compression_args.h" #include "src/core/lib/surface/call.h" #include "src/core/lib/surface/call_test_only.h" #include "src/core/lib/transport/static_metadata.h" diff --git a/test/core/end2end/tests/stream_compression_payload.cc b/test/core/end2end/tests/stream_compression_payload.cc index 4c08150723a..5f6b9a7f199 100644 --- a/test/core/end2end/tests/stream_compression_payload.cc +++ b/test/core/end2end/tests/stream_compression_payload.cc @@ -27,6 +27,7 @@ #include #include #include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/compression/compression_args.h" #include "src/core/lib/surface/call.h" #include "test/core/end2end/cq_verifier.h" 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 f7af59febe9..6e96f7d2938 100644 --- a/test/core/end2end/tests/stream_compression_ping_pong_streaming.cc +++ b/test/core/end2end/tests/stream_compression_ping_pong_streaming.cc @@ -28,6 +28,7 @@ #include #include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/compression/compression_args.h" #include "src/core/lib/surface/call.h" #include "test/core/end2end/cq_verifier.h" diff --git a/test/core/end2end/tests/workaround_cronet_compression.cc b/test/core/end2end/tests/workaround_cronet_compression.cc index f44ddca3b10..d79b2a9be3b 100644 --- a/test/core/end2end/tests/workaround_cronet_compression.cc +++ b/test/core/end2end/tests/workaround_cronet_compression.cc @@ -30,6 +30,7 @@ #include #include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/compression/compression_args.h" #include "src/core/lib/surface/call.h" #include "src/core/lib/surface/call_test_only.h" #include "src/core/lib/transport/static_metadata.h" diff --git a/test/core/fling/BUILD b/test/core/fling/BUILD index 268e94aacc1..0c16b2a8799 100644 --- a/test/core/fling/BUILD +++ b/test/core/fling/BUILD @@ -21,7 +21,7 @@ licenses(["notice"]) # Apache v2 load("//test/core/util:grpc_fuzzer.bzl", "grpc_fuzzer") grpc_cc_binary( - name = "client", + name = "fling_client", testonly = 1, srcs = ["client.cc"], language = "C++", @@ -29,13 +29,12 @@ grpc_cc_binary( "//:gpr", "//:grpc", "//test/core/end2end:ssl_test_data", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) grpc_cc_binary( - name = "server", + name = "fling_server", testonly = 1, srcs = ["server.cc"], language = "C++", @@ -43,7 +42,6 @@ grpc_cc_binary( "//:gpr", "//:grpc", "//test/core/end2end:ssl_test_data", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -52,14 +50,13 @@ grpc_cc_test( name = "fling", srcs = ["fling_test.cc"], data = [ - ":client", - ":server", + ":fling_client", + ":fling_server", ], deps = [ "//:gpr", "//:grpc", "//test/core/end2end:ssl_test_data", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -68,14 +65,13 @@ grpc_cc_test( name = "fling_stream", srcs = ["fling_stream_test.cc"], data = [ - ":client", - ":server", + ":fling_client", + ":fling_server", ], deps = [ "//:gpr", "//:grpc", "//test/core/end2end:ssl_test_data", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/fling/client.cc b/test/core/fling/client.cc index 05dc3052d1b..2a7a5ca6232 100644 --- a/test/core/fling/client.cc +++ b/test/core/fling/client.cc @@ -158,11 +158,11 @@ int main(int argc, char** argv) { gpr_timers_set_log_filename("latency_trace.fling_client.txt"); - grpc_init(); - GPR_ASSERT(argc >= 1); fake_argv[0] = argv[0]; - grpc_test_init(1, fake_argv); + grpc::testing::TestEnvironment env(1, fake_argv); + + grpc_init(); int warmup_seconds = 1; int benchmark_seconds = 5; diff --git a/test/core/gpr/BUILD b/test/core/gpr/BUILD index d58d4f2a14d..434d55e0451 100644 --- a/test/core/gpr/BUILD +++ b/test/core/gpr/BUILD @@ -24,7 +24,7 @@ grpc_cc_test( language = "C++", deps = [ "//:gpr", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -34,7 +34,7 @@ grpc_cc_test( language = "C++", deps = [ "//:gpr", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -44,7 +44,7 @@ grpc_cc_test( language = "C++", deps = [ "//:gpr", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -54,7 +54,7 @@ grpc_cc_test( language = "C++", deps = [ "//:gpr", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -64,7 +64,7 @@ grpc_cc_test( language = "C++", deps = [ "//:gpr", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -74,19 +74,19 @@ grpc_cc_test( language = "C++", deps = [ "//:gpr", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) grpc_cc_test( name = "mpscq_test", srcs = ["mpscq_test.cc"], + exec_compatible_with = ["//third_party/toolchains/machine_size:large"], language = "C++", deps = [ "//:gpr", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], - data = ["//third_party/toolchains:RBE_USE_MACHINE_TYPE_LARGE"], ) grpc_cc_test( @@ -95,7 +95,7 @@ grpc_cc_test( language = "C++", deps = [ "//:gpr", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -105,7 +105,7 @@ grpc_cc_test( language = "C++", deps = [ "//:gpr", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -115,7 +115,7 @@ grpc_cc_test( language = "C++", deps = [ "//:gpr", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -125,7 +125,7 @@ grpc_cc_test( language = "C++", deps = [ "//:gpr", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -135,7 +135,7 @@ grpc_cc_test( language = "C++", deps = [ "//:gpr", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -145,7 +145,7 @@ grpc_cc_test( language = "C++", deps = [ "//:gpr", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -155,6 +155,6 @@ grpc_cc_test( language = "C++", deps = [ "//:gpr", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/gpr/alloc_test.cc b/test/core/gpr/alloc_test.cc index 36cdc02ff22..0b110e2b77d 100644 --- a/test/core/gpr/alloc_test.cc +++ b/test/core/gpr/alloc_test.cc @@ -64,7 +64,7 @@ static void test_malloc_aligned() { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); test_custom_allocs(); test_malloc_aligned(); return 0; diff --git a/test/core/gpr/arena_test.cc b/test/core/gpr/arena_test.cc index 3e7c9065915..1df1052ab95 100644 --- a/test/core/gpr/arena_test.cc +++ b/test/core/gpr/arena_test.cc @@ -16,7 +16,7 @@ * */ -#include "src/core/lib/gpr/arena.h" +#include "src/core/lib/gprpp/arena.h" #include #include @@ -31,7 +31,9 @@ #include "src/core/lib/gprpp/thd.h" #include "test/core/util/test_config.h" -static void test_noop(void) { gpr_arena_destroy(gpr_arena_create(1)); } +using grpc_core::Arena; + +static void test_noop(void) { Arena::Create(1)->Destroy(); } static void test(const char* name, size_t init_size, const size_t* allocs, size_t nallocs) { @@ -50,10 +52,10 @@ static void test(const char* name, size_t init_size, const size_t* allocs, gpr_log(GPR_INFO, "%s", s); gpr_free(s); - gpr_arena* a = gpr_arena_create(init_size); + Arena* a = Arena::Create(init_size); void** ps = static_cast(gpr_zalloc(sizeof(*ps) * nallocs)); for (size_t i = 0; i < nallocs; i++) { - ps[i] = gpr_arena_alloc(a, allocs[i]); + ps[i] = a->Alloc(allocs[i]); // ensure the returned address is aligned GPR_ASSERT(((intptr_t)ps[i] & 0xf) == 0); // ensure no duplicate results @@ -63,7 +65,7 @@ static void test(const char* name, size_t init_size, const size_t* allocs, // ensure writable memset(ps[i], 1, allocs[i]); } - gpr_arena_destroy(a); + a->Destroy(); gpr_free(ps); } @@ -80,14 +82,14 @@ size_t concurrent_test_iterations() { typedef struct { gpr_event ev_start; - gpr_arena* arena; + Arena* arena; } concurrent_test_args; static void concurrent_test_body(void* arg) { concurrent_test_args* a = static_cast(arg); gpr_event_wait(&a->ev_start, gpr_inf_future(GPR_CLOCK_REALTIME)); for (size_t i = 0; i < concurrent_test_iterations(); i++) { - *static_cast(gpr_arena_alloc(a->arena, 1)) = static_cast(i); + *static_cast(a->arena->Alloc(1)) = static_cast(i); } } @@ -96,7 +98,7 @@ static void concurrent_test(void) { concurrent_test_args args; gpr_event_init(&args.ev_start); - args.arena = gpr_arena_create(1024); + args.arena = Arena::Create(1024); grpc_core::Thread thds[CONCURRENT_TEST_THREADS]; @@ -112,11 +114,11 @@ static void concurrent_test(void) { th.Join(); } - gpr_arena_destroy(args.arena); + args.arena->Destroy(); } int main(int argc, char* argv[]) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); test_noop(); TEST(0_1, 0, 1); diff --git a/test/core/gpr/cpu_test.cc b/test/core/gpr/cpu_test.cc index 1052d40b421..316a4c61bef 100644 --- a/test/core/gpr/cpu_test.cc +++ b/test/core/gpr/cpu_test.cc @@ -140,11 +140,13 @@ static void cpu_test(void) { } fprintf(stderr, "] (%d/%d)\n", cores_seen, ct.ncores); fflush(stderr); + gpr_mu_destroy(&ct.mu); + gpr_cv_destroy(&ct.done_cv); gpr_free(ct.used); } int main(int argc, char* argv[]) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); cpu_test(); return 0; } diff --git a/test/core/gpr/env_test.cc b/test/core/gpr/env_test.cc index 3f4b4932394..3883a5df997 100644 --- a/test/core/gpr/env_test.cc +++ b/test/core/gpr/env_test.cc @@ -42,8 +42,22 @@ static void test_setenv_getenv(void) { gpr_free(retrieved_value); } +static void test_unsetenv(void) { + const char* name = "FOO"; + const char* value = "BAR"; + char* retrieved_value; + + LOG_TEST_NAME("test_unsetenv"); + + gpr_setenv(name, value); + gpr_unsetenv(name); + retrieved_value = gpr_getenv(name); + GPR_ASSERT(retrieved_value == nullptr); +} + int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); test_setenv_getenv(); + test_unsetenv(); return 0; } diff --git a/test/core/gpr/host_port_test.cc b/test/core/gpr/host_port_test.cc index b5d88b2b011..b01bbf4b695 100644 --- a/test/core/gpr/host_port_test.cc +++ b/test/core/gpr/host_port_test.cc @@ -50,7 +50,7 @@ static void test_join_host_port_garbage(void) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); test_join_host_port(); test_join_host_port_garbage(); diff --git a/test/core/gpr/log_test.cc b/test/core/gpr/log_test.cc index 839ff0aef94..f96257738b2 100644 --- a/test/core/gpr/log_test.cc +++ b/test/core/gpr/log_test.cc @@ -53,7 +53,7 @@ static void test_should_not_log(gpr_log_func_args* args) { GPR_ASSERT(false); } gpr_log(SEVERITY, "hello %d %d %d", 1, 2, 3); int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); /* test logging at various verbosity levels */ gpr_log(GPR_DEBUG, "%s", "hello world"); gpr_log(GPR_INFO, "%s", "hello world"); diff --git a/test/core/gpr/mpscq_test.cc b/test/core/gpr/mpscq_test.cc index f51bdf8c502..744cea934c5 100644 --- a/test/core/gpr/mpscq_test.cc +++ b/test/core/gpr/mpscq_test.cc @@ -178,11 +178,12 @@ static void test_mt_multipop(void) { for (auto& th : thds) { th.Join(); } + gpr_mu_destroy(&pa.mu); gpr_mpscq_destroy(&q); } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); test_serial(); test_mt(); test_mt_multipop(); diff --git a/test/core/gpr/murmur_hash_test.cc b/test/core/gpr/murmur_hash_test.cc index 2d2fa72cfbc..fdc2cfa76b3 100644 --- a/test/core/gpr/murmur_hash_test.cc +++ b/test/core/gpr/murmur_hash_test.cc @@ -64,7 +64,7 @@ static void verification_test(hash_func hash, uint32_t expected) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); /* basic tests to verify that things don't crash */ gpr_murmur_hash3("", 0, 0); gpr_murmur_hash3("xyz", 3, 0); diff --git a/test/core/gpr/spinlock_test.cc b/test/core/gpr/spinlock_test.cc index 0ee72edb153..8bd9396da6e 100644 --- a/test/core/gpr/spinlock_test.cc +++ b/test/core/gpr/spinlock_test.cc @@ -149,7 +149,7 @@ static void inctry(void* v /*=m*/) { /* ------------------------------------------------- */ int main(int argc, char* argv[]) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); test("spinlock", &inc, 1, 1); test("spinlock try", &inctry, 1, 1); return 0; diff --git a/test/core/gpr/string_test.cc b/test/core/gpr/string_test.cc index 9f3b3124658..5e3ed9d5dfd 100644 --- a/test/core/gpr/string_test.cc +++ b/test/core/gpr/string_test.cc @@ -279,23 +279,24 @@ static void test_memrchr(void) { GPR_ASSERT(0 == strcmp((const char*)gpr_memrchr("hello", 'l', 5), "lo")); } -static void test_is_true(void) { - LOG_TEST_NAME("test_is_true"); +static void test_parse_bool_value(void) { + LOG_TEST_NAME("test_parse_bool_value"); - GPR_ASSERT(true == gpr_is_true("True")); - GPR_ASSERT(true == gpr_is_true("true")); - GPR_ASSERT(true == gpr_is_true("TRUE")); - GPR_ASSERT(true == gpr_is_true("Yes")); - GPR_ASSERT(true == gpr_is_true("yes")); - GPR_ASSERT(true == gpr_is_true("YES")); - GPR_ASSERT(true == gpr_is_true("1")); - GPR_ASSERT(false == gpr_is_true(nullptr)); - GPR_ASSERT(false == gpr_is_true("")); - GPR_ASSERT(false == gpr_is_true("0")); + bool ret; + GPR_ASSERT(true == gpr_parse_bool_value("truE", &ret) && true == ret); + GPR_ASSERT(true == gpr_parse_bool_value("falsE", &ret) && false == ret); + GPR_ASSERT(true == gpr_parse_bool_value("1", &ret) && true == ret); + GPR_ASSERT(true == gpr_parse_bool_value("0", &ret) && false == ret); + GPR_ASSERT(true == gpr_parse_bool_value("Yes", &ret) && true == ret); + GPR_ASSERT(true == gpr_parse_bool_value("No", &ret) && false == ret); + GPR_ASSERT(true == gpr_parse_bool_value("Y", &ret) && true == ret); + GPR_ASSERT(true == gpr_parse_bool_value("N", &ret) && false == ret); + GPR_ASSERT(false == gpr_parse_bool_value(nullptr, &ret)); + GPR_ASSERT(false == gpr_parse_bool_value("", &ret)); } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); test_strdup(); test_dump(); test_parse_uint32(); @@ -307,6 +308,6 @@ int main(int argc, char** argv) { test_leftpad(); test_stricmp(); test_memrchr(); - test_is_true(); + test_parse_bool_value(); return 0; } diff --git a/test/core/gpr/sync_test.cc b/test/core/gpr/sync_test.cc index 24b4562819f..fc7216e3601 100644 --- a/test/core/gpr/sync_test.cc +++ b/test/core/gpr/sync_test.cc @@ -458,7 +458,7 @@ static void refcheck(void* v /*=m*/) { /* ------------------------------------------------- */ int main(int argc, char* argv[]) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); test("mutex", &inc, nullptr, 1, 1); test("mutex try", &inctry, nullptr, 1, 1); test("cv", &inc_by_turns, nullptr, 1, 1); diff --git a/test/core/gpr/time_test.cc b/test/core/gpr/time_test.cc index 6f070f58df1..a32cbfb09aa 100644 --- a/test/core/gpr/time_test.cc +++ b/test/core/gpr/time_test.cc @@ -254,7 +254,7 @@ static void test_cmp_extreme(void) { } int main(int argc, char* argv[]) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); test_values(); test_add_sub(); diff --git a/test/core/gpr/tls_test.cc b/test/core/gpr/tls_test.cc index 0502fc7ef4d..d1bed0aafe3 100644 --- a/test/core/gpr/tls_test.cc +++ b/test/core/gpr/tls_test.cc @@ -50,7 +50,7 @@ static void thd_body(void* arg) { int main(int argc, char* argv[]) { grpc_core::Thread threads[NUM_THREADS]; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); gpr_tls_init(&test_var); diff --git a/test/core/gpr/useful_test.cc b/test/core/gpr/useful_test.cc index 619c800c4d9..4f8582ab415 100644 --- a/test/core/gpr/useful_test.cc +++ b/test/core/gpr/useful_test.cc @@ -26,7 +26,7 @@ int main(int argc, char** argv) { int four[4]; int five[5]; uint32_t bitset = 0; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); GPR_ASSERT(GPR_MIN(1, 2) == 1); GPR_ASSERT(GPR_MAX(1, 2) == 2); diff --git a/test/core/gprpp/BUILD b/test/core/gprpp/BUILD index e7232d9df81..cd3232addfd 100644 --- a/test/core/gprpp/BUILD +++ b/test/core/gprpp/BUILD @@ -24,7 +24,33 @@ grpc_cc_test( language = "C++", deps = [ "//:gpr", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + ], +) + +grpc_cc_test( + name = "global_config_test", + srcs = ["global_config_test.cc"], + external_deps = [ + "gtest", + ], + language = "C++", + deps = [ + "//:gpr", + "//test/core/util:grpc_test_util", + ], +) + +grpc_cc_test( + name = "global_config_env_test", + srcs = ["global_config_env_test.cc"], + external_deps = [ + "gtest", + ], + language = "C++", + deps = [ + "//:gpr", + "//test/core/util:grpc_test_util", ], ) @@ -34,7 +60,20 @@ grpc_cc_test( language = "C++", deps = [ "//:gpr", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + ], +) + +grpc_cc_test( + name = "grpc_core_map_test", + srcs = ["map_test.cc"], + external_deps = [ + "gtest", + ], + language = "C++", + deps = [ + "//:gpr_base", + "//test/core/util:grpc_test_util", ], ) @@ -47,7 +86,7 @@ grpc_cc_test( language = "C++", deps = [ "//:gpr_base", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -60,7 +99,20 @@ grpc_cc_test( language = "C++", deps = [ "//:inlined_vector", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + ], +) + +grpc_cc_test( + name = "optional_test", + srcs = ["optional_test.cc"], + external_deps = [ + "gtest", + ], + language = "C++", + deps = [ + "//:optional", + "//test/core/util:grpc_test_util", ], ) @@ -73,7 +125,7 @@ grpc_cc_test( language = "C++", deps = [ "//:orphanable", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -86,7 +138,7 @@ grpc_cc_test( language = "C++", deps = [ "//:ref_counted", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -100,7 +152,7 @@ grpc_cc_test( deps = [ "//:ref_counted", "//:ref_counted_ptr", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -110,6 +162,6 @@ grpc_cc_test( language = "C++", deps = [ "//:gpr", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/gprpp/fork_test.cc b/test/core/gprpp/fork_test.cc index 642f910489c..0f56eead49d 100644 --- a/test/core/gprpp/fork_test.cc +++ b/test/core/gprpp/fork_test.cc @@ -130,7 +130,7 @@ static void test_exec_count() { } int main(int argc, char* argv[]) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); test_init(); test_thd_count(); test_exec_count(); diff --git a/test/core/gprpp/global_config_env_test.cc b/test/core/gprpp/global_config_env_test.cc new file mode 100644 index 00000000000..74905d3b07c --- /dev/null +++ b/test/core/gprpp/global_config_env_test.cc @@ -0,0 +1,130 @@ +/* + * + * Copyright 2019 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 +#include + +#include + +#include +#include + +#include "src/core/lib/gpr/env.h" +#include "src/core/lib/gprpp/global_config_env.h" +#include "src/core/lib/gprpp/memory.h" + +namespace { + +bool g_config_error_function_called; + +void ClearConfigErrorCalled() { g_config_error_function_called = false; } + +bool IsConfigErrorCalled() { return g_config_error_function_called; } + +// This function is for preventing the program from invoking +// an error handler due to configuration error and +// make test routines know whether there is error. +void FakeConfigErrorFunction(const char* error_message) { + g_config_error_function_called = true; +} + +class GlobalConfigEnvTest : public ::testing::Test { + protected: + void SetUp() override { ClearConfigErrorCalled(); } + void TearDown() override { EXPECT_FALSE(IsConfigErrorCalled()); } +}; + +} // namespace + +GPR_GLOBAL_CONFIG_DEFINE_BOOL(bool_var, true, ""); +GPR_GLOBAL_CONFIG_DEFINE_INT32(int32_var, 1234, ""); +GPR_GLOBAL_CONFIG_DEFINE_STRING(string_var, "Apple", ""); + +TEST_F(GlobalConfigEnvTest, BoolWithEnvTest) { + const char* bool_var_name = "BOOL_VAR"; + + gpr_unsetenv(bool_var_name); + EXPECT_TRUE(GPR_GLOBAL_CONFIG_GET(bool_var)); + + gpr_setenv(bool_var_name, "true"); + EXPECT_TRUE(GPR_GLOBAL_CONFIG_GET(bool_var)); + + gpr_setenv(bool_var_name, "false"); + EXPECT_FALSE(GPR_GLOBAL_CONFIG_GET(bool_var)); + + EXPECT_FALSE(IsConfigErrorCalled()); + + gpr_setenv(bool_var_name, ""); + GPR_GLOBAL_CONFIG_GET(bool_var); + EXPECT_TRUE(IsConfigErrorCalled()); + ClearConfigErrorCalled(); + + gpr_setenv(bool_var_name, "!"); + GPR_GLOBAL_CONFIG_GET(bool_var); + EXPECT_TRUE(IsConfigErrorCalled()); + ClearConfigErrorCalled(); +} + +TEST_F(GlobalConfigEnvTest, Int32WithEnvTest) { + const char* int32_var_name = "INT32_VAR"; + + gpr_unsetenv(int32_var_name); + EXPECT_EQ(1234, GPR_GLOBAL_CONFIG_GET(int32_var)); + + gpr_setenv(int32_var_name, "0"); + EXPECT_EQ(0, GPR_GLOBAL_CONFIG_GET(int32_var)); + + gpr_setenv(int32_var_name, "-123456789"); + EXPECT_EQ(-123456789, GPR_GLOBAL_CONFIG_GET(int32_var)); + + gpr_setenv(int32_var_name, "123456789"); + EXPECT_EQ(123456789, GPR_GLOBAL_CONFIG_GET(int32_var)); + + EXPECT_FALSE(IsConfigErrorCalled()); + + gpr_setenv(int32_var_name, "-1AB"); + GPR_GLOBAL_CONFIG_GET(int32_var); + EXPECT_TRUE(IsConfigErrorCalled()); + ClearConfigErrorCalled(); +} + +TEST_F(GlobalConfigEnvTest, StringWithEnvTest) { + const char* string_var_name = "STRING_VAR"; + grpc_core::UniquePtr value; + + gpr_unsetenv(string_var_name); + value = GPR_GLOBAL_CONFIG_GET(string_var); + EXPECT_EQ(0, strcmp(value.get(), "Apple")); + + gpr_setenv(string_var_name, "Banana"); + value = GPR_GLOBAL_CONFIG_GET(string_var); + EXPECT_EQ(0, strcmp(value.get(), "Banana")); + + gpr_setenv(string_var_name, ""); + value = GPR_GLOBAL_CONFIG_GET(string_var); + EXPECT_EQ(0, strcmp(value.get(), "")); +} + +int main(int argc, char** argv) { + // Not to abort the test when parsing error happens. + grpc_core::SetGlobalConfigEnvErrorFunction(&FakeConfigErrorFunction); + + ::testing::InitGoogleTest(&argc, argv); + int ret = RUN_ALL_TESTS(); + return ret; +} diff --git a/test/core/gprpp/global_config_test.cc b/test/core/gprpp/global_config_test.cc new file mode 100644 index 00000000000..7da78b690b1 --- /dev/null +++ b/test/core/gprpp/global_config_test.cc @@ -0,0 +1,65 @@ +/* + * + * Copyright 2019 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 +#include + +#include + +#include +#include + +#include "src/core/lib/gpr/env.h" +#include "src/core/lib/gprpp/global_config.h" +#include "src/core/lib/gprpp/memory.h" + +GPR_GLOBAL_CONFIG_DECLARE_BOOL(bool_var); + +GPR_GLOBAL_CONFIG_DEFINE_BOOL(bool_var, false, ""); +GPR_GLOBAL_CONFIG_DEFINE_INT32(int32_var, 0, ""); +GPR_GLOBAL_CONFIG_DEFINE_STRING(string_var, "", ""); + +TEST(GlobalConfigTest, BoolTest) { + EXPECT_FALSE(GPR_GLOBAL_CONFIG_GET(bool_var)); + GPR_GLOBAL_CONFIG_SET(bool_var, true); + EXPECT_TRUE(GPR_GLOBAL_CONFIG_GET(bool_var)); +} + +TEST(GlobalConfigTest, Int32Test) { + EXPECT_EQ(0, GPR_GLOBAL_CONFIG_GET(int32_var)); + GPR_GLOBAL_CONFIG_SET(int32_var, 1024); + EXPECT_EQ(1024, GPR_GLOBAL_CONFIG_GET(int32_var)); +} + +TEST(GlobalConfigTest, StringTest) { + grpc_core::UniquePtr value; + + value = GPR_GLOBAL_CONFIG_GET(string_var); + EXPECT_EQ(0, strcmp(value.get(), "")); + + GPR_GLOBAL_CONFIG_SET(string_var, "Test"); + + value = GPR_GLOBAL_CONFIG_GET(string_var); + EXPECT_EQ(0, strcmp(value.get(), "Test")); +} + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + int ret = RUN_ALL_TESTS(); + return ret; +} diff --git a/test/core/gprpp/inlined_vector_test.cc b/test/core/gprpp/inlined_vector_test.cc index 73e0773b31d..f943128f53c 100644 --- a/test/core/gprpp/inlined_vector_test.cc +++ b/test/core/gprpp/inlined_vector_test.cc @@ -116,7 +116,7 @@ typedef InlinedVector IntVec8; const size_t kInlinedFillSize = kInlinedLength - 1; const size_t kAllocatedFillSize = kInlinedLength + 1; -TEST(InlinedVectorTest, CopyConstructerInlined) { +TEST(InlinedVectorTest, CopyConstructorInlined) { IntVec8 original; FillVector(&original, kInlinedFillSize); IntVec8 copy_constructed(original); @@ -125,7 +125,7 @@ TEST(InlinedVectorTest, CopyConstructerInlined) { } } -TEST(InlinedVectorTest, CopyConstructerAllocated) { +TEST(InlinedVectorTest, CopyConstructorAllocated) { IntVec8 original; FillVector(&original, kAllocatedFillSize); IntVec8 copy_constructed(original); @@ -264,6 +264,166 @@ TEST(InlinedVectorTest, MoveAssignmentAllocatedAllocated) { EXPECT_EQ(move_assigned.data(), old_data); } +// A copyable and movable value class, used to test that elements' copy +// and move methods are called correctly. +class Value { + public: + explicit Value(int v) : value_(MakeUnique(v)) {} + + // copyable + Value(const Value& v) { + value_ = MakeUnique(*v.value_); + copied_ = true; + } + Value& operator=(const Value& v) { + value_ = MakeUnique(*v.value_); + copied_ = true; + return *this; + } + + // movable + Value(Value&& v) { + value_ = std::move(v.value_); + moved_ = true; + } + Value& operator=(Value&& v) { + value_ = std::move(v.value_); + moved_ = true; + return *this; + } + + const UniquePtr& value() const { return value_; } + bool copied() const { return copied_; } + bool moved() const { return moved_; } + + private: + UniquePtr value_; + bool copied_ = false; + bool moved_ = false; +}; + +TEST(InlinedVectorTest, CopyConstructorCopiesElementsInlined) { + InlinedVector v1; + v1.emplace_back(3); + InlinedVector v2(v1); + EXPECT_EQ(v2.size(), 1UL); + EXPECT_EQ(*v2[0].value(), 3); + // Addresses should differ. + EXPECT_NE(v1[0].value().get(), v2[0].value().get()); + EXPECT_TRUE(v2[0].copied()); +} + +TEST(InlinedVectorTest, CopyConstructorCopiesElementsAllocated) { + InlinedVector v1; + v1.reserve(2); + v1.emplace_back(3); + v1.emplace_back(5); + InlinedVector v2(v1); + EXPECT_EQ(v2.size(), 2UL); + EXPECT_EQ(*v2[0].value(), 3); + EXPECT_EQ(*v2[1].value(), 5); + // Addresses should differ. + EXPECT_NE(v1[0].value().get(), v2[0].value().get()); + EXPECT_NE(v1[1].value().get(), v2[1].value().get()); + EXPECT_TRUE(v2[0].copied()); + EXPECT_TRUE(v2[1].copied()); +} + +TEST(InlinedVectorTest, CopyAssignmentCopiesElementsInlined) { + InlinedVector v1; + v1.emplace_back(3); + InlinedVector v2; + EXPECT_EQ(v2.size(), 0UL); + v2 = v1; + EXPECT_EQ(v2.size(), 1UL); + EXPECT_EQ(*v2[0].value(), 3); + // Addresses should differ. + EXPECT_NE(v1[0].value().get(), v2[0].value().get()); + EXPECT_TRUE(v2[0].copied()); +} + +TEST(InlinedVectorTest, CopyAssignmentCopiesElementsAllocated) { + InlinedVector v1; + v1.reserve(2); + v1.emplace_back(3); + v1.emplace_back(5); + InlinedVector v2; + EXPECT_EQ(v2.size(), 0UL); + v2 = v1; + EXPECT_EQ(v2.size(), 2UL); + EXPECT_EQ(*v2[0].value(), 3); + EXPECT_EQ(*v2[1].value(), 5); + // Addresses should differ. + EXPECT_NE(v1[0].value().get(), v2[0].value().get()); + EXPECT_NE(v1[1].value().get(), v2[1].value().get()); + EXPECT_TRUE(v2[0].copied()); + EXPECT_TRUE(v2[1].copied()); +} + +TEST(InlinedVectorTest, MoveConstructorMovesElementsInlined) { + InlinedVector v1; + v1.emplace_back(3); + int* addr = v1[0].value().get(); + InlinedVector v2(std::move(v1)); + EXPECT_EQ(v2.size(), 1UL); + EXPECT_EQ(*v2[0].value(), 3); + EXPECT_EQ(addr, v2[0].value().get()); + EXPECT_TRUE(v2[0].moved()); +} + +TEST(InlinedVectorTest, MoveConstructorMovesElementsAllocated) { + InlinedVector v1; + v1.reserve(2); + v1.emplace_back(3); + v1.emplace_back(5); + int* addr1 = v1[0].value().get(); + int* addr2 = v1[1].value().get(); + Value* data1 = v1.data(); + InlinedVector v2(std::move(v1)); + EXPECT_EQ(v2.size(), 2UL); + EXPECT_EQ(*v2[0].value(), 3); + EXPECT_EQ(*v2[1].value(), 5); + EXPECT_EQ(addr1, v2[0].value().get()); + EXPECT_EQ(addr2, v2[1].value().get()); + // In this case, elements won't be moved, because we have just stolen + // the underlying storage. + EXPECT_EQ(data1, v2.data()); +} + +TEST(InlinedVectorTest, MoveAssignmentMovesElementsInlined) { + InlinedVector v1; + v1.emplace_back(3); + int* addr = v1[0].value().get(); + InlinedVector v2; + EXPECT_EQ(v2.size(), 0UL); + v2 = std::move(v1); + EXPECT_EQ(v2.size(), 1UL); + EXPECT_EQ(*v2[0].value(), 3); + EXPECT_EQ(addr, v2[0].value().get()); + EXPECT_TRUE(v2[0].moved()); +} + +TEST(InlinedVectorTest, MoveAssignmentMovesElementsAllocated) { + InlinedVector v1; + v1.reserve(2); + v1.emplace_back(3); + v1.emplace_back(5); + int* addr1 = v1[0].value().get(); + int* addr2 = v1[1].value().get(); + Value* data1 = v1.data(); + InlinedVector v2; + EXPECT_EQ(v2.size(), 0UL); + v2 = std::move(v1); + EXPECT_EQ(v2.size(), 2UL); + EXPECT_EQ(*v2[0].value(), 3); + EXPECT_EQ(*v2[1].value(), 5); + EXPECT_EQ(addr1, v2[0].value().get()); + EXPECT_EQ(addr2, v2[1].value().get()); + // In this case, elements won't be moved, because we have just stolen + // the underlying storage. + EXPECT_EQ(data1, v2.data()); +} + TEST(InlinedVectorTest, PopBackInlined) { InlinedVector, 2> v; // Add two elements, pop one out @@ -294,7 +454,7 @@ TEST(InlinedVectorTest, PopBackAllocated) { } // namespace grpc_core int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/core/gprpp/manual_constructor_test.cc b/test/core/gprpp/manual_constructor_test.cc index af162ae8e8a..a5a45133d86 100644 --- a/test/core/gprpp/manual_constructor_test.cc +++ b/test/core/gprpp/manual_constructor_test.cc @@ -92,7 +92,7 @@ static void complex_test() { /* ------------------------------------------------- */ int main(int argc, char* argv[]) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); basic_test(); complex_test(); return 0; diff --git a/test/core/gprpp/map_test.cc b/test/core/gprpp/map_test.cc new file mode 100644 index 00000000000..e70bf38f111 --- /dev/null +++ b/test/core/gprpp/map_test.cc @@ -0,0 +1,409 @@ +/* + * + * 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 "src/core/lib/gprpp/map.h" +#include +#include "include/grpc/support/string_util.h" +#include "src/core/lib/gprpp/inlined_vector.h" +#include "src/core/lib/gprpp/memory.h" +#include "src/core/lib/gprpp/orphanable.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" +#include "test/core/util/test_config.h" + +namespace grpc_core { +namespace testing { +class Payload { + public: + Payload() : data_(-1) {} + explicit Payload(int data) : data_(data) {} + Payload(const Payload& other) : data_(other.data_) {} + Payload& operator=(const Payload& other) { + if (this != &other) { + data_ = other.data_; + } + return *this; + } + int data() { return data_; } + + private: + int data_; +}; + +inline UniquePtr CopyString(const char* string) { + return UniquePtr(gpr_strdup(string)); +} + +static constexpr char kKeys[][4] = {"abc", "efg", "hij", "klm", "xyz"}; + +class MapTest : public ::testing::Test { + public: + template + typename ::grpc_core::Map::Entry* Root( + typename ::grpc_core::Map* map) { + return map->root_; + } +}; + +// Test insertion of Payload +TEST_F(MapTest, EmplaceAndFind) { + Map test_map; + for (int i = 0; i < 5; i++) { + test_map.emplace(kKeys[i], Payload(i)); + } + for (int i = 0; i < 5; i++) { + EXPECT_EQ(i, test_map.find(kKeys[i])->second.data()); + } +} + +// Test insertion of Payload Unique Ptrs +TEST_F(MapTest, EmplaceAndFindWithUniquePtrValue) { + Map, StringLess> test_map; + for (int i = 0; i < 5; i++) { + test_map.emplace(kKeys[i], MakeUnique(i)); + } + for (int i = 0; i < 5; i++) { + EXPECT_EQ(i, test_map.find(kKeys[i])->second->data()); + } +} + +// Test insertion of Unique Ptr kKeys and Payload +TEST_F(MapTest, EmplaceAndFindWithUniquePtrKey) { + Map, Payload, StringLess> test_map; + for (int i = 0; i < 5; i++) { + test_map.emplace(CopyString(kKeys[i]), Payload(i)); + } + for (int i = 0; i < 5; i++) { + EXPECT_EQ(i, test_map.find(CopyString(kKeys[i]))->second.data()); + } +} + +// Test insertion of Payload +TEST_F(MapTest, InsertAndFind) { + Map test_map; + for (int i = 0; i < 5; i++) { + test_map.insert(MakePair(kKeys[i], Payload(i))); + } + for (int i = 0; i < 5; i++) { + EXPECT_EQ(i, test_map.find(kKeys[i])->second.data()); + } +} + +// Test insertion of Payload Unique Ptrs +TEST_F(MapTest, InsertAndFindWithUniquePtrValue) { + Map, StringLess> test_map; + for (int i = 0; i < 5; i++) { + test_map.insert(MakePair(kKeys[i], MakeUnique(i))); + } + for (int i = 0; i < 5; i++) { + EXPECT_EQ(i, test_map.find(kKeys[i])->second->data()); + } +} + +// Test insertion of Unique Ptr kKeys and Payload +TEST_F(MapTest, InsertAndFindWithUniquePtrKey) { + Map, Payload, StringLess> test_map; + for (int i = 0; i < 5; i++) { + test_map.insert(MakePair(CopyString(kKeys[i]), Payload(i))); + } + for (int i = 0; i < 5; i++) { + EXPECT_EQ(i, test_map.find(CopyString(kKeys[i]))->second.data()); + } +} + +// Test bracket operators +TEST_F(MapTest, BracketOperator) { + Map test_map; + for (int i = 0; i < 5; i++) { + test_map[kKeys[i]] = Payload(i); + } + for (int i = 0; i < 5; i++) { + EXPECT_EQ(i, test_map[kKeys[i]].data()); + } +} + +// Test bracket operators with unique pointer to payload +TEST_F(MapTest, BracketOperatorWithUniquePtrValue) { + Map, StringLess> test_map; + for (int i = 0; i < 5; i++) { + test_map[kKeys[i]] = MakeUnique(i); + } + for (int i = 0; i < 5; i++) { + EXPECT_EQ(i, test_map[kKeys[i]]->data()); + } +} + +// Test bracket operators with unique pointer to payload +TEST_F(MapTest, BracketOperatorWithUniquePtrKey) { + Map, Payload, StringLess> test_map; + for (int i = 0; i < 5; i++) { + test_map[CopyString(kKeys[i])] = Payload(i); + } + for (int i = 0; i < 5; i++) { + EXPECT_EQ(i, test_map[CopyString(kKeys[i])].data()); + } +} + +// Test removal of a single value +TEST_F(MapTest, Erase) { + Map test_map; + for (int i = 0; i < 5; i++) { + test_map.emplace(kKeys[i], Payload(i)); + } + EXPECT_EQ(test_map.size(), 5UL); + EXPECT_EQ(test_map.erase(kKeys[3]), 1UL); // Remove "hij" + for (int i = 0; i < 5; i++) { + if (i == 3) { // "hij" should not be present + EXPECT_TRUE(test_map.find(kKeys[i]) == test_map.end()); + } else { + EXPECT_EQ(i, test_map.find(kKeys[i])->second.data()); + } + } + EXPECT_EQ(test_map.size(), 4UL); +} + +// Test removal of a single value with unique ptr to payload +TEST_F(MapTest, EraseWithUniquePtrValue) { + Map, StringLess> test_map; + for (int i = 0; i < 5; i++) { + test_map.emplace(kKeys[i], MakeUnique(i)); + } + EXPECT_EQ(test_map.size(), 5UL); + test_map.erase(kKeys[3]); // Remove "hij" + for (int i = 0; i < 5; i++) { + if (i == 3) { // "hij" should not be present + EXPECT_TRUE(test_map.find(kKeys[i]) == test_map.end()); + } else { + EXPECT_EQ(i, test_map.find(kKeys[i])->second->data()); + } + } + EXPECT_EQ(test_map.size(), 4UL); +} + +// Test removal of a single value +TEST_F(MapTest, EraseWithUniquePtrKey) { + Map, Payload, StringLess> test_map; + for (int i = 0; i < 5; i++) { + test_map.emplace(CopyString(kKeys[i]), Payload(i)); + } + EXPECT_EQ(test_map.size(), 5UL); + test_map.erase(CopyString(kKeys[3])); // Remove "hij" + for (int i = 0; i < 5; i++) { + if (i == 3) { // "hij" should not be present + EXPECT_TRUE(test_map.find(CopyString(kKeys[i])) == test_map.end()); + } else { + EXPECT_EQ(i, test_map.find(CopyString(kKeys[i]))->second.data()); + } + } + EXPECT_EQ(test_map.size(), 4UL); +} + +// Test clear +TEST_F(MapTest, SizeAndClear) { + Map test_map; + for (int i = 0; i < 5; i++) { + test_map.emplace(kKeys[i], Payload(i)); + } + EXPECT_EQ(test_map.size(), 5UL); + EXPECT_FALSE(test_map.empty()); + test_map.clear(); + EXPECT_EQ(test_map.size(), 0UL); + EXPECT_TRUE(test_map.empty()); +} + +// Test clear with unique ptr payload +TEST_F(MapTest, SizeAndClearWithUniquePtrValue) { + Map, StringLess> test_map; + for (int i = 0; i < 5; i++) { + test_map.emplace(kKeys[i], MakeUnique(i)); + } + EXPECT_EQ(test_map.size(), 5UL); + EXPECT_FALSE(test_map.empty()); + test_map.clear(); + EXPECT_EQ(test_map.size(), 0UL); + EXPECT_TRUE(test_map.empty()); +} + +// Test clear with unique ptr char key +TEST_F(MapTest, SizeAndClearWithUniquePtrKey) { + Map, Payload, StringLess> test_map; + for (int i = 0; i < 5; i++) { + test_map.emplace(CopyString(kKeys[i]), Payload(i)); + } + EXPECT_EQ(test_map.size(), 5UL); + EXPECT_FALSE(test_map.empty()); + test_map.clear(); + EXPECT_EQ(test_map.size(), 0UL); + EXPECT_TRUE(test_map.empty()); +} + +// Test correction of Left-Left Tree imbalance +TEST_F(MapTest, MapLL) { + Map test_map; + for (int i = 2; i >= 0; i--) { + test_map.emplace(kKeys[i], Payload(i)); + } + EXPECT_EQ(strcmp(Root(&test_map)->pair.first, kKeys[1]), 0); + EXPECT_EQ(strcmp(Root(&test_map)->left->pair.first, kKeys[0]), 0); + EXPECT_EQ(strcmp(Root(&test_map)->right->pair.first, kKeys[2]), 0); +} + +// Test correction of Left-Right tree imbalance +TEST_F(MapTest, MapLR) { + Map test_map; + int insertion_key_index[] = {2, 0, 1}; + for (int i = 0; i < 3; i++) { + int key_index = insertion_key_index[i]; + test_map.emplace(kKeys[key_index], Payload(key_index)); + } + EXPECT_EQ(strcmp(Root(&test_map)->pair.first, kKeys[1]), 0); + EXPECT_EQ(strcmp(Root(&test_map)->left->pair.first, kKeys[0]), 0); + EXPECT_EQ(strcmp(Root(&test_map)->right->pair.first, kKeys[2]), 0); +} + +// Test correction of Right-Left tree imbalance +TEST_F(MapTest, MapRL) { + Map test_map; + int insertion_key_index[] = {0, 2, 1}; + for (int i = 0; i < 3; i++) { + int key_index = insertion_key_index[i]; + test_map.emplace(kKeys[key_index], Payload(key_index)); + } + EXPECT_EQ(strcmp(Root(&test_map)->pair.first, kKeys[1]), 0); + EXPECT_EQ(strcmp(Root(&test_map)->left->pair.first, kKeys[0]), 0); + EXPECT_EQ(strcmp(Root(&test_map)->right->pair.first, kKeys[2]), 0); +} + +// Test correction of Right-Right tree imbalance +TEST_F(MapTest, MapRR) { + Map test_map; + for (int i = 0; i < 5; i++) { + test_map.emplace(kKeys[i], Payload(i)); + } + EXPECT_EQ(strcmp(Root(&test_map)->pair.first, kKeys[1]), 0); + EXPECT_EQ(strcmp(Root(&test_map)->left->pair.first, kKeys[0]), 0); + EXPECT_EQ(strcmp(Root(&test_map)->right->pair.first, kKeys[3]), 0); + EXPECT_EQ(strcmp(Root(&test_map)->right->left->pair.first, kKeys[2]), 0); + EXPECT_EQ(strcmp(Root(&test_map)->right->right->pair.first, kKeys[4]), 0); +} + +// Test correction after random insertion +TEST_F(MapTest, MapRandomInsertions) { + Map test_map; + int insertion_key_index[] = {1, 4, 3, 0, 2}; + for (int i = 0; i < 5; i++) { + int key_index = insertion_key_index[i]; + test_map.emplace(kKeys[key_index], Payload(key_index)); + } + EXPECT_EQ(strcmp(Root(&test_map)->pair.first, kKeys[3]), 0); + EXPECT_EQ(strcmp(Root(&test_map)->left->pair.first, kKeys[1]), 0); + EXPECT_EQ(strcmp(Root(&test_map)->right->pair.first, kKeys[4]), 0); + EXPECT_EQ(strcmp(Root(&test_map)->left->right->pair.first, kKeys[2]), 0); + EXPECT_EQ(strcmp(Root(&test_map)->left->left->pair.first, kKeys[0]), 0); +} + +// Test Map iterator +TEST_F(MapTest, Iteration) { + Map test_map; + for (int i = 0; i < 5; i++) { + test_map.emplace(kKeys[i], Payload(i)); + } + int count = 0; + for (auto iter = test_map.begin(); iter != test_map.end(); iter++) { + EXPECT_EQ(iter->second.data(), count); + count++; + } + EXPECT_EQ(count, 5); +} + +// Test Map iterator with unique ptr payload +TEST_F(MapTest, IterationWithUniquePtrValue) { + Map, StringLess> test_map; + for (int i = 0; i < 5; i++) { + test_map.emplace(kKeys[i], MakeUnique(i)); + } + int count = 0; + for (auto iter = test_map.begin(); iter != test_map.end(); iter++) { + EXPECT_EQ(iter->second->data(), count); + count++; + } + EXPECT_EQ(count, 5); +} + +// Test Map iterator with unique ptr to char key +TEST_F(MapTest, IterationWithUniquePtrKey) { + Map, Payload, StringLess> test_map; + for (int i = 0; i < 5; i++) { + test_map.emplace(CopyString(kKeys[i]), Payload(i)); + } + int count = 0; + for (auto iter = test_map.begin(); iter != test_map.end(); iter++) { + EXPECT_EQ(iter->second.data(), count); + count++; + } + EXPECT_EQ(count, 5); +} + +// Test removing entries while iterating the map +TEST_F(MapTest, EraseUsingIterator) { + Map test_map; + for (int i = 0; i < 5; i++) { + test_map.emplace(kKeys[i], Payload(i)); + } + int count = 0; + for (auto iter = test_map.begin(); iter != test_map.end();) { + EXPECT_EQ(iter->second.data(), count); + iter = test_map.erase(iter); + count++; + } + EXPECT_EQ(count, 5); + EXPECT_TRUE(test_map.empty()); +} + +// Random ops on a Map with Integer key of Payload value, +// tests default comparator +TEST_F(MapTest, RandomOpsWithIntKey) { + Map test_map; + for (int i = 0; i < 5; i++) { + test_map.emplace(i, Payload(i)); + } + for (int i = 0; i < 5; i++) { + EXPECT_EQ(i, test_map.find(i)->second.data()); + } + for (int i = 0; i < 5; i++) { + test_map[i] = Payload(i + 10); + } + for (int i = 0; i < 5; i++) { + EXPECT_EQ(i + 10, test_map[i].data()); + } + EXPECT_EQ(test_map.erase(3), 1UL); + EXPECT_TRUE(test_map.find(3) == test_map.end()); + EXPECT_FALSE(test_map.empty()); + EXPECT_EQ(test_map.size(), 4UL); + test_map.clear(); + EXPECT_EQ(test_map.size(), 0UL); + EXPECT_TRUE(test_map.empty()); +} + +} // namespace testing +} // namespace grpc_core + +int main(int argc, char** argv) { + grpc::testing::TestEnvironment env(argc, argv); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/core/gprpp/memory_test.cc b/test/core/gprpp/memory_test.cc index 180c36fad7f..bb6a219a848 100644 --- a/test/core/gprpp/memory_test.cc +++ b/test/core/gprpp/memory_test.cc @@ -68,7 +68,7 @@ TEST(MemoryTest, UniquePtrWithCustomDeleter) { } // namespace grpc_core int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/core/gprpp/optional_test.cc b/test/core/gprpp/optional_test.cc new file mode 100644 index 00000000000..ce6f8692fd5 --- /dev/null +++ b/test/core/gprpp/optional_test.cc @@ -0,0 +1,50 @@ +/* + * + * Copyright 2019 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/lib/gprpp/optional.h" +#include +#include +#include "src/core/lib/gprpp/memory.h" +#include "test/core/util/test_config.h" + +namespace grpc_core { +namespace testing { + +namespace { +TEST(OptionalTest, BasicTest) { + grpc_core::Optional opt_val; + EXPECT_FALSE(opt_val.has_value()); + const int kTestVal = 123; + + opt_val.set(kTestVal); + EXPECT_TRUE(opt_val.has_value()); + EXPECT_EQ(opt_val.value(), kTestVal); + + opt_val.reset(); + EXPECT_EQ(opt_val.has_value(), false); +} +} // namespace + +} // namespace testing +} // namespace grpc_core + +int main(int argc, char** argv) { + grpc::testing::TestEnvironment env(argc, argv); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/core/gprpp/orphanable_test.cc b/test/core/gprpp/orphanable_test.cc index ad6b9ac8674..fe13df0d0d0 100644 --- a/test/core/gprpp/orphanable_test.cc +++ b/test/core/gprpp/orphanable_test.cc @@ -83,11 +83,11 @@ TEST(OrphanablePtr, InternallyRefCounted) { // things build properly in both debug and non-debug cases. DebugOnlyTraceFlag baz_tracer(true, "baz"); -class Baz : public InternallyRefCountedWithTracing { +class Baz : public InternallyRefCounted { public: Baz() : Baz(0) {} explicit Baz(int value) - : InternallyRefCountedWithTracing(&baz_tracer), value_(value) {} + : InternallyRefCounted(&baz_tracer), value_(value) {} void Orphan() override { Unref(); } int value() const { return value_; } @@ -114,7 +114,7 @@ TEST(OrphanablePtr, InternallyRefCountedWithTracing) { } // namespace grpc_core int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/core/gprpp/ref_counted_ptr_test.cc b/test/core/gprpp/ref_counted_ptr_test.cc index 463b5e89667..96dbdf884b0 100644 --- a/test/core/gprpp/ref_counted_ptr_test.cc +++ b/test/core/gprpp/ref_counted_ptr_test.cc @@ -163,9 +163,9 @@ TEST(MakeRefCounted, Args) { TraceFlag foo_tracer(true, "foo"); -class FooWithTracing : public RefCountedWithTracing { +class FooWithTracing : public RefCounted { public: - FooWithTracing() : RefCountedWithTracing(&foo_tracer) {} + FooWithTracing() : RefCounted(&foo_tracer) {} }; TEST(RefCountedPtr, RefCountedWithTracing) { @@ -241,7 +241,7 @@ TEST(RefCountedPtr, CanPassSubclassToFunctionExpectingSubclass) { } // namespace grpc_core int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/core/gprpp/ref_counted_test.cc b/test/core/gprpp/ref_counted_test.cc index 62a3ea4d53e..1955be33115 100644 --- a/test/core/gprpp/ref_counted_test.cc +++ b/test/core/gprpp/ref_counted_test.cc @@ -74,9 +74,9 @@ TEST(RefCountedNonPolymorphic, ExtraRef) { // things build properly in both debug and non-debug cases. DebugOnlyTraceFlag foo_tracer(true, "foo"); -class FooWithTracing : public RefCountedWithTracing { +class FooWithTracing : public RefCounted { public: - FooWithTracing() : RefCountedWithTracing(&foo_tracer) {} + FooWithTracing() : RefCounted(&foo_tracer) {} }; TEST(RefCountedWithTracing, Basic) { @@ -92,10 +92,9 @@ TEST(RefCountedWithTracing, Basic) { } class FooNonPolymorphicWithTracing - : public RefCountedWithTracing { + : public RefCounted { public: - FooNonPolymorphicWithTracing() : RefCountedWithTracing(&foo_tracer) {} + FooNonPolymorphicWithTracing() : RefCounted(&foo_tracer) {} }; TEST(RefCountedNonPolymorphicWithTracing, Basic) { @@ -116,7 +115,7 @@ TEST(RefCountedNonPolymorphicWithTracing, Basic) { } // namespace grpc_core int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/core/gprpp/thd_test.cc b/test/core/gprpp/thd_test.cc index 82dd681049b..eda78d95323 100644 --- a/test/core/gprpp/thd_test.cc +++ b/test/core/gprpp/thd_test.cc @@ -71,6 +71,8 @@ static void test1(void) { th.Join(); } GPR_ASSERT(t.n == 0); + gpr_mu_destroy(&t.mu); + gpr_cv_destroy(&t.done_cv); } static void thd_body2(void* v) {} @@ -92,7 +94,7 @@ static void test2(void) { /* ------------------------------------------------- */ int main(int argc, char* argv[]) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); test1(); test2(); return 0; diff --git a/test/core/handshake/BUILD b/test/core/handshake/BUILD index 712cd591977..0824efb980f 100644 --- a/test/core/handshake/BUILD +++ b/test/core/handshake/BUILD @@ -21,82 +21,80 @@ licenses(["notice"]) # Apache v2 grpc_cc_test( name = "client_ssl", srcs = ["client_ssl.cc"], - language = "C++", data = [ "//src/core/tsi/test_creds:ca.pem", "//src/core/tsi/test_creds:server1.key", "//src/core/tsi/test_creds:server1.pem", ], + language = "C++", deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], + tags = ["no_windows"], ) grpc_cc_library( name = "server_ssl_common", - hdrs = ["server_ssl_common.h"], srcs = ["server_ssl_common.cc"], + hdrs = ["server_ssl_common.h"], deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], + tags = ["no_windows"], ) grpc_cc_test( name = "server_ssl", srcs = ["server_ssl.cc"], - language = "C++", data = [ "//src/core/tsi/test_creds:ca.pem", "//src/core/tsi/test_creds:server1.key", "//src/core/tsi/test_creds:server1.pem", ], + language = "C++", deps = [ ":server_ssl_common", "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], + tags = ["no_windows"], ) grpc_cc_test( name = "handshake_server_with_readahead_handshaker", srcs = ["readahead_handshaker_server_ssl.cc"], - language = "C++", data = [ "//src/core/tsi/test_creds:ca.pem", "//src/core/tsi/test_creds:server1.key", "//src/core/tsi/test_creds:server1.pem", ], + language = "C++", deps = [ ":server_ssl_common", "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], + tags = ["no_windows"], ) grpc_cc_test( name = "handshake_verify_peer_options", srcs = ["verify_peer_options.cc"], - language = "C++", data = [ "//src/core/tsi/test_creds:ca.pem", "//src/core/tsi/test_creds:server1.key", "//src/core/tsi/test_creds:server1.pem", ], + language = "C++", deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) - diff --git a/test/core/handshake/readahead_handshaker_server_ssl.cc b/test/core/handshake/readahead_handshaker_server_ssl.cc index 14d96b5d89c..c0ab61136cb 100644 --- a/test/core/handshake/readahead_handshaker_server_ssl.cc +++ b/test/core/handshake/readahead_handshaker_server_ssl.cc @@ -49,53 +49,41 @@ * to the security_handshaker). This test is meant to protect code relying on * this functionality that lives outside of this repo. */ -static void readahead_handshaker_destroy(grpc_handshaker* handshaker) { - gpr_free(handshaker); -} +namespace grpc_core { -static void readahead_handshaker_shutdown(grpc_handshaker* handshaker, - grpc_error* error) {} +class ReadAheadHandshaker : public Handshaker { + public: + virtual ~ReadAheadHandshaker() {} + const char* name() const override { return "read_ahead"; } + void Shutdown(grpc_error* why) override {} + void DoHandshake(grpc_tcp_server_acceptor* acceptor, + grpc_closure* on_handshake_done, + HandshakerArgs* args) override { + grpc_endpoint_read(args->endpoint, args->read_buffer, on_handshake_done, + /*urgent=*/false); + } +}; -static void readahead_handshaker_do_handshake( - grpc_handshaker* handshaker, grpc_tcp_server_acceptor* acceptor, - grpc_closure* on_handshake_done, grpc_handshaker_args* args) { - grpc_endpoint_read(args->endpoint, args->read_buffer, on_handshake_done); -} +class ReadAheadHandshakerFactory : public HandshakerFactory { + public: + void AddHandshakers(const grpc_channel_args* args, + grpc_pollset_set* interested_parties, + HandshakeManager* handshake_mgr) override { + handshake_mgr->Add(MakeRefCounted()); + } + ~ReadAheadHandshakerFactory() override = default; +}; -const grpc_handshaker_vtable readahead_handshaker_vtable = { - readahead_handshaker_destroy, readahead_handshaker_shutdown, - readahead_handshaker_do_handshake, "read_ahead"}; - -static grpc_handshaker* readahead_handshaker_create() { - grpc_handshaker* h = - static_cast(gpr_zalloc(sizeof(grpc_handshaker))); - grpc_handshaker_init(&readahead_handshaker_vtable, h); - return h; -} - -static void readahead_handshaker_factory_add_handshakers( - grpc_handshaker_factory* hf, const grpc_channel_args* args, - grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr) { - grpc_handshake_manager_add(handshake_mgr, readahead_handshaker_create()); -} - -static void readahead_handshaker_factory_destroy( - grpc_handshaker_factory* handshaker_factory) {} - -static const grpc_handshaker_factory_vtable - readahead_handshaker_factory_vtable = { - readahead_handshaker_factory_add_handshakers, - readahead_handshaker_factory_destroy}; +} // namespace grpc_core int main(int argc, char* argv[]) { - grpc_handshaker_factory readahead_handshaker_factory = { - &readahead_handshaker_factory_vtable}; + using namespace grpc_core; grpc_init(); - grpc_handshaker_factory_register(true /* at_start */, HANDSHAKER_SERVER, - &readahead_handshaker_factory); + HandshakerRegistry::RegisterHandshakerFactory( + true /* at_start */, HANDSHAKER_SERVER, + UniquePtr(New())); const char* full_alpn_list[] = {"grpc-exp", "h2"}; GPR_ASSERT(server_ssl_test(full_alpn_list, 2, "grpc-exp")); - grpc_shutdown(); + grpc_shutdown_blocking(); return 0; } diff --git a/test/core/http/BUILD b/test/core/http/BUILD index be51ea07371..3e679262555 100644 --- a/test/core/http/BUILD +++ b/test/core/http/BUILD @@ -23,8 +23,8 @@ load("//test/core/util:grpc_fuzzer.bzl", "grpc_fuzzer") grpc_fuzzer( name = "response_fuzzer", srcs = ["response_fuzzer.cc"], - language = "C++", corpus = "response_corpus", + language = "C++", deps = [ "//:gpr", "//:grpc", @@ -35,8 +35,8 @@ grpc_fuzzer( grpc_fuzzer( name = "request_fuzzer", srcs = ["request_fuzzer.cc"], - language = "C++", corpus = "request_corpus", + language = "C++", deps = [ "//:gpr", "//:grpc", @@ -65,18 +65,17 @@ load("//test/core/util:grpc_fuzzer.bzl", "grpc_fuzzer") grpc_cc_test( name = "httpcli_test", srcs = ["httpcli_test.cc"], - language = "C++", data = [ "python_wrapper.sh", "test_server.py", + "//src/core/tsi/test_creds:server1.key", "//src/core/tsi/test_creds:server1.pem", - "//src/core/tsi/test_creds:server1.key" ], + language = "C++", deps = [ "//:gpr", "//:grpc", "//test/core/end2end:ssl_test_data", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -84,19 +83,18 @@ grpc_cc_test( grpc_cc_test( name = "httpscli_test", srcs = ["httpscli_test.cc"], - language = "C++", data = [ "python_wrapper.sh", "test_server.py", "//src/core/tsi/test_creds:ca.pem", + "//src/core/tsi/test_creds:server1.key", "//src/core/tsi/test_creds:server1.pem", - "//src/core/tsi/test_creds:server1.key" ], + language = "C++", deps = [ "//:gpr", "//:grpc", "//test/core/end2end:ssl_test_data", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -109,7 +107,6 @@ grpc_cc_test( "//:gpr", "//:grpc", "//test/core/end2end:ssl_test_data", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -122,7 +119,6 @@ grpc_cc_test( "//:gpr", "//:grpc", "//test/core/end2end:ssl_test_data", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/http/format_request_test.cc b/test/core/http/format_request_test.cc index 353e138b2a1..b0a90c4613b 100644 --- a/test/core/http/format_request_test.cc +++ b/test/core/http/format_request_test.cc @@ -138,7 +138,7 @@ static void test_format_post_request_content_type_override(void) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); test_format_get_request(); diff --git a/test/core/http/httpcli_test.cc b/test/core/http/httpcli_test.cc index a51a0a5f6d7..bfd75f86491 100644 --- a/test/core/http/httpcli_test.cc +++ b/test/core/http/httpcli_test.cc @@ -145,7 +145,7 @@ static void destroy_pops(void* p, grpc_error* error) { int main(int argc, char** argv) { gpr_subprocess* server; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); { grpc_closure destroyed; diff --git a/test/core/http/httpscli_test.cc b/test/core/http/httpscli_test.cc index 3fecf2b08bb..326b0e95e25 100644 --- a/test/core/http/httpscli_test.cc +++ b/test/core/http/httpscli_test.cc @@ -201,7 +201,7 @@ int main(int argc, char** argv) { gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_seconds(5, GPR_TIMESPAN))); - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); grpc_httpcli_context_init(&g_context); grpc_pollset* pollset = diff --git a/test/core/http/parser_test.cc b/test/core/http/parser_test.cc index fe824f57fce..d105b40bcd6 100644 --- a/test/core/http/parser_test.cc +++ b/test/core/http/parser_test.cc @@ -218,7 +218,7 @@ int main(int argc, char** argv) { GRPC_SLICE_SPLIT_ONE_BYTE}; char *tmp1, *tmp2; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); for (i = 0; i < GPR_ARRAY_SIZE(split_modes); i++) { diff --git a/test/core/iomgr/BUILD b/test/core/iomgr/BUILD index 70ee83acd23..1aefa0ab224 100644 --- a/test/core/iomgr/BUILD +++ b/test/core/iomgr/BUILD @@ -32,7 +32,6 @@ grpc_cc_library( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -40,12 +39,11 @@ grpc_cc_library( grpc_cc_test( name = "combiner_test", srcs = ["combiner_test.cc"], - data = ["//third_party/toolchains:RBE_USE_MACHINE_TYPE_LARGE"], + exec_compatible_with = ["//third_party/toolchains/machine_size:large"], language = "C++", deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -58,7 +56,6 @@ grpc_cc_test( ":endpoint_tests", "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -71,7 +68,6 @@ grpc_cc_test( ":endpoint_tests", "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -83,9 +79,9 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], + tags = ["no_windows"], ) grpc_cc_test( @@ -95,9 +91,9 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], + tags = ["no_windows"], ) grpc_cc_test( @@ -107,9 +103,9 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], + tags = ["no_windows"], ) grpc_cc_test( @@ -119,7 +115,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -131,21 +126,38 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) grpc_cc_test( - name = "resolve_address_posix_test", + name = "resolve_address_using_ares_resolver_posix_test", srcs = ["resolve_address_posix_test.cc"], + args = [ + "--resolver=ares", + ], language = "C++", deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], + tags = ["no_windows"], +) + +grpc_cc_test( + name = "resolve_address_using_native_resolver_posix_test", + srcs = ["resolve_address_posix_test.cc"], + args = [ + "--resolver=native", + ], + language = "C++", + deps = [ + "//:gpr", + "//:grpc", + "//test/core/util:grpc_test_util", + ], + tags = ["no_windows"], ) grpc_cc_test( @@ -158,7 +170,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -173,7 +184,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -185,7 +195,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -197,7 +206,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -209,9 +217,9 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], + tags = ["no_windows"], ) grpc_cc_test( @@ -221,9 +229,9 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], + tags = ["no_windows"], ) grpc_cc_test( @@ -234,9 +242,9 @@ grpc_cc_test( ":endpoint_tests", "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], + tags = ["no_windows"], ) grpc_cc_test( @@ -246,7 +254,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -255,13 +262,12 @@ grpc_cc_test( name = "tcp_server_posix_test", srcs = ["tcp_server_posix_test.cc"], language = "C++", - tags = ["manual"], # TODO(adelez): Remove once this works on Foundry. deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], + tags = ["no_windows"], ) grpc_cc_test( @@ -271,7 +277,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -283,7 +288,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -295,7 +299,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -307,19 +310,7 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", - "//test/core/util:grpc_test_util", - ], -) - -grpc_cc_test( - name = "wakeup_fd_cv_test", - srcs = ["wakeup_fd_cv_test.cc"], - language = "C++", - deps = [ - "//:gpr", - "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], + tags = ["no_windows"], ) diff --git a/test/core/iomgr/buffer_list_test.cc b/test/core/iomgr/buffer_list_test.cc index c7f30fa092c..70e36940425 100644 --- a/test/core/iomgr/buffer_list_test.cc +++ b/test/core/iomgr/buffer_list_test.cc @@ -48,9 +48,9 @@ static void TestShutdownFlushesList() { for (auto i = 0; i < NUM_ELEM; i++) { gpr_atm_rel_store(&verifier_called[i], static_cast(0)); grpc_core::TracedBuffer::AddNewEntry( - &list, i, static_cast(&verifier_called[i])); + &list, i, 0, static_cast(&verifier_called[i])); } - grpc_core::TracedBuffer::Shutdown(&list, GRPC_ERROR_NONE); + grpc_core::TracedBuffer::Shutdown(&list, nullptr, GRPC_ERROR_NONE); GPR_ASSERT(list == nullptr); for (auto i = 0; i < NUM_ELEM; i++) { GPR_ASSERT(gpr_atm_acq_load(&verifier_called[i]) == @@ -63,9 +63,10 @@ static void TestVerifierCalledOnAckVerifier(void* arg, grpc_error* error) { GPR_ASSERT(error == GRPC_ERROR_NONE); GPR_ASSERT(arg != nullptr); - GPR_ASSERT(ts->acked_time.clock_type == GPR_CLOCK_REALTIME); - GPR_ASSERT(ts->acked_time.tv_sec == 123); - GPR_ASSERT(ts->acked_time.tv_nsec == 456); + GPR_ASSERT(ts->acked_time.time.clock_type == GPR_CLOCK_REALTIME); + GPR_ASSERT(ts->acked_time.time.tv_sec == 123); + GPR_ASSERT(ts->acked_time.time.tv_nsec == 456); + GPR_ASSERT(ts->info.length > 0); gpr_atm* done = reinterpret_cast(arg); gpr_atm_rel_store(done, static_cast(1)); } @@ -84,11 +85,11 @@ static void TestVerifierCalledOnAck() { grpc_core::TracedBuffer* list = nullptr; gpr_atm verifier_called; gpr_atm_rel_store(&verifier_called, static_cast(0)); - grpc_core::TracedBuffer::AddNewEntry(&list, 213, &verifier_called); - grpc_core::TracedBuffer::ProcessTimestamp(&list, &serr, &tss); + grpc_core::TracedBuffer::AddNewEntry(&list, 213, 0, &verifier_called); + grpc_core::TracedBuffer::ProcessTimestamp(&list, &serr, nullptr, &tss); GPR_ASSERT(gpr_atm_acq_load(&verifier_called) == static_cast(1)); GPR_ASSERT(list == nullptr); - grpc_core::TracedBuffer::Shutdown(&list, GRPC_ERROR_NONE); + grpc_core::TracedBuffer::Shutdown(&list, nullptr, GRPC_ERROR_NONE); } static void TestTcpBufferList() { @@ -97,7 +98,7 @@ static void TestTcpBufferList() { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); TestTcpBufferList(); grpc_shutdown(); diff --git a/test/core/iomgr/combiner_test.cc b/test/core/iomgr/combiner_test.cc index cf2c7db8462..c39c3fc8fce 100644 --- a/test/core/iomgr/combiner_test.cc +++ b/test/core/iomgr/combiner_test.cc @@ -144,7 +144,7 @@ static void test_execute_finally(void) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); test_no_op(); test_execute_one(); diff --git a/test/core/iomgr/endpoint_pair_test.cc b/test/core/iomgr/endpoint_pair_test.cc index ad38076b516..3ddbe7f2fc0 100644 --- a/test/core/iomgr/endpoint_pair_test.cc +++ b/test/core/iomgr/endpoint_pair_test.cc @@ -60,7 +60,7 @@ static void destroy_pollset(void* p, grpc_error* error) { int main(int argc, char** argv) { grpc_closure destroyed; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); { grpc_core::ExecCtx exec_ctx; diff --git a/test/core/iomgr/endpoint_tests.cc b/test/core/iomgr/endpoint_tests.cc index a9e8ba86c5d..beae24769f6 100644 --- a/test/core/iomgr/endpoint_tests.cc +++ b/test/core/iomgr/endpoint_tests.cc @@ -129,7 +129,8 @@ static void read_and_write_test_read_handler(void* data, grpc_error* error) { GRPC_LOG_IF_ERROR("pollset_kick", grpc_pollset_kick(g_pollset, nullptr)); gpr_mu_unlock(g_mu); } else if (error == GRPC_ERROR_NONE) { - grpc_endpoint_read(state->read_ep, &state->incoming, &state->done_read); + grpc_endpoint_read(state->read_ep, &state->incoming, &state->done_read, + /*urgent=*/false); } } @@ -216,8 +217,8 @@ static void read_and_write_test(grpc_endpoint_test_config config, read_and_write_test_write_handler(&state, GRPC_ERROR_NONE); grpc_core::ExecCtx::Get()->Flush(); - grpc_endpoint_read(state.read_ep, &state.incoming, &state.done_read); - + grpc_endpoint_read(state.read_ep, &state.incoming, &state.done_read, + /*urgent=*/false); if (shutdown) { gpr_log(GPR_DEBUG, "shutdown read"); grpc_endpoint_shutdown( @@ -282,14 +283,16 @@ static void multiple_shutdown_test(grpc_endpoint_test_config config) { grpc_endpoint_add_to_pollset(f.client_ep, g_pollset); grpc_endpoint_read(f.client_ep, &slice_buffer, GRPC_CLOSURE_CREATE(inc_on_failure, &fail_count, - grpc_schedule_on_exec_ctx)); + grpc_schedule_on_exec_ctx), + /*urgent=*/false); wait_for_fail_count(&fail_count, 0); grpc_endpoint_shutdown(f.client_ep, GRPC_ERROR_CREATE_FROM_STATIC_STRING("Test Shutdown")); wait_for_fail_count(&fail_count, 1); grpc_endpoint_read(f.client_ep, &slice_buffer, GRPC_CLOSURE_CREATE(inc_on_failure, &fail_count, - grpc_schedule_on_exec_ctx)); + grpc_schedule_on_exec_ctx), + /*urgent=*/false); wait_for_fail_count(&fail_count, 2); grpc_slice_buffer_add(&slice_buffer, grpc_slice_from_copied_string("a")); grpc_endpoint_write(f.client_ep, &slice_buffer, diff --git a/test/core/iomgr/error_test.cc b/test/core/iomgr/error_test.cc index d78a8c2af39..3ba90147aad 100644 --- a/test/core/iomgr/error_test.cc +++ b/test/core/iomgr/error_test.cc @@ -215,7 +215,7 @@ static void test_overflow() { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); test_set_get_int(); test_set_get_str(); diff --git a/test/core/iomgr/ev_epollex_linux_test.cc b/test/core/iomgr/ev_epollex_linux_test.cc index 08d1e68b398..faa3ef344a1 100644 --- a/test/core/iomgr/ev_epollex_linux_test.cc +++ b/test/core/iomgr/ev_epollex_linux_test.cc @@ -92,7 +92,7 @@ static void test_pollable_owner_fd() { int main(int argc, char** argv) { const char* poll_strategy = nullptr; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); { grpc_core::ExecCtx exec_ctx; diff --git a/test/core/iomgr/fd_conservation_posix_test.cc b/test/core/iomgr/fd_conservation_posix_test.cc index 4866e350d53..0d27b94dc2d 100644 --- a/test/core/iomgr/fd_conservation_posix_test.cc +++ b/test/core/iomgr/fd_conservation_posix_test.cc @@ -29,7 +29,7 @@ int main(int argc, char** argv) { struct rlimit rlim; grpc_endpoint_pair p; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); { grpc_core::ExecCtx exec_ctx; diff --git a/test/core/iomgr/fd_posix_test.cc b/test/core/iomgr/fd_posix_test.cc index 4ea2389bbd8..cf5ffc63543 100644 --- a/test/core/iomgr/fd_posix_test.cc +++ b/test/core/iomgr/fd_posix_test.cc @@ -515,7 +515,7 @@ static void destroy_pollset(void* p, grpc_error* error) { int main(int argc, char** argv) { grpc_closure destroyed; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); { grpc_core::ExecCtx exec_ctx; diff --git a/test/core/iomgr/grpc_ipv6_loopback_available_test.cc b/test/core/iomgr/grpc_ipv6_loopback_available_test.cc index 329aa9a8517..2ef1f1978d6 100644 --- a/test/core/iomgr/grpc_ipv6_loopback_available_test.cc +++ b/test/core/iomgr/grpc_ipv6_loopback_available_test.cc @@ -32,7 +32,7 @@ #endif int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); // This test assumes that the ipv6 loopback is available // in all environments in which grpc tests run in. diff --git a/test/core/iomgr/ios/CFStreamTests/CFStreamEndpointTests.mm b/test/core/iomgr/ios/CFStreamTests/CFStreamEndpointTests.mm index fbc34c74d66..c882479a8d5 100644 --- a/test/core/iomgr/ios/CFStreamTests/CFStreamEndpointTests.mm +++ b/test/core/iomgr/ios/CFStreamTests/CFStreamEndpointTests.mm @@ -167,7 +167,7 @@ static bool compare_slice_buffer_with_buffer(grpc_slice_buffer *slices, const ch slice = grpc_slice_from_static_buffer(write_buffer, kBufferSize); grpc_slice_buffer_add(&write_slices, slice); init_event_closure(&write_done, &write); - grpc_endpoint_write(ep_, &write_slices, &write_done); + grpc_endpoint_write(ep_, &write_slices, &write_done, nullptr); XCTAssertEqual([self waitForEvent:&write timeout:kWriteTimeout], YES); XCTAssertEqual(reinterpret_cast(write), GRPC_ERROR_NONE); @@ -187,7 +187,7 @@ static bool compare_slice_buffer_with_buffer(grpc_slice_buffer *slices, const ch grpc_slice_buffer_init(&read_one_slice); while (read_slices.length < kBufferSize) { init_event_closure(&read_done, &read); - grpc_endpoint_read(ep_, &read_one_slice, &read_done); + grpc_endpoint_read(ep_, &read_one_slice, &read_done, /*urgent=*/false); XCTAssertEqual([self waitForEvent:&read timeout:kReadTimeout], YES); XCTAssertEqual(reinterpret_cast(read), GRPC_ERROR_NONE); grpc_slice_buffer_move_into(&read_one_slice, &read_slices); @@ -218,13 +218,13 @@ static bool compare_slice_buffer_with_buffer(grpc_slice_buffer *slices, const ch grpc_slice_buffer_init(&read_slices); init_event_closure(&read_done, &read); - grpc_endpoint_read(ep_, &read_slices, &read_done); + grpc_endpoint_read(ep_, &read_slices, &read_done, /*urgent=*/false); grpc_slice_buffer_init(&write_slices); slice = grpc_slice_from_static_buffer(write_buffer, kBufferSize); grpc_slice_buffer_add(&write_slices, slice); init_event_closure(&write_done, &write); - grpc_endpoint_write(ep_, &write_slices, &write_done); + grpc_endpoint_write(ep_, &write_slices, &write_done, nullptr); XCTAssertEqual([self waitForEvent:&write timeout:kWriteTimeout], YES); XCTAssertEqual(reinterpret_cast(write), GRPC_ERROR_NONE); @@ -267,13 +267,13 @@ static bool compare_slice_buffer_with_buffer(grpc_slice_buffer *slices, const ch init_event_closure(&read_done, &read); grpc_slice_buffer_init(&read_slices); - grpc_endpoint_read(ep_, &read_slices, &read_done); + grpc_endpoint_read(ep_, &read_slices, &read_done, /*urgent=*/false); grpc_slice_buffer_init(&write_slices); slice = grpc_slice_from_static_buffer(write_buffer, kBufferSize); grpc_slice_buffer_add(&write_slices, slice); init_event_closure(&write_done, &write); - grpc_endpoint_write(ep_, &write_slices, &write_done); + grpc_endpoint_write(ep_, &write_slices, &write_done, nullptr); XCTAssertEqual([self waitForEvent:&write timeout:kWriteTimeout], YES); XCTAssertEqual(reinterpret_cast(write), GRPC_ERROR_NONE); @@ -306,7 +306,7 @@ static bool compare_slice_buffer_with_buffer(grpc_slice_buffer *slices, const ch init_event_closure(&read_done, &read); grpc_slice_buffer_init(&read_slices); - grpc_endpoint_read(ep_, &read_slices, &read_done); + grpc_endpoint_read(ep_, &read_slices, &read_done, /*urgent=*/false); struct linger so_linger; so_linger.l_onoff = 1; diff --git a/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/project.pbxproj b/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/project.pbxproj index 2218f129ae5..c24151f0fa7 100644 --- a/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/project.pbxproj +++ b/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/project.pbxproj @@ -8,7 +8,6 @@ /* Begin PBXBuildFile section */ 5E143B892069D72200715A6E /* CFStreamClientTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5E143B882069D72200715A6E /* CFStreamClientTests.mm */; }; - 5E143B8C206B5F9F00715A6E /* Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 5E143B8A2069D72700715A6E /* Info.plist */; }; 5E143B8E206C5B9A00715A6E /* CFStreamEndpointTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5E143B8D206C5B9A00715A6E /* CFStreamEndpointTests.mm */; }; 604EA96D9CD477A8EA411BDF /* libPods-CFStreamTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AFFA154D492751CEAC05D591 /* libPods-CFStreamTests.a */; }; /* End PBXBuildFile section */ @@ -82,7 +81,6 @@ 4EBA55D3E23FC6C84596E3D5 /* [CP] Check Pods Manifest.lock */, 5E143B752069D67300715A6E /* Sources */, 5E143B762069D67300715A6E /* Frameworks */, - 5E143B772069D67300715A6E /* Resources */, ); buildRules = ( ); @@ -126,17 +124,6 @@ }; /* End PBXProject section */ -/* Begin PBXResourcesBuildPhase section */ - 5E143B772069D67300715A6E /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 5E143B8C206B5F9F00715A6E /* Info.plist in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - /* Begin PBXShellScriptBuildPhase section */ 4EBA55D3E23FC6C84596E3D5 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; diff --git a/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/xcshareddata/xcschemes/CFStreamTests.xcscheme b/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/xcshareddata/xcschemes/CFStreamTests.xcscheme index 25d6f780a1e..e4b4ce89e27 100644 --- a/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/xcshareddata/xcschemes/CFStreamTests.xcscheme +++ b/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/xcshareddata/xcschemes/CFStreamTests.xcscheme @@ -36,6 +36,13 @@ debugDocumentVersioning = "YES" debugServiceExtension = "internal" allowLocationSimulation = "YES"> + + + + diff --git a/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/xcshareddata/xcschemes/CFStreamTests_Asan.xcscheme b/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/xcshareddata/xcschemes/CFStreamTests_Asan.xcscheme index 6c5c43aa721..d29ed5cb548 100644 --- a/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/xcshareddata/xcschemes/CFStreamTests_Asan.xcscheme +++ b/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/xcshareddata/xcschemes/CFStreamTests_Asan.xcscheme @@ -12,7 +12,6 @@ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" enableAddressSanitizer = "YES" enableASanStackUseAfterReturn = "YES" - language = "" shouldUseLaunchSchemeArgsEnv = "YES"> + + + + diff --git a/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/xcshareddata/xcschemes/CFStreamTests_Msan.xcscheme b/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/xcshareddata/xcschemes/CFStreamTests_Msan.xcscheme index 3e39ff84d06..ab9b9be5917 100644 --- a/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/xcshareddata/xcschemes/CFStreamTests_Msan.xcscheme +++ b/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/xcshareddata/xcschemes/CFStreamTests_Msan.xcscheme @@ -10,7 +10,6 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - language = "" shouldUseLaunchSchemeArgsEnv = "YES"> + + + + diff --git a/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/xcshareddata/xcschemes/CFStreamTests_Tsan.xcscheme b/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/xcshareddata/xcschemes/CFStreamTests_Tsan.xcscheme index f0bde837c5b..bad1ceab715 100644 --- a/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/xcshareddata/xcschemes/CFStreamTests_Tsan.xcscheme +++ b/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/xcshareddata/xcschemes/CFStreamTests_Tsan.xcscheme @@ -11,7 +11,6 @@ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" enableThreadSanitizer = "YES" - language = "" shouldUseLaunchSchemeArgsEnv = "YES"> + + + + diff --git a/test/core/iomgr/ios/CFStreamTests/run_tests.sh b/test/core/iomgr/ios/CFStreamTests/run_tests.sh index 1045ec10a82..e49a2e0b65e 100755 --- a/test/core/iomgr/ios/CFStreamTests/run_tests.sh +++ b/test/core/iomgr/ios/CFStreamTests/run_tests.sh @@ -17,6 +17,7 @@ # ./tools/run_tests/run_tests.py -l objc set -ev +set -o pipefail cd "$(dirname "$0")" diff --git a/test/core/iomgr/load_file_test.cc b/test/core/iomgr/load_file_test.cc index 38c8710535b..a0e0e4d7a74 100644 --- a/test/core/iomgr/load_file_test.cc +++ b/test/core/iomgr/load_file_test.cc @@ -152,7 +152,7 @@ static void test_load_big_file(void) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); test_load_empty_file(); test_load_failure(); diff --git a/test/core/iomgr/resolve_address_posix_test.cc b/test/core/iomgr/resolve_address_posix_test.cc index e495e4c8770..826c7e1fafa 100644 --- a/test/core/iomgr/resolve_address_posix_test.cc +++ b/test/core/iomgr/resolve_address_posix_test.cc @@ -18,19 +18,24 @@ #include "src/core/lib/iomgr/resolve_address.h" +#include #include #include #include #include #include +#include #include #include +#include "src/core/lib/gpr/env.h" +#include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/useful.h" #include "src/core/lib/gprpp/thd.h" #include "src/core/lib/iomgr/executor.h" #include "src/core/lib/iomgr/iomgr.h" +#include "test/core/util/cmdline.h" #include "test/core/util/test_config.h" static gpr_timespec test_deadline(void) { @@ -115,12 +120,18 @@ static void must_succeed(void* argsp, grpc_error* err) { GPR_ASSERT(args->addrs != nullptr); GPR_ASSERT(args->addrs->naddrs > 0); gpr_atm_rel_store(&args->done_atm, 1); + gpr_mu_lock(args->mu); + GRPC_LOG_IF_ERROR("pollset_kick", grpc_pollset_kick(args->pollset, nullptr)); + gpr_mu_unlock(args->mu); } static void must_fail(void* argsp, grpc_error* err) { args_struct* args = static_cast(argsp); GPR_ASSERT(err != GRPC_ERROR_NONE); gpr_atm_rel_store(&args->done_atm, 1); + gpr_mu_lock(args->mu); + GRPC_LOG_IF_ERROR("pollset_kick", grpc_pollset_kick(args->pollset, nullptr)); + gpr_mu_unlock(args->mu); } static void test_unix_socket(void) { @@ -157,15 +168,92 @@ static void test_unix_socket_path_name_too_long(void) { args_finish(&args); } +static void resolve_address_must_succeed(const char* target) { + grpc_core::ExecCtx exec_ctx; + args_struct args; + args_init(&args); + poll_pollset_until_request_done(&args); + grpc_resolve_address( + target, "1" /* port number */, args.pollset_set, + GRPC_CLOSURE_CREATE(must_succeed, &args, grpc_schedule_on_exec_ctx), + &args.addrs); + grpc_core::ExecCtx::Get()->Flush(); + args_finish(&args); +} + +static void test_named_and_numeric_scope_ids(void) { + char* arbitrary_interface_name = static_cast(gpr_zalloc(IF_NAMESIZE)); + int interface_index = 0; + // Probe candidate interface index numbers until we find one that the + // system recognizes, and then use that for the test. + for (size_t i = 1; i < 65536; i++) { + if (if_indextoname(i, arbitrary_interface_name) != nullptr) { + gpr_log( + GPR_DEBUG, + "Found interface at index %d named %s. Will use this for the test", + (int)i, arbitrary_interface_name); + interface_index = (int)i; + break; + } + } + GPR_ASSERT(strlen(arbitrary_interface_name) > 0); + // Test resolution of an ipv6 address with a named scope ID + gpr_log(GPR_DEBUG, "test resolution with a named scope ID"); + char* target_with_named_scope_id = nullptr; + gpr_asprintf(&target_with_named_scope_id, "fe80::1234%%%s", + arbitrary_interface_name); + resolve_address_must_succeed(target_with_named_scope_id); + gpr_free(target_with_named_scope_id); + gpr_free(arbitrary_interface_name); + // Test resolution of an ipv6 address with a numeric scope ID + gpr_log(GPR_DEBUG, "test resolution with a numeric scope ID"); + char* target_with_numeric_scope_id = nullptr; + gpr_asprintf(&target_with_numeric_scope_id, "fe80::1234%%%d", + interface_index); + resolve_address_must_succeed(target_with_numeric_scope_id); + gpr_free(target_with_numeric_scope_id); +} + int main(int argc, char** argv) { - grpc_test_init(argc, argv); + // First set the resolver type based off of --resolver + const char* resolver_type = nullptr; + gpr_cmdline* cl = gpr_cmdline_create("resolve address test"); + gpr_cmdline_add_string(cl, "resolver", "Resolver type (ares or native)", + &resolver_type); + // In case that there are more than one argument on the command line, + // --resolver will always be the first one, so only parse the first argument + // (other arguments may be unknown to cl) + gpr_cmdline_parse(cl, argc > 2 ? 2 : argc, argv); + const char* cur_resolver = gpr_getenv("GRPC_DNS_RESOLVER"); + if (cur_resolver != nullptr && strlen(cur_resolver) != 0) { + gpr_log(GPR_INFO, "Warning: overriding resolver setting of %s", + cur_resolver); + } + if (gpr_stricmp(resolver_type, "native") == 0) { + gpr_setenv("GRPC_DNS_RESOLVER", "native"); + } else if (gpr_stricmp(resolver_type, "ares") == 0) { + gpr_setenv("GRPC_DNS_RESOLVER", "ares"); + } else { + gpr_log(GPR_ERROR, "--resolver_type was not set to ares or native"); + abort(); + } + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); { grpc_core::ExecCtx exec_ctx; - test_unix_socket(); - test_unix_socket_path_name_too_long(); + test_named_and_numeric_scope_ids(); + // c-ares resolver doesn't support UDS (ability for native DNS resolver + // to handle this is only expected to be used by servers, which + // unconditionally use the native DNS resolver). + char* resolver_env = gpr_getenv("GRPC_DNS_RESOLVER"); + if (resolver_env == nullptr || gpr_stricmp(resolver_env, "native") == 0) { + test_unix_socket(); + test_unix_socket_path_name_too_long(); + } + gpr_free(resolver_env); } + gpr_cmdline_destroy(cl); grpc_shutdown(); return 0; diff --git a/test/core/iomgr/resolve_address_test.cc b/test/core/iomgr/resolve_address_test.cc index 8d69bab5b12..1f0c0e3e835 100644 --- a/test/core/iomgr/resolve_address_test.cc +++ b/test/core/iomgr/resolve_address_test.cc @@ -23,6 +23,8 @@ #include #include +#include + #include #include "src/core/lib/gpr/env.h" @@ -81,7 +83,9 @@ static grpc_millis n_sec_deadline(int seconds) { static void poll_pollset_until_request_done(args_struct* args) { grpc_core::ExecCtx exec_ctx; - grpc_millis deadline = n_sec_deadline(10); + // Try to give enough time for c-ares to run through its retries + // a few times if needed. + grpc_millis deadline = n_sec_deadline(90); while (true) { bool done = gpr_atm_acq_load(&args->done_atm) != 0; if (done) { @@ -120,6 +124,35 @@ static void must_fail(void* argsp, grpc_error* err) { gpr_mu_unlock(args->mu); } +// This test assumes the environment has an ipv6 loopback +static void must_succeed_with_ipv6_first(void* argsp, grpc_error* err) { + args_struct* args = static_cast(argsp); + GPR_ASSERT(err == GRPC_ERROR_NONE); + GPR_ASSERT(args->addrs != nullptr); + GPR_ASSERT(args->addrs->naddrs > 0); + const struct sockaddr* first_address = + reinterpret_cast(args->addrs->addrs[0].addr); + GPR_ASSERT(first_address->sa_family == AF_INET6); + gpr_atm_rel_store(&args->done_atm, 1); + gpr_mu_lock(args->mu); + GRPC_LOG_IF_ERROR("pollset_kick", grpc_pollset_kick(args->pollset, nullptr)); + gpr_mu_unlock(args->mu); +} + +static void must_succeed_with_ipv4_first(void* argsp, grpc_error* err) { + args_struct* args = static_cast(argsp); + GPR_ASSERT(err == GRPC_ERROR_NONE); + GPR_ASSERT(args->addrs != nullptr); + GPR_ASSERT(args->addrs->naddrs > 0); + const struct sockaddr* first_address = + reinterpret_cast(args->addrs->addrs[0].addr); + GPR_ASSERT(first_address->sa_family == AF_INET); + gpr_atm_rel_store(&args->done_atm, 1); + gpr_mu_lock(args->mu); + GRPC_LOG_IF_ERROR("pollset_kick", grpc_pollset_kick(args->pollset, nullptr)); + gpr_mu_unlock(args->mu); +} + static void test_localhost(void) { grpc_core::ExecCtx exec_ctx; args_struct args; @@ -146,6 +179,33 @@ static void test_default_port(void) { args_finish(&args); } +static void test_localhost_result_has_ipv6_first(void) { + grpc_core::ExecCtx exec_ctx; + args_struct args; + args_init(&args); + grpc_resolve_address("localhost:1", nullptr, args.pollset_set, + GRPC_CLOSURE_CREATE(must_succeed_with_ipv6_first, &args, + grpc_schedule_on_exec_ctx), + &args.addrs); + grpc_core::ExecCtx::Get()->Flush(); + poll_pollset_until_request_done(&args); + args_finish(&args); +} + +static void test_localhost_result_has_ipv4_first_when_ipv6_isnt_available( + void) { + grpc_core::ExecCtx exec_ctx; + args_struct args; + args_init(&args); + grpc_resolve_address("localhost:1", nullptr, args.pollset_set, + GRPC_CLOSURE_CREATE(must_succeed_with_ipv4_first, &args, + grpc_schedule_on_exec_ctx), + &args.addrs); + grpc_core::ExecCtx::Get()->Flush(); + poll_pollset_until_request_done(&args); + args_finish(&args); +} + static void test_non_numeric_default_port(void) { grpc_core::ExecCtx exec_ctx; args_struct args; @@ -245,6 +305,38 @@ static void test_unparseable_hostports(void) { } } +typedef struct mock_ipv6_disabled_source_addr_factory { + address_sorting_source_addr_factory base; +} mock_ipv6_disabled_source_addr_factory; + +static bool mock_ipv6_disabled_source_addr_factory_get_source_addr( + address_sorting_source_addr_factory* factory, + const address_sorting_address* dest_addr, + address_sorting_address* source_addr) { + // Mock lack of IPv6. For IPv4, set the source addr to be the same + // as the destination; tests won't actually connect on the result anyways. + if (address_sorting_abstract_get_family(dest_addr) == + ADDRESS_SORTING_AF_INET6) { + return false; + } + memcpy(source_addr->addr, &dest_addr->addr, dest_addr->len); + source_addr->len = dest_addr->len; + return true; +} + +void mock_ipv6_disabled_source_addr_factory_destroy( + address_sorting_source_addr_factory* factory) { + mock_ipv6_disabled_source_addr_factory* f = + reinterpret_cast(factory); + gpr_free(f); +} + +const address_sorting_source_addr_factory_vtable + kMockIpv6DisabledSourceAddrFactoryVtable = { + mock_ipv6_disabled_source_addr_factory_get_source_addr, + mock_ipv6_disabled_source_addr_factory_destroy, +}; + int main(int argc, char** argv) { // First set the resolver type based off of --resolver const char* resolver_type = nullptr; @@ -271,7 +363,7 @@ int main(int argc, char** argv) { abort(); } // Run the test. - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); { grpc_core::ExecCtx exec_ctx; @@ -281,19 +373,31 @@ int main(int argc, char** argv) { test_missing_default_port(); test_ipv6_with_port(); test_ipv6_without_port(); - if (gpr_stricmp(resolver_type, "ares") != 0) { - // These tests can trigger DNS queries to the nearby nameserver - // that need to come back in order for the test to succeed. - // c-ares is prone to not using the local system caches that the - // native getaddrinfo implementations take advantage of, so running - // these unit tests under c-ares risks flakiness. - test_invalid_ip_addresses(); - test_unparseable_hostports(); + test_invalid_ip_addresses(); + test_unparseable_hostports(); + if (gpr_stricmp(resolver_type, "ares") == 0) { + // This behavior expectation is specific to c-ares. + test_localhost_result_has_ipv6_first(); } - grpc_executor_shutdown(); + grpc_core::Executor::ShutdownAll(); } gpr_cmdline_destroy(cl); - grpc_shutdown(); + // The following test uses + // "address_sorting_override_source_addr_factory_for_testing", which works + // on a per-grpc-init basis, and so it's simplest to run this next test + // within a standalone grpc_init/grpc_shutdown pair. + if (gpr_stricmp(resolver_type, "ares") == 0) { + // Run a test case in which c-ares's address sorter + // thinks that IPv4 is available and IPv6 isn't. + grpc_init(); + mock_ipv6_disabled_source_addr_factory* factory = + static_cast( + gpr_malloc(sizeof(mock_ipv6_disabled_source_addr_factory))); + factory->base.vtable = &kMockIpv6DisabledSourceAddrFactoryVtable; + address_sorting_override_source_addr_factory_for_testing(&factory->base); + test_localhost_result_has_ipv4_first_when_ipv6_isnt_available(); + grpc_shutdown(); + } return 0; } diff --git a/test/core/iomgr/resource_quota_test.cc b/test/core/iomgr/resource_quota_test.cc index f3b35fed327..4cbc016d587 100644 --- a/test/core/iomgr/resource_quota_test.cc +++ b/test/core/iomgr/resource_quota_test.cc @@ -891,7 +891,7 @@ static void test_thread_maxquota_change() { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); gpr_mu_init(&g_mu); gpr_cv_init(&g_cv); diff --git a/test/core/iomgr/sockaddr_utils_test.cc b/test/core/iomgr/sockaddr_utils_test.cc index 3783f968b7d..250d36a74a6 100644 --- a/test/core/iomgr/sockaddr_utils_test.cc +++ b/test/core/iomgr/sockaddr_utils_test.cc @@ -270,7 +270,7 @@ static void test_sockaddr_set_get_port(void) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); test_sockaddr_is_v4mapped(); test_sockaddr_to_v4mapped(); diff --git a/test/core/iomgr/socket_utils_test.cc b/test/core/iomgr/socket_utils_test.cc index a21f3fac62e..f0537e03e9d 100644 --- a/test/core/iomgr/socket_utils_test.cc +++ b/test/core/iomgr/socket_utils_test.cc @@ -24,6 +24,7 @@ #include "src/core/lib/iomgr/socket_utils_posix.h" #include +#include #include #include @@ -80,7 +81,7 @@ static const grpc_socket_mutator_vtable mutator_vtable = { int main(int argc, char** argv) { int sock; grpc_error* err; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); sock = socket(PF_INET, SOCK_STREAM, 0); GPR_ASSERT(sock > 0); diff --git a/test/core/iomgr/tcp_client_posix_test.cc b/test/core/iomgr/tcp_client_posix_test.cc index 90fc5aecfc6..5cf3530c77a 100644 --- a/test/core/iomgr/tcp_client_posix_test.cc +++ b/test/core/iomgr/tcp_client_posix_test.cc @@ -191,7 +191,7 @@ static void destroy_pollset(void* p, grpc_error* error) { int main(int argc, char** argv) { grpc_closure destroyed; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); { diff --git a/test/core/iomgr/tcp_client_uv_test.cc b/test/core/iomgr/tcp_client_uv_test.cc index 27f894e3f3c..bde8c2f3539 100644 --- a/test/core/iomgr/tcp_client_uv_test.cc +++ b/test/core/iomgr/tcp_client_uv_test.cc @@ -188,7 +188,7 @@ static void destroy_pollset(void* p, grpc_error* error) { int main(int argc, char** argv) { grpc_closure destroyed; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); { grpc_core::ExecCtx exec_ctx; diff --git a/test/core/iomgr/tcp_posix_test.cc b/test/core/iomgr/tcp_posix_test.cc index 6447cc234db..33a4d973ed3 100644 --- a/test/core/iomgr/tcp_posix_test.cc +++ b/test/core/iomgr/tcp_posix_test.cc @@ -191,7 +191,8 @@ static void read_cb(void* user_data, grpc_error* error) { GRPC_LOG_IF_ERROR("kick", grpc_pollset_kick(g_pollset, nullptr))); gpr_mu_unlock(g_mu); } else { - grpc_endpoint_read(state->ep, &state->incoming, &state->read_cb); + grpc_endpoint_read(state->ep, &state->incoming, &state->read_cb, + /*urgent=*/false); gpr_mu_unlock(g_mu); } } @@ -229,7 +230,7 @@ static void read_test(size_t num_bytes, size_t slice_size) { grpc_slice_buffer_init(&state.incoming); GRPC_CLOSURE_INIT(&state.read_cb, read_cb, &state, grpc_schedule_on_exec_ctx); - grpc_endpoint_read(ep, &state.incoming, &state.read_cb); + grpc_endpoint_read(ep, &state.incoming, &state.read_cb, /*urgent=*/false); gpr_mu_lock(g_mu); while (state.read_bytes < state.target_read_bytes) { @@ -280,7 +281,7 @@ static void large_read_test(size_t slice_size) { grpc_slice_buffer_init(&state.incoming); GRPC_CLOSURE_INIT(&state.read_cb, read_cb, &state, grpc_schedule_on_exec_ctx); - grpc_endpoint_read(ep, &state.incoming, &state.read_cb); + grpc_endpoint_read(ep, &state.incoming, &state.read_cb, /*urgent=*/false); gpr_mu_lock(g_mu); while (state.read_bytes < state.target_read_bytes) { @@ -384,9 +385,9 @@ void timestamps_verifier(void* arg, grpc_core::Timestamps* ts, grpc_error* error) { GPR_ASSERT(error == GRPC_ERROR_NONE); GPR_ASSERT(arg != nullptr); - GPR_ASSERT(ts->sendmsg_time.clock_type == GPR_CLOCK_REALTIME); - GPR_ASSERT(ts->scheduled_time.clock_type == GPR_CLOCK_REALTIME); - GPR_ASSERT(ts->acked_time.clock_type == GPR_CLOCK_REALTIME); + GPR_ASSERT(ts->sendmsg_time.time.clock_type == GPR_CLOCK_REALTIME); + GPR_ASSERT(ts->scheduled_time.time.clock_type == GPR_CLOCK_REALTIME); + GPR_ASSERT(ts->acked_time.time.clock_type == GPR_CLOCK_REALTIME); gpr_atm* done_timestamps = (gpr_atm*)arg; gpr_atm_rel_store(done_timestamps, static_cast(1)); } @@ -519,7 +520,7 @@ static void release_fd_test(size_t num_bytes, size_t slice_size) { grpc_slice_buffer_init(&state.incoming); GRPC_CLOSURE_INIT(&state.read_cb, read_cb, &state, grpc_schedule_on_exec_ctx); - grpc_endpoint_read(ep, &state.incoming, &state.read_cb); + grpc_endpoint_read(ep, &state.incoming, &state.read_cb, /*urgent=*/false); gpr_mu_lock(g_mu); while (state.read_bytes < state.target_read_bytes) { @@ -623,7 +624,7 @@ static void destroy_pollset(void* p, grpc_error* error) { int main(int argc, char** argv) { grpc_closure destroyed; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); grpc_core::grpc_tcp_set_write_timestamps_callback(timestamps_verifier); { diff --git a/test/core/iomgr/tcp_server_posix_test.cc b/test/core/iomgr/tcp_server_posix_test.cc index d646df1daef..81e26b20cd8 100644 --- a/test/core/iomgr/tcp_server_posix_test.cc +++ b/test/core/iomgr/tcp_server_posix_test.cc @@ -437,8 +437,13 @@ int main(int argc, char** argv) { // Zalloc dst_addrs to avoid oversized frames. test_addrs* dst_addrs = static_cast(gpr_zalloc(sizeof(*dst_addrs))); - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); + // wait a few seconds to make sure IPv6 link-local addresses can be bound + // if we are running under docker container that has just started. + // See https://github.com/moby/moby/issues/38491 + // See https://github.com/grpc/grpc/issues/15610 + gpr_sleep_until(grpc_timeout_seconds_to_deadline(4)); { grpc_core::ExecCtx exec_ctx; g_pollset = static_cast(gpr_zalloc(grpc_pollset_size())); diff --git a/test/core/iomgr/tcp_server_uv_test.cc b/test/core/iomgr/tcp_server_uv_test.cc index e99fa79bfd8..625a18c0cc7 100644 --- a/test/core/iomgr/tcp_server_uv_test.cc +++ b/test/core/iomgr/tcp_server_uv_test.cc @@ -288,7 +288,7 @@ static void destroy_pollset(void* p, grpc_error* error) { int main(int argc, char** argv) { grpc_closure destroyed; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); { grpc_core::ExecCtx exec_ctx; diff --git a/test/core/iomgr/time_averaged_stats_test.cc b/test/core/iomgr/time_averaged_stats_test.cc index b932e62d1f6..2923a35d1b6 100644 --- a/test/core/iomgr/time_averaged_stats_test.cc +++ b/test/core/iomgr/time_averaged_stats_test.cc @@ -180,7 +180,7 @@ static void some_regress_some_persist_test(void) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); no_regress_no_persist_test_1(); no_regress_no_persist_test_2(); no_regress_no_persist_test_3(); diff --git a/test/core/iomgr/timer_heap_test.cc b/test/core/iomgr/timer_heap_test.cc index ebe5e6610d1..b574e0a680e 100644 --- a/test/core/iomgr/timer_heap_test.cc +++ b/test/core/iomgr/timer_heap_test.cc @@ -164,13 +164,13 @@ static void test2(void) { size_t num_inserted = 0; grpc_timer_heap_init(&pq); - memset(elems, 0, elems_size); + memset(elems, 0, elems_size * sizeof(elems[0])); for (size_t round = 0; round < 10000; round++) { int r = rand() % 1000; if (r <= 550) { /* 55% of the time we try to add something */ - elem_struct* el = search_elems(elems, GPR_ARRAY_SIZE(elems), false); + elem_struct* el = search_elems(elems, elems_size, false); if (el != nullptr) { el->elem.deadline = random_deadline(); grpc_timer_heap_add(&pq, &el->elem); @@ -180,7 +180,7 @@ static void test2(void) { } } else if (r <= 650) { /* 10% of the time we try to remove something */ - elem_struct* el = search_elems(elems, GPR_ARRAY_SIZE(elems), true); + elem_struct* el = search_elems(elems, elems_size, true); if (el != nullptr) { grpc_timer_heap_remove(&pq, &el->elem); el->inserted = false; @@ -286,7 +286,7 @@ static void shrink_test(void) { int main(int argc, char** argv) { int i; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); for (i = 0; i < 5; i++) { test1(); diff --git a/test/core/iomgr/timer_list_test.cc b/test/core/iomgr/timer_list_test.cc index fd65d1abf1f..fa2444948b6 100644 --- a/test/core/iomgr/timer_list_test.cc +++ b/test/core/iomgr/timer_list_test.cc @@ -221,7 +221,7 @@ void long_running_service_cleanup_test(void) { int main(int argc, char** argv) { /* Tests with default g_start_time */ { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_core::ExecCtx::GlobalInit(); grpc_core::ExecCtx exec_ctx; grpc_determine_iomgr_platform(); @@ -235,7 +235,7 @@ int main(int argc, char** argv) { /* Begin long running service tests */ { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); /* Set g_start_time back 25 days. */ /* We set g_start_time here in case there are any initialization dependencies that use g_start_time. */ diff --git a/test/core/iomgr/udp_server_test.cc b/test/core/iomgr/udp_server_test.cc index d167c0131f3..f65783a0174 100644 --- a/test/core/iomgr/udp_server_test.cc +++ b/test/core/iomgr/udp_server_test.cc @@ -360,7 +360,7 @@ static void test_receive(int number_of_clients) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); if (grpc_is_socket_reuse_port_supported()) { g_num_listeners = 10; diff --git a/test/core/iomgr/wakeup_fd_cv_test.cc b/test/core/iomgr/wakeup_fd_cv_test.cc deleted file mode 100644 index f297a569d2d..00000000000 --- a/test/core/iomgr/wakeup_fd_cv_test.cc +++ /dev/null @@ -1,243 +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. - * - */ - -#include "src/core/lib/iomgr/port.h" - -#ifdef GRPC_POSIX_SOCKET - -#include - -#include -#include - -#include "src/core/lib/gpr/env.h" -#include "src/core/lib/gprpp/thd.h" -#include "src/core/lib/iomgr/ev_posix.h" -#include "src/core/lib/iomgr/iomgr_posix.h" - -typedef struct poll_args { - struct pollfd* fds; - nfds_t nfds; - int timeout; - int result; -} poll_args; - -gpr_cv poll_cv; -gpr_mu poll_mu; -static int socket_event = 0; - -// Trigger a "socket" POLLIN in mock_poll() -void trigger_socket_event() { - gpr_mu_lock(&poll_mu); - socket_event = 1; - gpr_cv_broadcast(&poll_cv); - gpr_mu_unlock(&poll_mu); -} - -void reset_socket_event() { - gpr_mu_lock(&poll_mu); - socket_event = 0; - gpr_mu_unlock(&poll_mu); -} - -// Mocks posix poll() function -int mock_poll(struct pollfd* fds, nfds_t nfds, int timeout) { - int res = 0; - gpr_timespec poll_time; - gpr_mu_lock(&poll_mu); - GPR_ASSERT(nfds == 3); - GPR_ASSERT(fds[0].fd == 20); - GPR_ASSERT(fds[1].fd == 30); - GPR_ASSERT(fds[2].fd == 50); - GPR_ASSERT(fds[0].events == (POLLIN | POLLHUP)); - GPR_ASSERT(fds[1].events == (POLLIN | POLLHUP)); - GPR_ASSERT(fds[2].events == POLLIN); - - if (timeout < 0) { - poll_time = gpr_inf_future(GPR_CLOCK_REALTIME); - } else { - poll_time = gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), - gpr_time_from_millis(timeout, GPR_TIMESPAN)); - } - - if (socket_event || !gpr_cv_wait(&poll_cv, &poll_mu, poll_time)) { - fds[0].revents = POLLIN; - res = 1; - } - gpr_mu_unlock(&poll_mu); - return res; -} - -void background_poll(void* args) { - poll_args* pargs = static_cast(args); - pargs->result = grpc_poll_function(pargs->fds, pargs->nfds, pargs->timeout); -} - -void test_many_fds(void) { - int i; - grpc_wakeup_fd fd[1000]; - for (i = 0; i < 1000; i++) { - GPR_ASSERT(grpc_wakeup_fd_init(&fd[i]) == GRPC_ERROR_NONE); - } - for (i = 0; i < 1000; i++) { - grpc_wakeup_fd_destroy(&fd[i]); - } -} - -void test_poll_cv_trigger(void) { - grpc_wakeup_fd cvfd1, cvfd2, cvfd3; - struct pollfd pfds[6]; - poll_args pargs; - - GPR_ASSERT(grpc_wakeup_fd_init(&cvfd1) == GRPC_ERROR_NONE); - GPR_ASSERT(grpc_wakeup_fd_init(&cvfd2) == GRPC_ERROR_NONE); - GPR_ASSERT(grpc_wakeup_fd_init(&cvfd3) == GRPC_ERROR_NONE); - GPR_ASSERT(cvfd1.read_fd < 0); - GPR_ASSERT(cvfd2.read_fd < 0); - GPR_ASSERT(cvfd3.read_fd < 0); - GPR_ASSERT(cvfd1.read_fd != cvfd2.read_fd); - GPR_ASSERT(cvfd2.read_fd != cvfd3.read_fd); - GPR_ASSERT(cvfd1.read_fd != cvfd3.read_fd); - - pfds[0].fd = cvfd1.read_fd; - pfds[1].fd = cvfd2.read_fd; - pfds[2].fd = 20; - pfds[3].fd = 30; - pfds[4].fd = cvfd3.read_fd; - pfds[5].fd = 50; - - pfds[0].events = 0; - pfds[1].events = POLLIN; - pfds[2].events = POLLIN | POLLHUP; - pfds[3].events = POLLIN | POLLHUP; - pfds[4].events = POLLIN; - pfds[5].events = POLLIN; - - pargs.fds = pfds; - pargs.nfds = 6; - pargs.timeout = 1000; - pargs.result = -2; - - { - grpc_core::Thread thd("grpc_background_poll", &background_poll, &pargs); - thd.Start(); - // Wakeup wakeup_fd not listening for events - GPR_ASSERT(grpc_wakeup_fd_wakeup(&cvfd1) == GRPC_ERROR_NONE); - thd.Join(); - GPR_ASSERT(pargs.result == 0); - GPR_ASSERT(pfds[0].revents == 0); - GPR_ASSERT(pfds[1].revents == 0); - GPR_ASSERT(pfds[2].revents == 0); - GPR_ASSERT(pfds[3].revents == 0); - GPR_ASSERT(pfds[4].revents == 0); - GPR_ASSERT(pfds[5].revents == 0); - } - - { - // Pollin on socket fd - pargs.timeout = -1; - pargs.result = -2; - grpc_core::Thread thd("grpc_background_poll", &background_poll, &pargs); - thd.Start(); - trigger_socket_event(); - thd.Join(); - GPR_ASSERT(pargs.result == 1); - GPR_ASSERT(pfds[0].revents == 0); - GPR_ASSERT(pfds[1].revents == 0); - GPR_ASSERT(pfds[2].revents == POLLIN); - GPR_ASSERT(pfds[3].revents == 0); - GPR_ASSERT(pfds[4].revents == 0); - GPR_ASSERT(pfds[5].revents == 0); - } - - { - // Pollin on wakeup fd - reset_socket_event(); - pargs.result = -2; - grpc_core::Thread thd("grpc_background_poll", &background_poll, &pargs); - thd.Start(); - GPR_ASSERT(grpc_wakeup_fd_wakeup(&cvfd2) == GRPC_ERROR_NONE); - thd.Join(); - - GPR_ASSERT(pargs.result == 1); - GPR_ASSERT(pfds[0].revents == 0); - GPR_ASSERT(pfds[1].revents == POLLIN); - GPR_ASSERT(pfds[2].revents == 0); - GPR_ASSERT(pfds[3].revents == 0); - GPR_ASSERT(pfds[4].revents == 0); - GPR_ASSERT(pfds[5].revents == 0); - } - - { - // Pollin on wakeupfd before poll() - pargs.result = -2; - grpc_core::Thread thd("grpc_background_poll", &background_poll, &pargs); - thd.Start(); - thd.Join(); - - GPR_ASSERT(pargs.result == 1); - GPR_ASSERT(pfds[0].revents == 0); - GPR_ASSERT(pfds[1].revents == POLLIN); - GPR_ASSERT(pfds[2].revents == 0); - GPR_ASSERT(pfds[3].revents == 0); - GPR_ASSERT(pfds[4].revents == 0); - GPR_ASSERT(pfds[5].revents == 0); - } - - { - // No Events - pargs.result = -2; - pargs.timeout = 1000; - reset_socket_event(); - GPR_ASSERT(grpc_wakeup_fd_consume_wakeup(&cvfd1) == GRPC_ERROR_NONE); - GPR_ASSERT(grpc_wakeup_fd_consume_wakeup(&cvfd2) == GRPC_ERROR_NONE); - grpc_core::Thread thd("grpc_background_poll", &background_poll, &pargs); - thd.Start(); - thd.Join(); - - GPR_ASSERT(pargs.result == 0); - GPR_ASSERT(pfds[0].revents == 0); - GPR_ASSERT(pfds[1].revents == 0); - GPR_ASSERT(pfds[2].revents == 0); - GPR_ASSERT(pfds[3].revents == 0); - GPR_ASSERT(pfds[4].revents == 0); - GPR_ASSERT(pfds[5].revents == 0); - } -} - -int main(int argc, char** argv) { - gpr_setenv("GRPC_POLL_STRATEGY", "poll-cv"); - grpc_poll_function = &mock_poll; - gpr_mu_init(&poll_mu); - gpr_cv_init(&poll_cv); - grpc_determine_iomgr_platform(); - grpc_iomgr_platform_init(); - test_many_fds(); - grpc_iomgr_platform_shutdown(); - - grpc_iomgr_platform_init(); - test_poll_cv_trigger(); - grpc_iomgr_platform_shutdown(); - return 0; -} - -#else /* GRPC_POSIX_SOCKET */ - -int main(int argc, char** argv) { return 1; } - -#endif /* GRPC_POSIX_SOCKET */ diff --git a/test/core/json/BUILD b/test/core/json/BUILD index b8b36c06528..5684505cbc9 100644 --- a/test/core/json/BUILD +++ b/test/core/json/BUILD @@ -23,8 +23,8 @@ load("//test/core/util:grpc_fuzzer.bzl", "grpc_fuzzer") grpc_fuzzer( name = "json_fuzzer", srcs = ["fuzzer.cc"], - language = "C++", corpus = "corpus", + language = "C++", deps = [ "//:gpr", "//:grpc", @@ -40,7 +40,6 @@ grpc_cc_binary( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -48,17 +47,16 @@ grpc_cc_binary( grpc_cc_test( name = "json_rewrite_test", srcs = ["json_rewrite_test.cc"], - language = "C++", data = [ "rewrite_test_input.json", "rewrite_test_output_condensed.json", "rewrite_test_output_indented.json", ":json_stream_error_test", ], + language = "C++", deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -70,7 +68,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -82,7 +79,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/json/fuzzer.cc b/test/core/json/fuzzer.cc index 6dafabb95b3..8b3e9792d15 100644 --- a/test/core/json/fuzzer.cc +++ b/test/core/json/fuzzer.cc @@ -31,8 +31,7 @@ bool leak_check = true; extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { char* s; - struct grpc_memory_counters counters; - grpc_memory_counters_init(); + grpc_core::testing::LeakDetector leak_detector(true); s = static_cast(gpr_malloc(size)); memcpy(s, data, size); grpc_json* x; @@ -40,8 +39,5 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { grpc_json_destroy(x); } gpr_free(s); - counters = grpc_memory_counters_snapshot(); - grpc_memory_counters_destroy(); - GPR_ASSERT(counters.total_size_relative == 0); return 0; } diff --git a/test/core/json/json_rewrite_test.cc b/test/core/json/json_rewrite_test.cc index 2fade12e13f..b7e89cdb1a3 100644 --- a/test/core/json/json_rewrite_test.cc +++ b/test/core/json/json_rewrite_test.cc @@ -287,7 +287,7 @@ void test_rewrites() { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); test_rewrites(); gpr_log(GPR_INFO, "json_rewrite_test success"); return 0; diff --git a/test/core/json/json_stream_error_test.cc b/test/core/json/json_stream_error_test.cc index 00288d6d5ea..53e20be2069 100644 --- a/test/core/json/json_stream_error_test.cc +++ b/test/core/json/json_stream_error_test.cc @@ -49,7 +49,7 @@ static void read_error() { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); read_error(); gpr_log(GPR_INFO, "json_stream_error success"); return 0; diff --git a/test/core/json/json_test.cc b/test/core/json/json_test.cc index 7f1dbb774a6..03dd96a8ae1 100644 --- a/test/core/json/json_test.cc +++ b/test/core/json/json_test.cc @@ -184,7 +184,7 @@ static void test_atypical() { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); test_pairs(); test_atypical(); gpr_log(GPR_INFO, "json_test success"); diff --git a/test/core/memory_usage/BUILD b/test/core/memory_usage/BUILD index f39c309e369..38b088c75c7 100644 --- a/test/core/memory_usage/BUILD +++ b/test/core/memory_usage/BUILD @@ -19,42 +19,39 @@ grpc_package(name = "test/core/memory_usage") licenses(["notice"]) # Apache v2 grpc_cc_library( - name = "client", + name = "memory_usage_client", testonly = 1, srcs = ["client.cc"], deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) grpc_cc_library( - name = "server", + name = "memory_usage_server", testonly = 1, srcs = ["server.cc"], deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", + "//test/core/end2end:ssl_test_data", "//test/core/util:grpc_test_util", - "//test/core/end2end:ssl_test_data" ], ) grpc_cc_test( name = "memory_usage_test", srcs = ["memory_usage_test.cc"], - language = "C++", data = [ - ":client", - ":server", + ":memory_usage_client", + ":memory_usage_server", ], + language = "C++", deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/memory_usage/client.cc b/test/core/memory_usage/client.cc index 3c3fa53b515..097288c5efa 100644 --- a/test/core/memory_usage/client.cc +++ b/test/core/memory_usage/client.cc @@ -193,11 +193,11 @@ int main(int argc, char** argv) { gpr_cmdline* cl; grpc_event event; - grpc_init(); - GPR_ASSERT(argc >= 1); fake_argv[0] = argv[0]; - grpc_test_init(1, fake_argv); + grpc::testing::TestEnvironment env(1, fake_argv); + + grpc_init(); int warmup_iterations = 100; int benchmark_iterations = 1000; @@ -285,7 +285,7 @@ int main(int argc, char** argv) { grpc_slice_unref(slice); grpc_completion_queue_destroy(cq); - grpc_shutdown(); + grpc_shutdown_blocking(); gpr_log(GPR_INFO, "---------client stats--------"); gpr_log( diff --git a/test/core/memory_usage/server.cc b/test/core/memory_usage/server.cc index 6f8a9bc0d46..6fb14fa31a0 100644 --- a/test/core/memory_usage/server.cc +++ b/test/core/memory_usage/server.cc @@ -162,7 +162,7 @@ int main(int argc, char** argv) { GPR_ASSERT(argc >= 1); fake_argv[0] = argv[0]; - grpc_test_init(1, fake_argv); + grpc::testing::TestEnvironment env(1, fake_argv); grpc_init(); srand(static_cast(clock())); @@ -318,7 +318,7 @@ int main(int argc, char** argv) { grpc_server_destroy(server); grpc_completion_queue_destroy(cq); - grpc_shutdown(); + grpc_shutdown_blocking(); grpc_memory_counters_destroy(); return 0; } diff --git a/test/core/network_benchmarks/BUILD b/test/core/network_benchmarks/BUILD index e1b49536084..1194e4ad7bb 100644 --- a/test/core/network_benchmarks/BUILD +++ b/test/core/network_benchmarks/BUILD @@ -14,8 +14,12 @@ load("//bazel:grpc_build_system.bzl", "grpc_cc_library", "grpc_cc_test", "grpc_cc_binary", "grpc_package") -grpc_package(name = "test/core/network_benchmarks", - features = ["-layering_check", "-parse_headers" ] +grpc_package( + name = "test/core/network_benchmarks", + features = [ + "-layering_check", + "-parse_headers", + ], ) licenses(["notice"]) # Apache v2 @@ -27,7 +31,7 @@ grpc_cc_binary( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], + tags = ["no_windows"], ) diff --git a/test/core/security/BUILD b/test/core/security/BUILD index b7de955cdbe..d8dcdc25231 100644 --- a/test/core/security/BUILD +++ b/test/core/security/BUILD @@ -23,8 +23,8 @@ 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", + language = "C++", deps = [ "//:gpr", "//:grpc", @@ -35,8 +35,8 @@ grpc_fuzzer( grpc_fuzzer( name = "ssl_server_fuzzer", srcs = ["ssl_server_fuzzer.cc"], - language = "C++", corpus = "corpus/ssl_server_corpus", + language = "C++", deps = [ "//:gpr", "//:grpc", @@ -50,8 +50,8 @@ grpc_cc_library( srcs = ["oauth2_utils.cc"], hdrs = ["oauth2_utils.h"], language = "C++", - deps = ["//:grpc"], visibility = ["//test/cpp:__subpackages__"], + deps = ["//:grpc"], ) grpc_cc_test( @@ -61,7 +61,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -73,7 +72,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -85,7 +83,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -97,12 +94,10 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) - grpc_cc_test( name = "secure_endpoint_test", srcs = ["secure_endpoint_test.cc"], @@ -111,7 +106,6 @@ grpc_cc_test( "//:gpr", "//:grpc", "//test/core/iomgr:endpoint_tests", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -123,7 +117,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -137,14 +130,13 @@ grpc_cc_test( "//test/core/security/etc:test_roots/cert2.pem", "//test/core/security/etc:test_roots/cert3.pem", ], - language = "C++", external_deps = [ "gtest", ], + language = "C++", deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -156,9 +148,8 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", - ] + ], ) grpc_cc_binary( @@ -204,7 +195,7 @@ grpc_cc_test( "//:gpr", "//:gpr_base", "//:grpc", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -217,7 +208,7 @@ grpc_cc_test( "//:gpr", "//:gpr_base", "//:grpc", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -229,7 +220,7 @@ grpc_cc_test( "//:alts_util", "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -244,6 +235,6 @@ grpc_cc_test( "//:grpc_secure", "//:tsi", "//:tsi_interface", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/security/alts_credentials_fuzzer.cc b/test/core/security/alts_credentials_fuzzer.cc index bf18f0a589e..abe50031687 100644 --- a/test/core/security/alts_credentials_fuzzer.cc +++ b/test/core/security/alts_credentials_fuzzer.cc @@ -66,10 +66,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { gpr_set_log_function(dont_log); } gpr_free(grpc_trace_fuzzer); - struct grpc_memory_counters counters; - if (leak_check) { - grpc_memory_counters_init(); - } + grpc_core::testing::LeakDetector leak_detector(leak_check); input_stream inp = {data, data + size}; grpc_init(); bool is_on_gcp = grpc_alts_is_running_on_gcp(); @@ -111,10 +108,5 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { 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/alts_security_connector_test.cc b/test/core/security/alts_security_connector_test.cc index 9378236338d..bcba3408216 100644 --- a/test/core/security/alts_security_connector_test.cc +++ b/test/core/security/alts_security_connector_test.cc @@ -33,40 +33,34 @@ using grpc_core::internal::grpc_alts_auth_context_from_tsi_peer; /* This file contains unit tests of grpc_alts_auth_context_from_tsi_peer(). */ static void test_invalid_input_failure() { - tsi_peer peer; - grpc_auth_context* ctx; - GPR_ASSERT(grpc_alts_auth_context_from_tsi_peer(nullptr, &ctx) == - GRPC_SECURITY_ERROR); - GPR_ASSERT(grpc_alts_auth_context_from_tsi_peer(&peer, nullptr) == - GRPC_SECURITY_ERROR); + grpc_core::RefCountedPtr ctx = + grpc_alts_auth_context_from_tsi_peer(nullptr); + GPR_ASSERT(ctx == nullptr); } static void test_empty_certificate_type_failure() { tsi_peer peer; - grpc_auth_context* ctx = nullptr; GPR_ASSERT(tsi_construct_peer(0, &peer) == TSI_OK); - GPR_ASSERT(grpc_alts_auth_context_from_tsi_peer(&peer, &ctx) == - GRPC_SECURITY_ERROR); + grpc_core::RefCountedPtr ctx = + grpc_alts_auth_context_from_tsi_peer(&peer); GPR_ASSERT(ctx == nullptr); tsi_peer_destruct(&peer); } static void test_empty_peer_property_failure() { tsi_peer peer; - grpc_auth_context* ctx; GPR_ASSERT(tsi_construct_peer(1, &peer) == TSI_OK); GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_ALTS_CERTIFICATE_TYPE, &peer.properties[0]) == TSI_OK); - GPR_ASSERT(grpc_alts_auth_context_from_tsi_peer(&peer, &ctx) == - GRPC_SECURITY_ERROR); + grpc_core::RefCountedPtr ctx = + grpc_alts_auth_context_from_tsi_peer(&peer); GPR_ASSERT(ctx == nullptr); tsi_peer_destruct(&peer); } static void test_missing_rpc_protocol_versions_property_failure() { tsi_peer peer; - grpc_auth_context* ctx; GPR_ASSERT(tsi_construct_peer(kTsiAltsNumOfPeerProperties, &peer) == TSI_OK); GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_ALTS_CERTIFICATE_TYPE, @@ -74,23 +68,22 @@ static void test_missing_rpc_protocol_versions_property_failure() { GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( TSI_ALTS_SERVICE_ACCOUNT_PEER_PROPERTY, "alice", &peer.properties[1]) == TSI_OK); - GPR_ASSERT(grpc_alts_auth_context_from_tsi_peer(&peer, &ctx) == - GRPC_SECURITY_ERROR); + grpc_core::RefCountedPtr ctx = + grpc_alts_auth_context_from_tsi_peer(&peer); GPR_ASSERT(ctx == nullptr); tsi_peer_destruct(&peer); } static void test_unknown_peer_property_failure() { tsi_peer peer; - grpc_auth_context* ctx; GPR_ASSERT(tsi_construct_peer(kTsiAltsNumOfPeerProperties, &peer) == TSI_OK); GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_ALTS_CERTIFICATE_TYPE, &peer.properties[0]) == TSI_OK); GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( "unknown", "alice", &peer.properties[1]) == TSI_OK); - GPR_ASSERT(grpc_alts_auth_context_from_tsi_peer(&peer, &ctx) == - GRPC_SECURITY_ERROR); + grpc_core::RefCountedPtr ctx = + grpc_alts_auth_context_from_tsi_peer(&peer); GPR_ASSERT(ctx == nullptr); tsi_peer_destruct(&peer); } @@ -119,7 +112,6 @@ static bool test_identity(const grpc_auth_context* ctx, static void test_alts_peer_to_auth_context_success() { tsi_peer peer; - grpc_auth_context* ctx; GPR_ASSERT(tsi_construct_peer(kTsiAltsNumOfPeerProperties, &peer) == TSI_OK); GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_ALTS_CERTIFICATE_TYPE, @@ -144,11 +136,12 @@ static void test_alts_peer_to_auth_context_success() { GRPC_SLICE_START_PTR(serialized_peer_versions)), GRPC_SLICE_LENGTH(serialized_peer_versions), &peer.properties[2]) == TSI_OK); - GPR_ASSERT(grpc_alts_auth_context_from_tsi_peer(&peer, &ctx) == - GRPC_SECURITY_OK); - GPR_ASSERT( - test_identity(ctx, TSI_ALTS_SERVICE_ACCOUNT_PEER_PROPERTY, "alice")); - GRPC_AUTH_CONTEXT_UNREF(ctx, "test"); + grpc_core::RefCountedPtr ctx = + grpc_alts_auth_context_from_tsi_peer(&peer); + GPR_ASSERT(ctx != nullptr); + GPR_ASSERT(test_identity(ctx.get(), TSI_ALTS_SERVICE_ACCOUNT_PEER_PROPERTY, + "alice")); + ctx.reset(DEBUG_LOCATION, "test"); grpc_slice_unref(serialized_peer_versions); tsi_peer_destruct(&peer); } diff --git a/test/core/security/auth_context_test.cc b/test/core/security/auth_context_test.cc index 58f0d8e1c27..e7e0cb2ed94 100644 --- a/test/core/security/auth_context_test.cc +++ b/test/core/security/auth_context_test.cc @@ -19,118 +19,126 @@ #include #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/security/context/security_context.h" #include "test/core/util/test_config.h" #include static void test_empty_context(void) { - grpc_auth_context* ctx = grpc_auth_context_create(nullptr); + grpc_core::RefCountedPtr ctx = + grpc_core::MakeRefCounted(nullptr); grpc_auth_property_iterator it; gpr_log(GPR_INFO, "test_empty_context"); GPR_ASSERT(ctx != nullptr); - GPR_ASSERT(grpc_auth_context_peer_identity_property_name(ctx) == nullptr); - it = grpc_auth_context_peer_identity(ctx); + GPR_ASSERT(grpc_auth_context_peer_identity_property_name(ctx.get()) == + nullptr); + it = grpc_auth_context_peer_identity(ctx.get()); GPR_ASSERT(grpc_auth_property_iterator_next(&it) == nullptr); - it = grpc_auth_context_property_iterator(ctx); + it = grpc_auth_context_property_iterator(ctx.get()); GPR_ASSERT(grpc_auth_property_iterator_next(&it) == nullptr); - it = grpc_auth_context_find_properties_by_name(ctx, "foo"); + it = grpc_auth_context_find_properties_by_name(ctx.get(), "foo"); GPR_ASSERT(grpc_auth_property_iterator_next(&it) == nullptr); - GPR_ASSERT(grpc_auth_context_set_peer_identity_property_name(ctx, "bar") == - 0); - GPR_ASSERT(grpc_auth_context_peer_identity_property_name(ctx) == nullptr); - GRPC_AUTH_CONTEXT_UNREF(ctx, "test"); + GPR_ASSERT( + grpc_auth_context_set_peer_identity_property_name(ctx.get(), "bar") == 0); + GPR_ASSERT(grpc_auth_context_peer_identity_property_name(ctx.get()) == + nullptr); + ctx.reset(DEBUG_LOCATION, "test"); } static void test_simple_context(void) { - grpc_auth_context* ctx = grpc_auth_context_create(nullptr); + grpc_core::RefCountedPtr ctx = + grpc_core::MakeRefCounted(nullptr); grpc_auth_property_iterator it; size_t i; gpr_log(GPR_INFO, "test_simple_context"); GPR_ASSERT(ctx != nullptr); - grpc_auth_context_add_cstring_property(ctx, "name", "chapi"); - grpc_auth_context_add_cstring_property(ctx, "name", "chapo"); - grpc_auth_context_add_cstring_property(ctx, "foo", "bar"); - GPR_ASSERT(ctx->properties.count == 3); - GPR_ASSERT(grpc_auth_context_set_peer_identity_property_name(ctx, "name") == - 1); + grpc_auth_context_add_cstring_property(ctx.get(), "name", "chapi"); + grpc_auth_context_add_cstring_property(ctx.get(), "name", "chapo"); + grpc_auth_context_add_cstring_property(ctx.get(), "foo", "bar"); + GPR_ASSERT(ctx->properties().count == 3); + GPR_ASSERT(grpc_auth_context_set_peer_identity_property_name(ctx.get(), + "name") == 1); - GPR_ASSERT( - strcmp(grpc_auth_context_peer_identity_property_name(ctx), "name") == 0); - it = grpc_auth_context_property_iterator(ctx); - for (i = 0; i < ctx->properties.count; i++) { + GPR_ASSERT(strcmp(grpc_auth_context_peer_identity_property_name(ctx.get()), + "name") == 0); + it = grpc_auth_context_property_iterator(ctx.get()); + for (i = 0; i < ctx->properties().count; i++) { const grpc_auth_property* p = grpc_auth_property_iterator_next(&it); - GPR_ASSERT(p == &ctx->properties.array[i]); + GPR_ASSERT(p == &ctx->properties().array[i]); } GPR_ASSERT(grpc_auth_property_iterator_next(&it) == nullptr); - it = grpc_auth_context_find_properties_by_name(ctx, "foo"); + it = grpc_auth_context_find_properties_by_name(ctx.get(), "foo"); GPR_ASSERT(grpc_auth_property_iterator_next(&it) == - &ctx->properties.array[2]); + &ctx->properties().array[2]); GPR_ASSERT(grpc_auth_property_iterator_next(&it) == nullptr); - it = grpc_auth_context_peer_identity(ctx); + it = grpc_auth_context_peer_identity(ctx.get()); GPR_ASSERT(grpc_auth_property_iterator_next(&it) == - &ctx->properties.array[0]); + &ctx->properties().array[0]); GPR_ASSERT(grpc_auth_property_iterator_next(&it) == - &ctx->properties.array[1]); + &ctx->properties().array[1]); GPR_ASSERT(grpc_auth_property_iterator_next(&it) == nullptr); - GRPC_AUTH_CONTEXT_UNREF(ctx, "test"); + ctx.reset(DEBUG_LOCATION, "test"); } static void test_chained_context(void) { - grpc_auth_context* chained = grpc_auth_context_create(nullptr); - grpc_auth_context* ctx = grpc_auth_context_create(chained); + grpc_core::RefCountedPtr chained = + grpc_core::MakeRefCounted(nullptr); + grpc_auth_context* chained_ptr = chained.get(); + grpc_core::RefCountedPtr ctx = + grpc_core::MakeRefCounted(std::move(chained)); + grpc_auth_property_iterator it; size_t i; gpr_log(GPR_INFO, "test_chained_context"); - GRPC_AUTH_CONTEXT_UNREF(chained, "chained"); - grpc_auth_context_add_cstring_property(chained, "name", "padapo"); - grpc_auth_context_add_cstring_property(chained, "foo", "baz"); - grpc_auth_context_add_cstring_property(ctx, "name", "chapi"); - grpc_auth_context_add_cstring_property(ctx, "name", "chap0"); - grpc_auth_context_add_cstring_property(ctx, "foo", "bar"); - GPR_ASSERT(grpc_auth_context_set_peer_identity_property_name(ctx, "name") == - 1); + grpc_auth_context_add_cstring_property(chained_ptr, "name", "padapo"); + grpc_auth_context_add_cstring_property(chained_ptr, "foo", "baz"); + grpc_auth_context_add_cstring_property(ctx.get(), "name", "chapi"); + grpc_auth_context_add_cstring_property(ctx.get(), "name", "chap0"); + grpc_auth_context_add_cstring_property(ctx.get(), "foo", "bar"); + GPR_ASSERT(grpc_auth_context_set_peer_identity_property_name(ctx.get(), + "name") == 1); - GPR_ASSERT( - strcmp(grpc_auth_context_peer_identity_property_name(ctx), "name") == 0); - it = grpc_auth_context_property_iterator(ctx); - for (i = 0; i < ctx->properties.count; i++) { + GPR_ASSERT(strcmp(grpc_auth_context_peer_identity_property_name(ctx.get()), + "name") == 0); + it = grpc_auth_context_property_iterator(ctx.get()); + for (i = 0; i < ctx->properties().count; i++) { const grpc_auth_property* p = grpc_auth_property_iterator_next(&it); - GPR_ASSERT(p == &ctx->properties.array[i]); + GPR_ASSERT(p == &ctx->properties().array[i]); } - for (i = 0; i < chained->properties.count; i++) { + for (i = 0; i < chained_ptr->properties().count; i++) { const grpc_auth_property* p = grpc_auth_property_iterator_next(&it); - GPR_ASSERT(p == &chained->properties.array[i]); + GPR_ASSERT(p == &chained_ptr->properties().array[i]); } GPR_ASSERT(grpc_auth_property_iterator_next(&it) == nullptr); - it = grpc_auth_context_find_properties_by_name(ctx, "foo"); + it = grpc_auth_context_find_properties_by_name(ctx.get(), "foo"); GPR_ASSERT(grpc_auth_property_iterator_next(&it) == - &ctx->properties.array[2]); + &ctx->properties().array[2]); GPR_ASSERT(grpc_auth_property_iterator_next(&it) == - &chained->properties.array[1]); + &chained_ptr->properties().array[1]); GPR_ASSERT(grpc_auth_property_iterator_next(&it) == nullptr); - it = grpc_auth_context_peer_identity(ctx); + it = grpc_auth_context_peer_identity(ctx.get()); GPR_ASSERT(grpc_auth_property_iterator_next(&it) == - &ctx->properties.array[0]); + &ctx->properties().array[0]); GPR_ASSERT(grpc_auth_property_iterator_next(&it) == - &ctx->properties.array[1]); + &ctx->properties().array[1]); GPR_ASSERT(grpc_auth_property_iterator_next(&it) == - &chained->properties.array[0]); + &chained_ptr->properties().array[0]); GPR_ASSERT(grpc_auth_property_iterator_next(&it) == nullptr); - GRPC_AUTH_CONTEXT_UNREF(ctx, "test"); + ctx.reset(DEBUG_LOCATION, "test"); } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); test_empty_context(); test_simple_context(); test_chained_context(); diff --git a/test/core/security/credentials_test.cc b/test/core/security/credentials_test.cc index 56c4c9c0ae1..11cfc8cc905 100644 --- a/test/core/security/credentials_test.cc +++ b/test/core/security/credentials_test.cc @@ -46,19 +46,6 @@ using grpc_core::internal::grpc_flush_cached_google_default_credentials; using grpc_core::internal::set_gce_tenancy_checker_for_testing; -/* -- Mock channel credentials. -- */ - -static grpc_channel_credentials* grpc_mock_channel_credentials_create( - const grpc_channel_credentials_vtable* vtable) { - grpc_channel_credentials* c = - static_cast(gpr_malloc(sizeof(*c))); - memset(c, 0, sizeof(*c)); - c->type = "mock"; - c->vtable = vtable; - gpr_ref_init(&c->refcount, 1); - return c; -} - /* -- Constants. -- */ static const char test_google_iam_authorization_token[] = "blahblahblhahb"; @@ -377,9 +364,9 @@ static void run_request_metadata_test(grpc_call_credentials* creds, grpc_auth_metadata_context auth_md_ctx, request_metadata_state* state) { grpc_error* error = GRPC_ERROR_NONE; - if (grpc_call_credentials_get_request_metadata( - creds, &state->pollent, auth_md_ctx, &state->md_array, - &state->on_request_metadata, &error)) { + if (creds->get_request_metadata(&state->pollent, auth_md_ctx, + &state->md_array, &state->on_request_metadata, + &error)) { // Synchronous result. Invoke the callback directly. check_request_metadata(state, error); GRPC_ERROR_UNREF(error); @@ -400,7 +387,7 @@ static void test_google_iam_creds(void) { grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method, nullptr, nullptr}; run_request_metadata_test(creds, auth_md_ctx, state); - grpc_call_credentials_unref(creds); + creds->Unref(); } static void test_access_token_creds(void) { @@ -412,28 +399,36 @@ static void test_access_token_creds(void) { grpc_access_token_credentials_create("blah", nullptr); grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method, nullptr, nullptr}; - GPR_ASSERT(strcmp(creds->type, GRPC_CALL_CREDENTIALS_TYPE_OAUTH2) == 0); + GPR_ASSERT(strcmp(creds->type(), GRPC_CALL_CREDENTIALS_TYPE_OAUTH2) == 0); run_request_metadata_test(creds, auth_md_ctx, state); - grpc_call_credentials_unref(creds); + creds->Unref(); } -static grpc_security_status check_channel_oauth2_create_security_connector( - grpc_channel_credentials* c, grpc_call_credentials* call_creds, - const char* target, const grpc_channel_args* args, - grpc_channel_security_connector** sc, grpc_channel_args** new_args) { - GPR_ASSERT(strcmp(c->type, "mock") == 0); - GPR_ASSERT(call_creds != nullptr); - GPR_ASSERT(strcmp(call_creds->type, GRPC_CALL_CREDENTIALS_TYPE_OAUTH2) == 0); - return GRPC_SECURITY_OK; -} +namespace { +class check_channel_oauth2 final : public grpc_channel_credentials { + public: + check_channel_oauth2() : grpc_channel_credentials("mock") {} + ~check_channel_oauth2() override = default; + + grpc_core::RefCountedPtr + create_security_connector( + grpc_core::RefCountedPtr call_creds, + const char* target, const grpc_channel_args* args, + grpc_channel_args** new_args) override { + GPR_ASSERT(strcmp(type(), "mock") == 0); + GPR_ASSERT(call_creds != nullptr); + GPR_ASSERT(strcmp(call_creds->type(), GRPC_CALL_CREDENTIALS_TYPE_OAUTH2) == + 0); + return nullptr; + } +}; +} // namespace static void test_channel_oauth2_composite_creds(void) { grpc_core::ExecCtx exec_ctx; grpc_channel_args* new_args; - grpc_channel_credentials_vtable vtable = { - nullptr, check_channel_oauth2_create_security_connector, nullptr}; grpc_channel_credentials* channel_creds = - grpc_mock_channel_credentials_create(&vtable); + grpc_core::New(); grpc_call_credentials* oauth2_creds = grpc_access_token_credentials_create("blah", nullptr); grpc_channel_credentials* channel_oauth2_creds = @@ -441,9 +436,8 @@ static void test_channel_oauth2_composite_creds(void) { nullptr); grpc_channel_credentials_release(channel_creds); grpc_call_credentials_release(oauth2_creds); - GPR_ASSERT(grpc_channel_credentials_create_security_connector( - channel_oauth2_creds, nullptr, nullptr, nullptr, &new_args) == - GRPC_SECURITY_OK); + channel_oauth2_creds->create_security_connector(nullptr, nullptr, nullptr, + &new_args); grpc_channel_credentials_release(channel_oauth2_creds); } @@ -467,47 +461,54 @@ static void test_oauth2_google_iam_composite_creds(void) { grpc_call_credentials* composite_creds = grpc_composite_call_credentials_create(oauth2_creds, google_iam_creds, nullptr); - grpc_call_credentials_unref(oauth2_creds); - grpc_call_credentials_unref(google_iam_creds); - GPR_ASSERT( - strcmp(composite_creds->type, GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) == 0); - const grpc_call_credentials_array* creds_array = - grpc_composite_call_credentials_get_credentials(composite_creds); - GPR_ASSERT(creds_array->num_creds == 2); - GPR_ASSERT(strcmp(creds_array->creds_array[0]->type, - GRPC_CALL_CREDENTIALS_TYPE_OAUTH2) == 0); - GPR_ASSERT(strcmp(creds_array->creds_array[1]->type, - GRPC_CALL_CREDENTIALS_TYPE_IAM) == 0); + oauth2_creds->Unref(); + google_iam_creds->Unref(); + GPR_ASSERT(strcmp(composite_creds->type(), + GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) == 0); + const grpc_composite_call_credentials::CallCredentialsList& creds_list = + static_cast(composite_creds) + ->inner(); + GPR_ASSERT(creds_list.size() == 2); + GPR_ASSERT(strcmp(creds_list[0]->type(), GRPC_CALL_CREDENTIALS_TYPE_OAUTH2) == + 0); + GPR_ASSERT(strcmp(creds_list[1]->type(), GRPC_CALL_CREDENTIALS_TYPE_IAM) == + 0); run_request_metadata_test(composite_creds, auth_md_ctx, state); - grpc_call_credentials_unref(composite_creds); + composite_creds->Unref(); } -static grpc_security_status -check_channel_oauth2_google_iam_create_security_connector( - grpc_channel_credentials* c, grpc_call_credentials* call_creds, - const char* target, const grpc_channel_args* args, - grpc_channel_security_connector** sc, grpc_channel_args** new_args) { - const grpc_call_credentials_array* creds_array; - GPR_ASSERT(strcmp(c->type, "mock") == 0); - GPR_ASSERT(call_creds != nullptr); - GPR_ASSERT(strcmp(call_creds->type, GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) == - 0); - creds_array = grpc_composite_call_credentials_get_credentials(call_creds); - GPR_ASSERT(strcmp(creds_array->creds_array[0]->type, - GRPC_CALL_CREDENTIALS_TYPE_OAUTH2) == 0); - GPR_ASSERT(strcmp(creds_array->creds_array[1]->type, - GRPC_CALL_CREDENTIALS_TYPE_IAM) == 0); - return GRPC_SECURITY_OK; -} +namespace { +class check_channel_oauth2_google_iam final : public grpc_channel_credentials { + public: + check_channel_oauth2_google_iam() : grpc_channel_credentials("mock") {} + ~check_channel_oauth2_google_iam() override = default; + + grpc_core::RefCountedPtr + create_security_connector( + grpc_core::RefCountedPtr call_creds, + const char* target, const grpc_channel_args* args, + grpc_channel_args** new_args) override { + GPR_ASSERT(strcmp(type(), "mock") == 0); + GPR_ASSERT(call_creds != nullptr); + GPR_ASSERT( + strcmp(call_creds->type(), GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) == 0); + const grpc_composite_call_credentials::CallCredentialsList& creds_list = + static_cast(call_creds.get()) + ->inner(); + GPR_ASSERT( + strcmp(creds_list[0]->type(), GRPC_CALL_CREDENTIALS_TYPE_OAUTH2) == 0); + GPR_ASSERT(strcmp(creds_list[1]->type(), GRPC_CALL_CREDENTIALS_TYPE_IAM) == + 0); + return nullptr; + } +}; +} // namespace static void test_channel_oauth2_google_iam_composite_creds(void) { grpc_core::ExecCtx exec_ctx; grpc_channel_args* new_args; - grpc_channel_credentials_vtable vtable = { - nullptr, check_channel_oauth2_google_iam_create_security_connector, - nullptr}; grpc_channel_credentials* channel_creds = - grpc_mock_channel_credentials_create(&vtable); + grpc_core::New(); grpc_call_credentials* oauth2_creds = grpc_access_token_credentials_create("blah", nullptr); grpc_channel_credentials* channel_oauth2_creds = @@ -524,9 +525,8 @@ static void test_channel_oauth2_google_iam_composite_creds(void) { grpc_channel_credentials_release(channel_oauth2_creds); grpc_call_credentials_release(google_iam_creds); - GPR_ASSERT(grpc_channel_credentials_create_security_connector( - channel_oauth2_iam_creds, nullptr, nullptr, nullptr, - &new_args) == GRPC_SECURITY_OK); + channel_oauth2_iam_creds->create_security_connector(nullptr, nullptr, nullptr, + &new_args); grpc_channel_credentials_release(channel_oauth2_iam_creds); } @@ -534,7 +534,7 @@ static void test_channel_oauth2_google_iam_composite_creds(void) { static void validate_compute_engine_http_request( const grpc_httpcli_request* request) { GPR_ASSERT(request->handshaker != &grpc_httpcli_ssl); - GPR_ASSERT(strcmp(request->host, "metadata.google.internal") == 0); + GPR_ASSERT(strcmp(request->host, "metadata.google.internal.") == 0); GPR_ASSERT( strcmp(request->http.path, "/computeMetadata/v1/instance/service-accounts/default/token") == @@ -578,7 +578,7 @@ static int httpcli_get_should_not_be_called(const grpc_httpcli_request* request, return 1; } -static void test_compute_engine_creds_success(void) { +static void test_compute_engine_creds_success() { grpc_core::ExecCtx exec_ctx; expected_md emd[] = { {"authorization", "Bearer ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_"}}; @@ -603,7 +603,7 @@ static void test_compute_engine_creds_success(void) { run_request_metadata_test(creds, auth_md_ctx, state); grpc_core::ExecCtx::Get()->Flush(); - grpc_call_credentials_unref(creds); + creds->Unref(); grpc_httpcli_set_override(nullptr, nullptr); } @@ -620,7 +620,7 @@ static void test_compute_engine_creds_failure(void) { grpc_httpcli_set_override(compute_engine_httpcli_get_failure_override, httpcli_post_should_not_be_called); run_request_metadata_test(creds, auth_md_ctx, state); - grpc_call_credentials_unref(creds); + creds->Unref(); grpc_httpcli_set_override(nullptr, nullptr); } @@ -692,7 +692,7 @@ static void test_refresh_token_creds_success(void) { run_request_metadata_test(creds, auth_md_ctx, state); grpc_core::ExecCtx::Get()->Flush(); - grpc_call_credentials_unref(creds); + creds->Unref(); grpc_httpcli_set_override(nullptr, nullptr); } @@ -709,7 +709,7 @@ static void test_refresh_token_creds_failure(void) { grpc_httpcli_set_override(httpcli_get_should_not_be_called, refresh_token_httpcli_post_failure); run_request_metadata_test(creds, auth_md_ctx, state); - grpc_call_credentials_unref(creds); + creds->Unref(); grpc_httpcli_set_override(nullptr, nullptr); } @@ -762,7 +762,7 @@ static char* encode_and_sign_jwt_should_not_be_called( static grpc_service_account_jwt_access_credentials* creds_as_jwt( grpc_call_credentials* creds) { GPR_ASSERT(creds != nullptr); - GPR_ASSERT(strcmp(creds->type, GRPC_CALL_CREDENTIALS_TYPE_JWT) == 0); + GPR_ASSERT(strcmp(creds->type(), GRPC_CALL_CREDENTIALS_TYPE_JWT) == 0); return reinterpret_cast(creds); } @@ -773,7 +773,7 @@ static void test_jwt_creds_lifetime(void) { grpc_call_credentials* jwt_creds = grpc_service_account_jwt_access_credentials_create( json_key_string, grpc_max_auth_token_lifetime(), nullptr); - GPR_ASSERT(gpr_time_cmp(creds_as_jwt(jwt_creds)->jwt_lifetime, + GPR_ASSERT(gpr_time_cmp(creds_as_jwt(jwt_creds)->jwt_lifetime(), grpc_max_auth_token_lifetime()) == 0); grpc_call_credentials_release(jwt_creds); @@ -782,8 +782,8 @@ static void test_jwt_creds_lifetime(void) { GPR_ASSERT(gpr_time_cmp(grpc_max_auth_token_lifetime(), token_lifetime) > 0); jwt_creds = grpc_service_account_jwt_access_credentials_create( json_key_string, token_lifetime, nullptr); - GPR_ASSERT( - gpr_time_cmp(creds_as_jwt(jwt_creds)->jwt_lifetime, token_lifetime) == 0); + GPR_ASSERT(gpr_time_cmp(creds_as_jwt(jwt_creds)->jwt_lifetime(), + token_lifetime) == 0); grpc_call_credentials_release(jwt_creds); // Cropped lifetime. @@ -791,7 +791,7 @@ static void test_jwt_creds_lifetime(void) { token_lifetime = gpr_time_add(grpc_max_auth_token_lifetime(), add_to_max); jwt_creds = grpc_service_account_jwt_access_credentials_create( json_key_string, token_lifetime, nullptr); - GPR_ASSERT(gpr_time_cmp(creds_as_jwt(jwt_creds)->jwt_lifetime, + GPR_ASSERT(gpr_time_cmp(creds_as_jwt(jwt_creds)->jwt_lifetime(), grpc_max_auth_token_lifetime()) == 0); grpc_call_credentials_release(jwt_creds); @@ -834,7 +834,7 @@ static void test_jwt_creds_success(void) { run_request_metadata_test(creds, auth_md_ctx, state); grpc_core::ExecCtx::Get()->Flush(); - grpc_call_credentials_unref(creds); + creds->Unref(); gpr_free(json_key_string); gpr_free(expected_md_value); grpc_jwt_encode_and_sign_set_override(nullptr); @@ -856,7 +856,7 @@ static void test_jwt_creds_signing_failure(void) { run_request_metadata_test(creds, auth_md_ctx, state); gpr_free(json_key_string); - grpc_call_credentials_unref(creds); + creds->Unref(); grpc_jwt_encode_and_sign_set_override(nullptr); } @@ -875,8 +875,6 @@ static void set_google_default_creds_env_var_with_file_contents( 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(); @@ -885,40 +883,58 @@ static void test_google_default_creds_auth_key(void) { gpr_free(json_key); creds = reinterpret_cast( grpc_google_default_credentials_create()); - default_creds = reinterpret_cast( - creds->inner_creds); - GPR_ASSERT(default_creds->ssl_creds != nullptr); - jwt = reinterpret_cast( - creds->call_creds); + auto* default_creds = + reinterpret_cast( + creds->inner_creds()); + GPR_ASSERT(default_creds->ssl_creds() != nullptr); + auto* jwt = + reinterpret_cast( + creds->call_creds()); GPR_ASSERT( - strcmp(jwt->key.client_id, + strcmp(jwt->key().client_id, "777-abaslkan11hlb6nmim3bpspl31ud.apps.googleusercontent.com") == 0); - grpc_channel_credentials_unref(&creds->base); + creds->Unref(); gpr_setenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR, ""); /* Reset. */ } 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_google_default_credentials_create()); - default_creds = reinterpret_cast( - creds->inner_creds); - GPR_ASSERT(default_creds->ssl_creds != nullptr); - refresh = reinterpret_cast( - creds->call_creds); - GPR_ASSERT(strcmp(refresh->refresh_token.client_id, + auto* default_creds = + reinterpret_cast( + creds->inner_creds()); + GPR_ASSERT(default_creds->ssl_creds() != nullptr); + auto* refresh = + reinterpret_cast( + creds->call_creds()); + GPR_ASSERT(strcmp(refresh->refresh_token().client_id, "32555999999.apps.googleusercontent.com") == 0); - grpc_channel_credentials_unref(&creds->base); + creds->Unref(); gpr_setenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR, ""); /* Reset. */ } +static int default_creds_metadata_server_detection_httpcli_get_success_override( + const grpc_httpcli_request* request, grpc_millis deadline, + grpc_closure* on_done, grpc_httpcli_response* response) { + *response = http_response(200, ""); + grpc_http_header* headers = + static_cast(gpr_malloc(sizeof(*headers) * 1)); + headers[0].key = gpr_strdup("Metadata-Flavor"); + headers[0].value = gpr_strdup("Google"); + response->hdr_count = 1; + response->hdrs = headers; + GPR_ASSERT(strcmp(request->http.path, "/") == 0); + GPR_ASSERT(strcmp(request->host, "metadata.google.internal.") == 0); + GRPC_CLOSURE_SCHED(on_done, GRPC_ERROR_NONE); + return 1; +} + static char* null_well_known_creds_path_getter(void) { return nullptr; } static bool test_gce_tenancy_checker(void) { @@ -949,40 +965,87 @@ static void test_google_default_creds_gce(void) { /* Verify that the default creds actually embeds a GCE creds. */ GPR_ASSERT(creds != nullptr); - GPR_ASSERT(creds->call_creds != nullptr); + GPR_ASSERT(creds->call_creds() != nullptr); grpc_httpcli_set_override(compute_engine_httpcli_get_success_override, httpcli_post_should_not_be_called); - run_request_metadata_test(creds->call_creds, auth_md_ctx, state); + run_request_metadata_test(creds->mutable_call_creds(), auth_md_ctx, state); grpc_core::ExecCtx::Get()->Flush(); GPR_ASSERT(g_test_gce_tenancy_checker_called == true); /* Cleanup. */ - grpc_channel_credentials_unref(&creds->base); + creds->Unref(); grpc_httpcli_set_override(nullptr, nullptr); grpc_override_well_known_credentials_path_getter(nullptr); } +static void test_google_default_creds_non_gce(void) { + grpc_core::ExecCtx exec_ctx; + expected_md emd[] = { + {"authorization", "Bearer ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_"}}; + request_metadata_state* state = + make_request_metadata_state(GRPC_ERROR_NONE, emd, GPR_ARRAY_SIZE(emd)); + grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method, + nullptr, nullptr}; + grpc_flush_cached_google_default_credentials(); + gpr_setenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR, ""); /* Reset. */ + grpc_override_well_known_credentials_path_getter( + null_well_known_creds_path_getter); + set_gce_tenancy_checker_for_testing(test_gce_tenancy_checker); + g_test_gce_tenancy_checker_called = false; + g_test_is_on_gce = false; + /* Simulate a successful detection of metadata server. */ + grpc_httpcli_set_override( + default_creds_metadata_server_detection_httpcli_get_success_override, + httpcli_post_should_not_be_called); + grpc_composite_channel_credentials* creds = + reinterpret_cast( + grpc_google_default_credentials_create()); + /* Verify that the default creds actually embeds a GCE creds. */ + GPR_ASSERT(creds != nullptr); + GPR_ASSERT(creds->call_creds() != nullptr); + grpc_httpcli_set_override(compute_engine_httpcli_get_success_override, + httpcli_post_should_not_be_called); + run_request_metadata_test(creds->mutable_call_creds(), auth_md_ctx, state); + grpc_core::ExecCtx::Get()->Flush(); + GPR_ASSERT(g_test_gce_tenancy_checker_called == true); + /* Cleanup. */ + creds->Unref(); + grpc_httpcli_set_override(nullptr, nullptr); + grpc_override_well_known_credentials_path_getter(nullptr); +} + +static int default_creds_gce_detection_httpcli_get_failure_override( + const grpc_httpcli_request* request, grpc_millis deadline, + grpc_closure* on_done, grpc_httpcli_response* response) { + /* No magic header. */ + GPR_ASSERT(strcmp(request->http.path, "/") == 0); + GPR_ASSERT(strcmp(request->host, "metadata.google.internal.") == 0); + *response = http_response(200, ""); + GRPC_CLOSURE_SCHED(on_done, GRPC_ERROR_NONE); + return 1; +} + static void test_no_google_default_creds(void) { grpc_flush_cached_google_default_credentials(); gpr_setenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR, ""); /* Reset. */ grpc_override_well_known_credentials_path_getter( null_well_known_creds_path_getter); - set_gce_tenancy_checker_for_testing(test_gce_tenancy_checker); g_test_gce_tenancy_checker_called = false; g_test_is_on_gce = false; - + grpc_httpcli_set_override( + default_creds_gce_detection_httpcli_get_failure_override, + httpcli_post_should_not_be_called); /* Simulate a successful detection of GCE. */ GPR_ASSERT(grpc_google_default_credentials_create() == nullptr); - - /* Try a second one. GCE detection should not occur anymore. */ + /* Try a second one. GCE detection should occur again. */ g_test_gce_tenancy_checker_called = false; GPR_ASSERT(grpc_google_default_credentials_create() == nullptr); - GPR_ASSERT(g_test_gce_tenancy_checker_called == false); - + GPR_ASSERT(g_test_gce_tenancy_checker_called == true); /* Cleanup. */ grpc_override_well_known_credentials_path_getter(nullptr); + grpc_httpcli_set_override(nullptr, nullptr); } typedef enum { @@ -1058,7 +1121,7 @@ static void test_metadata_plugin_success(void) { GPR_ASSERT(state == PLUGIN_INITIAL_STATE); run_request_metadata_test(creds, auth_md_ctx, md_state); GPR_ASSERT(state == PLUGIN_GET_METADATA_CALLED_STATE); - grpc_call_credentials_unref(creds); + creds->Unref(); GPR_ASSERT(state == PLUGIN_DESTROY_CALLED_STATE); } @@ -1086,7 +1149,7 @@ static void test_metadata_plugin_failure(void) { GPR_ASSERT(state == PLUGIN_INITIAL_STATE); run_request_metadata_test(creds, auth_md_ctx, md_state); GPR_ASSERT(state == PLUGIN_GET_METADATA_CALLED_STATE); - grpc_call_credentials_unref(creds); + creds->Unref(); GPR_ASSERT(state == PLUGIN_DESTROY_CALLED_STATE); } @@ -1113,25 +1176,23 @@ static void test_channel_creds_duplicate_without_call_creds(void) { grpc_channel_credentials* channel_creds = grpc_fake_transport_security_credentials_create(); - grpc_channel_credentials* dup = - grpc_channel_credentials_duplicate_without_call_credentials( - channel_creds); + grpc_core::RefCountedPtr dup = + channel_creds->duplicate_without_call_credentials(); GPR_ASSERT(dup == channel_creds); - grpc_channel_credentials_unref(dup); + dup.reset(); grpc_call_credentials* call_creds = grpc_access_token_credentials_create("blah", nullptr); grpc_channel_credentials* composite_creds = grpc_composite_channel_credentials_create(channel_creds, call_creds, nullptr); - grpc_call_credentials_unref(call_creds); - dup = grpc_channel_credentials_duplicate_without_call_credentials( - composite_creds); + call_creds->Unref(); + dup = composite_creds->duplicate_without_call_credentials(); GPR_ASSERT(dup == channel_creds); - grpc_channel_credentials_unref(dup); + dup.reset(); - grpc_channel_credentials_unref(channel_creds); - grpc_channel_credentials_unref(composite_creds); + channel_creds->Unref(); + composite_creds->Unref(); } typedef struct { @@ -1206,7 +1267,7 @@ static void test_auth_metadata_context(void) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); test_empty_md_array(); test_add_to_empty_md_array(); @@ -1233,6 +1294,7 @@ int main(int argc, char** argv) { test_google_default_creds_auth_key(); test_google_default_creds_refresh_token(); test_google_default_creds_gce(); + test_google_default_creds_non_gce(); test_no_google_default_creds(); test_metadata_plugin_success(); test_metadata_plugin_failure(); diff --git a/test/core/security/json_token_test.cc b/test/core/security/json_token_test.cc index 7a5b3355fec..a3ae18e6abd 100644 --- a/test/core/security/json_token_test.cc +++ b/test/core/security/json_token_test.cc @@ -482,7 +482,7 @@ static void test_parse_refresh_token_failure_no_refresh_token(void) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); test_parse_json_key_success(); test_parse_json_key_failure_bad_json(); diff --git a/test/core/security/jwt_verifier_test.cc b/test/core/security/jwt_verifier_test.cc index 9718580a08d..70155cdd065 100644 --- a/test/core/security/jwt_verifier_test.cc +++ b/test/core/security/jwt_verifier_test.cc @@ -600,7 +600,7 @@ static void test_jwt_verifier_bad_format(void) { /* bad key */ int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); test_jwt_issuer_email_domain(); test_claims_success(); diff --git a/test/core/security/linux_system_roots_test.cc b/test/core/security/linux_system_roots_test.cc index 24d446de359..cd8bd3beb77 100644 --- a/test/core/security/linux_system_roots_test.cc +++ b/test/core/security/linux_system_roots_test.cc @@ -86,7 +86,7 @@ TEST(CreateRootCertsBundleTest, BundlesCorrectly) { } // namespace grpc int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/core/security/oauth2_utils.cc b/test/core/security/oauth2_utils.cc index 469129a6d03..c9e205ab743 100644 --- a/test/core/security/oauth2_utils.cc +++ b/test/core/security/oauth2_utils.cc @@ -86,9 +86,8 @@ char* grpc_test_fetch_oauth2_token_with_credentials( grpc_schedule_on_exec_ctx); grpc_error* error = GRPC_ERROR_NONE; - if (grpc_call_credentials_get_request_metadata(creds, &request.pops, null_ctx, - &request.md_array, - &request.closure, &error)) { + if (creds->get_request_metadata(&request.pops, null_ctx, &request.md_array, + &request.closure, &error)) { // Synchronous result; invoke callback directly. on_oauth2_response(&request, error); GRPC_ERROR_UNREF(error); diff --git a/test/core/security/print_google_default_creds_token.cc b/test/core/security/print_google_default_creds_token.cc index 4d251391ff2..398c58c6e17 100644 --- a/test/core/security/print_google_default_creds_token.cc +++ b/test/core/security/print_google_default_creds_token.cc @@ -96,11 +96,10 @@ int main(int argc, char** argv) { grpc_schedule_on_exec_ctx); error = GRPC_ERROR_NONE; - if (grpc_call_credentials_get_request_metadata( - (reinterpret_cast(creds)) - ->call_creds, - &sync.pops, context, &sync.md_array, &sync.on_request_metadata, - &error)) { + if (reinterpret_cast(creds) + ->mutable_call_creds() + ->get_request_metadata(&sync.pops, context, &sync.md_array, + &sync.on_request_metadata, &error)) { // Synchronous response. Invoke callback directly. on_metadata_response(&sync, error); GRPC_ERROR_UNREF(error); diff --git a/test/core/security/secure_endpoint_test.cc b/test/core/security/secure_endpoint_test.cc index 23cef99dfa8..3a2d599767a 100644 --- a/test/core/security/secure_endpoint_test.cc +++ b/test/core/security/secure_endpoint_test.cc @@ -182,7 +182,7 @@ static void test_leftover(grpc_endpoint_test_config config, size_t slice_size) { grpc_slice_buffer_init(&incoming); GRPC_CLOSURE_INIT(&done_closure, inc_call_ctr, &n, grpc_schedule_on_exec_ctx); - grpc_endpoint_read(f.client_ep, &incoming, &done_closure); + grpc_endpoint_read(f.client_ep, &incoming, &done_closure, /*urgent=*/false); grpc_core::ExecCtx::Get()->Flush(); GPR_ASSERT(n == 1); @@ -208,7 +208,7 @@ static void destroy_pollset(void* p, grpc_error* error) { int main(int argc, char** argv) { grpc_closure destroyed; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); { diff --git a/test/core/security/security_connector_test.cc b/test/core/security/security_connector_test.cc index fef0ea71f7d..496f064439c 100644 --- a/test/core/security/security_connector_test.cc +++ b/test/core/security/security_connector_test.cc @@ -27,6 +27,7 @@ #include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/tmpfile.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/security/context/security_context.h" #include "src/core/lib/security/security_connector/security_connector.h" #include "src/core/lib/security/security_connector/ssl_utils.h" @@ -35,6 +36,10 @@ #include "src/core/tsi/transport_security.h" #include "test/core/util/test_config.h" +#ifndef TSI_OPENSSL_ALPN_SUPPORT +#define TSI_OPENSSL_ALPN_SUPPORT 1 +#endif + static int check_transport_security_type(const grpc_auth_context* ctx) { grpc_auth_property_iterator it = grpc_auth_context_find_properties_by_name( ctx, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME); @@ -83,22 +88,22 @@ static int check_ssl_peer_equivalence(const tsi_peer* original, static void test_unauthenticated_ssl_peer(void) { tsi_peer peer; tsi_peer rpeer; - grpc_auth_context* ctx; GPR_ASSERT(tsi_construct_peer(1, &peer) == TSI_OK); GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_X509_CERTIFICATE_TYPE, &peer.properties[0]) == TSI_OK); - ctx = grpc_ssl_peer_to_auth_context(&peer); + grpc_core::RefCountedPtr 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)); + GPR_ASSERT(!grpc_auth_context_peer_is_authenticated(ctx.get())); + GPR_ASSERT(check_transport_security_type(ctx.get())); - rpeer = grpc_shallow_peer_from_ssl_auth_context(ctx); + rpeer = grpc_shallow_peer_from_ssl_auth_context(ctx.get()); GPR_ASSERT(check_ssl_peer_equivalence(&peer, &rpeer)); grpc_shallow_peer_destruct(&rpeer); tsi_peer_destruct(&peer); - GRPC_AUTH_CONTEXT_UNREF(ctx, "test"); + ctx.reset(DEBUG_LOCATION, "test"); } static int check_identity(const grpc_auth_context* ctx, @@ -175,7 +180,6 @@ static int check_x509_pem_cert(const grpc_auth_context* ctx, static void test_cn_only_ssl_peer_to_auth_context(void) { tsi_peer peer; tsi_peer rpeer; - grpc_auth_context* ctx; const char* expected_cn = "cn1"; const char* expected_pem_cert = "pem_cert1"; GPR_ASSERT(tsi_construct_peer(3, &peer) == TSI_OK); @@ -188,26 +192,27 @@ static void test_cn_only_ssl_peer_to_auth_context(void) { GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( TSI_X509_PEM_CERT_PROPERTY, expected_pem_cert, &peer.properties[2]) == TSI_OK); - ctx = grpc_ssl_peer_to_auth_context(&peer); + grpc_core::RefCountedPtr 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)); - GPR_ASSERT(check_transport_security_type(ctx)); - GPR_ASSERT(check_x509_cn(ctx, expected_cn)); - GPR_ASSERT(check_x509_pem_cert(ctx, expected_pem_cert)); + GPR_ASSERT(grpc_auth_context_peer_is_authenticated(ctx.get())); + GPR_ASSERT( + check_identity(ctx.get(), GRPC_X509_CN_PROPERTY_NAME, &expected_cn, 1)); + GPR_ASSERT(check_transport_security_type(ctx.get())); + GPR_ASSERT(check_x509_cn(ctx.get(), expected_cn)); + GPR_ASSERT(check_x509_pem_cert(ctx.get(), expected_pem_cert)); - rpeer = grpc_shallow_peer_from_ssl_auth_context(ctx); + rpeer = grpc_shallow_peer_from_ssl_auth_context(ctx.get()); GPR_ASSERT(check_ssl_peer_equivalence(&peer, &rpeer)); grpc_shallow_peer_destruct(&rpeer); tsi_peer_destruct(&peer); - GRPC_AUTH_CONTEXT_UNREF(ctx, "test"); + ctx.reset(DEBUG_LOCATION, "test"); } static void test_cn_and_one_san_ssl_peer_to_auth_context(void) { tsi_peer peer; tsi_peer rpeer; - grpc_auth_context* ctx; const char* expected_cn = "cn1"; const char* expected_san = "san1"; const char* expected_pem_cert = "pem_cert1"; @@ -224,27 +229,28 @@ static void test_cn_and_one_san_ssl_peer_to_auth_context(void) { GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( TSI_X509_PEM_CERT_PROPERTY, expected_pem_cert, &peer.properties[3]) == TSI_OK); - 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_san, 1)); - GPR_ASSERT(check_transport_security_type(ctx)); - GPR_ASSERT(check_x509_cn(ctx, expected_cn)); - GPR_ASSERT(check_x509_pem_cert(ctx, expected_pem_cert)); - rpeer = grpc_shallow_peer_from_ssl_auth_context(ctx); + grpc_core::RefCountedPtr ctx = + grpc_ssl_peer_to_auth_context(&peer); + GPR_ASSERT(ctx != nullptr); + GPR_ASSERT(grpc_auth_context_peer_is_authenticated(ctx.get())); + GPR_ASSERT( + check_identity(ctx.get(), GRPC_X509_SAN_PROPERTY_NAME, &expected_san, 1)); + GPR_ASSERT(check_transport_security_type(ctx.get())); + GPR_ASSERT(check_x509_cn(ctx.get(), expected_cn)); + GPR_ASSERT(check_x509_pem_cert(ctx.get(), expected_pem_cert)); + + rpeer = grpc_shallow_peer_from_ssl_auth_context(ctx.get()); GPR_ASSERT(check_ssl_peer_equivalence(&peer, &rpeer)); grpc_shallow_peer_destruct(&rpeer); tsi_peer_destruct(&peer); - GRPC_AUTH_CONTEXT_UNREF(ctx, "test"); + ctx.reset(DEBUG_LOCATION, "test"); } static void test_cn_and_multiple_sans_ssl_peer_to_auth_context(void) { tsi_peer peer; tsi_peer rpeer; - grpc_auth_context* ctx; const char* expected_cn = "cn1"; const char* expected_sans[] = {"san1", "san2", "san3"}; const char* expected_pem_cert = "pem_cert1"; @@ -265,28 +271,28 @@ static void test_cn_and_multiple_sans_ssl_peer_to_auth_context(void) { TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY, expected_sans[i], &peer.properties[3 + i]) == TSI_OK); } - ctx = grpc_ssl_peer_to_auth_context(&peer); + grpc_core::RefCountedPtr 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, - GPR_ARRAY_SIZE(expected_sans))); - GPR_ASSERT(check_transport_security_type(ctx)); - GPR_ASSERT(check_x509_cn(ctx, expected_cn)); - GPR_ASSERT(check_x509_pem_cert(ctx, expected_pem_cert)); + GPR_ASSERT(grpc_auth_context_peer_is_authenticated(ctx.get())); + GPR_ASSERT(check_identity(ctx.get(), GRPC_X509_SAN_PROPERTY_NAME, + expected_sans, GPR_ARRAY_SIZE(expected_sans))); + GPR_ASSERT(check_transport_security_type(ctx.get())); + GPR_ASSERT(check_x509_cn(ctx.get(), expected_cn)); + GPR_ASSERT(check_x509_pem_cert(ctx.get(), expected_pem_cert)); - rpeer = grpc_shallow_peer_from_ssl_auth_context(ctx); + rpeer = grpc_shallow_peer_from_ssl_auth_context(ctx.get()); GPR_ASSERT(check_ssl_peer_equivalence(&peer, &rpeer)); grpc_shallow_peer_destruct(&rpeer); tsi_peer_destruct(&peer); - GRPC_AUTH_CONTEXT_UNREF(ctx, "test"); + ctx.reset(DEBUG_LOCATION, "test"); } static void test_cn_and_multiple_sans_and_others_ssl_peer_to_auth_context( void) { tsi_peer peer; tsi_peer rpeer; - grpc_auth_context* ctx; const char* expected_cn = "cn1"; const char* expected_pem_cert = "pem_cert1"; const char* expected_sans[] = {"san1", "san2", "san3"}; @@ -311,21 +317,22 @@ static void test_cn_and_multiple_sans_and_others_ssl_peer_to_auth_context( TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY, expected_sans[i], &peer.properties[5 + i]) == TSI_OK); } - ctx = grpc_ssl_peer_to_auth_context(&peer); + grpc_core::RefCountedPtr 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, - GPR_ARRAY_SIZE(expected_sans))); - GPR_ASSERT(check_transport_security_type(ctx)); - GPR_ASSERT(check_x509_cn(ctx, expected_cn)); - GPR_ASSERT(check_x509_pem_cert(ctx, expected_pem_cert)); + GPR_ASSERT(grpc_auth_context_peer_is_authenticated(ctx.get())); + GPR_ASSERT(check_identity(ctx.get(), GRPC_X509_SAN_PROPERTY_NAME, + expected_sans, GPR_ARRAY_SIZE(expected_sans))); + GPR_ASSERT(check_transport_security_type(ctx.get())); + GPR_ASSERT(check_x509_cn(ctx.get(), expected_cn)); + GPR_ASSERT(check_x509_pem_cert(ctx.get(), expected_pem_cert)); - rpeer = grpc_shallow_peer_from_ssl_auth_context(ctx); + rpeer = grpc_shallow_peer_from_ssl_auth_context(ctx.get()); GPR_ASSERT(check_ssl_peer_equivalence(&peer, &rpeer)); grpc_shallow_peer_destruct(&rpeer); tsi_peer_destruct(&peer); - GRPC_AUTH_CONTEXT_UNREF(ctx, "test"); + ctx.reset(DEBUG_LOCATION, "test"); } static const char* roots_for_override_api = "roots for override api"; @@ -429,8 +436,45 @@ static void test_default_ssl_roots(void) { gpr_free(roots_env_var_file_path); } +static void test_peer_alpn_check(void) { +#if TSI_OPENSSL_ALPN_SUPPORT + tsi_peer peer; + const char* alpn = "grpc"; + const char* wrong_alpn = "wrong"; + // peer does not have a TSI_SSL_ALPN_SELECTED_PROTOCOL property. + GPR_ASSERT(tsi_construct_peer(1, &peer) == TSI_OK); + GPR_ASSERT(tsi_construct_string_peer_property("wrong peer property name", + alpn, strlen(alpn), + &peer.properties[0]) == TSI_OK); + grpc_error* error = grpc_ssl_check_alpn(&peer); + GPR_ASSERT(error != GRPC_ERROR_NONE); + tsi_peer_destruct(&peer); + GRPC_ERROR_UNREF(error); + // peer has a TSI_SSL_ALPN_SELECTED_PROTOCOL property but with an incorrect + // property value. + GPR_ASSERT(tsi_construct_peer(1, &peer) == TSI_OK); + GPR_ASSERT(tsi_construct_string_peer_property(TSI_SSL_ALPN_SELECTED_PROTOCOL, + wrong_alpn, strlen(wrong_alpn), + &peer.properties[0]) == TSI_OK); + error = grpc_ssl_check_alpn(&peer); + GPR_ASSERT(error != GRPC_ERROR_NONE); + tsi_peer_destruct(&peer); + GRPC_ERROR_UNREF(error); + // peer has a TSI_SSL_ALPN_SELECTED_PROTOCOL property with a correct property + // value. + GPR_ASSERT(tsi_construct_peer(1, &peer) == TSI_OK); + GPR_ASSERT(tsi_construct_string_peer_property(TSI_SSL_ALPN_SELECTED_PROTOCOL, + alpn, strlen(alpn), + &peer.properties[0]) == TSI_OK); + GPR_ASSERT(grpc_ssl_check_alpn(&peer) == GRPC_ERROR_NONE); + tsi_peer_destruct(&peer); +#else + GPR_ASSERT(grpc_ssl_check_alpn(nullptr) == GRPC_ERROR_NONE); +#endif +} + int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); test_unauthenticated_ssl_peer(); @@ -440,7 +484,7 @@ int main(int argc, char** argv) { test_cn_and_multiple_sans_and_others_ssl_peer_to_auth_context(); test_ipv6_address_san(); test_default_ssl_roots(); - + test_peer_alpn_check(); grpc_shutdown(); return 0; } diff --git a/test/core/security/ssl_credentials_test.cc b/test/core/security/ssl_credentials_test.cc index 9edcf42d3a4..7c9f5616654 100644 --- a/test/core/security/ssl_credentials_test.cc +++ b/test/core/security/ssl_credentials_test.cc @@ -56,7 +56,7 @@ static void test_convert_grpc_to_tsi_cert_pairs() { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); test_convert_grpc_to_tsi_cert_pairs(); diff --git a/test/core/security/ssl_server_fuzzer.cc b/test/core/security/ssl_server_fuzzer.cc index d2bbb7c1c2e..5846964eb90 100644 --- a/test/core/security/ssl_server_fuzzer.cc +++ b/test/core/security/ssl_server_fuzzer.cc @@ -41,7 +41,8 @@ struct handshake_state { }; static void on_handshake_done(void* arg, grpc_error* error) { - grpc_handshaker_args* args = static_cast(arg); + grpc_core::HandshakerArgs* args = + static_cast(arg); struct handshake_state* state = static_cast(args->user_data); GPR_ASSERT(state->done_callback_called == false); @@ -51,9 +52,8 @@ static void on_handshake_done(void* arg, grpc_error* error) { } extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { - struct grpc_memory_counters counters; if (squelch) gpr_set_log_function(dont_log); - if (leak_check) grpc_memory_counters_init(); + grpc_core::testing::LeakDetector leak_detector(leak_check); grpc_init(); { grpc_core::ExecCtx exec_ctx; @@ -82,19 +82,19 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { ca_cert, &pem_key_cert_pair, 1, 0, nullptr); // Create security connector - grpc_server_security_connector* sc = nullptr; - grpc_security_status status = - grpc_server_credentials_create_security_connector(creds, &sc); - GPR_ASSERT(status == GRPC_SECURITY_OK); + grpc_core::RefCountedPtr sc = + creds->create_security_connector(); + GPR_ASSERT(sc != nullptr); grpc_millis deadline = GPR_MS_PER_SEC + grpc_core::ExecCtx::Get()->Now(); struct handshake_state state; state.done_callback_called = false; - grpc_handshake_manager* handshake_mgr = grpc_handshake_manager_create(); - grpc_server_security_connector_add_handshakers(sc, nullptr, handshake_mgr); - grpc_handshake_manager_do_handshake( - handshake_mgr, mock_endpoint, nullptr /* channel_args */, deadline, - nullptr /* acceptor */, on_handshake_done, &state); + auto handshake_mgr = + grpc_core::MakeRefCounted(); + sc->add_handshakers(nullptr, handshake_mgr.get()); + handshake_mgr->DoHandshake(mock_endpoint, nullptr /* channel_args */, + deadline, nullptr /* acceptor */, + on_handshake_done, &state); grpc_core::ExecCtx::Get()->Flush(); // If the given string happens to be part of the correct client hello, the @@ -109,8 +109,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { GPR_ASSERT(state.done_callback_called); - grpc_handshake_manager_destroy(handshake_mgr); - GRPC_SECURITY_CONNECTOR_UNREF(&sc->base, "test"); + sc.reset(DEBUG_LOCATION, "test"); grpc_server_credentials_release(creds); grpc_slice_unref(cert_slice); grpc_slice_unref(key_slice); @@ -118,11 +117,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { grpc_core::ExecCtx::Get()->Flush(); } - grpc_shutdown(); - if (leak_check) { - counters = grpc_memory_counters_snapshot(); - grpc_memory_counters_destroy(); - GPR_ASSERT(counters.total_size_relative == 0); - } + grpc_shutdown_blocking(); return 0; } diff --git a/test/core/slice/BUILD b/test/core/slice/BUILD index 9a1a506a43c..12ee42ba9c3 100644 --- a/test/core/slice/BUILD +++ b/test/core/slice/BUILD @@ -51,7 +51,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -63,7 +62,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -75,7 +73,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -87,7 +84,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -102,7 +98,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -117,7 +112,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -129,7 +123,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/slice/b64_test.cc b/test/core/slice/b64_test.cc index 6b29443ba10..6677150c231 100644 --- a/test/core/slice/b64_test.cc +++ b/test/core/slice/b64_test.cc @@ -201,7 +201,7 @@ static void test_unpadded_decode(void) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); test_simple_encode_decode_b64_no_multiline(); test_simple_encode_decode_b64_multiline(); diff --git a/test/core/slice/percent_decode_corpus/clusterfuzz-testcase-minimized-grpc_percent_decode_fuzzer-5652313562808320 b/test/core/slice/percent_decode_corpus/clusterfuzz-testcase-minimized-grpc_percent_decode_fuzzer-5652313562808320 new file mode 100644 index 00000000000..797993a54d0 --- /dev/null +++ b/test/core/slice/percent_decode_corpus/clusterfuzz-testcase-minimized-grpc_percent_decode_fuzzer-5652313562808320 @@ -0,0 +1 @@ +%c4%cc%c4%cc%cc%ccccc%cccc%ccc%ccc%cc%ccc%ccc \ No newline at end of file diff --git a/test/core/slice/percent_decode_fuzzer.cc b/test/core/slice/percent_decode_fuzzer.cc index 81eb031014f..da8e03a4662 100644 --- a/test/core/slice/percent_decode_fuzzer.cc +++ b/test/core/slice/percent_decode_fuzzer.cc @@ -31,9 +31,8 @@ bool squelch = true; bool leak_check = true; extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { - struct grpc_memory_counters counters; + grpc_core::testing::LeakDetector leak_detector(true); grpc_init(); - grpc_memory_counters_init(); grpc_slice input = grpc_slice_from_copied_buffer((const char*)data, size); grpc_slice output; if (grpc_strict_percent_decode_slice( @@ -46,9 +45,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { } grpc_slice_unref(grpc_permissive_percent_decode_slice(input)); grpc_slice_unref(input); - counters = grpc_memory_counters_snapshot(); - grpc_memory_counters_destroy(); - grpc_shutdown(); - GPR_ASSERT(counters.total_size_relative == 0); + grpc_shutdown_blocking(); return 0; } diff --git a/test/core/slice/percent_encode_fuzzer.cc b/test/core/slice/percent_encode_fuzzer.cc index 1fd197e180a..4efa7a8d8e7 100644 --- a/test/core/slice/percent_encode_fuzzer.cc +++ b/test/core/slice/percent_encode_fuzzer.cc @@ -31,9 +31,8 @@ bool squelch = true; bool leak_check = true; static void test(const uint8_t* data, size_t size, const uint8_t* dict) { - struct grpc_memory_counters counters; + grpc_core::testing::LeakDetector leak_detector(true); grpc_init(); - grpc_memory_counters_init(); grpc_slice input = grpc_slice_from_copied_buffer(reinterpret_cast(data), size); grpc_slice output = grpc_percent_encode_slice(input, dict); @@ -49,10 +48,7 @@ static void test(const uint8_t* data, size_t size, const uint8_t* dict) { grpc_slice_unref(output); grpc_slice_unref(decoded_output); grpc_slice_unref(permissive_decoded_output); - counters = grpc_memory_counters_snapshot(); - grpc_memory_counters_destroy(); - grpc_shutdown(); - GPR_ASSERT(counters.total_size_relative == 0); + grpc_shutdown_blocking(); } extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { diff --git a/test/core/slice/percent_encoding_test.cc b/test/core/slice/percent_encoding_test.cc index e8d04fcc83c..ae6c39eb266 100644 --- a/test/core/slice/percent_encoding_test.cc +++ b/test/core/slice/percent_encoding_test.cc @@ -118,7 +118,7 @@ static void test_nonconformant_vector(const char* encoded, } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); TEST_VECTOR( "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~", diff --git a/test/core/slice/slice_buffer_test.cc b/test/core/slice/slice_buffer_test.cc index e59986730b8..7d4acfed003 100644 --- a/test/core/slice/slice_buffer_test.cc +++ b/test/core/slice/slice_buffer_test.cc @@ -19,6 +19,7 @@ #include #include #include +#include "src/core/lib/slice/slice_internal.h" #include "test/core/util/test_config.h" void test_slice_buffer_add() { @@ -105,12 +106,54 @@ void test_slice_buffer_move_first() { GPR_ASSERT(dst.length == dst_len); } +void test_slice_buffer_first() { + grpc_slice slices[3]; + slices[0] = grpc_slice_from_copied_string("aaa"); + slices[1] = grpc_slice_from_copied_string("bbbb"); + slices[2] = grpc_slice_from_copied_string("ccccc"); + + grpc_slice_buffer buf; + grpc_slice_buffer_init(&buf); + for (int idx = 0; idx < 3; ++idx) { + grpc_slice_ref(slices[idx]); + grpc_slice_buffer_add_indexed(&buf, slices[idx]); + } + + grpc_slice* first = grpc_slice_buffer_peek_first(&buf); + GPR_ASSERT(GPR_SLICE_LENGTH(*first) == GPR_SLICE_LENGTH(slices[0])); + GPR_ASSERT(buf.count == 3); + GPR_ASSERT(buf.length == 12); + + grpc_slice_buffer_sub_first(&buf, 1, 2); + first = grpc_slice_buffer_peek_first(&buf); + GPR_ASSERT(GPR_SLICE_LENGTH(*first) == 1); + GPR_ASSERT(buf.count == 3); + GPR_ASSERT(buf.length == 10); + + grpc_slice_buffer_remove_first(&buf); + first = grpc_slice_buffer_peek_first(&buf); + GPR_ASSERT(GPR_SLICE_LENGTH(*first) == GPR_SLICE_LENGTH(slices[1])); + GPR_ASSERT(buf.count == 2); + GPR_ASSERT(buf.length == 9); + + grpc_slice_buffer_remove_first(&buf); + first = grpc_slice_buffer_peek_first(&buf); + GPR_ASSERT(GPR_SLICE_LENGTH(*first) == GPR_SLICE_LENGTH(slices[2])); + GPR_ASSERT(buf.count == 1); + GPR_ASSERT(buf.length == 5); + + grpc_slice_buffer_remove_first(&buf); + GPR_ASSERT(buf.count == 0); + GPR_ASSERT(buf.length == 0); +} + int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); test_slice_buffer_add(); test_slice_buffer_move_first(); + test_slice_buffer_first(); grpc_shutdown(); return 0; diff --git a/test/core/slice/slice_hash_table_test.cc b/test/core/slice/slice_hash_table_test.cc index 43ddfe9bf2c..08cfe91e5a1 100644 --- a/test/core/slice/slice_hash_table_test.cc +++ b/test/core/slice/slice_hash_table_test.cc @@ -217,7 +217,7 @@ TEST(SliceHashTable, CmpEmptyKeysDifferentValue) { int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_core::ExecCtx::GlobalInit(); int result = RUN_ALL_TESTS(); grpc_core::ExecCtx::GlobalShutdown(); diff --git a/test/core/slice/slice_string_helpers_test.cc b/test/core/slice/slice_string_helpers_test.cc index 860a1bfe034..1bbc0947bc6 100644 --- a/test/core/slice/slice_string_helpers_test.cc +++ b/test/core/slice/slice_string_helpers_test.cc @@ -195,7 +195,7 @@ static void test_strsplit_nospace(void) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); test_dump_slice(); test_strsplit(); test_strsplit_nospace(); diff --git a/test/core/slice/slice_test.cc b/test/core/slice/slice_test.cc index e683c41f312..6ed02366fe2 100644 --- a/test/core/slice/slice_test.cc +++ b/test/core/slice/slice_test.cc @@ -51,13 +51,6 @@ static void test_slice_malloc_returns_something_sensible(void) { } /* Returned slice length must be what was requested. */ GPR_ASSERT(GRPC_SLICE_LENGTH(slice) == length); - /* If the slice has a refcount, it must be destroyable. */ - if (slice.refcount) { - GPR_ASSERT(slice.refcount->vtable != nullptr); - GPR_ASSERT(slice.refcount->vtable->ref != nullptr); - GPR_ASSERT(slice.refcount->vtable->unref != nullptr); - GPR_ASSERT(slice.refcount->vtable->hash != nullptr); - } /* We must be able to write to every byte of the data */ for (i = 0; i < length; i++) { GRPC_SLICE_START_PTR(slice)[i] = static_cast(i); @@ -294,7 +287,7 @@ static void test_static_slice_copy_interning(void) { int main(int argc, char** argv) { unsigned length; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); test_slice_malloc_returns_something_sensible(); test_slice_new_returns_something_sensible(); diff --git a/test/core/slice/slice_weak_hash_table_test.cc b/test/core/slice/slice_weak_hash_table_test.cc index b0a243d572e..ab0a648727d 100644 --- a/test/core/slice/slice_weak_hash_table_test.cc +++ b/test/core/slice/slice_weak_hash_table_test.cc @@ -98,7 +98,7 @@ TEST(SliceWeakHashTable, ForceOverload) { int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_core::ExecCtx::GlobalInit(); int result = RUN_ALL_TESTS(); grpc_core::ExecCtx::GlobalShutdown(); diff --git a/test/core/surface/BUILD b/test/core/surface/BUILD index 77df1cc989c..34777806cf2 100644 --- a/test/core/surface/BUILD +++ b/test/core/surface/BUILD @@ -25,7 +25,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -37,7 +36,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -49,7 +47,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -61,7 +58,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -73,7 +69,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -85,7 +80,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -98,7 +92,6 @@ grpc_cc_test( "//:gpr", "//:grpc", "//test/core/end2end:cq_verifier", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -111,7 +104,6 @@ grpc_cc_test( "//:gpr", "//:grpc", "//test/core/end2end:ssl_test_data", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -123,7 +115,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -135,7 +126,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -148,7 +138,6 @@ grpc_cc_test( "//:gpr", "//:grpc", "//test/core/end2end:ssl_test_data", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -160,7 +149,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -172,7 +160,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/surface/byte_buffer_reader_test.cc b/test/core/surface/byte_buffer_reader_test.cc index cff05caec14..bc368c49657 100644 --- a/test/core/surface/byte_buffer_reader_test.cc +++ b/test/core/surface/byte_buffer_reader_test.cc @@ -101,6 +101,73 @@ static void test_read_none_compressed_slice(void) { grpc_byte_buffer_destroy(buffer); } +static void test_peek_one_slice(void) { + grpc_slice slice; + grpc_byte_buffer* buffer; + grpc_byte_buffer_reader reader; + grpc_slice* first_slice; + grpc_slice* second_slice; + int first_code, second_code; + + LOG_TEST("test_peek_one_slice"); + slice = grpc_slice_from_copied_string("test"); + buffer = grpc_raw_byte_buffer_create(&slice, 1); + grpc_slice_unref(slice); + GPR_ASSERT(grpc_byte_buffer_reader_init(&reader, buffer) && + "Couldn't init byte buffer reader"); + first_code = grpc_byte_buffer_reader_peek(&reader, &first_slice); + GPR_ASSERT(first_code != 0); + GPR_ASSERT(memcmp(GRPC_SLICE_START_PTR(*first_slice), "test", 4) == 0); + second_code = grpc_byte_buffer_reader_peek(&reader, &second_slice); + GPR_ASSERT(second_code == 0); + grpc_byte_buffer_destroy(buffer); +} + +static void test_peek_one_slice_malloc(void) { + grpc_slice slice; + grpc_byte_buffer* buffer; + grpc_byte_buffer_reader reader; + grpc_slice* first_slice; + grpc_slice* second_slice; + int first_code, second_code; + + LOG_TEST("test_peek_one_slice_malloc"); + slice = grpc_slice_malloc(4); + memcpy(GRPC_SLICE_START_PTR(slice), "test", 4); + buffer = grpc_raw_byte_buffer_create(&slice, 1); + grpc_slice_unref(slice); + GPR_ASSERT(grpc_byte_buffer_reader_init(&reader, buffer) && + "Couldn't init byte buffer reader"); + first_code = grpc_byte_buffer_reader_peek(&reader, &first_slice); + GPR_ASSERT(first_code != 0); + GPR_ASSERT(memcmp(GRPC_SLICE_START_PTR(*first_slice), "test", 4) == 0); + second_code = grpc_byte_buffer_reader_peek(&reader, &second_slice); + GPR_ASSERT(second_code == 0); + grpc_byte_buffer_destroy(buffer); +} + +static void test_peek_none_compressed_slice(void) { + grpc_slice slice; + grpc_byte_buffer* buffer; + grpc_byte_buffer_reader reader; + grpc_slice* first_slice; + grpc_slice* second_slice; + int first_code, second_code; + + LOG_TEST("test_peek_none_compressed_slice"); + slice = grpc_slice_from_copied_string("test"); + buffer = grpc_raw_byte_buffer_create(&slice, 1); + grpc_slice_unref(slice); + GPR_ASSERT(grpc_byte_buffer_reader_init(&reader, buffer) && + "Couldn't init byte buffer reader"); + first_code = grpc_byte_buffer_reader_peek(&reader, &first_slice); + GPR_ASSERT(first_code != 0); + GPR_ASSERT(memcmp(GRPC_SLICE_START_PTR(*first_slice), "test", 4) == 0); + second_code = grpc_byte_buffer_reader_peek(&reader, &second_slice); + GPR_ASSERT(second_code == 0); + grpc_byte_buffer_destroy(buffer); +} + static void test_read_corrupted_slice(void) { grpc_slice slice; grpc_byte_buffer* buffer; @@ -267,10 +334,13 @@ static void test_byte_buffer_copy(void) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); test_read_one_slice(); test_read_one_slice_malloc(); test_read_none_compressed_slice(); + test_peek_one_slice(); + test_peek_one_slice_malloc(); + test_peek_none_compressed_slice(); test_read_gzip_compressed_slice(); test_read_deflate_compressed_slice(); test_read_corrupted_slice(); diff --git a/test/core/surface/channel_create_test.cc b/test/core/surface/channel_create_test.cc index 56f4f602e87..5f109c0f840 100644 --- a/test/core/surface/channel_create_test.cc +++ b/test/core/surface/channel_create_test.cc @@ -44,7 +44,7 @@ void test_unknown_scheme_target(void) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); test_unknown_scheme_target(); grpc_shutdown(); diff --git a/test/core/surface/completion_queue_test.cc b/test/core/surface/completion_queue_test.cc index f7ce8a7042e..7c3630eaf18 100644 --- a/test/core/surface/completion_queue_test.cc +++ b/test/core/surface/completion_queue_test.cc @@ -389,46 +389,49 @@ static void test_callback(void) { attr.cq_shutdown_cb = &shutdown_cb; for (size_t pidx = 0; pidx < GPR_ARRAY_SIZE(polling_types); pidx++) { - grpc_core::ExecCtx exec_ctx; // reset exec_ctx - attr.cq_polling_type = polling_types[pidx]; - cc = grpc_completion_queue_create( - grpc_completion_queue_factory_lookup(&attr), &attr, nullptr); - + int sumtags = 0; int counter = 0; - class TagCallback : public grpc_experimental_completion_queue_functor { - public: - TagCallback(int* counter, int tag) : counter_(counter), tag_(tag) { - functor_run = &TagCallback::Run; - } - ~TagCallback() {} - static void Run(grpc_experimental_completion_queue_functor* cb, int ok) { - GPR_ASSERT(static_cast(ok)); - auto* callback = static_cast(cb); - *callback->counter_ += callback->tag_; - grpc_core::Delete(callback); + { + // reset exec_ctx types + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; + grpc_core::ExecCtx exec_ctx; + attr.cq_polling_type = polling_types[pidx]; + cc = grpc_completion_queue_create( + grpc_completion_queue_factory_lookup(&attr), &attr, nullptr); + + class TagCallback : public grpc_experimental_completion_queue_functor { + public: + TagCallback(int* counter, int tag) : counter_(counter), tag_(tag) { + functor_run = &TagCallback::Run; + } + ~TagCallback() {} + static void Run(grpc_experimental_completion_queue_functor* cb, + int ok) { + GPR_ASSERT(static_cast(ok)); + auto* callback = static_cast(cb); + *callback->counter_ += callback->tag_; + grpc_core::Delete(callback); + }; + + private: + int* counter_; + int tag_; }; - private: - int* counter_; - int tag_; - }; + for (i = 0; i < GPR_ARRAY_SIZE(tags); i++) { + tags[i] = static_cast(grpc_core::New(&counter, i)); + sumtags += i; + } - int sumtags = 0; - for (i = 0; i < GPR_ARRAY_SIZE(tags); i++) { - tags[i] = static_cast(grpc_core::New(&counter, i)); - sumtags += i; + for (i = 0; i < GPR_ARRAY_SIZE(tags); i++) { + GPR_ASSERT(grpc_cq_begin_op(cc, tags[i])); + grpc_cq_end_op(cc, tags[i], GRPC_ERROR_NONE, do_nothing_end_completion, + nullptr, &completions[i]); + } + + shutdown_and_destroy(cc); } - - for (i = 0; i < GPR_ARRAY_SIZE(tags); i++) { - GPR_ASSERT(grpc_cq_begin_op(cc, tags[i])); - grpc_cq_end_op(cc, tags[i], GRPC_ERROR_NONE, do_nothing_end_completion, - nullptr, &completions[i]); - } - GPR_ASSERT(sumtags == counter); - - shutdown_and_destroy(cc); - GPR_ASSERT(got_shutdown); got_shutdown = false; } @@ -440,7 +443,7 @@ struct thread_state { }; int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); test_no_op(); test_pollset_conversion(); diff --git a/test/core/surface/completion_queue_threading_test.cc b/test/core/surface/completion_queue_threading_test.cc index 0b82803af6f..4215aad14af 100644 --- a/test/core/surface/completion_queue_threading_test.cc +++ b/test/core/surface/completion_queue_threading_test.cc @@ -288,7 +288,7 @@ static void test_threading(size_t producers, size_t consumers) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); test_too_many_plucks(); test_threading(1, 1); diff --git a/test/core/surface/concurrent_connectivity_test.cc b/test/core/surface/concurrent_connectivity_test.cc index fbc5ec4c541..b201568f482 100644 --- a/test/core/surface/concurrent_connectivity_test.cc +++ b/test/core/surface/concurrent_connectivity_test.cc @@ -44,7 +44,7 @@ #define NUM_OUTER_LOOPS 10 #define NUM_INNER_LOOPS 10 #define DELAY_MILLIS 10 -#define POLL_MILLIS 3000 +#define POLL_MILLIS 15000 #define NUM_OUTER_LOOPS_SHORT_TIMEOUTS 10 #define NUM_INNER_LOOPS_SHORT_TIMEOUTS 100 @@ -300,7 +300,7 @@ int run_concurrent_watches_with_short_timeouts_test() { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); run_concurrent_connectivity_test(); run_concurrent_watches_with_short_timeouts_test(); diff --git a/test/core/surface/init_test.cc b/test/core/surface/init_test.cc index 5749bc8b36d..583dd1b6de9 100644 --- a/test/core/surface/init_test.cc +++ b/test/core/surface/init_test.cc @@ -18,6 +18,9 @@ #include #include +#include + +#include "src/core/lib/surface/init.h" #include "test/core/util/test_config.h" static int g_flag; @@ -30,6 +33,17 @@ static void test(int rounds) { for (i = 0; i < rounds; i++) { grpc_shutdown(); } + grpc_maybe_wait_for_async_shutdown(); +} + +static void test_blocking(int rounds) { + int i; + for (i = 0; i < rounds; i++) { + grpc_init(); + } + for (i = 0; i < rounds; i++) { + grpc_shutdown_blocking(); + } } static void test_mixed(void) { @@ -39,6 +53,7 @@ static void test_mixed(void) { grpc_init(); grpc_shutdown(); grpc_shutdown(); + grpc_maybe_wait_for_async_shutdown(); } static void plugin_init(void) { g_flag = 1; } @@ -48,7 +63,7 @@ static void test_plugin() { grpc_register_plugin(plugin_init, plugin_destroy); grpc_init(); GPR_ASSERT(g_flag == 1); - grpc_shutdown(); + grpc_shutdown_blocking(); GPR_ASSERT(g_flag == 2); } @@ -57,13 +72,17 @@ static void test_repeatedly() { grpc_init(); grpc_shutdown(); } + grpc_maybe_wait_for_async_shutdown(); } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); test(1); test(2); test(3); + test_blocking(1); + test_blocking(2); + test_blocking(3); test_mixed(); test_plugin(); test_repeatedly(); diff --git a/test/core/surface/lame_client_test.cc b/test/core/surface/lame_client_test.cc index fac5ca8f7f6..09c3d431977 100644 --- a/test/core/surface/lame_client_test.cc +++ b/test/core/surface/lame_client_test.cc @@ -75,7 +75,7 @@ int main(int argc, char** argv) { grpc_slice details; char* peer; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); grpc_metadata_array_init(&initial_metadata_recv); diff --git a/test/core/surface/num_external_connectivity_watchers_test.cc b/test/core/surface/num_external_connectivity_watchers_test.cc index 7b7a0b6dfc0..454cbd5747e 100644 --- a/test/core/surface/num_external_connectivity_watchers_test.cc +++ b/test/core/surface/num_external_connectivity_watchers_test.cc @@ -191,7 +191,7 @@ static const test_fixture secure_test = { }; int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); run_timeouts_test(&insecure_test); run_timeouts_test(&secure_test); diff --git a/test/core/surface/public_headers_must_be_c89.c b/test/core/surface/public_headers_must_be_c89.c index 426ef1e8b13..fa02e76ec92 100644 --- a/test/core/surface/public_headers_must_be_c89.c +++ b/test/core/surface/public_headers_must_be_c89.c @@ -78,6 +78,7 @@ int main(int argc, char **argv) { printf("%lx", (unsigned long) grpc_init); printf("%lx", (unsigned long) grpc_shutdown); printf("%lx", (unsigned long) grpc_is_initialized); + printf("%lx", (unsigned long) grpc_shutdown_blocking); printf("%lx", (unsigned long) grpc_version_string); printf("%lx", (unsigned long) grpc_g_stands_for); printf("%lx", (unsigned long) grpc_completion_queue_factory_lookup); @@ -191,6 +192,15 @@ int main(int argc, char **argv) { printf("%lx", (unsigned long) grpc_alts_server_credentials_create); printf("%lx", (unsigned long) grpc_local_credentials_create); printf("%lx", (unsigned long) grpc_local_server_credentials_create); + printf("%lx", (unsigned long) grpc_tls_credentials_options_create); + printf("%lx", (unsigned long) grpc_tls_credentials_options_set_cert_request_type); + printf("%lx", (unsigned long) grpc_tls_credentials_options_set_key_materials_config); + printf("%lx", (unsigned long) grpc_tls_credentials_options_set_credential_reload_config); + printf("%lx", (unsigned long) grpc_tls_credentials_options_set_server_authorization_check_config); + printf("%lx", (unsigned long) grpc_tls_key_materials_config_create); + printf("%lx", (unsigned long) grpc_tls_key_materials_config_set_key_materials); + printf("%lx", (unsigned long) grpc_tls_credential_reload_config_create); + printf("%lx", (unsigned long) grpc_tls_server_authorization_check_config_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); @@ -199,6 +209,7 @@ int main(int argc, char **argv) { printf("%lx", (unsigned long) grpc_byte_buffer_reader_init); printf("%lx", (unsigned long) grpc_byte_buffer_reader_destroy); printf("%lx", (unsigned long) grpc_byte_buffer_reader_next); + printf("%lx", (unsigned long) grpc_byte_buffer_reader_peek); printf("%lx", (unsigned long) grpc_byte_buffer_reader_readall); printf("%lx", (unsigned long) grpc_raw_byte_buffer_from_reader); printf("%lx", (unsigned long) gpr_log_severity_string); diff --git a/test/core/surface/secure_channel_create_test.cc b/test/core/surface/secure_channel_create_test.cc index 06962179a23..e9bb815f6ee 100644 --- a/test/core/surface/secure_channel_create_test.cc +++ b/test/core/surface/secure_channel_create_test.cc @@ -39,7 +39,7 @@ void test_unknown_scheme_target(void) { GPR_ASSERT(0 == strcmp(elem->filter->name, "lame-client")); grpc_core::ExecCtx exec_ctx; GRPC_CHANNEL_INTERNAL_UNREF(chan, "test"); - grpc_channel_credentials_unref(creds); + creds->Unref(); } void test_security_connector_already_in_arg(void) { @@ -70,7 +70,7 @@ void test_null_creds(void) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); test_security_connector_already_in_arg(); test_null_creds(); diff --git a/test/core/surface/sequential_connectivity_test.cc b/test/core/surface/sequential_connectivity_test.cc index 10562b3be9c..3f9a7baf98b 100644 --- a/test/core/surface/sequential_connectivity_test.cc +++ b/test/core/surface/sequential_connectivity_test.cc @@ -168,7 +168,7 @@ static const test_fixture secure_test = { }; int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); run_test(&insecure_test); run_test(&secure_test); diff --git a/test/core/surface/server_chttp2_test.cc b/test/core/surface/server_chttp2_test.cc index fd8ab9cd3d5..ffb7f14f987 100644 --- a/test/core/surface/server_chttp2_test.cc +++ b/test/core/surface/server_chttp2_test.cc @@ -67,7 +67,7 @@ void test_add_same_port_twice() { #endif int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); test_unparsable_target(); #ifndef GRPC_UV diff --git a/test/core/surface/server_test.cc b/test/core/surface/server_test.cc index b4eabd8d4d8..2fc166546b0 100644 --- a/test/core/surface/server_test.cc +++ b/test/core/surface/server_test.cc @@ -148,7 +148,7 @@ static void test_bind_server_to_addrs(const char** addrs, size_t n) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); test_register_method_fail(); test_request_call_on_no_server_cq(); diff --git a/test/core/transport/BUILD b/test/core/transport/BUILD index 7ca1c1d9435..f38ecf2f66b 100644 --- a/test/core/transport/BUILD +++ b/test/core/transport/BUILD @@ -21,31 +21,29 @@ grpc_package(name = "test/core/transport") grpc_cc_test( name = "bdp_estimator_test", srcs = ["bdp_estimator_test.cc"], + external_deps = [ + "gtest", + ], language = "C++", deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], - external_deps = [ - "gtest", - ], ) grpc_cc_test( name = "byte_stream_test", srcs = ["byte_stream_test.cc"], + external_deps = [ + "gtest", + ], language = "C++", deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], - external_deps = [ - "gtest", - ], ) grpc_cc_test( @@ -55,7 +53,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -67,7 +64,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -75,16 +71,15 @@ grpc_cc_test( grpc_cc_test( name = "pid_controller_test", srcs = ["pid_controller_test.cc"], + external_deps = [ + "gtest", + ], language = "C++", deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], - external_deps = [ - "gtest", - ], ) grpc_cc_test( @@ -94,7 +89,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -106,7 +100,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -118,7 +111,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -126,12 +118,12 @@ grpc_cc_test( grpc_cc_test( name = "status_metadata_test", srcs = ["status_metadata_test.cc"], - language = "C++", - deps = [ - "//:grpc", - "//test/core/util:gpr_test_util", - ], external_deps = [ "gtest", ], + language = "C++", + deps = [ + "//:grpc", + "//test/core/util:grpc_test_util", + ], ) diff --git a/test/core/transport/bdp_estimator_test.cc b/test/core/transport/bdp_estimator_test.cc index c7e6b2bd841..a795daaead7 100644 --- a/test/core/transport/bdp_estimator_test.cc +++ b/test/core/transport/bdp_estimator_test.cc @@ -139,7 +139,7 @@ INSTANTIATE_TEST_CASE_P(TooManyNames, BdpEstimatorRandomTest, } // namespace grpc_core int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); gpr_now_impl = grpc_core::testing::fake_gpr_now; grpc_init(); grpc_timer_manager_set_threading(false); diff --git a/test/core/transport/byte_stream_test.cc b/test/core/transport/byte_stream_test.cc index df096372498..6c543892d0a 100644 --- a/test/core/transport/byte_stream_test.cc +++ b/test/core/transport/byte_stream_test.cc @@ -245,7 +245,7 @@ TEST(CachingByteStream, SharedCache) { int main(int argc, char** argv) { grpc_init(); - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); int retval = RUN_ALL_TESTS(); grpc_shutdown(); diff --git a/test/core/transport/chttp2/BUILD b/test/core/transport/chttp2/BUILD index 6eff716b01c..e5c1a7cff70 100644 --- a/test/core/transport/chttp2/BUILD +++ b/test/core/transport/chttp2/BUILD @@ -37,7 +37,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -49,7 +48,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -61,7 +59,20 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + ], +) + +grpc_cc_test( + name = "context_list_test", + srcs = ["context_list_test.cc"], + external_deps = [ + "gtest", + ], + language = "C++", + deps = [ + "//:gpr", + "//:grpc", "//test/core/util:grpc_test_util", ], ) @@ -73,7 +84,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -85,7 +95,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -97,7 +106,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -109,7 +117,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) @@ -117,16 +124,15 @@ grpc_cc_test( grpc_cc_test( name = "settings_timeout_test", srcs = ["settings_timeout_test.cc"], + external_deps = [ + "gtest", + ], language = "C++", deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], - external_deps = [ - "gtest", - ], ) grpc_cc_test( @@ -136,7 +142,6 @@ grpc_cc_test( deps = [ "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/transport/chttp2/alpn_test.cc b/test/core/transport/chttp2/alpn_test.cc index a43377393e1..6da5299363b 100644 --- a/test/core/transport/chttp2/alpn_test.cc +++ b/test/core/transport/chttp2/alpn_test.cc @@ -49,7 +49,7 @@ static void test_alpn_grpc_before_h2(void) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); test_alpn_success(); test_alpn_failure(); test_alpn_grpc_before_h2(); diff --git a/test/core/transport/chttp2/context_list_test.cc b/test/core/transport/chttp2/context_list_test.cc new file mode 100644 index 00000000000..0379eaaee4c --- /dev/null +++ b/test/core/transport/chttp2/context_list_test.cc @@ -0,0 +1,107 @@ +/* + * + * 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/lib/iomgr/port.h" + +#include +#include +#include + +#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" +#include "src/core/ext/transport/chttp2/transport/context_list.h" +#include "src/core/lib/transport/transport.h" +#include "test/core/util/mock_endpoint.h" +#include "test/core/util/test_config.h" + +#include + +namespace grpc_core { +namespace testing { +namespace { + +const uint32_t kByteOffset = 123; + +void* DummyArgsCopier(void* arg) { return arg; } + +void TestExecuteFlushesListVerifier(void* arg, grpc_core::Timestamps* ts, + grpc_error* error) { + ASSERT_NE(arg, nullptr); + EXPECT_EQ(error, GRPC_ERROR_NONE); + EXPECT_EQ(ts->byte_offset, kByteOffset); + gpr_atm* done = reinterpret_cast(arg); + gpr_atm_rel_store(done, static_cast(1)); +} + +void discard_write(grpc_slice slice) {} + +/** Tests that all ContextList elements in the list are flushed out on + * execute. + * Also tests that arg and byte_counter are passed correctly. + */ +TEST(ContextList, ExecuteFlushesList) { + grpc_core::ContextList* list = nullptr; + grpc_http2_set_write_timestamps_callback(TestExecuteFlushesListVerifier); + grpc_http2_set_fn_get_copied_context(DummyArgsCopier); + const int kNumElems = 5; + grpc_core::ExecCtx exec_ctx; + grpc_stream_refcount ref; + GRPC_STREAM_REF_INIT(&ref, 1, nullptr, nullptr, "dummy ref"); + grpc_resource_quota* resource_quota = + grpc_resource_quota_create("context_list_test"); + grpc_endpoint* mock_endpoint = + grpc_mock_endpoint_create(discard_write, resource_quota); + grpc_transport* t = + grpc_create_chttp2_transport(nullptr, mock_endpoint, true); + std::vector s; + s.reserve(kNumElems); + gpr_atm verifier_called[kNumElems]; + for (auto i = 0; i < kNumElems; i++) { + s.push_back(static_cast( + gpr_malloc(grpc_transport_stream_size(t)))); + grpc_transport_init_stream(reinterpret_cast(t), + reinterpret_cast(s[i]), &ref, + nullptr, nullptr); + s[i]->context = &verifier_called[i]; + s[i]->byte_counter = kByteOffset; + gpr_atm_rel_store(&verifier_called[i], static_cast(0)); + grpc_core::ContextList::Append(&list, s[i]); + } + grpc_core::Timestamps ts; + grpc_core::ContextList::Execute(list, &ts, GRPC_ERROR_NONE); + for (auto i = 0; i < kNumElems; i++) { + EXPECT_EQ(gpr_atm_acq_load(&verifier_called[i]), static_cast(1)); + grpc_transport_destroy_stream(reinterpret_cast(t), + reinterpret_cast(s[i]), + nullptr); + exec_ctx.Flush(); + gpr_free(s[i]); + } + grpc_transport_destroy(t); + grpc_resource_quota_unref(resource_quota); + exec_ctx.Flush(); +} +} // namespace +} // namespace testing +} // namespace grpc_core + +int main(int argc, char** argv) { + grpc::testing::TestEnvironment env(argc, argv); + grpc_init(); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/core/transport/chttp2/hpack_encoder_test.cc b/test/core/transport/chttp2/hpack_encoder_test.cc index ab819f90923..6cbc914c7fa 100644 --- a/test/core/transport/chttp2/hpack_encoder_test.cc +++ b/test/core/transport/chttp2/hpack_encoder_test.cc @@ -261,7 +261,7 @@ static void run_test(void (*test)(), const char* name) { int main(int argc, char** argv) { size_t i; grpc_test_only_set_slice_hash_seed(0); - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); TEST(test_basic_headers); TEST(test_decode_table_overflow); diff --git a/test/core/transport/chttp2/hpack_parser_test.cc b/test/core/transport/chttp2/hpack_parser_test.cc index 43b6c79e8a9..882ad726b5a 100644 --- a/test/core/transport/chttp2/hpack_parser_test.cc +++ b/test/core/transport/chttp2/hpack_parser_test.cc @@ -208,7 +208,7 @@ static void test_vectors(grpc_slice_split_mode mode) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); test_vectors(GRPC_SLICE_SPLIT_MERGE_ALL); test_vectors(GRPC_SLICE_SPLIT_ONE_BYTE); diff --git a/test/core/transport/chttp2/hpack_table_test.cc b/test/core/transport/chttp2/hpack_table_test.cc index 3ab463b6312..c31975786f0 100644 --- a/test/core/transport/chttp2/hpack_table_test.cc +++ b/test/core/transport/chttp2/hpack_table_test.cc @@ -268,7 +268,7 @@ static void test_find(void) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); test_static_lookup(); test_many_additions(); diff --git a/test/core/transport/chttp2/settings_timeout_test.cc b/test/core/transport/chttp2/settings_timeout_test.cc index 2d6f0a9a629..32a268ed521 100644 --- a/test/core/transport/chttp2/settings_timeout_test.cc +++ b/test/core/transport/chttp2/settings_timeout_test.cc @@ -133,7 +133,8 @@ class Client { grpc_millis deadline = grpc_core::ExecCtx::Get()->Now() + 3000; while (true) { EventState state; - grpc_endpoint_read(endpoint_, &read_buffer, state.closure()); + grpc_endpoint_read(endpoint_, &read_buffer, state.closure(), + /*urgent=*/true); if (!PollUntilDone(&state, deadline)) { retval = false; break; @@ -248,7 +249,7 @@ TEST(SettingsTimeout, Basic) { int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); int result = RUN_ALL_TESTS(); grpc_shutdown(); diff --git a/test/core/transport/chttp2/stream_map_test.cc b/test/core/transport/chttp2/stream_map_test.cc index 773eb3a35f6..a36c496eb1e 100644 --- a/test/core/transport/chttp2/stream_map_test.cc +++ b/test/core/transport/chttp2/stream_map_test.cc @@ -193,7 +193,7 @@ int main(int argc, char** argv) { uint32_t prev = 1; uint32_t tmp; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); test_no_op(); test_empty_find(); diff --git a/test/core/transport/chttp2/varint_test.cc b/test/core/transport/chttp2/varint_test.cc index 36760d0c723..5e00cc376af 100644 --- a/test/core/transport/chttp2/varint_test.cc +++ b/test/core/transport/chttp2/varint_test.cc @@ -44,7 +44,7 @@ static void test_varint(uint32_t value, uint32_t prefix_bits, uint8_t prefix_or, test_varint(value, prefix_bits, prefix_or, expect, sizeof(expect) - 1) int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); TEST_VARINT(0, 1, 0, "\x00"); TEST_VARINT(128, 1, 0, "\x7f\x01"); diff --git a/test/core/transport/connectivity_state_test.cc b/test/core/transport/connectivity_state_test.cc index cbd6318f528..26c09a76039 100644 --- a/test/core/transport/connectivity_state_test.cc +++ b/test/core/transport/connectivity_state_test.cc @@ -60,13 +60,9 @@ static void test_connectivity_state_name(void) { static void test_check(void) { grpc_connectivity_state_tracker tracker; grpc_core::ExecCtx exec_ctx; - grpc_error* error; gpr_log(GPR_DEBUG, "test_check"); grpc_connectivity_state_init(&tracker, GRPC_CHANNEL_IDLE, "xxx"); - GPR_ASSERT(grpc_connectivity_state_get(&tracker, &error) == - GRPC_CHANNEL_IDLE); GPR_ASSERT(grpc_connectivity_state_check(&tracker) == GRPC_CHANNEL_IDLE); - GPR_ASSERT(error == GRPC_ERROR_NONE); grpc_connectivity_state_destroy(&tracker); } @@ -134,7 +130,7 @@ static void test_subscribe_with_failure_then_destroy(void) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); grpc_core::testing::grpc_tracer_enable_flag(&grpc_connectivity_state_trace); test_connectivity_state_name(); diff --git a/test/core/transport/metadata_test.cc b/test/core/transport/metadata_test.cc index 8ab9639dfa2..e6b73de2de5 100644 --- a/test/core/transport/metadata_test.cc +++ b/test/core/transport/metadata_test.cc @@ -289,6 +289,28 @@ static void test_user_data_works(void) { grpc_shutdown(); } +static void test_user_data_works_for_allocated_md(void) { + int* ud1; + int* ud2; + grpc_mdelem md; + gpr_log(GPR_INFO, "test_user_data_works"); + + grpc_init(); + grpc_core::ExecCtx exec_ctx; + ud1 = static_cast(gpr_malloc(sizeof(int))); + *ud1 = 1; + ud2 = static_cast(gpr_malloc(sizeof(int))); + *ud2 = 2; + md = grpc_mdelem_from_slices(grpc_slice_from_static_string("abc"), + grpc_slice_from_static_string("123")); + grpc_mdelem_set_user_data(md, gpr_free, ud1); + grpc_mdelem_set_user_data(md, gpr_free, ud2); + GPR_ASSERT(grpc_mdelem_get_user_data(md, gpr_free) == ud1); + GRPC_MDELEM_UNREF(md); + + grpc_shutdown(); +} + static void verify_ascii_header_size(const char* key, const char* value, bool intern_key, bool intern_value) { grpc_mdelem elem = grpc_mdelem_from_slices( @@ -370,7 +392,7 @@ static void test_copied_static_metadata(bool dup_key, bool dup_value) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); test_no_op(); for (int k = 0; k <= 1; k++) { @@ -386,6 +408,7 @@ int main(int argc, char** argv) { test_create_many_persistant_metadata(); test_things_stick_around(); test_user_data_works(); + test_user_data_works_for_allocated_md(); grpc_shutdown(); return 0; } diff --git a/test/core/transport/pid_controller_test.cc b/test/core/transport/pid_controller_test.cc index 8d2cec40421..f6235244f60 100644 --- a/test/core/transport/pid_controller_test.cc +++ b/test/core/transport/pid_controller_test.cc @@ -85,7 +85,7 @@ INSTANTIATE_TEST_CASE_P( } // namespace grpc_core int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/core/transport/status_conversion_test.cc b/test/core/transport/status_conversion_test.cc index f7b3c62a40d..949be42aeb4 100644 --- a/test/core/transport/status_conversion_test.cc +++ b/test/core/transport/status_conversion_test.cc @@ -163,7 +163,7 @@ static void test_http2_status_to_grpc_status() { int main(int argc, char** argv) { int i; - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); test_grpc_status_to_http2_error(); diff --git a/test/core/transport/stream_owned_slice_test.cc b/test/core/transport/stream_owned_slice_test.cc index 7831f67a048..c489b11c185 100644 --- a/test/core/transport/stream_owned_slice_test.cc +++ b/test/core/transport/stream_owned_slice_test.cc @@ -26,20 +26,17 @@ static void do_nothing(void* arg, grpc_error* error) {} int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); uint8_t buffer[] = "abc123"; grpc_stream_refcount r; GRPC_STREAM_REF_INIT(&r, 1, do_nothing, nullptr, "test"); - GPR_ASSERT(r.refs.count == 1); grpc_slice slice = grpc_slice_from_stream_owned_buffer(&r, buffer, sizeof(buffer)); GPR_ASSERT(GRPC_SLICE_START_PTR(slice) == buffer); GPR_ASSERT(GRPC_SLICE_LENGTH(slice) == sizeof(buffer)); - GPR_ASSERT(r.refs.count == 2); grpc_slice_unref(slice); - GPR_ASSERT(r.refs.count == 1); grpc_shutdown(); return 0; diff --git a/test/core/transport/timeout_encoding_test.cc b/test/core/transport/timeout_encoding_test.cc index b7044b5b410..22e68fe5540 100644 --- a/test/core/transport/timeout_encoding_test.cc +++ b/test/core/transport/timeout_encoding_test.cc @@ -156,7 +156,7 @@ void test_decoding_fails(void) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); test_encoding(); test_decoding(); test_decoding_fails(); diff --git a/test/core/tsi/BUILD b/test/core/tsi/BUILD index ae6e8fdc325..14578c0e48b 100644 --- a/test/core/tsi/BUILD +++ b/test/core/tsi/BUILD @@ -16,7 +16,10 @@ load("//bazel:grpc_build_system.bzl", "grpc_cc_library", "grpc_cc_test", "grpc_c licenses(["notice"]) # Apache v2 -grpc_package(name = "test/core/tsi", visibility = "public") +grpc_package( + name = "test/core/tsi", + visibility = "public", +) grpc_cc_library( name = "transport_security_test_lib", @@ -34,25 +37,25 @@ grpc_cc_test( language = "C++", deps = [ ":transport_security_test_lib", - "//:grpc", "//:gpr", + "//:grpc", "//:tsi", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) grpc_cc_test( name = "ssl_session_cache_test", srcs = ["ssl_session_cache_test.cc"], - language = "C++", external_deps = [ "gtest", ], + language = "C++", deps = [ - "//:grpc", "//:gpr", + "//:grpc", "//:tsi", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -75,10 +78,10 @@ grpc_cc_test( language = "C++", deps = [ ":transport_security_test_lib", - "//:grpc", "//:gpr", + "//:grpc", "//:tsi", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -87,9 +90,8 @@ grpc_cc_test( srcs = ["transport_security_test.cc"], language = "C++", deps = [ - "//:grpc", "//:gpr", - "//test/core/util:gpr_test_util", + "//:grpc", "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/tsi/alts/crypt/BUILD b/test/core/tsi/alts/crypt/BUILD index abe1e83656f..767368a2f80 100644 --- a/test/core/tsi/alts/crypt/BUILD +++ b/test/core/tsi/alts/crypt/BUILD @@ -1,5 +1,5 @@ # 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 @@ -16,7 +16,10 @@ load("//bazel:grpc_build_system.bzl", "grpc_cc_library", "grpc_cc_test", "grpc_p licenses(["notice"]) # Apache v2 -grpc_package(name = "test/core/tsi/alts/crypt", visibility = "public") +grpc_package( + name = "test/core/tsi/alts/crypt", + visibility = "public", +) grpc_cc_test( name = "alts_crypt_test", @@ -27,7 +30,7 @@ grpc_cc_test( "//:alts_frame_protector", "//:gpr", "//:grpc", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -40,4 +43,3 @@ grpc_cc_library( "//:grpc", ], ) - diff --git a/test/core/tsi/alts/fake_handshaker/BUILD b/test/core/tsi/alts/fake_handshaker/BUILD index 98cd628a7d2..8bf9c654d42 100644 --- a/test/core/tsi/alts/fake_handshaker/BUILD +++ b/test/core/tsi/alts/fake_handshaker/BUILD @@ -16,7 +16,10 @@ 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_package( + name = "test/core/tsi/alts/fake_handshaker", + visibility = "public", +) grpc_proto_library( name = "transport_security_common_proto", @@ -52,7 +55,7 @@ grpc_cc_binary( srcs = ["fake_handshaker_server_main.cc"], language = "C++", deps = [ - "//test/cpp/util:test_config", "fake_handshaker_lib", + "//test/cpp/util:test_config", ], ) diff --git a/test/core/tsi/alts/frame_protector/BUILD b/test/core/tsi/alts/frame_protector/BUILD index 6ff3015f4dd..1e3d16df02c 100644 --- a/test/core/tsi/alts/frame_protector/BUILD +++ b/test/core/tsi/alts/frame_protector/BUILD @@ -1,5 +1,5 @@ # 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 @@ -27,7 +27,7 @@ grpc_cc_test( "//:gpr", "//:grpc", "//test/core/tsi/alts/crypt:alts_crypt_test_util", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -40,7 +40,7 @@ grpc_cc_test( "//:gpr", "//:grpc", "//test/core/tsi/alts/crypt:alts_crypt_test_util", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -54,9 +54,9 @@ grpc_cc_test( "//:grpc", "//:tsi", "//:tsi_interface", - "//test/core/tsi/alts/crypt:alts_crypt_test_util", "//test/core/tsi:transport_security_test_lib", - "//test/core/util:gpr_test_util", + "//test/core/tsi/alts/crypt:alts_crypt_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -70,6 +70,6 @@ grpc_cc_test( "//:gpr_base", "//:grpc", "//test/core/tsi/alts/crypt:alts_crypt_test_util", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/tsi/alts/handshaker/BUILD b/test/core/tsi/alts/handshaker/BUILD index 3f1a681c1ad..61ba16ad6db 100644 --- a/test/core/tsi/alts/handshaker/BUILD +++ b/test/core/tsi/alts/handshaker/BUILD @@ -1,5 +1,5 @@ # 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 @@ -14,10 +14,10 @@ load("//bazel:grpc_build_system.bzl", "grpc_cc_library", "grpc_cc_test", "grpc_package") -licenses(["notice"]) # Apache v2 - +licenses(["notice"]) # Apache v2 + grpc_package(name = "test/core/tsi/alts/handshaker") - + grpc_cc_library( name = "alts_handshaker_service_api_test_lib", srcs = ["alts_handshaker_service_api_test_lib.cc"], @@ -25,7 +25,7 @@ grpc_cc_library( deps = [ "//:alts_util", "//:grpc", - ], + ], ) grpc_cc_test( @@ -34,10 +34,10 @@ grpc_cc_test( language = "C++", deps = [ ":alts_handshaker_service_api_test_lib", + "//:grpc", "//:tsi", "//:tsi_interface", - "//:grpc", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -48,7 +48,7 @@ grpc_cc_test( deps = [ ":alts_handshaker_service_api_test_lib", "//:grpc", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -62,7 +62,7 @@ grpc_cc_test( "//:gpr_base", "//:grpc", "//:tsi", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -74,7 +74,7 @@ grpc_cc_test( ":alts_handshaker_service_api_test_lib", "//:grpc", "//:tsi", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -85,7 +85,6 @@ grpc_cc_test( deps = [ "//:alts_util", "//:grpc", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) - diff --git a/test/core/tsi/alts/handshaker/alts_tsi_utils_test.cc b/test/core/tsi/alts/handshaker/alts_tsi_utils_test.cc index 98c5d236415..8d75d35368d 100644 --- a/test/core/tsi/alts/handshaker/alts_tsi_utils_test.cc +++ b/test/core/tsi/alts/handshaker/alts_tsi_utils_test.cc @@ -51,7 +51,7 @@ static void deserialize_response_test() { GPR_ASSERT(grpc_gcp_handshaker_resp_equals(resp, decoded_resp)); grpc_byte_buffer_destroy(buffer); - /* Invalid serializaiton. */ + /* Invalid serialization. */ grpc_slice bad_slice = grpc_slice_split_head(&slice, GRPC_SLICE_LENGTH(slice) - 1); buffer = grpc_raw_byte_buffer_create(&bad_slice, 1 /* number of slices */); diff --git a/test/core/tsi/alts/zero_copy_frame_protector/BUILD b/test/core/tsi/alts/zero_copy_frame_protector/BUILD index a3b797327e4..696fc8dc065 100644 --- a/test/core/tsi/alts/zero_copy_frame_protector/BUILD +++ b/test/core/tsi/alts/zero_copy_frame_protector/BUILD @@ -1,5 +1,5 @@ # 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 @@ -28,7 +28,7 @@ grpc_cc_test( "//:grpc", "//:grpc_base_c", "//test/core/tsi/alts/crypt:alts_crypt_test_util", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -41,7 +41,7 @@ grpc_cc_test( "//:gpr", "//:grpc", "//test/core/tsi/alts/crypt:alts_crypt_test_util", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -55,6 +55,6 @@ grpc_cc_test( "//:grpc", "//:grpc_base_c", "//test/core/tsi/alts/crypt:alts_crypt_test_util", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector_test.cc b/test/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector_test.cc index 3ee8323a310..62d799f18b3 100644 --- a/test/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector_test.cc +++ b/test/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector_test.cc @@ -175,7 +175,7 @@ static void seal_unseal_small_buffer(tsi_zero_copy_grpc_protector* sender, GPR_ASSERT(tsi_zero_copy_grpc_protector_protect( sender, &var->original_sb, &var->protected_sb) == TSI_OK); /* Splits protected slice buffer into two: first one is staging_sb, and - * second one is is protected_sb. */ + * second one is protected_sb. */ uint32_t staging_sb_size = gsec_test_bias_random_uint32( static_cast(var->protected_sb.length - 1)) + diff --git a/test/core/tsi/fake_transport_security_test.cc b/test/core/tsi/fake_transport_security_test.cc index 587d8f5dda5..32361f19d3f 100644 --- a/test/core/tsi/fake_transport_security_test.cc +++ b/test/core/tsi/fake_transport_security_test.cc @@ -139,7 +139,7 @@ void fake_tsi_test_do_round_trip_odd_buffer_size() { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); fake_tsi_test_do_handshake_tiny_handshake_buffer(); fake_tsi_test_do_handshake_small_handshake_buffer(); diff --git a/test/core/tsi/ssl_session_cache_test.cc b/test/core/tsi/ssl_session_cache_test.cc index c86cefb3ff4..b9c98c0b57c 100644 --- a/test/core/tsi/ssl_session_cache_test.cc +++ b/test/core/tsi/ssl_session_cache_test.cc @@ -145,7 +145,7 @@ TEST(SslSessionCacheTest, LruCache) { int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc_init(); int ret = RUN_ALL_TESTS(); grpc_shutdown(); diff --git a/test/core/tsi/ssl_transport_security_test.cc b/test/core/tsi/ssl_transport_security_test.cc index baffad6ea36..5985b0ecaa5 100644 --- a/test/core/tsi/ssl_transport_security_test.cc +++ b/test/core/tsi/ssl_transport_security_test.cc @@ -107,7 +107,6 @@ static void ssl_test_setup_handshakers(tsi_test_fixture* fixture) { ssl_alpn_lib* alpn_lib = ssl_fixture->alpn_lib; /* Create client handshaker factory. */ tsi_ssl_client_handshaker_options client_options; - memset(&client_options, 0, sizeof(client_options)); client_options.pem_root_certs = key_cert_lib->root_cert; if (ssl_fixture->force_client_auth) { client_options.pem_key_cert_pair = @@ -131,7 +130,6 @@ static void ssl_test_setup_handshakers(tsi_test_fixture* fixture) { TSI_OK); /* Create server handshaker factory. */ tsi_ssl_server_handshaker_options server_options; - memset(&server_options, 0, sizeof(server_options)); if (alpn_lib->alpn_mode == ALPN_SERVER_NO_CLIENT || alpn_lib->alpn_mode == ALPN_CLIENT_SERVER_OK || alpn_lib->alpn_mode == ALPN_CLIENT_SERVER_MISMATCH) { @@ -681,7 +679,6 @@ void test_tsi_ssl_client_handshaker_factory_refcounting() { char* cert_chain = load_file(SSL_TSI_TEST_CREDENTIALS_DIR, "client.pem"); tsi_ssl_client_handshaker_options options; - memset(&options, 0, sizeof(options)); options.pem_root_certs = cert_chain; tsi_ssl_client_handshaker_factory* client_handshaker_factory; GPR_ASSERT(tsi_create_ssl_client_handshaker_factory_with_options( @@ -726,10 +723,13 @@ void test_tsi_ssl_server_handshaker_factory_refcounting() { cert_pair.cert_chain = cert_chain; cert_pair.private_key = load_file(SSL_TSI_TEST_CREDENTIALS_DIR, "server0.key"); + tsi_ssl_server_handshaker_options options; + options.pem_key_cert_pairs = &cert_pair; + options.num_key_cert_pairs = 1; + options.pem_client_root_certs = cert_chain; - GPR_ASSERT(tsi_create_ssl_server_handshaker_factory( - &cert_pair, 1, cert_chain, 0, nullptr, nullptr, 0, - &server_handshaker_factory) == TSI_OK); + GPR_ASSERT(tsi_create_ssl_server_handshaker_factory_with_options( + &options, &server_handshaker_factory) == TSI_OK); handshaker_factory_destructor_called = false; original_vtable = tsi_ssl_handshaker_factory_swap_vtable( @@ -763,7 +763,6 @@ void test_tsi_ssl_client_handshaker_factory_bad_params() { tsi_ssl_client_handshaker_factory* client_handshaker_factory; tsi_ssl_client_handshaker_options options; - memset(&options, 0, sizeof(options)); options.pem_root_certs = cert_chain; GPR_ASSERT(tsi_create_ssl_client_handshaker_factory_with_options( &options, &client_handshaker_factory) == TSI_INVALID_ARGUMENT); @@ -776,10 +775,24 @@ void ssl_tsi_test_handshaker_factory_internals() { test_tsi_ssl_client_handshaker_factory_bad_params(); } -int main(int argc, char** argv) { - grpc_test_init(argc, argv); - grpc_init(); +void ssl_tsi_test_duplicate_root_certificates() { + char* root_cert = load_file(SSL_TSI_TEST_CREDENTIALS_DIR, "ca.pem"); + char* dup_root_cert = static_cast( + gpr_zalloc(sizeof(char) * (strlen(root_cert) * 2 + 1))); + memcpy(dup_root_cert, root_cert, strlen(root_cert)); + memcpy(dup_root_cert + strlen(root_cert), root_cert, strlen(root_cert)); + tsi_ssl_root_certs_store* root_store = + tsi_ssl_root_certs_store_create(dup_root_cert); + GPR_ASSERT(root_store != nullptr); + // Free memory. + tsi_ssl_root_certs_store_destroy(root_store); + gpr_free(root_cert); + gpr_free(dup_root_cert); +} +int main(int argc, char** argv) { + grpc::testing::TestEnvironment env(argc, argv); + grpc_init(); ssl_tsi_test_do_handshake_tiny_handshake_buffer(); ssl_tsi_test_do_handshake_small_handshake_buffer(); ssl_tsi_test_do_handshake(); @@ -801,6 +814,7 @@ int main(int argc, char** argv) { ssl_tsi_test_do_round_trip_for_all_configs(); ssl_tsi_test_do_round_trip_odd_buffer_size(); ssl_tsi_test_handshaker_factory_internals(); + ssl_tsi_test_duplicate_root_certificates(); grpc_shutdown(); return 0; } diff --git a/test/core/tsi/transport_security_test.cc b/test/core/tsi/transport_security_test.cc index 5c92912f6f6..150e5745a8d 100644 --- a/test/core/tsi/transport_security_test.cc +++ b/test/core/tsi/transport_security_test.cc @@ -381,7 +381,7 @@ static void test_handshaker_invalid_state(void) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); test_peer_matches_name(); test_result_strings(); test_protector_invalid_args(); diff --git a/test/core/util/BUILD b/test/core/util/BUILD index 5492dcfa795..47f814a7ad3 100644 --- a/test/core/util/BUILD +++ b/test/core/util/BUILD @@ -21,24 +21,6 @@ grpc_package( visibility = "public", ) -grpc_cc_library( - name = "gpr_test_util", - srcs = [ - "memory_counters.cc", - "test_config.cc", - ], - hdrs = [ - "memory_counters.h", - "test_config.h", - ], - deps = ["//:gpr"], - data = [ - "lsan_suppressions.txt", - "tsan_suppressions.txt", - "ubsan_suppressions.txt", - ], -) - grpc_cc_library( name = "grpc_debugger_macros", srcs = [ @@ -48,7 +30,6 @@ grpc_cc_library( "debugger_macros.h", ], deps = [ - ":gpr_test_util", "//:grpc_common", ], ) @@ -60,6 +41,7 @@ grpc_cc_library( "fuzzer_util.cc", "grpc_profiler.cc", "histogram.cc", + "memory_counters.cc", "mock_endpoint.cc", "parse_hexstring.cc", "passthru_endpoint.cc", @@ -70,6 +52,7 @@ grpc_cc_library( "slice_splitter.cc", "subprocess_posix.cc", "subprocess_windows.cc", + "test_config.cc", "test_tcp_server.cc", "tracer_util.cc", "trickle_endpoint.cc", @@ -79,22 +62,29 @@ grpc_cc_library( "fuzzer_util.h", "grpc_profiler.h", "histogram.h", + "memory_counters.h", "mock_endpoint.h", "parse_hexstring.h", "passthru_endpoint.h", "port.h", "port_server_client.h", "reconnect_server.h", - "subprocess.h", "slice_splitter.h", + "subprocess.h", + "test_config.h", "test_tcp_server.h", "tracer_util.h", "trickle_endpoint.h", ], + data = [ + "lsan_suppressions.txt", + "tsan_suppressions.txt", + "ubsan_suppressions.txt", + ], language = "C++", deps = [ - ":gpr_test_util", ":grpc_debugger_macros", + "//:gpr", "//:grpc_common", ], ) @@ -140,9 +130,11 @@ grpc_cc_library( "gflags", ], deps = [ - ":gpr_test_util", + ":grpc_test_util", "//:grpc", + "//test/cpp/util:test_config", ], + tags = ["no_windows"], ) grpc_cc_test( @@ -164,3 +156,13 @@ sh_library( name = "run_with_poller_sh", srcs = ["run_with_poller.sh"], ) + +grpc_cc_library( + name = "test_lb_policies", + testonly = 1, + srcs = ["test_lb_policies.cc"], + hdrs = ["test_lb_policies.h"], + deps = [ + "//:grpc", + ], +) diff --git a/test/core/util/cmdline_test.cc b/test/core/util/cmdline_test.cc index 9f5ad88d573..59e1bbff34e 100644 --- a/test/core/util/cmdline_test.cc +++ b/test/core/util/cmdline_test.cc @@ -463,7 +463,7 @@ static void test_badargs4(void) { } int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); test_simple_int(); test_eq_int(); test_2dash_int(); diff --git a/test/core/util/debugger_macros.cc b/test/core/util/debugger_macros.cc index 05fb1461733..fed6ad97285 100644 --- a/test/core/util/debugger_macros.cc +++ b/test/core/util/debugger_macros.cc @@ -36,13 +36,14 @@ grpc_stream* grpc_transport_stream_from_call(grpc_call* call) { for (;;) { grpc_call_element* el = grpc_call_stack_element(cs, cs->count - 1); if (el->filter == &grpc_client_channel_filter) { - grpc_subchannel_call* scc = grpc_client_channel_get_subchannel_call(el); + grpc_core::RefCountedPtr scc = + grpc_client_channel_get_subchannel_call(el); if (scc == nullptr) { fprintf(stderr, "No subchannel-call"); fflush(stderr); return nullptr; } - cs = grpc_subchannel_call_get_call_stack(scc); + cs = scc->GetCallStack(); } else if (el->filter == &grpc_connected_filter) { return grpc_connected_channel_get_stream(el); } else { diff --git a/test/core/util/fuzzer_corpus_test.cc b/test/core/util/fuzzer_corpus_test.cc index ebf19131371..864533c539b 100644 --- a/test/core/util/fuzzer_corpus_test.cc +++ b/test/core/util/fuzzer_corpus_test.cc @@ -29,6 +29,7 @@ #include "src/core/lib/gpr/env.h" #include "src/core/lib/iomgr/load_file.h" #include "test/core/util/test_config.h" +#include "test/cpp/util/test_config.h" extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size); extern bool squelch; @@ -144,9 +145,9 @@ INSTANTIATE_TEST_CASE_P( ::testing::internal::ParamGenerator(new ExampleGenerator)); int main(int argc, char** argv) { - grpc_test_init(argc, argv); - ParseCommandLineFlags(&argc, &argv, true); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); + grpc::testing::InitTest(&argc, &argv, true); return RUN_ALL_TESTS(); } diff --git a/test/core/util/memory_counters.cc b/test/core/util/memory_counters.cc index 4960fe07572..787fb76e48b 100644 --- a/test/core/util/memory_counters.cc +++ b/test/core/util/memory_counters.cc @@ -16,12 +16,18 @@ * */ +#include #include #include +#include #include +#include #include +#include +#include "src/core/lib/gpr/alloc.h" +#include "src/core/lib/surface/init.h" #include "test/core/util/memory_counters.h" static struct grpc_memory_counters g_memory_counters; @@ -42,19 +48,18 @@ static void guard_free(void* vptr); #endif static void* guard_malloc(size_t size) { - size_t* ptr; if (!size) return nullptr; NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_absolute, (gpr_atm)size); NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_relative, (gpr_atm)size); NO_BARRIER_FETCH_ADD(&g_memory_counters.total_allocs_absolute, (gpr_atm)1); NO_BARRIER_FETCH_ADD(&g_memory_counters.total_allocs_relative, (gpr_atm)1); - ptr = static_cast(g_old_allocs.malloc_fn(size + sizeof(size))); - *ptr++ = size; - return ptr; + void* ptr = g_old_allocs.malloc_fn( + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(size)) + size); + *static_cast(ptr) = size; + return static_cast(ptr) + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(size)); } static void* guard_realloc(void* vptr, size_t size) { - size_t* ptr = static_cast(vptr); if (vptr == nullptr) { return guard_malloc(size); } @@ -62,21 +67,25 @@ static void* guard_realloc(void* vptr, size_t size) { guard_free(vptr); return nullptr; } - --ptr; + void* ptr = + static_cast(vptr) - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(size)); NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_absolute, (gpr_atm)size); - NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_relative, -(gpr_atm)*ptr); + NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_relative, + -*static_cast(ptr)); NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_relative, (gpr_atm)size); NO_BARRIER_FETCH_ADD(&g_memory_counters.total_allocs_absolute, (gpr_atm)1); - ptr = static_cast(g_old_allocs.realloc_fn(ptr, size + sizeof(size))); - *ptr++ = size; - return ptr; + ptr = g_old_allocs.realloc_fn( + ptr, GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(size)) + size); + *static_cast(ptr) = size; + return static_cast(ptr) + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(size)); } static void guard_free(void* vptr) { - size_t* ptr = static_cast(vptr); - if (!vptr) return; - --ptr; - NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_relative, -(gpr_atm)*ptr); + if (vptr == nullptr) return; + void* ptr = + static_cast(vptr) - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(size_t)); + NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_relative, + -*static_cast(ptr)); NO_BARRIER_FETCH_ADD(&g_memory_counters.total_allocs_relative, -(gpr_atm)1); g_old_allocs.free_fn(ptr); } @@ -106,3 +115,29 @@ struct grpc_memory_counters grpc_memory_counters_snapshot() { NO_BARRIER_LOAD(&g_memory_counters.total_allocs_absolute); return counters; } + +namespace grpc_core { +namespace testing { + +LeakDetector::LeakDetector(bool enable) : enabled_(enable) { + if (enabled_) { + grpc_memory_counters_init(); + } +} + +LeakDetector::~LeakDetector() { + // Wait for grpc_shutdown() to finish its async work. + grpc_maybe_wait_for_async_shutdown(); + if (enabled_) { + struct grpc_memory_counters counters = grpc_memory_counters_snapshot(); + if (counters.total_size_relative != 0) { + gpr_log(GPR_ERROR, "Leaking %" PRIuPTR " bytes", + static_cast(counters.total_size_relative)); + GPR_ASSERT(0); + } + grpc_memory_counters_destroy(); + } +} + +} // namespace testing +} // namespace grpc_core diff --git a/test/core/util/memory_counters.h b/test/core/util/memory_counters.h index c23a13e5c85..c92a001ff13 100644 --- a/test/core/util/memory_counters.h +++ b/test/core/util/memory_counters.h @@ -32,4 +32,22 @@ void grpc_memory_counters_init(); void grpc_memory_counters_destroy(); struct grpc_memory_counters grpc_memory_counters_snapshot(); +namespace grpc_core { +namespace testing { + +// At destruction time, it will check there is no memory leak. +// The object should be created before grpc_init() is called and destroyed after +// grpc_shutdown() is returned. +class LeakDetector { + public: + explicit LeakDetector(bool enable); + ~LeakDetector(); + + private: + const bool enabled_; +}; + +} // namespace testing +} // namespace grpc_core + #endif diff --git a/test/core/util/mock_endpoint.cc b/test/core/util/mock_endpoint.cc index ef6fd62b516..2f78a7f8a97 100644 --- a/test/core/util/mock_endpoint.cc +++ b/test/core/util/mock_endpoint.cc @@ -41,7 +41,7 @@ typedef struct mock_endpoint { } mock_endpoint; static void me_read(grpc_endpoint* ep, grpc_slice_buffer* slices, - grpc_closure* cb) { + grpc_closure* cb, bool urgent) { mock_endpoint* m = reinterpret_cast(ep); gpr_mu_lock(&m->mu); if (m->read_buffer.count > 0) { @@ -89,6 +89,7 @@ static void me_destroy(grpc_endpoint* ep) { mock_endpoint* m = reinterpret_cast(ep); grpc_slice_buffer_destroy(&m->read_buffer); grpc_resource_user_unref(m->resource_user); + gpr_mu_destroy(&m->mu); gpr_free(m); } @@ -103,18 +104,19 @@ static grpc_resource_user* me_get_resource_user(grpc_endpoint* ep) { static int me_get_fd(grpc_endpoint* ep) { return -1; } -static const grpc_endpoint_vtable vtable = { - me_read, - me_write, - me_add_to_pollset, - me_add_to_pollset_set, - me_delete_from_pollset_set, - me_shutdown, - me_destroy, - me_get_resource_user, - me_get_peer, - me_get_fd, -}; +static bool me_can_track_err(grpc_endpoint* ep) { return false; } + +static const grpc_endpoint_vtable vtable = {me_read, + me_write, + me_add_to_pollset, + me_add_to_pollset_set, + me_delete_from_pollset_set, + me_shutdown, + me_destroy, + me_get_resource_user, + me_get_peer, + me_get_fd, + me_can_track_err}; grpc_endpoint* grpc_mock_endpoint_create(void (*on_write)(grpc_slice slice), grpc_resource_quota* resource_quota) { diff --git a/test/core/util/passthru_endpoint.cc b/test/core/util/passthru_endpoint.cc index 3cc8ad6fe14..2d26902fc44 100644 --- a/test/core/util/passthru_endpoint.cc +++ b/test/core/util/passthru_endpoint.cc @@ -54,7 +54,7 @@ struct passthru_endpoint { }; static void me_read(grpc_endpoint* ep, grpc_slice_buffer* slices, - grpc_closure* cb) { + grpc_closure* cb, bool urgent) { half* m = reinterpret_cast(ep); gpr_mu_lock(&m->parent->mu); if (m->parent->shutdown) { @@ -155,6 +155,8 @@ static char* me_get_peer(grpc_endpoint* ep) { static int me_get_fd(grpc_endpoint* ep) { return -1; } +static bool me_can_track_err(grpc_endpoint* ep) { return false; } + static grpc_resource_user* me_get_resource_user(grpc_endpoint* ep) { half* m = reinterpret_cast(ep); return m->resource_user; @@ -171,6 +173,7 @@ static const grpc_endpoint_vtable vtable = { me_get_resource_user, me_get_peer, me_get_fd, + me_can_track_err, }; static void half_init(half* m, passthru_endpoint* parent, diff --git a/test/core/util/port.cc b/test/core/util/port.cc index 303306de452..fe4caa6faf6 100644 --- a/test/core/util/port.cc +++ b/test/core/util/port.cc @@ -66,7 +66,7 @@ static void free_chosen_ports(void) { for (i = 0; i < num_chosen_ports; i++) { grpc_free_port_using_server(chosen_ports[i]); } - grpc_shutdown(); + grpc_shutdown_blocking(); gpr_free(chosen_ports); } diff --git a/test/core/util/reconnect_server.cc b/test/core/util/reconnect_server.cc index ad7cf42f71f..144ad64f095 100644 --- a/test/core/util/reconnect_server.cc +++ b/test/core/util/reconnect_server.cc @@ -109,7 +109,7 @@ void reconnect_server_start(reconnect_server* server, int port) { } void reconnect_server_poll(reconnect_server* server, int seconds) { - test_tcp_server_poll(&server->tcp_server, seconds); + test_tcp_server_poll(&server->tcp_server, 1000 * seconds); } void reconnect_server_clear_timestamps(reconnect_server* server) { diff --git a/test/core/util/test_config.cc b/test/core/util/test_config.cc index 6a0d444a732..476e424b1eb 100644 --- a/test/core/util/test_config.cc +++ b/test/core/util/test_config.cc @@ -31,6 +31,7 @@ #include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/useful.h" +#include "src/core/lib/surface/init.h" int64_t g_fixture_slowdown_factor = 1; int64_t g_poller_slowdown_factor = 1; @@ -381,13 +382,6 @@ gpr_timespec grpc_timeout_milliseconds_to_deadline(int64_t time_ms) { void grpc_test_init(int argc, char** argv) { install_crash_handler(); - { /* poll-cv poll strategy runs much more slowly than anything else */ - char* s = gpr_getenv("GRPC_POLL_STRATEGY"); - if (s != nullptr && 0 == strcmp(s, "poll-cv")) { - g_poller_slowdown_factor = 5; - } - gpr_free(s); - } gpr_log(GPR_DEBUG, "test slowdown factor: sanitizer=%" PRId64 ", fixture=%" PRId64 ", poller=%" PRId64 ", total=%" PRId64, @@ -397,3 +391,15 @@ void grpc_test_init(int argc, char** argv) { concurrently running test binary */ srand(seed()); } + +namespace grpc { +namespace testing { + +TestEnvironment::TestEnvironment(int argc, char** argv) { + grpc_test_init(argc, argv); +} + +TestEnvironment::~TestEnvironment() { grpc_maybe_wait_for_async_shutdown(); } + +} // namespace testing +} // namespace grpc diff --git a/test/core/util/test_config.h b/test/core/util/test_config.h index 5b3d34799ee..112af3176f9 100644 --- a/test/core/util/test_config.h +++ b/test/core/util/test_config.h @@ -37,6 +37,21 @@ gpr_timespec grpc_timeout_milliseconds_to_deadline(int64_t time_ms); #define GRPC_TEST_PICK_PORT #endif +// Prefer TestEnvironment below. void grpc_test_init(int argc, char** argv); +namespace grpc { +namespace testing { + +// A TestEnvironment object should be alive in the main function of a test. It +// provides test init and shutdown inside. +class TestEnvironment { + public: + TestEnvironment(int argc, char** argv); + ~TestEnvironment(); +}; + +} // namespace testing +} // namespace grpc + #endif /* GRPC_TEST_CORE_UTIL_TEST_CONFIG_H */ diff --git a/test/core/util/test_lb_policies.cc b/test/core/util/test_lb_policies.cc new file mode 100644 index 00000000000..b871f04bc9e --- /dev/null +++ b/test/core/util/test_lb_policies.cc @@ -0,0 +1,235 @@ +/* + * + * 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/test_lb_policies.h" + +#include + +#include "src/core/ext/filters/client_channel/lb_policy.h" +#include "src/core/ext/filters/client_channel/lb_policy_registry.h" +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/channel/channelz.h" +#include "src/core/lib/debug/trace.h" +#include "src/core/lib/gprpp/memory.h" +#include "src/core/lib/gprpp/orphanable.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/error.h" +#include "src/core/lib/iomgr/pollset_set.h" +#include "src/core/lib/json/json.h" +#include "src/core/lib/transport/connectivity_state.h" + +namespace grpc_core { + +TraceFlag grpc_trace_forwarding_lb(false, "forwarding_lb"); + +namespace { + +// +// ForwardingLoadBalancingPolicy +// + +// A minimal forwarding class to avoid implementing a standalone test LB. +class ForwardingLoadBalancingPolicy : public LoadBalancingPolicy { + public: + ForwardingLoadBalancingPolicy( + UniquePtr delegating_helper, Args args, + const std::string& delegate_policy_name, intptr_t initial_refcount = 1) + : LoadBalancingPolicy(std::move(args), initial_refcount) { + Args delegate_args; + delegate_args.combiner = combiner(); + delegate_args.channel_control_helper = std::move(delegating_helper); + delegate_args.args = args.args; + delegate_ = LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( + delegate_policy_name.c_str(), std::move(delegate_args)); + grpc_pollset_set_add_pollset_set(delegate_->interested_parties(), + interested_parties()); + } + + ~ForwardingLoadBalancingPolicy() override = default; + + void UpdateLocked(UpdateArgs args) override { + delegate_->UpdateLocked(std::move(args)); + } + + void ExitIdleLocked() override { delegate_->ExitIdleLocked(); } + + void ResetBackoffLocked() override { delegate_->ResetBackoffLocked(); } + + void FillChildRefsForChannelz( + channelz::ChildRefsList* child_subchannels, + channelz::ChildRefsList* child_channels) override { + delegate_->FillChildRefsForChannelz(child_subchannels, child_channels); + } + + private: + void ShutdownLocked() override { delegate_.reset(); } + + OrphanablePtr delegate_; +}; + +// +// InterceptRecvTrailingMetadataLoadBalancingPolicy +// + +constexpr char kInterceptRecvTrailingMetadataLbPolicyName[] = + "intercept_trailing_metadata_lb"; + +class InterceptRecvTrailingMetadataLoadBalancingPolicy + : public ForwardingLoadBalancingPolicy { + public: + InterceptRecvTrailingMetadataLoadBalancingPolicy( + Args args, InterceptRecvTrailingMetadataCallback cb, void* user_data) + : ForwardingLoadBalancingPolicy( + UniquePtr(New( + RefCountedPtr( + this), + cb, user_data)), + std::move(args), + /*delegate_lb_policy_name=*/"pick_first", + /*initial_refcount=*/2) {} + + ~InterceptRecvTrailingMetadataLoadBalancingPolicy() override = default; + + const char* name() const override { + return kInterceptRecvTrailingMetadataLbPolicyName; + } + + private: + class Picker : public SubchannelPicker { + public: + explicit Picker(UniquePtr delegate_picker, + InterceptRecvTrailingMetadataCallback cb, void* user_data) + : delegate_picker_(std::move(delegate_picker)), + cb_(cb), + user_data_(user_data) {} + + PickResult Pick(PickArgs* pick, grpc_error** error) override { + PickResult result = delegate_picker_->Pick(pick, error); + if (result == PICK_COMPLETE && pick->connected_subchannel != nullptr) { + New(pick, cb_, user_data_); // deletes itself + } + return result; + } + + private: + UniquePtr delegate_picker_; + InterceptRecvTrailingMetadataCallback cb_; + void* user_data_; + }; + + class Helper : public ChannelControlHelper { + public: + Helper( + RefCountedPtr parent, + InterceptRecvTrailingMetadataCallback cb, void* user_data) + : parent_(std::move(parent)), cb_(cb), user_data_(user_data) {} + + Subchannel* CreateSubchannel(const grpc_channel_args& args) override { + return parent_->channel_control_helper()->CreateSubchannel(args); + } + + grpc_channel* CreateChannel(const char* target, + const grpc_channel_args& args) override { + return parent_->channel_control_helper()->CreateChannel(target, args); + } + + void UpdateState(grpc_connectivity_state state, + UniquePtr picker) override { + parent_->channel_control_helper()->UpdateState( + state, UniquePtr( + New(std::move(picker), cb_, user_data_))); + } + + void RequestReresolution() override { + parent_->channel_control_helper()->RequestReresolution(); + } + + private: + RefCountedPtr parent_; + InterceptRecvTrailingMetadataCallback cb_; + void* user_data_; + }; + + class TrailingMetadataHandler { + public: + TrailingMetadataHandler(PickArgs* pick, + InterceptRecvTrailingMetadataCallback cb, + void* user_data) + : cb_(cb), user_data_(user_data) { + GRPC_CLOSURE_INIT(&recv_trailing_metadata_ready_, + RecordRecvTrailingMetadata, this, + grpc_schedule_on_exec_ctx); + pick->recv_trailing_metadata_ready = &recv_trailing_metadata_ready_; + pick->original_recv_trailing_metadata_ready = + &original_recv_trailing_metadata_ready_; + pick->recv_trailing_metadata = &recv_trailing_metadata_; + } + + private: + static void RecordRecvTrailingMetadata(void* arg, grpc_error* err) { + TrailingMetadataHandler* self = + static_cast(arg); + GPR_ASSERT(self->recv_trailing_metadata_ != nullptr); + self->cb_(self->user_data_); + GRPC_CLOSURE_SCHED(self->original_recv_trailing_metadata_ready_, + GRPC_ERROR_REF(err)); + Delete(self); + } + + InterceptRecvTrailingMetadataCallback cb_; + void* user_data_; + grpc_closure recv_trailing_metadata_ready_; + grpc_closure* original_recv_trailing_metadata_ready_ = nullptr; + grpc_metadata_batch* recv_trailing_metadata_ = nullptr; + }; +}; + +class InterceptTrailingFactory : public LoadBalancingPolicyFactory { + public: + explicit InterceptTrailingFactory(InterceptRecvTrailingMetadataCallback cb, + void* user_data) + : cb_(cb), user_data_(user_data) {} + + OrphanablePtr CreateLoadBalancingPolicy( + LoadBalancingPolicy::Args args) const override { + return OrphanablePtr( + New(std::move(args), + cb_, user_data_)); + } + + const char* name() const override { + return kInterceptRecvTrailingMetadataLbPolicyName; + } + + private: + InterceptRecvTrailingMetadataCallback cb_; + void* user_data_; +}; + +} // namespace + +void RegisterInterceptRecvTrailingMetadataLoadBalancingPolicy( + InterceptRecvTrailingMetadataCallback cb, void* user_data) { + LoadBalancingPolicyRegistry::Builder::RegisterLoadBalancingPolicyFactory( + UniquePtr( + New(cb, user_data))); +} + +} // namespace grpc_core diff --git a/src/core/lib/gprpp/mutex_lock.h b/test/core/util/test_lb_policies.h similarity index 57% rename from src/core/lib/gprpp/mutex_lock.h rename to test/core/util/test_lb_policies.h index 54751d5fe46..6d2693a0d59 100644 --- a/src/core/lib/gprpp/mutex_lock.h +++ b/test/core/util/test_lb_policies.h @@ -16,27 +16,19 @@ * */ -#ifndef GRPC_CORE_LIB_GPRPP_MUTEX_LOCK_H -#define GRPC_CORE_LIB_GPRPP_MUTEX_LOCK_H - -#include - -#include +#ifndef GRPC_TEST_CORE_UTIL_TEST_LB_POLICIES_H +#define GRPC_TEST_CORE_UTIL_TEST_LB_POLICIES_H namespace grpc_core { -class MutexLock { - public: - explicit MutexLock(gpr_mu* mu) : mu_(mu) { gpr_mu_lock(mu); } - ~MutexLock() { gpr_mu_unlock(mu_); } +typedef void (*InterceptRecvTrailingMetadataCallback)(void*); - MutexLock(const MutexLock&) = delete; - MutexLock& operator=(const MutexLock&) = delete; - - private: - gpr_mu* const mu_; -}; +// Registers an LB policy called "intercept_trailing_metadata_lb" that +// invokes cb with argument user_data when trailing metadata is received +// for each call. +void RegisterInterceptRecvTrailingMetadataLoadBalancingPolicy( + InterceptRecvTrailingMetadataCallback cb, void* user_data); } // namespace grpc_core -#endif /* GRPC_CORE_LIB_GPRPP_MUTEX_LOCK_H */ +#endif // GRPC_TEST_CORE_UTIL_TEST_LB_POLICIES_H diff --git a/test/core/util/test_tcp_server.cc b/test/core/util/test_tcp_server.cc index 610a9918ce6..80d0634a9b9 100644 --- a/test/core/util/test_tcp_server.cc +++ b/test/core/util/test_tcp_server.cc @@ -77,11 +77,11 @@ void test_tcp_server_start(test_tcp_server* server, int port) { gpr_log(GPR_INFO, "test tcp server listening on 0.0.0.0:%d", port); } -void test_tcp_server_poll(test_tcp_server* server, int seconds) { +void test_tcp_server_poll(test_tcp_server* server, int milliseconds) { grpc_pollset_worker* worker = nullptr; grpc_core::ExecCtx exec_ctx; grpc_millis deadline = grpc_timespec_to_millis_round_up( - grpc_timeout_seconds_to_deadline(seconds)); + grpc_timeout_milliseconds_to_deadline(milliseconds)); gpr_mu_lock(server->mu); GRPC_LOG_IF_ERROR("pollset_work", grpc_pollset_work(server->pollset, &worker, deadline)); @@ -104,7 +104,7 @@ void test_tcp_server_destroy(test_tcp_server* server) { gpr_time_from_seconds(5, GPR_TIMESPAN)); while (!server->shutdown && gpr_time_cmp(gpr_now(GPR_CLOCK_MONOTONIC), shutdown_deadline) < 0) { - test_tcp_server_poll(server, 1); + test_tcp_server_poll(server, 1000); } grpc_pollset_shutdown(server->pollset, GRPC_CLOSURE_CREATE(finish_pollset, server->pollset, diff --git a/test/core/util/test_tcp_server.h b/test/core/util/test_tcp_server.h index 58140388da3..313a27a3334 100644 --- a/test/core/util/test_tcp_server.h +++ b/test/core/util/test_tcp_server.h @@ -35,7 +35,7 @@ typedef struct test_tcp_server { void test_tcp_server_init(test_tcp_server* server, grpc_tcp_server_cb on_connect, void* user_data); void test_tcp_server_start(test_tcp_server* server, int port); -void test_tcp_server_poll(test_tcp_server* server, int seconds); +void test_tcp_server_poll(test_tcp_server* server, int milliseconds); void test_tcp_server_destroy(test_tcp_server* server); #endif /* GRPC_TEST_CORE_UTIL_TEST_TCP_SERVER_H */ diff --git a/test/core/util/trickle_endpoint.cc b/test/core/util/trickle_endpoint.cc index 62ed72a6295..bdac1334f48 100644 --- a/test/core/util/trickle_endpoint.cc +++ b/test/core/util/trickle_endpoint.cc @@ -47,9 +47,9 @@ typedef struct { } trickle_endpoint; static void te_read(grpc_endpoint* ep, grpc_slice_buffer* slices, - grpc_closure* cb) { + grpc_closure* cb, bool urgent) { trickle_endpoint* te = reinterpret_cast(ep); - grpc_endpoint_read(te->wrapped, slices, cb); + grpc_endpoint_read(te->wrapped, slices, cb, urgent); } static void maybe_call_write_cb_locked(trickle_endpoint* te) { @@ -131,6 +131,8 @@ static int te_get_fd(grpc_endpoint* ep) { return grpc_endpoint_get_fd(te->wrapped); } +static bool te_can_track_err(grpc_endpoint* ep) { return false; } + static void te_finish_write(void* arg, grpc_error* error) { trickle_endpoint* te = static_cast(arg); gpr_mu_lock(&te->mu); @@ -148,7 +150,8 @@ static const grpc_endpoint_vtable vtable = {te_read, te_destroy, te_get_resource_user, te_get_peer, - te_get_fd}; + te_get_fd, + te_can_track_err}; grpc_endpoint* grpc_trickle_endpoint_create(grpc_endpoint* wrap, double bytes_per_second) { diff --git a/test/core/util/ubsan_suppressions.txt b/test/core/util/ubsan_suppressions.txt index 63898ea3b1c..06533d9eb62 100644 --- a/test/core/util/ubsan_suppressions.txt +++ b/test/core/util/ubsan_suppressions.txt @@ -1,11 +1,4 @@ -# boringssl stuff -nonnull-attribute:bn_wexpand -nonnull-attribute:CBB_add_bytes -nonnull-attribute:rsa_blinding_get -nonnull-attribute:ssl_copy_key_material -alignment:CRYPTO_cbc128_encrypt -alignment:CRYPTO_gcm128_encrypt -alignment:poly1305_block_copy +# Protobuf stuff nonnull-attribute:google::protobuf::* alignment:google::protobuf::* nonnull-attribute:_tr_stored_block @@ -25,7 +18,7 @@ alignment:absl::little_endian::Store64 alignment:absl::little_endian::Load64 float-divide-by-zero:grpc::testing::postprocess_scenario_result enum:grpc_op_string -nonnull-attribute:grpc_lb_addresses_copy signed-integer-overflow:chrono enum:grpc_http2_error_to_grpc_status -enum:grpc_chttp2_cancel_stream \ No newline at end of file +enum:grpc_chttp2_cancel_stream +enum:api_fuzzer diff --git a/test/cpp/client/BUILD b/test/cpp/client/BUILD index c03ea92d34a..1d90e361913 100644 --- a/test/cpp/client/BUILD +++ b/test/cpp/client/BUILD @@ -28,7 +28,7 @@ grpc_cc_test( "//:gpr", "//:grpc", "//:grpc++", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -44,7 +44,6 @@ grpc_cc_test( "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", "//src/proto/grpc/testing/duplicate:echo_duplicate_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/end2end:test_service_impl", "//test/cpp/util:test_util", diff --git a/test/cpp/client/client_channel_stress_test.cc b/test/cpp/client/client_channel_stress_test.cc index 976eeb6aeab..7b4d47276ef 100644 --- a/test/cpp/client/client_channel_stress_test.cc +++ b/test/cpp/client/client_channel_stress_test.cc @@ -31,10 +31,13 @@ #include #include #include +#include #include #include +#include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h" +#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/gprpp/thd.h" #include "src/core/lib/iomgr/sockaddr.h" @@ -166,24 +169,24 @@ class ClientChannelStressTest { explicit ServerThread(const grpc::string& type, const grpc::string& server_host, T* service) : type_(type), service_(service) { - std::mutex mu; + grpc::internal::Mutex mu; // We need to acquire the lock here in order to prevent the notify_one // by ServerThread::Start from firing before the wait below is hit. - std::unique_lock lock(mu); + grpc::internal::MutexLock lock(&mu); port_ = grpc_pick_unused_port_or_die(); gpr_log(GPR_INFO, "starting %s server on port %d", type_.c_str(), port_); - std::condition_variable cond; + grpc::internal::CondVar cond; thread_.reset(new std::thread( std::bind(&ServerThread::Start, this, server_host, &mu, &cond))); - cond.wait(lock); + cond.Wait(&mu); gpr_log(GPR_INFO, "%s server startup complete", type_.c_str()); } - void Start(const grpc::string& server_host, std::mutex* mu, - std::condition_variable* cond) { + void Start(const grpc::string& server_host, grpc::internal::Mutex* mu, + grpc::internal::CondVar* cond) { // We need to acquire the lock here in order to prevent the notify_one // below from firing before its corresponding wait is executed. - std::lock_guard lock(*mu); + grpc::internal::MutexLock lock(mu); std::ostringstream server_address; server_address << server_host << ":" << port_; ServerBuilder builder; @@ -191,7 +194,7 @@ class ClientChannelStressTest { InsecureServerCredentials()); builder.RegisterService(service_); server_ = builder.BuildAndStart(); - cond->notify_one(); + cond->Signal(); } void Shutdown() { @@ -216,23 +219,29 @@ class ClientChannelStressTest { void SetNextResolution(const std::vector& address_data) { grpc_core::ExecCtx exec_ctx; - grpc_lb_addresses* addresses = - grpc_lb_addresses_create(address_data.size(), nullptr); - for (size_t i = 0; i < address_data.size(); ++i) { + grpc_core::Resolver::Result result; + for (const auto& addr : address_data) { char* lb_uri_str; - gpr_asprintf(&lb_uri_str, "ipv4:127.0.0.1:%d", address_data[i].port); + gpr_asprintf(&lb_uri_str, "ipv4:127.0.0.1:%d", addr.port); grpc_uri* lb_uri = grpc_uri_parse(lb_uri_str, true); GPR_ASSERT(lb_uri != nullptr); - grpc_lb_addresses_set_address_from_uri( - addresses, i, lb_uri, address_data[i].is_balancer, - address_data[i].balancer_name.c_str(), nullptr); + grpc_resolved_address address; + GPR_ASSERT(grpc_parse_uri(lb_uri, &address)); + std::vector args_to_add; + if (addr.is_balancer) { + args_to_add.emplace_back(grpc_channel_arg_integer_create( + const_cast(GRPC_ARG_ADDRESS_IS_BALANCER), 1)); + args_to_add.emplace_back(grpc_channel_arg_string_create( + const_cast(GRPC_ARG_ADDRESS_BALANCER_NAME), + const_cast(addr.balancer_name.c_str()))); + } + grpc_channel_args* args = grpc_channel_args_copy_and_add( + nullptr, args_to_add.data(), args_to_add.size()); + result.addresses.emplace_back(address.addr, address.len, args); grpc_uri_destroy(lb_uri); gpr_free(lb_uri_str); } - grpc_arg fake_addresses = grpc_lb_addresses_create_channel_arg(addresses); - grpc_channel_args fake_result = {1, &fake_addresses}; - response_generator_->SetResponse(&fake_result); - grpc_lb_addresses_destroy(addresses); + response_generator_->SetResponse(std::move(result)); } void KeepSendingRequests() { @@ -259,8 +268,8 @@ class ClientChannelStressTest { response_generator_.get()); std::ostringstream uri; uri << "fake:///servername_not_used"; - channel_ = - CreateCustomChannel(uri.str(), InsecureChannelCredentials(), args); + channel_ = ::grpc::CreateCustomChannel(uri.str(), + InsecureChannelCredentials(), args); stub_ = grpc::testing::EchoTestService::NewStub(channel_); } @@ -321,7 +330,7 @@ class ClientChannelStressTest { int main(int argc, char** argv) { grpc_init(); - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); grpc::testing::ClientChannelStressTest test; test.Run(); grpc_shutdown(); diff --git a/test/cpp/codegen/BUILD b/test/cpp/codegen/BUILD index 12712a3e6c8..90af67bd858 100644 --- a/test/cpp/codegen/BUILD +++ b/test/cpp/codegen/BUILD @@ -21,76 +21,77 @@ grpc_package(name = "test/cpp/codegen") grpc_cc_test( name = "codegen_test_full", srcs = ["codegen_test_full.cc"], - deps = [ - "//:grpc++", - "//test/core/util:gpr_test_util", - ], external_deps = [ "gtest", ], + deps = [ + "//:grpc++", + "//test/core/util:grpc_test_util", + ], ) grpc_cc_test( name = "codegen_test_minimal", srcs = ["codegen_test_minimal.cc"], - deps = [ - "//:grpc++", - "//test/core/util:gpr_test_util", - ], external_deps = [ "gtest", ], + deps = [ + "//:grpc++", + "//test/core/util:grpc_test_util", + ], ) grpc_cc_test( name = "proto_utils_test", srcs = ["proto_utils_test.cc"], - deps = [ - "//:grpc++", - "//test/core/util:gpr_test_util", - ], external_deps = [ "gtest", "protobuf", ], + deps = [ + "//:grpc++", + "//test/core/util:grpc_test_util", + ], ) grpc_cc_binary( name = "golden_file_test", testonly = True, srcs = ["golden_file_test.cc"], - deps = [ - "//:grpc++", - "//test/core/util:gpr_test_util", - ], external_deps = [ "gtest", "gflags", ], + deps = [ + "//:grpc++", + "//test/core/util:grpc_test_util", + "//test/cpp/util:test_config", + ], ) genrule( name = "copy_compiler_test_grpc_pb_h", srcs = ["//src/proto/grpc/testing:_compiler_test_proto_grpc_codegen"], - cmd = "cat $(GENDIR)/src/proto/grpc/testing/compiler_test.grpc.pb.h > $@", outs = ["compiler_test.grpc.pb.h"], + cmd = "cat $(GENDIR)/src/proto/grpc/testing/compiler_test.grpc.pb.h > $@", ) genrule( name = "copy_compiler_test_mock_grpc_pb_h", srcs = ["//src/proto/grpc/testing:_compiler_test_proto_grpc_codegen"], - cmd = "cat $(GENDIR)/src/proto/grpc/testing/compiler_test_mock.grpc.pb.h > $@", outs = ["compiler_test_mock.grpc.pb.h"], + cmd = "cat $(GENDIR)/src/proto/grpc/testing/compiler_test_mock.grpc.pb.h > $@", ) grpc_sh_test( name = "run_golden_file_test", srcs = ["run_golden_file_test.sh"], data = [ - ":golden_file_test", - ":compiler_test_golden", - ":compiler_test_mock_golden", ":compiler_test.grpc.pb.h", + ":compiler_test_golden", ":compiler_test_mock.grpc.pb.h", + ":compiler_test_mock_golden", + ":golden_file_test", ], ) diff --git a/test/cpp/codegen/compiler_test_golden b/test/cpp/codegen/compiler_test_golden index fdc67969d96..e571a95bb3e 100644 --- a/test/cpp/codegen/compiler_test_golden +++ b/test/cpp/codegen/compiler_test_golden @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -39,10 +40,20 @@ #include #include -namespace grpc { -class CompletionQueue; +namespace grpc_impl { class Channel; +class CompletionQueue; class ServerCompletionQueue; +} // namespace grpc_impl + +namespace grpc { +namespace experimental { +template +class MessageAllocator; +} // namespace experimental +} // namespace grpc_impl + +namespace grpc { class ServerContext; } // namespace grpc @@ -112,15 +123,21 @@ class ServiceA final { virtual ~experimental_async_interface() {} // MethodA1 leading comment 1 virtual void MethodA1(::grpc::ClientContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response, std::function) = 0; + virtual void MethodA1(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::grpc::testing::Response* response, std::function) = 0; + virtual void MethodA1(::grpc::ClientContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response, ::grpc::experimental::ClientUnaryReactor* reactor) = 0; + virtual void MethodA1(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::grpc::testing::Response* response, ::grpc::experimental::ClientUnaryReactor* reactor) = 0; // MethodA1 trailing comment 1 // MethodA2 detached leading comment 1 // // Method A2 leading comment 1 // Method A2 leading comment 2 + virtual void MethodA2(::grpc::ClientContext* context, ::grpc::testing::Response* response, ::grpc::experimental::ClientWriteReactor< ::grpc::testing::Request>* reactor) = 0; // MethodA2 trailing comment 1 // Method A3 leading comment 1 + virtual void MethodA3(::grpc::ClientContext* context, ::grpc::testing::Request* request, ::grpc::experimental::ClientReadReactor< ::grpc::testing::Response>* reactor) = 0; // Method A3 trailing comment 1 // Method A4 leading comment 1 + virtual void MethodA4(::grpc::ClientContext* context, ::grpc::experimental::ClientBidiReactor< ::grpc::testing::Request,::grpc::testing::Response>* reactor) = 0; // Method A4 trailing comment 1 }; virtual class experimental_async_interface* experimental_async() { return nullptr; } @@ -178,6 +195,12 @@ class ServiceA final { public StubInterface::experimental_async_interface { public: void MethodA1(::grpc::ClientContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response, std::function) override; + void MethodA1(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::grpc::testing::Response* response, std::function) override; + void MethodA1(::grpc::ClientContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response, ::grpc::experimental::ClientUnaryReactor* reactor) override; + void MethodA1(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::grpc::testing::Response* response, ::grpc::experimental::ClientUnaryReactor* reactor) override; + void MethodA2(::grpc::ClientContext* context, ::grpc::testing::Response* response, ::grpc::experimental::ClientWriteReactor< ::grpc::testing::Request>* reactor) override; + void MethodA3(::grpc::ClientContext* context, ::grpc::testing::Request* request, ::grpc::experimental::ClientReadReactor< ::grpc::testing::Response>* reactor) override; + void MethodA4(::grpc::ClientContext* context, ::grpc::experimental::ClientBidiReactor< ::grpc::testing::Request,::grpc::testing::Response>* reactor) override; private: friend class Stub; explicit experimental_async(Stub* stub): stub_(stub) { } @@ -315,13 +338,19 @@ class ServiceA final { public: ExperimentalWithCallbackMethod_MethodA1() { ::grpc::Service::experimental().MarkMethodCallback(0, - new ::grpc::internal::CallbackUnaryHandler< ExperimentalWithCallbackMethod_MethodA1, ::grpc::testing::Request, ::grpc::testing::Response>( + new ::grpc::internal::CallbackUnaryHandler< ::grpc::testing::Request, ::grpc::testing::Response>( [this](::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response, ::grpc::experimental::ServerCallbackRpcController* controller) { - this->MethodA1(context, request, response, controller); - }, this)); + return this->MethodA1(context, request, response, controller); + })); + } + void SetMessageAllocatorFor_MethodA1( + ::grpc::experimental::MessageAllocator< ::grpc::testing::Request, ::grpc::testing::Response>* allocator) { + static_cast<::grpc::internal::CallbackUnaryHandler< ::grpc::testing::Request, ::grpc::testing::Response>*>( + ::grpc::Service::experimental().GetHandler(0)) + ->SetMessageAllocator(allocator); } ~ExperimentalWithCallbackMethod_MethodA1() override { BaseClassMustBeDerivedFromService(this); @@ -339,6 +368,9 @@ class ServiceA final { void BaseClassMustBeDerivedFromService(const Service *service) {} public: ExperimentalWithCallbackMethod_MethodA2() { + ::grpc::Service::experimental().MarkMethodCallback(1, + new ::grpc::internal::CallbackClientStreamingHandler< ::grpc::testing::Request, ::grpc::testing::Response>( + [this] { return this->MethodA2(); })); } ~ExperimentalWithCallbackMethod_MethodA2() override { BaseClassMustBeDerivedFromService(this); @@ -348,6 +380,9 @@ class ServiceA final { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } + virtual ::grpc::experimental::ServerReadReactor< ::grpc::testing::Request, ::grpc::testing::Response>* MethodA2() { + return new ::grpc::internal::UnimplementedReadReactor< + ::grpc::testing::Request, ::grpc::testing::Response>;} }; template class ExperimentalWithCallbackMethod_MethodA3 : public BaseClass { @@ -355,6 +390,9 @@ class ServiceA final { void BaseClassMustBeDerivedFromService(const Service *service) {} public: ExperimentalWithCallbackMethod_MethodA3() { + ::grpc::Service::experimental().MarkMethodCallback(2, + new ::grpc::internal::CallbackServerStreamingHandler< ::grpc::testing::Request, ::grpc::testing::Response>( + [this] { return this->MethodA3(); })); } ~ExperimentalWithCallbackMethod_MethodA3() override { BaseClassMustBeDerivedFromService(this); @@ -364,6 +402,9 @@ class ServiceA final { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } + virtual ::grpc::experimental::ServerWriteReactor< ::grpc::testing::Request, ::grpc::testing::Response>* MethodA3() { + return new ::grpc::internal::UnimplementedWriteReactor< + ::grpc::testing::Request, ::grpc::testing::Response>;} }; template class ExperimentalWithCallbackMethod_MethodA4 : public BaseClass { @@ -371,6 +412,9 @@ class ServiceA final { void BaseClassMustBeDerivedFromService(const Service *service) {} public: ExperimentalWithCallbackMethod_MethodA4() { + ::grpc::Service::experimental().MarkMethodCallback(3, + new ::grpc::internal::CallbackBidiHandler< ::grpc::testing::Request, ::grpc::testing::Response>( + [this] { return this->MethodA4(); })); } ~ExperimentalWithCallbackMethod_MethodA4() override { BaseClassMustBeDerivedFromService(this); @@ -380,6 +424,9 @@ class ServiceA final { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } + virtual ::grpc::experimental::ServerBidiReactor< ::grpc::testing::Request, ::grpc::testing::Response>* MethodA4() { + return new ::grpc::internal::UnimplementedBidiReactor< + ::grpc::testing::Request, ::grpc::testing::Response>;} }; typedef ExperimentalWithCallbackMethod_MethodA1 > > > ExperimentalCallbackService; template @@ -537,13 +584,13 @@ class ServiceA final { public: ExperimentalWithRawCallbackMethod_MethodA1() { ::grpc::Service::experimental().MarkMethodRawCallback(0, - new ::grpc::internal::CallbackUnaryHandler< ExperimentalWithRawCallbackMethod_MethodA1, ::grpc::ByteBuffer, ::grpc::ByteBuffer>( + new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( [this](::grpc::ServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response, ::grpc::experimental::ServerCallbackRpcController* controller) { this->MethodA1(context, request, response, controller); - }, this)); + })); } ~ExperimentalWithRawCallbackMethod_MethodA1() override { BaseClassMustBeDerivedFromService(this); @@ -561,6 +608,9 @@ class ServiceA final { void BaseClassMustBeDerivedFromService(const Service *service) {} public: ExperimentalWithRawCallbackMethod_MethodA2() { + ::grpc::Service::experimental().MarkMethodRawCallback(1, + new ::grpc::internal::CallbackClientStreamingHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( + [this] { return this->MethodA2(); })); } ~ExperimentalWithRawCallbackMethod_MethodA2() override { BaseClassMustBeDerivedFromService(this); @@ -570,6 +620,9 @@ class ServiceA final { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } + virtual ::grpc::experimental::ServerReadReactor< ::grpc::ByteBuffer, ::grpc::ByteBuffer>* MethodA2() { + return new ::grpc::internal::UnimplementedReadReactor< + ::grpc::ByteBuffer, ::grpc::ByteBuffer>;} }; template class ExperimentalWithRawCallbackMethod_MethodA3 : public BaseClass { @@ -577,6 +630,9 @@ class ServiceA final { void BaseClassMustBeDerivedFromService(const Service *service) {} public: ExperimentalWithRawCallbackMethod_MethodA3() { + ::grpc::Service::experimental().MarkMethodRawCallback(2, + new ::grpc::internal::CallbackServerStreamingHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( + [this] { return this->MethodA3(); })); } ~ExperimentalWithRawCallbackMethod_MethodA3() override { BaseClassMustBeDerivedFromService(this); @@ -586,6 +642,9 @@ class ServiceA final { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } + virtual ::grpc::experimental::ServerWriteReactor< ::grpc::ByteBuffer, ::grpc::ByteBuffer>* MethodA3() { + return new ::grpc::internal::UnimplementedWriteReactor< + ::grpc::ByteBuffer, ::grpc::ByteBuffer>;} }; template class ExperimentalWithRawCallbackMethod_MethodA4 : public BaseClass { @@ -593,6 +652,9 @@ class ServiceA final { void BaseClassMustBeDerivedFromService(const Service *service) {} public: ExperimentalWithRawCallbackMethod_MethodA4() { + ::grpc::Service::experimental().MarkMethodRawCallback(3, + new ::grpc::internal::CallbackBidiHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( + [this] { return this->MethodA4(); })); } ~ExperimentalWithRawCallbackMethod_MethodA4() override { BaseClassMustBeDerivedFromService(this); @@ -602,6 +664,9 @@ class ServiceA final { abort(); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } + virtual ::grpc::experimental::ServerBidiReactor< ::grpc::ByteBuffer, ::grpc::ByteBuffer>* MethodA4() { + return new ::grpc::internal::UnimplementedBidiReactor< + ::grpc::ByteBuffer, ::grpc::ByteBuffer>;} }; template class WithStreamedUnaryMethod_MethodA1 : public BaseClass { @@ -671,6 +736,9 @@ class ServiceB final { virtual ~experimental_async_interface() {} // MethodB1 leading comment 1 virtual void MethodB1(::grpc::ClientContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response, std::function) = 0; + virtual void MethodB1(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::grpc::testing::Response* response, std::function) = 0; + virtual void MethodB1(::grpc::ClientContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response, ::grpc::experimental::ClientUnaryReactor* reactor) = 0; + virtual void MethodB1(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::grpc::testing::Response* response, ::grpc::experimental::ClientUnaryReactor* reactor) = 0; // MethodB1 trailing comment 1 }; virtual class experimental_async_interface* experimental_async() { return nullptr; } @@ -692,6 +760,9 @@ class ServiceB final { public StubInterface::experimental_async_interface { public: void MethodB1(::grpc::ClientContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response, std::function) override; + void MethodB1(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::grpc::testing::Response* response, std::function) override; + void MethodB1(::grpc::ClientContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response, ::grpc::experimental::ClientUnaryReactor* reactor) override; + void MethodB1(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::grpc::testing::Response* response, ::grpc::experimental::ClientUnaryReactor* reactor) override; private: friend class Stub; explicit experimental_async(Stub* stub): stub_(stub) { } @@ -745,13 +816,19 @@ class ServiceB final { public: ExperimentalWithCallbackMethod_MethodB1() { ::grpc::Service::experimental().MarkMethodCallback(0, - new ::grpc::internal::CallbackUnaryHandler< ExperimentalWithCallbackMethod_MethodB1, ::grpc::testing::Request, ::grpc::testing::Response>( + new ::grpc::internal::CallbackUnaryHandler< ::grpc::testing::Request, ::grpc::testing::Response>( [this](::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response, ::grpc::experimental::ServerCallbackRpcController* controller) { - this->MethodB1(context, request, response, controller); - }, this)); + return this->MethodB1(context, request, response, controller); + })); + } + void SetMessageAllocatorFor_MethodB1( + ::grpc::experimental::MessageAllocator< ::grpc::testing::Request, ::grpc::testing::Response>* allocator) { + static_cast<::grpc::internal::CallbackUnaryHandler< ::grpc::testing::Request, ::grpc::testing::Response>*>( + ::grpc::Service::experimental().GetHandler(0)) + ->SetMessageAllocator(allocator); } ~ExperimentalWithCallbackMethod_MethodB1() override { BaseClassMustBeDerivedFromService(this); @@ -808,13 +885,13 @@ class ServiceB final { public: ExperimentalWithRawCallbackMethod_MethodB1() { ::grpc::Service::experimental().MarkMethodRawCallback(0, - new ::grpc::internal::CallbackUnaryHandler< ExperimentalWithRawCallbackMethod_MethodB1, ::grpc::ByteBuffer, ::grpc::ByteBuffer>( + new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( [this](::grpc::ServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response, ::grpc::experimental::ServerCallbackRpcController* controller) { this->MethodB1(context, request, response, controller); - }, this)); + })); } ~ExperimentalWithRawCallbackMethod_MethodB1() override { BaseClassMustBeDerivedFromService(this); diff --git a/test/cpp/codegen/golden_file_test.cc b/test/cpp/codegen/golden_file_test.cc index bfd36494941..8951060b94e 100644 --- a/test/cpp/codegen/golden_file_test.cc +++ b/test/cpp/codegen/golden_file_test.cc @@ -22,6 +22,8 @@ #include #include +#include "test/cpp/util/test_config.h" + // In some distros, gflags is in the namespace google, and in some others, // in gflags. This hack is enabling us to find both. namespace google {} @@ -31,7 +33,7 @@ using namespace gflags; DEFINE_string( generated_file_path, "", - "path to the directory containing generated files compiler_test.grpc.pb.h" + "path to the directory containing generated files compiler_test.grpc.pb.h " "and compiler_test_mock.grpc.pb.h"); const char kGoldenFilePath[] = "test/cpp/codegen/compiler_test_golden"; @@ -67,7 +69,7 @@ TEST(GoldenMockFileTest, TestGeneratedMockFile) { int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); - ParseCommandLineFlags(&argc, &argv, true); + grpc::testing::InitTest(&argc, &argv, true); if (FLAGS_generated_file_path.empty()) { FLAGS_generated_file_path = "gens/src/proto/grpc/testing/"; } diff --git a/test/cpp/common/BUILD b/test/cpp/common/BUILD index 2cf3ad669fa..b67c1995ff7 100644 --- a/test/cpp/common/BUILD +++ b/test/cpp/common/BUILD @@ -21,61 +21,62 @@ grpc_package(name = "test/cpp/common") grpc_cc_test( name = "alarm_test", srcs = ["alarm_test.cc"], - deps = [ - "//:grpc++_unsecure", - "//test/core/util:gpr_test_util", - ], external_deps = [ "gtest", ], + deps = [ + "//:grpc++_unsecure", + "//test/core/util:grpc_test_util_unsecure", + ], + tags = ["no_windows"], ) grpc_cc_test( name = "auth_property_iterator_test", srcs = ["auth_property_iterator_test.cc"], - deps = [ - "//:grpc++", - "//test/core/util:gpr_test_util", - "//test/cpp/util:test_util", - ], external_deps = [ "gtest", ], + deps = [ + "//:grpc++", + "//test/core/util:grpc_test_util", + "//test/cpp/util:test_util", + ], ) grpc_cc_test( name = "channel_arguments_test", srcs = ["channel_arguments_test.cc"], - deps = [ - "//:grpc++", - "//test/core/util:gpr_test_util", - ], external_deps = [ "gtest", ], + deps = [ + "//:grpc++", + "//test/core/util:grpc_test_util", + ], ) grpc_cc_test( name = "channel_filter_test", srcs = ["channel_filter_test.cc"], - deps = [ - "//:grpc++", - "//test/core/util:gpr_test_util", - ], external_deps = [ "gtest", ], + deps = [ + "//:grpc++", + "//test/core/util:grpc_test_util", + ], ) grpc_cc_test( name = "secure_auth_context_test", srcs = ["secure_auth_context_test.cc"], - deps = [ - "//:grpc++", - "//test/core/util:gpr_test_util", - "//test/cpp/util:test_util", - ], external_deps = [ "gtest", ], + deps = [ + "//:grpc++", + "//test/core/util:grpc_test_util", + "//test/cpp/util:test_util", + ], ) diff --git a/test/cpp/common/alarm_test.cc b/test/cpp/common/alarm_test.cc index e909d03658c..4d410a5d460 100644 --- a/test/cpp/common/alarm_test.cc +++ b/test/cpp/common/alarm_test.cc @@ -47,6 +47,44 @@ TEST(AlarmTest, RegularExpiry) { EXPECT_EQ(junk, output_tag); } +TEST(AlarmTest, RegularExpiryMultiSet) { + CompletionQueue cq; + void* junk = reinterpret_cast(1618033); + Alarm alarm; + + for (int i = 0; i < 3; i++) { + alarm.Set(&cq, grpc_timeout_seconds_to_deadline(1), junk); + + void* output_tag; + bool ok; + const CompletionQueue::NextStatus status = + 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); + } +} + +TEST(AlarmTest, RegularExpiryMultiSetMultiCQ) { + void* junk = reinterpret_cast(1618033); + Alarm alarm; + + for (int i = 0; i < 3; i++) { + CompletionQueue cq; + alarm.Set(&cq, grpc_timeout_seconds_to_deadline(1), junk); + + void* output_tag; + bool ok; + const CompletionQueue::NextStatus status = + 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); + } +} + struct Completion { bool completed = false; std::mutex mu; @@ -313,7 +351,7 @@ TEST(AlarmTest, UnsetDestruction) { } // namespace grpc int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/cpp/common/auth_property_iterator_test.cc b/test/cpp/common/auth_property_iterator_test.cc index 9634555e4b5..5a2844d518a 100644 --- a/test/cpp/common/auth_property_iterator_test.cc +++ b/test/cpp/common/auth_property_iterator_test.cc @@ -40,15 +40,14 @@ class TestAuthPropertyIterator : public AuthPropertyIterator { class AuthPropertyIteratorTest : public ::testing::Test { protected: void SetUp() override { - ctx_ = grpc_auth_context_create(nullptr); - grpc_auth_context_add_cstring_property(ctx_, "name", "chapi"); - grpc_auth_context_add_cstring_property(ctx_, "name", "chapo"); - grpc_auth_context_add_cstring_property(ctx_, "foo", "bar"); - EXPECT_EQ(1, - grpc_auth_context_set_peer_identity_property_name(ctx_, "name")); + ctx_ = grpc_core::MakeRefCounted(nullptr); + grpc_auth_context_add_cstring_property(ctx_.get(), "name", "chapi"); + grpc_auth_context_add_cstring_property(ctx_.get(), "name", "chapo"); + grpc_auth_context_add_cstring_property(ctx_.get(), "foo", "bar"); + EXPECT_EQ(1, grpc_auth_context_set_peer_identity_property_name(ctx_.get(), + "name")); } - void TearDown() override { grpc_auth_context_release(ctx_); } - grpc_auth_context* ctx_; + grpc_core::RefCountedPtr ctx_; }; TEST_F(AuthPropertyIteratorTest, DefaultCtor) { @@ -59,7 +58,7 @@ TEST_F(AuthPropertyIteratorTest, DefaultCtor) { TEST_F(AuthPropertyIteratorTest, GeneralTest) { grpc_auth_property_iterator c_iter = - grpc_auth_context_property_iterator(ctx_); + grpc_auth_context_property_iterator(ctx_.get()); const grpc_auth_property* property = grpc_auth_property_iterator_next(&c_iter); TestAuthPropertyIterator iter(property, &c_iter); diff --git a/test/cpp/common/channel_arguments_test.cc b/test/cpp/common/channel_arguments_test.cc index 183d2afa783..12fd9784f47 100644 --- a/test/cpp/common/channel_arguments_test.cc +++ b/test/cpp/common/channel_arguments_test.cc @@ -209,6 +209,9 @@ TEST_F(ChannelArgumentsTest, SetSocketMutator) { channel_args_.SetSocketMutator(mutator0); EXPECT_TRUE(HasArg(arg0)); + // Exercise the copy constructor because we ran some sanity checks in it. + grpc::ChannelArguments new_args{channel_args_}; + channel_args_.SetSocketMutator(mutator1); EXPECT_TRUE(HasArg(arg1)); // arg0 is replaced by arg1 diff --git a/test/cpp/common/secure_auth_context_test.cc b/test/cpp/common/secure_auth_context_test.cc index 6461f497433..03b3a9fdd8e 100644 --- a/test/cpp/common/secure_auth_context_test.cc +++ b/test/cpp/common/secure_auth_context_test.cc @@ -33,7 +33,7 @@ class SecureAuthContextTest : public ::testing::Test {}; // Created with nullptr TEST_F(SecureAuthContextTest, EmptyContext) { - SecureAuthContext context(nullptr, true); + SecureAuthContext context(nullptr); EXPECT_TRUE(context.GetPeerIdentity().empty()); EXPECT_TRUE(context.GetPeerIdentityPropertyName().empty()); EXPECT_TRUE(context.FindPropertyValues("").empty()); @@ -42,8 +42,10 @@ TEST_F(SecureAuthContextTest, EmptyContext) { } TEST_F(SecureAuthContextTest, Properties) { - grpc_auth_context* ctx = grpc_auth_context_create(nullptr); - SecureAuthContext context(ctx, true); + grpc_core::RefCountedPtr ctx = + grpc_core::MakeRefCounted(nullptr); + SecureAuthContext context(ctx.get()); + ctx.reset(); context.AddProperty("name", "chapi"); context.AddProperty("name", "chapo"); context.AddProperty("foo", "bar"); @@ -60,8 +62,10 @@ TEST_F(SecureAuthContextTest, Properties) { } TEST_F(SecureAuthContextTest, Iterators) { - grpc_auth_context* ctx = grpc_auth_context_create(nullptr); - SecureAuthContext context(ctx, true); + grpc_core::RefCountedPtr ctx = + grpc_core::MakeRefCounted(nullptr); + SecureAuthContext context(ctx.get()); + ctx.reset(); context.AddProperty("name", "chapi"); context.AddProperty("name", "chapo"); context.AddProperty("foo", "bar"); diff --git a/test/cpp/end2end/BUILD b/test/cpp/end2end/BUILD index 4e3d841db01..519a33fd8a4 100644 --- a/test/cpp/end2end/BUILD +++ b/test/cpp/end2end/BUILD @@ -35,6 +35,18 @@ grpc_cc_library( ], ) +grpc_cc_library( + name = "test_health_check_service_impl", + testonly = True, + srcs = ["test_health_check_service_impl.cc"], + hdrs = ["test_health_check_service_impl.h"], + deps = [ + "//:grpc", + "//:grpc++", + "//src/proto/grpc/health/v1:health_proto", + ], +) + grpc_cc_library( name = "interceptors_util", testonly = True, @@ -63,12 +75,33 @@ grpc_cc_test( "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", "//src/proto/grpc/testing/duplicate:echo_duplicate_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], ) +grpc_cc_test( + name = "time_change_test", + srcs = ["time_change_test.cc"], + data = [ + ":client_crash_test_server", + ], + external_deps = [ + "gtest", + ], + deps = [ + ":test_service_impl", + "//:gpr", + "//:grpc", + "//:grpc++", + "//src/proto/grpc/testing:echo_messages_proto", + "//src/proto/grpc/testing:echo_proto", + "//test/core/util:grpc_test_util", + "//test/cpp/util:test_util", + ], + tags = ["no_windows"], +) + grpc_cc_test( name = "client_crash_test", srcs = ["client_crash_test.cc"], @@ -85,7 +118,6 @@ grpc_cc_test( "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", "//src/proto/grpc/testing/duplicate:echo_duplicate_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -100,14 +132,15 @@ grpc_cc_binary( "gtest", ], deps = [ + ":test_service_impl", "//:gpr", "//:grpc", "//:grpc++", "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", "//src/proto/grpc/testing/duplicate:echo_duplicate_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", + "//test/cpp/util:test_config", "//test/cpp/util:test_util", ], ) @@ -119,13 +152,14 @@ grpc_cc_test( "gtest", ], deps = [ + ":interceptors_util", ":test_service_impl", "//:gpr", "//:grpc", "//:grpc++", "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", - "//test/core/util:gpr_test_util", + "//src/proto/grpc/testing:simple_messages_proto", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -145,7 +179,6 @@ grpc_cc_test( "//:grpc++", "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -167,7 +200,6 @@ grpc_cc_library( "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", "//src/proto/grpc/testing/duplicate:echo_duplicate_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -188,7 +220,6 @@ grpc_cc_test( "//src/proto/grpc/channelz:channelz_proto", "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -206,7 +237,6 @@ grpc_cc_test( "//:grpc++", "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -214,8 +244,12 @@ grpc_cc_test( grpc_cc_test( name = "end2end_test", + size = "large", deps = [ ":end2end_test_lib", + # DO NOT REMOVE THE grpc++ dependence below since the internal build + # system uses it to specialize targets + "//:grpc++", ], ) @@ -231,7 +265,6 @@ grpc_cc_test( "//:grpc++", "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -250,7 +283,6 @@ grpc_cc_test( "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", "//src/proto/grpc/testing/duplicate:echo_duplicate_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -269,7 +301,6 @@ grpc_cc_test( "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", "//src/proto/grpc/testing/duplicate:echo_duplicate_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -282,6 +313,7 @@ grpc_cc_test( "gtest", ], deps = [ + ":test_health_check_service_impl", ":test_service_impl", "//:gpr", "//:grpc", @@ -290,7 +322,6 @@ grpc_cc_test( "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", "//src/proto/grpc/testing/duplicate:echo_duplicate_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -310,7 +341,6 @@ grpc_cc_test( "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", "//src/proto/grpc/testing/duplicate:echo_duplicate_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -330,7 +360,6 @@ grpc_cc_test( "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", "//src/proto/grpc/testing/duplicate:echo_duplicate_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -351,7 +380,6 @@ grpc_cc_test( "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", "//src/proto/grpc/testing/duplicate:echo_duplicate_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -369,7 +397,6 @@ grpc_cc_test( "//:grpc++", "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -379,6 +406,28 @@ grpc_cc_test( name = "client_lb_end2end_test", srcs = ["client_lb_end2end_test.cc"], external_deps = [ + "gmock", + "gtest", + ], + deps = [ + ":test_service_impl", + "//:gpr", + "//:grpc", + "//:grpc++", + "//src/proto/grpc/testing:echo_messages_proto", + "//src/proto/grpc/testing:echo_proto", + "//src/proto/grpc/testing/duplicate:echo_duplicate_proto", + "//test/core/util:grpc_test_util", + "//test/core/util:test_lb_policies", + "//test/cpp/util:test_util", + ], +) + +grpc_cc_test( + name = "service_config_end2end_test", + srcs = ["service_config_end2end_test.cc"], + external_deps = [ + "gmock", "gtest", ], deps = [ @@ -389,7 +438,6 @@ grpc_cc_test( "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", "//src/proto/grpc/testing/duplicate:echo_duplicate_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -412,7 +460,28 @@ grpc_cc_test( "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", "//src/proto/grpc/testing/duplicate:echo_duplicate_proto", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + "//test/cpp/util:test_util", + ], +) + +grpc_cc_test( + name = "xds_end2end_test", + srcs = ["xds_end2end_test.cc"], + external_deps = [ + "gmock", + "gtest", + ], + deps = [ + ":test_service_impl", + "//:gpr", + "//:grpc", + "//:grpc++", + "//:grpc_resolver_fake", + "//src/proto/grpc/lb/v1:load_balancer_proto", + "//src/proto/grpc/testing:echo_messages_proto", + "//src/proto/grpc/testing:echo_proto", + "//src/proto/grpc/testing/duplicate:echo_duplicate_proto", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -434,7 +503,6 @@ grpc_cc_test( "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", "//src/proto/grpc/testing/duplicate:echo_duplicate_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:grpc++_proto_reflection_desc_db", "//test/cpp/util:test_util", @@ -455,7 +523,6 @@ grpc_cc_test( "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", "//src/proto/grpc/testing/duplicate:echo_duplicate_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -477,7 +544,6 @@ grpc_cc_test( "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", "//src/proto/grpc/testing/duplicate:echo_duplicate_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -498,8 +564,8 @@ grpc_cc_binary( "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", "//src/proto/grpc/testing/duplicate:echo_duplicate_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", + "//test/cpp/util:test_config", "//test/cpp/util:test_util", ], ) @@ -518,7 +584,6 @@ grpc_cc_test( "//:grpc++", "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -538,6 +603,25 @@ grpc_cc_test( ], ) +grpc_cc_test( + name = "flaky_network_test", + srcs = ["flaky_network_test.cc"], + external_deps = [ + "gtest", + ], + tags = ["manual"], + deps = [ + ":test_service_impl", + "//:gpr", + "//:grpc", + "//:grpc++", + "//src/proto/grpc/testing:echo_messages_proto", + "//src/proto/grpc/testing:echo_proto", + "//test/core/util:grpc_test_util", + "//test/cpp/util:test_util", + ], +) + grpc_cc_test( name = "shutdown_test", srcs = ["shutdown_test.cc"], @@ -551,7 +635,6 @@ grpc_cc_test( "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", "//src/proto/grpc/testing/duplicate:echo_duplicate_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], @@ -570,14 +653,15 @@ grpc_cc_test( "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", "//src/proto/grpc/testing/duplicate:echo_duplicate_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], + tags = ["no_windows"], ) grpc_cc_test( name = "thread_stress_test", + timeout = "long", srcs = ["thread_stress_test.cc"], external_deps = [ "gtest", @@ -589,8 +673,47 @@ grpc_cc_test( "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", "//src/proto/grpc/testing/duplicate:echo_duplicate_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], ) + +grpc_cc_test( + name = "cfstream_test", + srcs = ["cfstream_test.cc"], + external_deps = [ + "gtest", + ], + tags = ["manual"], # test requires root, won't work with bazel RBE + deps = [ + ":test_service_impl", + "//:gpr", + "//:grpc", + "//:grpc++", + "//src/proto/grpc/testing:echo_messages_proto", + "//src/proto/grpc/testing:echo_proto", + "//src/proto/grpc/testing:simple_messages_proto", + "//test/core/util:grpc_test_util", + "//test/cpp/util:test_util", + ], +) + +grpc_cc_test( + name = "message_allocator_end2end_test", + srcs = ["message_allocator_end2end_test.cc"], + external_deps = [ + "gtest", + ], + deps = [ + ":test_service_impl", + "//:grpc", + "//:gpr", + "//:grpc++", + "//src/proto/grpc/testing:echo_messages_proto", + "//src/proto/grpc/testing:echo_proto", + "//src/proto/grpc/testing:simple_messages_proto", + "//test/core/util:grpc_test_util", + "//test/cpp/util:test_util", + ], +) + diff --git a/test/cpp/end2end/async_end2end_test.cc b/test/cpp/end2end/async_end2end_test.cc index 6ecb9578015..97275db6276 100644 --- a/test/cpp/end2end/async_end2end_test.cc +++ b/test/cpp/end2end/async_end2end_test.cc @@ -32,6 +32,7 @@ #include #include +#include "src/core/ext/filters/client_channel/backup_poller.h" #include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/tls.h" #include "src/core/lib/iomgr/port.h" @@ -294,9 +295,9 @@ class AsyncEnd2endTest : public ::testing::TestWithParam { auto channel_creds = GetCredentialsProvider()->GetChannelCredentials( GetParam().credentials_type, &args); std::shared_ptr channel = - !(GetParam().inproc) - ? CreateCustomChannel(server_address_.str(), channel_creds, args) - : server_->InProcessChannel(args); + !(GetParam().inproc) ? ::grpc::CreateCustomChannel( + server_address_.str(), channel_creds, args) + : server_->InProcessChannel(args); stub_ = grpc::testing::EchoTestService::NewStub(channel); } @@ -1255,9 +1256,9 @@ TEST_P(AsyncEnd2endTest, UnimplementedRpc) { const auto& channel_creds = GetCredentialsProvider()->GetChannelCredentials( GetParam().credentials_type, &args); std::shared_ptr channel = - !(GetParam().inproc) - ? CreateCustomChannel(server_address_.str(), channel_creds, args) - : server_->InProcessChannel(args); + !(GetParam().inproc) ? ::grpc::CreateCustomChannel(server_address_.str(), + channel_creds, args) + : server_->InProcessChannel(args); std::unique_ptr stub; stub = grpc::testing::UnimplementedEchoService::NewStub(channel); EchoRequest send_request; @@ -1883,8 +1884,8 @@ INSTANTIATE_TEST_CASE_P(AsyncEnd2endServerTryCancel, int main(int argc, char** argv) { // Change the backup poll interval from 5s to 100ms to speed up the // ReconnectChannel test - gpr_setenv("GRPC_CLIENT_CHANNEL_BACKUP_POLL_INTERVAL_MS", "100"); - grpc_test_init(argc, argv); + GPR_GLOBAL_CONFIG_SET(grpc_client_channel_backup_poll_interval_ms, 100); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); int ret = RUN_ALL_TESTS(); return ret; diff --git a/test/cpp/end2end/cfstream_test.cc b/test/cpp/end2end/cfstream_test.cc new file mode 100644 index 00000000000..59cf98ffc20 --- /dev/null +++ b/test/cpp/end2end/cfstream_test.cc @@ -0,0 +1,454 @@ +/* + * + * Copyright 2019 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. + * 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/lib/iomgr/port.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "src/core/lib/backoff/backoff.h" +#include "src/core/lib/gpr/env.h" + +#include "src/proto/grpc/testing/echo.grpc.pb.h" +#include "test/core/util/port.h" +#include "test/core/util/test_config.h" +#include "test/cpp/end2end/test_service_impl.h" +#include "test/cpp/util/test_credentials_provider.h" + +#ifdef GRPC_CFSTREAM +using grpc::ClientAsyncResponseReader; +using grpc::testing::EchoRequest; +using grpc::testing::EchoResponse; +using grpc::testing::RequestParams; +using std::chrono::system_clock; + +namespace grpc { +namespace testing { +namespace { + +struct TestScenario { + TestScenario(const grpc::string& creds_type, const grpc::string& content) + : credentials_type(creds_type), message_content(content) {} + const grpc::string credentials_type; + const grpc::string message_content; +}; + +class CFStreamTest : public ::testing::TestWithParam { + protected: + CFStreamTest() + : server_host_("grpctest"), + interface_("lo0"), + ipv4_address_("10.0.0.1") {} + + void DNSUp() { + std::ostringstream cmd; + // Add DNS entry for server_host_ in /etc/hosts + cmd << "echo '" << ipv4_address_ << " " << server_host_ + << " ' | sudo tee -a /etc/hosts"; + std::system(cmd.str().c_str()); + } + + void DNSDown() { + std::ostringstream cmd; + // Remove DNS entry for server_host_ in /etc/hosts + cmd << "sudo sed -i '.bak' '/" << server_host_ << "/d' /etc/hosts"; + std::system(cmd.str().c_str()); + } + + void InterfaceUp() { + std::ostringstream cmd; + cmd << "sudo /sbin/ifconfig " << interface_ << " alias " << ipv4_address_; + std::system(cmd.str().c_str()); + } + + void InterfaceDown() { + std::ostringstream cmd; + cmd << "sudo /sbin/ifconfig " << interface_ << " -alias " << ipv4_address_; + std::system(cmd.str().c_str()); + } + + void NetworkUp() { + gpr_log(GPR_DEBUG, "Bringing network up"); + InterfaceUp(); + DNSUp(); + } + + void NetworkDown() { + gpr_log(GPR_DEBUG, "Bringing network down"); + InterfaceDown(); + DNSDown(); + } + + void SetUp() override { + NetworkUp(); + grpc_init(); + StartServer(); + } + + void TearDown() override { + NetworkDown(); + StopServer(); + grpc_shutdown(); + } + + void StartServer() { + port_ = grpc_pick_unused_port_or_die(); + server_.reset(new ServerData(port_, GetParam().credentials_type)); + server_->Start(server_host_); + } + void StopServer() { server_->Shutdown(); } + + std::unique_ptr BuildStub( + const std::shared_ptr& channel) { + return grpc::testing::EchoTestService::NewStub(channel); + } + + std::shared_ptr BuildChannel() { + std::ostringstream server_address; + server_address << server_host_ << ":" << port_; + ChannelArguments args; + auto channel_creds = GetCredentialsProvider()->GetChannelCredentials( + GetParam().credentials_type, &args); + return CreateCustomChannel(server_address.str(), channel_creds, args); + } + + void SendRpc( + const std::unique_ptr& stub, + bool expect_success = false) { + auto response = std::unique_ptr(new EchoResponse()); + EchoRequest request; + auto& msg = GetParam().message_content; + request.set_message(msg); + ClientContext context; + Status status = stub->Echo(&context, request, response.get()); + if (status.ok()) { + EXPECT_EQ(msg, response->message()); + } else { + gpr_log(GPR_DEBUG, "RPC failed: %s", status.error_message().c_str()); + } + if (expect_success) { + EXPECT_TRUE(status.ok()); + } + } + void SendAsyncRpc( + const std::unique_ptr& stub, + RequestParams param = RequestParams()) { + EchoRequest request; + request.set_message(GetParam().message_content); + *request.mutable_param() = std::move(param); + AsyncClientCall* call = new AsyncClientCall; + + call->response_reader = + stub->PrepareAsyncEcho(&call->context, request, &cq_); + + call->response_reader->StartCall(); + call->response_reader->Finish(&call->reply, &call->status, (void*)call); + } + + void ShutdownCQ() { cq_.Shutdown(); } + + bool CQNext(void** tag, bool* ok) { return cq_.Next(tag, ok); } + + bool WaitForChannelNotReady(Channel* channel, int timeout_seconds = 5) { + const gpr_timespec deadline = + grpc_timeout_seconds_to_deadline(timeout_seconds); + grpc_connectivity_state state; + while ((state = channel->GetState(false /* try_to_connect */)) == + GRPC_CHANNEL_READY) { + if (!channel->WaitForStateChange(state, deadline)) return false; + } + return true; + } + + bool WaitForChannelReady(Channel* channel, int timeout_seconds = 10) { + const gpr_timespec deadline = + grpc_timeout_seconds_to_deadline(timeout_seconds); + grpc_connectivity_state state; + while ((state = channel->GetState(true /* try_to_connect */)) != + GRPC_CHANNEL_READY) { + if (!channel->WaitForStateChange(state, deadline)) return false; + } + return true; + } + + struct AsyncClientCall { + EchoResponse reply; + ClientContext context; + Status status; + std::unique_ptr> response_reader; + }; + + private: + struct ServerData { + int port_; + const grpc::string creds_; + std::unique_ptr server_; + TestServiceImpl service_; + std::unique_ptr thread_; + bool server_ready_ = false; + + ServerData(int port, const grpc::string& creds) + : port_(port), creds_(creds) {} + + void Start(const grpc::string& server_host) { + gpr_log(GPR_INFO, "starting server on port %d", port_); + std::mutex mu; + std::unique_lock lock(mu); + std::condition_variable cond; + thread_.reset(new std::thread( + std::bind(&ServerData::Serve, this, server_host, &mu, &cond))); + cond.wait(lock, [this] { return server_ready_; }); + server_ready_ = false; + gpr_log(GPR_INFO, "server startup complete"); + } + + void Serve(const grpc::string& server_host, std::mutex* mu, + std::condition_variable* cond) { + std::ostringstream server_address; + server_address << server_host << ":" << port_; + ServerBuilder builder; + auto server_creds = + GetCredentialsProvider()->GetServerCredentials(creds_); + builder.AddListeningPort(server_address.str(), server_creds); + builder.RegisterService(&service_); + server_ = builder.BuildAndStart(); + std::lock_guard lock(*mu); + server_ready_ = true; + cond->notify_one(); + } + + void Shutdown(bool join = true) { + server_->Shutdown(grpc_timeout_milliseconds_to_deadline(0)); + if (join) thread_->join(); + } + }; + + CompletionQueue cq_; + const grpc::string server_host_; + const grpc::string interface_; + const grpc::string ipv4_address_; + std::unique_ptr server_; + int port_; +}; + +std::vector CreateTestScenarios() { + std::vector scenarios; + std::vector credentials_types; + std::vector messages; + + credentials_types.push_back(kInsecureCredentialsType); + auto sec_list = GetCredentialsProvider()->GetSecureCredentialsTypeList(); + for (auto sec = sec_list.begin(); sec != sec_list.end(); sec++) { + credentials_types.push_back(*sec); + } + + messages.push_back("🖖"); + for (size_t k = 1; k < GRPC_DEFAULT_MAX_RECV_MESSAGE_LENGTH / 1024; k *= 32) { + grpc::string big_msg; + for (size_t i = 0; i < k * 1024; ++i) { + char c = 'a' + (i % 26); + big_msg += c; + } + messages.push_back(big_msg); + } + for (auto cred = credentials_types.begin(); cred != credentials_types.end(); + ++cred) { + for (auto msg = messages.begin(); msg != messages.end(); msg++) { + scenarios.emplace_back(*cred, *msg); + } + } + + return scenarios; +} + +INSTANTIATE_TEST_CASE_P(CFStreamTest, CFStreamTest, + ::testing::ValuesIn(CreateTestScenarios())); + +// gRPC should automatically detech network flaps (without enabling keepalives) +// when CFStream is enabled +TEST_P(CFStreamTest, NetworkTransition) { + auto channel = BuildChannel(); + auto stub = BuildStub(channel); + // Channel should be in READY state after we send an RPC + SendRpc(stub, /*expect_success=*/true); + EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); + + std::atomic_bool shutdown{false}; + std::thread sender = std::thread([this, &stub, &shutdown]() { + while (true) { + if (shutdown.load()) { + return; + } + SendRpc(stub); + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + } + }); + + // bring down network + NetworkDown(); + + // network going down should be detected by cfstream + EXPECT_TRUE(WaitForChannelNotReady(channel.get())); + + // bring network interface back up + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + NetworkUp(); + + // channel should reconnect + EXPECT_TRUE(WaitForChannelReady(channel.get())); + EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); + shutdown.store(true); + sender.join(); +} + +// Network flaps while RPCs are in flight +TEST_P(CFStreamTest, NetworkFlapRpcsInFlight) { + auto channel = BuildChannel(); + auto stub = BuildStub(channel); + std::atomic_int rpcs_sent{0}; + + // Channel should be in READY state after we send some RPCs + for (int i = 0; i < 10; ++i) { + SendAsyncRpc(stub); + ++rpcs_sent; + } + EXPECT_TRUE(WaitForChannelReady(channel.get())); + + // Bring down the network + NetworkDown(); + + std::thread thd = std::thread([this, &rpcs_sent]() { + void* got_tag; + bool ok = false; + bool network_down = true; + int total_completions = 0; + + while (CQNext(&got_tag, &ok)) { + ++total_completions; + GPR_ASSERT(ok); + AsyncClientCall* call = static_cast(got_tag); + if (!call->status.ok()) { + gpr_log(GPR_DEBUG, "RPC failed with error: %s", + call->status.error_message().c_str()); + // Bring network up when RPCs start failing + if (network_down) { + NetworkUp(); + network_down = false; + } + } + delete call; + } + EXPECT_EQ(total_completions, rpcs_sent); + }); + + for (int i = 0; i < 100; ++i) { + SendAsyncRpc(stub); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + ++rpcs_sent; + } + + ShutdownCQ(); + + thd.join(); +} + +// Send a bunch of RPCs, some of which are expected to fail. +// We should get back a response for all RPCs +TEST_P(CFStreamTest, ConcurrentRpc) { + auto channel = BuildChannel(); + auto stub = BuildStub(channel); + std::atomic_int rpcs_sent{0}; + std::thread thd = std::thread([this, &rpcs_sent]() { + void* got_tag; + bool ok = false; + bool network_down = true; + int total_completions = 0; + + while (CQNext(&got_tag, &ok)) { + ++total_completions; + GPR_ASSERT(ok); + AsyncClientCall* call = static_cast(got_tag); + if (!call->status.ok()) { + gpr_log(GPR_DEBUG, "RPC failed: %s", + call->status.error_message().c_str()); + // Bring network up when RPCs start failing + if (network_down) { + NetworkUp(); + network_down = false; + } + } + delete call; + } + EXPECT_EQ(total_completions, rpcs_sent); + }); + + for (int i = 0; i < 10; ++i) { + if (i % 3 == 0) { + RequestParams param; + ErrorStatus* error = param.mutable_expected_error(); + error->set_code(StatusCode::INTERNAL); + error->set_error_message("internal error"); + SendAsyncRpc(stub, param); + } else if (i % 5 == 0) { + RequestParams param; + param.set_echo_metadata(true); + DebugInfo* info = param.mutable_debug_info(); + info->add_stack_entries("stack_entry1"); + info->add_stack_entries("stack_entry2"); + info->set_detail("detailed debug info"); + SendAsyncRpc(stub, param); + } else { + SendAsyncRpc(stub); + } + ++rpcs_sent; + } + + ShutdownCQ(); + + thd.join(); +} + +} // namespace +} // namespace testing +} // namespace grpc +#endif // GRPC_CFSTREAM + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + grpc_test_init(argc, argv); + gpr_setenv("grpc_cfstream", "1"); + const auto result = RUN_ALL_TESTS(); + return result; +} diff --git a/test/cpp/end2end/channelz_service_test.cc b/test/cpp/end2end/channelz_service_test.cc index f04ffe4f2d5..26ef59fbeb3 100644 --- a/test/cpp/end2end/channelz_service_test.cc +++ b/test/cpp/end2end/channelz_service_test.cc @@ -35,8 +35,6 @@ #include "test/core/util/test_config.h" #include "test/cpp/end2end/test_service_impl.h" -#include - #include using grpc::channelz::v1::GetChannelRequest; @@ -147,7 +145,7 @@ class ChannelzServerTest : public ::testing::Test { ChannelArguments args; args.SetInt(GRPC_ARG_ENABLE_CHANNELZ, 1); args.SetInt(GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE, 1024); - std::shared_ptr channel_to_backend = CreateCustomChannel( + std::shared_ptr channel_to_backend = ::grpc::CreateCustomChannel( backend_server_address, InsecureChannelCredentials(), args); proxy_service_.AddChannelToBackend(channel_to_backend); } @@ -159,11 +157,24 @@ class ChannelzServerTest : public ::testing::Test { // disable channelz. We only want to focus on proxy to backend outbound. args.SetInt(GRPC_ARG_ENABLE_CHANNELZ, 0); std::shared_ptr channel = - CreateCustomChannel(target, InsecureChannelCredentials(), args); + ::grpc::CreateCustomChannel(target, InsecureChannelCredentials(), args); channelz_stub_ = grpc::channelz::v1::Channelz::NewStub(channel); echo_stub_ = grpc::testing::EchoTestService::NewStub(channel); } + std::unique_ptr NewEchoStub() { + static int salt = 0; + string target = "dns:localhost:" + to_string(proxy_port_); + ChannelArguments args; + // disable channelz. We only want to focus on proxy to backend outbound. + args.SetInt(GRPC_ARG_ENABLE_CHANNELZ, 0); + // This ensures that gRPC will not do connection sharing. + args.SetInt("salt", salt++); + std::shared_ptr channel = + ::grpc::CreateCustomChannel(target, InsecureChannelCredentials(), args); + return grpc::testing::EchoTestService::NewStub(channel); + } + void SendSuccessfulEcho(int channel_idx) { EchoRequest request; EchoResponse response; @@ -651,6 +662,67 @@ TEST_F(ChannelzServerTest, GetServerSocketsTest) { EXPECT_EQ(get_server_sockets_response.socket_ref_size(), 1); } +TEST_F(ChannelzServerTest, GetServerSocketsPaginationTest) { + ResetStubs(); + ConfigureProxy(1); + std::vector> stubs; + const int kNumServerSocketsCreated = 20; + for (int i = 0; i < kNumServerSocketsCreated; ++i) { + stubs.push_back(NewEchoStub()); + EchoRequest request; + EchoResponse response; + request.set_message("Hello channelz"); + request.mutable_param()->set_backend_channel_idx(0); + ClientContext context; + Status s = stubs.back()->Echo(&context, request, &response); + EXPECT_EQ(response.message(), request.message()); + EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message(); + } + GetServersRequest get_server_request; + GetServersResponse get_server_response; + get_server_request.set_start_server_id(0); + ClientContext get_server_context; + Status s = channelz_stub_->GetServers(&get_server_context, get_server_request, + &get_server_response); + EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message(); + EXPECT_EQ(get_server_response.server_size(), 1); + // Make a request that gets all of the serversockets + { + GetServerSocketsRequest get_server_sockets_request; + GetServerSocketsResponse get_server_sockets_response; + get_server_sockets_request.set_server_id( + get_server_response.server(0).ref().server_id()); + get_server_sockets_request.set_start_socket_id(0); + ClientContext get_server_sockets_context; + s = channelz_stub_->GetServerSockets(&get_server_sockets_context, + get_server_sockets_request, + &get_server_sockets_response); + EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message(); + // We add one to account the channelz stub that will end up creating + // a serversocket. + EXPECT_EQ(get_server_sockets_response.socket_ref_size(), + kNumServerSocketsCreated + 1); + EXPECT_TRUE(get_server_sockets_response.end()); + } + // Now we make a request that exercises pagination. + { + GetServerSocketsRequest get_server_sockets_request; + GetServerSocketsResponse get_server_sockets_response; + get_server_sockets_request.set_server_id( + get_server_response.server(0).ref().server_id()); + get_server_sockets_request.set_start_socket_id(0); + const int kMaxResults = 10; + get_server_sockets_request.set_max_results(kMaxResults); + ClientContext get_server_sockets_context; + s = channelz_stub_->GetServerSockets(&get_server_sockets_context, + get_server_sockets_request, + &get_server_sockets_response); + EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message(); + EXPECT_EQ(get_server_sockets_response.socket_ref_size(), kMaxResults); + EXPECT_FALSE(get_server_sockets_response.end()); + } +} + TEST_F(ChannelzServerTest, GetServerListenSocketsTest) { ResetStubs(); ConfigureProxy(1); @@ -677,7 +749,7 @@ TEST_F(ChannelzServerTest, GetServerListenSocketsTest) { } // namespace grpc int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/cpp/end2end/client_callback_end2end_test.cc b/test/cpp/end2end/client_callback_end2end_test.cc index a35991396ad..ede24f333ba 100644 --- a/test/cpp/end2end/client_callback_end2end_test.cc +++ b/test/cpp/end2end/client_callback_end2end_test.cc @@ -16,8 +16,10 @@ * */ +#include #include #include +#include #include #include @@ -30,29 +32,57 @@ #include #include +#include "src/core/lib/iomgr/iomgr.h" #include "src/proto/grpc/testing/echo.grpc.pb.h" +#include "test/core/util/port.h" #include "test/core/util/test_config.h" +#include "test/cpp/end2end/interceptors_util.h" #include "test/cpp/end2end/test_service_impl.h" #include "test/cpp/util/byte_buffer_proto_helper.h" #include "test/cpp/util/string_ref_helper.h" +#include "test/cpp/util/test_credentials_provider.h" #include +// MAYBE_SKIP_TEST is a macro to determine if this particular test configuration +// should be skipped based on a decision made at SetUp time. In particular, any +// callback tests can only be run if the iomgr can run in the background or if +// the transport is in-process. +#define MAYBE_SKIP_TEST \ + do { \ + if (do_not_test_) { \ + return; \ + } \ + } while (0) + namespace grpc { namespace testing { namespace { +enum class Protocol { INPROC, TCP }; + class TestScenario { public: - TestScenario(bool serve_callback) : callback_server(serve_callback) {} + TestScenario(bool serve_callback, Protocol protocol, bool intercept, + const grpc::string& creds_type) + : callback_server(serve_callback), + protocol(protocol), + use_interceptors(intercept), + credentials_type(creds_type) {} void Log() const; bool callback_server; + Protocol protocol; + bool use_interceptors; + const grpc::string credentials_type; }; static std::ostream& operator<<(std::ostream& out, const TestScenario& scenario) { return out << "TestScenario{callback_server=" - << (scenario.callback_server ? "true" : "false") << "}"; + << (scenario.callback_server ? "true" : "false") << ",protocol=" + << (scenario.protocol == Protocol::INPROC ? "INPROC" : "TCP") + << ",intercept=" << (scenario.use_interceptors ? "true" : "false") + << ",creds=" << scenario.credentials_type << "}"; } void TestScenario::Log() const { @@ -69,27 +99,80 @@ class ClientCallbackEnd2endTest void SetUp() override { ServerBuilder builder; + auto server_creds = GetCredentialsProvider()->GetServerCredentials( + GetParam().credentials_type); + // TODO(vjpai): Support testing of AuthMetadataProcessor + + if (GetParam().protocol == Protocol::TCP) { + if (!grpc_iomgr_run_in_background()) { + do_not_test_ = true; + return; + } + picked_port_ = grpc_pick_unused_port_or_die(); + server_address_ << "localhost:" << picked_port_; + builder.AddListeningPort(server_address_.str(), server_creds); + } if (!GetParam().callback_server) { builder.RegisterService(&service_); } else { builder.RegisterService(&callback_service_); } + if (GetParam().use_interceptors) { + std::vector< + std::unique_ptr> + creators; + // Add 20 dummy server interceptors + creators.reserve(20); + for (auto i = 0; i < 20; i++) { + creators.push_back(std::unique_ptr( + new DummyInterceptorFactory())); + } + builder.experimental().SetInterceptorCreators(std::move(creators)); + } + server_ = builder.BuildAndStart(); is_server_started_ = true; } void ResetStub() { ChannelArguments args; - channel_ = server_->InProcessChannel(args); + auto channel_creds = GetCredentialsProvider()->GetChannelCredentials( + GetParam().credentials_type, &args); + switch (GetParam().protocol) { + case Protocol::TCP: + if (!GetParam().use_interceptors) { + channel_ = ::grpc::CreateCustomChannel(server_address_.str(), + channel_creds, args); + } else { + channel_ = CreateCustomChannelWithInterceptors( + server_address_.str(), channel_creds, args, + CreateDummyClientInterceptors()); + } + break; + case Protocol::INPROC: + if (!GetParam().use_interceptors) { + channel_ = server_->InProcessChannel(args); + } else { + channel_ = server_->experimental().InProcessChannelWithInterceptors( + args, CreateDummyClientInterceptors()); + } + break; + default: + assert(false); + } stub_ = grpc::testing::EchoTestService::NewStub(channel_); generic_stub_.reset(new GenericStub(channel_)); + DummyInterceptor::Reset(); } void TearDown() override { if (is_server_started_) { server_->Shutdown(); } + if (picked_port_ > 0) { + grpc_recycle_unused_port(picked_port_); + } } void SendRpcs(int num_rpcs, bool with_binary_metadata) { @@ -140,6 +223,36 @@ class ClientCallbackEnd2endTest } } + void SendRpcsRawReq(int num_rpcs) { + grpc::string test_string("Hello raw world."); + EchoRequest request; + request.set_message(test_string); + std::unique_ptr send_buf = SerializeToByteBuffer(&request); + + for (int i = 0; i < num_rpcs; i++) { + EchoResponse response; + ClientContext cli_ctx; + + std::mutex mu; + std::condition_variable cv; + bool done = false; + stub_->experimental_async()->Echo( + &cli_ctx, send_buf.get(), &response, + [&request, &response, &done, &mu, &cv](Status s) { + GPR_ASSERT(s.ok()); + + EXPECT_EQ(request.message(), response.message()); + std::lock_guard l(mu); + done = true; + cv.notify_one(); + }); + std::unique_lock l(mu); + while (!done) { + cv.wait(l); + } + } + } + void SendRpcsGeneric(int num_rpcs, bool maybe_except) { const grpc::string kMethodName("/grpc.testing.EchoTestService/Echo"); grpc::string test_string(""); @@ -182,43 +295,164 @@ class ClientCallbackEnd2endTest } } - bool is_server_started_; + void SendGenericEchoAsBidi(int num_rpcs, int reuses) { + const grpc::string kMethodName("/grpc.testing.EchoTestService/Echo"); + grpc::string test_string(""); + for (int i = 0; i < num_rpcs; i++) { + test_string += "Hello world. "; + class Client : public grpc::experimental::ClientBidiReactor { + public: + Client(ClientCallbackEnd2endTest* test, const grpc::string& method_name, + const grpc::string& test_str, int reuses) + : reuses_remaining_(reuses) { + activate_ = [this, test, method_name, test_str] { + if (reuses_remaining_ > 0) { + cli_ctx_.reset(new ClientContext); + reuses_remaining_--; + test->generic_stub_->experimental().PrepareBidiStreamingCall( + cli_ctx_.get(), method_name, this); + request_.set_message(test_str); + send_buf_ = SerializeToByteBuffer(&request_); + StartWrite(send_buf_.get()); + StartRead(&recv_buf_); + StartCall(); + } else { + std::unique_lock l(mu_); + done_ = true; + cv_.notify_one(); + } + }; + activate_(); + } + void OnWriteDone(bool ok) override { StartWritesDone(); } + void OnReadDone(bool ok) override { + EchoResponse response; + EXPECT_TRUE(ParseFromByteBuffer(&recv_buf_, &response)); + EXPECT_EQ(request_.message(), response.message()); + }; + void OnDone(const Status& s) override { + EXPECT_TRUE(s.ok()); + activate_(); + } + void Await() { + std::unique_lock l(mu_); + while (!done_) { + cv_.wait(l); + } + } + + EchoRequest request_; + std::unique_ptr send_buf_; + ByteBuffer recv_buf_; + std::unique_ptr cli_ctx_; + int reuses_remaining_; + std::function activate_; + std::mutex mu_; + std::condition_variable cv_; + bool done_ = false; + } rpc{this, kMethodName, test_string, reuses}; + + rpc.Await(); + } + } + bool do_not_test_{false}; + bool is_server_started_{false}; + int picked_port_{0}; std::shared_ptr channel_; std::unique_ptr stub_; std::unique_ptr generic_stub_; TestServiceImpl service_; CallbackTestServiceImpl callback_service_; std::unique_ptr server_; + std::ostringstream server_address_; }; TEST_P(ClientCallbackEnd2endTest, SimpleRpc) { + MAYBE_SKIP_TEST; ResetStub(); SendRpcs(1, false); } TEST_P(ClientCallbackEnd2endTest, SequentialRpcs) { + MAYBE_SKIP_TEST; ResetStub(); SendRpcs(10, false); } +TEST_P(ClientCallbackEnd2endTest, SequentialRpcsRawReq) { + MAYBE_SKIP_TEST; + ResetStub(); + SendRpcsRawReq(10); +} + +TEST_P(ClientCallbackEnd2endTest, SendClientInitialMetadata) { + MAYBE_SKIP_TEST; + ResetStub(); + SimpleRequest request; + SimpleResponse response; + ClientContext cli_ctx; + + cli_ctx.AddMetadata(kCheckClientInitialMetadataKey, + kCheckClientInitialMetadataVal); + + std::mutex mu; + std::condition_variable cv; + bool done = false; + stub_->experimental_async()->CheckClientInitialMetadata( + &cli_ctx, &request, &response, [&done, &mu, &cv](Status s) { + GPR_ASSERT(s.ok()); + + std::lock_guard l(mu); + done = true; + cv.notify_one(); + }); + std::unique_lock l(mu); + while (!done) { + cv.wait(l); + } +} + +TEST_P(ClientCallbackEnd2endTest, SimpleRpcWithBinaryMetadata) { + MAYBE_SKIP_TEST; + ResetStub(); + SendRpcs(1, true); +} + TEST_P(ClientCallbackEnd2endTest, SequentialRpcsWithVariedBinaryMetadataValue) { + MAYBE_SKIP_TEST; ResetStub(); SendRpcs(10, true); } TEST_P(ClientCallbackEnd2endTest, SequentialGenericRpcs) { + MAYBE_SKIP_TEST; ResetStub(); SendRpcsGeneric(10, false); } +TEST_P(ClientCallbackEnd2endTest, SequentialGenericRpcsAsBidi) { + MAYBE_SKIP_TEST; + ResetStub(); + SendGenericEchoAsBidi(10, 1); +} + +TEST_P(ClientCallbackEnd2endTest, SequentialGenericRpcsAsBidiWithReactorReuse) { + MAYBE_SKIP_TEST; + ResetStub(); + SendGenericEchoAsBidi(10, 10); +} + #if GRPC_ALLOW_EXCEPTIONS TEST_P(ClientCallbackEnd2endTest, ExceptingRpc) { + MAYBE_SKIP_TEST; ResetStub(); SendRpcsGeneric(10, true); } #endif TEST_P(ClientCallbackEnd2endTest, MultipleRpcsWithVariedBinaryMetadataValue) { + MAYBE_SKIP_TEST; ResetStub(); std::vector threads; threads.reserve(10); @@ -231,6 +465,7 @@ TEST_P(ClientCallbackEnd2endTest, MultipleRpcsWithVariedBinaryMetadataValue) { } TEST_P(ClientCallbackEnd2endTest, MultipleRpcs) { + MAYBE_SKIP_TEST; ResetStub(); std::vector threads; threads.reserve(10); @@ -243,6 +478,7 @@ TEST_P(ClientCallbackEnd2endTest, MultipleRpcs) { } TEST_P(ClientCallbackEnd2endTest, CancelRpcBeforeStart) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -265,19 +501,804 @@ TEST_P(ClientCallbackEnd2endTest, CancelRpcBeforeStart) { while (!done) { cv.wait(l); } + if (GetParam().use_interceptors) { + EXPECT_EQ(20, DummyInterceptor::GetNumTimesCancel()); + } } -TestScenario scenarios[] = {TestScenario{false}, TestScenario{true}}; +TEST_P(ClientCallbackEnd2endTest, RequestEchoServerCancel) { + MAYBE_SKIP_TEST; + ResetStub(); + EchoRequest request; + EchoResponse response; + ClientContext context; + request.set_message("hello"); + context.AddMetadata(kServerTryCancelRequest, + grpc::to_string(CANCEL_BEFORE_PROCESSING)); + + std::mutex mu; + std::condition_variable cv; + bool done = false; + stub_->experimental_async()->Echo( + &context, &request, &response, [&done, &mu, &cv](Status s) { + EXPECT_FALSE(s.ok()); + EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code()); + std::lock_guard l(mu); + done = true; + cv.notify_one(); + }); + std::unique_lock l(mu); + while (!done) { + cv.wait(l); + } +} + +struct ClientCancelInfo { + bool cancel{false}; + int ops_before_cancel; + + ClientCancelInfo() : cancel{false} {} + explicit ClientCancelInfo(int ops) : cancel{true}, ops_before_cancel{ops} {} +}; + +class WriteClient : public grpc::experimental::ClientWriteReactor { + public: + WriteClient(grpc::testing::EchoTestService::Stub* stub, + ServerTryCancelRequestPhase server_try_cancel, + int num_msgs_to_send, ClientCancelInfo client_cancel = {}) + : server_try_cancel_(server_try_cancel), + num_msgs_to_send_(num_msgs_to_send), + client_cancel_{client_cancel} { + grpc::string msg{"Hello server."}; + for (int i = 0; i < num_msgs_to_send; i++) { + desired_ += msg; + } + if (server_try_cancel != DO_NOT_CANCEL) { + // Send server_try_cancel value in the client metadata + context_.AddMetadata(kServerTryCancelRequest, + grpc::to_string(server_try_cancel)); + } + context_.set_initial_metadata_corked(true); + stub->experimental_async()->RequestStream(&context_, &response_, this); + StartCall(); + request_.set_message(msg); + MaybeWrite(); + } + void OnWriteDone(bool ok) override { + if (ok) { + num_msgs_sent_++; + MaybeWrite(); + } + } + void OnDone(const Status& s) override { + gpr_log(GPR_INFO, "Sent %d messages", num_msgs_sent_); + int num_to_send = + (client_cancel_.cancel) + ? std::min(num_msgs_to_send_, client_cancel_.ops_before_cancel) + : num_msgs_to_send_; + switch (server_try_cancel_) { + case CANCEL_BEFORE_PROCESSING: + case CANCEL_DURING_PROCESSING: + // If the RPC is canceled by server before / during messages from the + // client, it means that the client most likely did not get a chance to + // send all the messages it wanted to send. i.e num_msgs_sent <= + // num_msgs_to_send + EXPECT_LE(num_msgs_sent_, num_to_send); + break; + case DO_NOT_CANCEL: + case CANCEL_AFTER_PROCESSING: + // If the RPC was not canceled or canceled after all messages were read + // by the server, the client did get a chance to send all its messages + EXPECT_EQ(num_msgs_sent_, num_to_send); + break; + default: + assert(false); + break; + } + if ((server_try_cancel_ == DO_NOT_CANCEL) && !client_cancel_.cancel) { + EXPECT_TRUE(s.ok()); + EXPECT_EQ(response_.message(), desired_); + } else { + EXPECT_FALSE(s.ok()); + EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code()); + } + std::unique_lock l(mu_); + done_ = true; + cv_.notify_one(); + } + void Await() { + std::unique_lock l(mu_); + while (!done_) { + cv_.wait(l); + } + } + + private: + void MaybeWrite() { + if (client_cancel_.cancel && + num_msgs_sent_ == client_cancel_.ops_before_cancel) { + context_.TryCancel(); + } else if (num_msgs_to_send_ > num_msgs_sent_ + 1) { + StartWrite(&request_); + } else if (num_msgs_to_send_ == num_msgs_sent_ + 1) { + StartWriteLast(&request_, WriteOptions()); + } + } + EchoRequest request_; + EchoResponse response_; + ClientContext context_; + const ServerTryCancelRequestPhase server_try_cancel_; + int num_msgs_sent_{0}; + const int num_msgs_to_send_; + grpc::string desired_; + const ClientCancelInfo client_cancel_; + std::mutex mu_; + std::condition_variable cv_; + bool done_ = false; +}; + +TEST_P(ClientCallbackEnd2endTest, RequestStream) { + MAYBE_SKIP_TEST; + ResetStub(); + WriteClient test{stub_.get(), DO_NOT_CANCEL, 3}; + test.Await(); + // Make sure that the server interceptors were not notified to cancel + if (GetParam().use_interceptors) { + EXPECT_EQ(0, DummyInterceptor::GetNumTimesCancel()); + } +} + +TEST_P(ClientCallbackEnd2endTest, ClientCancelsRequestStream) { + MAYBE_SKIP_TEST; + ResetStub(); + WriteClient test{stub_.get(), DO_NOT_CANCEL, 3, ClientCancelInfo{2}}; + test.Await(); + // Make sure that the server interceptors got the cancel + if (GetParam().use_interceptors) { + EXPECT_EQ(20, DummyInterceptor::GetNumTimesCancel()); + } +} + +// Server to cancel before doing reading the request +TEST_P(ClientCallbackEnd2endTest, RequestStreamServerCancelBeforeReads) { + MAYBE_SKIP_TEST; + ResetStub(); + WriteClient test{stub_.get(), CANCEL_BEFORE_PROCESSING, 1}; + test.Await(); + // Make sure that the server interceptors were notified + if (GetParam().use_interceptors) { + EXPECT_EQ(20, DummyInterceptor::GetNumTimesCancel()); + } +} + +// Server to cancel while reading a request from the stream in parallel +TEST_P(ClientCallbackEnd2endTest, RequestStreamServerCancelDuringRead) { + MAYBE_SKIP_TEST; + ResetStub(); + WriteClient test{stub_.get(), CANCEL_DURING_PROCESSING, 10}; + test.Await(); + // Make sure that the server interceptors were notified + if (GetParam().use_interceptors) { + EXPECT_EQ(20, DummyInterceptor::GetNumTimesCancel()); + } +} + +// Server to cancel after reading all the requests but before returning to the +// client +TEST_P(ClientCallbackEnd2endTest, RequestStreamServerCancelAfterReads) { + MAYBE_SKIP_TEST; + ResetStub(); + WriteClient test{stub_.get(), CANCEL_AFTER_PROCESSING, 4}; + test.Await(); + // Make sure that the server interceptors were notified + if (GetParam().use_interceptors) { + EXPECT_EQ(20, DummyInterceptor::GetNumTimesCancel()); + } +} + +TEST_P(ClientCallbackEnd2endTest, UnaryReactor) { + MAYBE_SKIP_TEST; + ResetStub(); + class UnaryClient : public grpc::experimental::ClientUnaryReactor { + public: + UnaryClient(grpc::testing::EchoTestService::Stub* stub) { + cli_ctx_.AddMetadata("key1", "val1"); + cli_ctx_.AddMetadata("key2", "val2"); + request_.mutable_param()->set_echo_metadata_initially(true); + request_.set_message("Hello metadata"); + stub->experimental_async()->Echo(&cli_ctx_, &request_, &response_, this); + StartCall(); + } + void OnReadInitialMetadataDone(bool ok) override { + EXPECT_TRUE(ok); + EXPECT_EQ(1u, cli_ctx_.GetServerInitialMetadata().count("key1")); + EXPECT_EQ( + "val1", + ToString(cli_ctx_.GetServerInitialMetadata().find("key1")->second)); + EXPECT_EQ(1u, cli_ctx_.GetServerInitialMetadata().count("key2")); + EXPECT_EQ( + "val2", + ToString(cli_ctx_.GetServerInitialMetadata().find("key2")->second)); + initial_metadata_done_ = true; + } + void OnDone(const Status& s) override { + EXPECT_TRUE(initial_metadata_done_); + EXPECT_EQ(0u, cli_ctx_.GetServerTrailingMetadata().size()); + EXPECT_TRUE(s.ok()); + EXPECT_EQ(request_.message(), response_.message()); + std::unique_lock l(mu_); + done_ = true; + cv_.notify_one(); + } + void Await() { + std::unique_lock l(mu_); + while (!done_) { + cv_.wait(l); + } + } + + private: + EchoRequest request_; + EchoResponse response_; + ClientContext cli_ctx_; + std::mutex mu_; + std::condition_variable cv_; + bool done_{false}; + bool initial_metadata_done_{false}; + }; + + UnaryClient test{stub_.get()}; + test.Await(); + // Make sure that the server interceptors were not notified of a cancel + if (GetParam().use_interceptors) { + EXPECT_EQ(0, DummyInterceptor::GetNumTimesCancel()); + } +} + +class ReadClient : public grpc::experimental::ClientReadReactor { + public: + ReadClient(grpc::testing::EchoTestService::Stub* stub, + ServerTryCancelRequestPhase server_try_cancel, + ClientCancelInfo client_cancel = {}) + : server_try_cancel_(server_try_cancel), client_cancel_{client_cancel} { + if (server_try_cancel_ != DO_NOT_CANCEL) { + // Send server_try_cancel value in the client metadata + context_.AddMetadata(kServerTryCancelRequest, + grpc::to_string(server_try_cancel)); + } + request_.set_message("Hello client "); + stub->experimental_async()->ResponseStream(&context_, &request_, this); + if (client_cancel_.cancel && + reads_complete_ == client_cancel_.ops_before_cancel) { + context_.TryCancel(); + } + // Even if we cancel, read until failure because there might be responses + // pending + StartRead(&response_); + StartCall(); + } + void OnReadDone(bool ok) override { + if (!ok) { + if (server_try_cancel_ == DO_NOT_CANCEL && !client_cancel_.cancel) { + EXPECT_EQ(reads_complete_, kServerDefaultResponseStreamsToSend); + } + } else { + EXPECT_LE(reads_complete_, kServerDefaultResponseStreamsToSend); + EXPECT_EQ(response_.message(), + request_.message() + grpc::to_string(reads_complete_)); + reads_complete_++; + if (client_cancel_.cancel && + reads_complete_ == client_cancel_.ops_before_cancel) { + context_.TryCancel(); + } + // Even if we cancel, read until failure because there might be responses + // pending + StartRead(&response_); + } + } + void OnDone(const Status& s) override { + gpr_log(GPR_INFO, "Read %d messages", reads_complete_); + switch (server_try_cancel_) { + case DO_NOT_CANCEL: + if (!client_cancel_.cancel || client_cancel_.ops_before_cancel > + kServerDefaultResponseStreamsToSend) { + EXPECT_TRUE(s.ok()); + EXPECT_EQ(reads_complete_, kServerDefaultResponseStreamsToSend); + } else { + EXPECT_GE(reads_complete_, client_cancel_.ops_before_cancel); + EXPECT_LE(reads_complete_, kServerDefaultResponseStreamsToSend); + // Status might be ok or cancelled depending on whether server + // sent status before client cancel went through + if (!s.ok()) { + EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code()); + } + } + break; + case CANCEL_BEFORE_PROCESSING: + EXPECT_FALSE(s.ok()); + EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code()); + EXPECT_EQ(reads_complete_, 0); + break; + case CANCEL_DURING_PROCESSING: + case CANCEL_AFTER_PROCESSING: + // If server canceled while writing messages, client must have read + // less than or equal to the expected number of messages. Even if the + // server canceled after writing all messages, the RPC may be canceled + // before the Client got a chance to read all the messages. + EXPECT_FALSE(s.ok()); + EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code()); + EXPECT_LE(reads_complete_, kServerDefaultResponseStreamsToSend); + break; + default: + assert(false); + } + std::unique_lock l(mu_); + done_ = true; + cv_.notify_one(); + } + void Await() { + std::unique_lock l(mu_); + while (!done_) { + cv_.wait(l); + } + } + + private: + EchoRequest request_; + EchoResponse response_; + ClientContext context_; + const ServerTryCancelRequestPhase server_try_cancel_; + int reads_complete_{0}; + const ClientCancelInfo client_cancel_; + std::mutex mu_; + std::condition_variable cv_; + bool done_ = false; +}; + +TEST_P(ClientCallbackEnd2endTest, ResponseStream) { + MAYBE_SKIP_TEST; + ResetStub(); + ReadClient test{stub_.get(), DO_NOT_CANCEL}; + test.Await(); + // Make sure that the server interceptors were not notified of a cancel + if (GetParam().use_interceptors) { + EXPECT_EQ(0, DummyInterceptor::GetNumTimesCancel()); + } +} + +TEST_P(ClientCallbackEnd2endTest, ClientCancelsResponseStream) { + MAYBE_SKIP_TEST; + ResetStub(); + ReadClient test{stub_.get(), DO_NOT_CANCEL, ClientCancelInfo{2}}; + test.Await(); + // Because cancel in this case races with server finish, we can't be sure that + // server interceptors even see cancellation +} + +// Server to cancel before sending any response messages +TEST_P(ClientCallbackEnd2endTest, ResponseStreamServerCancelBefore) { + MAYBE_SKIP_TEST; + ResetStub(); + ReadClient test{stub_.get(), CANCEL_BEFORE_PROCESSING}; + test.Await(); + // Make sure that the server interceptors were notified + if (GetParam().use_interceptors) { + EXPECT_EQ(20, DummyInterceptor::GetNumTimesCancel()); + } +} + +// Server to cancel while writing a response to the stream in parallel +TEST_P(ClientCallbackEnd2endTest, ResponseStreamServerCancelDuring) { + MAYBE_SKIP_TEST; + ResetStub(); + ReadClient test{stub_.get(), CANCEL_DURING_PROCESSING}; + test.Await(); + // Make sure that the server interceptors were notified + if (GetParam().use_interceptors) { + EXPECT_EQ(20, DummyInterceptor::GetNumTimesCancel()); + } +} + +// Server to cancel after writing all the respones to the stream but before +// returning to the client +TEST_P(ClientCallbackEnd2endTest, ResponseStreamServerCancelAfter) { + MAYBE_SKIP_TEST; + ResetStub(); + ReadClient test{stub_.get(), CANCEL_AFTER_PROCESSING}; + test.Await(); + // Make sure that the server interceptors were notified + if (GetParam().use_interceptors) { + EXPECT_EQ(20, DummyInterceptor::GetNumTimesCancel()); + } +} + +class BidiClient + : public grpc::experimental::ClientBidiReactor { + public: + BidiClient(grpc::testing::EchoTestService::Stub* stub, + ServerTryCancelRequestPhase server_try_cancel, + int num_msgs_to_send, ClientCancelInfo client_cancel = {}) + : server_try_cancel_(server_try_cancel), + msgs_to_send_{num_msgs_to_send}, + client_cancel_{client_cancel} { + if (server_try_cancel_ != DO_NOT_CANCEL) { + // Send server_try_cancel value in the client metadata + context_.AddMetadata(kServerTryCancelRequest, + grpc::to_string(server_try_cancel)); + } + request_.set_message("Hello fren "); + stub->experimental_async()->BidiStream(&context_, this); + MaybeWrite(); + StartRead(&response_); + StartCall(); + } + void OnReadDone(bool ok) override { + if (!ok) { + if (server_try_cancel_ == DO_NOT_CANCEL) { + if (!client_cancel_.cancel) { + EXPECT_EQ(reads_complete_, msgs_to_send_); + } else { + EXPECT_LE(reads_complete_, writes_complete_); + } + } + } else { + EXPECT_LE(reads_complete_, msgs_to_send_); + EXPECT_EQ(response_.message(), request_.message()); + reads_complete_++; + StartRead(&response_); + } + } + void OnWriteDone(bool ok) override { + if (server_try_cancel_ == DO_NOT_CANCEL) { + EXPECT_TRUE(ok); + } else if (!ok) { + return; + } + writes_complete_++; + MaybeWrite(); + } + void OnDone(const Status& s) override { + gpr_log(GPR_INFO, "Sent %d messages", writes_complete_); + gpr_log(GPR_INFO, "Read %d messages", reads_complete_); + switch (server_try_cancel_) { + case DO_NOT_CANCEL: + if (!client_cancel_.cancel || + client_cancel_.ops_before_cancel > msgs_to_send_) { + EXPECT_TRUE(s.ok()); + EXPECT_EQ(writes_complete_, msgs_to_send_); + EXPECT_EQ(reads_complete_, writes_complete_); + } else { + EXPECT_FALSE(s.ok()); + EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code()); + EXPECT_EQ(writes_complete_, client_cancel_.ops_before_cancel); + EXPECT_LE(reads_complete_, writes_complete_); + } + break; + case CANCEL_BEFORE_PROCESSING: + EXPECT_FALSE(s.ok()); + EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code()); + // The RPC is canceled before the server did any work or returned any + // reads, but it's possible that some writes took place first from the + // client + EXPECT_LE(writes_complete_, msgs_to_send_); + EXPECT_EQ(reads_complete_, 0); + break; + case CANCEL_DURING_PROCESSING: + EXPECT_FALSE(s.ok()); + EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code()); + EXPECT_LE(writes_complete_, msgs_to_send_); + EXPECT_LE(reads_complete_, writes_complete_); + break; + case CANCEL_AFTER_PROCESSING: + EXPECT_FALSE(s.ok()); + EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code()); + EXPECT_EQ(writes_complete_, msgs_to_send_); + // The Server canceled after reading the last message and after writing + // the message to the client. However, the RPC cancellation might have + // taken effect before the client actually read the response. + EXPECT_LE(reads_complete_, writes_complete_); + break; + default: + assert(false); + } + std::unique_lock l(mu_); + done_ = true; + cv_.notify_one(); + } + void Await() { + std::unique_lock l(mu_); + while (!done_) { + cv_.wait(l); + } + } + + private: + void MaybeWrite() { + if (client_cancel_.cancel && + writes_complete_ == client_cancel_.ops_before_cancel) { + context_.TryCancel(); + } else if (writes_complete_ == msgs_to_send_) { + StartWritesDone(); + } else { + StartWrite(&request_); + } + } + EchoRequest request_; + EchoResponse response_; + ClientContext context_; + const ServerTryCancelRequestPhase server_try_cancel_; + int reads_complete_{0}; + int writes_complete_{0}; + const int msgs_to_send_; + const ClientCancelInfo client_cancel_; + std::mutex mu_; + std::condition_variable cv_; + bool done_ = false; +}; + +TEST_P(ClientCallbackEnd2endTest, BidiStream) { + MAYBE_SKIP_TEST; + ResetStub(); + BidiClient test{stub_.get(), DO_NOT_CANCEL, + kServerDefaultResponseStreamsToSend}; + test.Await(); + // Make sure that the server interceptors were not notified of a cancel + if (GetParam().use_interceptors) { + EXPECT_EQ(0, DummyInterceptor::GetNumTimesCancel()); + } +} + +TEST_P(ClientCallbackEnd2endTest, ClientCancelsBidiStream) { + MAYBE_SKIP_TEST; + ResetStub(); + BidiClient test{stub_.get(), DO_NOT_CANCEL, + kServerDefaultResponseStreamsToSend, ClientCancelInfo{2}}; + test.Await(); + // Make sure that the server interceptors were notified of a cancel + if (GetParam().use_interceptors) { + EXPECT_EQ(20, DummyInterceptor::GetNumTimesCancel()); + } +} + +// Server to cancel before reading/writing any requests/responses on the stream +TEST_P(ClientCallbackEnd2endTest, BidiStreamServerCancelBefore) { + MAYBE_SKIP_TEST; + ResetStub(); + BidiClient test{stub_.get(), CANCEL_BEFORE_PROCESSING, 2}; + test.Await(); + // Make sure that the server interceptors were notified + if (GetParam().use_interceptors) { + EXPECT_EQ(20, DummyInterceptor::GetNumTimesCancel()); + } +} + +// Server to cancel while reading/writing requests/responses on the stream in +// parallel +TEST_P(ClientCallbackEnd2endTest, BidiStreamServerCancelDuring) { + MAYBE_SKIP_TEST; + ResetStub(); + BidiClient test{stub_.get(), CANCEL_DURING_PROCESSING, 10}; + test.Await(); + // Make sure that the server interceptors were notified + if (GetParam().use_interceptors) { + EXPECT_EQ(20, DummyInterceptor::GetNumTimesCancel()); + } +} + +// Server to cancel after reading/writing all requests/responses on the stream +// but before returning to the client +TEST_P(ClientCallbackEnd2endTest, BidiStreamServerCancelAfter) { + MAYBE_SKIP_TEST; + ResetStub(); + BidiClient test{stub_.get(), CANCEL_AFTER_PROCESSING, 5}; + test.Await(); + // Make sure that the server interceptors were notified + if (GetParam().use_interceptors) { + EXPECT_EQ(20, DummyInterceptor::GetNumTimesCancel()); + } +} + +TEST_P(ClientCallbackEnd2endTest, SimultaneousReadAndWritesDone) { + MAYBE_SKIP_TEST; + ResetStub(); + class Client : public grpc::experimental::ClientBidiReactor { + public: + Client(grpc::testing::EchoTestService::Stub* stub) { + request_.set_message("Hello bidi "); + stub->experimental_async()->BidiStream(&context_, this); + StartWrite(&request_); + StartCall(); + } + void OnReadDone(bool ok) override { + EXPECT_TRUE(ok); + EXPECT_EQ(response_.message(), request_.message()); + } + void OnWriteDone(bool ok) override { + EXPECT_TRUE(ok); + // Now send out the simultaneous Read and WritesDone + StartWritesDone(); + StartRead(&response_); + } + void OnDone(const Status& s) override { + EXPECT_TRUE(s.ok()); + EXPECT_EQ(response_.message(), request_.message()); + std::unique_lock l(mu_); + done_ = true; + cv_.notify_one(); + } + void Await() { + std::unique_lock l(mu_); + while (!done_) { + cv_.wait(l); + } + } + + private: + EchoRequest request_; + EchoResponse response_; + ClientContext context_; + std::mutex mu_; + std::condition_variable cv_; + bool done_ = false; + } test{stub_.get()}; + + test.Await(); +} + +TEST_P(ClientCallbackEnd2endTest, UnimplementedRpc) { + MAYBE_SKIP_TEST; + ChannelArguments args; + const auto& channel_creds = GetCredentialsProvider()->GetChannelCredentials( + GetParam().credentials_type, &args); + std::shared_ptr channel = + (GetParam().protocol == Protocol::TCP) + ? ::grpc::CreateCustomChannel(server_address_.str(), channel_creds, + args) + : server_->InProcessChannel(args); + std::unique_ptr stub; + stub = grpc::testing::UnimplementedEchoService::NewStub(channel); + EchoRequest request; + EchoResponse response; + ClientContext cli_ctx; + request.set_message("Hello world."); + std::mutex mu; + std::condition_variable cv; + bool done = false; + stub->experimental_async()->Unimplemented( + &cli_ctx, &request, &response, [&done, &mu, &cv](Status s) { + EXPECT_EQ(StatusCode::UNIMPLEMENTED, s.error_code()); + EXPECT_EQ("", s.error_message()); + + std::lock_guard l(mu); + done = true; + cv.notify_one(); + }); + std::unique_lock l(mu); + while (!done) { + cv.wait(l); + } +} + +TEST_P(ClientCallbackEnd2endTest, + ResponseStreamExtraReactionFlowReadsUntilDone) { + MAYBE_SKIP_TEST; + ResetStub(); + class ReadAllIncomingDataClient + : public grpc::experimental::ClientReadReactor { + public: + ReadAllIncomingDataClient(grpc::testing::EchoTestService::Stub* stub) { + request_.set_message("Hello client "); + stub->experimental_async()->ResponseStream(&context_, &request_, this); + } + bool WaitForReadDone() { + std::unique_lock l(mu_); + while (!read_done_) { + read_cv_.wait(l); + } + read_done_ = false; + return read_ok_; + } + void Await() { + std::unique_lock l(mu_); + while (!done_) { + done_cv_.wait(l); + } + } + const Status& status() { + std::unique_lock l(mu_); + return status_; + } + + private: + void OnReadDone(bool ok) override { + std::unique_lock l(mu_); + read_ok_ = ok; + read_done_ = true; + read_cv_.notify_one(); + } + void OnDone(const Status& s) override { + std::unique_lock l(mu_); + done_ = true; + status_ = s; + done_cv_.notify_one(); + } + + EchoRequest request_; + EchoResponse response_; + ClientContext context_; + bool read_ok_ = false; + bool read_done_ = false; + std::mutex mu_; + std::condition_variable read_cv_; + std::condition_variable done_cv_; + bool done_ = false; + Status status_; + } client{stub_.get()}; + + int reads_complete = 0; + client.AddHold(); + client.StartCall(); + + EchoResponse response; + bool read_ok = true; + while (read_ok) { + client.StartRead(&response); + read_ok = client.WaitForReadDone(); + if (read_ok) { + ++reads_complete; + } + } + client.RemoveHold(); + client.Await(); + + EXPECT_EQ(kServerDefaultResponseStreamsToSend, reads_complete); + EXPECT_EQ(client.status().error_code(), grpc::StatusCode::OK); +} + +std::vector CreateTestScenarios(bool test_insecure) { + std::vector scenarios; + std::vector credentials_types{ + GetCredentialsProvider()->GetSecureCredentialsTypeList()}; + auto insec_ok = [] { + // Only allow insecure credentials type when it is registered with the + // provider. User may create providers that do not have insecure. + return GetCredentialsProvider()->GetChannelCredentials( + kInsecureCredentialsType, nullptr) != nullptr; + }; + if (test_insecure && insec_ok()) { + credentials_types.push_back(kInsecureCredentialsType); + } + GPR_ASSERT(!credentials_types.empty()); + + bool barr[]{false, true}; + Protocol parr[]{Protocol::INPROC, Protocol::TCP}; + for (Protocol p : parr) { + for (const auto& cred : credentials_types) { + // TODO(vjpai): Test inproc with secure credentials when feasible + if (p == Protocol::INPROC && + (cred != kInsecureCredentialsType || !insec_ok())) { + continue; + } + for (bool callback_server : barr) { + for (bool use_interceptors : barr) { + scenarios.emplace_back(callback_server, p, use_interceptors, cred); + } + } + } + } + return scenarios; +} INSTANTIATE_TEST_CASE_P(ClientCallbackEnd2endTest, ClientCallbackEnd2endTest, - ::testing::ValuesIn(scenarios)); + ::testing::ValuesIn(CreateTestScenarios(true))); } // namespace } // namespace testing } // namespace grpc int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/cpp/end2end/client_crash_test.cc b/test/cpp/end2end/client_crash_test.cc index 2a06f44c608..2d5c1b47b17 100644 --- a/test/cpp/end2end/client_crash_test.cc +++ b/test/cpp/end2end/client_crash_test.cc @@ -60,7 +60,7 @@ class CrashTest : public ::testing::Test { })); GPR_ASSERT(server_); return grpc::testing::EchoTestService::NewStub( - CreateChannel(addr, InsecureChannelCredentials())); + grpc::CreateChannel(addr, InsecureChannelCredentials())); } void KillServer() { server_.reset(); } @@ -135,7 +135,7 @@ int main(int argc, char** argv) { g_root = "."; } - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); // Order seems to matter on these tests: run three times to eliminate that for (int i = 0; i < 3; i++) { diff --git a/test/cpp/end2end/client_crash_test_server.cc b/test/cpp/end2end/client_crash_test_server.cc index cb4afd71670..d92f9c5cff3 100644 --- a/test/cpp/end2end/client_crash_test_server.cc +++ b/test/cpp/end2end/client_crash_test_server.cc @@ -27,6 +27,7 @@ #include #include "src/proto/grpc/testing/echo.grpc.pb.h" +#include "test/cpp/util/test_config.h" DEFINE_string(address, "", "Address to bind to"); @@ -72,7 +73,7 @@ void RunServer() { } // namespace grpc int main(int argc, char** argv) { - ParseCommandLineFlags(&argc, &argv, true); + grpc::testing::InitTest(&argc, &argv, true); grpc::testing::RunServer(); return 0; diff --git a/test/cpp/end2end/client_interceptors_end2end_test.cc b/test/cpp/end2end/client_interceptors_end2end_test.cc index 60e8b051ab8..f1aed093dc4 100644 --- a/test/cpp/end2end/client_interceptors_end2end_test.cc +++ b/test/cpp/end2end/client_interceptors_end2end_test.cc @@ -23,11 +23,11 @@ #include #include #include -#include #include #include #include #include +#include #include "src/proto/grpc/testing/echo.grpc.pb.h" #include "test/core/util/port.h" @@ -50,6 +50,7 @@ class HijackingInterceptor : public experimental::Interceptor { info_ = info; // Make sure it is the right method EXPECT_EQ(strcmp("/grpc.testing.EchoTestService/Echo", info->method()), 0); + EXPECT_EQ(info->type(), experimental::ClientRpcInfo::Type::UNARY); } virtual void Intercept(experimental::InterceptorBatchMethods* methods) { @@ -67,7 +68,7 @@ class HijackingInterceptor : public experimental::Interceptor { if (methods->QueryInterceptionHookPoint( experimental::InterceptionHookPoints::PRE_SEND_MESSAGE)) { EchoRequest req; - auto* buffer = methods->GetSendMessage(); + auto* buffer = methods->GetSerializedSendMessage(); auto copied_buffer = *buffer; EXPECT_TRUE( SerializationTraits::Deserialize(&copied_buffer, &req) @@ -172,7 +173,7 @@ class HijackingInterceptorMakesAnotherCall : public experimental::Interceptor { if (methods->QueryInterceptionHookPoint( experimental::InterceptionHookPoints::PRE_SEND_MESSAGE)) { EchoRequest req; - auto* buffer = methods->GetSendMessage(); + auto* buffer = methods->GetSerializedSendMessage(); auto copied_buffer = *buffer; EXPECT_TRUE( SerializationTraits::Deserialize(&copied_buffer, &req) @@ -269,6 +270,235 @@ class HijackingInterceptorMakesAnotherCallFactory } }; +class BidiStreamingRpcHijackingInterceptor : public experimental::Interceptor { + public: + BidiStreamingRpcHijackingInterceptor(experimental::ClientRpcInfo* info) { + info_ = info; + } + + virtual void Intercept(experimental::InterceptorBatchMethods* methods) { + bool hijack = false; + if (methods->QueryInterceptionHookPoint( + experimental::InterceptionHookPoints::PRE_SEND_INITIAL_METADATA)) { + CheckMetadata(*methods->GetSendInitialMetadata(), "testkey", "testvalue"); + hijack = true; + } + if (methods->QueryInterceptionHookPoint( + experimental::InterceptionHookPoints::PRE_SEND_MESSAGE)) { + EchoRequest req; + auto* buffer = methods->GetSerializedSendMessage(); + auto copied_buffer = *buffer; + EXPECT_TRUE( + SerializationTraits::Deserialize(&copied_buffer, &req) + .ok()); + EXPECT_EQ(req.message().find("Hello"), 0u); + msg = req.message(); + } + if (methods->QueryInterceptionHookPoint( + experimental::InterceptionHookPoints::PRE_SEND_CLOSE)) { + // Got nothing to do here for now + } + if (methods->QueryInterceptionHookPoint( + experimental::InterceptionHookPoints::POST_RECV_STATUS)) { + CheckMetadata(*methods->GetRecvTrailingMetadata(), "testkey", + "testvalue"); + auto* status = methods->GetRecvStatus(); + EXPECT_EQ(status->ok(), true); + } + if (methods->QueryInterceptionHookPoint( + experimental::InterceptionHookPoints::PRE_RECV_MESSAGE)) { + EchoResponse* resp = + static_cast(methods->GetRecvMessage()); + resp->set_message(msg); + } + if (methods->QueryInterceptionHookPoint( + experimental::InterceptionHookPoints::POST_RECV_MESSAGE)) { + EXPECT_EQ(static_cast(methods->GetRecvMessage()) + ->message() + .find("Hello"), + 0u); + } + if (methods->QueryInterceptionHookPoint( + experimental::InterceptionHookPoints::PRE_RECV_STATUS)) { + auto* map = methods->GetRecvTrailingMetadata(); + // insert the metadata that we want + EXPECT_EQ(map->size(), static_cast(0)); + map->insert(std::make_pair("testkey", "testvalue")); + auto* status = methods->GetRecvStatus(); + *status = Status(StatusCode::OK, ""); + } + if (hijack) { + methods->Hijack(); + } else { + methods->Proceed(); + } + } + + private: + experimental::ClientRpcInfo* info_; + grpc::string msg; +}; + +class ClientStreamingRpcHijackingInterceptor + : public experimental::Interceptor { + public: + ClientStreamingRpcHijackingInterceptor(experimental::ClientRpcInfo* info) { + info_ = info; + } + virtual void Intercept(experimental::InterceptorBatchMethods* methods) { + bool hijack = false; + if (methods->QueryInterceptionHookPoint( + experimental::InterceptionHookPoints::PRE_SEND_INITIAL_METADATA)) { + hijack = true; + } + if (methods->QueryInterceptionHookPoint( + experimental::InterceptionHookPoints::PRE_SEND_MESSAGE)) { + if (++count_ > 10) { + methods->FailHijackedSendMessage(); + } + } + if (methods->QueryInterceptionHookPoint( + experimental::InterceptionHookPoints::POST_SEND_MESSAGE)) { + EXPECT_FALSE(got_failed_send_); + got_failed_send_ = !methods->GetSendMessageStatus(); + } + if (methods->QueryInterceptionHookPoint( + experimental::InterceptionHookPoints::PRE_RECV_STATUS)) { + auto* status = methods->GetRecvStatus(); + *status = Status(StatusCode::UNAVAILABLE, "Done sending 10 messages"); + } + if (hijack) { + methods->Hijack(); + } else { + methods->Proceed(); + } + } + + static bool GotFailedSend() { return got_failed_send_; } + + private: + experimental::ClientRpcInfo* info_; + int count_ = 0; + static bool got_failed_send_; +}; + +bool ClientStreamingRpcHijackingInterceptor::got_failed_send_ = false; + +class ClientStreamingRpcHijackingInterceptorFactory + : public experimental::ClientInterceptorFactoryInterface { + public: + virtual experimental::Interceptor* CreateClientInterceptor( + experimental::ClientRpcInfo* info) override { + return new ClientStreamingRpcHijackingInterceptor(info); + } +}; + +class ServerStreamingRpcHijackingInterceptor + : public experimental::Interceptor { + public: + ServerStreamingRpcHijackingInterceptor(experimental::ClientRpcInfo* info) { + info_ = info; + } + + virtual void Intercept(experimental::InterceptorBatchMethods* methods) { + bool hijack = false; + if (methods->QueryInterceptionHookPoint( + experimental::InterceptionHookPoints::PRE_SEND_INITIAL_METADATA)) { + auto* map = methods->GetSendInitialMetadata(); + // Check that we can see the test metadata + ASSERT_EQ(map->size(), static_cast(1)); + auto iterator = map->begin(); + EXPECT_EQ("testkey", iterator->first); + EXPECT_EQ("testvalue", iterator->second); + hijack = true; + } + if (methods->QueryInterceptionHookPoint( + experimental::InterceptionHookPoints::PRE_SEND_MESSAGE)) { + EchoRequest req; + auto* buffer = methods->GetSerializedSendMessage(); + auto copied_buffer = *buffer; + EXPECT_TRUE( + SerializationTraits::Deserialize(&copied_buffer, &req) + .ok()); + EXPECT_EQ(req.message(), "Hello"); + } + if (methods->QueryInterceptionHookPoint( + experimental::InterceptionHookPoints::PRE_SEND_CLOSE)) { + // Got nothing to do here for now + } + if (methods->QueryInterceptionHookPoint( + experimental::InterceptionHookPoints::POST_RECV_STATUS)) { + auto* map = methods->GetRecvTrailingMetadata(); + bool found = false; + // Check that we received the metadata as an echo + for (const auto& pair : *map) { + found = pair.first.starts_with("testkey") && + pair.second.starts_with("testvalue"); + if (found) break; + } + EXPECT_EQ(found, true); + auto* status = methods->GetRecvStatus(); + EXPECT_EQ(status->ok(), true); + } + if (methods->QueryInterceptionHookPoint( + experimental::InterceptionHookPoints::PRE_RECV_MESSAGE)) { + if (++count_ > 10) { + methods->FailHijackedRecvMessage(); + } + EchoResponse* resp = + static_cast(methods->GetRecvMessage()); + resp->set_message("Hello"); + } + if (methods->QueryInterceptionHookPoint( + experimental::InterceptionHookPoints::POST_RECV_MESSAGE)) { + // Only the last message will be a failure + EXPECT_FALSE(got_failed_message_); + got_failed_message_ = methods->GetRecvMessage() == nullptr; + } + if (methods->QueryInterceptionHookPoint( + experimental::InterceptionHookPoints::PRE_RECV_STATUS)) { + auto* map = methods->GetRecvTrailingMetadata(); + // insert the metadata that we want + EXPECT_EQ(map->size(), static_cast(0)); + map->insert(std::make_pair("testkey", "testvalue")); + auto* status = methods->GetRecvStatus(); + *status = Status(StatusCode::OK, ""); + } + if (hijack) { + methods->Hijack(); + } else { + methods->Proceed(); + } + } + + static bool GotFailedMessage() { return got_failed_message_; } + + private: + experimental::ClientRpcInfo* info_; + static bool got_failed_message_; + int count_ = 0; +}; + +bool ServerStreamingRpcHijackingInterceptor::got_failed_message_ = false; + +class ServerStreamingRpcHijackingInterceptorFactory + : public experimental::ClientInterceptorFactoryInterface { + public: + virtual experimental::Interceptor* CreateClientInterceptor( + experimental::ClientRpcInfo* info) override { + return new ServerStreamingRpcHijackingInterceptor(info); + } +}; + +class BidiStreamingRpcHijackingInterceptorFactory + : public experimental::ClientInterceptorFactoryInterface { + public: + virtual experimental::Interceptor* CreateClientInterceptor( + experimental::ClientRpcInfo* info) override { + return new BidiStreamingRpcHijackingInterceptor(info); + } +}; + class LoggingInterceptor : public experimental::Interceptor { public: LoggingInterceptor(experimental::ClientRpcInfo* info) { info_ = info; } @@ -286,12 +516,16 @@ class LoggingInterceptor : public experimental::Interceptor { if (methods->QueryInterceptionHookPoint( experimental::InterceptionHookPoints::PRE_SEND_MESSAGE)) { EchoRequest req; - auto* buffer = methods->GetSendMessage(); + EXPECT_EQ(static_cast(methods->GetSendMessage()) + ->message() + .find("Hello"), + 0u); + auto* buffer = methods->GetSerializedSendMessage(); auto copied_buffer = *buffer; EXPECT_TRUE( SerializationTraits::Deserialize(&copied_buffer, &req) .ok()); - EXPECT_TRUE(req.message().find("Hello") == 0); + EXPECT_TRUE(req.message().find("Hello") == 0u); } if (methods->QueryInterceptionHookPoint( experimental::InterceptionHookPoints::PRE_SEND_CLOSE)) { @@ -307,7 +541,7 @@ class LoggingInterceptor : public experimental::Interceptor { experimental::InterceptionHookPoints::POST_RECV_MESSAGE)) { EchoResponse* resp = static_cast(methods->GetRecvMessage()); - EXPECT_TRUE(resp->message().find("Hello") == 0); + EXPECT_TRUE(resp->message().find("Hello") == 0u); } if (methods->QueryInterceptionHookPoint( experimental::InterceptionHookPoints::POST_RECV_STATUS)) { @@ -377,12 +611,25 @@ TEST_F(ClientInterceptorsEnd2endTest, ClientInterceptorLoggingTest) { EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 20); } +TEST_F(ClientInterceptorsEnd2endTest, + LameChannelClientInterceptorHijackingTest) { + ChannelArguments args; + std::vector> + creators; + creators.push_back(std::unique_ptr( + new HijackingInterceptorFactory())); + auto channel = experimental::CreateCustomChannelWithInterceptors( + server_address_, nullptr, args, std::move(creators)); + MakeCall(channel); +} + TEST_F(ClientInterceptorsEnd2endTest, ClientInterceptorHijackingTest) { ChannelArguments args; DummyInterceptor::Reset(); std::vector> creators; // Add 20 dummy interceptors before hijacking interceptor + creators.reserve(20); for (auto i = 0; i < 20; i++) { creators.push_back(std::unique_ptr( new DummyInterceptorFactory())); @@ -423,6 +670,7 @@ TEST_F(ClientInterceptorsEnd2endTest, std::vector> creators; // Add 5 dummy interceptors before hijacking interceptor + creators.reserve(5); for (auto i = 0; i < 5; i++) { creators.push_back(std::unique_ptr( new DummyInterceptorFactory())); @@ -464,6 +712,28 @@ TEST_F(ClientInterceptorsEnd2endTest, EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 20); } +TEST_F(ClientInterceptorsEnd2endTest, + ClientInterceptorFactoryAllowsNullptrReturn) { + ChannelArguments args; + DummyInterceptor::Reset(); + std::vector> + creators; + creators.push_back(std::unique_ptr( + new LoggingInterceptorFactory())); + // Add 20 dummy interceptors and 20 null interceptors + for (auto i = 0; i < 20; i++) { + creators.push_back(std::unique_ptr( + new DummyInterceptorFactory())); + creators.push_back( + std::unique_ptr(new NullInterceptorFactory())); + } + auto channel = server_->experimental().InProcessChannelWithInterceptors( + args, std::move(creators)); + MakeCallbackCall(channel); + // Make sure all 20 dummy interceptors were run + EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 20); +} + class ClientInterceptorsStreamingEnd2endTest : public ::testing::Test { protected: ClientInterceptorsStreamingEnd2endTest() { @@ -521,6 +791,62 @@ TEST_F(ClientInterceptorsStreamingEnd2endTest, ServerStreamingTest) { EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 20); } +TEST_F(ClientInterceptorsStreamingEnd2endTest, ClientStreamingHijackingTest) { + ChannelArguments args; + std::vector> + creators; + creators.push_back( + std::unique_ptr( + new ClientStreamingRpcHijackingInterceptorFactory())); + auto channel = experimental::CreateCustomChannelWithInterceptors( + server_address_, InsecureChannelCredentials(), args, std::move(creators)); + + auto stub = grpc::testing::EchoTestService::NewStub(channel); + ClientContext ctx; + EchoRequest req; + EchoResponse resp; + req.mutable_param()->set_echo_metadata(true); + req.set_message("Hello"); + string expected_resp = ""; + auto writer = stub->RequestStream(&ctx, &resp); + for (int i = 0; i < 10; i++) { + EXPECT_TRUE(writer->Write(req)); + expected_resp += "Hello"; + } + // The interceptor will reject the 11th message + writer->Write(req); + Status s = writer->Finish(); + EXPECT_EQ(s.ok(), false); + EXPECT_TRUE(ClientStreamingRpcHijackingInterceptor::GotFailedSend()); +} + +TEST_F(ClientInterceptorsStreamingEnd2endTest, ServerStreamingHijackingTest) { + ChannelArguments args; + DummyInterceptor::Reset(); + std::vector> + creators; + creators.push_back( + std::unique_ptr( + new ServerStreamingRpcHijackingInterceptorFactory())); + auto channel = experimental::CreateCustomChannelWithInterceptors( + server_address_, InsecureChannelCredentials(), args, std::move(creators)); + MakeServerStreamingCall(channel); + EXPECT_TRUE(ServerStreamingRpcHijackingInterceptor::GotFailedMessage()); +} + +TEST_F(ClientInterceptorsStreamingEnd2endTest, BidiStreamingHijackingTest) { + ChannelArguments args; + DummyInterceptor::Reset(); + std::vector> + creators; + creators.push_back( + std::unique_ptr( + new BidiStreamingRpcHijackingInterceptorFactory())); + auto channel = experimental::CreateCustomChannelWithInterceptors( + server_address_, InsecureChannelCredentials(), args, std::move(creators)); + MakeBidiStreamingCall(channel); +} + TEST_F(ClientInterceptorsStreamingEnd2endTest, BidiStreamingTest) { ChannelArguments args; DummyInterceptor::Reset(); @@ -570,6 +896,7 @@ TEST_F(ClientGlobalInterceptorEnd2endTest, DummyGlobalInterceptor) { std::vector> creators; // Add 20 dummy interceptors + creators.reserve(20); for (auto i = 0; i < 20; i++) { creators.push_back(std::unique_ptr( new DummyInterceptorFactory())); @@ -579,9 +906,7 @@ TEST_F(ClientGlobalInterceptorEnd2endTest, DummyGlobalInterceptor) { MakeCall(channel); // Make sure all 20 dummy interceptors were run with the global interceptor EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 21); - // Reset the global interceptor. This is again 'safe' because there are no - // other ongoing gRPC operations - experimental::RegisterGlobalClientInterceptorFactory(nullptr); + experimental::TestOnlyResetGlobalClientInterceptorFactory(); } TEST_F(ClientGlobalInterceptorEnd2endTest, LoggingGlobalInterceptor) { @@ -595,6 +920,7 @@ TEST_F(ClientGlobalInterceptorEnd2endTest, LoggingGlobalInterceptor) { std::vector> creators; // Add 20 dummy interceptors + creators.reserve(20); for (auto i = 0; i < 20; i++) { creators.push_back(std::unique_ptr( new DummyInterceptorFactory())); @@ -604,9 +930,7 @@ TEST_F(ClientGlobalInterceptorEnd2endTest, LoggingGlobalInterceptor) { MakeCall(channel); // Make sure all 20 dummy interceptors were run EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 20); - // Reset the global interceptor. This is again 'safe' because there are no - // other ongoing gRPC operations - experimental::RegisterGlobalClientInterceptorFactory(nullptr); + experimental::TestOnlyResetGlobalClientInterceptorFactory(); } TEST_F(ClientGlobalInterceptorEnd2endTest, HijackingGlobalInterceptor) { @@ -620,6 +944,7 @@ TEST_F(ClientGlobalInterceptorEnd2endTest, HijackingGlobalInterceptor) { std::vector> creators; // Add 20 dummy interceptors + creators.reserve(20); for (auto i = 0; i < 20; i++) { creators.push_back(std::unique_ptr( new DummyInterceptorFactory())); @@ -629,9 +954,7 @@ TEST_F(ClientGlobalInterceptorEnd2endTest, HijackingGlobalInterceptor) { MakeCall(channel); // Make sure all 20 dummy interceptors were run EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 20); - // Reset the global interceptor. This is again 'safe' because there are no - // other ongoing gRPC operations - experimental::RegisterGlobalClientInterceptorFactory(nullptr); + experimental::TestOnlyResetGlobalClientInterceptorFactory(); } } // namespace @@ -639,7 +962,7 @@ TEST_F(ClientGlobalInterceptorEnd2endTest, HijackingGlobalInterceptor) { } // namespace grpc int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index 312065a2dfe..b623348e13f 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -32,13 +33,17 @@ #include #include #include +#include #include #include +#include "src/core/ext/filters/client_channel/backup_poller.h" +#include "src/core/ext/filters/client_channel/global_subchannel_pool.h" +#include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h" -#include "src/core/ext/filters/client_channel/subchannel_index.h" +#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/backoff/backoff.h" -#include "src/core/lib/gpr/env.h" +#include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gprpp/debug_location.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/tcp_client.h" @@ -49,8 +54,10 @@ #include "src/proto/grpc/testing/echo.grpc.pb.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" +#include "test/core/util/test_lb_policies.h" #include "test/cpp/end2end/test_service_impl.h" +#include #include using grpc::testing::EchoRequest; @@ -92,34 +99,50 @@ class MyTestServiceImpl : public TestServiceImpl { Status Echo(ServerContext* context, const EchoRequest* request, EchoResponse* response) override { { - std::unique_lock lock(mu_); + grpc::internal::MutexLock lock(&mu_); ++request_count_; } + AddClient(context->peer()); return TestServiceImpl::Echo(context, request, response); } int request_count() { - std::unique_lock lock(mu_); + grpc::internal::MutexLock lock(&mu_); return request_count_; } void ResetCounters() { - std::unique_lock lock(mu_); + grpc::internal::MutexLock lock(&mu_); request_count_ = 0; } + std::set clients() { + grpc::internal::MutexLock lock(&clients_mu_); + return clients_; + } + private: - std::mutex mu_; + void AddClient(const grpc::string& client) { + grpc::internal::MutexLock lock(&clients_mu_); + clients_.insert(client); + } + + grpc::internal::Mutex mu_; int request_count_; + grpc::internal::Mutex clients_mu_; + std::set clients_; }; class ClientLbEnd2endTest : public ::testing::Test { protected: ClientLbEnd2endTest() - : server_host_("localhost"), kRequestMessage_("Live long and prosper.") { + : server_host_("localhost"), + kRequestMessage_("Live long and prosper."), + creds_(new SecureChannelCredentials( + grpc_fake_transport_security_credentials_create())) { // Make the backup poller poll very frequently in order to pick up // updates from all the subchannels's FDs. - gpr_setenv("GRPC_CLIENT_CHANNEL_BACKUP_POLL_INTERVAL_MS", "1"); + GPR_GLOBAL_CONFIG_SET(grpc_client_channel_backup_poll_interval_ms, 1); } void SetUp() override { @@ -132,7 +155,13 @@ class ClientLbEnd2endTest : public ::testing::Test { for (size_t i = 0; i < servers_.size(); ++i) { servers_[i]->Shutdown(); } - grpc_shutdown(); + // Explicitly destroy all the members so that we can make sure grpc_shutdown + // has finished by the end of this function, and thus all the registered + // LB policy factories are removed. + stub_.reset(); + servers_.clear(); + creds_.reset(); + grpc_shutdown_blocking(); } void CreateServers(size_t num_servers, @@ -155,40 +184,31 @@ class ClientLbEnd2endTest : public ::testing::Test { } } - grpc_channel_args* BuildFakeResults(const std::vector& ports) { - grpc_lb_addresses* addresses = - grpc_lb_addresses_create(ports.size(), nullptr); - for (size_t i = 0; i < ports.size(); ++i) { + grpc_core::Resolver::Result BuildFakeResults(const std::vector& ports) { + grpc_core::Resolver::Result result; + for (const int& port : ports) { char* lb_uri_str; - gpr_asprintf(&lb_uri_str, "ipv4:127.0.0.1:%d", ports[i]); + gpr_asprintf(&lb_uri_str, "ipv4:127.0.0.1:%d", port); grpc_uri* lb_uri = grpc_uri_parse(lb_uri_str, true); GPR_ASSERT(lb_uri != nullptr); - grpc_lb_addresses_set_address_from_uri(addresses, i, lb_uri, - false /* is balancer */, - "" /* balancer name */, nullptr); + grpc_resolved_address address; + GPR_ASSERT(grpc_parse_uri(lb_uri, &address)); + result.addresses.emplace_back(address.addr, address.len, + nullptr /* args */); grpc_uri_destroy(lb_uri); gpr_free(lb_uri_str); } - const grpc_arg fake_addresses = - grpc_lb_addresses_create_channel_arg(addresses); - grpc_channel_args* fake_results = - grpc_channel_args_copy_and_add(nullptr, &fake_addresses, 1); - grpc_lb_addresses_destroy(addresses); - return fake_results; + return result; } void SetNextResolution(const std::vector& ports) { grpc_core::ExecCtx exec_ctx; - grpc_channel_args* fake_results = BuildFakeResults(ports); - response_generator_->SetResponse(fake_results); - grpc_channel_args_destroy(fake_results); + response_generator_->SetResponse(BuildFakeResults(ports)); } void SetNextResolutionUponError(const std::vector& ports) { grpc_core::ExecCtx exec_ctx; - grpc_channel_args* fake_results = BuildFakeResults(ports); - response_generator_->SetReresolutionResponse(fake_results); - grpc_channel_args_destroy(fake_results); + response_generator_->SetReresolutionResponse(BuildFakeResults(ports)); } void SetFailureOnReresolution() { @@ -196,9 +216,11 @@ class ClientLbEnd2endTest : public ::testing::Test { response_generator_->SetFailureOnReresolution(); } - std::vector GetServersPorts() { + std::vector GetServersPorts(size_t start_index = 0) { std::vector ports; - for (const auto& server : servers_) ports.push_back(server->port_); + for (size_t i = start_index; i < servers_.size(); ++i) { + ports.push_back(servers_[i]->port_); + } return ports; } @@ -215,9 +237,7 @@ class ClientLbEnd2endTest : public ::testing::Test { } // else, default to pick first args.SetPointer(GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR, response_generator_.get()); - std::shared_ptr creds(new SecureChannelCredentials( - grpc_fake_transport_security_credentials_create())); - return CreateCustomChannel("fake:///", std::move(creds), args); + return ::grpc::CreateCustomChannel("fake:///", creds_, args); } bool SendRpc( @@ -265,6 +285,7 @@ class ClientLbEnd2endTest : public ::testing::Test { MyTestServiceImpl service_; std::unique_ptr thread_; bool server_ready_ = false; + bool started_ = false; explicit ServerData(int port = 0) { port_ = port > 0 ? port : grpc_pick_unused_port_or_die(); @@ -272,18 +293,19 @@ class ClientLbEnd2endTest : public ::testing::Test { void Start(const grpc::string& server_host) { gpr_log(GPR_INFO, "starting server on port %d", port_); - std::mutex mu; - std::unique_lock lock(mu); - std::condition_variable cond; + started_ = true; + grpc::internal::Mutex mu; + grpc::internal::MutexLock lock(&mu); + grpc::internal::CondVar cond; thread_.reset(new std::thread( std::bind(&ServerData::Serve, this, server_host, &mu, &cond))); - cond.wait(lock, [this] { return server_ready_; }); + cond.WaitUntil(&mu, [this] { return server_ready_; }); server_ready_ = false; gpr_log(GPR_INFO, "server startup complete"); } - void Serve(const grpc::string& server_host, std::mutex* mu, - std::condition_variable* cond) { + void Serve(const grpc::string& server_host, grpc::internal::Mutex* mu, + grpc::internal::CondVar* cond) { std::ostringstream server_address; server_address << server_host << ":" << port_; ServerBuilder builder; @@ -292,14 +314,16 @@ class ClientLbEnd2endTest : public ::testing::Test { builder.AddListeningPort(server_address.str(), std::move(creds)); builder.RegisterService(&service_); server_ = builder.BuildAndStart(); - std::lock_guard lock(*mu); + grpc::internal::MutexLock lock(mu); server_ready_ = true; - cond->notify_one(); + cond->Signal(); } - void Shutdown(bool join = true) { + void Shutdown() { + if (!started_) return; server_->Shutdown(grpc_timeout_milliseconds_to_deadline(0)); - if (join) thread_->join(); + thread_->join(); + started_ = false; } void SetServingStatus(const grpc::string& service, bool serving) { @@ -378,8 +402,30 @@ class ClientLbEnd2endTest : public ::testing::Test { grpc_core::RefCountedPtr response_generator_; const grpc::string kRequestMessage_; + std::shared_ptr creds_; }; +TEST_F(ClientLbEnd2endTest, ChannelStateConnectingWhenResolving) { + const int kNumServers = 3; + StartServers(kNumServers); + auto channel = BuildChannel(""); + auto stub = BuildStub(channel); + // Initial state should be IDLE. + EXPECT_EQ(channel->GetState(false /* try_to_connect */), GRPC_CHANNEL_IDLE); + // Tell the channel to try to connect. + // Note that this call also returns IDLE, since the state change has + // not yet occurred; it just gets triggered by this call. + EXPECT_EQ(channel->GetState(true /* try_to_connect */), GRPC_CHANNEL_IDLE); + // Now that the channel is trying to connect, we should be in state + // CONNECTING. + EXPECT_EQ(channel->GetState(false /* try_to_connect */), + GRPC_CHANNEL_CONNECTING); + // Return a resolver result, which allows the connection attempt to proceed. + SetNextResolution(GetServersPorts()); + // We should eventually transition into state READY. + EXPECT_TRUE(WaitForChannelReady(channel.get())); +} + TEST_F(ClientLbEnd2endTest, PickFirst) { // Start servers and send one RPC per server. const int kNumServers = 3; @@ -422,6 +468,30 @@ TEST_F(ClientLbEnd2endTest, PickFirstProcessPending) { CheckRpcSendOk(second_stub, DEBUG_LOCATION); } +TEST_F(ClientLbEnd2endTest, PickFirstSelectsReadyAtStartup) { + ChannelArguments args; + constexpr int kInitialBackOffMs = 5000; + args.SetInt(GRPC_ARG_INITIAL_RECONNECT_BACKOFF_MS, kInitialBackOffMs); + // Create 2 servers, but start only the second one. + std::vector ports = {grpc_pick_unused_port_or_die(), + grpc_pick_unused_port_or_die()}; + CreateServers(2, ports); + StartServer(1); + auto channel1 = BuildChannel("pick_first", args); + auto stub1 = BuildStub(channel1); + SetNextResolution(ports); + // Wait for second server to be ready. + WaitForServer(stub1, 1, DEBUG_LOCATION); + // Create a second channel with the same addresses. Its PF instance + // should immediately pick the second subchannel, since it's already + // in READY state. + auto channel2 = BuildChannel("pick_first", args); + SetNextResolution(ports); + // Check that the channel reports READY without waiting for the + // initial backoff. + EXPECT_TRUE(WaitForChannelReady(channel2.get(), 1 /* timeout_seconds */)); +} + TEST_F(ClientLbEnd2endTest, PickFirstBackOffInitialReconnect) { ChannelArguments args; constexpr int kInitialBackOffMs = 100; @@ -507,6 +577,51 @@ TEST_F(ClientLbEnd2endTest, PickFirstResetConnectionBackoff) { EXPECT_LT(waited_ms, kInitialBackOffMs); } +TEST_F(ClientLbEnd2endTest, + PickFirstResetConnectionBackoffNextAttemptStartsImmediately) { + ChannelArguments args; + constexpr int kInitialBackOffMs = 1000; + args.SetInt(GRPC_ARG_INITIAL_RECONNECT_BACKOFF_MS, kInitialBackOffMs); + const std::vector ports = {grpc_pick_unused_port_or_die()}; + auto channel = BuildChannel("pick_first", args); + auto stub = BuildStub(channel); + SetNextResolution(ports); + // Wait for connect, which should fail ~immediately, because the server + // is not up. + gpr_log(GPR_INFO, "=== INITIAL CONNECTION ATTEMPT"); + EXPECT_FALSE( + channel->WaitForConnected(grpc_timeout_milliseconds_to_deadline(10))); + // Reset connection backoff. + // Note that the time at which the third attempt will be started is + // actually computed at this point, so we record the start time here. + gpr_log(GPR_INFO, "=== RESETTING BACKOFF"); + const gpr_timespec t0 = gpr_now(GPR_CLOCK_MONOTONIC); + experimental::ChannelResetConnectionBackoff(channel.get()); + // Trigger a second connection attempt. This should also fail + // ~immediately, but the retry should be scheduled for + // kInitialBackOffMs instead of applying the multiplier. + gpr_log(GPR_INFO, "=== POLLING FOR SECOND CONNECTION ATTEMPT"); + EXPECT_FALSE( + channel->WaitForConnected(grpc_timeout_milliseconds_to_deadline(10))); + // Bring up a server on the chosen port. + gpr_log(GPR_INFO, "=== STARTING BACKEND"); + StartServers(1, ports); + // Wait for connect. Should happen within kInitialBackOffMs. + // Give an extra 100ms to account for the time spent in the second and + // third connection attempts themselves (since what we really want to + // measure is the time between the two). As long as this is less than + // the 1.6x increase we would see if the backoff state was not reset + // properly, the test is still proving that the backoff was reset. + constexpr int kWaitMs = kInitialBackOffMs + 100; + gpr_log(GPR_INFO, "=== POLLING FOR THIRD CONNECTION ATTEMPT"); + EXPECT_TRUE(channel->WaitForConnected( + grpc_timeout_milliseconds_to_deadline(kWaitMs))); + const gpr_timespec t1 = gpr_now(GPR_CLOCK_MONOTONIC); + const grpc_millis waited_ms = gpr_time_to_millis(gpr_time_sub(t1, t0)); + gpr_log(GPR_DEBUG, "Waited %" PRId64 " milliseconds", waited_ms); + EXPECT_LT(waited_ms, kWaitMs); +} + TEST_F(ClientLbEnd2endTest, PickFirstUpdates) { // Start servers and send one RPC per server. const int kNumServers = 3; @@ -587,30 +702,62 @@ TEST_F(ClientLbEnd2endTest, PickFirstUpdateSuperset) { EXPECT_EQ("pick_first", channel->GetLoadBalancingPolicyName()); } -class ClientLbEnd2endWithParamTest - : public ClientLbEnd2endTest, - public ::testing::WithParamInterface { - protected: - void SetUp() override { - grpc_subchannel_index_test_only_set_force_creation(GetParam()); - ClientLbEnd2endTest::SetUp(); - } +TEST_F(ClientLbEnd2endTest, PickFirstGlobalSubchannelPool) { + // Start one server. + const int kNumServers = 1; + StartServers(kNumServers); + std::vector ports = GetServersPorts(); + // Create two channels that (by default) use the global subchannel pool. + auto channel1 = BuildChannel("pick_first"); + auto stub1 = BuildStub(channel1); + SetNextResolution(ports); + auto channel2 = BuildChannel("pick_first"); + auto stub2 = BuildStub(channel2); + SetNextResolution(ports); + WaitForServer(stub1, 0, DEBUG_LOCATION); + // Send one RPC on each channel. + CheckRpcSendOk(stub1, DEBUG_LOCATION); + CheckRpcSendOk(stub2, DEBUG_LOCATION); + // The server receives two requests. + EXPECT_EQ(2, servers_[0]->service_.request_count()); + // The two requests are from the same client port, because the two channels + // share subchannels via the global subchannel pool. + EXPECT_EQ(1UL, servers_[0]->service_.clients().size()); +} - void TearDown() override { - ClientLbEnd2endTest::TearDown(); - grpc_subchannel_index_test_only_set_force_creation(false); - } -}; +TEST_F(ClientLbEnd2endTest, PickFirstLocalSubchannelPool) { + // Start one server. + const int kNumServers = 1; + StartServers(kNumServers); + std::vector ports = GetServersPorts(); + // Create two channels that use local subchannel pool. + ChannelArguments args; + args.SetInt(GRPC_ARG_USE_LOCAL_SUBCHANNEL_POOL, 1); + auto channel1 = BuildChannel("pick_first", args); + auto stub1 = BuildStub(channel1); + SetNextResolution(ports); + auto channel2 = BuildChannel("pick_first", args); + auto stub2 = BuildStub(channel2); + SetNextResolution(ports); + WaitForServer(stub1, 0, DEBUG_LOCATION); + // Send one RPC on each channel. + CheckRpcSendOk(stub1, DEBUG_LOCATION); + CheckRpcSendOk(stub2, DEBUG_LOCATION); + // The server receives two requests. + EXPECT_EQ(2, servers_[0]->service_.request_count()); + // The two requests are from two client ports, because the two channels didn't + // share subchannels with each other. + EXPECT_EQ(2UL, servers_[0]->service_.clients().size()); +} -TEST_P(ClientLbEnd2endWithParamTest, PickFirstManyUpdates) { - gpr_log(GPR_INFO, "subchannel force creation: %d", GetParam()); - // Start servers and send one RPC per server. +TEST_F(ClientLbEnd2endTest, PickFirstManyUpdates) { + const int kNumUpdates = 1000; const int kNumServers = 3; StartServers(kNumServers); auto channel = BuildChannel("pick_first"); auto stub = BuildStub(channel); std::vector ports = GetServersPorts(); - for (size_t i = 0; i < 1000; ++i) { + for (size_t i = 0; i < kNumUpdates; ++i) { std::shuffle(ports.begin(), ports.end(), std::mt19937(std::random_device()())); SetNextResolution(ports); @@ -622,9 +769,6 @@ TEST_P(ClientLbEnd2endWithParamTest, PickFirstManyUpdates) { EXPECT_EQ("pick_first", channel->GetLoadBalancingPolicyName()); } -INSTANTIATE_TEST_CASE_P(SubchannelForceCreation, ClientLbEnd2endWithParamTest, - ::testing::Bool()); - TEST_F(ClientLbEnd2endTest, PickFirstReresolutionNoSelected) { // Prepare the ports for up servers and down servers. const int kNumServers = 3; @@ -750,6 +894,79 @@ TEST_F(ClientLbEnd2endTest, PickFirstIdleOnDisconnect) { servers_.clear(); } +TEST_F(ClientLbEnd2endTest, PickFirstPendingUpdateAndSelectedSubchannelFails) { + auto channel = BuildChannel(""); // pick_first is the default. + auto stub = BuildStub(channel); + // Create a number of servers, but only start 1 of them. + CreateServers(10); + StartServer(0); + // Initially resolve to first server and make sure it connects. + gpr_log(GPR_INFO, "Phase 1: Connect to first server."); + SetNextResolution({servers_[0]->port_}); + CheckRpcSendOk(stub, DEBUG_LOCATION, true /* wait_for_ready */); + EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); + // Send a resolution update with the remaining servers, none of which are + // running yet, so the update will stay pending. Note that it's important + // to have multiple servers here, or else the test will be flaky; with only + // one server, the pending subchannel list has already gone into + // TRANSIENT_FAILURE due to hitting the end of the list by the time we + // check the state. + gpr_log(GPR_INFO, + "Phase 2: Resolver update pointing to remaining " + "(not started) servers."); + SetNextResolution(GetServersPorts(1 /* start_index */)); + // RPCs will continue to be sent to the first server. + CheckRpcSendOk(stub, DEBUG_LOCATION); + // Now stop the first server, so that the current subchannel list + // fails. This should cause us to immediately swap over to the + // pending list, even though it's not yet connected. The state should + // be set to CONNECTING, since that's what the pending subchannel list + // was doing when we swapped over. + gpr_log(GPR_INFO, "Phase 3: Stopping first server."); + servers_[0]->Shutdown(); + WaitForChannelNotReady(channel.get()); + // TODO(roth): This should always return CONNECTING, but it's flaky + // between that and TRANSIENT_FAILURE. I suspect that this problem + // will go away once we move the backoff code out of the subchannel + // and into the LB policies. + EXPECT_THAT(channel->GetState(false), + ::testing::AnyOf(GRPC_CHANNEL_CONNECTING, + GRPC_CHANNEL_TRANSIENT_FAILURE)); + // Now start the second server. + gpr_log(GPR_INFO, "Phase 4: Starting second server."); + StartServer(1); + // The channel should go to READY state and RPCs should go to the + // second server. + WaitForChannelReady(channel.get()); + WaitForServer(stub, 1, DEBUG_LOCATION, true /* ignore_failure */); +} + +TEST_F(ClientLbEnd2endTest, PickFirstStaysIdleUponEmptyUpdate) { + // Start server, send RPC, and make sure channel is READY. + const int kNumServers = 1; + StartServers(kNumServers); + auto channel = BuildChannel(""); // pick_first is the default. + auto stub = BuildStub(channel); + SetNextResolution(GetServersPorts()); + CheckRpcSendOk(stub, DEBUG_LOCATION); + EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); + // Stop server. Channel should go into state IDLE. + servers_[0]->Shutdown(); + EXPECT_TRUE(WaitForChannelNotReady(channel.get())); + EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_IDLE); + // Now send resolver update that includes no addresses. Channel + // should stay in state IDLE. + SetNextResolution({}); + EXPECT_FALSE(channel->WaitForStateChange( + GRPC_CHANNEL_IDLE, grpc_timeout_seconds_to_deadline(3))); + // Now bring the backend back up and send a non-empty resolver update, + // and then try to send an RPC. Channel should go back into state READY. + StartServer(0); + SetNextResolution(GetServersPorts()); + CheckRpcSendOk(stub, DEBUG_LOCATION); + EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); +} + TEST_F(ClientLbEnd2endTest, RoundRobin) { // Start servers and send one RPC per server. const int kNumServers = 3; @@ -802,8 +1019,8 @@ TEST_F(ClientLbEnd2endTest, RoundRobinUpdates) { auto channel = BuildChannel("round_robin"); auto stub = BuildStub(channel); std::vector ports; - // Start with a single server. + gpr_log(GPR_INFO, "*** FIRST BACKEND ***"); ports.emplace_back(servers_[0]->port_); SetNextResolution(ports); WaitForServer(stub, 0, DEBUG_LOCATION); @@ -813,36 +1030,33 @@ TEST_F(ClientLbEnd2endTest, RoundRobinUpdates) { EXPECT_EQ(0, servers_[1]->service_.request_count()); EXPECT_EQ(0, servers_[2]->service_.request_count()); servers_[0]->service_.ResetCounters(); - // And now for the second server. + gpr_log(GPR_INFO, "*** SECOND BACKEND ***"); ports.clear(); ports.emplace_back(servers_[1]->port_); SetNextResolution(ports); - // Wait until update has been processed, as signaled by the second backend // receiving a request. EXPECT_EQ(0, servers_[1]->service_.request_count()); WaitForServer(stub, 1, DEBUG_LOCATION); - for (size_t i = 0; i < 10; ++i) CheckRpcSendOk(stub, DEBUG_LOCATION); EXPECT_EQ(0, servers_[0]->service_.request_count()); EXPECT_EQ(10, servers_[1]->service_.request_count()); EXPECT_EQ(0, servers_[2]->service_.request_count()); servers_[1]->service_.ResetCounters(); - // ... and for the last server. + gpr_log(GPR_INFO, "*** THIRD BACKEND ***"); ports.clear(); ports.emplace_back(servers_[2]->port_); SetNextResolution(ports); WaitForServer(stub, 2, DEBUG_LOCATION); - for (size_t i = 0; i < 10; ++i) CheckRpcSendOk(stub, DEBUG_LOCATION); EXPECT_EQ(0, servers_[0]->service_.request_count()); EXPECT_EQ(0, servers_[1]->service_.request_count()); EXPECT_EQ(10, servers_[2]->service_.request_count()); servers_[2]->service_.ResetCounters(); - // Back to all servers. + gpr_log(GPR_INFO, "*** ALL BACKENDS ***"); ports.clear(); ports.emplace_back(servers_[0]->port_); ports.emplace_back(servers_[1]->port_); @@ -851,14 +1065,13 @@ TEST_F(ClientLbEnd2endTest, RoundRobinUpdates) { WaitForServer(stub, 0, DEBUG_LOCATION); WaitForServer(stub, 1, DEBUG_LOCATION); WaitForServer(stub, 2, DEBUG_LOCATION); - // Send three RPCs, one per server. for (size_t i = 0; i < 3; ++i) CheckRpcSendOk(stub, DEBUG_LOCATION); EXPECT_EQ(1, servers_[0]->service_.request_count()); EXPECT_EQ(1, servers_[1]->service_.request_count()); EXPECT_EQ(1, servers_[2]->service_.request_count()); - // An empty update will result in the channel going into TRANSIENT_FAILURE. + gpr_log(GPR_INFO, "*** NO BACKENDS ***"); ports.clear(); SetNextResolution(ports); grpc_connectivity_state channel_state; @@ -867,15 +1080,14 @@ TEST_F(ClientLbEnd2endTest, RoundRobinUpdates) { } while (channel_state == GRPC_CHANNEL_READY); ASSERT_NE(channel_state, GRPC_CHANNEL_READY); servers_[0]->service_.ResetCounters(); - // Next update introduces servers_[1], making the channel recover. + gpr_log(GPR_INFO, "*** BACK TO SECOND BACKEND ***"); ports.clear(); ports.emplace_back(servers_[1]->port_); SetNextResolution(ports); WaitForServer(stub, 1, DEBUG_LOCATION); channel_state = channel->GetState(false /* try to connect */); ASSERT_EQ(channel_state, GRPC_CHANNEL_READY); - // Check LB policy name for the channel. EXPECT_EQ("round_robin", channel->GetLoadBalancingPolicyName()); } @@ -899,7 +1111,7 @@ TEST_F(ClientLbEnd2endTest, RoundRobinUpdateInError) { servers_[0]->service_.ResetCounters(); // Shutdown one of the servers to be sent in the update. - servers_[1]->Shutdown(false); + servers_[1]->Shutdown(); ports.emplace_back(servers_[1]->port_); ports.emplace_back(servers_[2]->port_); SetNextResolution(ports); @@ -958,7 +1170,7 @@ TEST_F(ClientLbEnd2endTest, RoundRobinReresolve) { // Kill all servers gpr_log(GPR_INFO, "****** ABOUT TO KILL SERVERS *******"); for (size_t i = 0; i < servers_.size(); ++i) { - servers_[i]->Shutdown(true); + servers_[i]->Shutdown(); } gpr_log(GPR_INFO, "****** SERVERS KILLED *******"); gpr_log(GPR_INFO, "****** SENDING DOOMED REQUESTS *******"); @@ -994,8 +1206,9 @@ TEST_F(ClientLbEnd2endTest, RoundRobinSingleReconnect) { auto channel = BuildChannel("round_robin"); auto stub = BuildStub(channel); SetNextResolution(ports); - for (size_t i = 0; i < kNumServers; ++i) + for (size_t i = 0; i < kNumServers; ++i) { WaitForServer(stub, i, DEBUG_LOCATION); + } for (size_t i = 0; i < servers_.size(); ++i) { CheckRpcSendOk(stub, DEBUG_LOCATION); EXPECT_EQ(1, servers_[i]->service_.request_count()) << "for backend #" << i; @@ -1006,7 +1219,7 @@ TEST_F(ClientLbEnd2endTest, RoundRobinSingleReconnect) { } const auto pre_death = servers_[0]->service_.request_count(); // Kill the first server. - servers_[0]->Shutdown(true); + servers_[0]->Shutdown(); // Client request still succeed. May need retrying if RR had returned a pick // before noticing the change in the server's connectivity. while (!SendRpc(stub)) { @@ -1019,7 +1232,6 @@ TEST_F(ClientLbEnd2endTest, RoundRobinSingleReconnect) { // No requests have gone to the deceased server. EXPECT_EQ(pre_death, post_death); // Bring the first server back up. - servers_[0].reset(new ServerData(ports[0])); StartServer(0); // Requests should start arriving at the first server either right away (if // the server managed to start before the RR policy retried the subchannel) or @@ -1143,17 +1355,138 @@ TEST_F(ClientLbEnd2endTest, RoundRobinWithHealthCheckingInhibitPerChannel) { // Second channel should be READY. EXPECT_TRUE(WaitForChannelReady(channel2.get(), 1)); CheckRpcSendOk(stub2, DEBUG_LOCATION); + // Enable health checks on the backend and wait for channel 1 to succeed. + servers_[0]->SetServingStatus("health_check_service_name", true); + CheckRpcSendOk(stub1, DEBUG_LOCATION, true /* wait_for_ready */); + // Check that we created only one subchannel to the backend. + EXPECT_EQ(1UL, servers_[0]->service_.clients().size()); // Clean up. EnableDefaultHealthCheckService(false); } +TEST_F(ClientLbEnd2endTest, RoundRobinWithHealthCheckingServiceNamePerChannel) { + EnableDefaultHealthCheckService(true); + // Start server. + const int kNumServers = 1; + StartServers(kNumServers); + // Create a channel with health-checking enabled. + ChannelArguments args; + args.SetServiceConfigJSON( + "{\"healthCheckConfig\": " + "{\"serviceName\": \"health_check_service_name\"}}"); + auto channel1 = BuildChannel("round_robin", args); + auto stub1 = BuildStub(channel1); + std::vector ports = GetServersPorts(); + SetNextResolution(ports); + // Create a channel with health-checking enabled with a different + // service name. + ChannelArguments args2; + args2.SetServiceConfigJSON( + "{\"healthCheckConfig\": " + "{\"serviceName\": \"health_check_service_name2\"}}"); + auto channel2 = BuildChannel("round_robin", args2); + auto stub2 = BuildStub(channel2); + SetNextResolution(ports); + // Allow health checks from channel 2 to succeed. + servers_[0]->SetServingStatus("health_check_service_name2", true); + // First channel should not become READY, because health checks should be + // failing. + EXPECT_FALSE(WaitForChannelReady(channel1.get(), 1)); + CheckRpcSendFailure(stub1); + // Second channel should be READY. + EXPECT_TRUE(WaitForChannelReady(channel2.get(), 1)); + CheckRpcSendOk(stub2, DEBUG_LOCATION); + // Enable health checks for channel 1 and wait for it to succeed. + servers_[0]->SetServingStatus("health_check_service_name", true); + CheckRpcSendOk(stub1, DEBUG_LOCATION, true /* wait_for_ready */); + // Check that we created only one subchannel to the backend. + EXPECT_EQ(1UL, servers_[0]->service_.clients().size()); + // Clean up. + EnableDefaultHealthCheckService(false); +} + +class ClientLbInterceptTrailingMetadataTest : public ClientLbEnd2endTest { + protected: + void SetUp() override { + ClientLbEnd2endTest::SetUp(); + grpc_core::RegisterInterceptRecvTrailingMetadataLoadBalancingPolicy( + ReportTrailerIntercepted, this); + } + + void TearDown() override { ClientLbEnd2endTest::TearDown(); } + + int trailers_intercepted() { + grpc::internal::MutexLock lock(&mu_); + return trailers_intercepted_; + } + + private: + static void ReportTrailerIntercepted(void* arg) { + ClientLbInterceptTrailingMetadataTest* self = + static_cast(arg); + grpc::internal::MutexLock lock(&self->mu_); + self->trailers_intercepted_++; + } + + grpc::internal::Mutex mu_; + int trailers_intercepted_ = 0; +}; + +TEST_F(ClientLbInterceptTrailingMetadataTest, InterceptsRetriesDisabled) { + const int kNumServers = 1; + const int kNumRpcs = 10; + StartServers(kNumServers); + auto channel = BuildChannel("intercept_trailing_metadata_lb"); + auto stub = BuildStub(channel); + SetNextResolution(GetServersPorts()); + for (size_t i = 0; i < kNumRpcs; ++i) { + CheckRpcSendOk(stub, DEBUG_LOCATION); + } + // Check LB policy name for the channel. + EXPECT_EQ("intercept_trailing_metadata_lb", + channel->GetLoadBalancingPolicyName()); + EXPECT_EQ(kNumRpcs, trailers_intercepted()); +} + +TEST_F(ClientLbInterceptTrailingMetadataTest, InterceptsRetriesEnabled) { + const int kNumServers = 1; + const int kNumRpcs = 10; + StartServers(kNumServers); + ChannelArguments args; + args.SetServiceConfigJSON( + "{\n" + " \"methodConfig\": [ {\n" + " \"name\": [\n" + " { \"service\": \"grpc.testing.EchoTestService\" }\n" + " ],\n" + " \"retryPolicy\": {\n" + " \"maxAttempts\": 3,\n" + " \"initialBackoff\": \"1s\",\n" + " \"maxBackoff\": \"120s\",\n" + " \"backoffMultiplier\": 1.6,\n" + " \"retryableStatusCodes\": [ \"ABORTED\" ]\n" + " }\n" + " } ]\n" + "}"); + auto channel = BuildChannel("intercept_trailing_metadata_lb", args); + auto stub = BuildStub(channel); + SetNextResolution(GetServersPorts()); + for (size_t i = 0; i < kNumRpcs; ++i) { + CheckRpcSendOk(stub, DEBUG_LOCATION); + } + // Check LB policy name for the channel. + EXPECT_EQ("intercept_trailing_metadata_lb", + channel->GetLoadBalancingPolicyName()); + EXPECT_EQ(kNumRpcs, trailers_intercepted()); +} + } // namespace } // namespace testing } // namespace grpc int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); const auto result = RUN_ALL_TESTS(); return result; } diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc index 03291e1785c..e5dc88ae6d7 100644 --- a/test/cpp/end2end/end2end_test.cc +++ b/test/cpp/end2end/end2end_test.cc @@ -34,7 +34,9 @@ #include #include +#include "src/core/ext/filters/client_channel/backup_poller.h" #include "src/core/lib/gpr/env.h" +#include "src/core/lib/iomgr/iomgr.h" #include "src/core/lib/security/credentials/credentials.h" #include "src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h" #include "src/proto/grpc/testing/echo.grpc.pb.h" @@ -52,6 +54,17 @@ using grpc::testing::EchoResponse; using grpc::testing::kTlsCredentialsType; using std::chrono::system_clock; +// MAYBE_SKIP_TEST is a macro to determine if this particular test configuration +// should be skipped based on a decision made at SetUp time. In particular, +// tests that use the callback server can only be run if the iomgr can run in +// the background or if the transport is in-process. +#define MAYBE_SKIP_TEST \ + do { \ + if (do_not_test_) { \ + return; \ + } \ + } while (0) + namespace grpc { namespace testing { namespace { @@ -117,7 +130,7 @@ class TestAuthMetadataProcessor : public AuthMetadataProcessor { TestAuthMetadataProcessor(bool is_blocking) : is_blocking_(is_blocking) {} std::shared_ptr GetCompatibleClientCreds() { - return MetadataCredentialsFromPlugin( + return grpc::MetadataCredentialsFromPlugin( std::unique_ptr( new TestMetadataCredentialsPlugin( TestMetadataCredentialsPlugin::kGoodMetadataKey, kGoodGuy, @@ -125,7 +138,7 @@ class TestAuthMetadataProcessor : public AuthMetadataProcessor { } std::shared_ptr GetIncompatibleClientCreds() { - return MetadataCredentialsFromPlugin( + return grpc::MetadataCredentialsFromPlugin( std::unique_ptr( new TestMetadataCredentialsPlugin( TestMetadataCredentialsPlugin::kGoodMetadataKey, "Mr Hyde", @@ -196,16 +209,18 @@ class TestServiceImplDupPkg class TestScenario { public: TestScenario(bool interceptors, bool proxy, bool inproc_stub, - const grpc::string& creds_type) + const grpc::string& creds_type, bool use_callback_server) : use_interceptors(interceptors), use_proxy(proxy), inproc(inproc_stub), - credentials_type(creds_type) {} + credentials_type(creds_type), + callback_server(use_callback_server) {} void Log() const; bool use_interceptors; bool use_proxy; bool inproc; const grpc::string credentials_type; + bool callback_server; }; static std::ostream& operator<<(std::ostream& out, @@ -214,6 +229,8 @@ static std::ostream& operator<<(std::ostream& out, << (scenario.use_interceptors ? "true" : "false") << ", use_proxy=" << (scenario.use_proxy ? "true" : "false") << ", inproc=" << (scenario.inproc ? "true" : "false") + << ", server_type=" + << (scenario.callback_server ? "callback" : "sync") << ", credentials='" << scenario.credentials_type << "'}"; } @@ -233,6 +250,14 @@ class End2endTest : public ::testing::TestWithParam { GetParam().Log(); } + void SetUp() override { + if (GetParam().callback_server && !GetParam().inproc && + !grpc_iomgr_run_in_background()) { + do_not_test_ = true; + return; + } + } + void TearDown() override { if (is_server_started_) { server_->Shutdown(); @@ -280,7 +305,11 @@ class End2endTest : public ::testing::TestWithParam { builder.experimental().SetInterceptorCreators(std::move(creators)); } builder.AddListeningPort(server_address_.str(), server_creds); - builder.RegisterService(&service_); + if (!GetParam().callback_server) { + builder.RegisterService(&service_); + } else { + builder.RegisterService(&callback_service_); + } builder.RegisterService("foo.test.youtube.com", &special_service_); builder.RegisterService(&dup_pkg_service_); @@ -312,8 +341,8 @@ class End2endTest : public ::testing::TestWithParam { if (!GetParam().inproc) { if (!GetParam().use_interceptors) { - channel_ = - CreateCustomChannel(server_address_.str(), channel_creds, args); + channel_ = ::grpc::CreateCustomChannel(server_address_.str(), + channel_creds, args); } else { channel_ = CreateCustomChannelWithInterceptors( server_address_.str(), channel_creds, args, @@ -346,13 +375,15 @@ class End2endTest : public ::testing::TestWithParam { proxy_server_ = builder.BuildAndStart(); - channel_ = CreateChannel(proxyaddr.str(), InsecureChannelCredentials()); + channel_ = + grpc::CreateChannel(proxyaddr.str(), InsecureChannelCredentials()); } stub_ = grpc::testing::EchoTestService::NewStub(channel_); DummyInterceptor::Reset(); } + bool do_not_test_{false}; bool is_server_started_; std::shared_ptr channel_; std::unique_ptr stub_; @@ -362,6 +393,7 @@ class End2endTest : public ::testing::TestWithParam { std::ostringstream server_address_; const int kMaxMessageSize_; TestServiceImpl service_; + CallbackTestServiceImpl callback_service_; TestServiceImpl special_service_; TestServiceImplDupPkg dup_pkg_service_; grpc::string user_agent_prefix_; @@ -407,6 +439,7 @@ class End2endServerTryCancelTest : public End2endTest { // NOTE: Do not call this function with server_try_cancel == DO_NOT_CANCEL. void TestRequestStreamServerCancel( ServerTryCancelRequestPhase server_try_cancel, int num_msgs_to_send) { + MAYBE_SKIP_TEST; RestartServer(std::shared_ptr()); ResetStub(); EchoRequest request; @@ -485,6 +518,7 @@ class End2endServerTryCancelTest : public End2endTest { // NOTE: Do not call this function with server_try_cancel == DO_NOT_CANCEL. void TestResponseStreamServerCancel( ServerTryCancelRequestPhase server_try_cancel) { + MAYBE_SKIP_TEST; RestartServer(std::shared_ptr()); ResetStub(); EchoRequest request; @@ -566,6 +600,7 @@ class End2endServerTryCancelTest : public End2endTest { // NOTE: Do not call this function with server_try_cancel == DO_NOT_CANCEL. void TestBidiStreamServerCancel(ServerTryCancelRequestPhase server_try_cancel, int num_messages) { + MAYBE_SKIP_TEST; RestartServer(std::shared_ptr()); ResetStub(); EchoRequest request; @@ -641,6 +676,7 @@ class End2endServerTryCancelTest : public End2endTest { }; TEST_P(End2endServerTryCancelTest, RequestEchoServerCancel) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -703,6 +739,7 @@ TEST_P(End2endServerTryCancelTest, BidiStreamServerCancelAfter) { } TEST_P(End2endTest, SimpleRpcWithCustomUserAgentPrefix) { + MAYBE_SKIP_TEST; // User-Agent is an HTTP header for HTTP transports only if (GetParam().inproc) { return; @@ -726,6 +763,7 @@ TEST_P(End2endTest, SimpleRpcWithCustomUserAgentPrefix) { } TEST_P(End2endTest, MultipleRpcsWithVariedBinaryMetadataValue) { + MAYBE_SKIP_TEST; ResetStub(); std::vector threads; threads.reserve(10); @@ -738,6 +776,7 @@ TEST_P(End2endTest, MultipleRpcsWithVariedBinaryMetadataValue) { } TEST_P(End2endTest, MultipleRpcs) { + MAYBE_SKIP_TEST; ResetStub(); std::vector threads; threads.reserve(10); @@ -749,7 +788,21 @@ TEST_P(End2endTest, MultipleRpcs) { } } +TEST_P(End2endTest, EmptyBinaryMetadata) { + MAYBE_SKIP_TEST; + ResetStub(); + EchoRequest request; + EchoResponse response; + request.set_message("Hello hello hello hello"); + ClientContext context; + context.AddMetadata("custom-bin", ""); + Status s = stub_->Echo(&context, request, &response); + EXPECT_EQ(response.message(), request.message()); + EXPECT_TRUE(s.ok()); +} + TEST_P(End2endTest, ReconnectChannel) { + MAYBE_SKIP_TEST; if (GetParam().inproc) { return; } @@ -775,6 +828,7 @@ TEST_P(End2endTest, ReconnectChannel) { } TEST_P(End2endTest, RequestStreamOneRequest) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -791,6 +845,7 @@ TEST_P(End2endTest, RequestStreamOneRequest) { } TEST_P(End2endTest, RequestStreamOneRequestWithCoalescingApi) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -806,6 +861,7 @@ TEST_P(End2endTest, RequestStreamOneRequestWithCoalescingApi) { } TEST_P(End2endTest, RequestStreamTwoRequests) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -822,6 +878,7 @@ TEST_P(End2endTest, RequestStreamTwoRequests) { } TEST_P(End2endTest, RequestStreamTwoRequestsWithWriteThrough) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -838,6 +895,7 @@ TEST_P(End2endTest, RequestStreamTwoRequestsWithWriteThrough) { } TEST_P(End2endTest, RequestStreamTwoRequestsWithCoalescingApi) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -854,6 +912,7 @@ TEST_P(End2endTest, RequestStreamTwoRequestsWithCoalescingApi) { } TEST_P(End2endTest, ResponseStream) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -872,6 +931,7 @@ TEST_P(End2endTest, ResponseStream) { } TEST_P(End2endTest, ResponseStreamWithCoalescingApi) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -893,6 +953,7 @@ TEST_P(End2endTest, ResponseStreamWithCoalescingApi) { // This was added to prevent regression from issue: // https://github.com/grpc/grpc/issues/11546 TEST_P(End2endTest, ResponseStreamWithEverythingCoalesced) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -914,6 +975,7 @@ TEST_P(End2endTest, ResponseStreamWithEverythingCoalesced) { } TEST_P(End2endTest, BidiStream) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -938,6 +1000,7 @@ TEST_P(End2endTest, BidiStream) { } TEST_P(End2endTest, BidiStreamWithCoalescingApi) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -973,6 +1036,7 @@ TEST_P(End2endTest, BidiStreamWithCoalescingApi) { // This was added to prevent regression from issue: // https://github.com/grpc/grpc/issues/11546 TEST_P(End2endTest, BidiStreamWithEverythingCoalesced) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -998,6 +1062,7 @@ TEST_P(End2endTest, BidiStreamWithEverythingCoalesced) { // Talk to the two services with the same name but different package names. // The two stubs are created on the same channel. TEST_P(End2endTest, DiffPackageServices) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -1016,7 +1081,8 @@ TEST_P(End2endTest, DiffPackageServices) { EXPECT_TRUE(s.ok()); } -void CancelRpc(ClientContext* context, int delay_us, TestServiceImpl* service) { +template +void CancelRpc(ClientContext* context, int delay_us, ServiceType* service) { gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_micros(delay_us, GPR_TIMESPAN))); while (!service->signal_client()) { @@ -1025,6 +1091,7 @@ void CancelRpc(ClientContext* context, int delay_us, TestServiceImpl* service) { } TEST_P(End2endTest, CancelRpcBeforeStart) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -1041,6 +1108,7 @@ TEST_P(End2endTest, CancelRpcBeforeStart) { // Client cancels request stream after sending two messages TEST_P(End2endTest, ClientCancelsRequestStream) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -1064,6 +1132,7 @@ TEST_P(End2endTest, ClientCancelsRequestStream) { // Client cancels server stream after sending some messages TEST_P(End2endTest, ClientCancelsResponseStream) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -1099,6 +1168,7 @@ TEST_P(End2endTest, ClientCancelsResponseStream) { // Client cancels bidi stream after sending some messages TEST_P(End2endTest, ClientCancelsBidi) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -1134,6 +1204,7 @@ TEST_P(End2endTest, ClientCancelsBidi) { } TEST_P(End2endTest, RpcMaxMessageSize) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -1156,6 +1227,7 @@ void ReaderThreadFunc(ClientReaderWriter* stream, // Run a Read and a WritesDone simultaneously. TEST_P(End2endTest, SimultaneousReadWritesDone) { + MAYBE_SKIP_TEST; ResetStub(); ClientContext context; gpr_event ev; @@ -1170,6 +1242,7 @@ TEST_P(End2endTest, SimultaneousReadWritesDone) { } TEST_P(End2endTest, ChannelState) { + MAYBE_SKIP_TEST; if (GetParam().inproc) { return; } @@ -1206,7 +1279,7 @@ TEST_P(End2endTest, ChannelStateTimeout) { server_address << "127.0.0.1:" << port; // Channel to non-existing server auto channel = - CreateChannel(server_address.str(), InsecureChannelCredentials()); + grpc::CreateChannel(server_address.str(), InsecureChannelCredentials()); // Start IDLE EXPECT_EQ(GRPC_CHANNEL_IDLE, channel->GetState(true)); @@ -1220,6 +1293,7 @@ TEST_P(End2endTest, ChannelStateTimeout) { // Talking to a non-existing service. TEST_P(End2endTest, NonExistingService) { + MAYBE_SKIP_TEST; ResetChannel(); std::unique_ptr stub; stub = grpc::testing::UnimplementedEchoService::NewStub(channel_); @@ -1237,6 +1311,7 @@ TEST_P(End2endTest, NonExistingService) { // Ask the server to send back a serialized proto in trailer. // This is an example of setting error details. TEST_P(End2endTest, BinaryTrailerTest) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -1263,6 +1338,7 @@ TEST_P(End2endTest, BinaryTrailerTest) { } TEST_P(End2endTest, ExpectErrorTest) { + MAYBE_SKIP_TEST; ResetStub(); std::vector expected_status; @@ -1307,6 +1383,80 @@ TEST_P(End2endTest, ExpectErrorTest) { } } +TEST_P(End2endTest, DelayedRpcEarlyCanceledUsingCancelCallback) { + MAYBE_SKIP_TEST; + // This test case is only relevant with callback server. + // Additionally, using interceptors makes this test subject to + // timing-dependent failures if the interceptors take too long to run. + if (!GetParam().callback_server || GetParam().use_interceptors) { + return; + } + + ResetStub(); + ClientContext context; + context.AddMetadata(kServerUseCancelCallback, + grpc::to_string(MAYBE_USE_CALLBACK_EARLY_CANCEL)); + EchoRequest request; + EchoResponse response; + request.set_message("Hello"); + request.mutable_param()->set_skip_cancelled_check(true); + context.TryCancel(); + Status s = stub_->Echo(&context, request, &response); + EXPECT_EQ(StatusCode::CANCELLED, s.error_code()); +} + +TEST_P(End2endTest, DelayedRpcLateCanceledUsingCancelCallback) { + MAYBE_SKIP_TEST; + // This test case is only relevant with callback server. + // Additionally, using interceptors makes this test subject to + // timing-dependent failures if the interceptors take too long to run. + if (!GetParam().callback_server || GetParam().use_interceptors) { + return; + } + + ResetStub(); + ClientContext context; + context.AddMetadata(kServerUseCancelCallback, + grpc::to_string(MAYBE_USE_CALLBACK_LATE_CANCEL)); + EchoRequest request; + EchoResponse response; + request.set_message("Hello"); + request.mutable_param()->set_skip_cancelled_check(true); + // Let server sleep for 200 ms first to give the cancellation a chance. + // This is split into 100 ms to start the cancel and 100 ms extra time for + // it to make it to the server, to make it highly probable that the server + // RPC would have already started by the time the cancellation is sent + // and the server-side gets enough time to react to it. + request.mutable_param()->set_server_sleep_us(200000); + + std::thread echo_thread{[this, &context, &request, &response] { + Status s = stub_->Echo(&context, request, &response); + EXPECT_EQ(StatusCode::CANCELLED, s.error_code()); + }}; + std::this_thread::sleep_for(std::chrono::microseconds(100000)); + context.TryCancel(); + echo_thread.join(); +} + +TEST_P(End2endTest, DelayedRpcNonCanceledUsingCancelCallback) { + MAYBE_SKIP_TEST; + if (!GetParam().callback_server) { + return; + } + + ResetStub(); + EchoRequest request; + EchoResponse response; + request.set_message("Hello"); + + ClientContext context; + context.AddMetadata(kServerUseCancelCallback, + grpc::to_string(MAYBE_USE_CALLBACK_NO_CANCEL)); + + Status s = stub_->Echo(&context, request, &response); + EXPECT_TRUE(s.ok()); +} + ////////////////////////////////////////////////////////////////////////// // Test with and without a proxy. class ProxyEnd2endTest : public End2endTest { @@ -1314,11 +1464,13 @@ class ProxyEnd2endTest : public End2endTest { }; TEST_P(ProxyEnd2endTest, SimpleRpc) { + MAYBE_SKIP_TEST; ResetStub(); SendRpc(stub_.get(), 1, false); } TEST_P(ProxyEnd2endTest, SimpleRpcWithEmptyMessages) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -1329,6 +1481,7 @@ TEST_P(ProxyEnd2endTest, SimpleRpcWithEmptyMessages) { } TEST_P(ProxyEnd2endTest, MultipleRpcs) { + MAYBE_SKIP_TEST; ResetStub(); std::vector threads; threads.reserve(10); @@ -1342,6 +1495,7 @@ TEST_P(ProxyEnd2endTest, MultipleRpcs) { // Set a 10us deadline and make sure proper error is returned. TEST_P(ProxyEnd2endTest, RpcDeadlineExpires) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -1367,6 +1521,7 @@ TEST_P(ProxyEnd2endTest, RpcDeadlineExpires) { // Set a long but finite deadline. TEST_P(ProxyEnd2endTest, RpcLongDeadline) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -1383,6 +1538,7 @@ TEST_P(ProxyEnd2endTest, RpcLongDeadline) { // Ask server to echo back the deadline it sees. TEST_P(ProxyEnd2endTest, EchoDeadline) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -1408,6 +1564,7 @@ TEST_P(ProxyEnd2endTest, EchoDeadline) { // Ask server to echo back the deadline it sees. The rpc has no deadline. TEST_P(ProxyEnd2endTest, EchoDeadlineForNoDeadlineRpc) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -1423,6 +1580,7 @@ TEST_P(ProxyEnd2endTest, EchoDeadlineForNoDeadlineRpc) { } TEST_P(ProxyEnd2endTest, UnimplementedRpc) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -1438,6 +1596,7 @@ TEST_P(ProxyEnd2endTest, UnimplementedRpc) { // Client cancels rpc after 10ms TEST_P(ProxyEnd2endTest, ClientCancelsRpc) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -1446,7 +1605,24 @@ TEST_P(ProxyEnd2endTest, ClientCancelsRpc) { request.mutable_param()->set_client_cancel_after_us(kCancelDelayUs); ClientContext context; - std::thread cancel_thread(CancelRpc, &context, kCancelDelayUs, &service_); + std::thread cancel_thread; + if (!GetParam().callback_server) { + cancel_thread = std::thread( + [&context, this](int delay) { CancelRpc(&context, delay, &service_); }, + kCancelDelayUs); + // Note: the unusual pattern above (and below) is caused by a conflict + // between two sets of compiler expectations. clang allows const to be + // captured without mention, so there is no need to capture kCancelDelayUs + // (and indeed clang-tidy complains if you do so). OTOH, a Windows compiler + // in our tests requires an explicit capture even for const. We square this + // circle by passing the const value in as an argument to the lambda. + } else { + cancel_thread = std::thread( + [&context, this](int delay) { + CancelRpc(&context, delay, &callback_service_); + }, + kCancelDelayUs); + } Status s = stub_->Echo(&context, request, &response); cancel_thread.join(); EXPECT_EQ(StatusCode::CANCELLED, s.error_code()); @@ -1455,6 +1631,7 @@ TEST_P(ProxyEnd2endTest, ClientCancelsRpc) { // Server cancels rpc after 1ms TEST_P(ProxyEnd2endTest, ServerCancelsRpc) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -1469,6 +1646,7 @@ TEST_P(ProxyEnd2endTest, ServerCancelsRpc) { // Make the response larger than the flow control window. TEST_P(ProxyEnd2endTest, HugeResponse) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -1486,6 +1664,7 @@ TEST_P(ProxyEnd2endTest, HugeResponse) { } TEST_P(ProxyEnd2endTest, Peer) { + MAYBE_SKIP_TEST; // Peer is not meaningful for inproc if (GetParam().inproc) { return; @@ -1514,6 +1693,7 @@ class SecureEnd2endTest : public End2endTest { }; TEST_P(SecureEnd2endTest, SimpleRpcWithHost) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; @@ -1545,6 +1725,7 @@ bool MetadataContains( } TEST_P(SecureEnd2endTest, BlockingAuthMetadataPluginAndProcessorSuccess) { + MAYBE_SKIP_TEST; auto* processor = new TestAuthMetadataProcessor(true); StartServer(std::shared_ptr(processor)); ResetStub(); @@ -1570,6 +1751,7 @@ TEST_P(SecureEnd2endTest, BlockingAuthMetadataPluginAndProcessorSuccess) { } TEST_P(SecureEnd2endTest, BlockingAuthMetadataPluginAndProcessorFailure) { + MAYBE_SKIP_TEST; auto* processor = new TestAuthMetadataProcessor(true); StartServer(std::shared_ptr(processor)); ResetStub(); @@ -1585,6 +1767,7 @@ TEST_P(SecureEnd2endTest, BlockingAuthMetadataPluginAndProcessorFailure) { } TEST_P(SecureEnd2endTest, SetPerCallCredentials) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -1607,6 +1790,7 @@ TEST_P(SecureEnd2endTest, SetPerCallCredentials) { } TEST_P(SecureEnd2endTest, OverridePerCallCredentials) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -1638,12 +1822,13 @@ TEST_P(SecureEnd2endTest, OverridePerCallCredentials) { } TEST_P(SecureEnd2endTest, AuthMetadataPluginKeyFailure) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; ClientContext context; - context.set_credentials( - MetadataCredentialsFromPlugin(std::unique_ptr( + context.set_credentials(grpc::MetadataCredentialsFromPlugin( + std::unique_ptr( new TestMetadataCredentialsPlugin( TestMetadataCredentialsPlugin::kBadMetadataKey, "Does not matter, will fail the key is invalid.", false, true)))); @@ -1655,12 +1840,13 @@ TEST_P(SecureEnd2endTest, AuthMetadataPluginKeyFailure) { } TEST_P(SecureEnd2endTest, AuthMetadataPluginValueFailure) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; ClientContext context; - context.set_credentials( - MetadataCredentialsFromPlugin(std::unique_ptr( + context.set_credentials(grpc::MetadataCredentialsFromPlugin( + std::unique_ptr( new TestMetadataCredentialsPlugin( TestMetadataCredentialsPlugin::kGoodMetadataKey, "With illegal \n value.", false, true)))); @@ -1672,12 +1858,13 @@ TEST_P(SecureEnd2endTest, AuthMetadataPluginValueFailure) { } TEST_P(SecureEnd2endTest, NonBlockingAuthMetadataPluginFailure) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; ClientContext context; - context.set_credentials( - MetadataCredentialsFromPlugin(std::unique_ptr( + context.set_credentials(grpc::MetadataCredentialsFromPlugin( + std::unique_ptr( new TestMetadataCredentialsPlugin( TestMetadataCredentialsPlugin::kGoodMetadataKey, "Does not matter, will fail anyway (see 3rd param)", false, @@ -1693,6 +1880,7 @@ TEST_P(SecureEnd2endTest, NonBlockingAuthMetadataPluginFailure) { } TEST_P(SecureEnd2endTest, NonBlockingAuthMetadataPluginAndProcessorSuccess) { + MAYBE_SKIP_TEST; auto* processor = new TestAuthMetadataProcessor(false); StartServer(std::shared_ptr(processor)); ResetStub(); @@ -1718,6 +1906,7 @@ TEST_P(SecureEnd2endTest, NonBlockingAuthMetadataPluginAndProcessorSuccess) { } TEST_P(SecureEnd2endTest, NonBlockingAuthMetadataPluginAndProcessorFailure) { + MAYBE_SKIP_TEST; auto* processor = new TestAuthMetadataProcessor(false); StartServer(std::shared_ptr(processor)); ResetStub(); @@ -1733,12 +1922,13 @@ TEST_P(SecureEnd2endTest, NonBlockingAuthMetadataPluginAndProcessorFailure) { } TEST_P(SecureEnd2endTest, BlockingAuthMetadataPluginFailure) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; ClientContext context; - context.set_credentials( - MetadataCredentialsFromPlugin(std::unique_ptr( + context.set_credentials(grpc::MetadataCredentialsFromPlugin( + std::unique_ptr( new TestMetadataCredentialsPlugin( TestMetadataCredentialsPlugin::kGoodMetadataKey, "Does not matter, will fail anyway (see 3rd param)", true, @@ -1754,6 +1944,7 @@ TEST_P(SecureEnd2endTest, BlockingAuthMetadataPluginFailure) { } TEST_P(SecureEnd2endTest, CompositeCallCreds) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -1763,13 +1954,15 @@ TEST_P(SecureEnd2endTest, CompositeCallCreds) { const char kMetadataVal1[] = "call-creds-val1"; const char kMetadataVal2[] = "call-creds-val2"; - context.set_credentials(CompositeCallCredentials( - MetadataCredentialsFromPlugin(std::unique_ptr( - new TestMetadataCredentialsPlugin(kMetadataKey1, kMetadataVal1, true, - true))), - MetadataCredentialsFromPlugin(std::unique_ptr( - new TestMetadataCredentialsPlugin(kMetadataKey2, kMetadataVal2, true, - true))))); + context.set_credentials(grpc::CompositeCallCredentials( + grpc::MetadataCredentialsFromPlugin( + std::unique_ptr( + new TestMetadataCredentialsPlugin(kMetadataKey1, kMetadataVal1, + true, true))), + grpc::MetadataCredentialsFromPlugin( + std::unique_ptr( + new TestMetadataCredentialsPlugin(kMetadataKey2, kMetadataVal2, + true, true))))); request.set_message("Hello"); request.mutable_param()->set_echo_metadata(true); @@ -1782,6 +1975,7 @@ TEST_P(SecureEnd2endTest, CompositeCallCreds) { } TEST_P(SecureEnd2endTest, ClientAuthContext) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -1826,6 +2020,7 @@ class ResourceQuotaEnd2endTest : public End2endTest { }; TEST_P(ResourceQuotaEnd2endTest, SimpleRequest) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; @@ -1838,10 +2033,12 @@ TEST_P(ResourceQuotaEnd2endTest, SimpleRequest) { EXPECT_TRUE(s.ok()); } +// TODO(vjpai): refactor arguments into a struct if it makes sense std::vector CreateTestScenarios(bool use_proxy, bool test_insecure, bool test_secure, - bool test_inproc) { + bool test_inproc, + bool test_callback_server) { std::vector scenarios; std::vector credentials_types; if (test_secure) { @@ -1857,49 +2054,62 @@ std::vector CreateTestScenarios(bool use_proxy, if (test_insecure && insec_ok()) { credentials_types.push_back(kInsecureCredentialsType); } + + // Test callback with inproc or if the event-engine allows it GPR_ASSERT(!credentials_types.empty()); for (const auto& cred : credentials_types) { - scenarios.emplace_back(false, false, false, cred); - scenarios.emplace_back(true, false, false, cred); + scenarios.emplace_back(false, false, false, cred, false); + scenarios.emplace_back(true, false, false, cred, false); + if (test_callback_server) { + // Note that these scenarios will be dynamically disabled if the event + // engine doesn't run in the background + scenarios.emplace_back(false, false, false, cred, true); + scenarios.emplace_back(true, false, false, cred, true); + } if (use_proxy) { - scenarios.emplace_back(false, true, false, cred); - scenarios.emplace_back(true, true, false, cred); + scenarios.emplace_back(false, true, false, cred, false); + scenarios.emplace_back(true, true, false, cred, false); } } if (test_inproc && insec_ok()) { - scenarios.emplace_back(false, false, true, kInsecureCredentialsType); - scenarios.emplace_back(true, false, true, kInsecureCredentialsType); + scenarios.emplace_back(false, false, true, kInsecureCredentialsType, false); + scenarios.emplace_back(true, false, true, kInsecureCredentialsType, false); + if (test_callback_server) { + scenarios.emplace_back(false, false, true, kInsecureCredentialsType, + true); + scenarios.emplace_back(true, false, true, kInsecureCredentialsType, true); + } } return scenarios; } -INSTANTIATE_TEST_CASE_P(End2end, End2endTest, - ::testing::ValuesIn(CreateTestScenarios(false, true, - true, true))); +INSTANTIATE_TEST_CASE_P( + End2end, End2endTest, + ::testing::ValuesIn(CreateTestScenarios(false, true, true, true, true))); -INSTANTIATE_TEST_CASE_P(End2endServerTryCancel, End2endServerTryCancelTest, - ::testing::ValuesIn(CreateTestScenarios(false, true, - true, true))); +INSTANTIATE_TEST_CASE_P( + End2endServerTryCancel, End2endServerTryCancelTest, + ::testing::ValuesIn(CreateTestScenarios(false, true, true, true, true))); -INSTANTIATE_TEST_CASE_P(ProxyEnd2end, ProxyEnd2endTest, - ::testing::ValuesIn(CreateTestScenarios(true, true, - true, true))); +INSTANTIATE_TEST_CASE_P( + ProxyEnd2end, ProxyEnd2endTest, + ::testing::ValuesIn(CreateTestScenarios(true, true, true, true, true))); -INSTANTIATE_TEST_CASE_P(SecureEnd2end, SecureEnd2endTest, - ::testing::ValuesIn(CreateTestScenarios(false, false, - true, false))); +INSTANTIATE_TEST_CASE_P( + SecureEnd2end, SecureEnd2endTest, + ::testing::ValuesIn(CreateTestScenarios(false, false, true, false, true))); -INSTANTIATE_TEST_CASE_P(ResourceQuotaEnd2end, ResourceQuotaEnd2endTest, - ::testing::ValuesIn(CreateTestScenarios(false, true, - true, true))); +INSTANTIATE_TEST_CASE_P( + ResourceQuotaEnd2end, ResourceQuotaEnd2endTest, + ::testing::ValuesIn(CreateTestScenarios(false, true, true, true, true))); } // namespace } // namespace testing } // namespace grpc int main(int argc, char** argv) { - gpr_setenv("GRPC_CLIENT_CHANNEL_BACKUP_POLL_INTERVAL_MS", "200"); - grpc_test_init(argc, argv); + GPR_GLOBAL_CONFIG_SET(grpc_client_channel_backup_poll_interval_ms, 200); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/cpp/end2end/exception_test.cc b/test/cpp/end2end/exception_test.cc index 5343997663e..0d2c00263b7 100644 --- a/test/cpp/end2end/exception_test.cc +++ b/test/cpp/end2end/exception_test.cc @@ -117,7 +117,7 @@ TEST_F(ExceptionTest, RequestStream) { } // namespace grpc int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/cpp/end2end/filter_end2end_test.cc b/test/cpp/end2end/filter_end2end_test.cc index 88f8f380c3a..a4c981a3eb1 100644 --- a/test/cpp/end2end/filter_end2end_test.cc +++ b/test/cpp/end2end/filter_end2end_test.cc @@ -146,8 +146,8 @@ class FilterEnd2endTest : public ::testing::Test { } void ResetStub() { - std::shared_ptr channel = - CreateChannel(server_address_.str(), InsecureChannelCredentials()); + std::shared_ptr channel = grpc::CreateChannel( + server_address_.str(), InsecureChannelCredentials()); generic_stub_.reset(new GenericStub(channel)); ResetConnectionCounter(); ResetCallCounter(); @@ -331,7 +331,7 @@ void RegisterFilter() { } // namespace grpc int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); grpc::testing::RegisterFilter(); return RUN_ALL_TESTS(); diff --git a/test/cpp/end2end/flaky_network_test.cc b/test/cpp/end2end/flaky_network_test.cc new file mode 100644 index 00000000000..63a6897f931 --- /dev/null +++ b/test/cpp/end2end/flaky_network_test.cc @@ -0,0 +1,501 @@ +/* + * + * Copyright 2019 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 +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "src/core/lib/backoff/backoff.h" +#include "src/core/lib/gpr/env.h" + +#include "src/proto/grpc/testing/echo.grpc.pb.h" +#include "test/core/util/port.h" +#include "test/core/util/test_config.h" +#include "test/cpp/end2end/test_service_impl.h" + +#include + +#ifdef GPR_LINUX +using grpc::testing::EchoRequest; +using grpc::testing::EchoResponse; + +namespace grpc { +namespace testing { +namespace { + +class FlakyNetworkTest : public ::testing::Test { + protected: + FlakyNetworkTest() + : server_host_("grpctest"), + interface_("lo:1"), + ipv4_address_("10.0.0.1"), + netmask_("/32"), + kRequestMessage_("🖖") {} + + void InterfaceUp() { + std::ostringstream cmd; + // create interface_ with address ipv4_address_ + cmd << "ip addr add " << ipv4_address_ << netmask_ << " dev " << interface_; + std::system(cmd.str().c_str()); + } + + void InterfaceDown() { + std::ostringstream cmd; + // remove interface_ + cmd << "ip addr del " << ipv4_address_ << netmask_ << " dev " << interface_; + std::system(cmd.str().c_str()); + } + + void DNSUp() { + std::ostringstream cmd; + // Add DNS entry for server_host_ in /etc/hosts + cmd << "echo '" << ipv4_address_ << " " << server_host_ + << "' >> /etc/hosts"; + std::system(cmd.str().c_str()); + } + + void DNSDown() { + std::ostringstream cmd; + // Remove DNS entry for server_host_ from /etc/hosts + // NOTE: we can't do this in one step with sed -i because when we are + // running under docker, the file is mounted by docker so we can't change + // its inode from within the container (sed -i creates a new file and + // replaces the old file, which changes the inode) + cmd << "sed '/" << server_host_ << "/d' /etc/hosts > /etc/hosts.orig"; + std::system(cmd.str().c_str()); + + // clear the stream + cmd.str(""); + + cmd << "cat /etc/hosts.orig > /etc/hosts"; + std::system(cmd.str().c_str()); + } + + void DropPackets() { + std::ostringstream cmd; + // drop packets with src IP = ipv4_address_ + cmd << "iptables -A INPUT -s " << ipv4_address_ << " -j DROP"; + + std::system(cmd.str().c_str()); + // clear the stream + cmd.str(""); + + // drop packets with dst IP = ipv4_address_ + cmd << "iptables -A INPUT -d " << ipv4_address_ << " -j DROP"; + } + + void RestoreNetwork() { + std::ostringstream cmd; + // remove iptables rule to drop packets with src IP = ipv4_address_ + cmd << "iptables -D INPUT -s " << ipv4_address_ << " -j DROP"; + std::system(cmd.str().c_str()); + // clear the stream + cmd.str(""); + // remove iptables rule to drop packets with dest IP = ipv4_address_ + cmd << "iptables -D INPUT -d " << ipv4_address_ << " -j DROP"; + } + + void FlakeNetwork() { + std::ostringstream cmd; + // Emulate a flaky network connection over interface_. Add a delay of 100ms + // +/- 590ms, 3% packet loss, 1% duplicates and 0.1% corrupt packets. + cmd << "tc qdisc replace dev " << interface_ + << " root netem delay 100ms 50ms distribution normal loss 3% duplicate " + "1% corrupt 0.1% "; + std::system(cmd.str().c_str()); + } + + void UnflakeNetwork() { + // Remove simulated network flake on interface_ + std::ostringstream cmd; + cmd << "tc qdisc del dev " << interface_ << " root netem"; + std::system(cmd.str().c_str()); + } + + void NetworkUp() { + InterfaceUp(); + DNSUp(); + } + + void NetworkDown() { + InterfaceDown(); + DNSDown(); + } + + void SetUp() override { + NetworkUp(); + grpc_init(); + StartServer(); + } + + void TearDown() override { + NetworkDown(); + StopServer(); + grpc_shutdown(); + } + + void StartServer() { + // TODO (pjaikumar): Ideally, we should allocate the port dynamically using + // grpc_pick_unused_port_or_die(). That doesn't work inside some docker + // containers because port_server listens on localhost which maps to + // ip6-looopback, but ipv6 support is not enabled by default in docker. + port_ = SERVER_PORT; + + server_.reset(new ServerData(port_)); + server_->Start(server_host_); + } + void StopServer() { server_->Shutdown(); } + + std::unique_ptr BuildStub( + const std::shared_ptr& channel) { + return grpc::testing::EchoTestService::NewStub(channel); + } + + std::shared_ptr BuildChannel( + const grpc::string& lb_policy_name, + ChannelArguments args = ChannelArguments()) { + if (lb_policy_name.size() > 0) { + args.SetLoadBalancingPolicyName(lb_policy_name); + } // else, default to pick first + std::ostringstream server_address; + server_address << server_host_ << ":" << port_; + return CreateCustomChannel(server_address.str(), + InsecureChannelCredentials(), args); + } + + bool SendRpc( + const std::unique_ptr& stub, + int timeout_ms = 0, bool wait_for_ready = false) { + auto response = std::unique_ptr(new EchoResponse()); + EchoRequest request; + request.set_message(kRequestMessage_); + ClientContext context; + if (timeout_ms > 0) { + context.set_deadline(grpc_timeout_milliseconds_to_deadline(timeout_ms)); + } + // See https://github.com/grpc/grpc/blob/master/doc/wait-for-ready.md for + // details of wait-for-ready semantics + if (wait_for_ready) { + context.set_wait_for_ready(true); + } + Status status = stub->Echo(&context, request, response.get()); + auto ok = status.ok(); + if (ok) { + gpr_log(GPR_DEBUG, "RPC returned %s\n", response->message().c_str()); + } else { + gpr_log(GPR_DEBUG, "RPC failed: %s", status.error_message().c_str()); + } + return ok; + } + + struct ServerData { + int port_; + std::unique_ptr server_; + TestServiceImpl service_; + std::unique_ptr thread_; + bool server_ready_ = false; + + explicit ServerData(int port) { port_ = port; } + + void Start(const grpc::string& server_host) { + gpr_log(GPR_INFO, "starting server on port %d", port_); + std::mutex mu; + std::unique_lock lock(mu); + std::condition_variable cond; + thread_.reset(new std::thread( + std::bind(&ServerData::Serve, this, server_host, &mu, &cond))); + cond.wait(lock, [this] { return server_ready_; }); + server_ready_ = false; + gpr_log(GPR_INFO, "server startup complete"); + } + + void Serve(const grpc::string& server_host, std::mutex* mu, + std::condition_variable* cond) { + std::ostringstream server_address; + server_address << server_host << ":" << port_; + ServerBuilder builder; + builder.AddListeningPort(server_address.str(), + InsecureServerCredentials()); + builder.RegisterService(&service_); + server_ = builder.BuildAndStart(); + std::lock_guard lock(*mu); + server_ready_ = true; + cond->notify_one(); + } + + void Shutdown() { + server_->Shutdown(grpc_timeout_milliseconds_to_deadline(0)); + thread_->join(); + } + }; + + bool WaitForChannelNotReady(Channel* channel, int timeout_seconds = 5) { + const gpr_timespec deadline = + grpc_timeout_seconds_to_deadline(timeout_seconds); + grpc_connectivity_state state; + while ((state = channel->GetState(false /* try_to_connect */)) == + GRPC_CHANNEL_READY) { + if (!channel->WaitForStateChange(state, deadline)) return false; + } + return true; + } + + bool WaitForChannelReady(Channel* channel, int timeout_seconds = 5) { + const gpr_timespec deadline = + grpc_timeout_seconds_to_deadline(timeout_seconds); + grpc_connectivity_state state; + while ((state = channel->GetState(true /* try_to_connect */)) != + GRPC_CHANNEL_READY) { + if (!channel->WaitForStateChange(state, deadline)) return false; + } + return true; + } + + private: + const grpc::string server_host_; + const grpc::string interface_; + const grpc::string ipv4_address_; + const grpc::string netmask_; + std::unique_ptr stub_; + std::unique_ptr server_; + const int SERVER_PORT = 32750; + int port_; + const grpc::string kRequestMessage_; +}; + +// Network interface connected to server flaps +TEST_F(FlakyNetworkTest, NetworkTransition) { + const int kKeepAliveTimeMs = 1000; + const int kKeepAliveTimeoutMs = 1000; + ChannelArguments args; + args.SetInt(GRPC_ARG_KEEPALIVE_TIME_MS, kKeepAliveTimeMs); + args.SetInt(GRPC_ARG_KEEPALIVE_TIMEOUT_MS, kKeepAliveTimeoutMs); + args.SetInt(GRPC_ARG_KEEPALIVE_PERMIT_WITHOUT_CALLS, 1); + args.SetInt(GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA, 0); + + auto channel = BuildChannel("pick_first", args); + auto stub = BuildStub(channel); + // Channel should be in READY state after we send an RPC + EXPECT_TRUE(SendRpc(stub)); + EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); + + std::atomic_bool shutdown{false}; + std::thread sender = std::thread([this, &stub, &shutdown]() { + while (true) { + if (shutdown.load()) { + return; + } + SendRpc(stub); + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + } + }); + + // bring down network + NetworkDown(); + EXPECT_TRUE(WaitForChannelNotReady(channel.get())); + // bring network interface back up + InterfaceUp(); + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + // Restore DNS entry for server + DNSUp(); + EXPECT_TRUE(WaitForChannelReady(channel.get())); + EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); + shutdown.store(true); + sender.join(); +} + +// Traffic to server server is blackholed temporarily with keepalives enabled +TEST_F(FlakyNetworkTest, ServerUnreachableWithKeepalive) { + const int kKeepAliveTimeMs = 1000; + const int kKeepAliveTimeoutMs = 1000; + const int kReconnectBackoffMs = 1000; + ChannelArguments args; + args.SetInt(GRPC_ARG_KEEPALIVE_TIME_MS, kKeepAliveTimeMs); + args.SetInt(GRPC_ARG_KEEPALIVE_TIMEOUT_MS, kKeepAliveTimeoutMs); + args.SetInt(GRPC_ARG_KEEPALIVE_PERMIT_WITHOUT_CALLS, 1); + args.SetInt(GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA, 0); + // max time for a connection attempt + args.SetInt(GRPC_ARG_MIN_RECONNECT_BACKOFF_MS, kReconnectBackoffMs); + // max time between reconnect attempts + args.SetInt(GRPC_ARG_MAX_RECONNECT_BACKOFF_MS, kReconnectBackoffMs); + + gpr_log(GPR_DEBUG, "FlakyNetworkTest.ServerUnreachableWithKeepalive start"); + auto channel = BuildChannel("pick_first", args); + auto stub = BuildStub(channel); + // Channel should be in READY state after we send an RPC + EXPECT_TRUE(SendRpc(stub)); + EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); + + std::atomic_bool shutdown{false}; + std::thread sender = std::thread([this, &stub, &shutdown]() { + while (true) { + if (shutdown.load()) { + return; + } + SendRpc(stub); + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + } + }); + + // break network connectivity + gpr_log(GPR_DEBUG, "Adding iptables rule to drop packets"); + DropPackets(); + std::this_thread::sleep_for(std::chrono::milliseconds(10000)); + EXPECT_TRUE(WaitForChannelNotReady(channel.get())); + // bring network interface back up + RestoreNetwork(); + gpr_log(GPR_DEBUG, "Removed iptables rule to drop packets"); + EXPECT_TRUE(WaitForChannelReady(channel.get())); + EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); + shutdown.store(true); + sender.join(); + gpr_log(GPR_DEBUG, "FlakyNetworkTest.ServerUnreachableWithKeepalive end"); +} + +// +// Traffic to server server is blackholed temporarily with keepalives disabled +TEST_F(FlakyNetworkTest, ServerUnreachableNoKeepalive) { + auto channel = BuildChannel("pick_first", ChannelArguments()); + auto stub = BuildStub(channel); + // Channel should be in READY state after we send an RPC + EXPECT_TRUE(SendRpc(stub)); + EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); + + // break network connectivity + DropPackets(); + + std::thread sender = std::thread([this, &stub]() { + // RPC with deadline should timeout + EXPECT_FALSE(SendRpc(stub, /*timeout_ms=*/500, /*wait_for_ready=*/true)); + // RPC without deadline forever until call finishes + EXPECT_TRUE(SendRpc(stub, /*timeout_ms=*/0, /*wait_for_ready=*/true)); + }); + + std::this_thread::sleep_for(std::chrono::milliseconds(2000)); + // bring network interface back up + RestoreNetwork(); + + // wait for RPC to finish + sender.join(); +} + +// Send RPCs over a flaky network connection +TEST_F(FlakyNetworkTest, FlakyNetwork) { + const int kKeepAliveTimeMs = 1000; + const int kKeepAliveTimeoutMs = 1000; + const int kMessageCount = 100; + ChannelArguments args; + args.SetInt(GRPC_ARG_KEEPALIVE_TIME_MS, kKeepAliveTimeMs); + args.SetInt(GRPC_ARG_KEEPALIVE_TIMEOUT_MS, kKeepAliveTimeoutMs); + args.SetInt(GRPC_ARG_KEEPALIVE_PERMIT_WITHOUT_CALLS, 1); + args.SetInt(GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA, 0); + + auto channel = BuildChannel("pick_first", args); + auto stub = BuildStub(channel); + // Channel should be in READY state after we send an RPC + EXPECT_TRUE(SendRpc(stub)); + EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); + + // simulate flaky network (packet loss, corruption and delays) + FlakeNetwork(); + for (int i = 0; i < kMessageCount; ++i) { + SendRpc(stub); + } + // remove network flakiness + UnflakeNetwork(); + EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); +} + +// Server is shutdown gracefully and restarted. Client keepalives are enabled +TEST_F(FlakyNetworkTest, ServerRestartKeepaliveEnabled) { + const int kKeepAliveTimeMs = 1000; + const int kKeepAliveTimeoutMs = 1000; + ChannelArguments args; + args.SetInt(GRPC_ARG_KEEPALIVE_TIME_MS, kKeepAliveTimeMs); + args.SetInt(GRPC_ARG_KEEPALIVE_TIMEOUT_MS, kKeepAliveTimeoutMs); + args.SetInt(GRPC_ARG_KEEPALIVE_PERMIT_WITHOUT_CALLS, 1); + args.SetInt(GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA, 0); + + auto channel = BuildChannel("pick_first", args); + auto stub = BuildStub(channel); + // Channel should be in READY state after we send an RPC + EXPECT_TRUE(SendRpc(stub)); + EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); + + // server goes down, client should detect server going down and calls should + // fail + StopServer(); + EXPECT_TRUE(WaitForChannelNotReady(channel.get())); + EXPECT_FALSE(SendRpc(stub)); + + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + + // server restarts, calls succeed + StartServer(); + EXPECT_TRUE(WaitForChannelReady(channel.get())); + // EXPECT_TRUE(SendRpc(stub)); +} + +// Server is shutdown gracefully and restarted. Client keepalives are enabled +TEST_F(FlakyNetworkTest, ServerRestartKeepaliveDisabled) { + auto channel = BuildChannel("pick_first", ChannelArguments()); + auto stub = BuildStub(channel); + // Channel should be in READY state after we send an RPC + EXPECT_TRUE(SendRpc(stub)); + EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); + + // server sends GOAWAY when it's shutdown, so client attempts to reconnect + StopServer(); + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + + EXPECT_TRUE(WaitForChannelNotReady(channel.get())); + + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + + // server restarts, calls succeed + StartServer(); + EXPECT_TRUE(WaitForChannelReady(channel.get())); +} + +} // namespace +} // namespace testing +} // namespace grpc +#endif // GPR_LINUX + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + grpc_test_init(argc, argv); + auto result = RUN_ALL_TESTS(); + return result; +} diff --git a/test/cpp/end2end/generic_end2end_test.cc b/test/cpp/end2end/generic_end2end_test.cc index 88a1227ca2e..c2807310aa4 100644 --- a/test/cpp/end2end/generic_end2end_test.cc +++ b/test/cpp/end2end/generic_end2end_test.cc @@ -17,6 +17,7 @@ */ #include +#include #include #include @@ -89,8 +90,8 @@ class GenericEnd2endTest : public ::testing::Test { } void ResetStub() { - std::shared_ptr channel = - CreateChannel(server_address_.str(), InsecureChannelCredentials()); + std::shared_ptr channel = grpc::CreateChannel( + server_address_.str(), InsecureChannelCredentials()); generic_stub_.reset(new GenericStub(channel)); } @@ -219,10 +220,11 @@ TEST_F(GenericEnd2endTest, SequentialUnaryRpcs) { // Use the same cq as server so that events can be polled in time. std::unique_ptr call = generic_stub_->PrepareUnaryCall(&cli_ctx, kMethodName, - *cli_send_buffer.get(), srv_cq_.get()); + *cli_send_buffer.get(), &cli_cq_); call->StartCall(); ByteBuffer cli_recv_buffer; call->Finish(&cli_recv_buffer, &recv_status, tag(1)); + std::thread client_check([this] { client_ok(1); }); generic_service_.RequestCall(&srv_ctx, &stream, srv_cq_.get(), srv_cq_.get(), tag(4)); @@ -246,7 +248,7 @@ TEST_F(GenericEnd2endTest, SequentialUnaryRpcs) { stream.Finish(Status::OK, tag(7)); server_ok(7); - verify_ok(srv_cq_.get(), 1, true); + client_check.join(); EXPECT_TRUE(ParseFromByteBuffer(&cli_recv_buffer, &recv_response)); EXPECT_EQ(send_response.message(), recv_response.message()); EXPECT_TRUE(recv_status.ok()); @@ -333,7 +335,7 @@ TEST_F(GenericEnd2endTest, Deadline) { } // namespace grpc int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/cpp/end2end/grpclb_end2end_test.cc b/test/cpp/end2end/grpclb_end2end_test.cc index 6ce0696114e..50b1383e7e1 100644 --- a/test/cpp/end2end/grpclb_end2end_test.cc +++ b/test/cpp/end2end/grpclb_end2end_test.cc @@ -18,6 +18,7 @@ #include #include +#include #include #include @@ -29,17 +30,20 @@ #include #include #include +#include #include #include +#include "src/core/ext/filters/client_channel/backup_poller.h" +#include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h" -#include "src/core/lib/gpr/env.h" +#include "src/core/ext/filters/client_channel/server_address.h" +#include "src/core/ext/filters/client_channel/service_config.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/sockaddr.h" #include "src/core/lib/security/credentials/fake/fake_credentials.h" -#include "src/cpp/server/secure_server_credentials.h" - #include "src/cpp/client/secure_credentials.h" +#include "src/cpp/server/secure_server_credentials.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" @@ -54,13 +58,8 @@ // TODO(dgq): Other scenarios in need of testing: // - Send a serverlist with faulty ip:port addresses (port > 2^16, etc). // - Test reception of invalid serverlist -// - Test pinging // - Test against a non-LB server. // - Random LB server closing the stream unexpectedly. -// - Test using DNS-resolvable names (localhost?) -// - Test handling of creation of faulty RR instance by having the LB return a -// serverlist with non-existent backends after having initially returned a -// valid one. // // Findings from end to end testing to be covered here: // - Handling of LB servers restart, including reconnection after backing-off @@ -72,8 +71,6 @@ // part of the grpclb shutdown process. // 2) the retry timer is active. Again, the weak reference it holds should // prevent a premature call to \a glb_destroy. -// - Restart of backend servers with no changes to serverlist. This exercises -// the RR handover mechanism. using std::chrono::system_clock; @@ -89,32 +86,32 @@ template class CountedService : public ServiceType { public: size_t request_count() { - std::unique_lock lock(mu_); + grpc::internal::MutexLock lock(&mu_); return request_count_; } size_t response_count() { - std::unique_lock lock(mu_); + grpc::internal::MutexLock lock(&mu_); return response_count_; } void IncreaseResponseCount() { - std::unique_lock lock(mu_); + grpc::internal::MutexLock lock(&mu_); ++response_count_; } void IncreaseRequestCount() { - std::unique_lock lock(mu_); + grpc::internal::MutexLock lock(&mu_); ++request_count_; } void ResetCounters() { - std::unique_lock lock(mu_); + grpc::internal::MutexLock lock(&mu_); request_count_ = 0; response_count_ = 0; } protected: - std::mutex mu_; + grpc::internal::Mutex mu_; private: size_t request_count_ = 0; @@ -143,21 +140,28 @@ class BackendServiceImpl : public BackendService { IncreaseRequestCount(); const auto status = TestServiceImpl::Echo(context, request, response); IncreaseResponseCount(); + AddClient(context->peer()); return status; } - // Returns true on its first invocation, false otherwise. - bool Shutdown() { - std::unique_lock lock(mu_); - const bool prev = !shutdown_; - shutdown_ = true; - gpr_log(GPR_INFO, "Backend: shut down"); - return prev; + void Start() {} + + void Shutdown() {} + + std::set clients() { + grpc::internal::MutexLock lock(&clients_mu_); + return clients_; } private: - std::mutex mu_; - bool shutdown_ = false; + void AddClient(const grpc::string& client) { + grpc::internal::MutexLock lock(&clients_mu_); + clients_.insert(client); + } + + grpc::internal::Mutex mu_; + grpc::internal::Mutex clients_mu_; + std::set clients_; }; grpc::string Ip4ToPackedString(const char* ip_str) { @@ -185,6 +189,14 @@ struct ClientStats { } return *this; } + + void Reset() { + num_calls_started = 0; + num_calls_finished = 0; + num_calls_finished_with_client_failed_to_send = 0; + num_calls_finished_known_received = 0; + drop_token_counts.clear(); + } }; class BalancerServiceImpl : public BalancerService { @@ -194,76 +206,77 @@ class BalancerServiceImpl : public BalancerService { explicit BalancerServiceImpl(int client_load_reporting_interval_seconds) : client_load_reporting_interval_seconds_( - client_load_reporting_interval_seconds), - shutdown_(false) {} + client_load_reporting_interval_seconds) {} Status BalanceLoad(ServerContext* context, Stream* stream) override { - // Balancer shouldn't receive the call credentials metadata. - EXPECT_EQ(context->client_metadata().find(g_kCallCredsMdKey), - context->client_metadata().end()); gpr_log(GPR_INFO, "LB[%p]: BalanceLoad", this); - LoadBalanceRequest request; - std::vector responses_and_delays; - - if (!stream->Read(&request)) { - goto done; - } - IncreaseRequestCount(); - gpr_log(GPR_INFO, "LB[%p]: received initial message '%s'", this, - request.DebugString().c_str()); - - // TODO(juanlishen): Initial response should always be the first response. - if (client_load_reporting_interval_seconds_ > 0) { - LoadBalanceResponse initial_response; - initial_response.mutable_initial_response() - ->mutable_client_stats_report_interval() - ->set_seconds(client_load_reporting_interval_seconds_); - stream->Write(initial_response); - } - { - std::unique_lock lock(mu_); - responses_and_delays = responses_and_delays_; + grpc::internal::MutexLock lock(&mu_); + if (serverlist_done_) goto done; } - for (const auto& response_and_delay : responses_and_delays) { - { - std::unique_lock lock(mu_); - if (shutdown_) goto done; + { + // Balancer shouldn't receive the call credentials metadata. + EXPECT_EQ(context->client_metadata().find(g_kCallCredsMdKey), + context->client_metadata().end()); + LoadBalanceRequest request; + std::vector responses_and_delays; + + if (!stream->Read(&request)) { + goto done; } - SendResponse(stream, response_and_delay.first, response_and_delay.second); - } - { - std::unique_lock lock(mu_); - if (shutdown_) goto done; - serverlist_cond_.wait(lock, [this] { return serverlist_ready_; }); - } + IncreaseRequestCount(); + gpr_log(GPR_INFO, "LB[%p]: received initial message '%s'", this, + request.DebugString().c_str()); - if (client_load_reporting_interval_seconds_ > 0) { - request.Clear(); - if (stream->Read(&request)) { - gpr_log(GPR_INFO, "LB[%p]: received client load report message '%s'", - this, request.DebugString().c_str()); - GPR_ASSERT(request.has_client_stats()); - // We need to acquire the lock here in order to prevent the notify_one - // below from firing before its corresponding wait is executed. - std::lock_guard lock(mu_); - client_stats_.num_calls_started += - request.client_stats().num_calls_started(); - client_stats_.num_calls_finished += - request.client_stats().num_calls_finished(); - client_stats_.num_calls_finished_with_client_failed_to_send += - request.client_stats() - .num_calls_finished_with_client_failed_to_send(); - client_stats_.num_calls_finished_known_received += - request.client_stats().num_calls_finished_known_received(); - for (const auto& drop_token_count : - request.client_stats().calls_finished_with_drop()) { - client_stats_ - .drop_token_counts[drop_token_count.load_balance_token()] += - drop_token_count.num_calls(); + // TODO(juanlishen): Initial response should always be the first response. + if (client_load_reporting_interval_seconds_ > 0) { + LoadBalanceResponse initial_response; + initial_response.mutable_initial_response() + ->mutable_client_stats_report_interval() + ->set_seconds(client_load_reporting_interval_seconds_); + stream->Write(initial_response); + } + + { + grpc::internal::MutexLock lock(&mu_); + responses_and_delays = responses_and_delays_; + } + for (const auto& response_and_delay : responses_and_delays) { + SendResponse(stream, response_and_delay.first, + response_and_delay.second); + } + { + grpc::internal::MutexLock lock(&mu_); + serverlist_cond_.WaitUntil(&mu_, [this] { return serverlist_done_; }); + } + + if (client_load_reporting_interval_seconds_ > 0) { + request.Clear(); + if (stream->Read(&request)) { + gpr_log(GPR_INFO, "LB[%p]: received client load report message '%s'", + this, request.DebugString().c_str()); + GPR_ASSERT(request.has_client_stats()); + // We need to acquire the lock here in order to prevent the notify_one + // below from firing before its corresponding wait is executed. + grpc::internal::MutexLock lock(&mu_); + client_stats_.num_calls_started += + request.client_stats().num_calls_started(); + client_stats_.num_calls_finished += + request.client_stats().num_calls_finished(); + client_stats_.num_calls_finished_with_client_failed_to_send += + request.client_stats() + .num_calls_finished_with_client_failed_to_send(); + client_stats_.num_calls_finished_known_received += + request.client_stats().num_calls_finished_known_received(); + for (const auto& drop_token_count : + request.client_stats().calls_finished_with_drop()) { + client_stats_ + .drop_token_counts[drop_token_count.load_balance_token()] += + drop_token_count.num_calls(); + } + load_report_ready_ = true; + load_report_cond_.Signal(); } - load_report_ready_ = true; - load_report_cond_.notify_one(); } } done: @@ -272,18 +285,21 @@ class BalancerServiceImpl : public BalancerService { } void add_response(const LoadBalanceResponse& response, int send_after_ms) { - std::unique_lock lock(mu_); + grpc::internal::MutexLock lock(&mu_); responses_and_delays_.push_back(std::make_pair(response, send_after_ms)); } - // Returns true on its first invocation, false otherwise. - bool Shutdown() { + void Start() { + grpc::internal::MutexLock lock(&mu_); + serverlist_done_ = false; + load_report_ready_ = false; + responses_and_delays_.clear(); + client_stats_.Reset(); + } + + void Shutdown() { NotifyDoneWithServerlists(); - std::unique_lock lock(mu_); - const bool prev = !shutdown_; - shutdown_ = true; gpr_log(GPR_INFO, "LB[%p]: shut down", this); - return prev; } static LoadBalanceResponse BuildResponseForBackends( @@ -301,21 +317,28 @@ class BalancerServiceImpl : public BalancerService { auto* server = response.mutable_server_list()->add_servers(); server->set_ip_address(Ip4ToPackedString("127.0.0.1")); server->set_port(backend_port); + static int token_count = 0; + char* token; + gpr_asprintf(&token, "token%03d", ++token_count); + server->set_load_balance_token(token); + gpr_free(token); } return response; } const ClientStats& WaitForLoadReport() { - std::unique_lock lock(mu_); - load_report_cond_.wait(lock, [this] { return load_report_ready_; }); + grpc::internal::MutexLock lock(&mu_); + load_report_cond_.WaitUntil(&mu_, [this] { return load_report_ready_; }); load_report_ready_ = false; return client_stats_; } void NotifyDoneWithServerlists() { - std::lock_guard lock(mu_); - serverlist_ready_ = true; - serverlist_cond_.notify_all(); + grpc::internal::MutexLock lock(&mu_); + if (!serverlist_done_) { + serverlist_done_ = true; + serverlist_cond_.Broadcast(); + } } private: @@ -333,18 +356,17 @@ class BalancerServiceImpl : public BalancerService { const int client_load_reporting_interval_seconds_; std::vector responses_and_delays_; - std::mutex mu_; - std::condition_variable load_report_cond_; + grpc::internal::Mutex mu_; + grpc::internal::CondVar load_report_cond_; bool load_report_ready_ = false; - std::condition_variable serverlist_cond_; - bool serverlist_ready_ = false; + grpc::internal::CondVar serverlist_cond_; + bool serverlist_done_ = false; ClientStats client_stats_; - bool shutdown_; }; class GrpclbEnd2endTest : public ::testing::Test { protected: - GrpclbEnd2endTest(int num_backends, int num_balancers, + GrpclbEnd2endTest(size_t num_backends, size_t num_balancers, int client_load_reporting_interval_seconds) : server_host_("localhost"), num_backends_(num_backends), @@ -353,7 +375,7 @@ class GrpclbEnd2endTest : public ::testing::Test { client_load_reporting_interval_seconds) { // Make the backup poller poll very frequently in order to pick up // updates from all the subchannels's FDs. - gpr_setenv("GRPC_CLIENT_CHANNEL_BACKUP_POLL_INTERVAL_MS", "1"); + GPR_GLOBAL_CONFIG_SET(grpc_client_channel_backup_poll_interval_ms, 1); } void SetUp() override { @@ -361,41 +383,39 @@ class GrpclbEnd2endTest : public ::testing::Test { grpc_core::MakeRefCounted(); // Start the backends. for (size_t i = 0; i < num_backends_; ++i) { - backends_.emplace_back(new BackendServiceImpl()); - backend_servers_.emplace_back(ServerThread( - "backend", server_host_, backends_.back().get())); + backends_.emplace_back(new ServerThread("backend")); + backends_.back()->Start(server_host_); } // Start the load balancers. for (size_t i = 0; i < num_balancers_; ++i) { - balancers_.emplace_back( - new BalancerServiceImpl(client_load_reporting_interval_seconds_)); - balancer_servers_.emplace_back(ServerThread( - "balancer", server_host_, balancers_.back().get())); + balancers_.emplace_back(new ServerThread( + "balancer", client_load_reporting_interval_seconds_)); + balancers_.back()->Start(server_host_); } ResetStub(); } void TearDown() override { - for (size_t i = 0; i < backends_.size(); ++i) { - if (backends_[i]->Shutdown()) backend_servers_[i].Shutdown(); - } - for (size_t i = 0; i < balancers_.size(); ++i) { - if (balancers_[i]->Shutdown()) balancer_servers_[i].Shutdown(); - } + ShutdownAllBackends(); + for (auto& balancer : balancers_) balancer->Shutdown(); } - void SetNextResolutionAllBalancers() { - std::vector addresses; - for (size_t i = 0; i < balancer_servers_.size(); ++i) { - addresses.emplace_back(AddressData{balancer_servers_[i].port_, true, ""}); - } - SetNextResolution(addresses); + void StartAllBackends() { + for (auto& backend : backends_) backend->Start(server_host_); } + void StartBackend(size_t index) { backends_[index]->Start(server_host_); } + + void ShutdownAllBackends() { + for (auto& backend : backends_) backend->Shutdown(); + } + + void ShutdownBackend(size_t index) { backends_[index]->Shutdown(); } + void ResetStub(int fallback_timeout = 0, const grpc::string& expected_targets = "") { ChannelArguments args; - args.SetGrpclbFallbackTimeout(fallback_timeout); + if (fallback_timeout > 0) args.SetGrpclbFallbackTimeout(fallback_timeout); args.SetPointer(GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR, response_generator_.get()); if (!expected_targets.empty()) { @@ -412,27 +432,28 @@ class GrpclbEnd2endTest : public ::testing::Test { std::shared_ptr creds( new SecureChannelCredentials(grpc_composite_channel_credentials_create( channel_creds, call_creds, nullptr))); - grpc_call_credentials_unref(call_creds); - grpc_channel_credentials_unref(channel_creds); - channel_ = CreateCustomChannel(uri.str(), creds, args); + call_creds->Unref(); + channel_creds->Unref(); + channel_ = ::grpc::CreateCustomChannel(uri.str(), creds, args); stub_ = grpc::testing::EchoTestService::NewStub(channel_); } void ResetBackendCounters() { - for (const auto& backend : backends_) backend->ResetCounters(); + for (auto& backend : backends_) backend->service_.ResetCounters(); } ClientStats WaitForLoadReports() { ClientStats client_stats; - for (const auto& balancer : balancers_) { - client_stats += balancer->WaitForLoadReport(); + for (auto& balancer : balancers_) { + client_stats += balancer->service_.WaitForLoadReport(); } return client_stats; } - bool SeenAllBackends() { - for (const auto& backend : backends_) { - if (backend->request_count() == 0) return false; + bool SeenAllBackends(size_t start_index = 0, size_t stop_index = 0) { + if (stop_index == 0) stop_index = backends_.size(); + for (size_t i = start_index; i < stop_index; ++i) { + if (backends_[i]->service_.request_count() == 0) return false; } return true; } @@ -452,13 +473,14 @@ class GrpclbEnd2endTest : public ::testing::Test { ++*num_total; } - std::tuple WaitForAllBackends( - int num_requests_multiple_of = 1) { + std::tuple WaitForAllBackends(int num_requests_multiple_of = 1, + size_t start_index = 0, + size_t stop_index = 0) { int num_ok = 0; int num_failure = 0; int num_drops = 0; int num_total = 0; - while (!SeenAllBackends()) { + while (!SeenAllBackends(start_index, stop_index)) { SendRpcAndCount(&num_total, &num_ok, &num_failure, &num_drops); } while (num_total % num_requests_multiple_of != 0) { @@ -476,7 +498,7 @@ class GrpclbEnd2endTest : public ::testing::Test { void WaitForBackend(size_t backend_idx) { do { (void)SendRpc(); - } while (backends_[backend_idx]->request_count() == 0); + } while (backends_[backend_idx]->service_.request_count() == 0); ResetBackendCounters(); } @@ -486,49 +508,70 @@ class GrpclbEnd2endTest : public ::testing::Test { grpc::string balancer_name; }; - grpc_lb_addresses* CreateLbAddressesFromAddressDataList( + grpc_core::ServerAddressList CreateLbAddressesFromAddressDataList( const std::vector& address_data) { - grpc_lb_addresses* addresses = - grpc_lb_addresses_create(address_data.size(), nullptr); - for (size_t i = 0; i < address_data.size(); ++i) { + grpc_core::ServerAddressList addresses; + for (const auto& addr : address_data) { char* lb_uri_str; - gpr_asprintf(&lb_uri_str, "ipv4:127.0.0.1:%d", address_data[i].port); + gpr_asprintf(&lb_uri_str, "ipv4:127.0.0.1:%d", addr.port); grpc_uri* lb_uri = grpc_uri_parse(lb_uri_str, true); GPR_ASSERT(lb_uri != nullptr); - grpc_lb_addresses_set_address_from_uri( - addresses, i, lb_uri, address_data[i].is_balancer, - address_data[i].balancer_name.c_str(), nullptr); + grpc_resolved_address address; + GPR_ASSERT(grpc_parse_uri(lb_uri, &address)); + std::vector args_to_add; + if (addr.is_balancer) { + args_to_add.emplace_back(grpc_channel_arg_integer_create( + const_cast(GRPC_ARG_ADDRESS_IS_BALANCER), 1)); + args_to_add.emplace_back(grpc_channel_arg_string_create( + const_cast(GRPC_ARG_ADDRESS_BALANCER_NAME), + const_cast(addr.balancer_name.c_str()))); + } + grpc_channel_args* args = grpc_channel_args_copy_and_add( + nullptr, args_to_add.data(), args_to_add.size()); + addresses.emplace_back(address.addr, address.len, args); grpc_uri_destroy(lb_uri); gpr_free(lb_uri_str); } return addresses; } - void SetNextResolution(const std::vector& address_data) { + void SetNextResolutionAllBalancers( + const char* service_config_json = nullptr) { + std::vector addresses; + for (size_t i = 0; i < balancers_.size(); ++i) { + addresses.emplace_back(AddressData{balancers_[i]->port_, true, ""}); + } + SetNextResolution(addresses, service_config_json); + } + + void SetNextResolution(const std::vector& address_data, + const char* service_config_json = nullptr) { grpc_core::ExecCtx exec_ctx; - grpc_lb_addresses* addresses = - CreateLbAddressesFromAddressDataList(address_data); - grpc_arg fake_addresses = grpc_lb_addresses_create_channel_arg(addresses); - grpc_channel_args fake_result = {1, &fake_addresses}; - response_generator_->SetResponse(&fake_result); - grpc_lb_addresses_destroy(addresses); + grpc_core::Resolver::Result result; + result.addresses = CreateLbAddressesFromAddressDataList(address_data); + if (service_config_json != nullptr) { + grpc_error* error = GRPC_ERROR_NONE; + result.service_config = + grpc_core::ServiceConfig::Create(service_config_json, &error); + GRPC_ERROR_UNREF(error); + } + response_generator_->SetResponse(std::move(result)); } void SetNextReresolutionResponse( const std::vector& address_data) { grpc_core::ExecCtx exec_ctx; - grpc_lb_addresses* addresses = - CreateLbAddressesFromAddressDataList(address_data); - grpc_arg fake_addresses = grpc_lb_addresses_create_channel_arg(addresses); - grpc_channel_args fake_result = {1, &fake_addresses}; - response_generator_->SetReresolutionResponse(&fake_result); - grpc_lb_addresses_destroy(addresses); + grpc_core::Resolver::Result result; + result.addresses = CreateLbAddressesFromAddressDataList(address_data); + response_generator_->SetReresolutionResponse(std::move(result)); } - const std::vector GetBackendPorts(const size_t start_index = 0) const { + const std::vector GetBackendPorts(size_t start_index = 0, + size_t stop_index = 0) const { + if (stop_index == 0) stop_index = backends_.size(); std::vector backend_ports; - for (size_t i = start_index; i < backend_servers_.size(); ++i) { - backend_ports.push_back(backend_servers_[i].port_); + for (size_t i = start_index; i < stop_index; ++i) { + backend_ports.push_back(backends_[i]->port_); } return backend_ports; } @@ -536,7 +579,7 @@ class GrpclbEnd2endTest : public ::testing::Test { void ScheduleResponseForBalancer(size_t i, const LoadBalanceResponse& response, int delay_ms) { - balancers_.at(i)->add_response(response, delay_ms); + balancers_[i]->service_.add_response(response, delay_ms); } Status SendRpc(EchoResponse* response = nullptr, int timeout_ms = 1000, @@ -553,10 +596,11 @@ class GrpclbEnd2endTest : public ::testing::Test { return status; } - void CheckRpcSendOk(const size_t times = 1, const int timeout_ms = 1000) { + void CheckRpcSendOk(const size_t times = 1, const int timeout_ms = 1000, + bool wait_for_ready = false) { for (size_t i = 0; i < times; ++i) { EchoResponse response; - const Status status = SendRpc(&response, timeout_ms); + const Status status = SendRpc(&response, timeout_ms, wait_for_ready); EXPECT_TRUE(status.ok()) << "code=" << status.error_code() << " message=" << status.error_message(); EXPECT_EQ(response.message(), kRequestMessage_); @@ -570,50 +614,60 @@ class GrpclbEnd2endTest : public ::testing::Test { template struct ServerThread { - explicit ServerThread(const grpc::string& type, - const grpc::string& server_host, T* service) - : type_(type), service_(service) { - std::mutex mu; - // We need to acquire the lock here in order to prevent the notify_one - // by ServerThread::Start from firing before the wait below is hit. - std::unique_lock lock(mu); - port_ = grpc_pick_unused_port_or_die(); + template + explicit ServerThread(const grpc::string& type, Args&&... args) + : port_(grpc_pick_unused_port_or_die()), + type_(type), + service_(std::forward(args)...) {} + + void Start(const grpc::string& server_host) { gpr_log(GPR_INFO, "starting %s server on port %d", type_.c_str(), port_); - std::condition_variable cond; + GPR_ASSERT(!running_); + running_ = true; + service_.Start(); + grpc::internal::Mutex mu; + // We need to acquire the lock here in order to prevent the notify_one + // by ServerThread::Serve from firing before the wait below is hit. + grpc::internal::MutexLock lock(&mu); + grpc::internal::CondVar cond; thread_.reset(new std::thread( - std::bind(&ServerThread::Start, this, server_host, &mu, &cond))); - cond.wait(lock); + std::bind(&ServerThread::Serve, this, server_host, &mu, &cond))); + cond.Wait(&mu); gpr_log(GPR_INFO, "%s server startup complete", type_.c_str()); } - void Start(const grpc::string& server_host, std::mutex* mu, - std::condition_variable* cond) { + void Serve(const grpc::string& server_host, grpc::internal::Mutex* mu, + grpc::internal::CondVar* cond) { // We need to acquire the lock here in order to prevent the notify_one // below from firing before its corresponding wait is executed. - std::lock_guard lock(*mu); + grpc::internal::MutexLock lock(mu); std::ostringstream server_address; server_address << server_host << ":" << port_; ServerBuilder builder; std::shared_ptr creds(new SecureServerCredentials( grpc_fake_transport_security_server_credentials_create())); builder.AddListeningPort(server_address.str(), creds); - builder.RegisterService(service_); + builder.RegisterService(&service_); server_ = builder.BuildAndStart(); - cond->notify_one(); + cond->Signal(); } void Shutdown() { + if (!running_) return; gpr_log(GPR_INFO, "%s about to shutdown", type_.c_str()); + service_.Shutdown(); server_->Shutdown(grpc_timeout_milliseconds_to_deadline(0)); thread_->join(); gpr_log(GPR_INFO, "%s shutdown completed", type_.c_str()); + running_ = false; } - int port_; + const int port_; grpc::string type_; + T service_; std::unique_ptr server_; - T* service_; std::unique_ptr thread_; + bool running_ = false; }; const grpc::string server_host_; @@ -622,10 +676,8 @@ class GrpclbEnd2endTest : public ::testing::Test { const int client_load_reporting_interval_seconds_; std::shared_ptr channel_; std::unique_ptr stub_; - std::vector> backends_; - std::vector> balancers_; - std::vector> backend_servers_; - std::vector> balancer_servers_; + std::vector>> backends_; + std::vector>> balancers_; grpc_core::RefCountedPtr response_generator_; const grpc::string kRequestMessage_ = "Live long and prosper."; @@ -652,22 +704,281 @@ TEST_F(SingleBalancerTest, Vanilla) { // Each backend should have gotten 100 requests. for (size_t i = 0; i < backends_.size(); ++i) { - EXPECT_EQ(kNumRpcsPerAddress, - backend_servers_[i].service_->request_count()); + EXPECT_EQ(kNumRpcsPerAddress, backends_[i]->service_.request_count()); } - balancers_[0]->NotifyDoneWithServerlists(); + balancers_[0]->service_.NotifyDoneWithServerlists(); // The balancer got a single request. - EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); // and sent a single response. - EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); + EXPECT_EQ(1U, balancers_[0]->service_.response_count()); // Check LB policy name for the channel. EXPECT_EQ("grpclb", channel_->GetLoadBalancingPolicyName()); } +TEST_F(SingleBalancerTest, SelectGrpclbWithMigrationServiceConfig) { + SetNextResolutionAllBalancers( + "{\n" + " \"loadBalancingConfig\":[\n" + " { \"does_not_exist\":{} },\n" + " { \"grpclb\":{} }\n" + " ]\n" + "}"); + ScheduleResponseForBalancer( + 0, BalancerServiceImpl::BuildResponseForBackends(GetBackendPorts(), {}), + 0); + CheckRpcSendOk(1, 1000 /* timeout_ms */, true /* wait_for_ready */); + balancers_[0]->service_.NotifyDoneWithServerlists(); + // The balancer got a single request. + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); + // and sent a single response. + EXPECT_EQ(1U, balancers_[0]->service_.response_count()); + // Check LB policy name for the channel. + EXPECT_EQ("grpclb", channel_->GetLoadBalancingPolicyName()); +} + +TEST_F(SingleBalancerTest, + DoNotSpecialCaseUseGrpclbWithLoadBalancingConfigTest) { + const int kFallbackTimeoutMs = 200 * grpc_test_slowdown_factor(); + ResetStub(kFallbackTimeoutMs); + SetNextResolution({AddressData{backends_[0]->port_, false, ""}, + AddressData{balancers_[0]->port_, true, ""}}, + "{\n" + " \"loadBalancingConfig\":[\n" + " {\"pick_first\":{} }\n" + " ]\n" + "}"); + CheckRpcSendOk(); + // Check LB policy name for the channel. + EXPECT_EQ("pick_first", channel_->GetLoadBalancingPolicyName()); +} + +TEST_F( + SingleBalancerTest, + DoNotSpecialCaseUseGrpclbWithLoadBalancingConfigTestAndNoBackendAddress) { + const int kFallbackTimeoutMs = 200 * grpc_test_slowdown_factor(); + ResetStub(kFallbackTimeoutMs); + SetNextResolution({AddressData{balancers_[0]->port_, true, ""}}, + "{\n" + " \"loadBalancingConfig\":[\n" + " {\"pick_first\":{} }\n" + " ]\n" + "}"); + // This should fail since we do not have a non-balancer backend + CheckRpcSendFailure(); + // Check LB policy name for the channel. + EXPECT_EQ("pick_first", channel_->GetLoadBalancingPolicyName()); +} + +TEST_F(SingleBalancerTest, + SelectGrpclbWithMigrationServiceConfigAndNoAddresses) { + const int kFallbackTimeoutMs = 200 * grpc_test_slowdown_factor(); + ResetStub(kFallbackTimeoutMs); + SetNextResolution({}, + "{\n" + " \"loadBalancingConfig\":[\n" + " { \"does_not_exist\":{} },\n" + " { \"grpclb\":{} }\n" + " ]\n" + "}"); + // Try to connect. + EXPECT_EQ(GRPC_CHANNEL_IDLE, channel_->GetState(true)); + // Should go into state TRANSIENT_FAILURE when we enter fallback mode. + const gpr_timespec deadline = grpc_timeout_seconds_to_deadline(1); + grpc_connectivity_state state; + while ((state = channel_->GetState(false)) != + GRPC_CHANNEL_TRANSIENT_FAILURE) { + ASSERT_TRUE(channel_->WaitForStateChange(state, deadline)); + } + // Check LB policy name for the channel. + EXPECT_EQ("grpclb", channel_->GetLoadBalancingPolicyName()); +} + +TEST_F(SingleBalancerTest, + SelectGrpclbWithMigrationServiceConfigAndNoBalancerAddresses) { + const int kFallbackTimeoutMs = 200 * grpc_test_slowdown_factor(); + ResetStub(kFallbackTimeoutMs); + // Resolution includes fallback address but no balancers. + SetNextResolution({AddressData{backends_[0]->port_, false, ""}}, + "{\n" + " \"loadBalancingConfig\":[\n" + " { \"does_not_exist\":{} },\n" + " { \"grpclb\":{} }\n" + " ]\n" + "}"); + CheckRpcSendOk(1, 1000 /* timeout_ms */, true /* wait_for_ready */); + // Check LB policy name for the channel. + EXPECT_EQ("grpclb", channel_->GetLoadBalancingPolicyName()); +} + +TEST_F(SingleBalancerTest, UsePickFirstChildPolicy) { + SetNextResolutionAllBalancers( + "{\n" + " \"loadBalancingConfig\":[\n" + " { \"grpclb\":{\n" + " \"childPolicy\":[\n" + " { \"pick_first\":{} }\n" + " ]\n" + " } }\n" + " ]\n" + "}"); + ScheduleResponseForBalancer( + 0, BalancerServiceImpl::BuildResponseForBackends(GetBackendPorts(), {}), + 0); + const size_t kNumRpcs = num_backends_ * 2; + CheckRpcSendOk(kNumRpcs, 1000 /* timeout_ms */, true /* wait_for_ready */); + balancers_[0]->service_.NotifyDoneWithServerlists(); + // Check that all requests went to the first backend. This verifies + // that we used pick_first instead of round_robin as the child policy. + EXPECT_EQ(backends_[0]->service_.request_count(), kNumRpcs); + for (size_t i = 1; i < backends_.size(); ++i) { + EXPECT_EQ(backends_[i]->service_.request_count(), 0UL); + } + // The balancer got a single request. + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); + // and sent a single response. + EXPECT_EQ(1U, balancers_[0]->service_.response_count()); + // Check LB policy name for the channel. + EXPECT_EQ("grpclb", channel_->GetLoadBalancingPolicyName()); +} + +TEST_F(SingleBalancerTest, SwapChildPolicy) { + SetNextResolutionAllBalancers( + "{\n" + " \"loadBalancingConfig\":[\n" + " { \"grpclb\":{\n" + " \"childPolicy\":[\n" + " { \"pick_first\":{} }\n" + " ]\n" + " } }\n" + " ]\n" + "}"); + ScheduleResponseForBalancer( + 0, BalancerServiceImpl::BuildResponseForBackends(GetBackendPorts(), {}), + 0); + const size_t kNumRpcs = num_backends_ * 2; + CheckRpcSendOk(kNumRpcs, 1000 /* timeout_ms */, true /* wait_for_ready */); + // Check that all requests went to the first backend. This verifies + // that we used pick_first instead of round_robin as the child policy. + EXPECT_EQ(backends_[0]->service_.request_count(), kNumRpcs); + for (size_t i = 1; i < backends_.size(); ++i) { + EXPECT_EQ(backends_[i]->service_.request_count(), 0UL); + } + // Send new resolution that removes child policy from service config. + SetNextResolutionAllBalancers("{}"); + WaitForAllBackends(); + CheckRpcSendOk(kNumRpcs, 1000 /* timeout_ms */, true /* wait_for_ready */); + // Check that every backend saw the same number of requests. This verifies + // that we used round_robin. + for (size_t i = 0; i < backends_.size(); ++i) { + EXPECT_EQ(backends_[i]->service_.request_count(), 2UL); + } + // Done. + balancers_[0]->service_.NotifyDoneWithServerlists(); + // The balancer got a single request. + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); + // and sent a single response. + EXPECT_EQ(1U, balancers_[0]->service_.response_count()); + // Check LB policy name for the channel. + EXPECT_EQ("grpclb", channel_->GetLoadBalancingPolicyName()); +} + +TEST_F(SingleBalancerTest, UpdatesGoToMostRecentChildPolicy) { + const int kFallbackTimeoutMs = 200 * grpc_test_slowdown_factor(); + ResetStub(kFallbackTimeoutMs); + int unreachable_balancer_port = grpc_pick_unused_port_or_die(); + int unreachable_backend_port = grpc_pick_unused_port_or_die(); + // Phase 1: Start with RR pointing to first backend. + gpr_log(GPR_INFO, "PHASE 1: Initial setup with RR with first backend"); + SetNextResolution( + { + // Unreachable balancer. + {unreachable_balancer_port, true, ""}, + // Fallback address: first backend. + {backends_[0]->port_, false, ""}, + }, + "{\n" + " \"loadBalancingConfig\":[\n" + " { \"grpclb\":{\n" + " \"childPolicy\":[\n" + " { \"round_robin\":{} }\n" + " ]\n" + " } }\n" + " ]\n" + "}"); + // RPCs should go to first backend. + WaitForBackend(0); + // Phase 2: Switch to PF pointing to unreachable backend. + gpr_log(GPR_INFO, "PHASE 2: Update to use PF with unreachable backend"); + SetNextResolution( + { + // Unreachable balancer. + {unreachable_balancer_port, true, ""}, + // Fallback address: unreachable backend. + {unreachable_backend_port, false, ""}, + }, + "{\n" + " \"loadBalancingConfig\":[\n" + " { \"grpclb\":{\n" + " \"childPolicy\":[\n" + " { \"pick_first\":{} }\n" + " ]\n" + " } }\n" + " ]\n" + "}"); + // RPCs should continue to go to the first backend, because the new + // PF child policy will never go into state READY. + WaitForBackend(0); + // Phase 3: Switch back to RR pointing to second and third backends. + // This ensures that we create a new policy rather than updating the + // pending PF policy. + gpr_log(GPR_INFO, "PHASE 3: Update to use RR again with two backends"); + SetNextResolution( + { + // Unreachable balancer. + {unreachable_balancer_port, true, ""}, + // Fallback address: second and third backends. + {backends_[1]->port_, false, ""}, + {backends_[2]->port_, false, ""}, + }, + "{\n" + " \"loadBalancingConfig\":[\n" + " { \"grpclb\":{\n" + " \"childPolicy\":[\n" + " { \"round_robin\":{} }\n" + " ]\n" + " } }\n" + " ]\n" + "}"); + // RPCs should go to the second and third backends. + WaitForBackend(1); + WaitForBackend(2); +} + +TEST_F(SingleBalancerTest, SameBackendListedMultipleTimes) { + SetNextResolutionAllBalancers(); + // Same backend listed twice. + std::vector ports; + ports.push_back(backends_[0]->port_); + ports.push_back(backends_[0]->port_); + const size_t kNumRpcsPerAddress = 10; + ScheduleResponseForBalancer( + 0, BalancerServiceImpl::BuildResponseForBackends(ports, {}), 0); + // We need to wait for the backend to come online. + WaitForBackend(0); + // Send kNumRpcsPerAddress RPCs per server. + CheckRpcSendOk(kNumRpcsPerAddress * ports.size()); + // Backend should have gotten 20 requests. + EXPECT_EQ(kNumRpcsPerAddress * 2, backends_[0]->service_.request_count()); + // And they should have come from a single client port, because of + // subchannel sharing. + EXPECT_EQ(1UL, backends_[0]->service_.clients().size()); + balancers_[0]->service_.NotifyDoneWithServerlists(); +} + TEST_F(SingleBalancerTest, SecureNaming) { ResetStub(0, kApplicationTargetName_ + ";lb"); - SetNextResolution({AddressData{balancer_servers_[0].port_, true, "lb"}}); + SetNextResolution({AddressData{balancers_[0]->port_, true, "lb"}}); const size_t kNumRpcsPerAddress = 100; ScheduleResponseForBalancer( 0, BalancerServiceImpl::BuildResponseForBackends(GetBackendPorts(), {}), @@ -681,14 +992,13 @@ TEST_F(SingleBalancerTest, SecureNaming) { // Each backend should have gotten 100 requests. for (size_t i = 0; i < backends_.size(); ++i) { - EXPECT_EQ(kNumRpcsPerAddress, - backend_servers_[i].service_->request_count()); + EXPECT_EQ(kNumRpcsPerAddress, backends_[i]->service_.request_count()); } - balancers_[0]->NotifyDoneWithServerlists(); + balancers_[0]->service_.NotifyDoneWithServerlists(); // The balancer got a single request. - EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); // and sent a single response. - EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); + EXPECT_EQ(1U, balancers_[0]->service_.response_count()); // Check LB policy name for the channel. EXPECT_EQ("grpclb", channel_->GetLoadBalancingPolicyName()); } @@ -700,8 +1010,7 @@ TEST_F(SingleBalancerTest, SecureNamingDeathTest) { ASSERT_DEATH( { ResetStub(0, kApplicationTargetName_ + ";lb"); - SetNextResolution( - {AddressData{balancer_servers_[0].port_, true, "woops"}}); + SetNextResolution({AddressData{balancers_[0]->port_, true, "woops"}}); channel_->WaitForConnected(grpc_timeout_seconds_to_deadline(1)); }, ""); @@ -717,10 +1026,9 @@ TEST_F(SingleBalancerTest, InitiallyEmptyServerlist) { ScheduleResponseForBalancer( 0, BalancerServiceImpl::BuildResponseForBackends(GetBackendPorts(), {}), kServerlistDelayMs); - const auto t0 = system_clock::now(); // Client will block: LB will initially send empty serverlist. - CheckRpcSendOk(1, kCallDeadlineMs); + CheckRpcSendOk(1, kCallDeadlineMs, true /* wait_for_ready */); const auto ellapsed_ms = std::chrono::duration_cast( system_clock::now() - t0); @@ -729,11 +1037,11 @@ TEST_F(SingleBalancerTest, InitiallyEmptyServerlist) { // populated serverlist but under the call's deadline (which is enforced by // the call's deadline). EXPECT_GT(ellapsed_ms.count(), kServerlistDelayMs); - balancers_[0]->NotifyDoneWithServerlists(); + balancers_[0]->service_.NotifyDoneWithServerlists(); // The balancer got a single request. - EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); // and sent two responses. - EXPECT_EQ(2U, balancer_servers_[0].service_->response_count()); + EXPECT_EQ(2U, balancers_[0]->service_.response_count()); } TEST_F(SingleBalancerTest, AllServersUnreachableFailFast) { @@ -748,24 +1056,24 @@ TEST_F(SingleBalancerTest, AllServersUnreachableFailFast) { const Status status = SendRpc(); // The error shouldn't be DEADLINE_EXCEEDED. EXPECT_EQ(StatusCode::UNAVAILABLE, status.error_code()); - balancers_[0]->NotifyDoneWithServerlists(); + balancers_[0]->service_.NotifyDoneWithServerlists(); // The balancer got a single request. - EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); // and sent a single response. - EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); + EXPECT_EQ(1U, balancers_[0]->service_.response_count()); } TEST_F(SingleBalancerTest, Fallback) { SetNextResolutionAllBalancers(); const int kFallbackTimeoutMs = 200 * grpc_test_slowdown_factor(); const int kServerlistDelayMs = 500 * grpc_test_slowdown_factor(); - const size_t kNumBackendInResolution = backends_.size() / 2; + const size_t kNumBackendsInResolution = backends_.size() / 2; ResetStub(kFallbackTimeoutMs); std::vector addresses; - addresses.emplace_back(AddressData{balancer_servers_[0].port_, true, ""}); - for (size_t i = 0; i < kNumBackendInResolution; ++i) { - addresses.emplace_back(AddressData{backend_servers_[i].port_, false, ""}); + addresses.emplace_back(AddressData{balancers_[0]->port_, true, ""}); + for (size_t i = 0; i < kNumBackendsInResolution; ++i) { + addresses.emplace_back(AddressData{backends_[i]->port_, false, ""}); } SetNextResolution(addresses); @@ -773,67 +1081,67 @@ TEST_F(SingleBalancerTest, Fallback) { ScheduleResponseForBalancer( 0, BalancerServiceImpl::BuildResponseForBackends( - GetBackendPorts(kNumBackendInResolution /* start_index */), {}), + GetBackendPorts(kNumBackendsInResolution /* start_index */), {}), kServerlistDelayMs); // Wait until all the fallback backends are reachable. - for (size_t i = 0; i < kNumBackendInResolution; ++i) { + for (size_t i = 0; i < kNumBackendsInResolution; ++i) { WaitForBackend(i); } // The first request. gpr_log(GPR_INFO, "========= BEFORE FIRST BATCH =========="); - CheckRpcSendOk(kNumBackendInResolution); + CheckRpcSendOk(kNumBackendsInResolution); gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH =========="); // Fallback is used: each backend returned by the resolver should have // gotten one request. - for (size_t i = 0; i < kNumBackendInResolution; ++i) { - EXPECT_EQ(1U, backend_servers_[i].service_->request_count()); + for (size_t i = 0; i < kNumBackendsInResolution; ++i) { + EXPECT_EQ(1U, backends_[i]->service_.request_count()); } - for (size_t i = kNumBackendInResolution; i < backends_.size(); ++i) { - EXPECT_EQ(0U, backend_servers_[i].service_->request_count()); + for (size_t i = kNumBackendsInResolution; i < backends_.size(); ++i) { + EXPECT_EQ(0U, backends_[i]->service_.request_count()); } // Wait until the serverlist reception has been processed and all backends // in the serverlist are reachable. - for (size_t i = kNumBackendInResolution; i < backends_.size(); ++i) { + for (size_t i = kNumBackendsInResolution; i < backends_.size(); ++i) { WaitForBackend(i); } // Send out the second request. gpr_log(GPR_INFO, "========= BEFORE SECOND BATCH =========="); - CheckRpcSendOk(backends_.size() - kNumBackendInResolution); + CheckRpcSendOk(backends_.size() - kNumBackendsInResolution); gpr_log(GPR_INFO, "========= DONE WITH SECOND BATCH =========="); // Serverlist is used: each backend returned by the balancer should // have gotten one request. - for (size_t i = 0; i < kNumBackendInResolution; ++i) { - EXPECT_EQ(0U, backend_servers_[i].service_->request_count()); + for (size_t i = 0; i < kNumBackendsInResolution; ++i) { + EXPECT_EQ(0U, backends_[i]->service_.request_count()); } - for (size_t i = kNumBackendInResolution; i < backends_.size(); ++i) { - EXPECT_EQ(1U, backend_servers_[i].service_->request_count()); + for (size_t i = kNumBackendsInResolution; i < backends_.size(); ++i) { + EXPECT_EQ(1U, backends_[i]->service_.request_count()); } - balancers_[0]->NotifyDoneWithServerlists(); + balancers_[0]->service_.NotifyDoneWithServerlists(); // The balancer got a single request. - EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); // and sent a single response. - EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); + EXPECT_EQ(1U, balancers_[0]->service_.response_count()); } TEST_F(SingleBalancerTest, FallbackUpdate) { SetNextResolutionAllBalancers(); const int kFallbackTimeoutMs = 200 * grpc_test_slowdown_factor(); const int kServerlistDelayMs = 500 * grpc_test_slowdown_factor(); - const size_t kNumBackendInResolution = backends_.size() / 3; - const size_t kNumBackendInResolutionUpdate = backends_.size() / 3; + const size_t kNumBackendsInResolution = backends_.size() / 3; + const size_t kNumBackendsInResolutionUpdate = backends_.size() / 3; ResetStub(kFallbackTimeoutMs); std::vector addresses; - addresses.emplace_back(AddressData{balancer_servers_[0].port_, true, ""}); - for (size_t i = 0; i < kNumBackendInResolution; ++i) { - addresses.emplace_back(AddressData{backend_servers_[i].port_, false, ""}); + addresses.emplace_back(AddressData{balancers_[0]->port_, true, ""}); + for (size_t i = 0; i < kNumBackendsInResolution; ++i) { + addresses.emplace_back(AddressData{backends_[i]->port_, false, ""}); } SetNextResolution(addresses); @@ -841,93 +1149,229 @@ TEST_F(SingleBalancerTest, FallbackUpdate) { ScheduleResponseForBalancer( 0, BalancerServiceImpl::BuildResponseForBackends( - GetBackendPorts(kNumBackendInResolution + - kNumBackendInResolutionUpdate /* start_index */), + GetBackendPorts(kNumBackendsInResolution + + kNumBackendsInResolutionUpdate /* start_index */), {}), kServerlistDelayMs); // Wait until all the fallback backends are reachable. - for (size_t i = 0; i < kNumBackendInResolution; ++i) { + for (size_t i = 0; i < kNumBackendsInResolution; ++i) { WaitForBackend(i); } // The first request. gpr_log(GPR_INFO, "========= BEFORE FIRST BATCH =========="); - CheckRpcSendOk(kNumBackendInResolution); + CheckRpcSendOk(kNumBackendsInResolution); gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH =========="); // Fallback is used: each backend returned by the resolver should have // gotten one request. - for (size_t i = 0; i < kNumBackendInResolution; ++i) { - EXPECT_EQ(1U, backend_servers_[i].service_->request_count()); + for (size_t i = 0; i < kNumBackendsInResolution; ++i) { + EXPECT_EQ(1U, backends_[i]->service_.request_count()); } - for (size_t i = kNumBackendInResolution; i < backends_.size(); ++i) { - EXPECT_EQ(0U, backend_servers_[i].service_->request_count()); + for (size_t i = kNumBackendsInResolution; i < backends_.size(); ++i) { + EXPECT_EQ(0U, backends_[i]->service_.request_count()); } addresses.clear(); - addresses.emplace_back(AddressData{balancer_servers_[0].port_, true, ""}); - for (size_t i = kNumBackendInResolution; - i < kNumBackendInResolution + kNumBackendInResolutionUpdate; ++i) { - addresses.emplace_back(AddressData{backend_servers_[i].port_, false, ""}); + addresses.emplace_back(AddressData{balancers_[0]->port_, true, ""}); + for (size_t i = kNumBackendsInResolution; + i < kNumBackendsInResolution + kNumBackendsInResolutionUpdate; ++i) { + addresses.emplace_back(AddressData{backends_[i]->port_, false, ""}); } SetNextResolution(addresses); // Wait until the resolution update has been processed and all the new // fallback backends are reachable. - for (size_t i = kNumBackendInResolution; - i < kNumBackendInResolution + kNumBackendInResolutionUpdate; ++i) { + for (size_t i = kNumBackendsInResolution; + i < kNumBackendsInResolution + kNumBackendsInResolutionUpdate; ++i) { WaitForBackend(i); } // Send out the second request. gpr_log(GPR_INFO, "========= BEFORE SECOND BATCH =========="); - CheckRpcSendOk(kNumBackendInResolutionUpdate); + CheckRpcSendOk(kNumBackendsInResolutionUpdate); gpr_log(GPR_INFO, "========= DONE WITH SECOND BATCH =========="); // The resolution update is used: each backend in the resolution update should // have gotten one request. - for (size_t i = 0; i < kNumBackendInResolution; ++i) { - EXPECT_EQ(0U, backend_servers_[i].service_->request_count()); + for (size_t i = 0; i < kNumBackendsInResolution; ++i) { + EXPECT_EQ(0U, backends_[i]->service_.request_count()); } - for (size_t i = kNumBackendInResolution; - i < kNumBackendInResolution + kNumBackendInResolutionUpdate; ++i) { - EXPECT_EQ(1U, backend_servers_[i].service_->request_count()); + for (size_t i = kNumBackendsInResolution; + i < kNumBackendsInResolution + kNumBackendsInResolutionUpdate; ++i) { + EXPECT_EQ(1U, backends_[i]->service_.request_count()); } - for (size_t i = kNumBackendInResolution + kNumBackendInResolutionUpdate; + for (size_t i = kNumBackendsInResolution + kNumBackendsInResolutionUpdate; i < backends_.size(); ++i) { - EXPECT_EQ(0U, backend_servers_[i].service_->request_count()); + EXPECT_EQ(0U, backends_[i]->service_.request_count()); } // Wait until the serverlist reception has been processed and all backends // in the serverlist are reachable. - for (size_t i = kNumBackendInResolution + kNumBackendInResolutionUpdate; + for (size_t i = kNumBackendsInResolution + kNumBackendsInResolutionUpdate; i < backends_.size(); ++i) { WaitForBackend(i); } // Send out the third request. gpr_log(GPR_INFO, "========= BEFORE THIRD BATCH =========="); - CheckRpcSendOk(backends_.size() - kNumBackendInResolution - - kNumBackendInResolutionUpdate); + CheckRpcSendOk(backends_.size() - kNumBackendsInResolution - + kNumBackendsInResolutionUpdate); gpr_log(GPR_INFO, "========= DONE WITH THIRD BATCH =========="); // Serverlist is used: each backend returned by the balancer should // have gotten one request. for (size_t i = 0; - i < kNumBackendInResolution + kNumBackendInResolutionUpdate; ++i) { - EXPECT_EQ(0U, backend_servers_[i].service_->request_count()); + i < kNumBackendsInResolution + kNumBackendsInResolutionUpdate; ++i) { + EXPECT_EQ(0U, backends_[i]->service_.request_count()); } - for (size_t i = kNumBackendInResolution + kNumBackendInResolutionUpdate; + for (size_t i = kNumBackendsInResolution + kNumBackendsInResolutionUpdate; i < backends_.size(); ++i) { - EXPECT_EQ(1U, backend_servers_[i].service_->request_count()); + EXPECT_EQ(1U, backends_[i]->service_.request_count()); } - balancers_[0]->NotifyDoneWithServerlists(); + balancers_[0]->service_.NotifyDoneWithServerlists(); // The balancer got a single request. - EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); // and sent a single response. - EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); + EXPECT_EQ(1U, balancers_[0]->service_.response_count()); +} + +TEST_F(SingleBalancerTest, + FallbackAfterStartup_LoseContactWithBalancerThenBackends) { + // First two backends are fallback, last two are pointed to by balancer. + const size_t kNumFallbackBackends = 2; + const size_t kNumBalancerBackends = backends_.size() - kNumFallbackBackends; + std::vector addresses; + for (size_t i = 0; i < kNumFallbackBackends; ++i) { + addresses.emplace_back(AddressData{backends_[i]->port_, false, ""}); + } + for (size_t i = 0; i < balancers_.size(); ++i) { + addresses.emplace_back(AddressData{balancers_[i]->port_, true, ""}); + } + SetNextResolution(addresses); + ScheduleResponseForBalancer(0, + BalancerServiceImpl::BuildResponseForBackends( + GetBackendPorts(kNumFallbackBackends), {}), + 0); + // Try to connect. + channel_->GetState(true /* try_to_connect */); + WaitForAllBackends(1 /* num_requests_multiple_of */, + kNumFallbackBackends /* start_index */); + // Stop balancer. RPCs should continue going to backends from balancer. + balancers_[0]->Shutdown(); + CheckRpcSendOk(100 * kNumBalancerBackends); + for (size_t i = kNumFallbackBackends; i < backends_.size(); ++i) { + EXPECT_EQ(100UL, backends_[i]->service_.request_count()); + } + // Stop backends from balancer. This should put us in fallback mode. + for (size_t i = kNumFallbackBackends; i < backends_.size(); ++i) { + ShutdownBackend(i); + } + WaitForAllBackends(1 /* num_requests_multiple_of */, 0 /* start_index */, + kNumFallbackBackends /* stop_index */); + // Restart the backends from the balancer. We should *not* start + // sending traffic back to them at this point (although the behavior + // in xds may be different). + for (size_t i = kNumFallbackBackends; i < backends_.size(); ++i) { + StartBackend(i); + } + CheckRpcSendOk(100 * kNumBalancerBackends); + for (size_t i = 0; i < kNumFallbackBackends; ++i) { + EXPECT_EQ(100UL, backends_[i]->service_.request_count()); + } + // Now start the balancer again. This should cause us to exit + // fallback mode. + balancers_[0]->Start(server_host_); + ScheduleResponseForBalancer(0, + BalancerServiceImpl::BuildResponseForBackends( + GetBackendPorts(kNumFallbackBackends), {}), + 0); + WaitForAllBackends(1 /* num_requests_multiple_of */, + kNumFallbackBackends /* start_index */); +} + +TEST_F(SingleBalancerTest, + FallbackAfterStartup_LoseContactWithBackendsThenBalancer) { + // First two backends are fallback, last two are pointed to by balancer. + const size_t kNumFallbackBackends = 2; + const size_t kNumBalancerBackends = backends_.size() - kNumFallbackBackends; + std::vector addresses; + for (size_t i = 0; i < kNumFallbackBackends; ++i) { + addresses.emplace_back(AddressData{backends_[i]->port_, false, ""}); + } + for (size_t i = 0; i < balancers_.size(); ++i) { + addresses.emplace_back(AddressData{balancers_[i]->port_, true, ""}); + } + SetNextResolution(addresses); + ScheduleResponseForBalancer(0, + BalancerServiceImpl::BuildResponseForBackends( + GetBackendPorts(kNumFallbackBackends), {}), + 0); + // Try to connect. + channel_->GetState(true /* try_to_connect */); + WaitForAllBackends(1 /* num_requests_multiple_of */, + kNumFallbackBackends /* start_index */); + // Stop backends from balancer. Since we are still in contact with + // the balancer at this point, RPCs should be failing. + for (size_t i = kNumFallbackBackends; i < backends_.size(); ++i) { + ShutdownBackend(i); + } + CheckRpcSendFailure(); + // Stop balancer. This should put us in fallback mode. + balancers_[0]->Shutdown(); + WaitForAllBackends(1 /* num_requests_multiple_of */, 0 /* start_index */, + kNumFallbackBackends /* stop_index */); + // Restart the backends from the balancer. We should *not* start + // sending traffic back to them at this point (although the behavior + // in xds may be different). + for (size_t i = kNumFallbackBackends; i < backends_.size(); ++i) { + StartBackend(i); + } + CheckRpcSendOk(100 * kNumBalancerBackends); + for (size_t i = 0; i < kNumFallbackBackends; ++i) { + EXPECT_EQ(100UL, backends_[i]->service_.request_count()); + } + // Now start the balancer again. This should cause us to exit + // fallback mode. + balancers_[0]->Start(server_host_); + ScheduleResponseForBalancer(0, + BalancerServiceImpl::BuildResponseForBackends( + GetBackendPorts(kNumFallbackBackends), {}), + 0); + WaitForAllBackends(1 /* num_requests_multiple_of */, + kNumFallbackBackends /* start_index */); +} + +TEST_F(SingleBalancerTest, FallbackEarlyWhenBalancerChannelFails) { + const int kFallbackTimeoutMs = 10000 * grpc_test_slowdown_factor(); + ResetStub(kFallbackTimeoutMs); + // Return an unreachable balancer and one fallback backend. + std::vector addresses; + addresses.emplace_back(AddressData{grpc_pick_unused_port_or_die(), true, ""}); + addresses.emplace_back(AddressData{backends_[0]->port_, false, ""}); + SetNextResolution(addresses); + // Send RPC with deadline less than the fallback timeout and make sure it + // succeeds. + CheckRpcSendOk(/* times */ 1, /* timeout_ms */ 1000, + /* wait_for_ready */ false); +} + +TEST_F(SingleBalancerTest, FallbackEarlyWhenBalancerCallFails) { + const int kFallbackTimeoutMs = 10000 * grpc_test_slowdown_factor(); + ResetStub(kFallbackTimeoutMs); + // Return an unreachable balancer and one fallback backend. + std::vector addresses; + addresses.emplace_back(AddressData{balancers_[0]->port_, true, ""}); + addresses.emplace_back(AddressData{backends_[0]->port_, false, ""}); + SetNextResolution(addresses); + // Balancer drops call without sending a serverlist. + balancers_[0]->service_.NotifyDoneWithServerlists(); + // Send RPC with deadline less than the fallback timeout and make sure it + // succeeds. + CheckRpcSendOk(/* times */ 1, /* timeout_ms */ 1000, + /* wait_for_ready */ false); } TEST_F(SingleBalancerTest, BackendsRestart) { @@ -940,27 +1384,17 @@ TEST_F(SingleBalancerTest, BackendsRestart) { channel_->GetState(true /* try_to_connect */); // Send kNumRpcsPerAddress RPCs per server. CheckRpcSendOk(kNumRpcsPerAddress * num_backends_); - balancers_[0]->NotifyDoneWithServerlists(); + // Stop backends. RPCs should fail. + ShutdownAllBackends(); + CheckRpcSendFailure(); + // Restart backends. RPCs should start succeeding again. + StartAllBackends(); + CheckRpcSendOk(1 /* times */, 2000 /* timeout_ms */, + true /* wait_for_ready */); // The balancer got a single request. - EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); // and sent a single response. - EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); - for (size_t i = 0; i < backends_.size(); ++i) { - if (backends_[i]->Shutdown()) backend_servers_[i].Shutdown(); - } - CheckRpcSendFailure(); - for (size_t i = 0; i < num_backends_; ++i) { - backends_.emplace_back(new BackendServiceImpl()); - backend_servers_.emplace_back(ServerThread( - "backend", server_host_, backends_.back().get())); - } - // The following RPC will fail due to the backend ports having changed. It - // will nonetheless exercise the grpclb-roundrobin handling of the RR policy - // having gone into shutdown. - // TODO(dgq): implement the "backend restart" component as well. We need extra - // machinery to either update the LB responses "on the fly" or instruct - // backends which ports to restart on. - CheckRpcSendFailure(); + EXPECT_EQ(1U, balancers_[0]->service_.response_count()); } class UpdatesTest : public GrpclbEnd2endTest { @@ -968,7 +1402,7 @@ class UpdatesTest : public GrpclbEnd2endTest { UpdatesTest() : GrpclbEnd2endTest(4, 3, 0) {} }; -TEST_F(UpdatesTest, UpdateBalancers) { +TEST_F(UpdatesTest, UpdateBalancersButKeepUsingOriginalBalancer) { SetNextResolutionAllBalancers(); const std::vector first_backend{GetBackendPorts()[0]}; const std::vector second_backend{GetBackendPorts()[1]}; @@ -986,47 +1420,40 @@ TEST_F(UpdatesTest, UpdateBalancers) { gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH =========="); // All 10 requests should have gone to the first backend. - EXPECT_EQ(10U, backend_servers_[0].service_->request_count()); + EXPECT_EQ(10U, backends_[0]->service_.request_count()); - balancers_[0]->NotifyDoneWithServerlists(); - balancers_[1]->NotifyDoneWithServerlists(); - balancers_[2]->NotifyDoneWithServerlists(); // Balancer 0 got a single request. - EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); // and sent a single response. - EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); - EXPECT_EQ(0U, balancer_servers_[1].service_->request_count()); - EXPECT_EQ(0U, balancer_servers_[1].service_->response_count()); - EXPECT_EQ(0U, balancer_servers_[2].service_->request_count()); - EXPECT_EQ(0U, balancer_servers_[2].service_->response_count()); + EXPECT_EQ(1U, balancers_[0]->service_.response_count()); + EXPECT_EQ(0U, balancers_[1]->service_.request_count()); + EXPECT_EQ(0U, balancers_[1]->service_.response_count()); + EXPECT_EQ(0U, balancers_[2]->service_.request_count()); + EXPECT_EQ(0U, balancers_[2]->service_.response_count()); std::vector addresses; - addresses.emplace_back(AddressData{balancer_servers_[1].port_, true, ""}); + addresses.emplace_back(AddressData{balancers_[1]->port_, true, ""}); gpr_log(GPR_INFO, "========= ABOUT TO UPDATE 1 =========="); SetNextResolution(addresses); gpr_log(GPR_INFO, "========= UPDATE 1 DONE =========="); - // Wait until update has been processed, as signaled by the second backend - // receiving a request. - EXPECT_EQ(0U, backend_servers_[1].service_->request_count()); - WaitForBackend(1); + EXPECT_EQ(0U, backends_[1]->service_.request_count()); + gpr_timespec deadline = gpr_time_add( + gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_millis(10000, GPR_TIMESPAN)); + // Send 10 seconds worth of RPCs + do { + CheckRpcSendOk(); + } while (gpr_time_cmp(gpr_now(GPR_CLOCK_REALTIME), deadline) < 0); + // The current LB call is still working, so grpclb continued using it to the + // first balancer, which doesn't assign the second backend. + EXPECT_EQ(0U, backends_[1]->service_.request_count()); - backend_servers_[1].service_->ResetCounters(); - gpr_log(GPR_INFO, "========= BEFORE SECOND BATCH =========="); - CheckRpcSendOk(10); - gpr_log(GPR_INFO, "========= DONE WITH SECOND BATCH =========="); - // All 10 requests should have gone to the second backend. - EXPECT_EQ(10U, backend_servers_[1].service_->request_count()); - - balancers_[0]->NotifyDoneWithServerlists(); - balancers_[1]->NotifyDoneWithServerlists(); - balancers_[2]->NotifyDoneWithServerlists(); - EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); - EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); - EXPECT_EQ(1U, balancer_servers_[1].service_->request_count()); - EXPECT_EQ(1U, balancer_servers_[1].service_->response_count()); - EXPECT_EQ(0U, balancer_servers_[2].service_->request_count()); - EXPECT_EQ(0U, balancer_servers_[2].service_->response_count()); + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); + EXPECT_EQ(1U, balancers_[0]->service_.response_count()); + EXPECT_EQ(0U, balancers_[1]->service_.request_count()); + EXPECT_EQ(0U, balancers_[1]->service_.response_count()); + EXPECT_EQ(0U, balancers_[2]->service_.request_count()); + EXPECT_EQ(0U, balancers_[2]->service_.response_count()); } // Send an update with the same set of LBs as the one in SetUp() in order to @@ -1051,27 +1478,27 @@ TEST_F(UpdatesTest, UpdateBalancersRepeated) { gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH =========="); // All 10 requests should have gone to the first backend. - EXPECT_EQ(10U, backend_servers_[0].service_->request_count()); + EXPECT_EQ(10U, backends_[0]->service_.request_count()); - balancers_[0]->NotifyDoneWithServerlists(); + balancers_[0]->service_.NotifyDoneWithServerlists(); // Balancer 0 got a single request. - EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); // and sent a single response. - EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); - EXPECT_EQ(0U, balancer_servers_[1].service_->request_count()); - EXPECT_EQ(0U, balancer_servers_[1].service_->response_count()); - EXPECT_EQ(0U, balancer_servers_[2].service_->request_count()); - EXPECT_EQ(0U, balancer_servers_[2].service_->response_count()); + EXPECT_EQ(1U, balancers_[0]->service_.response_count()); + EXPECT_EQ(0U, balancers_[1]->service_.request_count()); + EXPECT_EQ(0U, balancers_[1]->service_.response_count()); + EXPECT_EQ(0U, balancers_[2]->service_.request_count()); + EXPECT_EQ(0U, balancers_[2]->service_.response_count()); std::vector addresses; - addresses.emplace_back(AddressData{balancer_servers_[0].port_, true, ""}); - addresses.emplace_back(AddressData{balancer_servers_[1].port_, true, ""}); - addresses.emplace_back(AddressData{balancer_servers_[2].port_, true, ""}); + addresses.emplace_back(AddressData{balancers_[0]->port_, true, ""}); + addresses.emplace_back(AddressData{balancers_[1]->port_, true, ""}); + addresses.emplace_back(AddressData{balancers_[2]->port_, true, ""}); gpr_log(GPR_INFO, "========= ABOUT TO UPDATE 1 =========="); SetNextResolution(addresses); gpr_log(GPR_INFO, "========= UPDATE 1 DONE =========="); - EXPECT_EQ(0U, backend_servers_[1].service_->request_count()); + EXPECT_EQ(0U, backends_[1]->service_.request_count()); gpr_timespec deadline = gpr_time_add( gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_millis(10000, GPR_TIMESPAN)); // Send 10 seconds worth of RPCs @@ -1080,17 +1507,17 @@ TEST_F(UpdatesTest, UpdateBalancersRepeated) { } while (gpr_time_cmp(gpr_now(GPR_CLOCK_REALTIME), deadline) < 0); // grpclb continued using the original LB call to the first balancer, which // doesn't assign the second backend. - EXPECT_EQ(0U, backend_servers_[1].service_->request_count()); - balancers_[0]->NotifyDoneWithServerlists(); + EXPECT_EQ(0U, backends_[1]->service_.request_count()); + balancers_[0]->service_.NotifyDoneWithServerlists(); addresses.clear(); - addresses.emplace_back(AddressData{balancer_servers_[0].port_, true, ""}); - addresses.emplace_back(AddressData{balancer_servers_[1].port_, true, ""}); + addresses.emplace_back(AddressData{balancers_[0]->port_, true, ""}); + addresses.emplace_back(AddressData{balancers_[1]->port_, true, ""}); gpr_log(GPR_INFO, "========= ABOUT TO UPDATE 2 =========="); SetNextResolution(addresses); gpr_log(GPR_INFO, "========= UPDATE 2 DONE =========="); - EXPECT_EQ(0U, backend_servers_[1].service_->request_count()); + EXPECT_EQ(0U, backends_[1]->service_.request_count()); deadline = gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_millis(10000, GPR_TIMESPAN)); // Send 10 seconds worth of RPCs @@ -1099,13 +1526,13 @@ TEST_F(UpdatesTest, UpdateBalancersRepeated) { } while (gpr_time_cmp(gpr_now(GPR_CLOCK_REALTIME), deadline) < 0); // grpclb continued using the original LB call to the first balancer, which // doesn't assign the second backend. - EXPECT_EQ(0U, backend_servers_[1].service_->request_count()); - balancers_[0]->NotifyDoneWithServerlists(); + EXPECT_EQ(0U, backends_[1]->service_.request_count()); + balancers_[0]->service_.NotifyDoneWithServerlists(); } TEST_F(UpdatesTest, UpdateBalancersDeadUpdate) { std::vector addresses; - addresses.emplace_back(AddressData{balancer_servers_[0].port_, true, ""}); + addresses.emplace_back(AddressData{balancers_[0]->port_, true, ""}); SetNextResolution(addresses); const std::vector first_backend{GetBackendPorts()[0]}; const std::vector second_backend{GetBackendPorts()[1]}; @@ -1120,12 +1547,11 @@ TEST_F(UpdatesTest, UpdateBalancersDeadUpdate) { CheckRpcSendOk(10); gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH =========="); // All 10 requests should have gone to the first backend. - EXPECT_EQ(10U, backend_servers_[0].service_->request_count()); + EXPECT_EQ(10U, backends_[0]->service_.request_count()); // Kill balancer 0 gpr_log(GPR_INFO, "********** ABOUT TO KILL BALANCER 0 *************"); - balancers_[0]->NotifyDoneWithServerlists(); - if (balancers_[0]->Shutdown()) balancer_servers_[0].Shutdown(); + balancers_[0]->Shutdown(); gpr_log(GPR_INFO, "********** KILLED BALANCER 0 *************"); // This is serviced by the existing RR policy @@ -1133,23 +1559,20 @@ TEST_F(UpdatesTest, UpdateBalancersDeadUpdate) { CheckRpcSendOk(10); gpr_log(GPR_INFO, "========= DONE WITH SECOND BATCH =========="); // All 10 requests should again have gone to the first backend. - EXPECT_EQ(20U, backend_servers_[0].service_->request_count()); - EXPECT_EQ(0U, backend_servers_[1].service_->request_count()); + EXPECT_EQ(20U, backends_[0]->service_.request_count()); + EXPECT_EQ(0U, backends_[1]->service_.request_count()); - balancers_[0]->NotifyDoneWithServerlists(); - balancers_[1]->NotifyDoneWithServerlists(); - balancers_[2]->NotifyDoneWithServerlists(); // Balancer 0 got a single request. - EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); // and sent a single response. - EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); - EXPECT_EQ(0U, balancer_servers_[1].service_->request_count()); - EXPECT_EQ(0U, balancer_servers_[1].service_->response_count()); - EXPECT_EQ(0U, balancer_servers_[2].service_->request_count()); - EXPECT_EQ(0U, balancer_servers_[2].service_->response_count()); + EXPECT_EQ(1U, balancers_[0]->service_.response_count()); + EXPECT_EQ(0U, balancers_[1]->service_.request_count()); + EXPECT_EQ(0U, balancers_[1]->service_.response_count()); + EXPECT_EQ(0U, balancers_[2]->service_.request_count()); + EXPECT_EQ(0U, balancers_[2]->service_.response_count()); addresses.clear(); - addresses.emplace_back(AddressData{balancer_servers_[1].port_, true, ""}); + addresses.emplace_back(AddressData{balancers_[1]->port_, true, ""}); gpr_log(GPR_INFO, "========= ABOUT TO UPDATE 1 =========="); SetNextResolution(addresses); gpr_log(GPR_INFO, "========= UPDATE 1 DONE =========="); @@ -1157,32 +1580,29 @@ TEST_F(UpdatesTest, UpdateBalancersDeadUpdate) { // Wait until update has been processed, as signaled by the second backend // receiving a request. In the meantime, the client continues to be serviced // (by the first backend) without interruption. - EXPECT_EQ(0U, backend_servers_[1].service_->request_count()); + EXPECT_EQ(0U, backends_[1]->service_.request_count()); WaitForBackend(1); // This is serviced by the updated RR policy - backend_servers_[1].service_->ResetCounters(); + backends_[1]->service_.ResetCounters(); gpr_log(GPR_INFO, "========= BEFORE THIRD BATCH =========="); CheckRpcSendOk(10); gpr_log(GPR_INFO, "========= DONE WITH THIRD BATCH =========="); // All 10 requests should have gone to the second backend. - EXPECT_EQ(10U, backend_servers_[1].service_->request_count()); + EXPECT_EQ(10U, backends_[1]->service_.request_count()); - balancers_[0]->NotifyDoneWithServerlists(); - balancers_[1]->NotifyDoneWithServerlists(); - balancers_[2]->NotifyDoneWithServerlists(); - EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); - EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); + EXPECT_EQ(1U, balancers_[0]->service_.response_count()); // The second balancer, published as part of the first update, may end up // getting two requests (that is, 1 <= #req <= 2) if the LB call retry timer // firing races with the arrival of the update containing the second // balancer. - EXPECT_GE(balancer_servers_[1].service_->request_count(), 1U); - EXPECT_GE(balancer_servers_[1].service_->response_count(), 1U); - EXPECT_LE(balancer_servers_[1].service_->request_count(), 2U); - EXPECT_LE(balancer_servers_[1].service_->response_count(), 2U); - EXPECT_EQ(0U, balancer_servers_[2].service_->request_count()); - EXPECT_EQ(0U, balancer_servers_[2].service_->response_count()); + EXPECT_GE(balancers_[1]->service_.request_count(), 1U); + EXPECT_GE(balancers_[1]->service_.response_count(), 1U); + EXPECT_LE(balancers_[1]->service_.request_count(), 2U); + EXPECT_LE(balancers_[1]->service_.response_count(), 2U); + EXPECT_EQ(0U, balancers_[2]->service_.request_count()); + EXPECT_EQ(0U, balancers_[2]->service_.response_count()); } TEST_F(UpdatesTest, ReresolveDeadBackend) { @@ -1190,14 +1610,14 @@ TEST_F(UpdatesTest, ReresolveDeadBackend) { // The first resolution contains the addresses of a balancer that never // responds, and a fallback backend. std::vector addresses; - addresses.emplace_back(AddressData{balancer_servers_[0].port_, true, ""}); - addresses.emplace_back(AddressData{backend_servers_[0].port_, false, ""}); + addresses.emplace_back(AddressData{balancers_[0]->port_, true, ""}); + addresses.emplace_back(AddressData{backends_[0]->port_, false, ""}); SetNextResolution(addresses); // The re-resolution result will contain the addresses of the same balancer // and a new fallback backend. addresses.clear(); - addresses.emplace_back(AddressData{balancer_servers_[0].port_, true, ""}); - addresses.emplace_back(AddressData{backend_servers_[1].port_, false, ""}); + addresses.emplace_back(AddressData{balancers_[0]->port_, true, ""}); + addresses.emplace_back(AddressData{backends_[1]->port_, false, ""}); SetNextReresolutionResponse(addresses); // Start servers and send 10 RPCs per server. @@ -1205,11 +1625,11 @@ TEST_F(UpdatesTest, ReresolveDeadBackend) { CheckRpcSendOk(10); gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH =========="); // All 10 requests should have gone to the fallback backend. - EXPECT_EQ(10U, backend_servers_[0].service_->request_count()); + EXPECT_EQ(10U, backends_[0]->service_.request_count()); // Kill backend 0. gpr_log(GPR_INFO, "********** ABOUT TO KILL BACKEND 0 *************"); - if (backends_[0]->Shutdown()) backend_servers_[0].Shutdown(); + backends_[0]->Shutdown(); gpr_log(GPR_INFO, "********** KILLED BACKEND 0 *************"); // Wait until re-resolution has finished, as signaled by the second backend @@ -1220,17 +1640,17 @@ TEST_F(UpdatesTest, ReresolveDeadBackend) { CheckRpcSendOk(10); gpr_log(GPR_INFO, "========= DONE WITH SECOND BATCH =========="); // All 10 requests should have gone to the second backend. - EXPECT_EQ(10U, backend_servers_[1].service_->request_count()); + EXPECT_EQ(10U, backends_[1]->service_.request_count()); - balancers_[0]->NotifyDoneWithServerlists(); - balancers_[1]->NotifyDoneWithServerlists(); - balancers_[2]->NotifyDoneWithServerlists(); - EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); - EXPECT_EQ(0U, balancer_servers_[0].service_->response_count()); - EXPECT_EQ(0U, balancer_servers_[1].service_->request_count()); - EXPECT_EQ(0U, balancer_servers_[1].service_->response_count()); - EXPECT_EQ(0U, balancer_servers_[2].service_->request_count()); - EXPECT_EQ(0U, balancer_servers_[2].service_->response_count()); + balancers_[0]->service_.NotifyDoneWithServerlists(); + balancers_[1]->service_.NotifyDoneWithServerlists(); + balancers_[2]->service_.NotifyDoneWithServerlists(); + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); + EXPECT_EQ(0U, balancers_[0]->service_.response_count()); + EXPECT_EQ(0U, balancers_[1]->service_.request_count()); + EXPECT_EQ(0U, balancers_[1]->service_.response_count()); + EXPECT_EQ(0U, balancers_[2]->service_.request_count()); + EXPECT_EQ(0U, balancers_[2]->service_.response_count()); } // TODO(juanlishen): Should be removed when the first response is always the @@ -1245,10 +1665,10 @@ class UpdatesWithClientLoadReportingTest : public GrpclbEnd2endTest { TEST_F(UpdatesWithClientLoadReportingTest, ReresolveDeadBalancer) { std::vector addresses; - addresses.emplace_back(AddressData{balancer_servers_[0].port_, true, ""}); + addresses.emplace_back(AddressData{balancers_[0]->port_, true, ""}); SetNextResolution(addresses); addresses.clear(); - addresses.emplace_back(AddressData{balancer_servers_[1].port_, true, ""}); + addresses.emplace_back(AddressData{balancers_[1]->port_, true, ""}); SetNextReresolutionResponse(addresses); const std::vector first_backend{GetBackendPorts()[0]}; const std::vector second_backend{GetBackendPorts()[1]}; @@ -1263,27 +1683,27 @@ TEST_F(UpdatesWithClientLoadReportingTest, ReresolveDeadBalancer) { CheckRpcSendOk(10); gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH =========="); // All 10 requests should have gone to the first backend. - EXPECT_EQ(10U, backend_servers_[0].service_->request_count()); + EXPECT_EQ(10U, backends_[0]->service_.request_count()); // Kill backend 0. gpr_log(GPR_INFO, "********** ABOUT TO KILL BACKEND 0 *************"); - if (backends_[0]->Shutdown()) backend_servers_[0].Shutdown(); + backends_[0]->Shutdown(); gpr_log(GPR_INFO, "********** KILLED BACKEND 0 *************"); CheckRpcSendFailure(); // Balancer 0 got a single request. - EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); // and sent a single response. - EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); - EXPECT_EQ(0U, balancer_servers_[1].service_->request_count()); - EXPECT_EQ(0U, balancer_servers_[1].service_->response_count()); - EXPECT_EQ(0U, balancer_servers_[2].service_->request_count()); - EXPECT_EQ(0U, balancer_servers_[2].service_->response_count()); + EXPECT_EQ(1U, balancers_[0]->service_.response_count()); + EXPECT_EQ(0U, balancers_[1]->service_.request_count()); + EXPECT_EQ(0U, balancers_[1]->service_.response_count()); + EXPECT_EQ(0U, balancers_[2]->service_.request_count()); + EXPECT_EQ(0U, balancers_[2]->service_.response_count()); // Kill balancer 0. gpr_log(GPR_INFO, "********** ABOUT TO KILL BALANCER 0 *************"); - if (balancers_[0]->Shutdown()) balancer_servers_[0].Shutdown(); + balancers_[0]->Shutdown(); gpr_log(GPR_INFO, "********** KILLED BALANCER 0 *************"); // Wait until re-resolution has finished, as signaled by the second backend @@ -1295,22 +1715,22 @@ TEST_F(UpdatesWithClientLoadReportingTest, ReresolveDeadBalancer) { CheckRpcSendOk(10); gpr_log(GPR_INFO, "========= DONE WITH SECOND BATCH =========="); // All 10 requests should have gone to the second backend. - EXPECT_EQ(10U, backend_servers_[1].service_->request_count()); + EXPECT_EQ(10U, backends_[1]->service_.request_count()); - EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); - EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); + EXPECT_EQ(1U, balancers_[0]->service_.response_count()); // After balancer 0 is killed, we restart an LB call immediately (because we // disconnect to a previously connected balancer). Although we will cancel // this call when the re-resolution update is done and another LB call restart // is needed, this old call may still succeed reaching the LB server if // re-resolution is slow. So balancer 1 may have received 2 requests and sent // 2 responses. - EXPECT_GE(balancer_servers_[1].service_->request_count(), 1U); - EXPECT_GE(balancer_servers_[1].service_->response_count(), 1U); - EXPECT_LE(balancer_servers_[1].service_->request_count(), 2U); - EXPECT_LE(balancer_servers_[1].service_->response_count(), 2U); - EXPECT_EQ(0U, balancer_servers_[2].service_->request_count()); - EXPECT_EQ(0U, balancer_servers_[2].service_->response_count()); + EXPECT_GE(balancers_[1]->service_.request_count(), 1U); + EXPECT_GE(balancers_[1]->service_.response_count(), 1U); + EXPECT_LE(balancers_[1]->service_.request_count(), 2U); + EXPECT_LE(balancers_[1]->service_.response_count(), 2U); + EXPECT_EQ(0U, balancers_[2]->service_.request_count()); + EXPECT_EQ(0U, balancers_[2]->service_.response_count()); } TEST_F(SingleBalancerTest, Drop) { @@ -1345,16 +1765,14 @@ TEST_F(SingleBalancerTest, Drop) { } } EXPECT_EQ(kNumRpcsPerAddress * num_of_drop_addresses, num_drops); - // Each backend should have gotten 100 requests. for (size_t i = 0; i < backends_.size(); ++i) { - EXPECT_EQ(kNumRpcsPerAddress, - backend_servers_[i].service_->request_count()); + EXPECT_EQ(kNumRpcsPerAddress, backends_[i]->service_.request_count()); } // The balancer got a single request. - EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); // and sent a single response. - EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); + EXPECT_EQ(1U, balancers_[0]->service_.response_count()); } TEST_F(SingleBalancerTest, DropAllFirst) { @@ -1419,14 +1837,13 @@ TEST_F(SingleBalancerWithClientLoadReportingTest, Vanilla) { CheckRpcSendOk(kNumRpcsPerAddress * num_backends_); // Each backend should have gotten 100 requests. for (size_t i = 0; i < backends_.size(); ++i) { - EXPECT_EQ(kNumRpcsPerAddress, - backend_servers_[i].service_->request_count()); + EXPECT_EQ(kNumRpcsPerAddress, backends_[i]->service_.request_count()); } - balancers_[0]->NotifyDoneWithServerlists(); + balancers_[0]->service_.NotifyDoneWithServerlists(); // The balancer got a single request. - EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); // and sent a single response. - EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); + EXPECT_EQ(1U, balancers_[0]->service_.response_count()); const ClientStats client_stats = WaitForLoadReports(); EXPECT_EQ(kNumRpcsPerAddress * num_backends_ + num_ok, @@ -1439,6 +1856,67 @@ TEST_F(SingleBalancerWithClientLoadReportingTest, Vanilla) { EXPECT_THAT(client_stats.drop_token_counts, ::testing::ElementsAre()); } +TEST_F(SingleBalancerWithClientLoadReportingTest, BalancerRestart) { + SetNextResolutionAllBalancers(); + const size_t kNumBackendsFirstPass = 2; + const size_t kNumBackendsSecondPass = + backends_.size() - kNumBackendsFirstPass; + // Balancer returns backends starting at index 1. + ScheduleResponseForBalancer( + 0, + BalancerServiceImpl::BuildResponseForBackends( + GetBackendPorts(0, kNumBackendsFirstPass), {}), + 0); + // Wait until all backends returned by the balancer are ready. + int num_ok = 0; + int num_failure = 0; + int num_drops = 0; + std::tie(num_ok, num_failure, num_drops) = + WaitForAllBackends(/* num_requests_multiple_of */ 1, /* start_index */ 0, + /* stop_index */ kNumBackendsFirstPass); + balancers_[0]->service_.NotifyDoneWithServerlists(); + ClientStats client_stats = WaitForLoadReports(); + EXPECT_EQ(static_cast(num_ok), client_stats.num_calls_started); + EXPECT_EQ(static_cast(num_ok), client_stats.num_calls_finished); + EXPECT_EQ(0U, client_stats.num_calls_finished_with_client_failed_to_send); + EXPECT_EQ(static_cast(num_ok), + client_stats.num_calls_finished_known_received); + EXPECT_THAT(client_stats.drop_token_counts, ::testing::ElementsAre()); + // Shut down the balancer. + balancers_[0]->Shutdown(); + // Send 10 more requests per backend. This will continue using the + // last serverlist we received from the balancer before it was shut down. + ResetBackendCounters(); + CheckRpcSendOk(kNumBackendsFirstPass); + // Each backend should have gotten 1 request. + for (size_t i = 0; i < kNumBackendsFirstPass; ++i) { + EXPECT_EQ(1UL, backends_[i]->service_.request_count()); + } + // Now restart the balancer, this time pointing to all backends. + balancers_[0]->Start(server_host_); + ScheduleResponseForBalancer(0, + BalancerServiceImpl::BuildResponseForBackends( + GetBackendPorts(kNumBackendsFirstPass), {}), + 0); + // Wait for queries to start going to one of the new backends. + // This tells us that we're now using the new serverlist. + do { + CheckRpcSendOk(); + } while (backends_[2]->service_.request_count() == 0 && + backends_[3]->service_.request_count() == 0); + // Send one RPC per backend. + CheckRpcSendOk(kNumBackendsSecondPass); + balancers_[0]->service_.NotifyDoneWithServerlists(); + // Check client stats. + client_stats = WaitForLoadReports(); + EXPECT_EQ(kNumBackendsSecondPass + 1, client_stats.num_calls_started); + EXPECT_EQ(kNumBackendsSecondPass + 1, client_stats.num_calls_finished); + EXPECT_EQ(0U, client_stats.num_calls_finished_with_client_failed_to_send); + EXPECT_EQ(kNumBackendsSecondPass + 1, + client_stats.num_calls_finished_known_received); + EXPECT_THAT(client_stats.drop_token_counts, ::testing::ElementsAre()); +} + TEST_F(SingleBalancerWithClientLoadReportingTest, Drop) { SetNextResolutionAllBalancers(); const size_t kNumRpcsPerAddress = 3; @@ -1478,14 +1956,13 @@ TEST_F(SingleBalancerWithClientLoadReportingTest, Drop) { EXPECT_EQ(kNumRpcsPerAddress * num_of_drop_addresses, num_drops); // Each backend should have gotten 100 requests. for (size_t i = 0; i < backends_.size(); ++i) { - EXPECT_EQ(kNumRpcsPerAddress, - backend_servers_[i].service_->request_count()); + EXPECT_EQ(kNumRpcsPerAddress, backends_[i]->service_.request_count()); } - balancers_[0]->NotifyDoneWithServerlists(); + balancers_[0]->service_.NotifyDoneWithServerlists(); // The balancer got a single request. - EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); // and sent a single response. - EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); + EXPECT_EQ(1U, balancers_[0]->service_.response_count()); const ClientStats client_stats = WaitForLoadReports(); EXPECT_EQ( @@ -1518,7 +1995,7 @@ TEST_F(SingleBalancerWithClientLoadReportingTest, Drop) { int main(int argc, char** argv) { grpc_init(); - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); const auto result = RUN_ALL_TESTS(); grpc_shutdown(); diff --git a/test/cpp/end2end/health_service_end2end_test.cc b/test/cpp/end2end/health_service_end2end_test.cc index fca65dfc13b..13d5ea55c15 100644 --- a/test/cpp/end2end/health_service_end2end_test.cc +++ b/test/cpp/end2end/health_service_end2end_test.cc @@ -37,6 +37,7 @@ #include "src/proto/grpc/testing/echo.grpc.pb.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" +#include "test/cpp/end2end/test_health_check_service_impl.h" #include "test/cpp/end2end/test_service_impl.h" #include @@ -49,62 +50,6 @@ namespace grpc { namespace testing { namespace { -// A sample sync implementation of the health checking service. This does the -// same thing as the default one. -class HealthCheckServiceImpl : public ::grpc::health::v1::Health::Service { - public: - Status Check(ServerContext* context, const HealthCheckRequest* request, - HealthCheckResponse* response) override { - std::lock_guard lock(mu_); - auto iter = status_map_.find(request->service()); - if (iter == status_map_.end()) { - return Status(StatusCode::NOT_FOUND, ""); - } - response->set_status(iter->second); - return Status::OK; - } - - Status Watch(ServerContext* context, const HealthCheckRequest* request, - ::grpc::ServerWriter* writer) override { - auto last_state = HealthCheckResponse::UNKNOWN; - while (!context->IsCancelled()) { - { - std::lock_guard lock(mu_); - HealthCheckResponse response; - auto iter = status_map_.find(request->service()); - if (iter == status_map_.end()) { - response.set_status(response.SERVICE_UNKNOWN); - } else { - response.set_status(iter->second); - } - if (response.status() != last_state) { - writer->Write(response, ::grpc::WriteOptions()); - } - } - gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), - gpr_time_from_millis(1000, GPR_TIMESPAN))); - } - return Status::OK; - } - - void SetStatus(const grpc::string& service_name, - HealthCheckResponse::ServingStatus status) { - std::lock_guard lock(mu_); - status_map_[service_name] = status; - } - - void SetAll(HealthCheckResponse::ServingStatus status) { - std::lock_guard lock(mu_); - for (auto iter = status_map_.begin(); iter != status_map_.end(); ++iter) { - iter->second = status; - } - } - - private: - std::mutex mu_; - std::map status_map_; -}; - // A custom implementation of the health checking service interface. This is // used to test that it prevents the server from creating a default service and // also serves as an example of how to override the default service. @@ -125,6 +70,8 @@ class CustomHealthCheckService : public HealthCheckServiceInterface { : HealthCheckResponse::NOT_SERVING); } + void Shutdown() override { impl_->Shutdown(); } + private: HealthCheckServiceImpl* impl_; // not owned }; @@ -177,8 +124,8 @@ class HealthServiceEnd2endTest : public ::testing::Test { } void ResetStubs() { - std::shared_ptr channel = - CreateChannel(server_address_.str(), InsecureChannelCredentials()); + std::shared_ptr channel = grpc::CreateChannel( + server_address_.str(), InsecureChannelCredentials()); hc_stub_ = grpc::health::v1::Health::NewStub(channel); } @@ -260,6 +207,74 @@ class HealthServiceEnd2endTest : public ::testing::Test { context.TryCancel(); } + // Verify that after HealthCheckServiceInterface::Shutdown is called + // 1. unary client will see NOT_SERVING. + // 2. unary client still sees NOT_SERVING after a SetServing(true) is called. + // 3. streaming (Watch) client will see an update. + // 4. setting a new service to serving after shutdown will add the service + // name but return NOT_SERVING to client. + // This has to be called last. + void VerifyHealthCheckServiceShutdown() { + HealthCheckServiceInterface* service = server_->GetHealthCheckService(); + EXPECT_TRUE(service != nullptr); + const grpc::string kHealthyService("healthy_service"); + const grpc::string kUnhealthyService("unhealthy_service"); + const grpc::string kNotRegisteredService("not_registered"); + const grpc::string kNewService("add_after_shutdown"); + service->SetServingStatus(kHealthyService, true); + service->SetServingStatus(kUnhealthyService, false); + + ResetStubs(); + + // Start Watch for service. + ClientContext context; + HealthCheckRequest request; + request.set_service(kHealthyService); + std::unique_ptr<::grpc::ClientReaderInterface> reader = + hc_stub_->Watch(&context, request); + + HealthCheckResponse response; + EXPECT_TRUE(reader->Read(&response)); + EXPECT_EQ(response.SERVING, response.status()); + + SendHealthCheckRpc("", Status::OK, HealthCheckResponse::SERVING); + SendHealthCheckRpc(kHealthyService, Status::OK, + HealthCheckResponse::SERVING); + SendHealthCheckRpc(kUnhealthyService, Status::OK, + HealthCheckResponse::NOT_SERVING); + SendHealthCheckRpc(kNotRegisteredService, + Status(StatusCode::NOT_FOUND, "")); + SendHealthCheckRpc(kNewService, Status(StatusCode::NOT_FOUND, "")); + + // Shutdown health check service. + service->Shutdown(); + + // Watch client gets another update. + EXPECT_TRUE(reader->Read(&response)); + EXPECT_EQ(response.NOT_SERVING, response.status()); + // Finish Watch call. + context.TryCancel(); + + SendHealthCheckRpc("", Status::OK, HealthCheckResponse::NOT_SERVING); + SendHealthCheckRpc(kHealthyService, Status::OK, + HealthCheckResponse::NOT_SERVING); + SendHealthCheckRpc(kUnhealthyService, Status::OK, + HealthCheckResponse::NOT_SERVING); + SendHealthCheckRpc(kNotRegisteredService, + Status(StatusCode::NOT_FOUND, "")); + + // Setting status after Shutdown has no effect. + service->SetServingStatus(kHealthyService, true); + SendHealthCheckRpc(kHealthyService, Status::OK, + HealthCheckResponse::NOT_SERVING); + + // Adding serving status for a new service after shutdown will return + // NOT_SERVING. + service->SetServingStatus(kNewService, true); + SendHealthCheckRpc(kNewService, Status::OK, + HealthCheckResponse::NOT_SERVING); + } + TestServiceImpl echo_test_service_; HealthCheckServiceImpl health_check_service_impl_; std::unique_ptr hc_stub_; @@ -295,6 +310,13 @@ TEST_F(HealthServiceEnd2endTest, DefaultHealthService) { Status(StatusCode::INVALID_ARGUMENT, "")); } +TEST_F(HealthServiceEnd2endTest, DefaultHealthServiceShutdown) { + EnableDefaultHealthCheckService(true); + EXPECT_TRUE(DefaultHealthCheckServiceEnabled()); + SetUpServer(true, false, false, nullptr); + VerifyHealthCheckServiceShutdown(); +} + // Provide an empty service to disable the default service. TEST_F(HealthServiceEnd2endTest, ExplicitlyDisableViaOverride) { EnableDefaultHealthCheckService(true); @@ -326,12 +348,27 @@ TEST_F(HealthServiceEnd2endTest, ExplicitlyOverride) { VerifyHealthCheckServiceStreaming(); } +TEST_F(HealthServiceEnd2endTest, ExplicitlyHealthServiceShutdown) { + EnableDefaultHealthCheckService(true); + EXPECT_TRUE(DefaultHealthCheckServiceEnabled()); + std::unique_ptr override_service( + new CustomHealthCheckService(&health_check_service_impl_)); + HealthCheckServiceInterface* underlying_service = override_service.get(); + SetUpServer(false, false, true, std::move(override_service)); + HealthCheckServiceInterface* service = server_->GetHealthCheckService(); + EXPECT_TRUE(service == underlying_service); + + ResetStubs(); + + VerifyHealthCheckServiceShutdown(); +} + } // namespace } // namespace testing } // namespace grpc int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/cpp/end2end/hybrid_end2end_test.cc b/test/cpp/end2end/hybrid_end2end_test.cc index 339eadde92e..75001f0ab27 100644 --- a/test/cpp/end2end/hybrid_end2end_test.cc +++ b/test/cpp/end2end/hybrid_end2end_test.cc @@ -28,6 +28,7 @@ #include #include +#include "src/core/lib/iomgr/iomgr.h" #include "src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h" #include "src/proto/grpc/testing/echo.grpc.pb.h" #include "test/core/util/port.h" @@ -39,7 +40,6 @@ namespace grpc { namespace testing { - namespace { void* tag(int i) { return (void*)static_cast(i); } @@ -225,13 +225,23 @@ class TestServiceImplDupPkg } }; -class HybridEnd2endTest : public ::testing::Test { +class HybridEnd2endTest : public ::testing::TestWithParam { protected: HybridEnd2endTest() {} - void SetUpServer(::grpc::Service* service1, ::grpc::Service* service2, - AsyncGenericService* generic_service, - int max_message_size = 0) { + void SetUp() override { + inproc_ = (::testing::UnitTest::GetInstance() + ->current_test_info() + ->value_param() != nullptr) + ? GetParam() + : false; + } + + bool SetUpServer( + ::grpc::Service* service1, ::grpc::Service* service2, + AsyncGenericService* generic_service, + experimental::CallbackGenericService* callback_generic_service, + int max_message_size = 0) { int port = grpc_pick_unused_port_or_die(); server_address_ << "localhost:" << port; @@ -249,6 +259,10 @@ class HybridEnd2endTest : public ::testing::Test { if (generic_service) { builder.RegisterAsyncGenericService(generic_service); } + if (callback_generic_service) { + builder.experimental().RegisterCallbackGenericService( + callback_generic_service); + } if (max_message_size != 0) { builder.SetMaxMessageSize(max_message_size); @@ -259,6 +273,11 @@ class HybridEnd2endTest : public ::testing::Test { cqs_.push_back(builder.AddCompletionQueue(false)); } server_ = builder.BuildAndStart(); + + // If there is a generic callback service, this setup is only successful if + // we have an iomgr that can run in the background or are inprocess + return !callback_generic_service || grpc_iomgr_run_in_background() || + inproc_; } void TearDown() override { @@ -276,7 +295,9 @@ class HybridEnd2endTest : public ::testing::Test { void ResetStub() { std::shared_ptr channel = - CreateChannel(server_address_.str(), InsecureChannelCredentials()); + inproc_ ? server_->InProcessChannel(ChannelArguments()) + : grpc::CreateChannel(server_address_.str(), + InsecureChannelCredentials()); stub_ = grpc::testing::EchoTestService::NewStub(channel); } @@ -300,8 +321,8 @@ class HybridEnd2endTest : public ::testing::Test { } void SendEchoToDupService() { - std::shared_ptr channel = - CreateChannel(server_address_.str(), InsecureChannelCredentials()); + std::shared_ptr channel = grpc::CreateChannel( + server_address_.str(), InsecureChannelCredentials()); auto stub = grpc::testing::duplicate::EchoTestService::NewStub(channel); EchoRequest send_request; EchoResponse recv_response; @@ -352,8 +373,8 @@ class HybridEnd2endTest : public ::testing::Test { } void SendSimpleServerStreamingToDupService() { - std::shared_ptr channel = - CreateChannel(server_address_.str(), InsecureChannelCredentials()); + std::shared_ptr channel = grpc::CreateChannel( + server_address_.str(), InsecureChannelCredentials()); auto stub = grpc::testing::duplicate::EchoTestService::NewStub(channel); EchoRequest request; EchoResponse response; @@ -411,12 +432,13 @@ class HybridEnd2endTest : public ::testing::Test { std::unique_ptr stub_; std::unique_ptr server_; std::ostringstream server_address_; + bool inproc_; }; TEST_F(HybridEnd2endTest, AsyncEcho) { typedef EchoTestService::WithAsyncMethod_Echo SType; SType service; - SetUpServer(&service, nullptr, nullptr); + SetUpServer(&service, nullptr, nullptr, nullptr); ResetStub(); std::thread echo_handler_thread(HandleEcho, &service, cqs_[0].get(), false); @@ -427,7 +449,7 @@ TEST_F(HybridEnd2endTest, AsyncEcho) { TEST_F(HybridEnd2endTest, RawEcho) { typedef EchoTestService::WithRawMethod_Echo SType; SType service; - SetUpServer(&service, nullptr, nullptr); + SetUpServer(&service, nullptr, nullptr, nullptr); ResetStub(); std::thread echo_handler_thread(HandleRawEcho, &service, cqs_[0].get(), false); @@ -438,7 +460,7 @@ TEST_F(HybridEnd2endTest, RawEcho) { TEST_F(HybridEnd2endTest, RawRequestStream) { typedef EchoTestService::WithRawMethod_RequestStream SType; SType service; - SetUpServer(&service, nullptr, nullptr); + SetUpServer(&service, nullptr, nullptr, nullptr); ResetStub(); std::thread request_stream_handler_thread(HandleRawClientStreaming, &service, cqs_[0].get()); @@ -451,7 +473,7 @@ TEST_F(HybridEnd2endTest, AsyncEchoRawRequestStream) { EchoTestService::WithAsyncMethod_Echo> SType; SType service; - SetUpServer(&service, nullptr, nullptr); + SetUpServer(&service, nullptr, nullptr, nullptr); ResetStub(); std::thread echo_handler_thread(HandleEcho, &service, cqs_[0].get(), false); @@ -468,7 +490,7 @@ TEST_F(HybridEnd2endTest, GenericEchoRawRequestStream) { SType; SType service; AsyncGenericService generic_service; - SetUpServer(&service, nullptr, &generic_service); + SetUpServer(&service, nullptr, &generic_service, nullptr); ResetStub(); std::thread generic_handler_thread(HandleGenericCall, &generic_service, cqs_[0].get()); @@ -484,7 +506,7 @@ TEST_F(HybridEnd2endTest, AsyncEchoRequestStream) { EchoTestService::WithAsyncMethod_Echo> SType; SType service; - SetUpServer(&service, nullptr, nullptr); + SetUpServer(&service, nullptr, nullptr, nullptr); ResetStub(); std::thread echo_handler_thread(HandleEcho, &service, cqs_[0].get(), false); @@ -500,7 +522,7 @@ TEST_F(HybridEnd2endTest, AsyncRequestStreamResponseStream) { EchoTestService::WithAsyncMethod_ResponseStream> SType; SType service; - SetUpServer(&service, nullptr, nullptr); + SetUpServer(&service, nullptr, nullptr, nullptr); ResetStub(); std::thread response_stream_handler_thread(HandleServerStreaming, &service, cqs_[0].get()); @@ -518,7 +540,7 @@ TEST_F(HybridEnd2endTest, AsyncRequestStreamResponseStream_SyncDupService) { SType; SType service; TestServiceImplDupPkg dup_service; - SetUpServer(&service, &dup_service, nullptr); + SetUpServer(&service, &dup_service, nullptr, nullptr); ResetStub(); std::thread response_stream_handler_thread(HandleServerStreaming, &service, cqs_[0].get()); @@ -557,7 +579,7 @@ TEST_F(HybridEnd2endTest, SType; SType service; StreamedUnaryDupPkg dup_service; - SetUpServer(&service, &dup_service, nullptr, 8192); + SetUpServer(&service, &dup_service, nullptr, nullptr, 8192); ResetStub(); std::thread response_stream_handler_thread(HandleServerStreaming, &service, cqs_[0].get()); @@ -595,7 +617,7 @@ TEST_F(HybridEnd2endTest, SType; SType service; FullyStreamedUnaryDupPkg dup_service; - SetUpServer(&service, &dup_service, nullptr, 8192); + SetUpServer(&service, &dup_service, nullptr, nullptr, 8192); ResetStub(); std::thread response_stream_handler_thread(HandleServerStreaming, &service, cqs_[0].get()); @@ -636,7 +658,7 @@ TEST_F(HybridEnd2endTest, SType; SType service; SplitResponseStreamDupPkg dup_service; - SetUpServer(&service, &dup_service, nullptr, 8192); + SetUpServer(&service, &dup_service, nullptr, nullptr, 8192); ResetStub(); std::thread response_stream_handler_thread(HandleServerStreaming, &service, cqs_[0].get()); @@ -676,7 +698,7 @@ TEST_F(HybridEnd2endTest, SType; SType service; FullySplitStreamedDupPkg dup_service; - SetUpServer(&service, &dup_service, nullptr, 8192); + SetUpServer(&service, &dup_service, nullptr, nullptr, 8192); ResetStub(); std::thread response_stream_handler_thread(HandleServerStreaming, &service, cqs_[0].get()); @@ -728,7 +750,7 @@ TEST_F(HybridEnd2endTest, SType; SType service; FullyStreamedDupPkg dup_service; - SetUpServer(&service, &dup_service, nullptr, 8192); + SetUpServer(&service, &dup_service, nullptr, nullptr, 8192); ResetStub(); std::thread response_stream_handler_thread(HandleServerStreaming, &service, cqs_[0].get()); @@ -748,7 +770,7 @@ TEST_F(HybridEnd2endTest, AsyncRequestStreamResponseStream_AsyncDupService) { SType; SType service; duplicate::EchoTestService::AsyncService dup_service; - SetUpServer(&service, &dup_service, nullptr); + SetUpServer(&service, &dup_service, nullptr, nullptr); ResetStub(); std::thread response_stream_handler_thread(HandleServerStreaming, &service, cqs_[0].get()); @@ -767,7 +789,7 @@ TEST_F(HybridEnd2endTest, AsyncRequestStreamResponseStream_AsyncDupService) { TEST_F(HybridEnd2endTest, GenericEcho) { EchoTestService::WithGenericMethod_Echo service; AsyncGenericService generic_service; - SetUpServer(&service, nullptr, &generic_service); + SetUpServer(&service, nullptr, &generic_service, nullptr); ResetStub(); std::thread generic_handler_thread(HandleGenericCall, &generic_service, cqs_[0].get()); @@ -775,13 +797,56 @@ TEST_F(HybridEnd2endTest, GenericEcho) { generic_handler_thread.join(); } +TEST_P(HybridEnd2endTest, CallbackGenericEcho) { + EchoTestService::WithGenericMethod_Echo service; + class GenericEchoService : public experimental::CallbackGenericService { + private: + experimental::ServerGenericBidiReactor* CreateReactor() override { + class Reactor : public experimental::ServerGenericBidiReactor { + private: + void OnStarted(GenericServerContext* ctx) override { + ctx_ = ctx; + EXPECT_EQ(ctx->method(), "/grpc.testing.EchoTestService/Echo"); + StartRead(&request_); + } + void OnDone() override { delete this; } + void OnReadDone(bool ok) override { + if (!ok) { + EXPECT_EQ(reads_complete_, 1); + } else { + EXPECT_EQ(reads_complete_++, 0); + response_ = request_; + StartWrite(&response_); + StartRead(&request_); + } + } + void OnWriteDone(bool ok) override { + Finish(ok ? Status::OK + : Status(StatusCode::UNKNOWN, "Unexpected failure")); + } + GenericServerContext* ctx_; + ByteBuffer request_; + ByteBuffer response_; + std::atomic_int reads_complete_{0}; + }; + return new Reactor; + } + } generic_service; + + if (!SetUpServer(&service, nullptr, nullptr, &generic_service)) { + return; + } + ResetStub(); + TestAllMethods(); +} + TEST_F(HybridEnd2endTest, GenericEchoAsyncRequestStream) { typedef EchoTestService::WithAsyncMethod_RequestStream< EchoTestService::WithGenericMethod_Echo> SType; SType service; AsyncGenericService generic_service; - SetUpServer(&service, nullptr, &generic_service); + SetUpServer(&service, nullptr, &generic_service, nullptr); ResetStub(); std::thread generic_handler_thread(HandleGenericCall, &generic_service, cqs_[0].get()); @@ -800,7 +865,7 @@ TEST_F(HybridEnd2endTest, GenericEchoAsyncRequestStream_SyncDupService) { SType service; AsyncGenericService generic_service; TestServiceImplDupPkg dup_service; - SetUpServer(&service, &dup_service, &generic_service); + SetUpServer(&service, &dup_service, &generic_service, nullptr); ResetStub(); std::thread generic_handler_thread(HandleGenericCall, &generic_service, cqs_[0].get()); @@ -820,7 +885,7 @@ TEST_F(HybridEnd2endTest, GenericEchoAsyncRequestStream_AsyncDupService) { SType service; AsyncGenericService generic_service; duplicate::EchoTestService::AsyncService dup_service; - SetUpServer(&service, &dup_service, &generic_service); + SetUpServer(&service, &dup_service, &generic_service, nullptr); ResetStub(); std::thread generic_handler_thread(HandleGenericCall, &generic_service, cqs_[0].get()); @@ -843,7 +908,7 @@ TEST_F(HybridEnd2endTest, GenericEchoAsyncRequestStreamResponseStream) { SType; SType service; AsyncGenericService generic_service; - SetUpServer(&service, nullptr, &generic_service); + SetUpServer(&service, nullptr, &generic_service, nullptr); ResetStub(); std::thread generic_handler_thread(HandleGenericCall, &generic_service, cqs_[0].get()); @@ -864,7 +929,7 @@ TEST_F(HybridEnd2endTest, GenericEchoRequestStreamAsyncResponseStream) { SType; SType service; AsyncGenericService generic_service; - SetUpServer(&service, nullptr, &generic_service); + SetUpServer(&service, nullptr, &generic_service, nullptr); ResetStub(); std::thread generic_handler_thread(HandleGenericCall, &generic_service, cqs_[0].get()); @@ -885,16 +950,19 @@ TEST_F(HybridEnd2endTest, GenericMethodWithoutGenericService) { EchoTestService::WithGenericMethod_Echo< EchoTestService::WithAsyncMethod_ResponseStream>> service; - SetUpServer(&service, nullptr, nullptr); + SetUpServer(&service, nullptr, nullptr, nullptr); EXPECT_EQ(nullptr, server_.get()); } +INSTANTIATE_TEST_CASE_P(HybridEnd2endTest, HybridEnd2endTest, + ::testing::Bool()); + } // namespace } // namespace testing } // namespace grpc int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/cpp/end2end/interceptors_util.cc b/test/cpp/end2end/interceptors_util.cc index 5d59c1a4b72..900f02b5f36 100644 --- a/test/cpp/end2end/interceptors_util.cc +++ b/test/cpp/end2end/interceptors_util.cc @@ -132,11 +132,22 @@ bool CheckMetadata(const std::multimap& map, return false; } +bool CheckMetadata(const std::multimap& map, + const string& key, const string& value) { + for (const auto& pair : map) { + if (pair.first == key && pair.second == value) { + return true; + } + } + return false; +} + std::vector> CreateDummyClientInterceptors() { std::vector> creators; // Add 20 dummy interceptors before hijacking interceptor + creators.reserve(20); for (auto i = 0; i < 20; i++) { creators.push_back(std::unique_ptr( new DummyInterceptorFactory())); diff --git a/test/cpp/end2end/interceptors_util.h b/test/cpp/end2end/interceptors_util.h index d886e32494c..419845e5f61 100644 --- a/test/cpp/end2end/interceptors_util.h +++ b/test/cpp/end2end/interceptors_util.h @@ -82,6 +82,22 @@ class DummyInterceptorFactory } }; +/* This interceptor factory returns nullptr on interceptor creation */ +class NullInterceptorFactory + : public experimental::ClientInterceptorFactoryInterface, + public experimental::ServerInterceptorFactoryInterface { + public: + virtual experimental::Interceptor* CreateClientInterceptor( + experimental::ClientRpcInfo* info) override { + return nullptr; + } + + virtual experimental::Interceptor* CreateServerInterceptor( + experimental::ServerRpcInfo* info) override { + return nullptr; + } +}; + class EchoTestServiceStreamingImpl : public EchoTestService::Service { public: ~EchoTestServiceStreamingImpl() override {} @@ -149,6 +165,9 @@ void MakeCallbackCall(const std::shared_ptr& channel); bool CheckMetadata(const std::multimap& map, const string& key, const string& value); +bool CheckMetadata(const std::multimap& map, + const string& key, const string& value); + std::vector> CreateDummyClientInterceptors(); diff --git a/test/cpp/end2end/message_allocator_end2end_test.cc b/test/cpp/end2end/message_allocator_end2end_test.cc new file mode 100644 index 00000000000..c833a4ff1b6 --- /dev/null +++ b/test/cpp/end2end/message_allocator_end2end_test.cc @@ -0,0 +1,405 @@ +/* + * + * Copyright 2019 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 +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "src/core/lib/iomgr/iomgr.h" +#include "src/proto/grpc/testing/echo.grpc.pb.h" +#include "test/core/util/port.h" +#include "test/core/util/test_config.h" +#include "test/cpp/util/test_credentials_provider.h" + +// MAYBE_SKIP_TEST is a macro to determine if this particular test configuration +// should be skipped based on a decision made at SetUp time. In particular, any +// callback tests can only be run if the iomgr can run in the background or if +// the transport is in-process. +#define MAYBE_SKIP_TEST \ + do { \ + if (do_not_test_) { \ + return; \ + } \ + } while (0) + +namespace grpc { +namespace testing { +namespace { + +class CallbackTestServiceImpl + : public EchoTestService::ExperimentalCallbackService { + public: + explicit CallbackTestServiceImpl() {} + + void SetFreeRequest() { free_request_ = true; } + + void SetAllocatorMutator( + std::function + mutator) { + allocator_mutator_ = mutator; + } + + void Echo(ServerContext* context, const EchoRequest* request, + EchoResponse* response, + experimental::ServerCallbackRpcController* controller) override { + response->set_message(request->message()); + if (free_request_) { + controller->FreeRequest(); + } else if (allocator_mutator_) { + allocator_mutator_(controller->GetAllocatorState(), request, response); + } + controller->Finish(Status::OK); + } + + private: + bool free_request_ = false; + std::function + allocator_mutator_; +}; + +enum class Protocol { INPROC, TCP }; + +class TestScenario { + public: + TestScenario(Protocol protocol, const grpc::string& creds_type) + : protocol(protocol), credentials_type(creds_type) {} + void Log() const; + Protocol protocol; + const grpc::string credentials_type; +}; + +static std::ostream& operator<<(std::ostream& out, + const TestScenario& scenario) { + return out << "TestScenario{protocol=" + << (scenario.protocol == Protocol::INPROC ? "INPROC" : "TCP") + << "," << scenario.credentials_type << "}"; +} + +void TestScenario::Log() const { + std::ostringstream out; + out << *this; + gpr_log(GPR_INFO, "%s", out.str().c_str()); +} + +class MessageAllocatorEnd2endTestBase + : public ::testing::TestWithParam { + protected: + MessageAllocatorEnd2endTestBase() { + GetParam().Log(); + if (GetParam().protocol == Protocol::TCP) { + if (!grpc_iomgr_run_in_background()) { + do_not_test_ = true; + return; + } + } + } + + ~MessageAllocatorEnd2endTestBase() = default; + + void CreateServer( + experimental::MessageAllocator* allocator) { + ServerBuilder builder; + + auto server_creds = GetCredentialsProvider()->GetServerCredentials( + GetParam().credentials_type); + if (GetParam().protocol == Protocol::TCP) { + picked_port_ = grpc_pick_unused_port_or_die(); + server_address_ << "localhost:" << picked_port_; + builder.AddListeningPort(server_address_.str(), server_creds); + } + callback_service_.SetMessageAllocatorFor_Echo(allocator); + builder.RegisterService(&callback_service_); + + server_ = builder.BuildAndStart(); + is_server_started_ = true; + } + + void ResetStub() { + ChannelArguments args; + auto channel_creds = GetCredentialsProvider()->GetChannelCredentials( + GetParam().credentials_type, &args); + switch (GetParam().protocol) { + case Protocol::TCP: + channel_ = ::grpc::CreateCustomChannel(server_address_.str(), + channel_creds, args); + break; + case Protocol::INPROC: + channel_ = server_->InProcessChannel(args); + break; + default: + assert(false); + } + stub_ = EchoTestService::NewStub(channel_); + } + + void TearDown() override { + if (is_server_started_) { + server_->Shutdown(); + } + if (picked_port_ > 0) { + grpc_recycle_unused_port(picked_port_); + } + } + + void SendRpcs(int num_rpcs) { + grpc::string test_string(""); + for (int i = 0; i < num_rpcs; i++) { + EchoRequest request; + EchoResponse response; + ClientContext cli_ctx; + + test_string += grpc::string(1024, 'x'); + request.set_message(test_string); + grpc::string val; + cli_ctx.set_compression_algorithm(GRPC_COMPRESS_GZIP); + + std::mutex mu; + std::condition_variable cv; + bool done = false; + stub_->experimental_async()->Echo( + &cli_ctx, &request, &response, + [&request, &response, &done, &mu, &cv, val](Status s) { + GPR_ASSERT(s.ok()); + + EXPECT_EQ(request.message(), response.message()); + std::lock_guard l(mu); + done = true; + cv.notify_one(); + }); + std::unique_lock l(mu); + while (!done) { + cv.wait(l); + } + } + } + + bool do_not_test_{false}; + bool is_server_started_{false}; + int picked_port_{0}; + std::shared_ptr channel_; + std::unique_ptr stub_; + CallbackTestServiceImpl callback_service_; + std::unique_ptr server_; + std::ostringstream server_address_; +}; + +class NullAllocatorTest : public MessageAllocatorEnd2endTestBase {}; + +TEST_P(NullAllocatorTest, SimpleRpc) { + MAYBE_SKIP_TEST; + CreateServer(nullptr); + ResetStub(); + SendRpcs(1); +} + +class SimpleAllocatorTest : public MessageAllocatorEnd2endTestBase { + public: + class SimpleAllocator + : public experimental::MessageAllocator { + public: + void AllocateMessages( + experimental::RpcAllocatorInfo* info) { + allocation_count++; + info->request = new EchoRequest; + info->response = new EchoResponse; + info->allocator_state = info; + } + void DeallocateRequest( + experimental::RpcAllocatorInfo* info) { + request_deallocation_count++; + delete info->request; + info->request = nullptr; + } + void DeallocateMessages( + experimental::RpcAllocatorInfo* info) { + messages_deallocation_count++; + delete info->request; + delete info->response; + } + + int allocation_count = 0; + int request_deallocation_count = 0; + int messages_deallocation_count = 0; + }; +}; + +TEST_P(SimpleAllocatorTest, SimpleRpc) { + MAYBE_SKIP_TEST; + const int kRpcCount = 10; + std::unique_ptr allocator(new SimpleAllocator); + CreateServer(allocator.get()); + ResetStub(); + SendRpcs(kRpcCount); + EXPECT_EQ(kRpcCount, allocator->allocation_count); + EXPECT_EQ(kRpcCount, allocator->messages_deallocation_count); + EXPECT_EQ(0, allocator->request_deallocation_count); +} + +TEST_P(SimpleAllocatorTest, RpcWithEarlyFreeRequest) { + MAYBE_SKIP_TEST; + const int kRpcCount = 10; + std::unique_ptr allocator(new SimpleAllocator); + callback_service_.SetFreeRequest(); + CreateServer(allocator.get()); + ResetStub(); + SendRpcs(kRpcCount); + EXPECT_EQ(kRpcCount, allocator->allocation_count); + EXPECT_EQ(kRpcCount, allocator->messages_deallocation_count); + EXPECT_EQ(kRpcCount, allocator->request_deallocation_count); +} + +TEST_P(SimpleAllocatorTest, RpcWithReleaseRequest) { + MAYBE_SKIP_TEST; + const int kRpcCount = 10; + std::unique_ptr allocator(new SimpleAllocator); + std::vector released_requests; + auto mutator = [&released_requests](void* allocator_state, + const EchoRequest* req, + EchoResponse* resp) { + auto* info = + static_cast*>( + allocator_state); + EXPECT_EQ(req, info->request); + EXPECT_EQ(resp, info->response); + EXPECT_EQ(allocator_state, info->allocator_state); + released_requests.push_back(info->request); + info->request = nullptr; + }; + callback_service_.SetAllocatorMutator(mutator); + CreateServer(allocator.get()); + ResetStub(); + SendRpcs(kRpcCount); + EXPECT_EQ(kRpcCount, allocator->allocation_count); + EXPECT_EQ(kRpcCount, allocator->messages_deallocation_count); + EXPECT_EQ(0, allocator->request_deallocation_count); + EXPECT_EQ(static_cast(kRpcCount), released_requests.size()); + for (auto* req : released_requests) { + delete req; + } +} + +class ArenaAllocatorTest : public MessageAllocatorEnd2endTestBase { + public: + class ArenaAllocator + : public experimental::MessageAllocator { + public: + void AllocateMessages( + experimental::RpcAllocatorInfo* info) { + allocation_count++; + auto* arena = new google::protobuf::Arena; + info->allocator_state = arena; + info->request = + google::protobuf::Arena::CreateMessage(arena); + info->response = + google::protobuf::Arena::CreateMessage(arena); + } + void DeallocateRequest( + experimental::RpcAllocatorInfo* info) { + GPR_ASSERT(0); + } + void DeallocateMessages( + experimental::RpcAllocatorInfo* info) { + deallocation_count++; + auto* arena = + static_cast(info->allocator_state); + delete arena; + } + + int allocation_count = 0; + int deallocation_count = 0; + }; +}; + +TEST_P(ArenaAllocatorTest, SimpleRpc) { + MAYBE_SKIP_TEST; + const int kRpcCount = 10; + std::unique_ptr allocator(new ArenaAllocator); + CreateServer(allocator.get()); + ResetStub(); + SendRpcs(kRpcCount); + EXPECT_EQ(kRpcCount, allocator->allocation_count); + EXPECT_EQ(kRpcCount, allocator->deallocation_count); +} + +std::vector CreateTestScenarios(bool test_insecure) { + std::vector scenarios; + std::vector credentials_types{ + GetCredentialsProvider()->GetSecureCredentialsTypeList()}; + auto insec_ok = [] { + // Only allow insecure credentials type when it is registered with the + // provider. User may create providers that do not have insecure. + return GetCredentialsProvider()->GetChannelCredentials( + kInsecureCredentialsType, nullptr) != nullptr; + }; + if (test_insecure && insec_ok()) { + credentials_types.push_back(kInsecureCredentialsType); + } + GPR_ASSERT(!credentials_types.empty()); + + Protocol parr[]{Protocol::INPROC, Protocol::TCP}; + for (Protocol p : parr) { + for (const auto& cred : credentials_types) { + // TODO(vjpai): Test inproc with secure credentials when feasible + if (p == Protocol::INPROC && + (cred != kInsecureCredentialsType || !insec_ok())) { + continue; + } + scenarios.emplace_back(p, cred); + } + } + return scenarios; +} + +INSTANTIATE_TEST_CASE_P(NullAllocatorTest, NullAllocatorTest, + ::testing::ValuesIn(CreateTestScenarios(true))); +INSTANTIATE_TEST_CASE_P(SimpleAllocatorTest, SimpleAllocatorTest, + ::testing::ValuesIn(CreateTestScenarios(true))); +INSTANTIATE_TEST_CASE_P(ArenaAllocatorTest, ArenaAllocatorTest, + ::testing::ValuesIn(CreateTestScenarios(true))); + +} // namespace +} // namespace testing +} // namespace grpc + +int main(int argc, char** argv) { + grpc::testing::TestEnvironment env(argc, argv); + // The grpc_init is to cover the MAYBE_SKIP_TEST. + grpc_init(); + ::testing::InitGoogleTest(&argc, argv); + int ret = RUN_ALL_TESTS(); + grpc_shutdown(); + return ret; +} diff --git a/test/cpp/end2end/mock_test.cc b/test/cpp/end2end/mock_test.cc index ba3122c895f..0196c9de7e0 100644 --- a/test/cpp/end2end/mock_test.cc +++ b/test/cpp/end2end/mock_test.cc @@ -244,8 +244,8 @@ class MockTest : public ::testing::Test { void TearDown() override { server_->Shutdown(); } void ResetStub() { - std::shared_ptr channel = - CreateChannel(server_address_.str(), InsecureChannelCredentials()); + std::shared_ptr channel = grpc::CreateChannel( + server_address_.str(), InsecureChannelCredentials()); stub_ = grpc::testing::EchoTestService::NewStub(channel); } @@ -345,7 +345,7 @@ TEST_F(MockTest, BidiStream) { } // namespace grpc int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/cpp/end2end/nonblocking_test.cc b/test/cpp/end2end/nonblocking_test.cc index d8337baca22..eb651df21df 100644 --- a/test/cpp/end2end/nonblocking_test.cc +++ b/test/cpp/end2end/nonblocking_test.cc @@ -106,7 +106,7 @@ class NonblockingTest : public ::testing::Test { } void ResetStub() { - std::shared_ptr channel = CreateChannel( + std::shared_ptr channel = grpc::CreateChannel( server_address_.str(), grpc::InsecureChannelCredentials()); stub_ = grpc::testing::EchoTestService::NewStub(channel); } @@ -187,7 +187,7 @@ int main(int argc, char** argv) { grpc_poll_function = maybe_assert_non_blocking_poll; #endif // GRPC_POSIX_SOCKET - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); int ret = RUN_ALL_TESTS(); return ret; diff --git a/test/cpp/end2end/proto_server_reflection_test.cc b/test/cpp/end2end/proto_server_reflection_test.cc index 21a275ef62c..d817438f41b 100644 --- a/test/cpp/end2end/proto_server_reflection_test.cc +++ b/test/cpp/end2end/proto_server_reflection_test.cc @@ -55,7 +55,7 @@ class ProtoServerReflectionTest : public ::testing::Test { void ResetStub() { string target = "dns:localhost:" + to_string(port_); std::shared_ptr channel = - CreateChannel(target, InsecureChannelCredentials()); + grpc::CreateChannel(target, InsecureChannelCredentials()); stub_ = grpc::testing::EchoTestService::NewStub(channel); desc_db_.reset(new ProtoReflectionDescriptorDatabase(channel)); desc_pool_.reset(new protobuf::DescriptorPool(desc_db_.get())); @@ -144,7 +144,7 @@ TEST_F(ProtoServerReflectionTest, CheckResponseWithLocalDescriptorPool) { } // namespace grpc int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/cpp/end2end/raw_end2end_test.cc b/test/cpp/end2end/raw_end2end_test.cc index a413905ef7a..184dc1e5f56 100644 --- a/test/cpp/end2end/raw_end2end_test.cc +++ b/test/cpp/end2end/raw_end2end_test.cc @@ -130,7 +130,7 @@ class RawEnd2EndTest : public ::testing::Test { void ResetStub() { ChannelArguments args; - std::shared_ptr channel = CreateChannel( + std::shared_ptr channel = grpc::CreateChannel( server_address_.str(), grpc::InsecureChannelCredentials()); stub_ = grpc::testing::EchoTestService::NewStub(channel); } @@ -363,7 +363,7 @@ TEST_F(RawEnd2EndTest, CompileTest) { int main(int argc, char** argv) { // Change the backup poll interval from 5s to 100ms to speed up the // ReconnectChannel test - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); int ret = RUN_ALL_TESTS(); return ret; diff --git a/test/cpp/end2end/server_builder_plugin_test.cc b/test/cpp/end2end/server_builder_plugin_test.cc index d54523fcbb1..43b00b95f49 100644 --- a/test/cpp/end2end/server_builder_plugin_test.cc +++ b/test/cpp/end2end/server_builder_plugin_test.cc @@ -185,7 +185,7 @@ class ServerBuilderPluginTest : public ::testing::TestWithParam { void ResetStub() { string target = "dns:localhost:" + to_string(port_); - channel_ = CreateChannel(target, InsecureChannelCredentials()); + channel_ = grpc::CreateChannel(target, InsecureChannelCredentials()); stub_ = grpc::testing::EchoTestService::NewStub(channel_); } @@ -264,7 +264,7 @@ INSTANTIATE_TEST_CASE_P(ServerBuilderPluginTest, ServerBuilderPluginTest, } // namespace grpc int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/cpp/end2end/server_crash_test.cc b/test/cpp/end2end/server_crash_test.cc index 93257b2705c..353ebf713a0 100644 --- a/test/cpp/end2end/server_crash_test.cc +++ b/test/cpp/end2end/server_crash_test.cc @@ -153,7 +153,7 @@ int main(int argc, char** argv) { g_root = "."; } - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/cpp/end2end/server_crash_test_client.cc b/test/cpp/end2end/server_crash_test_client.cc index c05fcfdb810..b261560470d 100644 --- a/test/cpp/end2end/server_crash_test_client.cc +++ b/test/cpp/end2end/server_crash_test_client.cc @@ -28,6 +28,7 @@ #include #include "src/proto/grpc/testing/echo.grpc.pb.h" +#include "test/cpp/util/test_config.h" DEFINE_string(address, "", "Address to connect to"); DEFINE_string(mode, "", "Test mode to use"); @@ -35,15 +36,8 @@ DEFINE_string(mode, "", "Test mode to use"); using grpc::testing::EchoRequest; using grpc::testing::EchoResponse; -// In some distros, gflags is in the namespace google, and in some others, -// in gflags. This hack is enabling us to find both. -namespace google {} -namespace gflags {} -using namespace google; -using namespace gflags; - int main(int argc, char** argv) { - ParseCommandLineFlags(&argc, &argv, true); + grpc::testing::InitTest(&argc, &argv, true); auto stub = grpc::testing::EchoTestService::NewStub( grpc::CreateChannel(FLAGS_address, grpc::InsecureChannelCredentials())); diff --git a/test/cpp/end2end/server_early_return_test.cc b/test/cpp/end2end/server_early_return_test.cc index 8948e5b8546..6f35c3e7d93 100644 --- a/test/cpp/end2end/server_early_return_test.cc +++ b/test/cpp/end2end/server_early_return_test.cc @@ -122,8 +122,8 @@ class ServerEarlyReturnTest : public ::testing::Test { builder.RegisterService(&service_); server_ = builder.BuildAndStart(); - channel_ = - CreateChannel(server_address_.str(), InsecureChannelCredentials()); + channel_ = grpc::CreateChannel(server_address_.str(), + InsecureChannelCredentials()); stub_ = grpc::testing::EchoTestService::NewStub(channel_); } @@ -226,7 +226,7 @@ TEST_F(ServerEarlyReturnTest, RequestStreamEarlyCancel) { } // namespace grpc int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/cpp/end2end/server_interceptors_end2end_test.cc b/test/cpp/end2end/server_interceptors_end2end_test.cc index 295d63516bd..68103f7ed34 100644 --- a/test/cpp/end2end/server_interceptors_end2end_test.cc +++ b/test/cpp/end2end/server_interceptors_end2end_test.cc @@ -24,10 +24,10 @@ #include #include #include -#include #include #include #include +#include #include "src/proto/grpc/testing/echo.grpc.pb.h" #include "test/core/util/port.h" @@ -44,9 +44,36 @@ namespace { class LoggingInterceptor : public experimental::Interceptor { public: - LoggingInterceptor(experimental::ServerRpcInfo* info) { info_ = info; } + LoggingInterceptor(experimental::ServerRpcInfo* info) { + info_ = info; - virtual void Intercept(experimental::InterceptorBatchMethods* methods) { + // Check the method name and compare to the type + const char* method = info->method(); + experimental::ServerRpcInfo::Type type = info->type(); + + // Check that we use one of our standard methods with expected type. + // Also allow the health checking service. + // We accept BIDI_STREAMING for Echo in case it's an AsyncGenericService + // being tested (the GenericRpc test). + // The empty method is for the Unimplemented requests that arise + // when draining the CQ. + EXPECT_TRUE( + strstr(method, "/grpc.health") == method || + (strcmp(method, "/grpc.testing.EchoTestService/Echo") == 0 && + (type == experimental::ServerRpcInfo::Type::UNARY || + type == experimental::ServerRpcInfo::Type::BIDI_STREAMING)) || + (strcmp(method, "/grpc.testing.EchoTestService/RequestStream") == 0 && + type == experimental::ServerRpcInfo::Type::CLIENT_STREAMING) || + (strcmp(method, "/grpc.testing.EchoTestService/ResponseStream") == 0 && + type == experimental::ServerRpcInfo::Type::SERVER_STREAMING) || + (strcmp(method, "/grpc.testing.EchoTestService/BidiStream") == 0 && + type == experimental::ServerRpcInfo::Type::BIDI_STREAMING) || + strcmp(method, "/grpc.testing.EchoTestService/Unimplemented") == 0 || + (strcmp(method, "") == 0 && + type == experimental::ServerRpcInfo::Type::BIDI_STREAMING)); + } + + void Intercept(experimental::InterceptorBatchMethods* methods) override { if (methods->QueryInterceptionHookPoint( experimental::InterceptionHookPoints::PRE_SEND_INITIAL_METADATA)) { auto* map = methods->GetSendInitialMetadata(); @@ -56,7 +83,7 @@ class LoggingInterceptor : public experimental::Interceptor { if (methods->QueryInterceptionHookPoint( experimental::InterceptionHookPoints::PRE_SEND_MESSAGE)) { EchoRequest req; - auto* buffer = methods->GetSendMessage(); + auto* buffer = methods->GetSerializedSendMessage(); auto copied_buffer = *buffer; EXPECT_TRUE( SerializationTraits::Deserialize(&copied_buffer, &req) @@ -115,6 +142,71 @@ class LoggingInterceptorFactory } }; +// Test if SendMessage function family works as expected for sync/callback apis +class SyncSendMessageTester : public experimental::Interceptor { + public: + SyncSendMessageTester(experimental::ServerRpcInfo* info) {} + + void Intercept(experimental::InterceptorBatchMethods* methods) override { + if (methods->QueryInterceptionHookPoint( + experimental::InterceptionHookPoints::PRE_SEND_MESSAGE)) { + string old_msg = + static_cast(methods->GetSendMessage())->message(); + EXPECT_EQ(old_msg.find("Hello"), 0u); + new_msg_.set_message("World" + old_msg); + methods->ModifySendMessage(&new_msg_); + } + methods->Proceed(); + } + + private: + EchoRequest new_msg_; +}; + +class SyncSendMessageTesterFactory + : public experimental::ServerInterceptorFactoryInterface { + public: + virtual experimental::Interceptor* CreateServerInterceptor( + experimental::ServerRpcInfo* info) override { + return new SyncSendMessageTester(info); + } +}; + +// Test if SendMessage function family works as expected for sync/callback apis +class SyncSendMessageVerifier : public experimental::Interceptor { + public: + SyncSendMessageVerifier(experimental::ServerRpcInfo* info) {} + + void Intercept(experimental::InterceptorBatchMethods* methods) override { + if (methods->QueryInterceptionHookPoint( + experimental::InterceptionHookPoints::PRE_SEND_MESSAGE)) { + // Make sure that the changes made in SyncSendMessageTester persisted + string old_msg = + static_cast(methods->GetSendMessage())->message(); + EXPECT_EQ(old_msg.find("World"), 0u); + + // Remove the "World" part of the string that we added earlier + new_msg_.set_message(old_msg.erase(0, 5)); + methods->ModifySendMessage(&new_msg_); + + // LoggingInterceptor verifies that changes got reverted + } + methods->Proceed(); + } + + private: + EchoRequest new_msg_; +}; + +class SyncSendMessageVerifierFactory + : public experimental::ServerInterceptorFactoryInterface { + public: + virtual experimental::Interceptor* CreateServerInterceptor( + experimental::ServerRpcInfo* info) override { + return new SyncSendMessageVerifier(info); + } +}; + void MakeBidiStreamingCall(const std::shared_ptr& channel) { auto stub = grpc::testing::EchoTestService::NewStub(channel); ClientContext ctx; @@ -146,12 +238,21 @@ class ServerInterceptorsEnd2endSyncUnaryTest : public ::testing::Test { std::vector< std::unique_ptr> creators; + creators.push_back( + std::unique_ptr( + new SyncSendMessageTesterFactory())); + creators.push_back( + std::unique_ptr( + new SyncSendMessageVerifierFactory())); creators.push_back( std::unique_ptr( new LoggingInterceptorFactory())); + // Add 20 dummy interceptor factories and null interceptor factories for (auto i = 0; i < 20; i++) { creators.push_back(std::unique_ptr( new DummyInterceptorFactory())); + creators.push_back(std::unique_ptr( + new NullInterceptorFactory())); } builder.experimental().SetInterceptorCreators(std::move(creators)); server_ = builder.BuildAndStart(); @@ -164,7 +265,8 @@ class ServerInterceptorsEnd2endSyncUnaryTest : public ::testing::Test { TEST_F(ServerInterceptorsEnd2endSyncUnaryTest, UnaryTest) { ChannelArguments args; DummyInterceptor::Reset(); - auto channel = CreateChannel(server_address_, InsecureChannelCredentials()); + auto channel = + grpc::CreateChannel(server_address_, InsecureChannelCredentials()); MakeCall(channel); // Make sure all 20 dummy interceptors were run EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 20); @@ -183,6 +285,12 @@ class ServerInterceptorsEnd2endSyncStreamingTest : public ::testing::Test { std::vector< std::unique_ptr> creators; + creators.push_back( + std::unique_ptr( + new SyncSendMessageTesterFactory())); + creators.push_back( + std::unique_ptr( + new SyncSendMessageVerifierFactory())); creators.push_back( std::unique_ptr( new LoggingInterceptorFactory())); @@ -201,7 +309,8 @@ class ServerInterceptorsEnd2endSyncStreamingTest : public ::testing::Test { TEST_F(ServerInterceptorsEnd2endSyncStreamingTest, ClientStreamingTest) { ChannelArguments args; DummyInterceptor::Reset(); - auto channel = CreateChannel(server_address_, InsecureChannelCredentials()); + auto channel = + grpc::CreateChannel(server_address_, InsecureChannelCredentials()); MakeClientStreamingCall(channel); // Make sure all 20 dummy interceptors were run EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 20); @@ -210,7 +319,8 @@ TEST_F(ServerInterceptorsEnd2endSyncStreamingTest, ClientStreamingTest) { TEST_F(ServerInterceptorsEnd2endSyncStreamingTest, ServerStreamingTest) { ChannelArguments args; DummyInterceptor::Reset(); - auto channel = CreateChannel(server_address_, InsecureChannelCredentials()); + auto channel = + grpc::CreateChannel(server_address_, InsecureChannelCredentials()); MakeServerStreamingCall(channel); // Make sure all 20 dummy interceptors were run EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 20); @@ -219,7 +329,8 @@ TEST_F(ServerInterceptorsEnd2endSyncStreamingTest, ServerStreamingTest) { TEST_F(ServerInterceptorsEnd2endSyncStreamingTest, BidiStreamingTest) { ChannelArguments args; DummyInterceptor::Reset(); - auto channel = CreateChannel(server_address_, InsecureChannelCredentials()); + auto channel = + grpc::CreateChannel(server_address_, InsecureChannelCredentials()); MakeBidiStreamingCall(channel); // Make sure all 20 dummy interceptors were run EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 20); @@ -249,7 +360,8 @@ TEST_F(ServerInterceptorsAsyncEnd2endTest, UnaryTest) { auto server = builder.BuildAndStart(); ChannelArguments args; - auto channel = CreateChannel(server_address, InsecureChannelCredentials()); + auto channel = + grpc::CreateChannel(server_address, InsecureChannelCredentials()); auto stub = grpc::testing::EchoTestService::NewStub(channel); EchoRequest send_request; @@ -321,7 +433,8 @@ TEST_F(ServerInterceptorsAsyncEnd2endTest, BidiStreamingTest) { auto server = builder.BuildAndStart(); ChannelArguments args; - auto channel = CreateChannel(server_address, InsecureChannelCredentials()); + auto channel = + grpc::CreateChannel(server_address, InsecureChannelCredentials()); auto stub = grpc::testing::EchoTestService::NewStub(channel); EchoRequest send_request; @@ -397,11 +510,13 @@ TEST_F(ServerInterceptorsAsyncEnd2endTest, GenericRPCTest) { new DummyInterceptorFactory())); } builder.experimental().SetInterceptorCreators(std::move(creators)); - auto cq = builder.AddCompletionQueue(); + auto srv_cq = builder.AddCompletionQueue(); + CompletionQueue cli_cq; auto server = builder.BuildAndStart(); ChannelArguments args; - auto channel = CreateChannel(server_address, InsecureChannelCredentials()); + auto channel = + grpc::CreateChannel(server_address, InsecureChannelCredentials()); GenericStub generic_stub(channel); const grpc::string kMethodName("/grpc.cpp.test.util.EchoTestService/Echo"); @@ -420,28 +535,28 @@ TEST_F(ServerInterceptorsAsyncEnd2endTest, GenericRPCTest) { cli_ctx.AddMetadata("testkey", "testvalue"); std::unique_ptr call = - generic_stub.PrepareCall(&cli_ctx, kMethodName, cq.get()); + generic_stub.PrepareCall(&cli_ctx, kMethodName, &cli_cq); call->StartCall(tag(1)); - Verifier().Expect(1, true).Verify(cq.get()); + Verifier().Expect(1, true).Verify(&cli_cq); std::unique_ptr send_buffer = SerializeToByteBuffer(&send_request); call->Write(*send_buffer, tag(2)); // Send ByteBuffer can be destroyed after calling Write. send_buffer.reset(); - Verifier().Expect(2, true).Verify(cq.get()); + Verifier().Expect(2, true).Verify(&cli_cq); call->WritesDone(tag(3)); - Verifier().Expect(3, true).Verify(cq.get()); + Verifier().Expect(3, true).Verify(&cli_cq); - service.RequestCall(&srv_ctx, &stream, cq.get(), cq.get(), tag(4)); + service.RequestCall(&srv_ctx, &stream, srv_cq.get(), srv_cq.get(), tag(4)); - Verifier().Expect(4, true).Verify(cq.get()); + Verifier().Expect(4, true).Verify(srv_cq.get()); EXPECT_EQ(kMethodName, srv_ctx.method()); EXPECT_TRUE(CheckMetadata(srv_ctx.client_metadata(), "testkey", "testvalue")); srv_ctx.AddTrailingMetadata("testkey", "testvalue"); ByteBuffer recv_buffer; stream.Read(&recv_buffer, tag(5)); - Verifier().Expect(5, true).Verify(cq.get()); + Verifier().Expect(5, true).Verify(srv_cq.get()); EXPECT_TRUE(ParseFromByteBuffer(&recv_buffer, &recv_request)); EXPECT_EQ(send_request.message(), recv_request.message()); @@ -449,18 +564,23 @@ TEST_F(ServerInterceptorsAsyncEnd2endTest, GenericRPCTest) { send_buffer = SerializeToByteBuffer(&send_response); stream.Write(*send_buffer, tag(6)); send_buffer.reset(); - Verifier().Expect(6, true).Verify(cq.get()); + Verifier().Expect(6, true).Verify(srv_cq.get()); stream.Finish(Status::OK, tag(7)); - Verifier().Expect(7, true).Verify(cq.get()); + // Shutdown srv_cq before we try to get the tag back, to verify that the + // interception API handles completion queue shutdowns that take place before + // all the tags are returned + srv_cq->Shutdown(); + Verifier().Expect(7, true).Verify(srv_cq.get()); recv_buffer.Clear(); call->Read(&recv_buffer, tag(8)); - Verifier().Expect(8, true).Verify(cq.get()); + Verifier().Expect(8, true).Verify(&cli_cq); EXPECT_TRUE(ParseFromByteBuffer(&recv_buffer, &recv_response)); call->Finish(&recv_status, tag(9)); - Verifier().Expect(9, true).Verify(cq.get()); + cli_cq.Shutdown(); + Verifier().Expect(9, true).Verify(&cli_cq); EXPECT_EQ(send_response.message(), recv_response.message()); EXPECT_TRUE(recv_status.ok()); @@ -471,10 +591,11 @@ TEST_F(ServerInterceptorsAsyncEnd2endTest, GenericRPCTest) { EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 20); server->Shutdown(); - cq->Shutdown(); void* ignored_tag; bool ignored_ok; - while (cq->Next(&ignored_tag, &ignored_ok)) + while (cli_cq.Next(&ignored_tag, &ignored_ok)) + ; + while (srv_cq->Next(&ignored_tag, &ignored_ok)) ; grpc_recycle_unused_port(port); } @@ -498,7 +619,7 @@ TEST_F(ServerInterceptorsAsyncEnd2endTest, UnimplementedRpcTest) { ChannelArguments args; std::shared_ptr channel = - CreateChannel(server_address, InsecureChannelCredentials()); + grpc::CreateChannel(server_address, InsecureChannelCredentials()); std::unique_ptr stub; stub = grpc::testing::UnimplementedEchoService::NewStub(channel); EchoRequest send_request; @@ -551,7 +672,7 @@ TEST_F(ServerInterceptorsSyncUnimplementedEnd2endTest, UnimplementedRpcTest) { ChannelArguments args; std::shared_ptr channel = - CreateChannel(server_address, InsecureChannelCredentials()); + grpc::CreateChannel(server_address, InsecureChannelCredentials()); std::unique_ptr stub; stub = grpc::testing::UnimplementedEchoService::NewStub(channel); EchoRequest send_request; @@ -577,7 +698,7 @@ TEST_F(ServerInterceptorsSyncUnimplementedEnd2endTest, UnimplementedRpcTest) { } // namespace grpc int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/cpp/end2end/server_load_reporting_end2end_test.cc b/test/cpp/end2end/server_load_reporting_end2end_test.cc index 7bc9af2a6eb..8eba9127ec6 100644 --- a/test/cpp/end2end/server_load_reporting_end2end_test.cc +++ b/test/cpp/end2end/server_load_reporting_end2end_test.cc @@ -94,7 +94,7 @@ class ServerLoadReportingEnd2endTest : public ::testing::Test { const grpc::string& lb_tag, const grpc::string& message, size_t num_requests) { auto stub = EchoTestService::NewStub( - CreateChannel(server_address_, InsecureChannelCredentials())); + grpc::CreateChannel(server_address_, InsecureChannelCredentials())); grpc::string lb_token = lb_id + lb_tag; for (int i = 0; i < num_requests; ++i) { ClientContext ctx; diff --git a/test/cpp/end2end/service_config_end2end_test.cc b/test/cpp/end2end/service_config_end2end_test.cc new file mode 100644 index 00000000000..b3299232763 --- /dev/null +++ b/test/cpp/end2end/service_config_end2end_test.cc @@ -0,0 +1,614 @@ +/* + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "src/core/ext/filters/client_channel/backup_poller.h" +#include "src/core/ext/filters/client_channel/global_subchannel_pool.h" +#include "src/core/ext/filters/client_channel/parse_address.h" +#include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h" +#include "src/core/ext/filters/client_channel/server_address.h" +#include "src/core/lib/backoff/backoff.h" +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gprpp/debug_location.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" +#include "src/core/lib/iomgr/tcp_client.h" +#include "src/core/lib/security/credentials/fake/fake_credentials.h" +#include "src/cpp/client/secure_credentials.h" +#include "src/cpp/server/secure_server_credentials.h" + +#include "src/proto/grpc/testing/echo.grpc.pb.h" +#include "test/core/util/port.h" +#include "test/core/util/test_config.h" +#include "test/cpp/end2end/test_service_impl.h" + +#include +#include + +using grpc::testing::EchoRequest; +using grpc::testing::EchoResponse; +using std::chrono::system_clock; + +namespace grpc { +namespace testing { +namespace { + +// Subclass of TestServiceImpl that increments a request counter for +// every call to the Echo RPC. +class MyTestServiceImpl : public TestServiceImpl { + public: + MyTestServiceImpl() : request_count_(0) {} + + Status Echo(ServerContext* context, const EchoRequest* request, + EchoResponse* response) override { + { + grpc::internal::MutexLock lock(&mu_); + ++request_count_; + } + AddClient(context->peer()); + return TestServiceImpl::Echo(context, request, response); + } + + int request_count() { + grpc::internal::MutexLock lock(&mu_); + return request_count_; + } + + void ResetCounters() { + grpc::internal::MutexLock lock(&mu_); + request_count_ = 0; + } + + std::set clients() { + grpc::internal::MutexLock lock(&clients_mu_); + return clients_; + } + + private: + void AddClient(const grpc::string& client) { + grpc::internal::MutexLock lock(&clients_mu_); + clients_.insert(client); + } + + grpc::internal::Mutex mu_; + int request_count_; + grpc::internal::Mutex clients_mu_; + std::set clients_; +}; + +class ServiceConfigEnd2endTest : public ::testing::Test { + protected: + ServiceConfigEnd2endTest() + : server_host_("localhost"), + kRequestMessage_("Live long and prosper."), + creds_(new SecureChannelCredentials( + grpc_fake_transport_security_credentials_create())) { + // Make the backup poller poll very frequently in order to pick up + // updates from all the subchannels's FDs. + GPR_GLOBAL_CONFIG_SET(grpc_client_channel_backup_poll_interval_ms, 1); + } + + void SetUp() override { + grpc_init(); + response_generator_ = + grpc_core::MakeRefCounted(); + } + + void TearDown() override { + for (size_t i = 0; i < servers_.size(); ++i) { + servers_[i]->Shutdown(); + } + // Explicitly destroy all the members so that we can make sure grpc_shutdown + // has finished by the end of this function, and thus all the registered + // LB policy factories are removed. + stub_.reset(); + servers_.clear(); + creds_.reset(); + grpc_shutdown_blocking(); + } + + void CreateServers(size_t num_servers, + std::vector ports = std::vector()) { + servers_.clear(); + for (size_t i = 0; i < num_servers; ++i) { + int port = 0; + if (ports.size() == num_servers) port = ports[i]; + servers_.emplace_back(new ServerData(port)); + } + } + + void StartServer(size_t index) { servers_[index]->Start(server_host_); } + + void StartServers(size_t num_servers, + std::vector ports = std::vector()) { + CreateServers(num_servers, std::move(ports)); + for (size_t i = 0; i < num_servers; ++i) { + StartServer(i); + } + } + + grpc_core::Resolver::Result BuildFakeResults(const std::vector& ports) { + grpc_core::Resolver::Result result; + for (const int& port : ports) { + char* lb_uri_str; + gpr_asprintf(&lb_uri_str, "ipv4:127.0.0.1:%d", port); + grpc_uri* lb_uri = grpc_uri_parse(lb_uri_str, true); + GPR_ASSERT(lb_uri != nullptr); + grpc_resolved_address address; + GPR_ASSERT(grpc_parse_uri(lb_uri, &address)); + result.addresses.emplace_back(address.addr, address.len, + nullptr /* args */); + grpc_uri_destroy(lb_uri); + gpr_free(lb_uri_str); + } + return result; + } + + void SetNextResolutionNoServiceConfig(const std::vector& ports) { + grpc_core::ExecCtx exec_ctx; + grpc_core::Resolver::Result result = BuildFakeResults(ports); + response_generator_->SetResponse(result); + } + + void SetNextResolutionValidServiceConfig(const std::vector& ports) { + grpc_core::ExecCtx exec_ctx; + grpc_core::Resolver::Result result = BuildFakeResults(ports); + result.service_config = + grpc_core::ServiceConfig::Create("{}", &result.service_config_error); + response_generator_->SetResponse(result); + } + + void SetNextResolutionInvalidServiceConfig(const std::vector& ports) { + grpc_core::ExecCtx exec_ctx; + grpc_core::Resolver::Result result = BuildFakeResults(ports); + result.service_config = + grpc_core::ServiceConfig::Create("{", &result.service_config_error); + response_generator_->SetResponse(result); + } + + void SetNextResolutionWithServiceConfig(const std::vector& ports, + const char* svc_cfg) { + grpc_core::ExecCtx exec_ctx; + grpc_core::Resolver::Result result = BuildFakeResults(ports); + result.service_config = + grpc_core::ServiceConfig::Create(svc_cfg, &result.service_config_error); + response_generator_->SetResponse(result); + } + + std::vector GetServersPorts(size_t start_index = 0) { + std::vector ports; + for (size_t i = start_index; i < servers_.size(); ++i) { + ports.push_back(servers_[i]->port_); + } + return ports; + } + + std::unique_ptr BuildStub( + const std::shared_ptr& channel) { + return grpc::testing::EchoTestService::NewStub(channel); + } + + std::shared_ptr BuildChannel() { + ChannelArguments args; + args.SetPointer(GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR, + response_generator_.get()); + return ::grpc::CreateCustomChannel("fake:///", creds_, args); + } + + std::shared_ptr BuildChannelWithDefaultServiceConfig() { + ChannelArguments args; + args.SetServiceConfigJSON(ValidDefaultServiceConfig()); + args.SetPointer(GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR, + response_generator_.get()); + return ::grpc::CreateCustomChannel("fake:///", creds_, args); + } + + std::shared_ptr BuildChannelWithInvalidDefaultServiceConfig() { + ChannelArguments args; + args.SetServiceConfigJSON(InvalidDefaultServiceConfig()); + args.SetPointer(GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR, + response_generator_.get()); + return ::grpc::CreateCustomChannel("fake:///", creds_, args); + } + + bool SendRpc( + const std::unique_ptr& stub, + EchoResponse* response = nullptr, int timeout_ms = 1000, + Status* result = nullptr, bool wait_for_ready = false) { + const bool local_response = (response == nullptr); + if (local_response) response = new EchoResponse; + EchoRequest request; + request.set_message(kRequestMessage_); + ClientContext context; + context.set_deadline(grpc_timeout_milliseconds_to_deadline(timeout_ms)); + if (wait_for_ready) context.set_wait_for_ready(true); + Status status = stub->Echo(&context, request, response); + if (result != nullptr) *result = status; + if (local_response) delete response; + return status.ok(); + } + + void CheckRpcSendOk( + const std::unique_ptr& stub, + const grpc_core::DebugLocation& location, bool wait_for_ready = false) { + EchoResponse response; + Status status; + const bool success = + SendRpc(stub, &response, 2000, &status, wait_for_ready); + ASSERT_TRUE(success) << "From " << location.file() << ":" << location.line() + << "\n" + << "Error: " << status.error_message() << " " + << status.error_details(); + ASSERT_EQ(response.message(), kRequestMessage_) + << "From " << location.file() << ":" << location.line(); + if (!success) abort(); + } + + void CheckRpcSendFailure( + const std::unique_ptr& stub) { + const bool success = SendRpc(stub); + EXPECT_FALSE(success); + } + + struct ServerData { + int port_; + std::unique_ptr server_; + MyTestServiceImpl service_; + std::unique_ptr thread_; + bool server_ready_ = false; + bool started_ = false; + + explicit ServerData(int port = 0) { + port_ = port > 0 ? port : grpc_pick_unused_port_or_die(); + } + + void Start(const grpc::string& server_host) { + gpr_log(GPR_INFO, "starting server on port %d", port_); + started_ = true; + grpc::internal::Mutex mu; + grpc::internal::MutexLock lock(&mu); + grpc::internal::CondVar cond; + thread_.reset(new std::thread( + std::bind(&ServerData::Serve, this, server_host, &mu, &cond))); + cond.WaitUntil(&mu, [this] { return server_ready_; }); + server_ready_ = false; + gpr_log(GPR_INFO, "server startup complete"); + } + + void Serve(const grpc::string& server_host, grpc::internal::Mutex* mu, + grpc::internal::CondVar* cond) { + std::ostringstream server_address; + server_address << server_host << ":" << port_; + ServerBuilder builder; + std::shared_ptr creds(new SecureServerCredentials( + grpc_fake_transport_security_server_credentials_create())); + builder.AddListeningPort(server_address.str(), std::move(creds)); + builder.RegisterService(&service_); + server_ = builder.BuildAndStart(); + grpc::internal::MutexLock lock(mu); + server_ready_ = true; + cond->Signal(); + } + + void Shutdown() { + if (!started_) return; + server_->Shutdown(grpc_timeout_milliseconds_to_deadline(0)); + thread_->join(); + started_ = false; + } + + void SetServingStatus(const grpc::string& service, bool serving) { + server_->GetHealthCheckService()->SetServingStatus(service, serving); + } + }; + + void ResetCounters() { + for (const auto& server : servers_) server->service_.ResetCounters(); + } + + void WaitForServer( + const std::unique_ptr& stub, + size_t server_idx, const grpc_core::DebugLocation& location, + bool ignore_failure = false) { + do { + if (ignore_failure) { + SendRpc(stub); + } else { + CheckRpcSendOk(stub, location, true); + } + } while (servers_[server_idx]->service_.request_count() == 0); + ResetCounters(); + } + + bool WaitForChannelNotReady(Channel* channel, int timeout_seconds = 5) { + const gpr_timespec deadline = + grpc_timeout_seconds_to_deadline(timeout_seconds); + grpc_connectivity_state state; + while ((state = channel->GetState(false /* try_to_connect */)) == + GRPC_CHANNEL_READY) { + if (!channel->WaitForStateChange(state, deadline)) return false; + } + return true; + } + + bool WaitForChannelReady(Channel* channel, int timeout_seconds = 5) { + const gpr_timespec deadline = + grpc_timeout_seconds_to_deadline(timeout_seconds); + grpc_connectivity_state state; + while ((state = channel->GetState(true /* try_to_connect */)) != + GRPC_CHANNEL_READY) { + if (!channel->WaitForStateChange(state, deadline)) return false; + } + return true; + } + + bool SeenAllServers() { + for (const auto& server : servers_) { + if (server->service_.request_count() == 0) return false; + } + return true; + } + + // Updates \a connection_order by appending to it the index of the newly + // connected server. Must be called after every single RPC. + void UpdateConnectionOrder( + const std::vector>& servers, + std::vector* connection_order) { + for (size_t i = 0; i < servers.size(); ++i) { + if (servers[i]->service_.request_count() == 1) { + // Was the server index known? If not, update connection_order. + const auto it = + std::find(connection_order->begin(), connection_order->end(), i); + if (it == connection_order->end()) { + connection_order->push_back(i); + return; + } + } + } + } + + const char* ValidServiceConfigV1() { return "{\"version\": \"1\"}"; } + + const char* ValidServiceConfigV2() { return "{\"version\": \"2\"}"; } + + const char* ValidDefaultServiceConfig() { + return "{\"version\": \"valid_default\"}"; + } + + const char* InvalidDefaultServiceConfig() { + return "{\"version\": \"invalid_default\""; + } + + const grpc::string server_host_; + std::unique_ptr stub_; + std::vector> servers_; + grpc_core::RefCountedPtr + response_generator_; + const grpc::string kRequestMessage_; + std::shared_ptr creds_; +}; + +TEST_F(ServiceConfigEnd2endTest, NoServiceConfigTest) { + StartServers(1); + auto channel = BuildChannel(); + auto stub = BuildStub(channel); + SetNextResolutionNoServiceConfig(GetServersPorts()); + CheckRpcSendOk(stub, DEBUG_LOCATION); + EXPECT_STREQ("", channel->GetServiceConfigJSON().c_str()); +} + +TEST_F(ServiceConfigEnd2endTest, NoServiceConfigWithDefaultConfigTest) { + StartServers(1); + auto channel = BuildChannelWithDefaultServiceConfig(); + auto stub = BuildStub(channel); + SetNextResolutionNoServiceConfig(GetServersPorts()); + CheckRpcSendOk(stub, DEBUG_LOCATION); + EXPECT_STREQ(ValidDefaultServiceConfig(), + channel->GetServiceConfigJSON().c_str()); +} + +TEST_F(ServiceConfigEnd2endTest, InvalidServiceConfigTest) { + StartServers(1); + auto channel = BuildChannel(); + auto stub = BuildStub(channel); + SetNextResolutionInvalidServiceConfig(GetServersPorts()); + CheckRpcSendFailure(stub); +} + +TEST_F(ServiceConfigEnd2endTest, InvalidServiceConfigWithDefaultConfigTest) { + StartServers(1); + auto channel = BuildChannelWithDefaultServiceConfig(); + auto stub = BuildStub(channel); + SetNextResolutionInvalidServiceConfig(GetServersPorts()); + CheckRpcSendOk(stub, DEBUG_LOCATION); + EXPECT_STREQ(ValidDefaultServiceConfig(), + channel->GetServiceConfigJSON().c_str()); +} + +TEST_F(ServiceConfigEnd2endTest, ValidServiceConfigUpdatesTest) { + StartServers(1); + auto channel = BuildChannel(); + auto stub = BuildStub(channel); + SetNextResolutionWithServiceConfig(GetServersPorts(), ValidServiceConfigV1()); + CheckRpcSendOk(stub, DEBUG_LOCATION); + EXPECT_STREQ(ValidServiceConfigV1(), channel->GetServiceConfigJSON().c_str()); + SetNextResolutionWithServiceConfig(GetServersPorts(), ValidServiceConfigV2()); + CheckRpcSendOk(stub, DEBUG_LOCATION); + EXPECT_STREQ(ValidServiceConfigV2(), channel->GetServiceConfigJSON().c_str()); +} + +TEST_F(ServiceConfigEnd2endTest, + NoServiceConfigUpdateAfterValidServiceConfigTest) { + StartServers(1); + auto channel = BuildChannel(); + auto stub = BuildStub(channel); + SetNextResolutionWithServiceConfig(GetServersPorts(), ValidServiceConfigV1()); + CheckRpcSendOk(stub, DEBUG_LOCATION); + EXPECT_STREQ(ValidServiceConfigV1(), channel->GetServiceConfigJSON().c_str()); + SetNextResolutionNoServiceConfig(GetServersPorts()); + CheckRpcSendOk(stub, DEBUG_LOCATION); + EXPECT_STREQ("", channel->GetServiceConfigJSON().c_str()); +} + +TEST_F(ServiceConfigEnd2endTest, + NoServiceConfigUpdateAfterValidServiceConfigWithDefaultConfigTest) { + StartServers(1); + auto channel = BuildChannelWithDefaultServiceConfig(); + auto stub = BuildStub(channel); + SetNextResolutionWithServiceConfig(GetServersPorts(), ValidServiceConfigV1()); + CheckRpcSendOk(stub, DEBUG_LOCATION); + EXPECT_STREQ(ValidServiceConfigV1(), channel->GetServiceConfigJSON().c_str()); + SetNextResolutionNoServiceConfig(GetServersPorts()); + CheckRpcSendOk(stub, DEBUG_LOCATION); + EXPECT_STREQ(ValidDefaultServiceConfig(), + channel->GetServiceConfigJSON().c_str()); +} + +TEST_F(ServiceConfigEnd2endTest, + InvalidServiceConfigUpdateAfterValidServiceConfigTest) { + StartServers(1); + auto channel = BuildChannel(); + auto stub = BuildStub(channel); + SetNextResolutionWithServiceConfig(GetServersPorts(), ValidServiceConfigV1()); + CheckRpcSendOk(stub, DEBUG_LOCATION); + EXPECT_STREQ(ValidServiceConfigV1(), channel->GetServiceConfigJSON().c_str()); + SetNextResolutionInvalidServiceConfig(GetServersPorts()); + CheckRpcSendOk(stub, DEBUG_LOCATION); + EXPECT_STREQ(ValidServiceConfigV1(), channel->GetServiceConfigJSON().c_str()); +} + +TEST_F(ServiceConfigEnd2endTest, + InvalidServiceConfigUpdateAfterValidServiceConfigWithDefaultConfigTest) { + StartServers(1); + auto channel = BuildChannelWithDefaultServiceConfig(); + auto stub = BuildStub(channel); + SetNextResolutionWithServiceConfig(GetServersPorts(), ValidServiceConfigV1()); + CheckRpcSendOk(stub, DEBUG_LOCATION); + EXPECT_STREQ(ValidServiceConfigV1(), channel->GetServiceConfigJSON().c_str()); + SetNextResolutionInvalidServiceConfig(GetServersPorts()); + CheckRpcSendOk(stub, DEBUG_LOCATION); + EXPECT_STREQ(ValidServiceConfigV1(), channel->GetServiceConfigJSON().c_str()); +} + +TEST_F(ServiceConfigEnd2endTest, + ValidServiceConfigAfterInvalidServiceConfigTest) { + StartServers(1); + auto channel = BuildChannel(); + auto stub = BuildStub(channel); + SetNextResolutionInvalidServiceConfig(GetServersPorts()); + CheckRpcSendFailure(stub); + SetNextResolutionValidServiceConfig(GetServersPorts()); + CheckRpcSendOk(stub, DEBUG_LOCATION); +} + +TEST_F(ServiceConfigEnd2endTest, NoServiceConfigAfterInvalidServiceConfigTest) { + StartServers(1); + auto channel = BuildChannel(); + auto stub = BuildStub(channel); + SetNextResolutionInvalidServiceConfig(GetServersPorts()); + CheckRpcSendFailure(stub); + SetNextResolutionNoServiceConfig(GetServersPorts()); + CheckRpcSendOk(stub, DEBUG_LOCATION); + EXPECT_STREQ("", channel->GetServiceConfigJSON().c_str()); +} + +TEST_F(ServiceConfigEnd2endTest, + AnotherInvalidServiceConfigAfterInvalidServiceConfigTest) { + StartServers(1); + auto channel = BuildChannel(); + auto stub = BuildStub(channel); + SetNextResolutionInvalidServiceConfig(GetServersPorts()); + CheckRpcSendFailure(stub); + SetNextResolutionInvalidServiceConfig(GetServersPorts()); + CheckRpcSendFailure(stub); +} + +TEST_F(ServiceConfigEnd2endTest, InvalidDefaultServiceConfigTest) { + StartServers(1); + auto channel = BuildChannelWithInvalidDefaultServiceConfig(); + auto stub = BuildStub(channel); + // An invalid default service config results in a lame channel which fails all + // RPCs + CheckRpcSendFailure(stub); +} + +TEST_F(ServiceConfigEnd2endTest, + InvalidDefaultServiceConfigTestWithValidServiceConfig) { + StartServers(1); + auto channel = BuildChannelWithInvalidDefaultServiceConfig(); + auto stub = BuildStub(channel); + CheckRpcSendFailure(stub); + // An invalid default service config results in a lame channel which fails all + // RPCs + SetNextResolutionValidServiceConfig(GetServersPorts()); + CheckRpcSendFailure(stub); +} + +TEST_F(ServiceConfigEnd2endTest, + InvalidDefaultServiceConfigTestWithInvalidServiceConfig) { + StartServers(1); + auto channel = BuildChannelWithInvalidDefaultServiceConfig(); + auto stub = BuildStub(channel); + CheckRpcSendFailure(stub); + // An invalid default service config results in a lame channel which fails all + // RPCs + SetNextResolutionInvalidServiceConfig(GetServersPorts()); + CheckRpcSendFailure(stub); +} + +TEST_F(ServiceConfigEnd2endTest, + InvalidDefaultServiceConfigTestWithNoServiceConfig) { + StartServers(1); + auto channel = BuildChannelWithInvalidDefaultServiceConfig(); + auto stub = BuildStub(channel); + CheckRpcSendFailure(stub); + // An invalid default service config results in a lame channel which fails all + // RPCs + SetNextResolutionNoServiceConfig(GetServersPorts()); + CheckRpcSendFailure(stub); +} + +} // namespace +} // namespace testing +} // namespace grpc + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + grpc::testing::TestEnvironment env(argc, argv); + const auto result = RUN_ALL_TESTS(); + return result; +} diff --git a/test/cpp/end2end/shutdown_test.cc b/test/cpp/end2end/shutdown_test.cc index a53de691bcd..9e925364b1f 100644 --- a/test/cpp/end2end/shutdown_test.cc +++ b/test/cpp/end2end/shutdown_test.cc @@ -86,7 +86,7 @@ class ShutdownTest : public ::testing::TestWithParam { ChannelArguments args; auto channel_creds = GetCredentialsProvider()->GetChannelCredentials(GetParam(), &args); - channel_ = CreateCustomChannel(target, channel_creds, args); + channel_ = ::grpc::CreateCustomChannel(target, channel_creds, args); stub_ = grpc::testing::EchoTestService::NewStub(channel_); } @@ -164,7 +164,7 @@ TEST_P(ShutdownTest, ShutdownTest) { } // namespace grpc int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/cpp/end2end/streaming_throughput_test.cc b/test/cpp/end2end/streaming_throughput_test.cc index 898d1ec1188..0c10957eb77 100644 --- a/test/cpp/end2end/streaming_throughput_test.cc +++ b/test/cpp/end2end/streaming_throughput_test.cc @@ -145,8 +145,8 @@ class End2endTest : public ::testing::Test { void TearDown() override { server_->Shutdown(); } void ResetStub() { - std::shared_ptr channel = - CreateChannel(server_address_.str(), InsecureChannelCredentials()); + std::shared_ptr channel = grpc::CreateChannel( + server_address_.str(), InsecureChannelCredentials()); stub_ = grpc::testing::EchoTestService::NewStub(channel); } @@ -187,7 +187,7 @@ TEST_F(End2endTest, StreamingThroughput) { } // namespace grpc int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/cpp/end2end/test_health_check_service_impl.cc b/test/cpp/end2end/test_health_check_service_impl.cc new file mode 100644 index 00000000000..0801e301996 --- /dev/null +++ b/test/cpp/end2end/test_health_check_service_impl.cc @@ -0,0 +1,97 @@ +/* + * + * 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/cpp/end2end/test_health_check_service_impl.h" + +#include + +using grpc::health::v1::HealthCheckRequest; +using grpc::health::v1::HealthCheckResponse; + +namespace grpc { +namespace testing { + +Status HealthCheckServiceImpl::Check(ServerContext* context, + const HealthCheckRequest* request, + HealthCheckResponse* response) { + std::lock_guard lock(mu_); + auto iter = status_map_.find(request->service()); + if (iter == status_map_.end()) { + return Status(StatusCode::NOT_FOUND, ""); + } + response->set_status(iter->second); + return Status::OK; +} + +Status HealthCheckServiceImpl::Watch( + ServerContext* context, const HealthCheckRequest* request, + ::grpc::ServerWriter* writer) { + auto last_state = HealthCheckResponse::UNKNOWN; + while (!context->IsCancelled()) { + { + std::lock_guard lock(mu_); + HealthCheckResponse response; + auto iter = status_map_.find(request->service()); + if (iter == status_map_.end()) { + response.set_status(response.SERVICE_UNKNOWN); + } else { + response.set_status(iter->second); + } + if (response.status() != last_state) { + writer->Write(response, ::grpc::WriteOptions()); + } + } + gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), + gpr_time_from_millis(1000, GPR_TIMESPAN))); + } + return Status::OK; +} + +void HealthCheckServiceImpl::SetStatus( + const grpc::string& service_name, + HealthCheckResponse::ServingStatus status) { + std::lock_guard lock(mu_); + if (shutdown_) { + status = HealthCheckResponse::NOT_SERVING; + } + status_map_[service_name] = status; +} + +void HealthCheckServiceImpl::SetAll(HealthCheckResponse::ServingStatus status) { + std::lock_guard lock(mu_); + if (shutdown_) { + return; + } + for (auto iter = status_map_.begin(); iter != status_map_.end(); ++iter) { + iter->second = status; + } +} + +void HealthCheckServiceImpl::Shutdown() { + std::lock_guard lock(mu_); + if (shutdown_) { + return; + } + shutdown_ = true; + for (auto iter = status_map_.begin(); iter != status_map_.end(); ++iter) { + iter->second = HealthCheckResponse::NOT_SERVING; + } +} + +} // namespace testing +} // namespace grpc diff --git a/test/cpp/end2end/test_health_check_service_impl.h b/test/cpp/end2end/test_health_check_service_impl.h new file mode 100644 index 00000000000..5d36ce5320a --- /dev/null +++ b/test/cpp/end2end/test_health_check_service_impl.h @@ -0,0 +1,58 @@ +/* + * + * 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_CPP_END2END_TEST_HEALTH_CHECK_SERVICE_IMPL_H +#define GRPC_TEST_CPP_END2END_TEST_HEALTH_CHECK_SERVICE_IMPL_H + +#include +#include + +#include +#include + +#include "src/proto/grpc/health/v1/health.grpc.pb.h" + +namespace grpc { +namespace testing { + +// A sample sync implementation of the health checking service. This does the +// same thing as the default one. +class HealthCheckServiceImpl : public health::v1::Health::Service { + public: + Status Check(ServerContext* context, + const health::v1::HealthCheckRequest* request, + health::v1::HealthCheckResponse* response) override; + Status Watch(ServerContext* context, + const health::v1::HealthCheckRequest* request, + ServerWriter* writer) override; + void SetStatus(const grpc::string& service_name, + health::v1::HealthCheckResponse::ServingStatus status); + void SetAll(health::v1::HealthCheckResponse::ServingStatus status); + + void Shutdown(); + + private: + std::mutex mu_; + bool shutdown_ = false; + std::map + status_map_; +}; + +} // namespace testing +} // namespace grpc + +#endif // GRPC_TEST_CPP_END2END_TEST_HEALTH_CHECK_SERVICE_IMPL_H diff --git a/test/cpp/end2end/test_service_impl.cc b/test/cpp/end2end/test_service_impl.cc index 605356724fb..4078cdfb257 100644 --- a/test/cpp/end2end/test_service_impl.cc +++ b/test/cpp/end2end/test_service_impl.cc @@ -69,6 +69,76 @@ void CheckServerAuthContext( EXPECT_EQ(expected_client_identity, identity[0]); } } + +// Returns the number of pairs in metadata that exactly match the given +// key-value pair. Returns -1 if the pair wasn't found. +int MetadataMatchCount( + const std::multimap& metadata, + const grpc::string& key, const grpc::string& value) { + int count = 0; + for (std::multimap::const_iterator iter = + metadata.begin(); + iter != metadata.end(); ++iter) { + if (ToString(iter->first) == key && ToString(iter->second) == value) { + count++; + } + } + return count; +} +} // namespace + +namespace { +int GetIntValueFromMetadataHelper( + const char* key, + const std::multimap& metadata, + int default_value) { + if (metadata.find(key) != metadata.end()) { + std::istringstream iss(ToString(metadata.find(key)->second)); + iss >> default_value; + gpr_log(GPR_INFO, "%s : %d", key, default_value); + } + + return default_value; +} + +int GetIntValueFromMetadata( + const char* key, + const std::multimap& metadata, + int default_value) { + return GetIntValueFromMetadataHelper(key, metadata, default_value); +} + +void ServerTryCancel(ServerContext* context) { + EXPECT_FALSE(context->IsCancelled()); + context->TryCancel(); + gpr_log(GPR_INFO, "Server called TryCancel() to cancel the request"); + // Now wait until it's really canceled + while (!context->IsCancelled()) { + gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), + gpr_time_from_micros(1000, GPR_TIMESPAN))); + } +} + +void ServerTryCancelNonblocking(ServerContext* context) { + EXPECT_FALSE(context->IsCancelled()); + context->TryCancel(); + gpr_log(GPR_INFO, "Server called TryCancel() to cancel the request"); +} + +void LoopUntilCancelled(Alarm* alarm, ServerContext* context, + experimental::ServerCallbackRpcController* controller, + int loop_delay_us) { + if (!context->IsCancelled()) { + alarm->experimental().Set( + gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), + gpr_time_from_micros(loop_delay_us, GPR_TIMESPAN)), + [alarm, context, controller, loop_delay_us](bool) { + LoopUntilCancelled(alarm, context, controller, loop_delay_us); + }); + } else { + controller->Finish(Status::CANCELLED); + } +} } // namespace Status TestServiceImpl::Echo(ServerContext* context, const EchoRequest* request, @@ -130,6 +200,17 @@ Status TestServiceImpl::Echo(ServerContext* context, const EchoRequest* request, EXPECT_FALSE(context->IsCancelled()); } + if (request->has_param() && request->param().echo_metadata_initially()) { + const std::multimap& client_metadata = + context->client_metadata(); + for (std::multimap::const_iterator + iter = client_metadata.begin(); + iter != client_metadata.end(); ++iter) { + context->AddInitialMetadata(ToString(iter->first), + ToString(iter->second)); + } + } + if (request->has_param() && request->param().echo_metadata()) { const std::multimap& client_metadata = context->client_metadata(); @@ -165,9 +246,40 @@ Status TestServiceImpl::Echo(ServerContext* context, const EchoRequest* request, return Status::OK; } +Status TestServiceImpl::CheckClientInitialMetadata(ServerContext* context, + const SimpleRequest* request, + SimpleResponse* response) { + EXPECT_EQ(MetadataMatchCount(context->client_metadata(), + kCheckClientInitialMetadataKey, + kCheckClientInitialMetadataVal), + 1); + EXPECT_EQ(1u, + context->client_metadata().count(kCheckClientInitialMetadataKey)); + return Status::OK; +} + void CallbackTestServiceImpl::Echo( ServerContext* context, const EchoRequest* request, EchoResponse* response, experimental::ServerCallbackRpcController* controller) { + CancelState* cancel_state = new CancelState; + int server_use_cancel_callback = + GetIntValueFromMetadata(kServerUseCancelCallback, + context->client_metadata(), DO_NOT_USE_CALLBACK); + if (server_use_cancel_callback != DO_NOT_USE_CALLBACK) { + controller->SetCancelCallback([cancel_state] { + EXPECT_FALSE(cancel_state->callback_invoked.exchange( + true, std::memory_order_relaxed)); + }); + if (server_use_cancel_callback == MAYBE_USE_CALLBACK_EARLY_CANCEL) { + EXPECT_TRUE(context->IsCancelled()); + EXPECT_TRUE( + cancel_state->callback_invoked.load(std::memory_order_relaxed)); + } else { + EXPECT_FALSE(context->IsCancelled()); + EXPECT_FALSE( + cancel_state->callback_invoked.load(std::memory_order_relaxed)); + } + } // A bit of sleep to make sure that short deadline tests fail if (request->has_param() && request->param().server_sleep_us() > 0) { // Set an alarm for that much time @@ -175,17 +287,49 @@ void CallbackTestServiceImpl::Echo( gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), gpr_time_from_micros(request->param().server_sleep_us(), GPR_TIMESPAN)), - [this, context, request, response, controller](bool) { - EchoNonDelayed(context, request, response, controller); + [this, context, request, response, controller, cancel_state](bool) { + EchoNonDelayed(context, request, response, controller, cancel_state); }); } else { - EchoNonDelayed(context, request, response, controller); + EchoNonDelayed(context, request, response, controller, cancel_state); } } +void CallbackTestServiceImpl::CheckClientInitialMetadata( + ServerContext* context, const SimpleRequest* request, + SimpleResponse* response, + experimental::ServerCallbackRpcController* controller) { + EXPECT_EQ(MetadataMatchCount(context->client_metadata(), + kCheckClientInitialMetadataKey, + kCheckClientInitialMetadataVal), + 1); + EXPECT_EQ(1u, + context->client_metadata().count(kCheckClientInitialMetadataKey)); + controller->Finish(Status::OK); +} + void CallbackTestServiceImpl::EchoNonDelayed( ServerContext* context, const EchoRequest* request, EchoResponse* response, - experimental::ServerCallbackRpcController* controller) { + experimental::ServerCallbackRpcController* controller, + CancelState* cancel_state) { + int server_use_cancel_callback = + GetIntValueFromMetadata(kServerUseCancelCallback, + context->client_metadata(), DO_NOT_USE_CALLBACK); + + // Safe to clear cancel callback even if it wasn't set + controller->ClearCancelCallback(); + if (server_use_cancel_callback == MAYBE_USE_CALLBACK_EARLY_CANCEL || + server_use_cancel_callback == MAYBE_USE_CALLBACK_LATE_CANCEL) { + EXPECT_TRUE(context->IsCancelled()); + EXPECT_TRUE(cancel_state->callback_invoked.load(std::memory_order_relaxed)); + delete cancel_state; + controller->Finish(Status::CANCELLED); + return; + } + + EXPECT_FALSE(cancel_state->callback_invoked.load(std::memory_order_relaxed)); + delete cancel_state; + if (request->has_param() && request->param().server_die()) { gpr_log(GPR_ERROR, "The request should not reach application handler."); GPR_ASSERT(0); @@ -195,6 +339,7 @@ void CallbackTestServiceImpl::EchoNonDelayed( controller->Finish(Status(static_cast(error.code()), error.error_message(), error.binary_error_details())); + return; } int server_try_cancel = GetIntValueFromMetadata( kServerTryCancelRequest, context->client_metadata(), DO_NOT_CANCEL); @@ -206,23 +351,15 @@ void CallbackTestServiceImpl::EchoNonDelayed( EXPECT_FALSE(context->IsCancelled()); context->TryCancel(); gpr_log(GPR_INFO, "Server called TryCancel() to cancel the request"); - // Now wait until it's really canceled - std::function recurrence = [this, context, controller, - &recurrence](bool) { - if (!context->IsCancelled()) { - alarm_.experimental().Set( - gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), - gpr_time_from_micros(1000, GPR_TIMESPAN)), - recurrence); - } else { - controller->Finish(Status::CANCELLED); - } - }; - recurrence(true); + if (server_use_cancel_callback == DO_NOT_USE_CALLBACK) { + // Now wait until it's really canceled + LoopUntilCancelled(&alarm_, context, controller, 1000); + } return; } + gpr_log(GPR_DEBUG, "Request message was %s", request->message().c_str()); response->set_message(request->message()); MaybeEchoDeadline(context, request, response); if (host_) { @@ -233,27 +370,18 @@ void CallbackTestServiceImpl::EchoNonDelayed( std::unique_lock lock(mu_); signal_client_ = true; } - std::function recurrence = [this, context, request, controller, - &recurrence](bool) { - if (!context->IsCancelled()) { - alarm_.experimental().Set( - gpr_time_add( - gpr_now(GPR_CLOCK_REALTIME), - gpr_time_from_micros(request->param().client_cancel_after_us(), - GPR_TIMESPAN)), - recurrence); - } else { - controller->Finish(Status::CANCELLED); - } - }; - recurrence(true); + if (server_use_cancel_callback == DO_NOT_USE_CALLBACK) { + // Now wait until it's really canceled + LoopUntilCancelled(&alarm_, context, controller, + request->param().client_cancel_after_us()); + } return; } else if (request->has_param() && request->param().server_cancel_after_us()) { alarm_.experimental().Set( gpr_time_add( gpr_now(GPR_CLOCK_REALTIME), - gpr_time_from_micros(request->param().client_cancel_after_us(), + gpr_time_from_micros(request->param().server_cancel_after_us(), GPR_TIMESPAN)), [controller](bool) { controller->Finish(Status::CANCELLED); }); return; @@ -262,6 +390,18 @@ void CallbackTestServiceImpl::EchoNonDelayed( EXPECT_FALSE(context->IsCancelled()); } + if (request->has_param() && request->param().echo_metadata_initially()) { + const std::multimap& client_metadata = + context->client_metadata(); + for (std::multimap::const_iterator + iter = client_metadata.begin(); + iter != client_metadata.end(); ++iter) { + context->AddInitialMetadata(ToString(iter->first), + ToString(iter->second)); + } + controller->SendInitialMetadata([](bool ok) { EXPECT_TRUE(ok); }); + } + if (request->has_param() && request->param().echo_metadata()) { const std::multimap& client_metadata = context->client_metadata(); @@ -278,6 +418,7 @@ void CallbackTestServiceImpl::EchoNonDelayed( request->param().debug_info().SerializeAsString(); context->AddTrailingMetadata(kDebugInfoTrailerKey, serialized_debug_info); controller->Finish(Status::CANCELLED); + return; } } if (request->has_param() && @@ -324,7 +465,7 @@ Status TestServiceImpl::RequestStream(ServerContext* context, std::thread* server_try_cancel_thd = nullptr; if (server_try_cancel == CANCEL_DURING_PROCESSING) { server_try_cancel_thd = - new std::thread(&TestServiceImpl::ServerTryCancel, this, context); + new std::thread([context] { ServerTryCancel(context); }); } int num_msgs_read = 0; @@ -379,7 +520,7 @@ Status TestServiceImpl::ResponseStream(ServerContext* context, std::thread* server_try_cancel_thd = nullptr; if (server_try_cancel == CANCEL_DURING_PROCESSING) { server_try_cancel_thd = - new std::thread(&TestServiceImpl::ServerTryCancel, this, context); + new std::thread([context] { ServerTryCancel(context); }); } for (int i = 0; i < server_responses_to_send; i++) { @@ -430,7 +571,7 @@ Status TestServiceImpl::BidiStream( std::thread* server_try_cancel_thd = nullptr; if (server_try_cancel == CANCEL_DURING_PROCESSING) { server_try_cancel_thd = - new std::thread(&TestServiceImpl::ServerTryCancel, this, context); + new std::thread([context] { ServerTryCancel(context); }); } // kServerFinishAfterNReads suggests after how many reads, the server should @@ -464,44 +605,283 @@ Status TestServiceImpl::BidiStream( return Status::OK; } -namespace { -int GetIntValueFromMetadataHelper( - const char* key, - const std::multimap& metadata, - int default_value) { - if (metadata.find(key) != metadata.end()) { - std::istringstream iss(ToString(metadata.find(key)->second)); - iss >> default_value; - gpr_log(GPR_INFO, "%s : %d", key, default_value); - } +experimental::ServerReadReactor* +CallbackTestServiceImpl::RequestStream() { + class Reactor : public ::grpc::experimental::ServerReadReactor { + public: + Reactor() {} + void OnStarted(ServerContext* context, EchoResponse* response) override { + // Assign ctx_ and response_ as late as possible to increase likelihood of + // catching any races - return default_value; -} -}; // namespace + // If 'server_try_cancel' is set in the metadata, the RPC is cancelled by + // the server by calling ServerContext::TryCancel() depending on the + // value: + // CANCEL_BEFORE_PROCESSING: The RPC is cancelled before the server + // reads any message from the client CANCEL_DURING_PROCESSING: The RPC + // is cancelled while the server is reading messages from the client + // CANCEL_AFTER_PROCESSING: The RPC is cancelled after the server reads + // all the messages from the client + server_try_cancel_ = GetIntValueFromMetadata( + kServerTryCancelRequest, context->client_metadata(), DO_NOT_CANCEL); -int TestServiceImpl::GetIntValueFromMetadata( - const char* key, - const std::multimap& metadata, - int default_value) { - return GetIntValueFromMetadataHelper(key, metadata, default_value); + response->set_message(""); + + if (server_try_cancel_ == CANCEL_BEFORE_PROCESSING) { + ServerTryCancelNonblocking(context); + ctx_ = context; + } else { + if (server_try_cancel_ == CANCEL_DURING_PROCESSING) { + context->TryCancel(); + // Don't wait for it here + } + ctx_ = context; + response_ = response; + StartRead(&request_); + } + + on_started_done_ = true; + } + void OnDone() override { delete this; } + void OnCancel() override { + EXPECT_TRUE(on_started_done_); + EXPECT_TRUE(ctx_->IsCancelled()); + FinishOnce(Status::CANCELLED); + } + void OnReadDone(bool ok) override { + if (ok) { + response_->mutable_message()->append(request_.message()); + num_msgs_read_++; + StartRead(&request_); + } else { + gpr_log(GPR_INFO, "Read: %d messages", num_msgs_read_); + + if (server_try_cancel_ == CANCEL_DURING_PROCESSING) { + // Let OnCancel recover this + return; + } + if (server_try_cancel_ == CANCEL_AFTER_PROCESSING) { + ServerTryCancelNonblocking(ctx_); + return; + } + FinishOnce(Status::OK); + } + } + + private: + void FinishOnce(const Status& s) { + std::lock_guard l(finish_mu_); + if (!finished_) { + Finish(s); + finished_ = true; + } + } + + ServerContext* ctx_; + EchoResponse* response_; + EchoRequest request_; + int num_msgs_read_{0}; + int server_try_cancel_; + std::mutex finish_mu_; + bool finished_{false}; + bool on_started_done_{false}; + }; + + return new Reactor; } -int CallbackTestServiceImpl::GetIntValueFromMetadata( - const char* key, - const std::multimap& metadata, - int default_value) { - return GetIntValueFromMetadataHelper(key, metadata, default_value); +// Return 'kNumResponseStreamMsgs' messages. +// TODO(yangg) make it generic by adding a parameter into EchoRequest +experimental::ServerWriteReactor* +CallbackTestServiceImpl::ResponseStream() { + class Reactor + : public ::grpc::experimental::ServerWriteReactor { + public: + Reactor() {} + void OnStarted(ServerContext* context, + const EchoRequest* request) override { + // Assign ctx_ and request_ as late as possible to increase likelihood of + // catching any races + + // If 'server_try_cancel' is set in the metadata, the RPC is cancelled by + // the server by calling ServerContext::TryCancel() depending on the + // value: + // CANCEL_BEFORE_PROCESSING: The RPC is cancelled before the server + // reads any message from the client CANCEL_DURING_PROCESSING: The RPC + // is cancelled while the server is reading messages from the client + // CANCEL_AFTER_PROCESSING: The RPC is cancelled after the server reads + // all the messages from the client + server_try_cancel_ = GetIntValueFromMetadata( + kServerTryCancelRequest, context->client_metadata(), DO_NOT_CANCEL); + server_coalescing_api_ = GetIntValueFromMetadata( + kServerUseCoalescingApi, context->client_metadata(), 0); + server_responses_to_send_ = GetIntValueFromMetadata( + kServerResponseStreamsToSend, context->client_metadata(), + kServerDefaultResponseStreamsToSend); + if (server_try_cancel_ == CANCEL_BEFORE_PROCESSING) { + ServerTryCancelNonblocking(context); + ctx_ = context; + } else { + if (server_try_cancel_ == CANCEL_DURING_PROCESSING) { + context->TryCancel(); + } + ctx_ = context; + request_ = request; + if (num_msgs_sent_ < server_responses_to_send_) { + NextWrite(); + } + } + on_started_done_ = true; + } + void OnDone() override { delete this; } + void OnCancel() override { + EXPECT_TRUE(on_started_done_); + EXPECT_TRUE(ctx_->IsCancelled()); + FinishOnce(Status::CANCELLED); + } + void OnWriteDone(bool ok) override { + if (num_msgs_sent_ < server_responses_to_send_) { + NextWrite(); + } else if (server_coalescing_api_ != 0) { + // We would have already done Finish just after the WriteLast + } else if (server_try_cancel_ == CANCEL_DURING_PROCESSING) { + // Let OnCancel recover this + } else if (server_try_cancel_ == CANCEL_AFTER_PROCESSING) { + ServerTryCancelNonblocking(ctx_); + } else { + FinishOnce(Status::OK); + } + } + + private: + void FinishOnce(const Status& s) { + std::lock_guard l(finish_mu_); + if (!finished_) { + Finish(s); + finished_ = true; + } + } + + void NextWrite() { + response_.set_message(request_->message() + + grpc::to_string(num_msgs_sent_)); + if (num_msgs_sent_ == server_responses_to_send_ - 1 && + server_coalescing_api_ != 0) { + num_msgs_sent_++; + StartWriteLast(&response_, WriteOptions()); + // If we use WriteLast, we shouldn't wait before attempting Finish + FinishOnce(Status::OK); + } else { + num_msgs_sent_++; + StartWrite(&response_); + } + } + ServerContext* ctx_; + const EchoRequest* request_; + EchoResponse response_; + int num_msgs_sent_{0}; + int server_try_cancel_; + int server_coalescing_api_; + int server_responses_to_send_; + std::mutex finish_mu_; + bool finished_{false}; + bool on_started_done_{false}; + }; + return new Reactor; } -void TestServiceImpl::ServerTryCancel(ServerContext* context) { - EXPECT_FALSE(context->IsCancelled()); - context->TryCancel(); - gpr_log(GPR_INFO, "Server called TryCancel() to cancel the request"); - // Now wait until it's really canceled - while (!context->IsCancelled()) { - gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), - gpr_time_from_micros(1000, GPR_TIMESPAN))); - } +experimental::ServerBidiReactor* +CallbackTestServiceImpl::BidiStream() { + class Reactor : public ::grpc::experimental::ServerBidiReactor { + public: + Reactor() {} + void OnStarted(ServerContext* context) override { + // Assign ctx_ as late as possible to increase likelihood of catching any + // races + + // If 'server_try_cancel' is set in the metadata, the RPC is cancelled by + // the server by calling ServerContext::TryCancel() depending on the + // value: + // CANCEL_BEFORE_PROCESSING: The RPC is cancelled before the server + // reads any message from the client CANCEL_DURING_PROCESSING: The RPC + // is cancelled while the server is reading messages from the client + // CANCEL_AFTER_PROCESSING: The RPC is cancelled after the server reads + // all the messages from the client + server_try_cancel_ = GetIntValueFromMetadata( + kServerTryCancelRequest, context->client_metadata(), DO_NOT_CANCEL); + server_write_last_ = GetIntValueFromMetadata( + kServerFinishAfterNReads, context->client_metadata(), 0); + if (server_try_cancel_ == CANCEL_BEFORE_PROCESSING) { + ServerTryCancelNonblocking(context); + ctx_ = context; + } else { + if (server_try_cancel_ == CANCEL_DURING_PROCESSING) { + context->TryCancel(); + } + ctx_ = context; + StartRead(&request_); + } + on_started_done_ = true; + } + void OnDone() override { delete this; } + void OnCancel() override { + EXPECT_TRUE(on_started_done_); + EXPECT_TRUE(ctx_->IsCancelled()); + FinishOnce(Status::CANCELLED); + } + void OnReadDone(bool ok) override { + if (ok) { + num_msgs_read_++; + gpr_log(GPR_INFO, "recv msg %s", request_.message().c_str()); + response_.set_message(request_.message()); + if (num_msgs_read_ == server_write_last_) { + StartWriteLast(&response_, WriteOptions()); + // If we use WriteLast, we shouldn't wait before attempting Finish + } else { + StartWrite(&response_); + return; + } + } + + if (server_try_cancel_ == CANCEL_DURING_PROCESSING) { + // Let OnCancel handle this + } else if (server_try_cancel_ == CANCEL_AFTER_PROCESSING) { + ServerTryCancelNonblocking(ctx_); + } else { + FinishOnce(Status::OK); + } + } + void OnWriteDone(bool ok) override { + std::lock_guard l(finish_mu_); + if (!finished_) { + StartRead(&request_); + } + } + + private: + void FinishOnce(const Status& s) { + std::lock_guard l(finish_mu_); + if (!finished_) { + Finish(s); + finished_ = true; + } + } + + ServerContext* ctx_; + EchoRequest request_; + EchoResponse response_; + int num_msgs_read_{0}; + int server_try_cancel_; + int server_write_last_; + std::mutex finish_mu_; + bool finished_{false}; + bool on_started_done_{false}; + }; + + return new Reactor; } } // namespace testing diff --git a/test/cpp/end2end/test_service_impl.h b/test/cpp/end2end/test_service_impl.h index ddfe94487e8..81b0234e213 100644 --- a/test/cpp/end2end/test_service_impl.h +++ b/test/cpp/end2end/test_service_impl.h @@ -33,9 +33,12 @@ namespace testing { const int kServerDefaultResponseStreamsToSend = 3; const char* const kServerResponseStreamsToSend = "server_responses_to_send"; const char* const kServerTryCancelRequest = "server_try_cancel"; +const char* const kServerUseCancelCallback = "server_use_cancel_callback"; const char* const kDebugInfoTrailerKey = "debug-info-bin"; const char* const kServerFinishAfterNReads = "server_finish_after_n_reads"; const char* const kServerUseCoalescingApi = "server_use_coalescing_api"; +const char* const kCheckClientInitialMetadataKey = "custom_client_metadata"; +const char* const kCheckClientInitialMetadataVal = "Value for client metadata"; typedef enum { DO_NOT_CANCEL = 0, @@ -44,6 +47,13 @@ typedef enum { CANCEL_AFTER_PROCESSING } ServerTryCancelRequestPhase; +typedef enum { + DO_NOT_USE_CALLBACK = 0, + MAYBE_USE_CALLBACK_EARLY_CANCEL, + MAYBE_USE_CALLBACK_LATE_CANCEL, + MAYBE_USE_CALLBACK_NO_CANCEL, +} ServerUseCancelCallback; + class TestServiceImpl : public ::grpc::testing::EchoTestService::Service { public: TestServiceImpl() : signal_client_(false), host_() {} @@ -53,6 +63,10 @@ class TestServiceImpl : public ::grpc::testing::EchoTestService::Service { Status Echo(ServerContext* context, const EchoRequest* request, EchoResponse* response) override; + Status CheckClientInitialMetadata(ServerContext* context, + const SimpleRequest* request, + SimpleResponse* response) override; + // Unimplemented is left unimplemented to test the returned error. Status RequestStream(ServerContext* context, @@ -72,13 +86,6 @@ class TestServiceImpl : public ::grpc::testing::EchoTestService::Service { } private: - int GetIntValueFromMetadata( - const char* key, - const std::multimap& metadata, - int default_value); - - void ServerTryCancel(ServerContext* context); - bool signal_client_; std::mutex mu_; std::unique_ptr host_; @@ -95,6 +102,20 @@ class CallbackTestServiceImpl EchoResponse* response, experimental::ServerCallbackRpcController* controller) override; + void CheckClientInitialMetadata( + ServerContext* context, const SimpleRequest* request, + SimpleResponse* response, + experimental::ServerCallbackRpcController* controller) override; + + experimental::ServerReadReactor* RequestStream() + override; + + experimental::ServerWriteReactor* ResponseStream() + override; + + experimental::ServerBidiReactor* BidiStream() + override; + // Unimplemented is left unimplemented to test the returned error. bool signal_client() { std::unique_lock lock(mu_); @@ -102,14 +123,13 @@ class CallbackTestServiceImpl } private: + struct CancelState { + std::atomic_bool callback_invoked{false}; + }; void EchoNonDelayed(ServerContext* context, const EchoRequest* request, EchoResponse* response, - experimental::ServerCallbackRpcController* controller); - - int GetIntValueFromMetadata( - const char* key, - const std::multimap& metadata, - int default_value); + experimental::ServerCallbackRpcController* controller, + CancelState* cancel_state); Alarm alarm_; bool signal_client_; diff --git a/test/cpp/end2end/thread_stress_test.cc b/test/cpp/end2end/thread_stress_test.cc index 1a5ed28a2cc..eb8e7958b4b 100644 --- a/test/cpp/end2end/thread_stress_test.cc +++ b/test/cpp/end2end/thread_stress_test.cc @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -95,8 +96,8 @@ template class CommonStressTestInsecure : public CommonStressTest { public: void ResetStub() override { - std::shared_ptr channel = - CreateChannel(server_address_.str(), InsecureChannelCredentials()); + std::shared_ptr channel = grpc::CreateChannel( + server_address_.str(), InsecureChannelCredentials()); this->stub_ = grpc::testing::EchoTestService::NewStub(channel); } bool AllowExhaustion() override { return false; } @@ -188,7 +189,7 @@ class CommonStressTestAsyncServer : public BaseClass { } void TearDown() override { { - std::unique_lock l(mu_); + grpc::internal::MutexLock l(&mu_); this->TearDownStart(); shutting_down_ = true; cq_->Shutdown(); @@ -229,7 +230,7 @@ class CommonStressTestAsyncServer : public BaseClass { } } void RefreshContext(int i) { - std::unique_lock l(mu_); + grpc::internal::MutexLock l(&mu_); if (!shutting_down_) { contexts_[i].state = Context::READY; contexts_[i].srv_ctx.reset(new ServerContext); @@ -253,7 +254,7 @@ class CommonStressTestAsyncServer : public BaseClass { ::grpc::testing::EchoTestService::AsyncService service_; std::unique_ptr cq_; bool shutting_down_; - std::mutex mu_; + grpc::internal::Mutex mu_; std::vector server_threads_; }; @@ -341,9 +342,9 @@ class AsyncClientEnd2endTest : public ::testing::Test { } void Wait() { - std::unique_lock l(mu_); + grpc::internal::MutexLock l(&mu_); while (rpcs_outstanding_ != 0) { - cv_.wait(l); + cv_.Wait(&mu_); } cq_.Shutdown(); @@ -366,7 +367,7 @@ class AsyncClientEnd2endTest : public ::testing::Test { call->response_reader->Finish(&call->response, &call->status, (void*)call); - std::unique_lock l(mu_); + grpc::internal::MutexLock l(&mu_); rpcs_outstanding_++; } } @@ -384,20 +385,20 @@ class AsyncClientEnd2endTest : public ::testing::Test { bool notify; { - std::unique_lock l(mu_); + grpc::internal::MutexLock l(&mu_); rpcs_outstanding_--; notify = (rpcs_outstanding_ == 0); } if (notify) { - cv_.notify_all(); + cv_.Signal(); } } } Common common_; CompletionQueue cq_; - std::mutex mu_; - std::condition_variable cv_; + grpc::internal::Mutex mu_; + grpc::internal::CondVar cv_; int rpcs_outstanding_; }; @@ -429,7 +430,7 @@ TYPED_TEST(AsyncClientEnd2endTest, ThreadStress) { } // namespace grpc int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/cpp/end2end/time_change_test.cc b/test/cpp/end2end/time_change_test.cc new file mode 100644 index 00000000000..688549e5772 --- /dev/null +++ b/test/cpp/end2end/time_change_test.cc @@ -0,0 +1,426 @@ +/* + * + * Copyright 2019 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include "src/core/lib/iomgr/timer.h" +#include "src/proto/grpc/testing/echo.grpc.pb.h" +#include "test/core/util/port.h" +#include "test/core/util/test_config.h" +#include "test/cpp/end2end/test_service_impl.h" +#include "test/cpp/util/subprocess.h" + +#include +#include +#include +#include + +using grpc::testing::EchoRequest; +using grpc::testing::EchoResponse; + +static std::string g_root; + +static gpr_mu g_mu; +extern gpr_timespec (*gpr_now_impl)(gpr_clock_type clock_type); +gpr_timespec (*gpr_now_impl_orig)(gpr_clock_type clock_type) = gpr_now_impl; +static int g_time_shift_sec = 0; +static int g_time_shift_nsec = 0; +static gpr_timespec now_impl(gpr_clock_type clock) { + auto ts = gpr_now_impl_orig(clock); + // We only manipulate the realtime clock to simulate changes in wall-clock + // time + if (clock != GPR_CLOCK_REALTIME) { + return ts; + } + GPR_ASSERT(ts.tv_nsec >= 0); + GPR_ASSERT(ts.tv_nsec < GPR_NS_PER_SEC); + gpr_mu_lock(&g_mu); + ts.tv_sec += g_time_shift_sec; + ts.tv_nsec += g_time_shift_nsec; + gpr_mu_unlock(&g_mu); + if (ts.tv_nsec >= GPR_NS_PER_SEC) { + ts.tv_nsec -= GPR_NS_PER_SEC; + ++ts.tv_sec; + } else if (ts.tv_nsec < 0) { + --ts.tv_sec; + ts.tv_nsec = GPR_NS_PER_SEC + ts.tv_nsec; + } + return ts; +} + +// offset the value returned by gpr_now(GPR_CLOCK_REALTIME) by msecs +// milliseconds +static void set_now_offset(int msecs) { + gpr_mu_lock(&g_mu); + g_time_shift_sec = msecs / 1000; + g_time_shift_nsec = (msecs % 1000) * 1e6; + gpr_mu_unlock(&g_mu); +} + +// restore the original implementation of gpr_now() +static void reset_now_offset() { + gpr_mu_lock(&g_mu); + g_time_shift_sec = 0; + g_time_shift_nsec = 0; + gpr_mu_unlock(&g_mu); +} + +namespace grpc { +namespace testing { + +namespace { + +// gpr_now() is called with invalid clock_type +TEST(TimespecTest, GprNowInvalidClockType) { + // initialize to some junk value + gpr_clock_type invalid_clock_type = (gpr_clock_type)32641; + EXPECT_DEATH(gpr_now(invalid_clock_type), ".*"); +} + +// Add timespan with negative nanoseconds +TEST(TimespecTest, GprTimeAddNegativeNs) { + gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC); + gpr_timespec bad_ts = {1, -1000, GPR_TIMESPAN}; + EXPECT_DEATH(gpr_time_add(now, bad_ts), ".*"); +} + +// Subtract timespan with negative nanoseconds +TEST(TimespecTest, GprTimeSubNegativeNs) { + // Nanoseconds must always be positive. Negative timestamps are represented by + // (negative seconds, positive nanoseconds) + gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC); + gpr_timespec bad_ts = {1, -1000, GPR_TIMESPAN}; + EXPECT_DEATH(gpr_time_sub(now, bad_ts), ".*"); +} + +// Add negative milliseconds to gpr_timespec +TEST(TimespecTest, GrpcNegativeMillisToTimespec) { + // -1500 milliseconds converts to timespec (-2 secs, 5 * 10^8 nsec) + gpr_timespec ts = grpc_millis_to_timespec(-1500, GPR_CLOCK_MONOTONIC); + GPR_ASSERT(ts.tv_sec = -2); + GPR_ASSERT(ts.tv_nsec = 5e8); + GPR_ASSERT(ts.clock_type == GPR_CLOCK_MONOTONIC); +} + +class TimeChangeTest : public ::testing::Test { + protected: + TimeChangeTest() {} + + void SetUp() { + auto port = grpc_pick_unused_port_or_die(); + std::ostringstream addr_stream; + addr_stream << "localhost:" << port; + auto addr = addr_stream.str(); + server_.reset(new SubProcess({ + g_root + "/client_crash_test_server", + "--address=" + addr, + })); + GPR_ASSERT(server_); + channel_ = grpc::CreateChannel(addr, InsecureChannelCredentials()); + GPR_ASSERT(channel_); + stub_ = grpc::testing::EchoTestService::NewStub(channel_); + } + + void TearDown() { + server_.reset(); + reset_now_offset(); + } + + std::unique_ptr CreateStub() { + return grpc::testing::EchoTestService::NewStub(channel_); + } + + std::shared_ptr GetChannel() { return channel_; } + // time jump offsets in milliseconds + const int TIME_OFFSET1 = 20123; + const int TIME_OFFSET2 = 5678; + + private: + std::unique_ptr server_; + std::shared_ptr channel_; + std::unique_ptr stub_; +}; + +// Wall-clock time jumps forward on client before bidi stream is created +TEST_F(TimeChangeTest, TimeJumpForwardBeforeStreamCreated) { + EchoRequest request; + EchoResponse response; + ClientContext context; + context.set_deadline(grpc_timeout_milliseconds_to_deadline(5000)); + context.AddMetadata(kServerResponseStreamsToSend, "1"); + + auto channel = GetChannel(); + GPR_ASSERT(channel); + EXPECT_TRUE( + channel->WaitForConnected(grpc_timeout_milliseconds_to_deadline(5000))); + auto stub = CreateStub(); + + // time jumps forward by TIME_OFFSET1 milliseconds + set_now_offset(TIME_OFFSET1); + auto stream = stub->BidiStream(&context); + request.set_message("Hello"); + EXPECT_TRUE(stream->Write(request)); + + EXPECT_TRUE(stream->WritesDone()); + EXPECT_TRUE(stream->Read(&response)); + + auto status = stream->Finish(); + EXPECT_TRUE(status.ok()); +} + +// Wall-clock time jumps back on client before bidi stream is created +TEST_F(TimeChangeTest, TimeJumpBackBeforeStreamCreated) { + EchoRequest request; + EchoResponse response; + ClientContext context; + context.set_deadline(grpc_timeout_milliseconds_to_deadline(5000)); + context.AddMetadata(kServerResponseStreamsToSend, "1"); + + auto channel = GetChannel(); + GPR_ASSERT(channel); + EXPECT_TRUE( + channel->WaitForConnected(grpc_timeout_milliseconds_to_deadline(5000))); + auto stub = CreateStub(); + + // time jumps back by TIME_OFFSET1 milliseconds + set_now_offset(-TIME_OFFSET1); + auto stream = stub->BidiStream(&context); + request.set_message("Hello"); + EXPECT_TRUE(stream->Write(request)); + + EXPECT_TRUE(stream->WritesDone()); + EXPECT_TRUE(stream->Read(&response)); + EXPECT_EQ(request.message(), response.message()); + + auto status = stream->Finish(); + EXPECT_TRUE(status.ok()); +} + +// Wall-clock time jumps forward on client while call is in progress +TEST_F(TimeChangeTest, TimeJumpForwardAfterStreamCreated) { + EchoRequest request; + EchoResponse response; + ClientContext context; + context.set_deadline(grpc_timeout_milliseconds_to_deadline(5000)); + context.AddMetadata(kServerResponseStreamsToSend, "2"); + + auto channel = GetChannel(); + GPR_ASSERT(channel); + EXPECT_TRUE( + channel->WaitForConnected(grpc_timeout_milliseconds_to_deadline(5000))); + auto stub = CreateStub(); + + auto stream = stub->BidiStream(&context); + + request.set_message("Hello"); + EXPECT_TRUE(stream->Write(request)); + EXPECT_TRUE(stream->Read(&response)); + + // time jumps forward by TIME_OFFSET1 milliseconds. + set_now_offset(TIME_OFFSET1); + + request.set_message("World"); + EXPECT_TRUE(stream->Write(request)); + EXPECT_TRUE(stream->WritesDone()); + EXPECT_TRUE(stream->Read(&response)); + + auto status = stream->Finish(); + EXPECT_TRUE(status.ok()); +} + +// Wall-clock time jumps back on client while call is in progress +TEST_F(TimeChangeTest, TimeJumpBackAfterStreamCreated) { + EchoRequest request; + EchoResponse response; + ClientContext context; + context.set_deadline(grpc_timeout_milliseconds_to_deadline(5000)); + context.AddMetadata(kServerResponseStreamsToSend, "2"); + + auto channel = GetChannel(); + GPR_ASSERT(channel); + EXPECT_TRUE( + channel->WaitForConnected(grpc_timeout_milliseconds_to_deadline(5000))); + auto stub = CreateStub(); + + auto stream = stub->BidiStream(&context); + + request.set_message("Hello"); + EXPECT_TRUE(stream->Write(request)); + EXPECT_TRUE(stream->Read(&response)); + + // time jumps back TIME_OFFSET1 milliseconds. + set_now_offset(-TIME_OFFSET1); + + request.set_message("World"); + EXPECT_TRUE(stream->Write(request)); + EXPECT_TRUE(stream->WritesDone()); + EXPECT_TRUE(stream->Read(&response)); + + auto status = stream->Finish(); + EXPECT_TRUE(status.ok()); +} + +// Wall-clock time jumps forward on client before connection to server is up +TEST_F(TimeChangeTest, TimeJumpForwardBeforeServerConnect) { + EchoRequest request; + EchoResponse response; + ClientContext context; + context.set_deadline(grpc_timeout_milliseconds_to_deadline(5000)); + context.AddMetadata(kServerResponseStreamsToSend, "2"); + + auto channel = GetChannel(); + GPR_ASSERT(channel); + + // time jumps forward by TIME_OFFSET2 milliseconds + set_now_offset(TIME_OFFSET2); + + auto ret = + channel->WaitForConnected(grpc_timeout_milliseconds_to_deadline(5000)); + // We use monotonic clock for pthread_cond_timedwait() deadline on linux, and + // realtime clock on other platforms - see gpr_cv_wait() in sync_posix.cc. + // So changes in system clock affect deadlines on non-linux platforms +#ifdef GPR_LINUX + EXPECT_TRUE(ret); + auto stub = CreateStub(); + auto stream = stub->BidiStream(&context); + + request.set_message("Hello"); + EXPECT_TRUE(stream->Write(request)); + EXPECT_TRUE(stream->Read(&response)); + request.set_message("World"); + EXPECT_TRUE(stream->Write(request)); + EXPECT_TRUE(stream->WritesDone()); + EXPECT_TRUE(stream->Read(&response)); + + auto status = stream->Finish(); + EXPECT_TRUE(status.ok()); +#else + EXPECT_FALSE(ret); +#endif +} + +// Wall-clock time jumps back on client before connection to server is up +TEST_F(TimeChangeTest, TimeJumpBackBeforeServerConnect) { + EchoRequest request; + EchoResponse response; + ClientContext context; + context.set_deadline(grpc_timeout_milliseconds_to_deadline(5000)); + context.AddMetadata(kServerResponseStreamsToSend, "2"); + + auto channel = GetChannel(); + GPR_ASSERT(channel); + + // time jumps back by TIME_OFFSET2 milliseconds + set_now_offset(-TIME_OFFSET2); + + EXPECT_TRUE( + channel->WaitForConnected(grpc_timeout_milliseconds_to_deadline(5000))); + auto stub = CreateStub(); + auto stream = stub->BidiStream(&context); + + request.set_message("Hello"); + EXPECT_TRUE(stream->Write(request)); + EXPECT_TRUE(stream->Read(&response)); + request.set_message("World"); + EXPECT_TRUE(stream->Write(request)); + EXPECT_TRUE(stream->WritesDone()); + EXPECT_TRUE(stream->Read(&response)); + + auto status = stream->Finish(); + EXPECT_TRUE(status.ok()); +} + +// Wall-clock time jumps forward and backwards during call +TEST_F(TimeChangeTest, TimeJumpForwardAndBackDuringCall) { + EchoRequest request; + EchoResponse response; + ClientContext context; + context.set_deadline(grpc_timeout_milliseconds_to_deadline(5000)); + context.AddMetadata(kServerResponseStreamsToSend, "2"); + + auto channel = GetChannel(); + GPR_ASSERT(channel); + + EXPECT_TRUE( + channel->WaitForConnected(grpc_timeout_milliseconds_to_deadline(5000))); + auto stub = CreateStub(); + auto stream = stub->BidiStream(&context); + + request.set_message("Hello"); + EXPECT_TRUE(stream->Write(request)); + + // time jumps back by TIME_OFFSET2 milliseconds + set_now_offset(-TIME_OFFSET2); + + EXPECT_TRUE(stream->Read(&response)); + request.set_message("World"); + + // time jumps forward by TIME_OFFSET milliseconds + set_now_offset(TIME_OFFSET1); + + EXPECT_TRUE(stream->Write(request)); + + // time jumps back by TIME_OFFSET2 milliseconds + set_now_offset(-TIME_OFFSET2); + + EXPECT_TRUE(stream->WritesDone()); + + // time jumps back by TIME_OFFSET2 milliseconds + set_now_offset(-TIME_OFFSET2); + + EXPECT_TRUE(stream->Read(&response)); + + // time jumps back by TIME_OFFSET2 milliseconds + set_now_offset(-TIME_OFFSET2); + + auto status = stream->Finish(); + EXPECT_TRUE(status.ok()); +} + +} // namespace + +} // namespace testing +} // namespace grpc + +int main(int argc, char** argv) { + std::string me = argv[0]; + // get index of last slash in path to test binary + auto lslash = me.rfind('/'); + // set g_root = path to directory containing test binary + if (lslash != std::string::npos) { + g_root = me.substr(0, lslash); + } else { + g_root = "."; + } + + gpr_mu_init(&g_mu); + gpr_now_impl = now_impl; + + grpc::testing::TestEnvironment env(argc, argv); + ::testing::InitGoogleTest(&argc, argv); + auto ret = RUN_ALL_TESTS(); + return ret; +} diff --git a/test/cpp/end2end/xds_end2end_test.cc b/test/cpp/end2end/xds_end2end_test.cc new file mode 100644 index 00000000000..b876e062426 --- /dev/null +++ b/test/cpp/end2end/xds_end2end_test.cc @@ -0,0 +1,1398 @@ +/* + * + * 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 +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "src/core/ext/filters/client_channel/backup_poller.h" +#include "src/core/ext/filters/client_channel/parse_address.h" +#include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h" +#include "src/core/ext/filters/client_channel/server_address.h" +#include "src/core/lib/gpr/env.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" +#include "src/core/lib/iomgr/sockaddr.h" +#include "src/core/lib/security/credentials/fake/fake_credentials.h" +#include "src/cpp/client/secure_credentials.h" +#include "src/cpp/server/secure_server_credentials.h" + +#include "test/core/util/port.h" +#include "test/core/util/test_config.h" +#include "test/cpp/end2end/test_service_impl.h" + +#include "src/proto/grpc/lb/v1/load_balancer.grpc.pb.h" +#include "src/proto/grpc/testing/echo.grpc.pb.h" + +#include +#include + +// TODO(dgq): Other scenarios in need of testing: +// - Send a serverlist with faulty ip:port addresses (port > 2^16, etc). +// - Test reception of invalid serverlist +// - Test against a non-LB server. +// - Random LB server closing the stream unexpectedly. +// +// Findings from end to end testing to be covered here: +// - Handling of LB servers restart, including reconnection after backing-off +// retries. +// - Destruction of load balanced channel (and therefore of xds instance) +// while: +// 1) the internal LB call is still active. This should work by virtue +// of the weak reference the LB call holds. The call should be terminated as +// part of the xds shutdown process. +// 2) the retry timer is active. Again, the weak reference it holds should +// prevent a premature call to \a glb_destroy. + +using std::chrono::system_clock; + +using grpc::lb::v1::LoadBalanceRequest; +using grpc::lb::v1::LoadBalanceResponse; +using grpc::lb::v1::LoadBalancer; + +namespace grpc { +namespace testing { +namespace { + +template +class CountedService : public ServiceType { + public: + size_t request_count() { + grpc::internal::MutexLock lock(&mu_); + return request_count_; + } + + size_t response_count() { + grpc::internal::MutexLock lock(&mu_); + return response_count_; + } + + void IncreaseResponseCount() { + grpc::internal::MutexLock lock(&mu_); + ++response_count_; + } + void IncreaseRequestCount() { + grpc::internal::MutexLock lock(&mu_); + ++request_count_; + } + + void ResetCounters() { + grpc::internal::MutexLock lock(&mu_); + request_count_ = 0; + response_count_ = 0; + } + + protected: + grpc::internal::Mutex mu_; + + private: + size_t request_count_ = 0; + size_t response_count_ = 0; +}; + +using BackendService = CountedService; +using BalancerService = CountedService; + +const char g_kCallCredsMdKey[] = "Balancer should not ..."; +const char g_kCallCredsMdValue[] = "... receive me"; + +class BackendServiceImpl : public BackendService { + public: + BackendServiceImpl() {} + + Status Echo(ServerContext* context, const EchoRequest* request, + EchoResponse* response) override { + // Backend should receive the call credentials metadata. + auto call_credentials_entry = + context->client_metadata().find(g_kCallCredsMdKey); + EXPECT_NE(call_credentials_entry, context->client_metadata().end()); + if (call_credentials_entry != context->client_metadata().end()) { + EXPECT_EQ(call_credentials_entry->second, g_kCallCredsMdValue); + } + IncreaseRequestCount(); + const auto status = TestServiceImpl::Echo(context, request, response); + IncreaseResponseCount(); + AddClient(context->peer()); + return status; + } + + void Shutdown() {} + + std::set clients() { + grpc::internal::MutexLock lock(&clients_mu_); + return clients_; + } + + private: + void AddClient(const grpc::string& client) { + grpc::internal::MutexLock lock(&clients_mu_); + clients_.insert(client); + } + + grpc::internal::Mutex mu_; + grpc::internal::Mutex clients_mu_; + std::set clients_; +}; + +grpc::string Ip4ToPackedString(const char* ip_str) { + struct in_addr ip4; + GPR_ASSERT(inet_pton(AF_INET, ip_str, &ip4) == 1); + return grpc::string(reinterpret_cast(&ip4), sizeof(ip4)); +} + +struct ClientStats { + size_t num_calls_started = 0; + size_t num_calls_finished = 0; + size_t num_calls_finished_with_client_failed_to_send = 0; + size_t num_calls_finished_known_received = 0; + std::map drop_token_counts; + + ClientStats& operator+=(const ClientStats& other) { + num_calls_started += other.num_calls_started; + num_calls_finished += other.num_calls_finished; + num_calls_finished_with_client_failed_to_send += + other.num_calls_finished_with_client_failed_to_send; + num_calls_finished_known_received += + other.num_calls_finished_known_received; + for (const auto& p : other.drop_token_counts) { + drop_token_counts[p.first] += p.second; + } + return *this; + } + + void Reset() { + num_calls_started = 0; + num_calls_finished = 0; + num_calls_finished_with_client_failed_to_send = 0; + num_calls_finished_known_received = 0; + drop_token_counts.clear(); + } +}; + +class BalancerServiceImpl : public BalancerService { + public: + using Stream = ServerReaderWriter; + using ResponseDelayPair = std::pair; + + explicit BalancerServiceImpl(int client_load_reporting_interval_seconds) + : client_load_reporting_interval_seconds_( + client_load_reporting_interval_seconds) {} + + Status BalanceLoad(ServerContext* context, Stream* stream) override { + // TODO(juanlishen): Clean up the scoping. + gpr_log(GPR_INFO, "LB[%p]: BalanceLoad", this); + { + grpc::internal::MutexLock lock(&mu_); + if (serverlist_done_) goto done; + } + { + // Balancer shouldn't receive the call credentials metadata. + EXPECT_EQ(context->client_metadata().find(g_kCallCredsMdKey), + context->client_metadata().end()); + LoadBalanceRequest request; + std::vector responses_and_delays; + + if (!stream->Read(&request)) { + goto done; + } + IncreaseRequestCount(); + gpr_log(GPR_INFO, "LB[%p]: received initial message '%s'", this, + request.DebugString().c_str()); + + { + LoadBalanceResponse initial_response; + initial_response.mutable_initial_response() + ->mutable_client_stats_report_interval() + ->set_seconds(client_load_reporting_interval_seconds_); + stream->Write(initial_response); + } + + { + grpc::internal::MutexLock lock(&mu_); + responses_and_delays = responses_and_delays_; + } + for (const auto& response_and_delay : responses_and_delays) { + SendResponse(stream, response_and_delay.first, + response_and_delay.second); + } + { + grpc::internal::MutexLock lock(&mu_); + serverlist_cond_.WaitUntil(&mu_, [this] { return serverlist_done_; }); + } + + if (client_load_reporting_interval_seconds_ > 0) { + request.Clear(); + if (stream->Read(&request)) { + gpr_log(GPR_INFO, "LB[%p]: received client load report message '%s'", + this, request.DebugString().c_str()); + GPR_ASSERT(request.has_client_stats()); + // We need to acquire the lock here in order to prevent the notify_one + // below from firing before its corresponding wait is executed. + grpc::internal::MutexLock lock(&mu_); + client_stats_.num_calls_started += + request.client_stats().num_calls_started(); + client_stats_.num_calls_finished += + request.client_stats().num_calls_finished(); + client_stats_.num_calls_finished_with_client_failed_to_send += + request.client_stats() + .num_calls_finished_with_client_failed_to_send(); + client_stats_.num_calls_finished_known_received += + request.client_stats().num_calls_finished_known_received(); + for (const auto& drop_token_count : + request.client_stats().calls_finished_with_drop()) { + client_stats_ + .drop_token_counts[drop_token_count.load_balance_token()] += + drop_token_count.num_calls(); + } + load_report_ready_ = true; + load_report_cond_.Signal(); + } + } + } + done: + gpr_log(GPR_INFO, "LB[%p]: done", this); + return Status::OK; + } + + void add_response(const LoadBalanceResponse& response, int send_after_ms) { + grpc::internal::MutexLock lock(&mu_); + responses_and_delays_.push_back(std::make_pair(response, send_after_ms)); + } + + void Shutdown() { + grpc::internal::MutexLock lock(&mu_); + NotifyDoneWithServerlistsLocked(); + responses_and_delays_.clear(); + client_stats_.Reset(); + gpr_log(GPR_INFO, "LB[%p]: shut down", this); + } + + static LoadBalanceResponse BuildResponseForBackends( + const std::vector& backend_ports, + const std::map& drop_token_counts) { + LoadBalanceResponse response; + for (const auto& drop_token_count : drop_token_counts) { + for (size_t i = 0; i < drop_token_count.second; ++i) { + auto* server = response.mutable_server_list()->add_servers(); + server->set_drop(true); + server->set_load_balance_token(drop_token_count.first); + } + } + for (const int& backend_port : backend_ports) { + auto* server = response.mutable_server_list()->add_servers(); + server->set_ip_address(Ip4ToPackedString("127.0.0.1")); + server->set_port(backend_port); + static int token_count = 0; + char* token; + gpr_asprintf(&token, "token%03d", ++token_count); + server->set_load_balance_token(token); + gpr_free(token); + } + return response; + } + + const ClientStats& WaitForLoadReport() { + grpc::internal::MutexLock lock(&mu_); + load_report_cond_.WaitUntil(&mu_, [this] { return load_report_ready_; }); + load_report_ready_ = false; + return client_stats_; + } + + void NotifyDoneWithServerlists() { + grpc::internal::MutexLock lock(&mu_); + NotifyDoneWithServerlistsLocked(); + } + + void NotifyDoneWithServerlistsLocked() { + if (!serverlist_done_) { + serverlist_done_ = true; + serverlist_cond_.Broadcast(); + } + } + + private: + void SendResponse(Stream* stream, const LoadBalanceResponse& response, + int delay_ms) { + gpr_log(GPR_INFO, "LB[%p]: sleeping for %d ms...", this, delay_ms); + if (delay_ms > 0) { + gpr_sleep_until(grpc_timeout_milliseconds_to_deadline(delay_ms)); + } + gpr_log(GPR_INFO, "LB[%p]: Woke up! Sending response '%s'", this, + response.DebugString().c_str()); + IncreaseResponseCount(); + stream->Write(response); + } + + const int client_load_reporting_interval_seconds_; + std::vector responses_and_delays_; + grpc::internal::Mutex mu_; + grpc::internal::CondVar load_report_cond_; + bool load_report_ready_ = false; + grpc::internal::CondVar serverlist_cond_; + bool serverlist_done_ = false; + ClientStats client_stats_; +}; + +class XdsEnd2endTest : public ::testing::Test { + protected: + XdsEnd2endTest(size_t num_backends, size_t num_balancers, + int client_load_reporting_interval_seconds) + : server_host_("localhost"), + num_backends_(num_backends), + num_balancers_(num_balancers), + client_load_reporting_interval_seconds_( + client_load_reporting_interval_seconds) { + // Make the backup poller poll very frequently in order to pick up + // updates from all the subchannels's FDs. + GPR_GLOBAL_CONFIG_SET(grpc_client_channel_backup_poll_interval_ms, 1); + } + + void SetUp() override { + response_generator_ = + grpc_core::MakeRefCounted(); + lb_channel_response_generator_ = + grpc_core::MakeRefCounted(); + // Start the backends. + for (size_t i = 0; i < num_backends_; ++i) { + backends_.emplace_back(new ServerThread("backend")); + backends_.back()->Start(server_host_); + } + // Start the load balancers. + for (size_t i = 0; i < num_balancers_; ++i) { + balancers_.emplace_back(new ServerThread( + "balancer", client_load_reporting_interval_seconds_)); + balancers_.back()->Start(server_host_); + } + ResetStub(); + } + + void TearDown() override { + ShutdownAllBackends(); + for (auto& balancer : balancers_) balancer->Shutdown(); + } + + void StartAllBackends() { + for (auto& backend : backends_) backend->Start(server_host_); + } + + void StartBackend(size_t index) { backends_[index]->Start(server_host_); } + + void ShutdownAllBackends() { + for (auto& backend : backends_) backend->Shutdown(); + } + + void ShutdownBackend(size_t index) { backends_[index]->Shutdown(); } + + void ResetStub(int fallback_timeout = 0, + const grpc::string& expected_targets = "") { + ChannelArguments args; + // TODO(juanlishen): Add setter to ChannelArguments. + if (fallback_timeout > 0) { + args.SetInt(GRPC_ARG_XDS_FALLBACK_TIMEOUT_MS, fallback_timeout); + } + args.SetPointer(GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR, + response_generator_.get()); + if (!expected_targets.empty()) { + args.SetString(GRPC_ARG_FAKE_SECURITY_EXPECTED_TARGETS, expected_targets); + } + std::ostringstream uri; + uri << "fake:///" << kApplicationTargetName_; + // TODO(dgq): templatize tests to run everything using both secure and + // insecure channel credentials. + grpc_channel_credentials* channel_creds = + grpc_fake_transport_security_credentials_create(); + grpc_call_credentials* call_creds = grpc_md_only_test_credentials_create( + g_kCallCredsMdKey, g_kCallCredsMdValue, false); + std::shared_ptr creds( + new SecureChannelCredentials(grpc_composite_channel_credentials_create( + channel_creds, call_creds, nullptr))); + call_creds->Unref(); + channel_creds->Unref(); + channel_ = ::grpc::CreateCustomChannel(uri.str(), creds, args); + stub_ = grpc::testing::EchoTestService::NewStub(channel_); + } + + void ResetBackendCounters() { + for (auto& backend : backends_) backend->service_.ResetCounters(); + } + + ClientStats WaitForLoadReports() { + ClientStats client_stats; + for (auto& balancer : balancers_) { + client_stats += balancer->service_.WaitForLoadReport(); + } + return client_stats; + } + + bool SeenAllBackends(size_t start_index = 0, size_t stop_index = 0) { + if (stop_index == 0) stop_index = backends_.size(); + for (size_t i = start_index; i < stop_index; ++i) { + if (backends_[i]->service_.request_count() == 0) return false; + } + return true; + } + + void SendRpcAndCount(int* num_total, int* num_ok, int* num_failure, + int* num_drops) { + const Status status = SendRpc(); + if (status.ok()) { + ++*num_ok; + } else { + if (status.error_message() == "Call dropped by load balancing policy") { + ++*num_drops; + } else { + ++*num_failure; + } + } + ++*num_total; + } + + std::tuple WaitForAllBackends(int num_requests_multiple_of = 1, + size_t start_index = 0, + size_t stop_index = 0) { + int num_ok = 0; + int num_failure = 0; + int num_drops = 0; + int num_total = 0; + while (!SeenAllBackends(start_index, stop_index)) { + SendRpcAndCount(&num_total, &num_ok, &num_failure, &num_drops); + } + while (num_total % num_requests_multiple_of != 0) { + SendRpcAndCount(&num_total, &num_ok, &num_failure, &num_drops); + } + ResetBackendCounters(); + gpr_log(GPR_INFO, + "Performed %d warm up requests (a multiple of %d) against the " + "backends. %d succeeded, %d failed, %d dropped.", + num_total, num_requests_multiple_of, num_ok, num_failure, + num_drops); + return std::make_tuple(num_ok, num_failure, num_drops); + } + + void WaitForBackend(size_t backend_idx) { + do { + (void)SendRpc(); + } while (backends_[backend_idx]->service_.request_count() == 0); + ResetBackendCounters(); + } + + grpc_core::ServerAddressList CreateLbAddressesFromPortList( + const std::vector& ports) { + grpc_core::ServerAddressList addresses; + for (int port : ports) { + char* lb_uri_str; + gpr_asprintf(&lb_uri_str, "ipv4:127.0.0.1:%d", port); + grpc_uri* lb_uri = grpc_uri_parse(lb_uri_str, true); + GPR_ASSERT(lb_uri != nullptr); + grpc_resolved_address address; + GPR_ASSERT(grpc_parse_uri(lb_uri, &address)); + std::vector args_to_add; + grpc_channel_args* args = grpc_channel_args_copy_and_add( + nullptr, args_to_add.data(), args_to_add.size()); + addresses.emplace_back(address.addr, address.len, args); + grpc_uri_destroy(lb_uri); + gpr_free(lb_uri_str); + } + return addresses; + } + + void SetNextResolution(const std::vector& ports, + const char* service_config_json = nullptr, + grpc_core::FakeResolverResponseGenerator* + lb_channel_response_generator = nullptr) { + grpc_core::ExecCtx exec_ctx; + grpc_core::Resolver::Result result; + result.addresses = CreateLbAddressesFromPortList(ports); + if (service_config_json != nullptr) { + grpc_error* error = GRPC_ERROR_NONE; + result.service_config = + grpc_core::ServiceConfig::Create(service_config_json, &error); + GRPC_ERROR_UNREF(error); + } + grpc_arg arg = grpc_core::FakeResolverResponseGenerator::MakeChannelArg( + lb_channel_response_generator == nullptr + ? lb_channel_response_generator_.get() + : lb_channel_response_generator); + result.args = grpc_channel_args_copy_and_add(nullptr, &arg, 1); + response_generator_->SetResponse(std::move(result)); + } + + void SetNextResolutionForLbChannelAllBalancers( + const char* service_config_json = nullptr, + grpc_core::FakeResolverResponseGenerator* lb_channel_response_generator = + nullptr) { + std::vector ports; + for (size_t i = 0; i < balancers_.size(); ++i) { + ports.emplace_back(balancers_[i]->port_); + } + SetNextResolutionForLbChannel(ports, service_config_json, + lb_channel_response_generator); + } + + void SetNextResolutionForLbChannel( + const std::vector& ports, const char* service_config_json = nullptr, + grpc_core::FakeResolverResponseGenerator* lb_channel_response_generator = + nullptr) { + grpc_core::ExecCtx exec_ctx; + grpc_core::Resolver::Result result; + result.addresses = CreateLbAddressesFromPortList(ports); + if (service_config_json != nullptr) { + grpc_error* error = GRPC_ERROR_NONE; + result.service_config = + grpc_core::ServiceConfig::Create(service_config_json, &error); + GRPC_ERROR_UNREF(error); + } + if (lb_channel_response_generator == nullptr) { + lb_channel_response_generator = lb_channel_response_generator_.get(); + } + lb_channel_response_generator->SetResponse(std::move(result)); + } + + void SetNextReresolutionResponse(const std::vector& ports) { + grpc_core::ExecCtx exec_ctx; + grpc_core::Resolver::Result result; + result.addresses = CreateLbAddressesFromPortList(ports); + response_generator_->SetReresolutionResponse(std::move(result)); + } + + const std::vector GetBackendPorts(size_t start_index = 0, + size_t stop_index = 0) const { + if (stop_index == 0) stop_index = backends_.size(); + std::vector backend_ports; + for (size_t i = start_index; i < stop_index; ++i) { + backend_ports.push_back(backends_[i]->port_); + } + return backend_ports; + } + + void ScheduleResponseForBalancer(size_t i, + const LoadBalanceResponse& response, + int delay_ms) { + balancers_[i]->service_.add_response(response, delay_ms); + } + + Status SendRpc(EchoResponse* response = nullptr, int timeout_ms = 1000, + bool wait_for_ready = false) { + const bool local_response = (response == nullptr); + if (local_response) response = new EchoResponse; + EchoRequest request; + request.set_message(kRequestMessage_); + ClientContext context; + context.set_deadline(grpc_timeout_milliseconds_to_deadline(timeout_ms)); + if (wait_for_ready) context.set_wait_for_ready(true); + Status status = stub_->Echo(&context, request, response); + if (local_response) delete response; + return status; + } + + void CheckRpcSendOk(const size_t times = 1, const int timeout_ms = 1000, + bool wait_for_ready = false) { + for (size_t i = 0; i < times; ++i) { + EchoResponse response; + const Status status = SendRpc(&response, timeout_ms, wait_for_ready); + EXPECT_TRUE(status.ok()) << "code=" << status.error_code() + << " message=" << status.error_message(); + EXPECT_EQ(response.message(), kRequestMessage_); + } + } + + void CheckRpcSendFailure() { + const Status status = SendRpc(); + EXPECT_FALSE(status.ok()); + } + + template + struct ServerThread { + template + explicit ServerThread(const grpc::string& type, Args&&... args) + : port_(grpc_pick_unused_port_or_die()), + type_(type), + service_(std::forward(args)...) {} + + void Start(const grpc::string& server_host) { + gpr_log(GPR_INFO, "starting %s server on port %d", type_.c_str(), port_); + GPR_ASSERT(!running_); + running_ = true; + grpc::internal::Mutex mu; + // We need to acquire the lock here in order to prevent the notify_one + // by ServerThread::Serve from firing before the wait below is hit. + grpc::internal::MutexLock lock(&mu); + grpc::internal::CondVar cond; + thread_.reset(new std::thread( + std::bind(&ServerThread::Serve, this, server_host, &mu, &cond))); + cond.Wait(&mu); + gpr_log(GPR_INFO, "%s server startup complete", type_.c_str()); + } + + void Serve(const grpc::string& server_host, grpc::internal::Mutex* mu, + grpc::internal::CondVar* cond) { + // We need to acquire the lock here in order to prevent the notify_one + // below from firing before its corresponding wait is executed. + grpc::internal::MutexLock lock(mu); + std::ostringstream server_address; + server_address << server_host << ":" << port_; + ServerBuilder builder; + std::shared_ptr creds(new SecureServerCredentials( + grpc_fake_transport_security_server_credentials_create())); + builder.AddListeningPort(server_address.str(), creds); + builder.RegisterService(&service_); + server_ = builder.BuildAndStart(); + cond->Signal(); + } + + void Shutdown() { + if (!running_) return; + gpr_log(GPR_INFO, "%s about to shutdown", type_.c_str()); + service_.Shutdown(); + server_->Shutdown(grpc_timeout_milliseconds_to_deadline(0)); + thread_->join(); + gpr_log(GPR_INFO, "%s shutdown completed", type_.c_str()); + running_ = false; + } + + const int port_; + grpc::string type_; + T service_; + std::unique_ptr server_; + std::unique_ptr thread_; + bool running_ = false; + }; + + const grpc::string server_host_; + const size_t num_backends_; + const size_t num_balancers_; + const int client_load_reporting_interval_seconds_; + std::shared_ptr channel_; + std::unique_ptr stub_; + std::vector>> backends_; + std::vector>> balancers_; + grpc_core::RefCountedPtr + response_generator_; + grpc_core::RefCountedPtr + lb_channel_response_generator_; + const grpc::string kRequestMessage_ = "Live long and prosper."; + const grpc::string kApplicationTargetName_ = "application_target_name"; + const grpc::string kDefaultServiceConfig_ = + "{\n" + " \"loadBalancingConfig\":[\n" + " { \"does_not_exist\":{} },\n" + " { \"xds_experimental\":{ \"balancerName\": \"fake:///lb\" } }\n" + " ]\n" + "}"; +}; + +class SingleBalancerTest : public XdsEnd2endTest { + public: + SingleBalancerTest() : XdsEnd2endTest(4, 1, 0) {} +}; + +TEST_F(SingleBalancerTest, Vanilla) { + SetNextResolution({}, kDefaultServiceConfig_.c_str()); + SetNextResolutionForLbChannelAllBalancers(); + const size_t kNumRpcsPerAddress = 100; + ScheduleResponseForBalancer( + 0, BalancerServiceImpl::BuildResponseForBackends(GetBackendPorts(), {}), + 0); + // Make sure that trying to connect works without a call. + channel_->GetState(true /* try_to_connect */); + // We need to wait for all backends to come online. + WaitForAllBackends(); + // Send kNumRpcsPerAddress RPCs per server. + CheckRpcSendOk(kNumRpcsPerAddress * num_backends_); + // Each backend should have gotten 100 requests. + for (size_t i = 0; i < backends_.size(); ++i) { + EXPECT_EQ(kNumRpcsPerAddress, backends_[i]->service_.request_count()); + } + balancers_[0]->service_.NotifyDoneWithServerlists(); + // The balancer got a single request. + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); + // and sent a single response. + EXPECT_EQ(1U, balancers_[0]->service_.response_count()); + + // Check LB policy name for the channel. + EXPECT_EQ("xds_experimental", channel_->GetLoadBalancingPolicyName()); +} + +TEST_F(SingleBalancerTest, SameBackendListedMultipleTimes) { + SetNextResolution({}, kDefaultServiceConfig_.c_str()); + SetNextResolutionForLbChannelAllBalancers(); + // Same backend listed twice. + std::vector ports; + ports.push_back(backends_[0]->port_); + ports.push_back(backends_[0]->port_); + const size_t kNumRpcsPerAddress = 10; + ScheduleResponseForBalancer( + 0, BalancerServiceImpl::BuildResponseForBackends(ports, {}), 0); + // We need to wait for the backend to come online. + WaitForBackend(0); + // Send kNumRpcsPerAddress RPCs per server. + CheckRpcSendOk(kNumRpcsPerAddress * ports.size()); + // Backend should have gotten 20 requests. + EXPECT_EQ(kNumRpcsPerAddress * 2, backends_[0]->service_.request_count()); + // And they should have come from a single client port, because of + // subchannel sharing. + EXPECT_EQ(1UL, backends_[0]->service_.clients().size()); + balancers_[0]->service_.NotifyDoneWithServerlists(); +} + +TEST_F(SingleBalancerTest, SecureNaming) { + // TODO(juanlishen): Use separate fake creds for the balancer channel. + ResetStub(0, kApplicationTargetName_ + ";lb"); + SetNextResolution({}, kDefaultServiceConfig_.c_str()); + SetNextResolutionForLbChannel({balancers_[0]->port_}); + const size_t kNumRpcsPerAddress = 100; + ScheduleResponseForBalancer( + 0, BalancerServiceImpl::BuildResponseForBackends(GetBackendPorts(), {}), + 0); + // Make sure that trying to connect works without a call. + channel_->GetState(true /* try_to_connect */); + // We need to wait for all backends to come online. + WaitForAllBackends(); + // Send kNumRpcsPerAddress RPCs per server. + CheckRpcSendOk(kNumRpcsPerAddress * num_backends_); + + // Each backend should have gotten 100 requests. + for (size_t i = 0; i < backends_.size(); ++i) { + EXPECT_EQ(kNumRpcsPerAddress, backends_[i]->service_.request_count()); + } + // The balancer got a single request. + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); + // and sent a single response. + EXPECT_EQ(1U, balancers_[0]->service_.response_count()); +} + +TEST_F(SingleBalancerTest, SecureNamingDeathTest) { + ::testing::FLAGS_gtest_death_test_style = "threadsafe"; + // Make sure that we blow up (via abort() from the security connector) when + // the name from the balancer doesn't match expectations. + ASSERT_DEATH( + { + ResetStub(0, kApplicationTargetName_ + ";lb"); + SetNextResolution({}, + "{\n" + " \"loadBalancingConfig\":[\n" + " { \"does_not_exist\":{} },\n" + " { \"xds_experimental\":{ \"balancerName\": " + "\"fake:///wrong_lb\" } }\n" + " ]\n" + "}"); + SetNextResolutionForLbChannel({balancers_[0]->port_}); + channel_->WaitForConnected(grpc_timeout_seconds_to_deadline(1)); + }, + ""); +} + +TEST_F(SingleBalancerTest, InitiallyEmptyServerlist) { + SetNextResolution({}, kDefaultServiceConfig_.c_str()); + SetNextResolutionForLbChannelAllBalancers(); + const int kServerlistDelayMs = 500 * grpc_test_slowdown_factor(); + const int kCallDeadlineMs = kServerlistDelayMs * 2; + // First response is an empty serverlist, sent right away. + ScheduleResponseForBalancer(0, LoadBalanceResponse(), 0); + // Send non-empty serverlist only after kServerlistDelayMs + ScheduleResponseForBalancer( + 0, BalancerServiceImpl::BuildResponseForBackends(GetBackendPorts(), {}), + kServerlistDelayMs); + const auto t0 = system_clock::now(); + // Client will block: LB will initially send empty serverlist. + CheckRpcSendOk(1, kCallDeadlineMs, true /* wait_for_ready */); + const auto ellapsed_ms = + std::chrono::duration_cast( + system_clock::now() - t0); + // but eventually, the LB sends a serverlist update that allows the call to + // proceed. The call delay must be larger than the delay in sending the + // populated serverlist but under the call's deadline (which is enforced by + // the call's deadline). + EXPECT_GT(ellapsed_ms.count(), kServerlistDelayMs); + balancers_[0]->service_.NotifyDoneWithServerlists(); + // The balancer got a single request. + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); + // and sent two responses. + EXPECT_EQ(2U, balancers_[0]->service_.response_count()); +} + +TEST_F(SingleBalancerTest, AllServersUnreachableFailFast) { + SetNextResolution({}, kDefaultServiceConfig_.c_str()); + SetNextResolutionForLbChannelAllBalancers(); + const size_t kNumUnreachableServers = 5; + std::vector ports; + for (size_t i = 0; i < kNumUnreachableServers; ++i) { + ports.push_back(grpc_pick_unused_port_or_die()); + } + ScheduleResponseForBalancer( + 0, BalancerServiceImpl::BuildResponseForBackends(ports, {}), 0); + const Status status = SendRpc(); + // The error shouldn't be DEADLINE_EXCEEDED. + EXPECT_EQ(StatusCode::UNAVAILABLE, status.error_code()); + balancers_[0]->service_.NotifyDoneWithServerlists(); + // The balancer got a single request. + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); + // and sent a single response. + EXPECT_EQ(1U, balancers_[0]->service_.response_count()); +} + +TEST_F(SingleBalancerTest, Fallback) { + const int kFallbackTimeoutMs = 200 * grpc_test_slowdown_factor(); + const int kServerlistDelayMs = 500 * grpc_test_slowdown_factor(); + const size_t kNumBackendsInResolution = backends_.size() / 2; + ResetStub(kFallbackTimeoutMs); + SetNextResolution(GetBackendPorts(0, kNumBackendsInResolution), + kDefaultServiceConfig_.c_str()); + SetNextResolutionForLbChannelAllBalancers(); + // Send non-empty serverlist only after kServerlistDelayMs. + ScheduleResponseForBalancer( + 0, + BalancerServiceImpl::BuildResponseForBackends( + GetBackendPorts(kNumBackendsInResolution /* start_index */), {}), + kServerlistDelayMs); + // Wait until all the fallback backends are reachable. + WaitForAllBackends(1 /* num_requests_multiple_of */, 0 /* start_index */, + kNumBackendsInResolution /* stop_index */); + gpr_log(GPR_INFO, "========= BEFORE FIRST BATCH =========="); + CheckRpcSendOk(kNumBackendsInResolution); + gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH =========="); + // Fallback is used: each backend returned by the resolver should have + // gotten one request. + for (size_t i = 0; i < kNumBackendsInResolution; ++i) { + EXPECT_EQ(1U, backends_[i]->service_.request_count()); + } + for (size_t i = kNumBackendsInResolution; i < backends_.size(); ++i) { + EXPECT_EQ(0U, backends_[i]->service_.request_count()); + } + // Wait until the serverlist reception has been processed and all backends + // in the serverlist are reachable. + WaitForAllBackends(1 /* num_requests_multiple_of */, + kNumBackendsInResolution /* start_index */); + gpr_log(GPR_INFO, "========= BEFORE SECOND BATCH =========="); + CheckRpcSendOk(backends_.size() - kNumBackendsInResolution); + gpr_log(GPR_INFO, "========= DONE WITH SECOND BATCH =========="); + // Serverlist is used: each backend returned by the balancer should + // have gotten one request. + for (size_t i = 0; i < kNumBackendsInResolution; ++i) { + EXPECT_EQ(0U, backends_[i]->service_.request_count()); + } + for (size_t i = kNumBackendsInResolution; i < backends_.size(); ++i) { + EXPECT_EQ(1U, backends_[i]->service_.request_count()); + } + // The balancer got a single request. + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); + // and sent a single response. + EXPECT_EQ(1U, balancers_[0]->service_.response_count()); +} + +TEST_F(SingleBalancerTest, FallbackUpdate) { + const int kFallbackTimeoutMs = 200 * grpc_test_slowdown_factor(); + const int kServerlistDelayMs = 500 * grpc_test_slowdown_factor(); + const size_t kNumBackendsInResolution = backends_.size() / 3; + const size_t kNumBackendsInResolutionUpdate = backends_.size() / 3; + ResetStub(kFallbackTimeoutMs); + SetNextResolution(GetBackendPorts(0, kNumBackendsInResolution), + kDefaultServiceConfig_.c_str()); + SetNextResolutionForLbChannelAllBalancers(); + // Send non-empty serverlist only after kServerlistDelayMs. + ScheduleResponseForBalancer( + 0, + BalancerServiceImpl::BuildResponseForBackends( + GetBackendPorts(kNumBackendsInResolution + + kNumBackendsInResolutionUpdate /* start_index */), + {}), + kServerlistDelayMs); + // Wait until all the fallback backends are reachable. + WaitForAllBackends(1 /* num_requests_multiple_of */, 0 /* start_index */, + kNumBackendsInResolution /* stop_index */); + gpr_log(GPR_INFO, "========= BEFORE FIRST BATCH =========="); + CheckRpcSendOk(kNumBackendsInResolution); + gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH =========="); + // Fallback is used: each backend returned by the resolver should have + // gotten one request. + for (size_t i = 0; i < kNumBackendsInResolution; ++i) { + EXPECT_EQ(1U, backends_[i]->service_.request_count()); + } + for (size_t i = kNumBackendsInResolution; i < backends_.size(); ++i) { + EXPECT_EQ(0U, backends_[i]->service_.request_count()); + } + SetNextResolution(GetBackendPorts(kNumBackendsInResolution, + kNumBackendsInResolution + + kNumBackendsInResolutionUpdate), + kDefaultServiceConfig_.c_str()); + // Wait until the resolution update has been processed and all the new + // fallback backends are reachable. + WaitForAllBackends(1 /* num_requests_multiple_of */, + kNumBackendsInResolution /* start_index */, + kNumBackendsInResolution + + kNumBackendsInResolutionUpdate /* stop_index */); + gpr_log(GPR_INFO, "========= BEFORE SECOND BATCH =========="); + CheckRpcSendOk(kNumBackendsInResolutionUpdate); + gpr_log(GPR_INFO, "========= DONE WITH SECOND BATCH =========="); + // The resolution update is used: each backend in the resolution update should + // have gotten one request. + for (size_t i = 0; i < kNumBackendsInResolution; ++i) { + EXPECT_EQ(0U, backends_[i]->service_.request_count()); + } + for (size_t i = kNumBackendsInResolution; + i < kNumBackendsInResolution + kNumBackendsInResolutionUpdate; ++i) { + EXPECT_EQ(1U, backends_[i]->service_.request_count()); + } + for (size_t i = kNumBackendsInResolution + kNumBackendsInResolutionUpdate; + i < backends_.size(); ++i) { + EXPECT_EQ(0U, backends_[i]->service_.request_count()); + } + // Wait until the serverlist reception has been processed and all backends + // in the serverlist are reachable. + WaitForAllBackends(1 /* num_requests_multiple_of */, + kNumBackendsInResolution + + kNumBackendsInResolutionUpdate /* start_index */); + gpr_log(GPR_INFO, "========= BEFORE THIRD BATCH =========="); + CheckRpcSendOk(backends_.size() - kNumBackendsInResolution - + kNumBackendsInResolutionUpdate); + gpr_log(GPR_INFO, "========= DONE WITH THIRD BATCH =========="); + // Serverlist is used: each backend returned by the balancer should + // have gotten one request. + for (size_t i = 0; + i < kNumBackendsInResolution + kNumBackendsInResolutionUpdate; ++i) { + EXPECT_EQ(0U, backends_[i]->service_.request_count()); + } + for (size_t i = kNumBackendsInResolution + kNumBackendsInResolutionUpdate; + i < backends_.size(); ++i) { + EXPECT_EQ(1U, backends_[i]->service_.request_count()); + } + // The balancer got a single request. + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); + // and sent a single response. + EXPECT_EQ(1U, balancers_[0]->service_.response_count()); +} + +TEST_F(SingleBalancerTest, FallbackEarlyWhenBalancerChannelFails) { + const int kFallbackTimeoutMs = 10000 * grpc_test_slowdown_factor(); + ResetStub(kFallbackTimeoutMs); + // Return an unreachable balancer and one fallback backend. + SetNextResolution({backends_[0]->port_}, kDefaultServiceConfig_.c_str()); + SetNextResolutionForLbChannel({grpc_pick_unused_port_or_die()}); + // Send RPC with deadline less than the fallback timeout and make sure it + // succeeds. + CheckRpcSendOk(/* times */ 1, /* timeout_ms */ 1000, + /* wait_for_ready */ false); +} + +TEST_F(SingleBalancerTest, FallbackEarlyWhenBalancerCallFails) { + const int kFallbackTimeoutMs = 10000 * grpc_test_slowdown_factor(); + ResetStub(kFallbackTimeoutMs); + // Return one balancer and one fallback backend. + SetNextResolution({backends_[0]->port_}, kDefaultServiceConfig_.c_str()); + SetNextResolutionForLbChannelAllBalancers(); + // Balancer drops call without sending a serverlist. + balancers_[0]->service_.NotifyDoneWithServerlists(); + // Send RPC with deadline less than the fallback timeout and make sure it + // succeeds. + CheckRpcSendOk(/* times */ 1, /* timeout_ms */ 1000, + /* wait_for_ready */ false); +} + +TEST_F(SingleBalancerTest, FallbackModeIsExitedWhenBalancerSaysToDropAllCalls) { + // Return an unreachable balancer and one fallback backend. + SetNextResolution({backends_[0]->port_}, kDefaultServiceConfig_.c_str()); + SetNextResolutionForLbChannel({grpc_pick_unused_port_or_die()}); + // Enter fallback mode because the LB channel fails to connect. + WaitForBackend(0); + // Return a new balancer that sends an empty serverlist. + ScheduleResponseForBalancer( + 0, BalancerServiceImpl::BuildResponseForBackends({}, {}), 0); + SetNextResolutionForLbChannelAllBalancers(); + // Send RPCs until failure. + gpr_timespec deadline = gpr_time_add( + gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_millis(5000, GPR_TIMESPAN)); + do { + auto status = SendRpc(); + if (!status.ok()) break; + } while (gpr_time_cmp(gpr_now(GPR_CLOCK_REALTIME), deadline) < 0); + CheckRpcSendFailure(); +} + +TEST_F(SingleBalancerTest, FallbackModeIsExitedAfterChildRready) { + // Return an unreachable balancer and one fallback backend. + SetNextResolution({backends_[0]->port_}, kDefaultServiceConfig_.c_str()); + SetNextResolutionForLbChannel({grpc_pick_unused_port_or_die()}); + // Enter fallback mode because the LB channel fails to connect. + WaitForBackend(0); + // Return a new balancer that sends a dead backend. + ShutdownBackend(1); + ScheduleResponseForBalancer( + 0, + BalancerServiceImpl::BuildResponseForBackends({backends_[1]->port_}, {}), + 0); + SetNextResolutionForLbChannelAllBalancers(); + // The state (TRANSIENT_FAILURE) update from the child policy will be ignored + // because we are still in fallback mode. + gpr_timespec deadline = gpr_time_add( + gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_millis(5000, GPR_TIMESPAN)); + // Send 5 seconds worth of RPCs. + do { + CheckRpcSendOk(); + } while (gpr_time_cmp(gpr_now(GPR_CLOCK_REALTIME), deadline) < 0); + // After the backend is restarted, the child policy will eventually be READY, + // and we will exit fallback mode. + StartBackend(1); + WaitForBackend(1); + // We have exited fallback mode, so calls will go to the child policy + // exclusively. + CheckRpcSendOk(100); + EXPECT_EQ(0U, backends_[0]->service_.request_count()); + EXPECT_EQ(100U, backends_[1]->service_.request_count()); +} + +TEST_F(SingleBalancerTest, BackendsRestart) { + SetNextResolution({}, kDefaultServiceConfig_.c_str()); + SetNextResolutionForLbChannelAllBalancers(); + ScheduleResponseForBalancer( + 0, BalancerServiceImpl::BuildResponseForBackends(GetBackendPorts(), {}), + 0); + WaitForAllBackends(); + // Stop backends. RPCs should fail. + ShutdownAllBackends(); + CheckRpcSendFailure(); + // Restart all backends. RPCs should start succeeding again. + StartAllBackends(); + CheckRpcSendOk(1 /* times */, 2000 /* timeout_ms */, + true /* wait_for_ready */); +} + +class UpdatesTest : public XdsEnd2endTest { + public: + UpdatesTest() : XdsEnd2endTest(4, 3, 0) {} +}; + +TEST_F(UpdatesTest, UpdateBalancersButKeepUsingOriginalBalancer) { + SetNextResolution({}, kDefaultServiceConfig_.c_str()); + SetNextResolutionForLbChannelAllBalancers(); + const std::vector first_backend{GetBackendPorts()[0]}; + const std::vector second_backend{GetBackendPorts()[1]}; + ScheduleResponseForBalancer( + 0, BalancerServiceImpl::BuildResponseForBackends(first_backend, {}), 0); + ScheduleResponseForBalancer( + 1, BalancerServiceImpl::BuildResponseForBackends(second_backend, {}), 0); + + // Wait until the first backend is ready. + WaitForBackend(0); + + // Send 10 requests. + gpr_log(GPR_INFO, "========= BEFORE FIRST BATCH =========="); + CheckRpcSendOk(10); + gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH =========="); + + // All 10 requests should have gone to the first backend. + EXPECT_EQ(10U, backends_[0]->service_.request_count()); + + // Balancer 0 got a single request. + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); + // and sent a single response. + EXPECT_EQ(1U, balancers_[0]->service_.response_count()); + EXPECT_EQ(0U, balancers_[1]->service_.request_count()); + EXPECT_EQ(0U, balancers_[1]->service_.response_count()); + EXPECT_EQ(0U, balancers_[2]->service_.request_count()); + EXPECT_EQ(0U, balancers_[2]->service_.response_count()); + + gpr_log(GPR_INFO, "========= ABOUT TO UPDATE 1 =========="); + SetNextResolutionForLbChannel({balancers_[1]->port_}); + gpr_log(GPR_INFO, "========= UPDATE 1 DONE =========="); + + EXPECT_EQ(0U, backends_[1]->service_.request_count()); + gpr_timespec deadline = gpr_time_add( + gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_millis(10000, GPR_TIMESPAN)); + // Send 10 seconds worth of RPCs + do { + CheckRpcSendOk(); + } while (gpr_time_cmp(gpr_now(GPR_CLOCK_REALTIME), deadline) < 0); + // The current LB call is still working, so xds continued using it to the + // first balancer, which doesn't assign the second backend. + EXPECT_EQ(0U, backends_[1]->service_.request_count()); + + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); + EXPECT_EQ(1U, balancers_[0]->service_.response_count()); + EXPECT_EQ(0U, balancers_[1]->service_.request_count()); + EXPECT_EQ(0U, balancers_[1]->service_.response_count()); + EXPECT_EQ(0U, balancers_[2]->service_.request_count()); + EXPECT_EQ(0U, balancers_[2]->service_.response_count()); +} + +TEST_F(UpdatesTest, UpdateBalancerName) { + SetNextResolution({}, kDefaultServiceConfig_.c_str()); + SetNextResolutionForLbChannelAllBalancers(); + const std::vector first_backend{GetBackendPorts()[0]}; + const std::vector second_backend{GetBackendPorts()[1]}; + ScheduleResponseForBalancer( + 0, BalancerServiceImpl::BuildResponseForBackends(first_backend, {}), 0); + ScheduleResponseForBalancer( + 1, BalancerServiceImpl::BuildResponseForBackends(second_backend, {}), 0); + + // Wait until the first backend is ready. + WaitForBackend(0); + + // Send 10 requests. + gpr_log(GPR_INFO, "========= BEFORE FIRST BATCH =========="); + CheckRpcSendOk(10); + gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH =========="); + + // All 10 requests should have gone to the first backend. + EXPECT_EQ(10U, backends_[0]->service_.request_count()); + + // Balancer 0 got a single request. + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); + // and sent a single response. + EXPECT_EQ(1U, balancers_[0]->service_.response_count()); + EXPECT_EQ(0U, balancers_[1]->service_.request_count()); + EXPECT_EQ(0U, balancers_[1]->service_.response_count()); + EXPECT_EQ(0U, balancers_[2]->service_.request_count()); + EXPECT_EQ(0U, balancers_[2]->service_.response_count()); + + std::vector ports; + ports.emplace_back(balancers_[1]->port_); + auto new_lb_channel_response_generator = + grpc_core::MakeRefCounted(); + SetNextResolutionForLbChannel(ports, nullptr, + new_lb_channel_response_generator.get()); + gpr_log(GPR_INFO, "========= ABOUT TO UPDATE BALANCER NAME =========="); + SetNextResolution({}, + "{\n" + " \"loadBalancingConfig\":[\n" + " { \"does_not_exist\":{} },\n" + " { \"xds_experimental\":{ \"balancerName\": " + "\"fake:///updated_lb\" } }\n" + " ]\n" + "}", + new_lb_channel_response_generator.get()); + gpr_log(GPR_INFO, "========= UPDATED BALANCER NAME =========="); + + // Wait until update has been processed, as signaled by the second backend + // receiving a request. + EXPECT_EQ(0U, backends_[1]->service_.request_count()); + WaitForBackend(1); + + backends_[1]->service_.ResetCounters(); + gpr_log(GPR_INFO, "========= BEFORE SECOND BATCH =========="); + CheckRpcSendOk(10); + gpr_log(GPR_INFO, "========= DONE WITH SECOND BATCH =========="); + // All 10 requests should have gone to the second backend. + EXPECT_EQ(10U, backends_[1]->service_.request_count()); + + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); + EXPECT_EQ(1U, balancers_[0]->service_.response_count()); + EXPECT_EQ(1U, balancers_[1]->service_.request_count()); + EXPECT_EQ(1U, balancers_[1]->service_.response_count()); + EXPECT_EQ(0U, balancers_[2]->service_.request_count()); + EXPECT_EQ(0U, balancers_[2]->service_.response_count()); +} + +// Send an update with the same set of LBs as the one in SetUp() in order to +// verify that the LB channel inside xds keeps the initial connection (which +// by definition is also present in the update). +TEST_F(UpdatesTest, UpdateBalancersRepeated) { + SetNextResolution({}, kDefaultServiceConfig_.c_str()); + SetNextResolutionForLbChannelAllBalancers(); + const std::vector first_backend{GetBackendPorts()[0]}; + const std::vector second_backend{GetBackendPorts()[0]}; + + ScheduleResponseForBalancer( + 0, BalancerServiceImpl::BuildResponseForBackends(first_backend, {}), 0); + ScheduleResponseForBalancer( + 1, BalancerServiceImpl::BuildResponseForBackends(second_backend, {}), 0); + + // Wait until the first backend is ready. + WaitForBackend(0); + + // Send 10 requests. + gpr_log(GPR_INFO, "========= BEFORE FIRST BATCH =========="); + CheckRpcSendOk(10); + gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH =========="); + + // All 10 requests should have gone to the first backend. + EXPECT_EQ(10U, backends_[0]->service_.request_count()); + + // Balancer 0 got a single request. + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); + // and sent a single response. + EXPECT_EQ(1U, balancers_[0]->service_.response_count()); + EXPECT_EQ(0U, balancers_[1]->service_.request_count()); + EXPECT_EQ(0U, balancers_[1]->service_.response_count()); + EXPECT_EQ(0U, balancers_[2]->service_.request_count()); + EXPECT_EQ(0U, balancers_[2]->service_.response_count()); + + std::vector ports; + ports.emplace_back(balancers_[0]->port_); + ports.emplace_back(balancers_[1]->port_); + ports.emplace_back(balancers_[2]->port_); + gpr_log(GPR_INFO, "========= ABOUT TO UPDATE 1 =========="); + SetNextResolutionForLbChannel(ports); + gpr_log(GPR_INFO, "========= UPDATE 1 DONE =========="); + + EXPECT_EQ(0U, backends_[1]->service_.request_count()); + gpr_timespec deadline = gpr_time_add( + gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_millis(10000, GPR_TIMESPAN)); + // Send 10 seconds worth of RPCs + do { + CheckRpcSendOk(); + } while (gpr_time_cmp(gpr_now(GPR_CLOCK_REALTIME), deadline) < 0); + // xds continued using the original LB call to the first balancer, which + // doesn't assign the second backend. + EXPECT_EQ(0U, backends_[1]->service_.request_count()); + + ports.clear(); + ports.emplace_back(balancers_[0]->port_); + ports.emplace_back(balancers_[1]->port_); + gpr_log(GPR_INFO, "========= ABOUT TO UPDATE 2 =========="); + SetNextResolutionForLbChannel(ports); + gpr_log(GPR_INFO, "========= UPDATE 2 DONE =========="); + + EXPECT_EQ(0U, backends_[1]->service_.request_count()); + deadline = gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), + gpr_time_from_millis(10000, GPR_TIMESPAN)); + // Send 10 seconds worth of RPCs + do { + CheckRpcSendOk(); + } while (gpr_time_cmp(gpr_now(GPR_CLOCK_REALTIME), deadline) < 0); + // xds continued using the original LB call to the first balancer, which + // doesn't assign the second backend. + EXPECT_EQ(0U, backends_[1]->service_.request_count()); +} + +TEST_F(UpdatesTest, UpdateBalancersDeadUpdate) { + SetNextResolution({}, kDefaultServiceConfig_.c_str()); + SetNextResolutionForLbChannel({balancers_[0]->port_}); + const std::vector first_backend{GetBackendPorts()[0]}; + const std::vector second_backend{GetBackendPorts()[1]}; + + ScheduleResponseForBalancer( + 0, BalancerServiceImpl::BuildResponseForBackends(first_backend, {}), 0); + ScheduleResponseForBalancer( + 1, BalancerServiceImpl::BuildResponseForBackends(second_backend, {}), 0); + + // Start servers and send 10 RPCs per server. + gpr_log(GPR_INFO, "========= BEFORE FIRST BATCH =========="); + CheckRpcSendOk(10); + gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH =========="); + // All 10 requests should have gone to the first backend. + EXPECT_EQ(10U, backends_[0]->service_.request_count()); + + // Kill balancer 0 + gpr_log(GPR_INFO, "********** ABOUT TO KILL BALANCER 0 *************"); + balancers_[0]->Shutdown(); + gpr_log(GPR_INFO, "********** KILLED BALANCER 0 *************"); + + // This is serviced by the existing child policy. + gpr_log(GPR_INFO, "========= BEFORE SECOND BATCH =========="); + CheckRpcSendOk(10); + gpr_log(GPR_INFO, "========= DONE WITH SECOND BATCH =========="); + // All 10 requests should again have gone to the first backend. + EXPECT_EQ(20U, backends_[0]->service_.request_count()); + EXPECT_EQ(0U, backends_[1]->service_.request_count()); + + // Balancer 0 got a single request. + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); + // and sent a single response. + EXPECT_EQ(1U, balancers_[0]->service_.response_count()); + EXPECT_EQ(0U, balancers_[1]->service_.request_count()); + EXPECT_EQ(0U, balancers_[1]->service_.response_count()); + EXPECT_EQ(0U, balancers_[2]->service_.request_count()); + EXPECT_EQ(0U, balancers_[2]->service_.response_count()); + + gpr_log(GPR_INFO, "========= ABOUT TO UPDATE 1 =========="); + SetNextResolutionForLbChannel({balancers_[1]->port_}); + gpr_log(GPR_INFO, "========= UPDATE 1 DONE =========="); + + // Wait until update has been processed, as signaled by the second backend + // receiving a request. In the meantime, the client continues to be serviced + // (by the first backend) without interruption. + EXPECT_EQ(0U, backends_[1]->service_.request_count()); + WaitForBackend(1); + + // This is serviced by the updated RR policy + backends_[1]->service_.ResetCounters(); + gpr_log(GPR_INFO, "========= BEFORE THIRD BATCH =========="); + CheckRpcSendOk(10); + gpr_log(GPR_INFO, "========= DONE WITH THIRD BATCH =========="); + // All 10 requests should have gone to the second backend. + EXPECT_EQ(10U, backends_[1]->service_.request_count()); + + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); + EXPECT_EQ(1U, balancers_[0]->service_.response_count()); + // The second balancer, published as part of the first update, may end up + // getting two requests (that is, 1 <= #req <= 2) if the LB call retry timer + // firing races with the arrival of the update containing the second + // balancer. + EXPECT_GE(balancers_[1]->service_.request_count(), 1U); + EXPECT_GE(balancers_[1]->service_.response_count(), 1U); + EXPECT_LE(balancers_[1]->service_.request_count(), 2U); + EXPECT_LE(balancers_[1]->service_.response_count(), 2U); + EXPECT_EQ(0U, balancers_[2]->service_.request_count()); + EXPECT_EQ(0U, balancers_[2]->service_.response_count()); +} + +// The re-resolution tests are deferred because they rely on the fallback mode, +// which hasn't been supported. + +// TODO(juanlishen): Add TEST_F(UpdatesTest, ReresolveDeadBackend). + +// TODO(juanlishen): Add TEST_F(UpdatesWithClientLoadReportingTest, +// ReresolveDeadBalancer) + +// The drop tests are deferred because the drop handling hasn't been added yet. + +// TODO(roth): Add TEST_F(SingleBalancerTest, Drop) + +// TODO(roth): Add TEST_F(SingleBalancerTest, DropAllFirst) + +// TODO(roth): Add TEST_F(SingleBalancerTest, DropAll) + +class SingleBalancerWithClientLoadReportingTest : public XdsEnd2endTest { + public: + SingleBalancerWithClientLoadReportingTest() : XdsEnd2endTest(4, 1, 3) {} +}; + +// The client load reporting tests are deferred because the client load +// reporting hasn't been supported yet. + +// TODO(vpowar): Add TEST_F(SingleBalancerWithClientLoadReportingTest, Vanilla) + +// TODO(roth): Add TEST_F(SingleBalancerWithClientLoadReportingTest, +// BalancerRestart) + +// TODO(roth): Add TEST_F(SingleBalancerWithClientLoadReportingTest, Drop) + +} // namespace +} // namespace testing +} // namespace grpc + +int main(int argc, char** argv) { + grpc_init(); + grpc::testing::TestEnvironment env(argc, argv); + ::testing::InitGoogleTest(&argc, argv); + const auto result = RUN_ALL_TESTS(); + grpc_shutdown(); + return result; +} diff --git a/test/cpp/ext/filters/census/BUILD b/test/cpp/ext/filters/census/BUILD index 6567dc667aa..78b27e2063c 100644 --- a/test/cpp/ext/filters/census/BUILD +++ b/test/cpp/ext/filters/census/BUILD @@ -24,19 +24,18 @@ grpc_cc_test( srcs = [ "stats_plugin_end2end_test.cc", ], - language = "C++", external_deps = [ "gtest", "gmock", "opencensus-stats-test", ], + language = "C++", deps = [ "//:grpc++", "//:grpc_opencensus_plugin", "//src/proto/grpc/testing:echo_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", - "//test/cpp/util:test_util", "//test/cpp/util:test_config", + "//test/cpp/util:test_util", ], ) diff --git a/test/cpp/ext/filters/census/stats_plugin_end2end_test.cc b/test/cpp/ext/filters/census/stats_plugin_end2end_test.cc index 664504a0903..0638c3343e6 100644 --- a/test/cpp/ext/filters/census/stats_plugin_end2end_test.cc +++ b/test/cpp/ext/filters/census/stats_plugin_end2end_test.cc @@ -25,6 +25,7 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" #include "include/grpc++/grpc++.h" +#include "include/grpcpp/opencensus.h" #include "opencensus/stats/stats.h" #include "opencensus/stats/testing/test_utils.h" #include "src/cpp/ext/filters/census/grpc_plugin.h" @@ -370,7 +371,7 @@ TEST_F(StatsPluginEnd2EndTest, RequestReceivedMessagesPerRpc) { } // namespace grpc int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/cpp/grpclb/BUILD b/test/cpp/grpclb/BUILD index 8319eb5142a..2f74a9bab0e 100644 --- a/test/cpp/grpclb/BUILD +++ b/test/cpp/grpclb/BUILD @@ -32,7 +32,6 @@ grpc_cc_test( "//:grpc", "//:grpc++", "//src/proto/grpc/lb/v1:load_balancer_proto", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], diff --git a/test/cpp/interop/BUILD b/test/cpp/interop/BUILD index 0f813054053..6cf4719c17b 100644 --- a/test/cpp/interop/BUILD +++ b/test/cpp/interop/BUILD @@ -157,9 +157,9 @@ grpc_cc_test( "//:gpr", "//:grpc", "//:grpc++", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_config", "//test/cpp/util:test_util", ], + tags = ["no_windows"], ) diff --git a/test/cpp/interop/client.cc b/test/cpp/interop/client.cc index a4b1a85f856..ccfd2bb0c45 100644 --- a/test/cpp/interop/client.cc +++ b/test/cpp/interop/client.cc @@ -38,7 +38,7 @@ DEFINE_string(custom_credentials_type, "", "User provided credentials type."); DEFINE_bool(use_test_ca, false, "False to use SSL roots for google"); DEFINE_int32(server_port, 0, "Server port."); DEFINE_string(server_host, "localhost", "Server host to connect to"); -DEFINE_string(server_host_override, "foo.test.google.fr", +DEFINE_string(server_host_override, "", "Override the server host which is sent in HTTP header"); DEFINE_string( test_case, "large_unary", @@ -54,6 +54,7 @@ DEFINE_string( "custom_metadata: server will echo custom metadata;\n" "empty_stream : bi-di stream with no request/response;\n" "empty_unary : empty (zero bytes) request and response;\n" + "google_default_credentials: large unary using GDC;\n" "half_duplex : half-duplex streaming;\n" "jwt_token_creds: large_unary with JWT token auth;\n" "large_unary : single request and (large) response;\n" @@ -91,17 +92,101 @@ DEFINE_int32(soak_iterations, 1000, DEFINE_int32(iteration_interval, 10, "The interval in seconds between rpcs. This is used by " "long_connection test"); +DEFINE_string(additional_metadata, "", + "Additional metadata to send in each request, as a " + "semicolon-separated list of key:value pairs."); using grpc::testing::CreateChannelForTestCase; using grpc::testing::GetServiceAccountJsonKey; using grpc::testing::UpdateActions; +namespace { + +// Parse the contents of FLAGS_additional_metadata into a map. Allow +// alphanumeric characters and dashes in keys, and any character but semicolons +// in values. Convert keys to lowercase. On failure, log an error and return +// false. +bool ParseAdditionalMetadataFlag( + const grpc::string& flag, + std::multimap* additional_metadata) { + size_t start_pos = 0; + while (start_pos < flag.length()) { + size_t colon_pos = flag.find(':', start_pos); + if (colon_pos == grpc::string::npos) { + gpr_log(GPR_ERROR, + "Couldn't parse metadata flag: extra characters at end of flag"); + return false; + } + size_t semicolon_pos = flag.find(';', colon_pos); + + grpc::string key = flag.substr(start_pos, colon_pos - start_pos); + grpc::string value = + flag.substr(colon_pos + 1, semicolon_pos - colon_pos - 1); + + constexpr char alphanum_and_hyphen[] = + "-0123456789" + "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + if (key.find_first_not_of(alphanum_and_hyphen) != grpc::string::npos) { + gpr_log(GPR_ERROR, + "Couldn't parse metadata flag: key contains characters other " + "than alphanumeric and hyphens: %s", + key.c_str()); + return false; + } + + // Convert to lowercase. + for (char& c : key) { + if (c >= 'A' && c <= 'Z') { + c += ('a' - 'A'); + } + } + + gpr_log(GPR_INFO, "Adding additional metadata with key %s and value %s", + key.c_str(), value.c_str()); + additional_metadata->insert({key, value}); + + if (semicolon_pos == grpc::string::npos) { + break; + } else { + start_pos = semicolon_pos + 1; + } + } + + return true; +} + +} // namespace + int main(int argc, char** argv) { grpc::testing::InitTest(&argc, &argv, true); gpr_log(GPR_INFO, "Testing these cases: %s", FLAGS_test_case.c_str()); int ret = 0; - grpc::testing::ChannelCreationFunc channel_creation_func = - std::bind(&CreateChannelForTestCase, FLAGS_test_case); + + grpc::testing::ChannelCreationFunc channel_creation_func; + grpc::string test_case = FLAGS_test_case; + if (FLAGS_additional_metadata == "") { + channel_creation_func = [test_case]() { + return CreateChannelForTestCase(test_case); + }; + } else { + std::multimap additional_metadata; + if (!ParseAdditionalMetadataFlag(FLAGS_additional_metadata, + &additional_metadata)) { + return 1; + } + + channel_creation_func = [test_case, additional_metadata]() { + std::vector> + factories; + factories.emplace_back( + new grpc::testing::AdditionalMetadataInterceptorFactory( + additional_metadata)); + return CreateChannelForTestCase(test_case, std::move(factories)); + }; + } + grpc::testing::InteropClient client(channel_creation_func, true, FLAGS_do_not_abort_on_transient_failures); @@ -151,6 +236,11 @@ int main(int argc, char** argv) { std::bind(&grpc::testing::InteropClient::DoPerRpcCreds, &client, GetServiceAccountJsonKey()); } + if (FLAGS_custom_credentials_type == "google_default_credentials") { + actions["google_default_credentials"] = + std::bind(&grpc::testing::InteropClient::DoGoogleDefaultCredentials, + &client, FLAGS_default_service_account); + } actions["status_code_and_message"] = std::bind(&grpc::testing::InteropClient::DoStatusWithMessage, &client); actions["custom_metadata"] = diff --git a/test/cpp/interop/client_helper.cc b/test/cpp/interop/client_helper.cc index fb7b7bb7d03..92f07387d75 100644 --- a/test/cpp/interop/client_helper.cc +++ b/test/cpp/interop/client_helper.cc @@ -79,7 +79,10 @@ void UpdateActions( std::unordered_map>* actions) {} std::shared_ptr CreateChannelForTestCase( - const grpc::string& test_case) { + const grpc::string& test_case, + std::vector< + std::unique_ptr> + interceptor_creators) { GPR_ASSERT(FLAGS_server_port); const int host_port_buf_size = 1024; char host_port[host_port_buf_size]; @@ -107,9 +110,15 @@ std::shared_ptr CreateChannelForTestCase( transport_security security_type = FLAGS_use_alts ? ALTS : (FLAGS_use_tls ? TLS : INSECURE); return CreateTestChannel(host_port, FLAGS_server_host_override, - security_type, !FLAGS_use_test_ca, creds); + security_type, !FLAGS_use_test_ca, creds, + std::move(interceptor_creators)); } else { - return CreateTestChannel(host_port, FLAGS_custom_credentials_type, creds); + if (interceptor_creators.empty()) { + return CreateTestChannel(host_port, FLAGS_custom_credentials_type, creds); + } else { + return CreateTestChannel(host_port, FLAGS_custom_credentials_type, creds, + std::move(interceptor_creators)); + } } } diff --git a/test/cpp/interop/client_helper.h b/test/cpp/interop/client_helper.h index 7dee85cc980..4afce27470b 100644 --- a/test/cpp/interop/client_helper.h +++ b/test/cpp/interop/client_helper.h @@ -39,7 +39,10 @@ void UpdateActions( std::unordered_map>* actions); std::shared_ptr CreateChannelForTestCase( - const grpc::string& test_case); + const grpc::string& test_case, + std::vector< + std::unique_ptr> + interceptor_creators = {}); class InteropClientContextInspector { public: @@ -59,6 +62,43 @@ class InteropClientContextInspector { const ::grpc::ClientContext& context_; }; +class AdditionalMetadataInterceptor : public experimental::Interceptor { + public: + AdditionalMetadataInterceptor( + std::multimap additional_metadata) + : additional_metadata_(std::move(additional_metadata)) {} + + void Intercept(experimental::InterceptorBatchMethods* methods) override { + if (methods->QueryInterceptionHookPoint( + experimental::InterceptionHookPoints::PRE_SEND_INITIAL_METADATA)) { + std::multimap* metadata = + methods->GetSendInitialMetadata(); + for (const auto& entry : additional_metadata_) { + metadata->insert(entry); + } + } + methods->Proceed(); + } + + private: + const std::multimap additional_metadata_; +}; + +class AdditionalMetadataInterceptorFactory + : public experimental::ClientInterceptorFactoryInterface { + public: + AdditionalMetadataInterceptorFactory( + std::multimap additional_metadata) + : additional_metadata_(std::move(additional_metadata)) {} + + experimental::Interceptor* CreateClientInterceptor( + experimental::ClientRpcInfo* info) override { + return new AdditionalMetadataInterceptor(additional_metadata_); + } + + const std::multimap additional_metadata_; +}; + } // namespace testing } // namespace grpc diff --git a/test/cpp/interop/interop_client.cc b/test/cpp/interop/interop_client.cc index 4ff153f980a..649abf8a938 100644 --- a/test/cpp/interop/interop_client.cc +++ b/test/cpp/interop/interop_client.cc @@ -294,6 +294,25 @@ bool InteropClient::DoJwtTokenCreds(const grpc::string& username) { return true; } +bool InteropClient::DoGoogleDefaultCredentials( + const grpc::string& default_service_account) { + gpr_log(GPR_DEBUG, + "Sending a large unary rpc with GoogleDefaultCredentials..."); + SimpleRequest request; + SimpleResponse response; + request.set_fill_username(true); + + if (!PerformLargeUnary(&request, &response)) { + return false; + } + + gpr_log(GPR_DEBUG, "Got username %s", response.username().c_str()); + GPR_ASSERT(!response.username().empty()); + GPR_ASSERT(response.username().c_str() == default_service_account); + gpr_log(GPR_DEBUG, "Large unary rpc with GoogleDefaultCredentials done."); + return true; +} + bool InteropClient::DoLargeUnary() { gpr_log(GPR_DEBUG, "Sending a large unary rpc..."); SimpleRequest request; diff --git a/test/cpp/interop/interop_client.h b/test/cpp/interop/interop_client.h index 0ceff55c5c2..22df688468b 100644 --- a/test/cpp/interop/interop_client.h +++ b/test/cpp/interop/interop_client.h @@ -89,6 +89,8 @@ class InteropClient { const grpc::string& oauth_scope); // username is a string containing the user email bool DoPerRpcCreds(const grpc::string& json_key); + // default_service_account is the GCE default service account email + bool DoGoogleDefaultCredentials(const grpc::string& default_service_account); private: class ServiceStub { diff --git a/test/cpp/interop/interop_test.cc b/test/cpp/interop/interop_test.cc index ae155b65f95..8e45b877212 100644 --- a/test/cpp/interop/interop_test.cc +++ b/test/cpp/interop/interop_test.cc @@ -16,10 +16,6 @@ * */ -#ifndef _POSIX_SOURCE -#define _POSIX_SOURCE -#endif - #include #include #include diff --git a/test/cpp/interop/metrics_client.cc b/test/cpp/interop/metrics_client.cc index 02cd5643355..dca8e07b96c 100644 --- a/test/cpp/interop/metrics_client.cc +++ b/test/cpp/interop/metrics_client.cc @@ -88,7 +88,7 @@ bool PrintMetrics(std::unique_ptr stub, bool total_only, int main(int argc, char** argv) { grpc::testing::InitTest(&argc, &argv, true); - // The output of metrics client is in some cases programatically parsed (for + // The output of metrics client is in some cases programmatically parsed (for // example by the stress test framework). So, we do not want any of the log // from the grpc library appearing on stdout. gpr_set_log_function(BlackholeLogger); diff --git a/test/cpp/interop/stress_test.cc b/test/cpp/interop/stress_test.cc index ebbd14beba2..3e00980a269 100644 --- a/test/cpp/interop/stress_test.cc +++ b/test/cpp/interop/stress_test.cc @@ -103,7 +103,7 @@ 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", +DEFINE_string(server_host_override, "", "Override the server host which is sent in HTTP header"); using grpc::testing::ALTS; diff --git a/test/cpp/microbenchmarks/BUILD b/test/cpp/microbenchmarks/BUILD index 097e92f5836..d9424f24f16 100644 --- a/test/cpp/microbenchmarks/BUILD +++ b/test/cpp/microbenchmarks/BUILD @@ -24,7 +24,7 @@ grpc_cc_test( external_deps = [ "benchmark", ], - deps = ["//test/core/util:gpr_test_util"], + deps = ["//test/core/util:grpc_test_util"], ) grpc_cc_library( @@ -39,6 +39,7 @@ grpc_cc_library( external_deps = [ "benchmark", ], + tags = ["no_windows"], deps = [ "//:grpc++_unsecure", "//src/proto/grpc/testing:echo_proto", @@ -51,6 +52,15 @@ grpc_cc_binary( name = "bm_closure", testonly = 1, srcs = ["bm_closure.cc"], + tags = ["no_windows"], + deps = [":helpers"], +) + +grpc_cc_binary( + name = "bm_alarm", + testonly = 1, + srcs = ["bm_alarm.cc"], + tags = ["no_windows"], deps = [":helpers"], ) @@ -58,6 +68,15 @@ grpc_cc_binary( name = "bm_arena", testonly = 1, srcs = ["bm_arena.cc"], + tags = ["no_windows"], + deps = [":helpers"], +) + +grpc_cc_binary( + name = "bm_byte_buffer", + testonly = 1, + srcs = ["bm_byte_buffer.cc"], + tags = ["no_windows"], deps = [":helpers"], ) @@ -65,6 +84,7 @@ grpc_cc_binary( name = "bm_channel", testonly = 1, srcs = ["bm_channel.cc"], + tags = ["no_windows"], deps = [":helpers"], ) @@ -72,6 +92,7 @@ grpc_cc_binary( name = "bm_call_create", testonly = 1, srcs = ["bm_call_create.cc"], + tags = ["no_windows"], deps = [":helpers"], ) @@ -79,6 +100,7 @@ grpc_cc_binary( name = "bm_cq", testonly = 1, srcs = ["bm_cq.cc"], + tags = ["no_windows"], deps = [":helpers"], ) @@ -86,6 +108,7 @@ grpc_cc_binary( name = "bm_cq_multiple_threads", testonly = 1, srcs = ["bm_cq_multiple_threads.cc"], + tags = ["no_windows"], deps = [":helpers"], ) @@ -93,6 +116,7 @@ grpc_cc_binary( name = "bm_error", testonly = 1, srcs = ["bm_error.cc"], + tags = ["no_windows"], deps = [":helpers"], ) @@ -102,6 +126,7 @@ grpc_cc_library( hdrs = [ "fullstack_streaming_ping_pong.h", ], + tags = ["no_windows"], deps = [":helpers"], ) @@ -111,6 +136,7 @@ grpc_cc_binary( srcs = [ "bm_fullstack_streaming_ping_pong.cc", ], + tags = ["no_windows"], deps = [":fullstack_streaming_ping_pong_h"], ) @@ -129,6 +155,7 @@ grpc_cc_binary( srcs = [ "bm_fullstack_streaming_pump.cc", ], + tags = ["no_windows"], deps = [":fullstack_streaming_pump_h"], ) @@ -136,6 +163,7 @@ grpc_cc_binary( name = "bm_fullstack_trickle", testonly = 1, srcs = ["bm_fullstack_trickle.cc"], + tags = ["no_windows"], deps = [":helpers"], ) @@ -154,6 +182,7 @@ grpc_cc_binary( srcs = [ "bm_fullstack_unary_ping_pong.cc", ], + tags = ["no_windows"], deps = [":fullstack_unary_ping_pong_h"], ) @@ -161,6 +190,7 @@ grpc_cc_binary( name = "bm_metadata", testonly = 1, srcs = ["bm_metadata.cc"], + tags = ["no_windows"], deps = [":helpers"], ) @@ -168,6 +198,7 @@ grpc_cc_binary( name = "bm_chttp2_hpack", testonly = 1, srcs = ["bm_chttp2_hpack.cc"], + tags = ["no_windows"], deps = [":helpers"], ) @@ -182,3 +213,70 @@ grpc_cc_binary( "//src/proto/grpc/testing:echo_proto", ], ) + +grpc_cc_binary( + name = "bm_timer", + testonly = 1, + srcs = ["bm_timer.cc"], + tags = ["no_windows"], + deps = [":helpers"], +) + +grpc_cc_library( + name = "bm_callback_test_service_impl", + testonly = 1, + srcs = ["callback_test_service.cc"], + hdrs = ["callback_test_service.h"], + external_deps = [ + "benchmark", + ], + deps = [ + ":helpers", + "//src/proto/grpc/testing:echo_proto", + "//test/cpp/util:test_util", + ], +) + +grpc_cc_library( + name = "callback_unary_ping_pong_h", + testonly = 1, + hdrs = [ + "callback_unary_ping_pong.h", + ], + deps = [ + ":bm_callback_test_service_impl", + ":helpers", + ], +) + +grpc_cc_binary( + name = "bm_callback_unary_ping_pong", + testonly = 1, + srcs = [ + "bm_callback_unary_ping_pong.cc", + ], + tags = ["no_windows"], + deps = [":callback_unary_ping_pong_h"], +) + +grpc_cc_library( + name = "callback_streaming_ping_pong_h", + testonly = 1, + hdrs = [ + "callback_streaming_ping_pong.h", + ], + deps = [ + ":bm_callback_test_service_impl", + ":helpers", + ], +) + +grpc_cc_binary( + name = "bm_callback_streaming_ping_pong", + testonly = 1, + srcs = [ + "bm_callback_streaming_ping_pong.cc", + ], + tags = ["no_windows"], + deps = [":callback_streaming_ping_pong_h"], +) diff --git a/test/cpp/microbenchmarks/bm_alarm.cc b/test/cpp/microbenchmarks/bm_alarm.cc new file mode 100644 index 00000000000..d95771a57c6 --- /dev/null +++ b/test/cpp/microbenchmarks/bm_alarm.cc @@ -0,0 +1,63 @@ +/* + * + * 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 benchmark exists to ensure that immediately-firing alarms are fast */ + +#include +#include +#include +#include +#include +#include "test/core/util/test_config.h" +#include "test/cpp/microbenchmarks/helpers.h" +#include "test/cpp/util/test_config.h" + +namespace grpc { +namespace testing { + +static void BM_Alarm_Tag_Immediate(benchmark::State& state) { + TrackCounters track_counters; + CompletionQueue cq; + Alarm alarm; + void* output_tag; + bool ok; + auto deadline = grpc_timeout_seconds_to_deadline(0); + while (state.KeepRunning()) { + alarm.Set(&cq, deadline, nullptr); + cq.Next(&output_tag, &ok); + } + track_counters.Finish(state); +} +BENCHMARK(BM_Alarm_Tag_Immediate); + +} // namespace testing +} // namespace grpc + +// 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) { + LibraryInitializer libInit; + ::benchmark::Initialize(&argc, argv); + ::grpc::testing::InitTest(&argc, &argv, false); + benchmark::RunTheBenchmarksNamespaced(); + return 0; +} diff --git a/test/cpp/microbenchmarks/bm_arena.cc b/test/cpp/microbenchmarks/bm_arena.cc index b97c954fae8..c3ded0d76f7 100644 --- a/test/cpp/microbenchmarks/bm_arena.cc +++ b/test/cpp/microbenchmarks/bm_arena.cc @@ -19,40 +19,42 @@ /* Benchmark arenas */ #include -#include "src/core/lib/gpr/arena.h" +#include "src/core/lib/gprpp/arena.h" #include "test/cpp/microbenchmarks/helpers.h" #include "test/cpp/util/test_config.h" +using grpc_core::Arena; + static void BM_Arena_NoOp(benchmark::State& state) { while (state.KeepRunning()) { - gpr_arena_destroy(gpr_arena_create(state.range(0))); + Arena::Create(state.range(0))->Destroy(); } } BENCHMARK(BM_Arena_NoOp)->Range(1, 1024 * 1024); static void BM_Arena_ManyAlloc(benchmark::State& state) { - gpr_arena* a = gpr_arena_create(state.range(0)); + Arena* a = Arena::Create(state.range(0)); const size_t realloc_after = 1024 * 1024 * 1024 / ((state.range(1) + 15) & 0xffffff0u); while (state.KeepRunning()) { - gpr_arena_alloc(a, state.range(1)); + a->Alloc(state.range(1)); // periodically recreate arena to avoid OOM if (state.iterations() % realloc_after == 0) { - gpr_arena_destroy(a); - a = gpr_arena_create(state.range(0)); + a->Destroy(); + a = Arena::Create(state.range(0)); } } - gpr_arena_destroy(a); + a->Destroy(); } BENCHMARK(BM_Arena_ManyAlloc)->Ranges({{1, 1024 * 1024}, {1, 32 * 1024}}); static void BM_Arena_Batch(benchmark::State& state) { while (state.KeepRunning()) { - gpr_arena* a = gpr_arena_create(state.range(0)); + Arena* a = Arena::Create(state.range(0)); for (int i = 0; i < state.range(1); i++) { - gpr_arena_alloc(a, state.range(2)); + a->Alloc(state.range(2)); } - gpr_arena_destroy(a); + a->Destroy(); } } BENCHMARK(BM_Arena_Batch)->Ranges({{1, 64 * 1024}, {1, 64}, {1, 1024}}); diff --git a/test/cpp/microbenchmarks/bm_byte_buffer.cc b/test/cpp/microbenchmarks/bm_byte_buffer.cc new file mode 100644 index 00000000000..595cc734b69 --- /dev/null +++ b/test/cpp/microbenchmarks/bm_byte_buffer.cc @@ -0,0 +1,130 @@ +/* + * + * 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 benchmark exists to show that byte-buffer copy is size-independent */ + +#include + +#include +#include +#include +#include "test/cpp/microbenchmarks/helpers.h" +#include "test/cpp/util/test_config.h" + +namespace grpc { +namespace testing { + +static void BM_ByteBuffer_Copy(benchmark::State& state) { + int num_slices = state.range(0); + size_t slice_size = state.range(1); + std::vector slices; + while (num_slices > 0) { + num_slices--; + std::unique_ptr buf(new char[slice_size]); + memset(buf.get(), 0, slice_size); + slices.emplace_back(buf.get(), slice_size); + } + grpc::ByteBuffer bb(slices.data(), num_slices); + while (state.KeepRunning()) { + grpc::ByteBuffer cc(bb); + } +} +BENCHMARK(BM_ByteBuffer_Copy)->Ranges({{1, 64}, {1, 1024 * 1024}}); + +static void BM_ByteBufferReader_Next(benchmark::State& state) { + const int num_slices = state.range(0); + constexpr size_t kSliceSize = 16; + std::vector slices; + for (int i = 0; i < num_slices; ++i) { + std::unique_ptr buf(new char[kSliceSize]); + slices.emplace_back(g_core_codegen_interface->grpc_slice_from_copied_buffer( + buf.get(), kSliceSize)); + } + grpc_byte_buffer* bb = g_core_codegen_interface->grpc_raw_byte_buffer_create( + slices.data(), num_slices); + grpc_byte_buffer_reader reader; + GPR_ASSERT( + g_core_codegen_interface->grpc_byte_buffer_reader_init(&reader, bb)); + while (state.KeepRunning()) { + grpc_slice* slice; + if (GPR_UNLIKELY(!g_core_codegen_interface->grpc_byte_buffer_reader_peek( + &reader, &slice))) { + g_core_codegen_interface->grpc_byte_buffer_reader_destroy(&reader); + GPR_ASSERT( + g_core_codegen_interface->grpc_byte_buffer_reader_init(&reader, bb)); + continue; + } + } + + g_core_codegen_interface->grpc_byte_buffer_reader_destroy(&reader); + g_core_codegen_interface->grpc_byte_buffer_destroy(bb); + for (auto& slice : slices) { + g_core_codegen_interface->grpc_slice_unref(slice); + } +} +BENCHMARK(BM_ByteBufferReader_Next)->Ranges({{64 * 1024, 1024 * 1024}}); + +static void BM_ByteBufferReader_Peek(benchmark::State& state) { + const int num_slices = state.range(0); + constexpr size_t kSliceSize = 16; + std::vector slices; + for (int i = 0; i < num_slices; ++i) { + std::unique_ptr buf(new char[kSliceSize]); + slices.emplace_back(g_core_codegen_interface->grpc_slice_from_copied_buffer( + buf.get(), kSliceSize)); + } + grpc_byte_buffer* bb = g_core_codegen_interface->grpc_raw_byte_buffer_create( + slices.data(), num_slices); + grpc_byte_buffer_reader reader; + GPR_ASSERT( + g_core_codegen_interface->grpc_byte_buffer_reader_init(&reader, bb)); + while (state.KeepRunning()) { + grpc_slice* slice; + if (GPR_UNLIKELY(!g_core_codegen_interface->grpc_byte_buffer_reader_peek( + &reader, &slice))) { + g_core_codegen_interface->grpc_byte_buffer_reader_destroy(&reader); + GPR_ASSERT( + g_core_codegen_interface->grpc_byte_buffer_reader_init(&reader, bb)); + continue; + } + } + + g_core_codegen_interface->grpc_byte_buffer_reader_destroy(&reader); + g_core_codegen_interface->grpc_byte_buffer_destroy(bb); + for (auto& slice : slices) { + g_core_codegen_interface->grpc_slice_unref(slice); + } +} +BENCHMARK(BM_ByteBufferReader_Peek)->Ranges({{64 * 1024, 1024 * 1024}}); + +} // namespace testing +} // namespace grpc + +// 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) { + LibraryInitializer libInit; + ::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 8d12606434b..3bd1464b2aa 100644 --- a/test/cpp/microbenchmarks/bm_call_create.cc +++ b/test/cpp/microbenchmarks/bm_call_create.cc @@ -47,8 +47,6 @@ #include "test/cpp/microbenchmarks/helpers.h" #include "test/cpp/util/test_config.h" -auto& force_library_initialization = Library::get(); - void BM_Zalloc(benchmark::State& state) { // speed of light for call creation is zalloc, so benchmark a few interesting // sizes @@ -318,30 +316,18 @@ static void FilterDestroy(void* arg, grpc_error* error) { gpr_free(arg); } static void DoNothing(void* arg, grpc_error* error) {} -class FakeClientChannelFactory : public grpc_client_channel_factory { +class FakeClientChannelFactory : public grpc_core::ClientChannelFactory { public: - FakeClientChannelFactory() { vtable = &vtable_; } - - private: - static void NoRef(grpc_client_channel_factory* factory) {} - static void NoUnref(grpc_client_channel_factory* factory) {} - static grpc_subchannel* CreateSubchannel(grpc_client_channel_factory* factory, - const grpc_subchannel_args* args) { + grpc_core::Subchannel* CreateSubchannel( + const grpc_channel_args* args) override { return nullptr; } - static grpc_channel* CreateClientChannel(grpc_client_channel_factory* factory, - const char* target, - grpc_client_channel_type type, - const grpc_channel_args* args) { + grpc_channel* CreateChannel(const char* target, + const grpc_channel_args* args) override { return nullptr; } - - static const grpc_client_channel_factory_vtable vtable_; }; -const grpc_client_channel_factory_vtable FakeClientChannelFactory::vtable_ = { - NoRef, NoUnref, CreateSubchannel, CreateClientChannel}; - static grpc_arg StringArg(const char* key, const char* value) { grpc_arg a; a.type = GRPC_ARG_STRING; @@ -417,7 +403,7 @@ const char* name; /* implementation of grpc_transport_init_stream */ int InitStream(grpc_transport* self, grpc_stream* stream, grpc_stream_refcount* refcount, const void* server_data, - gpr_arena* arena) { + grpc_core::Arena* arena) { return 0; } @@ -506,13 +492,13 @@ static void BM_IsolatedFilter(benchmark::State& state) { TrackCounters track_counters; Fixture fixture; std::ostringstream label; - - std::vector args; FakeClientChannelFactory fake_client_channel_factory; - args.push_back(grpc_client_channel_factory_create_channel_arg( - &fake_client_channel_factory)); - args.push_back(StringArg(GRPC_ARG_SERVER_URI, "localhost")); + std::vector args = { + grpc_core::ClientChannelFactory::CreateChannelArg( + &fake_client_channel_factory), + StringArg(GRPC_ARG_SERVER_URI, "localhost"), + }; grpc_channel_args channel_args = {args.size(), &args[0]}; std::vector filters; @@ -545,15 +531,15 @@ static void BM_IsolatedFilter(benchmark::State& state) { grpc_slice method = grpc_slice_from_static_string("/foo/bar"); grpc_call_final_info final_info; TestOp test_op_data; - grpc_call_element_args call_args; - call_args.call_stack = call_stack; - call_args.server_transport_data = nullptr; - call_args.context = nullptr; - call_args.path = method; - call_args.start_time = start_time; - call_args.deadline = deadline; const int kArenaSize = 4096; - call_args.arena = gpr_arena_create(kArenaSize); + grpc_call_element_args call_args{call_stack, + nullptr, + nullptr, + method, + start_time, + deadline, + grpc_core::Arena::Create(kArenaSize), + nullptr}; while (state.KeepRunning()) { GPR_TIMER_SCOPE("BenchmarkCycle", 0); GRPC_ERROR_UNREF( @@ -564,12 +550,13 @@ static void BM_IsolatedFilter(benchmark::State& state) { grpc_core::ExecCtx::Get()->Flush(); // recreate arena every 64k iterations to avoid oom if (0 == (state.iterations() & 0xffff)) { - gpr_arena_destroy(call_args.arena); - call_args.arena = gpr_arena_create(kArenaSize); + call_args.arena->Destroy(); + call_args.arena = grpc_core::Arena::Create(kArenaSize); } } - gpr_arena_destroy(call_args.arena); + call_args.arena->Destroy(); grpc_channel_stack_destroy(channel_stack); + grpc_core::ExecCtx::Get()->Flush(); gpr_free(channel_stack); gpr_free(call_stack); @@ -620,7 +607,7 @@ BENCHMARK_TEMPLATE(BM_IsolatedFilter, MessageSizeFilter, SendEmptyMetadata); namespace isolated_call_filter { typedef struct { - grpc_call_combiner* call_combiner; + grpc_core::CallCombiner* call_combiner; } call_data; static void StartTransportStreamOp(grpc_call_element* elem, @@ -834,6 +821,7 @@ void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } } // namespace benchmark int main(int argc, char** argv) { + LibraryInitializer libInit; ::benchmark::Initialize(&argc, argv); ::grpc::testing::InitTest(&argc, &argv, false); benchmark::RunTheBenchmarksNamespaced(); diff --git a/test/cpp/microbenchmarks/bm_callback_streaming_ping_pong.cc b/test/cpp/microbenchmarks/bm_callback_streaming_ping_pong.cc new file mode 100644 index 00000000000..cde3eb2a241 --- /dev/null +++ b/test/cpp/microbenchmarks/bm_callback_streaming_ping_pong.cc @@ -0,0 +1,136 @@ +/* + * + * Copyright 2019 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/cpp/microbenchmarks/callback_streaming_ping_pong.h" +#include "test/cpp/util/test_config.h" + +namespace grpc { +namespace testing { + +/******************************************************************************* + * CONFIGURATIONS + */ + +// Replace "benchmark::internal::Benchmark" with "::testing::Benchmark" to use +// internal microbenchmarking tooling +static void StreamingPingPongMsgSizeArgs(benchmark::internal::Benchmark* b) { + // base case: 0 byte ping-pong msgs + b->Args({0, 1}); + b->Args({0, 2}); + + for (int msg_size = 1; msg_size <= 128 * 1024 * 1024; msg_size *= 8) { + b->Args({msg_size, 1}); + b->Args({msg_size, 2}); + } +} + +// Replace "benchmark::internal::Benchmark" with "::testing::Benchmark" to use +// internal microbenchmarking tooling +static void StreamingPingPongMsgsNumberArgs(benchmark::internal::Benchmark* b) { + for (int msg_number = 1; msg_number <= 256 * 1024; msg_number *= 8) { + b->Args({0, msg_number}); + b->Args({1024, msg_number}); + } +} + +// Streaming with different message size +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcess, NoOpMutator, + NoOpMutator) + ->Apply(StreamingPingPongMsgSizeArgs); +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, MinInProcess, NoOpMutator, + NoOpMutator) + ->Apply(StreamingPingPongMsgSizeArgs); + +// Streaming with different message number +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcess, NoOpMutator, + NoOpMutator) + ->Apply(StreamingPingPongMsgsNumberArgs); +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, MinInProcess, NoOpMutator, + NoOpMutator) + ->Apply(StreamingPingPongMsgsNumberArgs); + +// Client context with different metadata +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcess, + Client_AddMetadata, 1>, NoOpMutator) + ->Args({0, 1}); +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcess, + Client_AddMetadata, 1>, NoOpMutator) + ->Args({0, 1}); +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcess, + Client_AddMetadata, 1>, + NoOpMutator) + ->Args({0, 1}); +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcess, + Client_AddMetadata, 2>, NoOpMutator) + ->Args({0, 1}); +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcess, + Client_AddMetadata, 2>, NoOpMutator) + ->Args({0, 1}); +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcess, + Client_AddMetadata, 2>, + NoOpMutator) + ->Args({0, 1}); +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcess, + Client_AddMetadata, 1>, NoOpMutator) + ->Args({0, 1}); +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcess, + Client_AddMetadata, 1>, NoOpMutator) + ->Args({0, 1}); +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcess, + Client_AddMetadata, 1>, NoOpMutator) + ->Args({0, 1}); + +// Server context with different metadata +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcess, NoOpMutator, + Server_AddInitialMetadata, 1>) + ->Args({0, 1}); +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcess, NoOpMutator, + Server_AddInitialMetadata, 1>) + ->Args({0, 1}); +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcess, NoOpMutator, + Server_AddInitialMetadata, 1>) + ->Args({0, 1}); +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcess, NoOpMutator, + Server_AddInitialMetadata, 1>) + ->Args({0, 1}); +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcess, NoOpMutator, + Server_AddInitialMetadata, 1>) + ->Args({0, 1}); +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcess, NoOpMutator, + Server_AddInitialMetadata, 1>) + ->Args({0, 1}); +BENCHMARK_TEMPLATE(BM_CallbackBidiStreaming, InProcess, NoOpMutator, + Server_AddInitialMetadata, 100>) + ->Args({0, 1}); + +} // namespace testing +} // namespace grpc + +// 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) { + LibraryInitializer libInit; + ::benchmark::Initialize(&argc, argv); + ::grpc::testing::InitTest(&argc, &argv, false); + benchmark::RunTheBenchmarksNamespaced(); + return 0; +} diff --git a/test/cpp/microbenchmarks/bm_callback_unary_ping_pong.cc b/test/cpp/microbenchmarks/bm_callback_unary_ping_pong.cc new file mode 100644 index 00000000000..4ee77525bc6 --- /dev/null +++ b/test/cpp/microbenchmarks/bm_callback_unary_ping_pong.cc @@ -0,0 +1,118 @@ +/* + * + * Copyright 2019 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/cpp/microbenchmarks/callback_unary_ping_pong.h" +#include "test/cpp/util/test_config.h" + +namespace grpc { +namespace testing { + +/******************************************************************************* + * CONFIGURATIONS + */ + +// Replace "benchmark::internal::Benchmark" with "::testing::Benchmark" to use +// internal microbenchmarking tooling +static void SweepSizesArgs(benchmark::internal::Benchmark* b) { + b->Args({0, 0}); + for (int i = 1; i <= 128 * 1024 * 1024; i *= 8) { + // First argument is the message size of request + // Second argument is the message size of response + b->Args({i, 0}); + b->Args({0, i}); + b->Args({i, i}); + } +} + +// Unary ping pong with different message size of request and response +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcess, NoOpMutator, + NoOpMutator) + ->Apply(SweepSizesArgs); +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, MinInProcess, NoOpMutator, + NoOpMutator) + ->Apply(SweepSizesArgs); + +// Client context with different metadata +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcess, + Client_AddMetadata, 1>, NoOpMutator) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcess, + Client_AddMetadata, 1>, NoOpMutator) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcess, + Client_AddMetadata, 1>, + NoOpMutator) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcess, + Client_AddMetadata, 2>, NoOpMutator) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcess, + Client_AddMetadata, 2>, NoOpMutator) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcess, + Client_AddMetadata, 2>, + NoOpMutator) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcess, + Client_AddMetadata, 1>, NoOpMutator) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcess, + Client_AddMetadata, 1>, NoOpMutator) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcess, + Client_AddMetadata, 1>, NoOpMutator) + ->Args({0, 0}); + +// Server context with different metadata +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcess, NoOpMutator, + Server_AddInitialMetadata, 1>) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcess, NoOpMutator, + Server_AddInitialMetadata, 1>) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcess, NoOpMutator, + Server_AddInitialMetadata, 1>) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcess, NoOpMutator, + Server_AddInitialMetadata, 1>) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcess, NoOpMutator, + Server_AddInitialMetadata, 1>) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcess, NoOpMutator, + Server_AddInitialMetadata, 1>) + ->Args({0, 0}); +BENCHMARK_TEMPLATE(BM_CallbackUnaryPingPong, InProcess, NoOpMutator, + Server_AddInitialMetadata, 100>) + ->Args({0, 0}); +} // namespace testing +} // namespace grpc + +// 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) { + LibraryInitializer libInit; + ::benchmark::Initialize(&argc, argv); + ::grpc::testing::InitTest(&argc, &argv, false); + benchmark::RunTheBenchmarksNamespaced(); + return 0; +} diff --git a/test/cpp/microbenchmarks/bm_channel.cc b/test/cpp/microbenchmarks/bm_channel.cc index 15ac9975400..88856c3439b 100644 --- a/test/cpp/microbenchmarks/bm_channel.cc +++ b/test/cpp/microbenchmarks/bm_channel.cc @@ -23,8 +23,6 @@ #include "test/cpp/microbenchmarks/helpers.h" #include "test/cpp/util/test_config.h" -auto& force_library_initialization = Library::get(); - class ChannelDestroyerFixture { public: ChannelDestroyerFixture() {} @@ -83,6 +81,7 @@ void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } } // namespace benchmark int main(int argc, char** argv) { + LibraryInitializer libInit; ::benchmark::Initialize(&argc, argv); ::grpc::testing::InitTest(&argc, &argv, false); benchmark::RunTheBenchmarksNamespaced(); diff --git a/test/cpp/microbenchmarks/bm_chttp2_hpack.cc b/test/cpp/microbenchmarks/bm_chttp2_hpack.cc index 85d233dd264..d0ed1da7671 100644 --- a/test/cpp/microbenchmarks/bm_chttp2_hpack.cc +++ b/test/cpp/microbenchmarks/bm_chttp2_hpack.cc @@ -36,8 +36,6 @@ #include "test/cpp/microbenchmarks/helpers.h" #include "test/cpp/util/test_config.h" -auto& force_library_initialization = Library::get(); - static grpc_slice MakeSlice(std::vector bytes) { grpc_slice s = grpc_slice_malloc(bytes.size()); uint8_t* p = GRPC_SLICE_START_PTR(s); @@ -458,7 +456,7 @@ static void BM_HpackParserParseHeader(benchmark::State& state) { grpc_chttp2_hpack_parser p; grpc_chttp2_hpack_parser_init(&p); const int kArenaSize = 4096 * 4096; - p.on_header_user_data = gpr_arena_create(kArenaSize); + p.on_header_user_data = grpc_core::Arena::Create(kArenaSize); p.on_header = OnHeader; for (auto slice : init_slices) { GPR_ASSERT(GRPC_ERROR_NONE == grpc_chttp2_hpack_parser_parse(&p, slice)); @@ -470,12 +468,12 @@ static void BM_HpackParserParseHeader(benchmark::State& state) { grpc_core::ExecCtx::Get()->Flush(); // Recreate arena every 4k iterations to avoid oom if (0 == (state.iterations() & 0xfff)) { - gpr_arena_destroy((gpr_arena*)p.on_header_user_data); - p.on_header_user_data = gpr_arena_create(kArenaSize); + static_cast(p.on_header_user_data)->Destroy(); + p.on_header_user_data = grpc_core::Arena::Create(kArenaSize); } } // Clean up - gpr_arena_destroy((gpr_arena*)p.on_header_user_data); + static_cast(p.on_header_user_data)->Destroy(); for (auto slice : init_slices) grpc_slice_unref(slice); for (auto slice : benchmark_slices) grpc_slice_unref(slice); grpc_chttp2_hpack_parser_destroy(&p); @@ -778,7 +776,8 @@ static void free_timeout(void* p) { gpr_free(p); } // Benchmark the current on_initial_header implementation static void OnInitialHeader(void* user_data, grpc_mdelem md) { // Setup for benchmark. This will bloat the absolute values of this benchmark - grpc_chttp2_incoming_metadata_buffer buffer((gpr_arena*)user_data); + grpc_chttp2_incoming_metadata_buffer buffer( + static_cast(user_data)); bool seen_error = false; // Below here is the code we actually care about benchmarking @@ -927,6 +926,7 @@ void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } } // namespace benchmark int main(int argc, char** argv) { + LibraryInitializer libInit; ::benchmark::Initialize(&argc, argv); ::grpc::testing::InitTest(&argc, &argv, false); benchmark::RunTheBenchmarksNamespaced(); diff --git a/test/cpp/microbenchmarks/bm_chttp2_transport.cc b/test/cpp/microbenchmarks/bm_chttp2_transport.cc index f7ae16e61d4..05504584c20 100644 --- a/test/cpp/microbenchmarks/bm_chttp2_transport.cc +++ b/test/cpp/microbenchmarks/bm_chttp2_transport.cc @@ -36,8 +36,6 @@ #include "test/cpp/microbenchmarks/helpers.h" #include "test/cpp/util/test_config.h" -auto& force_library_initialization = Library::get(); - //////////////////////////////////////////////////////////////////////////////// // Helper classes // @@ -54,9 +52,11 @@ class DummyEndpoint : public grpc_endpoint { destroy, get_resource_user, get_peer, - get_fd}; + get_fd, + can_track_err}; grpc_endpoint::vtable = &my_vtable; - ru_ = grpc_resource_user_create(Library::get().rq(), "dummy_endpoint"); + ru_ = grpc_resource_user_create(LibraryInitializer::get().rq(), + "dummy_endpoint"); } void PushInput(grpc_slice slice) { @@ -91,7 +91,7 @@ class DummyEndpoint : public grpc_endpoint { } static void read(grpc_endpoint* ep, grpc_slice_buffer* slices, - grpc_closure* cb) { + grpc_closure* cb, bool urgent) { static_cast(ep)->QueueRead(slices, cb); } @@ -100,8 +100,6 @@ class DummyEndpoint : public grpc_endpoint { GRPC_CLOSURE_SCHED(cb, GRPC_ERROR_NONE); } - static grpc_workqueue* get_workqueue(grpc_endpoint* ep) { return nullptr; } - static void add_to_pollset(grpc_endpoint* ep, grpc_pollset* pollset) {} static void add_to_pollset_set(grpc_endpoint* ep, grpc_pollset_set* pollset) { @@ -125,6 +123,7 @@ class DummyEndpoint : public grpc_endpoint { } static char* get_peer(grpc_endpoint* ep) { return gpr_strdup("test"); } static int get_fd(grpc_endpoint* ep) { return 0; } + static bool can_track_err(grpc_endpoint* ep) { return false; } }; class Fixture { @@ -193,13 +192,13 @@ class Stream { Stream(Fixture* f) : f_(f) { stream_size_ = grpc_transport_stream_size(f->transport()); stream_ = gpr_malloc(stream_size_); - arena_ = gpr_arena_create(4096); + arena_ = grpc_core::Arena::Create(4096); } ~Stream() { gpr_event_wait(&done_, gpr_inf_future(GPR_CLOCK_REALTIME)); gpr_free(stream_); - gpr_arena_destroy(arena_); + arena_->Destroy(); } void Init(benchmark::State& state) { @@ -208,8 +207,8 @@ class Stream { gpr_event_init(&done_); memset(stream_, 0, stream_size_); if ((state.iterations() & 0xffff) == 0) { - gpr_arena_destroy(arena_); - arena_ = gpr_arena_create(4096); + arena_->Destroy(); + arena_ = grpc_core::Arena::Create(4096); } grpc_transport_init_stream(f_->transport(), static_cast(stream_), &refcount_, @@ -245,7 +244,7 @@ class Stream { Fixture* f_; grpc_stream_refcount refcount_; - gpr_arena* arena_; + grpc_core::Arena* arena_; size_t stream_size_; void* stream_; grpc_closure* destroy_closure_ = nullptr; @@ -642,6 +641,7 @@ void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } } // namespace benchmark int main(int argc, char** argv) { + LibraryInitializer libInit; ::benchmark::Initialize(&argc, argv); ::grpc::testing::InitTest(&argc, &argv, false); benchmark::RunTheBenchmarksNamespaced(); diff --git a/test/cpp/microbenchmarks/bm_closure.cc b/test/cpp/microbenchmarks/bm_closure.cc index 74ca1ce3a49..84b1c536bf0 100644 --- a/test/cpp/microbenchmarks/bm_closure.cc +++ b/test/cpp/microbenchmarks/bm_closure.cc @@ -30,8 +30,6 @@ #include "test/cpp/microbenchmarks/helpers.h" #include "test/cpp/util/test_config.h" -auto& force_library_initialization = Library::get(); - static void BM_NoOpExecCtx(benchmark::State& state) { TrackCounters track_counters; while (state.KeepRunning()) { @@ -183,6 +181,7 @@ static void BM_AcquireMutex(benchmark::State& state) { DoNothing(nullptr, GRPC_ERROR_NONE); gpr_mu_unlock(&mu); } + gpr_mu_destroy(&mu); track_counters.Finish(state); } @@ -202,6 +201,7 @@ static void BM_TryAcquireMutex(benchmark::State& state) { abort(); } } + gpr_mu_destroy(&mu); track_counters.Finish(state); } @@ -423,6 +423,7 @@ void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } } // namespace benchmark int main(int argc, char** argv) { + LibraryInitializer libInit; ::benchmark::Initialize(&argc, argv); ::grpc::testing::InitTest(&argc, &argv, false); benchmark::RunTheBenchmarksNamespaced(); diff --git a/test/cpp/microbenchmarks/bm_cq.cc b/test/cpp/microbenchmarks/bm_cq.cc index a7cb939265f..50eb9454fbe 100644 --- a/test/cpp/microbenchmarks/bm_cq.cc +++ b/test/cpp/microbenchmarks/bm_cq.cc @@ -32,8 +32,6 @@ namespace grpc { namespace testing { -auto& force_library_initialization = Library::get(); - static void BM_CreateDestroyCpp(benchmark::State& state) { TrackCounters track_counters; while (state.KeepRunning()) { @@ -146,6 +144,66 @@ static void BM_EmptyCore(benchmark::State& state) { } BENCHMARK(BM_EmptyCore); +// Helper for tests to shutdown correctly and tersely +static void shutdown_and_destroy(grpc_completion_queue* cc) { + grpc_completion_queue_shutdown(cc); + grpc_completion_queue_destroy(cc); +} + +// Tag completion queue iterate times +class TagCallback : public grpc_experimental_completion_queue_functor { + public: + explicit TagCallback(int* iter) : iter_(iter) { + functor_run = &TagCallback::Run; + } + ~TagCallback() {} + static void Run(grpc_experimental_completion_queue_functor* cb, int ok) { + GPR_ASSERT(static_cast(ok)); + *static_cast(cb)->iter_ += 1; + }; + + private: + int* iter_; +}; + +// Check if completion queue is shut down +class ShutdownCallback : public grpc_experimental_completion_queue_functor { + public: + explicit ShutdownCallback(bool* done) : done_(done) { + functor_run = &ShutdownCallback::Run; + } + ~ShutdownCallback() {} + static void Run(grpc_experimental_completion_queue_functor* cb, int ok) { + *static_cast(cb)->done_ = static_cast(ok); + } + + private: + bool* done_; +}; + +static void BM_Callback_CQ_Pass1Core(benchmark::State& state) { + TrackCounters track_counters; + int iteration = 0; + TagCallback tag_cb(&iteration); + bool got_shutdown = false; + ShutdownCallback shutdown_cb(&got_shutdown); + grpc_completion_queue* cc = + grpc_completion_queue_create_for_callback(&shutdown_cb, nullptr); + while (state.KeepRunning()) { + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; + grpc_core::ExecCtx exec_ctx; + grpc_cq_completion completion; + GPR_ASSERT(grpc_cq_begin_op(cc, &tag_cb)); + grpc_cq_end_op(cc, &tag_cb, GRPC_ERROR_NONE, DoneWithCompletionOnStack, + nullptr, &completion); + } + shutdown_and_destroy(cc); + GPR_ASSERT(got_shutdown); + GPR_ASSERT(iteration == static_cast(state.iterations())); + track_counters.Finish(state); +} +BENCHMARK(BM_Callback_CQ_Pass1Core); + } // namespace testing } // namespace grpc @@ -156,6 +214,7 @@ void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } } // namespace benchmark int main(int argc, char** argv) { + LibraryInitializer libInit; ::benchmark::Initialize(&argc, argv); ::grpc::testing::InitTest(&argc, &argv, false); benchmark::RunTheBenchmarksNamespaced(); diff --git a/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc b/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc index 85767c8758f..329eaf2434e 100644 --- a/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc +++ b/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc @@ -94,6 +94,10 @@ static const grpc_event_engine_vtable* init_engine_vtable(bool) { g_vtable.pollset_destroy = pollset_destroy; g_vtable.pollset_work = pollset_work; g_vtable.pollset_kick = pollset_kick; + g_vtable.is_any_background_poller_thread = [] { return false; }; + g_vtable.add_closure_to_background_poller = + [](grpc_closure* closure, grpc_error* error) { return false; }; + g_vtable.shutdown_background_closure = [] {}; g_vtable.shutdown_engine = [] {}; return &g_vtable; @@ -134,7 +138,7 @@ static void teardown() { Setup: The benchmark framework ensures that none of the threads proceed beyond the state.KeepRunning() call unless all the threads have called state.keepRunning - atleast once. So it is safe to do the initialization in one of the threads + at least once. So it is safe to do the initialization in one of the threads before state.KeepRunning() is called. Teardown: diff --git a/test/cpp/microbenchmarks/bm_error.cc b/test/cpp/microbenchmarks/bm_error.cc index ae557a580aa..a71817f7e54 100644 --- a/test/cpp/microbenchmarks/bm_error.cc +++ b/test/cpp/microbenchmarks/bm_error.cc @@ -27,8 +27,6 @@ #include "test/cpp/microbenchmarks/helpers.h" #include "test/cpp/util/test_config.h" -auto& force_library_initialization = Library::get(); - class ErrorDeleter { public: void operator()(grpc_error* error) { GRPC_ERROR_UNREF(error); } @@ -318,6 +316,7 @@ void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } } // namespace benchmark int main(int argc, char** argv) { + LibraryInitializer libInit; ::benchmark::Initialize(&argc, argv); ::grpc::testing::InitTest(&argc, &argv, false); benchmark::RunTheBenchmarksNamespaced(); diff --git a/test/cpp/microbenchmarks/bm_fullstack_streaming_ping_pong.cc b/test/cpp/microbenchmarks/bm_fullstack_streaming_ping_pong.cc index 34df77aca3c..60ca9a093ed 100644 --- a/test/cpp/microbenchmarks/bm_fullstack_streaming_ping_pong.cc +++ b/test/cpp/microbenchmarks/bm_fullstack_streaming_ping_pong.cc @@ -24,9 +24,6 @@ namespace grpc { namespace testing { -// force library initialization -auto& force_library_initialization = Library::get(); - /******************************************************************************* * CONFIGURATIONS */ @@ -122,6 +119,7 @@ void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } } // namespace benchmark int main(int argc, char** argv) { + LibraryInitializer libInit; ::benchmark::Initialize(&argc, argv); ::grpc::testing::InitTest(&argc, &argv, false); benchmark::RunTheBenchmarksNamespaced(); diff --git a/test/cpp/microbenchmarks/bm_fullstack_streaming_pump.cc b/test/cpp/microbenchmarks/bm_fullstack_streaming_pump.cc index da98f3cbcd4..d4533e6c78e 100644 --- a/test/cpp/microbenchmarks/bm_fullstack_streaming_pump.cc +++ b/test/cpp/microbenchmarks/bm_fullstack_streaming_pump.cc @@ -28,9 +28,6 @@ namespace testing { * CONFIGURATIONS */ -// force library initialization -auto& force_library_initialization = Library::get(); - BENCHMARK_TEMPLATE(BM_PumpStreamClientToServer, TCP) ->Range(0, 128 * 1024 * 1024); BENCHMARK_TEMPLATE(BM_PumpStreamClientToServer, UDS) @@ -72,6 +69,7 @@ void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } } // namespace benchmark int main(int argc, char** argv) { + LibraryInitializer libInit; ::benchmark::Initialize(&argc, argv); ::grpc::testing::InitTest(&argc, &argv, false); benchmark::RunTheBenchmarksNamespaced(); diff --git a/test/cpp/microbenchmarks/bm_fullstack_trickle.cc b/test/cpp/microbenchmarks/bm_fullstack_trickle.cc index 1af92d2c80c..2d733bcaa42 100644 --- a/test/cpp/microbenchmarks/bm_fullstack_trickle.cc +++ b/test/cpp/microbenchmarks/bm_fullstack_trickle.cc @@ -214,8 +214,8 @@ class TrickledCHTTP2 : public EndpointPairFixture { static grpc_endpoint_pair MakeEndpoints(size_t kilobits, grpc_passthru_endpoint_stats* stats) { grpc_endpoint_pair p; - grpc_passthru_endpoint_create(&p.client, &p.server, Library::get().rq(), - stats); + grpc_passthru_endpoint_create(&p.client, &p.server, + LibraryInitializer::get().rq(), stats); double bytes_per_second = 125.0 * kilobits; p.client = grpc_trickle_endpoint_create(p.client, bytes_per_second); p.server = grpc_trickle_endpoint_create(p.server, bytes_per_second); @@ -235,9 +235,6 @@ class TrickledCHTTP2 : public EndpointPairFixture { } }; -// force library initialization -auto& force_library_initialization = Library::get(); - static void TrickleCQNext(TrickledCHTTP2* fixture, void** t, bool* ok, int64_t iteration) { while (true) { @@ -465,6 +462,7 @@ void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } } // namespace benchmark int main(int argc, char** argv) { + LibraryInitializer libInit; ::benchmark::Initialize(&argc, argv); ::grpc::testing::InitTest(&argc, &argv, false); grpc_timer_manager_set_threading(false); diff --git a/test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong.cc b/test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong.cc index d4bd58b9838..3e8f9344021 100644 --- a/test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong.cc +++ b/test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong.cc @@ -24,9 +24,6 @@ namespace grpc { namespace testing { -// force library initialization -auto& force_library_initialization = Library::get(); - /******************************************************************************* * CONFIGURATIONS */ @@ -174,6 +171,7 @@ void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } } // namespace benchmark int main(int argc, char** argv) { + LibraryInitializer libInit; ::benchmark::Initialize(&argc, argv); ::grpc::testing::InitTest(&argc, &argv, false); benchmark::RunTheBenchmarksNamespaced(); diff --git a/test/cpp/microbenchmarks/bm_metadata.cc b/test/cpp/microbenchmarks/bm_metadata.cc index 553b33c4028..ff8fe541dfc 100644 --- a/test/cpp/microbenchmarks/bm_metadata.cc +++ b/test/cpp/microbenchmarks/bm_metadata.cc @@ -27,8 +27,6 @@ #include "test/cpp/microbenchmarks/helpers.h" #include "test/cpp/util/test_config.h" -auto& force_library_initialization = Library::get(); - static void BM_SliceFromStatic(benchmark::State& state) { TrackCounters track_counters; while (state.KeepRunning()) { @@ -298,6 +296,7 @@ void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } } // namespace benchmark int main(int argc, char** argv) { + LibraryInitializer libInit; ::benchmark::Initialize(&argc, argv); ::grpc::testing::InitTest(&argc, &argv, false); benchmark::RunTheBenchmarksNamespaced(); diff --git a/test/cpp/microbenchmarks/bm_opencensus_plugin.cc b/test/cpp/microbenchmarks/bm_opencensus_plugin.cc index 9d42eb891df..4f4884bef9b 100644 --- a/test/cpp/microbenchmarks/bm_opencensus_plugin.cc +++ b/test/cpp/microbenchmarks/bm_opencensus_plugin.cc @@ -23,13 +23,17 @@ #include "absl/base/call_once.h" #include "absl/strings/str_cat.h" #include "include/grpc++/grpc++.h" +#include "include/grpcpp/opencensus.h" #include "opencensus/stats/stats.h" #include "src/cpp/ext/filters/census/grpc_plugin.h" #include "src/proto/grpc/testing/echo.grpc.pb.h" #include "test/cpp/microbenchmarks/helpers.h" +using ::grpc::RegisterOpenCensusPlugin; +using ::grpc::RegisterOpenCensusViewsForExport; + absl::once_flag once; -void RegisterOnce() { absl::call_once(once, grpc::RegisterOpenCensusPlugin); } +void RegisterOnce() { absl::call_once(once, RegisterOpenCensusPlugin); } class EchoServer final : public grpc::testing::EchoTestService::Service { grpc::Status Echo(grpc::ServerContext* context, @@ -99,7 +103,7 @@ static void BM_E2eLatencyCensusEnabled(benchmark::State& state) { RegisterOnce(); // This we can safely repeat, and doing so clears accumulated data to avoid // initialization costs varying between runs. - grpc::RegisterOpenCensusViewsForExport(); + RegisterOpenCensusViewsForExport(); EchoServerThread server; std::unique_ptr stub = diff --git a/test/cpp/microbenchmarks/bm_pollset.cc b/test/cpp/microbenchmarks/bm_pollset.cc index 050c7f7c171..f8e36f178e4 100644 --- a/test/cpp/microbenchmarks/bm_pollset.cc +++ b/test/cpp/microbenchmarks/bm_pollset.cc @@ -40,8 +40,6 @@ #include #endif -auto& force_library_initialization = Library::get(); - static void shutdown_ps(void* ps, grpc_error* error) { grpc_pollset_destroy(static_cast(ps)); } @@ -264,6 +262,7 @@ void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } } // namespace benchmark int main(int argc, char** argv) { + LibraryInitializer libInit; ::benchmark::Initialize(&argc, argv); ::grpc::testing::InitTest(&argc, &argv, false); benchmark::RunTheBenchmarksNamespaced(); diff --git a/test/cpp/microbenchmarks/bm_timer.cc b/test/cpp/microbenchmarks/bm_timer.cc new file mode 100644 index 00000000000..53aaead992d --- /dev/null +++ b/test/cpp/microbenchmarks/bm_timer.cc @@ -0,0 +1,117 @@ +/* + * + * 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 +#include +#include +#include + +#include +#include +#include +#include "test/cpp/microbenchmarks/helpers.h" +#include "test/cpp/util/test_config.h" + +#include "src/core/lib/iomgr/timer.h" + +namespace grpc { +namespace testing { + +struct TimerClosure { + grpc_timer timer; + grpc_closure closure; +}; + +static void BM_InitCancelTimer(benchmark::State& state) { + constexpr int kTimerCount = 1024; + TrackCounters track_counters; + grpc_core::ExecCtx exec_ctx; + std::vector timer_closures(kTimerCount); + int i = 0; + while (state.KeepRunning()) { + TimerClosure* timer_closure = &timer_closures[i++ % kTimerCount]; + GRPC_CLOSURE_INIT(&timer_closure->closure, + [](void* /*args*/, grpc_error* /*err*/) {}, nullptr, + grpc_schedule_on_exec_ctx); + grpc_timer_init(&timer_closure->timer, GRPC_MILLIS_INF_FUTURE, + &timer_closure->closure); + grpc_timer_cancel(&timer_closure->timer); + exec_ctx.Flush(); + } + track_counters.Finish(state); +} +BENCHMARK(BM_InitCancelTimer); + +static void BM_TimerBatch(benchmark::State& state) { + constexpr int kTimerCount = 1024; + const bool check = state.range(0); + const bool reverse = state.range(1); + + const grpc_millis start = + reverse ? GRPC_MILLIS_INF_FUTURE : GRPC_MILLIS_INF_FUTURE - kTimerCount; + const grpc_millis end = + reverse ? GRPC_MILLIS_INF_FUTURE - kTimerCount : GRPC_MILLIS_INF_FUTURE; + const grpc_millis increment = reverse ? -1 : 1; + + TrackCounters track_counters; + grpc_core::ExecCtx exec_ctx; + std::vector timer_closures(kTimerCount); + while (state.KeepRunning()) { + for (grpc_millis deadline = start; deadline != end; deadline += increment) { + TimerClosure* timer_closure = &timer_closures[deadline % kTimerCount]; + GRPC_CLOSURE_INIT(&timer_closure->closure, + [](void* /*args*/, grpc_error* /*err*/) {}, nullptr, + grpc_schedule_on_exec_ctx); + + grpc_timer_init(&timer_closure->timer, deadline, &timer_closure->closure); + } + if (check) { + grpc_millis next; + grpc_timer_check(&next); + } + for (grpc_millis deadline = start; deadline != end; deadline += increment) { + TimerClosure* timer_closure = &timer_closures[deadline % kTimerCount]; + grpc_timer_cancel(&timer_closure->timer); + } + exec_ctx.Flush(); + } + track_counters.Finish(state); +} +BENCHMARK(BM_TimerBatch) + ->Args({/*check=*/false, /*reverse=*/false}) + ->Args({/*check=*/false, /*reverse=*/true}) + ->Args({/*check=*/true, /*reverse=*/false}) + ->Args({/*check=*/true, /*reverse=*/true}) + ->ThreadRange(1, 128); + +} // namespace testing +} // namespace grpc + +// 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) { + LibraryInitializer libInit; + ::benchmark::Initialize(&argc, argv); + ::grpc::testing::InitTest(&argc, &argv, false); + benchmark::RunTheBenchmarksNamespaced(); + return 0; +} diff --git a/test/cpp/microbenchmarks/callback_streaming_ping_pong.h b/test/cpp/microbenchmarks/callback_streaming_ping_pong.h new file mode 100644 index 00000000000..9fb86bd8299 --- /dev/null +++ b/test/cpp/microbenchmarks/callback_streaming_ping_pong.h @@ -0,0 +1,150 @@ +/* + * + * Copyright 2019 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 TEST_CPP_MICROBENCHMARKS_CALLBACK_STREAMING_PING_PONG_H +#define TEST_CPP_MICROBENCHMARKS_CALLBACK_STREAMING_PING_PONG_H + +#include +#include +#include "src/core/lib/profiling/timers.h" +#include "src/proto/grpc/testing/echo.grpc.pb.h" +#include "test/cpp/microbenchmarks/callback_test_service.h" +#include "test/cpp/microbenchmarks/fullstack_context_mutators.h" +#include "test/cpp/microbenchmarks/fullstack_fixtures.h" + +namespace grpc { +namespace testing { + +/******************************************************************************* + * BENCHMARKING KERNELS + */ + +class BidiClient + : public grpc::experimental::ClientBidiReactor { + public: + BidiClient(benchmark::State* state, EchoTestService::Stub* stub, + ClientContext* cli_ctx, EchoRequest* request, + EchoResponse* response) + : state_{state}, + stub_{stub}, + cli_ctx_{cli_ctx}, + request_{request}, + response_{response} { + msgs_size_ = state->range(0); + msgs_to_send_ = state->range(1); + StartNewRpc(); + } + + void OnReadDone(bool ok) override { + if (!ok) { + gpr_log(GPR_ERROR, "Client read failed"); + return; + } + MaybeWrite(); + } + + void OnWriteDone(bool ok) override { + if (!ok) { + gpr_log(GPR_ERROR, "Client write failed"); + return; + } + writes_complete_++; + StartRead(response_); + } + + void OnDone(const Status& s) override { + GPR_ASSERT(s.ok()); + GPR_ASSERT(writes_complete_ == msgs_to_send_); + if (state_->KeepRunning()) { + writes_complete_ = 0; + StartNewRpc(); + } else { + std::unique_lock l(mu); + done = true; + cv.notify_one(); + } + } + + void StartNewRpc() { + cli_ctx_->~ClientContext(); + new (cli_ctx_) ClientContext(); + cli_ctx_->AddMetadata(kServerMessageSize, grpc::to_string(msgs_size_)); + stub_->experimental_async()->BidiStream(cli_ctx_, this); + MaybeWrite(); + StartCall(); + } + + void Await() { + std::unique_lock l(mu); + while (!done) { + cv.wait(l); + } + } + + private: + void MaybeWrite() { + if (writes_complete_ < msgs_to_send_) { + StartWrite(request_); + } else { + StartWritesDone(); + } + } + + benchmark::State* state_; + EchoTestService::Stub* stub_; + ClientContext* cli_ctx_; + EchoRequest* request_; + EchoResponse* response_; + int writes_complete_{0}; + int msgs_to_send_; + int msgs_size_; + std::mutex mu; + std::condition_variable cv; + bool done; +}; + +template +static void BM_CallbackBidiStreaming(benchmark::State& state) { + int message_size = state.range(0); + int max_ping_pongs = state.range(1); + CallbackStreamingTestService service; + std::unique_ptr fixture(new Fixture(&service)); + std::unique_ptr stub_( + EchoTestService::NewStub(fixture->channel())); + EchoRequest request; + EchoResponse response; + ClientContext cli_ctx; + if (message_size > 0) { + request.set_message(std::string(message_size, 'a')); + } else { + request.set_message(""); + } + if (state.KeepRunning()) { + GPR_TIMER_SCOPE("BenchmarkCycle", 0); + BidiClient test{&state, stub_.get(), &cli_ctx, &request, &response}; + test.Await(); + } + fixture->Finish(state); + fixture.reset(); + state.SetBytesProcessed(2 * message_size * max_ping_pongs * + state.iterations()); +} + +} // namespace testing +} // namespace grpc +#endif // TEST_CPP_MICROBENCHMARKS_CALLBACK_STREAMING_PING_PONG_H diff --git a/test/cpp/microbenchmarks/callback_test_service.cc b/test/cpp/microbenchmarks/callback_test_service.cc new file mode 100644 index 00000000000..321a5b39184 --- /dev/null +++ b/test/cpp/microbenchmarks/callback_test_service.cc @@ -0,0 +1,112 @@ +/* + * + * Copyright 2019 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/cpp/microbenchmarks/callback_test_service.h" + +namespace grpc { +namespace testing { +namespace { + +grpc::string ToString(const grpc::string_ref& r) { + return grpc::string(r.data(), r.size()); +} + +int GetIntValueFromMetadataHelper( + const char* key, + const std::multimap& metadata, + int default_value) { + if (metadata.find(key) != metadata.end()) { + std::istringstream iss(ToString(metadata.find(key)->second)); + iss >> default_value; + } + + return default_value; +} + +int GetIntValueFromMetadata( + const char* key, + const std::multimap& metadata, + int default_value) { + return GetIntValueFromMetadataHelper(key, metadata, default_value); +} +} // namespace + +void CallbackStreamingTestService::Echo( + ServerContext* context, const EchoRequest* request, EchoResponse* response, + experimental::ServerCallbackRpcController* controller) { + int response_msgs_size = GetIntValueFromMetadata( + kServerMessageSize, context->client_metadata(), 0); + if (response_msgs_size > 0) { + response->set_message(std::string(response_msgs_size, 'a')); + } else { + response->set_message(""); + } + controller->Finish(Status::OK); +} + +experimental::ServerBidiReactor* +CallbackStreamingTestService::BidiStream() { + class Reactor + : public experimental::ServerBidiReactor { + public: + Reactor() {} + void OnStarted(ServerContext* context) override { + ctx_ = context; + message_size_ = GetIntValueFromMetadata(kServerMessageSize, + context->client_metadata(), 0); + StartRead(&request_); + } + void OnDone() override { + GPR_ASSERT(finished_); + delete this; + } + void OnCancel() override {} + void OnReadDone(bool ok) override { + if (!ok) { + // Stream is over + Finish(::grpc::Status::OK); + finished_ = true; + return; + } + if (message_size_ > 0) { + response_.set_message(std::string(message_size_, 'a')); + } else { + response_.set_message(""); + } + StartWrite(&response_); + } + void OnWriteDone(bool ok) override { + if (!ok) { + gpr_log(GPR_ERROR, "Server write failed"); + return; + } + StartRead(&request_); + } + + private: + ServerContext* ctx_; + EchoRequest request_; + EchoResponse response_; + int message_size_; + bool finished_{false}; + }; + + return new Reactor; +} +} // namespace testing +} // namespace grpc diff --git a/test/cpp/microbenchmarks/callback_test_service.h b/test/cpp/microbenchmarks/callback_test_service.h new file mode 100644 index 00000000000..97188595382 --- /dev/null +++ b/test/cpp/microbenchmarks/callback_test_service.h @@ -0,0 +1,48 @@ +/* + * + * Copyright 2019 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 TEST_CPP_MICROBENCHMARKS_CALLBACK_TEST_SERVICE_H +#define TEST_CPP_MICROBENCHMARKS_CALLBACK_TEST_SERVICE_H + +#include +#include +#include +#include +#include +#include "src/proto/grpc/testing/echo.grpc.pb.h" +#include "test/cpp/util/string_ref_helper.h" + +namespace grpc { +namespace testing { + +const char* const kServerMessageSize = "server_message_size"; + +class CallbackStreamingTestService + : public EchoTestService::ExperimentalCallbackService { + public: + CallbackStreamingTestService() {} + void Echo(ServerContext* context, const EchoRequest* request, + EchoResponse* response, + experimental::ServerCallbackRpcController* controller) override; + + experimental::ServerBidiReactor* BidiStream() + override; +}; +} // namespace testing +} // namespace grpc +#endif // TEST_CPP_MICROBENCHMARKS_CALLBACK_TEST_SERVICE_H diff --git a/test/cpp/microbenchmarks/callback_unary_ping_pong.h b/test/cpp/microbenchmarks/callback_unary_ping_pong.h new file mode 100644 index 00000000000..359b91eb6fe --- /dev/null +++ b/test/cpp/microbenchmarks/callback_unary_ping_pong.h @@ -0,0 +1,101 @@ +/* + * + * Copyright 2019 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. + * + */ + +/* Benchmark gRPC end2end in various configurations */ + +#ifndef TEST_CPP_MICROBENCHMARKS_CALLBACK_UNARY_PING_PONG_H +#define TEST_CPP_MICROBENCHMARKS_CALLBACK_UNARY_PING_PONG_H + +#include +#include +#include "src/core/lib/profiling/timers.h" +#include "src/proto/grpc/testing/echo.grpc.pb.h" +#include "test/cpp/microbenchmarks/callback_test_service.h" +#include "test/cpp/microbenchmarks/fullstack_context_mutators.h" +#include "test/cpp/microbenchmarks/fullstack_fixtures.h" + +namespace grpc { +namespace testing { + +/******************************************************************************* + * BENCHMARKING KERNELS + */ + +void SendCallbackUnaryPingPong(benchmark::State* state, ClientContext* cli_ctx, + EchoRequest* request, EchoResponse* response, + EchoTestService::Stub* stub_, bool* done, + std::mutex* mu, std::condition_variable* cv) { + int response_msgs_size = state->range(1); + cli_ctx->AddMetadata(kServerMessageSize, grpc::to_string(response_msgs_size)); + stub_->experimental_async()->Echo( + cli_ctx, request, response, + [state, cli_ctx, request, response, stub_, done, mu, cv](Status s) { + GPR_ASSERT(s.ok()); + if (state->KeepRunning()) { + cli_ctx->~ClientContext(); + new (cli_ctx) ClientContext(); + SendCallbackUnaryPingPong(state, cli_ctx, request, response, stub_, + done, mu, cv); + } else { + std::lock_guard l(*mu); + *done = true; + cv->notify_one(); + } + }); +}; + +template +static void BM_CallbackUnaryPingPong(benchmark::State& state) { + int request_msgs_size = state.range(0); + int response_msgs_size = state.range(1); + CallbackStreamingTestService service; + std::unique_ptr fixture(new Fixture(&service)); + std::unique_ptr stub_( + EchoTestService::NewStub(fixture->channel())); + EchoRequest request; + EchoResponse response; + ClientContext cli_ctx; + + if (request_msgs_size > 0) { + request.set_message(std::string(request_msgs_size, 'a')); + } else { + request.set_message(""); + } + + std::mutex mu; + std::condition_variable cv; + bool done = false; + if (state.KeepRunning()) { + GPR_TIMER_SCOPE("BenchmarkCycle", 0); + SendCallbackUnaryPingPong(&state, &cli_ctx, &request, &response, + stub_.get(), &done, &mu, &cv); + } + std::unique_lock l(mu); + while (!done) { + cv.wait(l); + } + fixture->Finish(state); + fixture.reset(); + state.SetBytesProcessed(request_msgs_size * state.iterations() + + response_msgs_size * state.iterations()); +} + +} // namespace testing +} // namespace grpc + +#endif // TEST_CPP_MICROBENCHMARKS_FULLSTACK_UNARY_PING_PONG_H diff --git a/test/cpp/microbenchmarks/fullstack_fixtures.h b/test/cpp/microbenchmarks/fullstack_fixtures.h index 71e8d9972bf..4d60e97d5f6 100644 --- a/test/cpp/microbenchmarks/fullstack_fixtures.h +++ b/test/cpp/microbenchmarks/fullstack_fixtures.h @@ -86,8 +86,8 @@ class FullstackFixture : public BaseFixture { ChannelArguments args; config.ApplyCommonChannelArguments(&args); if (address.length() > 0) { - channel_ = - CreateCustomChannel(address, InsecureChannelCredentials(), args); + channel_ = ::grpc::CreateCustomChannel( + address, InsecureChannelCredentials(), args); } else { channel_ = server_->InProcessChannel(args); } @@ -200,7 +200,7 @@ class EndpointPairFixture : public BaseFixture { } grpc_server_setup_transport(server_->c_server(), server_transport_, - nullptr, server_args, 0); + nullptr, server_args, nullptr); grpc_chttp2_transport_start_reading(server_transport_, nullptr, nullptr); } @@ -218,7 +218,7 @@ class EndpointPairFixture : public BaseFixture { "target", &c_args, GRPC_CLIENT_DIRECT_CHANNEL, client_transport_); grpc_chttp2_transport_start_reading(client_transport_, nullptr, nullptr); - channel_ = CreateChannelInternal( + channel_ = ::grpc::CreateChannelInternal( "", channel, std::vector>()); @@ -299,8 +299,8 @@ class InProcessCHTTP2WithExplicitStats : public EndpointPairFixture { static grpc_endpoint_pair MakeEndpoints(grpc_passthru_endpoint_stats* stats) { grpc_endpoint_pair p; - grpc_passthru_endpoint_create(&p.client, &p.server, Library::get().rq(), - stats); + grpc_passthru_endpoint_create(&p.client, &p.server, + LibraryInitializer::get().rq(), stats); return p; } }; diff --git a/test/cpp/microbenchmarks/helpers.cc b/test/cpp/microbenchmarks/helpers.cc index bce72985dc2..7d78e21aef7 100644 --- a/test/cpp/microbenchmarks/helpers.cc +++ b/test/cpp/microbenchmarks/helpers.cc @@ -20,6 +20,32 @@ #include "test/cpp/microbenchmarks/helpers.h" +static grpc::internal::GrpcLibraryInitializer g_gli_initializer; +static LibraryInitializer* g_libraryInitializer; + +LibraryInitializer::LibraryInitializer() { + GPR_ASSERT(g_libraryInitializer == nullptr); + g_libraryInitializer = this; + + g_gli_initializer.summon(); +#ifdef GPR_LOW_LEVEL_COUNTERS + grpc_memory_counters_init(); +#endif + init_lib_.init(); + rq_ = grpc_resource_quota_create("bm"); +} + +LibraryInitializer::~LibraryInitializer() { + g_libraryInitializer = nullptr; + init_lib_.shutdown(); + grpc_resource_quota_unref(rq_); +} + +LibraryInitializer& LibraryInitializer::get() { + GPR_ASSERT(g_libraryInitializer != nullptr); + return *g_libraryInitializer; +} + void TrackCounters::Finish(benchmark::State& state) { std::ostringstream out; for (const auto& l : labels_) { diff --git a/test/cpp/microbenchmarks/helpers.h b/test/cpp/microbenchmarks/helpers.h index 25d34b5f871..b712c85d354 100644 --- a/test/cpp/microbenchmarks/helpers.h +++ b/test/cpp/microbenchmarks/helpers.h @@ -29,26 +29,16 @@ #include #include -class Library { +class LibraryInitializer { public: - static Library& get() { - static Library lib; - return lib; - } + LibraryInitializer(); + ~LibraryInitializer(); grpc_resource_quota* rq() { return rq_; } + static LibraryInitializer& get(); + private: - Library() { -#ifdef GPR_LOW_LEVEL_COUNTERS - grpc_memory_counters_init(); -#endif - init_lib_.init(); - rq_ = grpc_resource_quota_create("bm"); - } - - ~Library() { init_lib_.shutdown(); } - grpc::internal::GrpcLibrary init_lib_; grpc_resource_quota* rq_; }; diff --git a/test/cpp/naming/BUILD b/test/cpp/naming/BUILD index 2925e8fbcfb..7db435a3fd4 100644 --- a/test/cpp/naming/BUILD +++ b/test/cpp/naming/BUILD @@ -22,17 +22,16 @@ package( licenses(["notice"]) # Apache v2 -load("//bazel:grpc_build_system.bzl", "grpc_py_binary", "grpc_cc_test") - +load("//bazel:grpc_build_system.bzl", "grpc_py_binary", "grpc_cc_test", "grpc_cc_library") load(":generate_resolver_component_tests.bzl", "generate_resolver_component_tests") # Meant to be invoked only through the top-level shell script driver. grpc_py_binary( name = "resolver_component_tests_runner", + testonly = True, srcs = [ "resolver_component_tests_runner.py", ], - testonly = True, ) grpc_cc_test( @@ -40,14 +39,24 @@ grpc_cc_test( srcs = ["cancel_ares_query_test.cc"], external_deps = ["gmock"], deps = [ - "//test/cpp/util:test_util", - "//test/core/util:grpc_test_util", - "//test/core/util:gpr_test_util", - "//:grpc++", - "//:grpc", + ":dns_test_util", "//:gpr", - "//test/cpp/util:test_config", + "//:grpc", + "//:grpc++", "//test/core/end2end:cq_verifier", + "//test/core/util:grpc_test_util", + "//test/cpp/util:test_config", + "//test/cpp/util:test_util", + ], +) + +grpc_cc_library( + name = "dns_test_util", + hdrs = ["dns_test_util.h"], + srcs = ["dns_test_util.cc"], + deps = [ + "//:gpr", + "//:grpc", ], ) diff --git a/test/cpp/naming/address_sorting_test.cc b/test/cpp/naming/address_sorting_test.cc index fc6721d0ba8..bd685632c33 100644 --- a/test/cpp/naming/address_sorting_test.cc +++ b/test/cpp/naming/address_sorting_test.cc @@ -37,6 +37,7 @@ #include "src/core/ext/filters/client_channel/resolver.h" #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" #include "src/core/ext/filters/client_channel/resolver_registry.h" +#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/host_port.h" @@ -51,6 +52,7 @@ #ifndef GPR_WINDOWS #include +#include #include #endif @@ -167,30 +169,26 @@ void OverrideAddressSortingSourceAddrFactory( address_sorting_override_source_addr_factory_for_testing(factory); } -grpc_lb_addresses* BuildLbAddrInputs(std::vector test_addrs) { - grpc_lb_addresses* lb_addrs = grpc_lb_addresses_create(0, nullptr); - lb_addrs->addresses = - (grpc_lb_address*)gpr_zalloc(sizeof(grpc_lb_address) * test_addrs.size()); - lb_addrs->num_addresses = test_addrs.size(); - for (size_t i = 0; i < test_addrs.size(); i++) { - lb_addrs->addresses[i].address = - TestAddressToGrpcResolvedAddress(test_addrs[i]); +grpc_core::ServerAddressList BuildLbAddrInputs( + const std::vector& test_addrs) { + grpc_core::ServerAddressList addresses; + for (const auto& addr : test_addrs) { + addresses.emplace_back(TestAddressToGrpcResolvedAddress(addr), nullptr); } - return lb_addrs; + return addresses; } -void VerifyLbAddrOutputs(grpc_lb_addresses* lb_addrs, +void VerifyLbAddrOutputs(const grpc_core::ServerAddressList addresses, std::vector expected_addrs) { - EXPECT_EQ(lb_addrs->num_addresses, expected_addrs.size()); - for (size_t i = 0; i < lb_addrs->num_addresses; i++) { + EXPECT_EQ(addresses.size(), expected_addrs.size()); + for (size_t i = 0; i < addresses.size(); ++i) { char* ip_addr_str; - grpc_sockaddr_to_string(&ip_addr_str, &lb_addrs->addresses[i].address, + grpc_sockaddr_to_string(&ip_addr_str, &addresses[i].address(), false /* normalize */); EXPECT_EQ(expected_addrs[i], ip_addr_str); gpr_free(ip_addr_str); } grpc_core::ExecCtx exec_ctx; - grpc_lb_addresses_destroy(lb_addrs); } /* We need to run each test case inside of its own @@ -200,7 +198,7 @@ void VerifyLbAddrOutputs(grpc_lb_addresses* lb_addrs, class AddressSortingTest : public ::testing::Test { protected: void SetUp() override { grpc_init(); } - void TearDown() override { grpc_shutdown(); } + void TearDown() override { grpc_shutdown_blocking(); } }; /* Tests for rule 1 */ @@ -212,11 +210,11 @@ TEST_F(AddressSortingTest, TestDepriotizesUnreachableAddresses) { { {"1.2.3.4:443", {"4.3.2.1:443", AF_INET}}, }); - auto* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"1.2.3.4:443", AF_INET}, {"5.6.7.8:443", AF_INET}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "1.2.3.4:443", "5.6.7.8:443", @@ -235,7 +233,7 @@ TEST_F(AddressSortingTest, TestDepriotizesUnsupportedDomainIpv6) { {"[2607:f8b0:400a:801::1002]:443", AF_INET6}, {"1.2.3.4:443", AF_INET}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "1.2.3.4:443", "[2607:f8b0:400a:801::1002]:443", @@ -251,11 +249,11 @@ TEST_F(AddressSortingTest, TestDepriotizesUnsupportedDomainIpv4) { {"1.2.3.4:443", {"4.3.2.1:0", AF_INET}}, {"[2607:f8b0:400a:801::1002]:443", {"[fec0::1234]:0", AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[2607:f8b0:400a:801::1002]:443", AF_INET6}, {"1.2.3.4:443", AF_INET}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[2607:f8b0:400a:801::1002]:443", "1.2.3.4:443", @@ -275,11 +273,11 @@ TEST_F(AddressSortingTest, TestDepriotizesNonMatchingScope) { {"[fec0::5000]:443", {"[fec0::5001]:0", AF_INET6}}, // site-local and site-local scope }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[2000:f8b0:400a:801::1002]:443", AF_INET6}, {"[fec0::5000]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[fec0::5000]:443", "[2000:f8b0:400a:801::1002]:443", @@ -298,11 +296,11 @@ TEST_F(AddressSortingTest, TestUsesLabelFromDefaultTable) { {"[2001::5001]:443", {"[2001::5002]:0", AF_INET6}}, // matching labels }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[2002::5001]:443", AF_INET6}, {"[2001::5001]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[2001::5001]:443", "[2002::5001]:443", @@ -321,11 +319,11 @@ TEST_F(AddressSortingTest, TestUsesLabelFromDefaultTableInputFlipped) { {"[2001::5001]:443", {"[2001::5002]:0", AF_INET6}}, // matching labels }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[2001::5001]:443", AF_INET6}, {"[2002::5001]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[2001::5001]:443", "[2002::5001]:443", @@ -344,11 +342,11 @@ TEST_F(AddressSortingTest, {"[3ffe::5001]:443", {"[3ffe::5002]:0", AF_INET6}}, {"1.2.3.4:443", {"5.6.7.8:0", AF_INET}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[3ffe::5001]:443", AF_INET6}, {"1.2.3.4:443", AF_INET}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs( lb_addrs, { // The AF_INET address should be IPv4-mapped by the sort, @@ -377,11 +375,11 @@ TEST_F(AddressSortingTest, {"[::1]:443", {"[::1]:0", AF_INET6}}, {v4_compat_dest, {v4_compat_src, AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {v4_compat_dest, AF_INET6}, {"[::1]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[::1]:443", v4_compat_dest, @@ -400,11 +398,11 @@ TEST_F(AddressSortingTest, {"[1234::2]:443", {"[1234::2]:0", AF_INET6}}, {"[::1]:443", {"[::1]:0", AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[1234::2]:443", AF_INET6}, {"[::1]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs( lb_addrs, { @@ -424,11 +422,11 @@ TEST_F(AddressSortingTest, {"[2001::1234]:443", {"[2001::5678]:0", AF_INET6}}, {"[2000::5001]:443", {"[2000::5002]:0", AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[2001::1234]:443", AF_INET6}, {"[2000::5001]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs( lb_addrs, { // The 2000::/16 address should match the ::/0 prefix rule @@ -448,11 +446,11 @@ TEST_F( {"[2001::1231]:443", {"[2001::1232]:0", AF_INET6}}, {"[2000::5001]:443", {"[2000::5002]:0", AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[2001::1231]:443", AF_INET6}, {"[2000::5001]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[2000::5001]:443", "[2001::1231]:443", @@ -469,11 +467,11 @@ TEST_F(AddressSortingTest, {"[fec0::1234]:443", {"[fec0::5678]:0", AF_INET6}}, {"[fc00::5001]:443", {"[fc00::5002]:0", AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[fec0::1234]:443", AF_INET6}, {"[fc00::5001]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[fc00::5001]:443", "[fec0::1234]:443", @@ -494,11 +492,11 @@ TEST_F( {"[::ffff:1.1.1.2]:443", {"[::ffff:1.1.1.3]:0", AF_INET6}}, {"[1234::2]:443", {"[1234::3]:0", AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[::ffff:1.1.1.2]:443", AF_INET6}, {"[1234::2]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { // ::ffff:0:2 should match the v4-mapped // precedence entry and be deprioritized. @@ -521,11 +519,11 @@ TEST_F(AddressSortingTest, TestPrefersSmallerScope) { {"[fec0::1234]:443", {"[fec0::5678]:0", AF_INET6}}, {"[3ffe::5001]:443", {"[3ffe::5002]:0", AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[3ffe::5001]:443", AF_INET6}, {"[fec0::1234]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[fec0::1234]:443", "[3ffe::5001]:443", @@ -546,11 +544,11 @@ TEST_F(AddressSortingTest, TestPrefersLongestMatchingSrcDstPrefix) { {"[3ffe:1234::]:443", {"[3ffe:1235::]:0", AF_INET6}}, {"[3ffe:5001::]:443", {"[3ffe:4321::]:0", AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[3ffe:5001::]:443", AF_INET6}, {"[3ffe:1234::]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[3ffe:1234::]:443", "[3ffe:5001::]:443", @@ -567,11 +565,11 @@ TEST_F(AddressSortingTest, {"[3ffe::1234]:443", {"[3ffe::1235]:0", AF_INET6}}, {"[3ffe::5001]:443", {"[3ffe::4321]:0", AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[3ffe::5001]:443", AF_INET6}, {"[3ffe::1234]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[3ffe::1234]:443", "[3ffe::5001]:443", @@ -587,11 +585,11 @@ TEST_F(AddressSortingTest, TestPrefersLongestPrefixStressInnerBytePrefix) { {"[3ffe:8000::]:443", {"[3ffe:C000::]:0", AF_INET6}}, {"[3ffe:2000::]:443", {"[3ffe:3000::]:0", AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[3ffe:8000::]:443", AF_INET6}, {"[3ffe:2000::]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[3ffe:2000::]:443", "[3ffe:8000::]:443", @@ -607,11 +605,11 @@ TEST_F(AddressSortingTest, TestPrefersLongestPrefixDiffersOnHighestBitOfByte) { {"[3ffe:6::]:443", {"[3ffe:8::]:0", AF_INET6}}, {"[3ffe:c::]:443", {"[3ffe:8::]:0", AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[3ffe:6::]:443", AF_INET6}, {"[3ffe:c::]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[3ffe:c::]:443", "[3ffe:6::]:443", @@ -629,11 +627,11 @@ TEST_F(AddressSortingTest, TestPrefersLongestPrefixDiffersByLastBit) { {"[3ffe:1111:1111:1110::]:443", {"[3ffe:1111:1111:1111::]:0", AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[3ffe:1111:1111:1110::]:443", AF_INET6}, {"[3ffe:1111:1111:1111::]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[3ffe:1111:1111:1111::]:443", "[3ffe:1111:1111:1110::]:443", @@ -651,11 +649,11 @@ TEST_F(AddressSortingTest, TestStableSort) { {"[3ffe::1234]:443", {"[3ffe::1236]:0", AF_INET6}}, {"[3ffe::1235]:443", {"[3ffe::1237]:0", AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[3ffe::1234]:443", AF_INET6}, {"[3ffe::1235]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[3ffe::1234]:443", "[3ffe::1235]:443", @@ -674,14 +672,14 @@ TEST_F(AddressSortingTest, TestStableSortFiveElements) { {"[3ffe::1234]:443", {"[3ffe::1204]:0", AF_INET6}}, {"[3ffe::1235]:443", {"[3ffe::1205]:0", AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[3ffe::1231]:443", AF_INET6}, {"[3ffe::1232]:443", AF_INET6}, {"[3ffe::1233]:443", AF_INET6}, {"[3ffe::1234]:443", AF_INET6}, {"[3ffe::1235]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[3ffe::1231]:443", "[3ffe::1232]:443", @@ -695,14 +693,14 @@ TEST_F(AddressSortingTest, TestStableSortNoSrcAddrsExist) { bool ipv4_supported = true; bool ipv6_supported = true; OverrideAddressSortingSourceAddrFactory(ipv4_supported, ipv6_supported, {}); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[3ffe::1231]:443", AF_INET6}, {"[3ffe::1232]:443", AF_INET6}, {"[3ffe::1233]:443", AF_INET6}, {"[3ffe::1234]:443", AF_INET6}, {"[3ffe::1235]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[3ffe::1231]:443", "[3ffe::1232]:443", @@ -716,11 +714,11 @@ TEST_F(AddressSortingTest, TestStableSortNoSrcAddrsExistWithIpv4) { bool ipv4_supported = true; bool ipv6_supported = true; OverrideAddressSortingSourceAddrFactory(ipv4_supported, ipv6_supported, {}); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[::ffff:5.6.7.8]:443", AF_INET6}, {"1.2.3.4:443", AF_INET}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[::ffff:5.6.7.8]:443", "1.2.3.4:443", @@ -744,11 +742,11 @@ TEST_F(AddressSortingTest, TestStableSortV4CompatAndSiteLocalAddresses) { {"[fec0::2000]:443", {"[fec0::2001]:0", AF_INET6}}, {v4_compat_dest, {v4_compat_src, AF_INET6}}, }); - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[fec0::2000]:443", AF_INET6}, {v4_compat_dest, AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { // The sort should be stable since @@ -765,11 +763,11 @@ TEST_F(AddressSortingTest, TestStableSortV4CompatAndSiteLocalAddresses) { * (whether ipv4 loopback is available or not, an available ipv6 * loopback should be preferred). */ TEST_F(AddressSortingTest, TestPrefersIpv6Loopback) { - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"[::1]:443", AF_INET6}, {"127.0.0.1:443", AF_INET}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[::1]:443", "127.0.0.1:443", @@ -779,11 +777,11 @@ TEST_F(AddressSortingTest, TestPrefersIpv6Loopback) { /* Flip the order of the inputs above and expect the same output order * (try to rule out influence of arbitrary qsort ordering) */ TEST_F(AddressSortingTest, TestPrefersIpv6LoopbackInputsFlipped) { - grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({ + auto lb_addrs = BuildLbAddrInputs({ {"127.0.0.1:443", AF_INET}, {"[::1]:443", AF_INET6}, }); - grpc_cares_wrapper_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(&lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[::1]:443", "127.0.0.1:443", @@ -793,7 +791,7 @@ TEST_F(AddressSortingTest, TestPrefersIpv6LoopbackInputsFlipped) { /* Try to rule out false positives in the above two tests in which * the sorter might think that neither ipv6 or ipv4 loopback is * available, but ipv6 loopback is still preferred only due - * to precedance table lookups. */ + * to precedence table lookups. */ TEST_F(AddressSortingTest, TestSorterKnowsIpv6LoopbackIsAvailable) { sockaddr_in6 ipv6_loopback; memset(&ipv6_loopback, 0, sizeof(ipv6_loopback)); @@ -838,7 +836,7 @@ int main(int argc, char** argv) { gpr_log(GPR_INFO, "GRPC_DNS_RESOLVER != ares: %s.", resolver); } gpr_free(resolver); - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); auto result = RUN_ALL_TESTS(); // Test sequential and nested inits and shutdowns. diff --git a/test/cpp/naming/cancel_ares_query_test.cc b/test/cpp/naming/cancel_ares_query_test.cc index dec7c171dc0..674e72fdc52 100644 --- a/test/cpp/naming/cancel_ares_query_test.cc +++ b/test/cpp/naming/cancel_ares_query_test.cc @@ -44,6 +44,7 @@ #include "test/core/util/cmdline.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" +#include "test/cpp/naming/dns_test_util.h" #ifdef GPR_WINDOWS #include "src/core/lib/iomgr/sockaddr_windows.h" @@ -76,36 +77,6 @@ void EndTest(grpc_channel* client, grpc_completion_queue* cq) { grpc_completion_queue_destroy(cq); } -class FakeNonResponsiveDNSServer { - public: - FakeNonResponsiveDNSServer(int port) { - socket_ = socket(AF_INET6, SOCK_DGRAM, 0); - if (socket_ == BAD_SOCKET_RETURN_VAL) { - gpr_log(GPR_DEBUG, "Failed to create UDP ipv6 socket"); - abort(); - } - sockaddr_in6 addr; - memset(&addr, 0, sizeof(addr)); - addr.sin6_family = AF_INET6; - addr.sin6_port = htons(port); - ((char*)&addr.sin6_addr)[15] = 1; - if (bind(socket_, (const sockaddr*)&addr, sizeof(addr)) != 0) { - gpr_log(GPR_DEBUG, "Failed to bind UDP ipv6 socket to [::1]:%d", port); - abort(); - } - } - ~FakeNonResponsiveDNSServer() { -#ifdef GPR_WINDOWS - closesocket(socket_); -#else - close(socket_); -#endif - } - - private: - int socket_; -}; - struct ArgsStruct { gpr_atm done_atm; gpr_mu* mu; @@ -160,18 +131,31 @@ void PollPollsetUntilRequestDone(ArgsStruct* args) { } } -void CheckResolverResultAssertFailureLocked(void* arg, grpc_error* error) { - EXPECT_NE(error, GRPC_ERROR_NONE); - ArgsStruct* args = static_cast(arg); - gpr_atm_rel_store(&args->done_atm, 1); - gpr_mu_lock(args->mu); - GRPC_LOG_IF_ERROR("pollset_kick", grpc_pollset_kick(args->pollset, nullptr)); - gpr_mu_unlock(args->mu); -} +class AssertFailureResultHandler : public grpc_core::Resolver::ResultHandler { + public: + explicit AssertFailureResultHandler(ArgsStruct* args) : args_(args) {} + + ~AssertFailureResultHandler() override { + gpr_atm_rel_store(&args_->done_atm, 1); + gpr_mu_lock(args_->mu); + GRPC_LOG_IF_ERROR("pollset_kick", + grpc_pollset_kick(args_->pollset, nullptr)); + gpr_mu_unlock(args_->mu); + } + + void ReturnResult(grpc_core::Resolver::Result result) override { + GPR_ASSERT(false); + } + + void ReturnError(grpc_error* error) override { GPR_ASSERT(false); } + + private: + ArgsStruct* args_; +}; void TestCancelActiveDNSQuery(ArgsStruct* args) { int fake_dns_port = grpc_pick_unused_port_or_die(); - FakeNonResponsiveDNSServer fake_dns_server(fake_dns_port); + grpc::testing::FakeNonResponsiveDNSServer fake_dns_server(fake_dns_port); char* client_target; GPR_ASSERT(gpr_asprintf( &client_target, @@ -180,13 +164,11 @@ void TestCancelActiveDNSQuery(ArgsStruct* args) { // create resolver and resolve grpc_core::OrphanablePtr resolver = grpc_core::ResolverRegistry::CreateResolver( - client_target, nullptr, args->pollset_set, args->lock); + client_target, nullptr, args->pollset_set, args->lock, + grpc_core::UniquePtr( + grpc_core::New(args))); gpr_free(client_target); - grpc_closure on_resolver_result_changed; - GRPC_CLOSURE_INIT(&on_resolver_result_changed, - CheckResolverResultAssertFailureLocked, (void*)args, - grpc_combiner_scheduler(args->lock)); - resolver->NextLocked(&args->channel_args, &on_resolver_result_changed); + resolver->StartLocked(); // Without resetting and causing resolver shutdown, the // PollPollsetUntilRequestDone call should never finish. resolver.reset(); @@ -260,20 +242,51 @@ TEST(CancelDuringAresQuery, TestFdsAreDeletedFromPollsetSet) { grpc_pollset_set_destroy(fake_other_pollset_set); } -TEST(CancelDuringAresQuery, - TestHitDeadlineAndDestroyChannelDuringAresResolutionIsGraceful) { +// Settings for TestCancelDuringActiveQuery test +typedef enum { + NONE, + SHORT, + ZERO, +} cancellation_test_query_timeout_setting; + +void TestCancelDuringActiveQuery( + cancellation_test_query_timeout_setting query_timeout_setting) { // Start up fake non responsive DNS server int fake_dns_port = grpc_pick_unused_port_or_die(); - FakeNonResponsiveDNSServer fake_dns_server(fake_dns_port); + grpc::testing::FakeNonResponsiveDNSServer fake_dns_server(fake_dns_port); // Create a call that will try to use the fake DNS server char* client_target = nullptr; GPR_ASSERT(gpr_asprintf( &client_target, "dns://[::1]:%d/dont-care-since-wont-be-resolved.test.com:1234", fake_dns_port)); + gpr_log(GPR_DEBUG, "TestCancelActiveDNSQuery. query timeout setting: %d", + query_timeout_setting); + grpc_channel_args* client_args = nullptr; + grpc_status_code expected_status_code = GRPC_STATUS_OK; + if (query_timeout_setting == NONE) { + expected_status_code = GRPC_STATUS_DEADLINE_EXCEEDED; + client_args = nullptr; + } else if (query_timeout_setting == SHORT) { + expected_status_code = GRPC_STATUS_UNAVAILABLE; + grpc_arg arg; + arg.type = GRPC_ARG_INTEGER; + arg.key = const_cast(GRPC_ARG_DNS_ARES_QUERY_TIMEOUT_MS); + arg.value.integer = + 1; // Set this shorter than the call deadline so that it goes off. + client_args = grpc_channel_args_copy_and_add(nullptr, &arg, 1); + } else if (query_timeout_setting == ZERO) { + expected_status_code = GRPC_STATUS_DEADLINE_EXCEEDED; + grpc_arg arg; + arg.type = GRPC_ARG_INTEGER; + arg.key = const_cast(GRPC_ARG_DNS_ARES_QUERY_TIMEOUT_MS); + arg.value.integer = 0; // Set this to zero to disable query timeouts. + client_args = grpc_channel_args_copy_and_add(nullptr, &arg, 1); + } else { + abort(); + } grpc_channel* client = - grpc_insecure_channel_create(client_target, - /* client_args */ nullptr, nullptr); + grpc_insecure_channel_create(client_target, client_args, nullptr); gpr_free(client_target); grpc_completion_queue* cq = grpc_completion_queue_create_for_next(nullptr); cq_verifier* cqv = cq_verifier_create(cq); @@ -325,8 +338,9 @@ TEST(CancelDuringAresQuery, EXPECT_EQ(GRPC_CALL_OK, error); CQ_EXPECT_COMPLETION(cqv, Tag(1), 1); cq_verify(cqv); - EXPECT_EQ(status, GRPC_STATUS_DEADLINE_EXCEEDED); + EXPECT_EQ(status, expected_status_code); // Teardown + grpc_channel_args_destroy(client_args); grpc_slice_unref(details); gpr_free((void*)error_string); grpc_metadata_array_destroy(&initial_metadata_recv); @@ -338,10 +352,27 @@ TEST(CancelDuringAresQuery, EndTest(client, cq); } +TEST(CancelDuringAresQuery, + TestHitDeadlineAndDestroyChannelDuringAresResolutionIsGraceful) { + TestCancelDuringActiveQuery(NONE /* don't set query timeouts */); +} + +TEST( + CancelDuringAresQuery, + TestHitDeadlineAndDestroyChannelDuringAresResolutionWithQueryTimeoutIsGraceful) { + TestCancelDuringActiveQuery(SHORT /* set short query timeout */); +} + +TEST( + CancelDuringAresQuery, + TestHitDeadlineAndDestroyChannelDuringAresResolutionWithZeroQueryTimeoutIsGraceful) { + TestCancelDuringActiveQuery(ZERO /* disable query timeouts */); +} + } // namespace int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); gpr_setenv("GRPC_DNS_RESOLVER", "ares"); // Sanity check the time that it takes to run the test diff --git a/test/cpp/naming/dns_test_util.cc b/test/cpp/naming/dns_test_util.cc new file mode 100644 index 00000000000..1380d0ab423 --- /dev/null +++ b/test/cpp/naming/dns_test_util.cc @@ -0,0 +1,97 @@ +/* + * + * 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 +#include + +#include +#include + +#include "test/cpp/naming/dns_test_util.h" + +#ifdef GPR_WINDOWS +#include "src/core/lib/iomgr/sockaddr_windows.h" +#include "src/core/lib/iomgr/socket_windows.h" +#define BAD_SOCKET_RETURN_VAL INVALID_SOCKET +#else +#include "src/core/lib/iomgr/sockaddr_posix.h" +#define BAD_SOCKET_RETURN_VAL -1 +#endif + +namespace grpc { +namespace testing { + +FakeNonResponsiveDNSServer::FakeNonResponsiveDNSServer(int port) { + udp_socket_ = socket(AF_INET6, SOCK_DGRAM, 0); + tcp_socket_ = socket(AF_INET6, SOCK_STREAM, 0); + if (udp_socket_ == BAD_SOCKET_RETURN_VAL) { + gpr_log(GPR_DEBUG, "Failed to create UDP ipv6 socket"); + abort(); + } + if (tcp_socket_ == BAD_SOCKET_RETURN_VAL) { + gpr_log(GPR_DEBUG, "Failed to create TCP ipv6 socket"); + abort(); + } + sockaddr_in6 addr; + memset(&addr, 0, sizeof(addr)); + addr.sin6_family = AF_INET6; + addr.sin6_port = htons(port); + ((char*)&addr.sin6_addr)[15] = 1; + if (bind(udp_socket_, (const sockaddr*)&addr, sizeof(addr)) != 0) { + gpr_log(GPR_DEBUG, "Failed to bind UDP ipv6 socket to [::1]:%d", port); + abort(); + } +#ifdef GPR_WINDOWS + char val = 1; + if (setsockopt(tcp_socket_, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) == + SOCKET_ERROR) { + gpr_log(GPR_DEBUG, + "Failed to set SO_REUSEADDR on TCP ipv6 socket to [::1]:%d", port); + abort(); + } +#else + int val = 1; + if (setsockopt(tcp_socket_, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) != + 0) { + gpr_log(GPR_DEBUG, + "Failed to set SO_REUSEADDR on TCP ipv6 socket to [::1]:%d", port); + abort(); + } +#endif + if (bind(tcp_socket_, (const sockaddr*)&addr, sizeof(addr)) != 0) { + gpr_log(GPR_DEBUG, "Failed to bind TCP ipv6 socket to [::1]:%d", port); + abort(); + } + if (listen(tcp_socket_, 100)) { + gpr_log(GPR_DEBUG, "Failed to listen on TCP ipv6 socket to [::1]:%d", port); + abort(); + } +} + +FakeNonResponsiveDNSServer::~FakeNonResponsiveDNSServer() { +#ifdef GPR_WINDOWS + closesocket(udp_socket_); + closesocket(tcp_socket_); +#else + close(udp_socket_); + close(tcp_socket_); +#endif +} + +} // namespace testing +} // namespace grpc diff --git a/test/cpp/naming/dns_test_util.h b/test/cpp/naming/dns_test_util.h new file mode 100644 index 00000000000..d5e50992672 --- /dev/null +++ b/test/cpp/naming/dns_test_util.h @@ -0,0 +1,38 @@ +/* + * + * 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 GRPC_DNS_TEST_UTIL_H +#define GRPC_DNS_TEST_UTIL_H + +namespace grpc { +namespace testing { + +class FakeNonResponsiveDNSServer { + public: + explicit FakeNonResponsiveDNSServer(int port); + virtual ~FakeNonResponsiveDNSServer(); + + private: + int udp_socket_; + int tcp_socket_; +}; + +} // namespace testing +} // namespace grpc + +#endif /* GRPC_DNS_TEST_UTIL_H */ diff --git a/test/cpp/naming/gen_build_yaml.py b/test/cpp/naming/gen_build_yaml.py index 1c9d0676b89..7cbf9163700 100755 --- a/test/cpp/naming/gen_build_yaml.py +++ b/test/cpp/naming/gen_build_yaml.py @@ -47,7 +47,11 @@ def _resolver_test_cases(resolver_component_data): _build_expected_addrs_cmd_arg(test_case['expected_addrs'])), ('expected_chosen_service_config', (test_case['expected_chosen_service_config'] or '')), + ('expected_service_config_error', (test_case['expected_service_config_error'] or '')), ('expected_lb_policy', (test_case['expected_lb_policy'] or '')), + ('enable_srv_queries', test_case['enable_srv_queries']), + ('enable_txt_queries', test_case['enable_txt_queries']), + ('inject_broken_nameserver_list', test_case['inject_broken_nameserver_list']), ], }) return out @@ -70,9 +74,9 @@ def main(): 'src': ['test/cpp/naming/resolver_component_test.cc'], 'platforms': ['linux', 'posix', 'mac', 'windows'], 'deps': [ + 'dns_test_util', 'grpc++_test_util' + unsecure_build_config_suffix, 'grpc_test_util' + unsecure_build_config_suffix, - 'gpr_test_util', 'grpc++' + unsecure_build_config_suffix, 'grpc' + unsecure_build_config_suffix, 'gpr', @@ -91,7 +95,6 @@ def main(): 'deps': [ 'grpc++_test_util', 'grpc_test_util', - 'gpr_test_util', 'grpc++', 'grpc', 'gpr', @@ -114,7 +117,6 @@ def main(): 'deps': [ 'grpc++_test_util' + unsecure_build_config_suffix, 'grpc_test_util' + unsecure_build_config_suffix, - 'gpr_test_util', 'grpc++' + unsecure_build_config_suffix, 'grpc' + unsecure_build_config_suffix, 'gpr', @@ -131,9 +133,9 @@ def main(): 'src': ['test/cpp/naming/cancel_ares_query_test.cc'], 'platforms': ['linux', 'posix', 'mac', 'windows'], 'deps': [ + 'dns_test_util', 'grpc++_test_util', 'grpc_test_util', - 'gpr_test_util', 'grpc++', 'grpc', 'gpr', diff --git a/test/cpp/naming/generate_resolver_component_tests.bzl b/test/cpp/naming/generate_resolver_component_tests.bzl index 5e9aa63abe0..bcc62f62871 100755 --- a/test/cpp/naming/generate_resolver_component_tests.bzl +++ b/test/cpp/naming/generate_resolver_component_tests.bzl @@ -28,12 +28,12 @@ def generate_resolver_component_tests(): deps = [ "//test/cpp/util:test_util%s" % unsecure_build_config_suffix, "//test/core/util:grpc_test_util%s" % unsecure_build_config_suffix, - "//test/core/util:gpr_test_util", "//:grpc++%s" % unsecure_build_config_suffix, "//:grpc%s" % unsecure_build_config_suffix, "//:gpr", "//test/cpp/util:test_config", ], + tags = ["no_windows"], ) # meant to be invoked only through the top-level shell script driver grpc_cc_binary( @@ -46,14 +46,15 @@ def generate_resolver_component_tests(): "gmock", ], deps = [ + ":dns_test_util", "//test/cpp/util:test_util%s" % unsecure_build_config_suffix, "//test/core/util:grpc_test_util%s" % unsecure_build_config_suffix, - "//test/core/util:gpr_test_util", "//:grpc++%s" % unsecure_build_config_suffix, "//:grpc%s" % unsecure_build_config_suffix, "//:gpr", "//test/cpp/util:test_config", ], + tags = ["no_windows"], ) grpc_cc_test( name = "resolver_component_tests_runner_invoker%s" % unsecure_build_config_suffix, @@ -63,7 +64,6 @@ def generate_resolver_component_tests(): deps = [ "//test/cpp/util:test_util", "//test/core/util:grpc_test_util", - "//test/core/util:gpr_test_util", "//:grpc++", "//:grpc", "//:gpr", @@ -80,5 +80,6 @@ def generate_resolver_component_tests(): args = [ "--test_bin_name=resolver_component_test%s" % unsecure_build_config_suffix, "--running_under_bazel=true", - ] + ], + tags = ["no_windows"], ) diff --git a/test/cpp/naming/resolver_component_test.cc b/test/cpp/naming/resolver_component_test.cc index 3dc6e7178cc..93a92f68a6d 100644 --- a/test/cpp/naming/resolver_component_test.cc +++ b/test/cpp/naming/resolver_component_test.cc @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -38,9 +39,12 @@ #include "test/cpp/util/test_config.h" #include "src/core/ext/filters/client_channel/client_channel.h" +#include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver.h" +#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h" #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" #include "src/core/ext/filters/client_channel/resolver_registry.h" +#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/host_port.h" @@ -51,9 +55,12 @@ #include "src/core/lib/iomgr/iomgr.h" #include "src/core/lib/iomgr/resolve_address.h" #include "src/core/lib/iomgr/sockaddr_utils.h" +#include "src/core/lib/iomgr/socket_utils.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" +#include "test/cpp/naming/dns_test_util.h" + // TODO: pull in different headers when enabling this // test on windows. Also set BAD_SOCKET_RETURN_VAL // to INVALID_SOCKET on windows. @@ -87,9 +94,36 @@ DEFINE_string(expected_addrs, "", DEFINE_string(expected_chosen_service_config, "", "Expected service config json string that gets chosen (no " "whitespace). Empty for none."); +DEFINE_string(expected_service_config_error, "", + "Expected service config error. Empty for none."); DEFINE_string( local_dns_server_address, "", "Optional. This address is placed as the uri authority if present."); +DEFINE_string( + enable_srv_queries, "", + "Whether or not to enable SRV queries for the ares resolver instance." + "It would be better if this arg could be bool, but the way that we " + "generate " + "the python script runner doesn't allow us to pass a gflags bool to this " + "binary."); +DEFINE_string( + enable_txt_queries, "", + "Whether or not to enable TXT queries for the ares resolver instance." + "It would be better if this arg could be bool, but the way that we " + "generate " + "the python script runner doesn't allow us to pass a gflags bool to this " + "binary."); +DEFINE_string( + inject_broken_nameserver_list, "", + "Whether or not to configure c-ares to use a broken nameserver list, in " + "which " + "the first nameserver in the list is non-responsive, but the second one " + "works, i.e " + "serves the expected DNS records; using for testing such a real scenario." + "It would be better if this arg could be bool, but the way that we " + "generate " + "the python script runner doesn't allow us to pass a gflags bool to this " + "binary."); DEFINE_string(expected_lb_policy, "", "Expected lb policy name that appears in resolver result channel " "arg. Empty for none."); @@ -130,8 +164,9 @@ vector ParseExpectedAddrs(std::string expected_addrs) { expected_addrs = expected_addrs.substr(next_comma + 1, std::string::npos); // get the next is_balancer 'bool' associated with this address size_t next_semicolon = expected_addrs.find(';'); - bool is_balancer = - gpr_is_true(expected_addrs.substr(0, next_semicolon).c_str()); + bool is_balancer = false; + gpr_parse_bool_value(expected_addrs.substr(0, next_semicolon).c_str(), + &is_balancer); out.emplace_back(GrpcLBAddress(next_addr, is_balancer)); if (next_semicolon == std::string::npos) { break; @@ -162,6 +197,7 @@ struct ArgsStruct { grpc_channel_args* channel_args; vector expected_addrs; std::string expected_service_config_string; + std::string expected_service_config_error; std::string expected_lb_policy; }; @@ -200,7 +236,10 @@ gpr_timespec NSecondDeadline(int seconds) { } void PollPollsetUntilRequestDone(ArgsStruct* args) { - gpr_timespec deadline = NSecondDeadline(10); + // Use a 20-second timeout to give room for the tests that involve + // a non-responsive name server (c-ares uses a ~5 second query timeout + // for that server before succeeding with the healthy one). + gpr_timespec deadline = NSecondDeadline(20); while (true) { bool done = gpr_atm_acq_load(&args->done_atm) != 0; if (done) { @@ -223,21 +262,23 @@ void PollPollsetUntilRequestDone(ArgsStruct* args) { gpr_event_set(&args->ev, (void*)1); } -void CheckServiceConfigResultLocked(grpc_channel_args* channel_args, +void CheckServiceConfigResultLocked(const char* service_config_json, + grpc_error* service_config_error, ArgsStruct* args) { - const grpc_arg* service_config_arg = - grpc_channel_args_find(channel_args, GRPC_ARG_SERVICE_CONFIG); if (args->expected_service_config_string != "") { - GPR_ASSERT(service_config_arg != nullptr); - GPR_ASSERT(service_config_arg->type == GRPC_ARG_STRING); - EXPECT_EQ(service_config_arg->value.string, - args->expected_service_config_string); - } else { - GPR_ASSERT(service_config_arg == nullptr); + GPR_ASSERT(service_config_json != nullptr); + EXPECT_EQ(service_config_json, args->expected_service_config_string); } + if (args->expected_service_config_error == "") { + EXPECT_EQ(service_config_error, GRPC_ERROR_NONE); + } else { + EXPECT_THAT(grpc_error_string(service_config_error), + testing::HasSubstr(args->expected_service_config_error)); + } + GRPC_ERROR_UNREF(service_config_error); } -void CheckLBPolicyResultLocked(grpc_channel_args* channel_args, +void CheckLBPolicyResultLocked(const grpc_channel_args* channel_args, ArgsStruct* args) { const grpc_arg* lb_policy_arg = grpc_channel_args_find(channel_args, GRPC_ARG_LB_POLICY_NAME); @@ -378,85 +419,216 @@ void OpenAndCloseSocketsStressLoop(int dummy_port, gpr_event* done_ev) { } #endif -void CheckResolverResultLocked(void* argsp, grpc_error* err) { - EXPECT_EQ(err, GRPC_ERROR_NONE); - ArgsStruct* args = (ArgsStruct*)argsp; - grpc_channel_args* channel_args = args->channel_args; - const grpc_arg* channel_arg = - grpc_channel_args_find(channel_args, GRPC_ARG_LB_ADDRESSES); - GPR_ASSERT(channel_arg != nullptr); - 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, - addresses->num_addresses, args->expected_addrs.size()); - GPR_ASSERT(addresses->num_addresses == args->expected_addrs.size()); - std::vector found_lb_addrs; - for (size_t i = 0; i < addresses->num_addresses; i++) { - grpc_lb_address addr = addresses->addresses[i]; - char* str; - grpc_sockaddr_to_string(&str, &addr.address, 1 /* normalize */); - gpr_log(GPR_INFO, "%s", str); - found_lb_addrs.emplace_back( - GrpcLBAddress(std::string(str), addr.is_balancer)); - gpr_free(str); +class ResultHandler : public grpc_core::Resolver::ResultHandler { + public: + static grpc_core::UniquePtr Create( + ArgsStruct* args) { + return grpc_core::UniquePtr( + grpc_core::New(args)); } - if (args->expected_addrs.size() != found_lb_addrs.size()) { - gpr_log(GPR_DEBUG, - "found lb addrs size is: %" PRIdPTR - ". expected addrs size is %" PRIdPTR, - found_lb_addrs.size(), args->expected_addrs.size()); - abort(); + + explicit ResultHandler(ArgsStruct* args) : args_(args) {} + + void ReturnResult(grpc_core::Resolver::Result result) override { + CheckResult(result); + gpr_atm_rel_store(&args_->done_atm, 1); + gpr_mu_lock(args_->mu); + GRPC_LOG_IF_ERROR("pollset_kick", + grpc_pollset_kick(args_->pollset, nullptr)); + gpr_mu_unlock(args_->mu); } - EXPECT_THAT(args->expected_addrs, UnorderedElementsAreArray(found_lb_addrs)); - CheckServiceConfigResultLocked(channel_args, args); - if (args->expected_service_config_string == "") { - CheckLBPolicyResultLocked(channel_args, args); + + void ReturnError(grpc_error* error) override { + gpr_log(GPR_ERROR, "resolver returned error: %s", grpc_error_string(error)); + GPR_ASSERT(false); } - gpr_atm_rel_store(&args->done_atm, 1); - gpr_mu_lock(args->mu); - GRPC_LOG_IF_ERROR("pollset_kick", grpc_pollset_kick(args->pollset, nullptr)); - gpr_mu_unlock(args->mu); + + virtual void CheckResult(const grpc_core::Resolver::Result& result) {} + + protected: + ArgsStruct* args_struct() const { return args_; } + + private: + ArgsStruct* args_; +}; + +class CheckingResultHandler : public ResultHandler { + public: + static grpc_core::UniquePtr Create( + ArgsStruct* args) { + return grpc_core::UniquePtr( + grpc_core::New(args)); + } + + explicit CheckingResultHandler(ArgsStruct* args) : ResultHandler(args) {} + + void CheckResult(const grpc_core::Resolver::Result& result) override { + ArgsStruct* args = args_struct(); + gpr_log(GPR_INFO, "num addrs found: %" PRIdPTR ". expected %" PRIdPTR, + result.addresses.size(), args->expected_addrs.size()); + GPR_ASSERT(result.addresses.size() == args->expected_addrs.size()); + std::vector found_lb_addrs; + for (size_t i = 0; i < result.addresses.size(); i++) { + const grpc_core::ServerAddress& addr = result.addresses[i]; + char* str; + grpc_sockaddr_to_string(&str, &addr.address(), 1 /* normalize */); + gpr_log(GPR_INFO, "%s", str); + found_lb_addrs.emplace_back( + GrpcLBAddress(std::string(str), addr.IsBalancer())); + gpr_free(str); + } + if (args->expected_addrs.size() != found_lb_addrs.size()) { + gpr_log(GPR_DEBUG, + "found lb addrs size is: %" PRIdPTR + ". expected addrs size is %" PRIdPTR, + found_lb_addrs.size(), args->expected_addrs.size()); + abort(); + } + EXPECT_THAT(args->expected_addrs, + UnorderedElementsAreArray(found_lb_addrs)); + const char* service_config_json = + result.service_config == nullptr + ? nullptr + : result.service_config->service_config_json(); + CheckServiceConfigResultLocked( + service_config_json, GRPC_ERROR_REF(result.service_config_error), args); + if (args->expected_service_config_string == "") { + CheckLBPolicyResultLocked(result.args, args); + } + } +}; + +int g_fake_non_responsive_dns_server_port = -1; + +/* This function will configure any ares_channel created by the c-ares based + * resolver. This is useful to effectively mock /etc/resolv.conf settings + * (and equivalent on Windows), which unit tests don't have write permissions. + */ +void InjectBrokenNameServerList(ares_channel channel) { + struct ares_addr_port_node dns_server_addrs[2]; + memset(dns_server_addrs, 0, sizeof(dns_server_addrs)); + char* unused_host; + char* local_dns_server_port; + GPR_ASSERT(gpr_split_host_port(FLAGS_local_dns_server_address.c_str(), + &unused_host, &local_dns_server_port)); + gpr_log(GPR_DEBUG, + "Injecting broken nameserver list. Bad server address:|[::1]:%d|. " + "Good server address:%s", + g_fake_non_responsive_dns_server_port, + FLAGS_local_dns_server_address.c_str()); + // Put the non-responsive DNS server at the front of c-ares's nameserver list. + dns_server_addrs[0].family = AF_INET6; + ((char*)&dns_server_addrs[0].addr.addr6)[15] = 0x1; + dns_server_addrs[0].tcp_port = g_fake_non_responsive_dns_server_port; + dns_server_addrs[0].udp_port = g_fake_non_responsive_dns_server_port; + dns_server_addrs[0].next = &dns_server_addrs[1]; + // Put the actual healthy DNS server after the first one. The expectation is + // that the resolver will timeout the query to the non-responsive DNS server + // and will skip over to this healthy DNS server, without causing any DNS + // resolution errors. + dns_server_addrs[1].family = AF_INET; + ((char*)&dns_server_addrs[1].addr.addr4)[0] = 0x7f; + ((char*)&dns_server_addrs[1].addr.addr4)[3] = 0x1; + dns_server_addrs[1].tcp_port = atoi(local_dns_server_port); + dns_server_addrs[1].udp_port = atoi(local_dns_server_port); + dns_server_addrs[1].next = nullptr; + GPR_ASSERT(ares_set_servers_ports(channel, dns_server_addrs) == ARES_SUCCESS); + gpr_free(local_dns_server_port); + gpr_free(unused_host); } -void CheckResolvedWithoutErrorLocked(void* argsp, grpc_error* err) { - EXPECT_EQ(err, GRPC_ERROR_NONE); - ArgsStruct* args = (ArgsStruct*)argsp; - gpr_atm_rel_store(&args->done_atm, 1); - gpr_mu_lock(args->mu); - GRPC_LOG_IF_ERROR("pollset_kick", grpc_pollset_kick(args->pollset, nullptr)); - gpr_mu_unlock(args->mu); +void StartResolvingLocked(void* arg, grpc_error* unused) { + grpc_core::Resolver* r = static_cast(arg); + r->StartLocked(); } -void RunResolvesRelevantRecordsTest(void (*OnDoneLocked)(void* arg, - grpc_error* error)) { +void RunResolvesRelevantRecordsTest( + grpc_core::UniquePtr ( + *CreateResultHandler)(ArgsStruct* args)) { grpc_core::ExecCtx exec_ctx; ArgsStruct args; ArgsInit(&args); args.expected_addrs = ParseExpectedAddrs(FLAGS_expected_addrs); args.expected_service_config_string = FLAGS_expected_chosen_service_config; + args.expected_service_config_error = FLAGS_expected_service_config_error; args.expected_lb_policy = FLAGS_expected_lb_policy; // maybe build the address with an authority char* whole_uri = nullptr; - GPR_ASSERT(gpr_asprintf(&whole_uri, "dns://%s/%s", - FLAGS_local_dns_server_address.c_str(), - FLAGS_target_name.c_str())); + gpr_log(GPR_DEBUG, + "resolver_component_test: --inject_broken_nameserver_list: %s", + FLAGS_inject_broken_nameserver_list.c_str()); + grpc_core::UniquePtr + fake_non_responsive_dns_server; + if (FLAGS_inject_broken_nameserver_list == "True") { + g_fake_non_responsive_dns_server_port = grpc_pick_unused_port_or_die(); + fake_non_responsive_dns_server.reset( + grpc_core::New( + g_fake_non_responsive_dns_server_port)); + grpc_ares_test_only_inject_config = InjectBrokenNameServerList; + GPR_ASSERT( + gpr_asprintf(&whole_uri, "dns:///%s", FLAGS_target_name.c_str())); + } else if (FLAGS_inject_broken_nameserver_list == "False") { + gpr_log(GPR_INFO, "Specifying authority in uris to: %s", + FLAGS_local_dns_server_address.c_str()); + GPR_ASSERT(gpr_asprintf(&whole_uri, "dns://%s/%s", + FLAGS_local_dns_server_address.c_str(), + FLAGS_target_name.c_str())); + } else { + gpr_log(GPR_DEBUG, "Invalid value for --inject_broken_nameserver_list."); + abort(); + } + gpr_log(GPR_DEBUG, "resolver_component_test: --enable_srv_queries: %s", + FLAGS_enable_srv_queries.c_str()); + grpc_channel_args* resolver_args = nullptr; + // By default, SRV queries are disabled, so tests that expect no SRV query + // should avoid setting any channel arg. Test cases that do rely on the SRV + // query must explicitly enable SRV though. + if (FLAGS_enable_srv_queries == "True") { + grpc_arg srv_queries_arg = grpc_channel_arg_integer_create( + const_cast(GRPC_ARG_DNS_ENABLE_SRV_QUERIES), true); + resolver_args = + grpc_channel_args_copy_and_add(nullptr, &srv_queries_arg, 1); + } else if (FLAGS_enable_srv_queries != "False") { + gpr_log(GPR_DEBUG, "Invalid value for --enable_srv_queries."); + abort(); + } + gpr_log(GPR_DEBUG, "resolver_component_test: --enable_txt_queries: %s", + FLAGS_enable_txt_queries.c_str()); + // By default, TXT queries are disabled, so tests that expect no TXT query + // should avoid setting any channel arg. Test cases that do rely on the TXT + // query must explicitly enable TXT though. + if (FLAGS_enable_txt_queries == "True") { + // Unlike SRV queries, there isn't a channel arg specific to TXT records. + // Rather, we use the resolver-agnostic "service config" resolution option, + // for which c-ares has its own specific default value, which isn't + // necessarily shared by other resolvers. + grpc_arg txt_queries_arg = grpc_channel_arg_integer_create( + const_cast(GRPC_ARG_SERVICE_CONFIG_DISABLE_RESOLUTION), false); + grpc_channel_args* tmp_args = + grpc_channel_args_copy_and_add(resolver_args, &txt_queries_arg, 1); + grpc_channel_args_destroy(resolver_args); + resolver_args = tmp_args; + } else if (FLAGS_enable_txt_queries != "False") { + gpr_log(GPR_DEBUG, "Invalid value for --enable_txt_queries."); + abort(); + } // create resolver and resolve grpc_core::OrphanablePtr resolver = - grpc_core::ResolverRegistry::CreateResolver(whole_uri, nullptr, - args.pollset_set, args.lock); + grpc_core::ResolverRegistry::CreateResolver(whole_uri, resolver_args, + args.pollset_set, args.lock, + CreateResultHandler(&args)); + grpc_channel_args_destroy(resolver_args); gpr_free(whole_uri); - grpc_closure on_resolver_result_changed; - GRPC_CLOSURE_INIT(&on_resolver_result_changed, OnDoneLocked, (void*)&args, - grpc_combiner_scheduler(args.lock)); - resolver->NextLocked(&args.channel_args, &on_resolver_result_changed); + GRPC_CLOSURE_SCHED(GRPC_CLOSURE_CREATE(StartResolvingLocked, resolver.get(), + grpc_combiner_scheduler(args.lock)), + GRPC_ERROR_NONE); grpc_core::ExecCtx::Get()->Flush(); PollPollsetUntilRequestDone(&args); ArgsFinish(&args); } TEST(ResolverComponentTest, TestResolvesRelevantRecords) { - RunResolvesRelevantRecordsTest(CheckResolverResultLocked); + RunResolvesRelevantRecordsTest(CheckingResultHandler::Create); } TEST(ResolverComponentTest, TestResolvesRelevantRecordsWithConcurrentFdStress) { @@ -467,7 +639,7 @@ TEST(ResolverComponentTest, TestResolvesRelevantRecordsWithConcurrentFdStress) { std::thread socket_stress_thread(OpenAndCloseSocketsStressLoop, dummy_port, &done_ev); // Run the resolver test - RunResolvesRelevantRecordsTest(CheckResolvedWithoutErrorLocked); + RunResolvesRelevantRecordsTest(ResultHandler::Create); // Shutdown and join stress thread gpr_event_set(&done_ev, (void*)1); socket_stress_thread.join(); @@ -477,17 +649,13 @@ TEST(ResolverComponentTest, TestResolvesRelevantRecordsWithConcurrentFdStress) { int main(int argc, char** argv) { grpc_init(); - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); - ParseCommandLineFlags(&argc, &argv, true); + grpc::testing::InitTest(&argc, &argv, true); if (FLAGS_target_name == "") { gpr_log(GPR_ERROR, "Missing target_name param."); abort(); } - if (FLAGS_local_dns_server_address != "") { - gpr_log(GPR_INFO, "Specifying authority in uris to: %s", - FLAGS_local_dns_server_address.c_str()); - } auto result = RUN_ALL_TESTS(); grpc_shutdown(); return result; diff --git a/test/cpp/naming/resolver_component_tests_runner.py b/test/cpp/naming/resolver_component_tests_runner.py index 1873eec35bd..e767e4cb5b8 100755 --- a/test/cpp/naming/resolver_component_tests_runner.py +++ b/test/cpp/naming/resolver_component_tests_runner.py @@ -55,7 +55,6 @@ if cur_resolver and cur_resolver != 'ares': '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'}) os.environ.update({'GRPC_TRACE': 'cares_resolver'}) def wait_until_dns_server_is_up(args, @@ -125,7 +124,11 @@ current_test_subprocess = subprocess.Popen([ '--target_name', 'no-srv-ipv4-single-target.resolver-tests-version-4.grpctestingexp.', '--expected_addrs', '5.5.5.5:443,False', '--expected_chosen_service_config', '', + '--expected_service_config_error', '', '--expected_lb_policy', '', + '--enable_srv_queries', 'True', + '--enable_txt_queries', 'True', + '--inject_broken_nameserver_list', 'False', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -137,7 +140,11 @@ current_test_subprocess = subprocess.Popen([ '--target_name', 'srv-ipv4-single-target.resolver-tests-version-4.grpctestingexp.', '--expected_addrs', '1.2.3.4:1234,True', '--expected_chosen_service_config', '', + '--expected_service_config_error', '', '--expected_lb_policy', '', + '--enable_srv_queries', 'True', + '--enable_txt_queries', 'True', + '--inject_broken_nameserver_list', 'False', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -149,7 +156,11 @@ current_test_subprocess = subprocess.Popen([ '--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_service_config_error', '', '--expected_lb_policy', '', + '--enable_srv_queries', 'True', + '--enable_txt_queries', 'True', + '--inject_broken_nameserver_list', 'False', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -161,7 +172,11 @@ current_test_subprocess = subprocess.Popen([ '--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_service_config_error', '', '--expected_lb_policy', '', + '--enable_srv_queries', 'True', + '--enable_txt_queries', 'True', + '--inject_broken_nameserver_list', 'False', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -173,7 +188,11 @@ current_test_subprocess = subprocess.Popen([ '--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_service_config_error', '', '--expected_lb_policy', '', + '--enable_srv_queries', 'True', + '--enable_txt_queries', 'True', + '--inject_broken_nameserver_list', 'False', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -184,8 +203,12 @@ 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_chosen_service_config', '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"SimpleService"}],"waitForReady":true}]}', + '--expected_service_config_error', '', '--expected_lb_policy', 'round_robin', + '--enable_srv_queries', 'True', + '--enable_txt_queries', 'True', + '--inject_broken_nameserver_list', 'False', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -196,8 +219,12 @@ 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_chosen_service_config', '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"NoSrvSimpleService"}],"waitForReady":true}]}', + '--expected_service_config_error', '', '--expected_lb_policy', 'round_robin', + '--enable_srv_queries', 'True', + '--enable_txt_queries', 'True', + '--inject_broken_nameserver_list', 'False', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -209,7 +236,11 @@ current_test_subprocess = subprocess.Popen([ '--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_service_config_error', '', '--expected_lb_policy', '', + '--enable_srv_queries', 'True', + '--enable_txt_queries', 'True', + '--inject_broken_nameserver_list', 'False', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -221,7 +252,11 @@ current_test_subprocess = subprocess.Popen([ '--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_service_config_error', '', '--expected_lb_policy', '', + '--enable_srv_queries', 'True', + '--enable_txt_queries', 'True', + '--inject_broken_nameserver_list', 'False', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -232,8 +267,12 @@ 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_chosen_service_config', '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"CppService"}],"waitForReady":true}]}', + '--expected_service_config_error', '', '--expected_lb_policy', 'round_robin', + '--enable_srv_queries', 'True', + '--enable_txt_queries', 'True', + '--inject_broken_nameserver_list', 'False', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -244,8 +283,12 @@ 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_chosen_service_config', '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"AlwaysPickedService"}],"waitForReady":true}]}', + '--expected_service_config_error', '', '--expected_lb_policy', 'round_robin', + '--enable_srv_queries', 'True', + '--enable_txt_queries', 'True', + '--inject_broken_nameserver_list', 'False', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -257,7 +300,11 @@ current_test_subprocess = subprocess.Popen([ '--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_service_config_error', '', '--expected_lb_policy', '', + '--enable_srv_queries', 'True', + '--enable_txt_queries', 'True', + '--inject_broken_nameserver_list', 'False', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -269,7 +316,11 @@ current_test_subprocess = subprocess.Popen([ '--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_service_config_error', '', '--expected_lb_policy', '', + '--enable_srv_queries', 'True', + '--enable_txt_queries', 'True', + '--inject_broken_nameserver_list', 'False', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -280,8 +331,236 @@ 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_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_service_config_error', '', '--expected_lb_policy', '', + '--enable_srv_queries', 'True', + '--enable_txt_queries', 'True', + '--inject_broken_nameserver_list', 'False', + '--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-single-target-srv-disabled.resolver-tests-version-4.grpctestingexp.') +current_test_subprocess = subprocess.Popen([ + args.test_bin_path, + '--target_name', 'srv-ipv4-single-target-srv-disabled.resolver-tests-version-4.grpctestingexp.', + '--expected_addrs', '2.3.4.5:443,False', + '--expected_chosen_service_config', '', + '--expected_service_config_error', '', + '--expected_lb_policy', '', + '--enable_srv_queries', 'False', + '--enable_txt_queries', 'True', + '--inject_broken_nameserver_list', 'False', + '--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-srv-disabled.resolver-tests-version-4.grpctestingexp.') +current_test_subprocess = subprocess.Popen([ + args.test_bin_path, + '--target_name', 'srv-ipv4-multi-target-srv-disabled.resolver-tests-version-4.grpctestingexp.', + '--expected_addrs', '9.2.3.5:443,False;9.2.3.6:443,False;9.2.3.7:443,False', + '--expected_chosen_service_config', '', + '--expected_service_config_error', '', + '--expected_lb_policy', '', + '--enable_srv_queries', 'False', + '--enable_txt_queries', 'True', + '--inject_broken_nameserver_list', 'False', + '--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-srv-disabled.resolver-tests-version-4.grpctestingexp.') +current_test_subprocess = subprocess.Popen([ + args.test_bin_path, + '--target_name', 'srv-ipv6-single-target-srv-disabled.resolver-tests-version-4.grpctestingexp.', + '--expected_addrs', '[2600::1001]:443,False', + '--expected_chosen_service_config', '', + '--expected_service_config_error', '', + '--expected_lb_policy', '', + '--enable_srv_queries', 'False', + '--enable_txt_queries', 'True', + '--inject_broken_nameserver_list', 'False', + '--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-srv-disabled.resolver-tests-version-4.grpctestingexp.') +current_test_subprocess = subprocess.Popen([ + args.test_bin_path, + '--target_name', 'srv-ipv6-multi-target-srv-disabled.resolver-tests-version-4.grpctestingexp.', + '--expected_addrs', '[2600::1002]:443,False;[2600::1003]:443,False;[2600::1004]:443,False', + '--expected_chosen_service_config', '', + '--expected_service_config_error', '', + '--expected_lb_policy', '', + '--enable_srv_queries', 'False', + '--enable_txt_queries', 'True', + '--inject_broken_nameserver_list', 'False', + '--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-srv-disabled.resolver-tests-version-4.grpctestingexp.') +current_test_subprocess = subprocess.Popen([ + args.test_bin_path, + '--target_name', 'srv-ipv4-simple-service-config-srv-disabled.resolver-tests-version-4.grpctestingexp.', + '--expected_addrs', '5.5.3.4:443,False', + '--expected_chosen_service_config', '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"SimpleService"}],"waitForReady":true}]}', + '--expected_service_config_error', '', + '--expected_lb_policy', 'round_robin', + '--enable_srv_queries', 'False', + '--enable_txt_queries', 'True', + '--inject_broken_nameserver_list', 'False', + '--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-txt-disabled.resolver-tests-version-4.grpctestingexp.') +current_test_subprocess = subprocess.Popen([ + args.test_bin_path, + '--target_name', 'srv-ipv4-simple-service-config-txt-disabled.resolver-tests-version-4.grpctestingexp.', + '--expected_addrs', '1.2.3.4:1234,True', + '--expected_chosen_service_config', '', + '--expected_service_config_error', '', + '--expected_lb_policy', '', + '--enable_srv_queries', 'True', + '--enable_txt_queries', 'False', + '--inject_broken_nameserver_list', 'False', + '--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-txt-disabled.resolver-tests-version-4.grpctestingexp.') +current_test_subprocess = subprocess.Popen([ + args.test_bin_path, + '--target_name', 'ipv4-cpp-config-has-zero-percentage-txt-disabled.resolver-tests-version-4.grpctestingexp.', + '--expected_addrs', '1.2.3.4:443,False', + '--expected_chosen_service_config', '', + '--expected_service_config_error', '', + '--expected_lb_policy', '', + '--enable_srv_queries', 'True', + '--enable_txt_queries', 'False', + '--inject_broken_nameserver_list', 'False', + '--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-txt-disabled.resolver-tests-version-4.grpctestingexp.') +current_test_subprocess = subprocess.Popen([ + args.test_bin_path, + '--target_name', 'ipv4-second-language-is-cpp-txt-disabled.resolver-tests-version-4.grpctestingexp.', + '--expected_addrs', '1.2.3.4:443,False', + '--expected_chosen_service_config', '', + '--expected_service_config_error', '', + '--expected_lb_policy', '', + '--enable_srv_queries', 'True', + '--enable_txt_queries', 'False', + '--inject_broken_nameserver_list', 'False', + '--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-svc_cfg_bad_json.resolver-tests-version-4.grpctestingexp.') +current_test_subprocess = subprocess.Popen([ + args.test_bin_path, + '--target_name', 'ipv4-svc_cfg_bad_json.resolver-tests-version-4.grpctestingexp.', + '--expected_addrs', '1.2.3.4:443,False', + '--expected_chosen_service_config', '', + '--expected_service_config_error', 'could not parse', + '--expected_lb_policy', '', + '--enable_srv_queries', 'True', + '--enable_txt_queries', 'True', + '--inject_broken_nameserver_list', 'False', + '--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-svc_cfg_bad_client_language.resolver-tests-version-4.grpctestingexp.') +current_test_subprocess = subprocess.Popen([ + args.test_bin_path, + '--target_name', 'ipv4-svc_cfg_bad_client_language.resolver-tests-version-4.grpctestingexp.', + '--expected_addrs', '1.2.3.4:443,False', + '--expected_chosen_service_config', '', + '--expected_service_config_error', 'field:clientLanguage error:should be of type array', + '--expected_lb_policy', '', + '--enable_srv_queries', 'True', + '--enable_txt_queries', 'True', + '--inject_broken_nameserver_list', 'False', + '--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-svc_cfg_bad_percentage.resolver-tests-version-4.grpctestingexp.') +current_test_subprocess = subprocess.Popen([ + args.test_bin_path, + '--target_name', 'ipv4-svc_cfg_bad_percentage.resolver-tests-version-4.grpctestingexp.', + '--expected_addrs', '1.2.3.4:443,False', + '--expected_chosen_service_config', '', + '--expected_service_config_error', 'field:percentage error:should be of type number', + '--expected_lb_policy', '', + '--enable_srv_queries', 'True', + '--enable_txt_queries', 'True', + '--inject_broken_nameserver_list', 'False', + '--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-svc_cfg_bad_wait_for_ready.resolver-tests-version-4.grpctestingexp.') +current_test_subprocess = subprocess.Popen([ + args.test_bin_path, + '--target_name', 'ipv4-svc_cfg_bad_wait_for_ready.resolver-tests-version-4.grpctestingexp.', + '--expected_addrs', '1.2.3.4:443,False', + '--expected_chosen_service_config', '', + '--expected_service_config_error', 'field:waitForReady error:Type should be true/false', + '--expected_lb_policy', '', + '--enable_srv_queries', 'True', + '--enable_txt_queries', 'True', + '--inject_broken_nameserver_list', 'False', + '--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' % 'no-srv-ipv4-single-target-inject-broken-nameservers.resolver-tests-version-4.grpctestingexp.') +current_test_subprocess = subprocess.Popen([ + args.test_bin_path, + '--target_name', 'no-srv-ipv4-single-target-inject-broken-nameservers.resolver-tests-version-4.grpctestingexp.', + '--expected_addrs', '5.5.5.5:443,False', + '--expected_chosen_service_config', '', + '--expected_service_config_error', '', + '--expected_lb_policy', '', + '--enable_srv_queries', 'True', + '--enable_txt_queries', 'True', + '--inject_broken_nameserver_list', 'True', + '--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-inject-broken-nameservers.resolver-tests-version-4.grpctestingexp.') +current_test_subprocess = subprocess.Popen([ + args.test_bin_path, + '--target_name', 'ipv4-config-causing-fallback-to-tcp-inject-broken-nameservers.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_service_config_error', 'Service config parsing error', + '--expected_lb_policy', '', + '--enable_srv_queries', 'True', + '--enable_txt_queries', 'True', + '--inject_broken_nameserver_list', 'True', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: diff --git a/test/cpp/naming/resolver_component_tests_runner_invoker.cc b/test/cpp/naming/resolver_component_tests_runner_invoker.cc index 68be00a67d6..d8f7100a284 100644 --- a/test/cpp/naming/resolver_component_tests_runner_invoker.cc +++ b/test/cpp/naming/resolver_component_tests_runner_invoker.cc @@ -29,6 +29,10 @@ #include #include +#ifdef __FreeBSD__ +#include +#endif + #include "test/cpp/util/subprocess.h" #include "test/cpp/util/test_config.h" diff --git a/test/cpp/naming/resolver_test_record_groups.yaml b/test/cpp/naming/resolver_test_record_groups.yaml index 3c51a00c7b1..f72a7eaf572 100644 --- a/test/cpp/naming/resolver_test_record_groups.yaml +++ b/test/cpp/naming/resolver_test_record_groups.yaml @@ -1,9 +1,14 @@ resolver_tests_common_zone_name: resolver-tests-version-4.grpctestingexp. resolver_component_tests: +# Tests for which we enable SRV queries - expected_addrs: - {address: '5.5.5.5:443', is_balancer: false} expected_chosen_service_config: null + expected_service_config_error: null expected_lb_policy: null + enable_srv_queries: true + enable_txt_queries: true + inject_broken_nameserver_list: false record_to_resolve: no-srv-ipv4-single-target records: no-srv-ipv4-single-target: @@ -11,7 +16,11 @@ resolver_component_tests: - expected_addrs: - {address: '1.2.3.4:1234', is_balancer: true} expected_chosen_service_config: null + expected_service_config_error: null expected_lb_policy: null + enable_srv_queries: true + enable_txt_queries: true + inject_broken_nameserver_list: false record_to_resolve: srv-ipv4-single-target records: _grpclb._tcp.srv-ipv4-single-target: @@ -23,7 +32,11 @@ resolver_component_tests: - {address: '1.2.3.6:1234', is_balancer: true} - {address: '1.2.3.7:1234', is_balancer: true} expected_chosen_service_config: null + expected_service_config_error: null expected_lb_policy: null + enable_srv_queries: true + enable_txt_queries: true + inject_broken_nameserver_list: false record_to_resolve: srv-ipv4-multi-target records: _grpclb._tcp.srv-ipv4-multi-target: @@ -35,7 +48,11 @@ resolver_component_tests: - expected_addrs: - {address: '[2607:f8b0:400a:801::1001]:1234', is_balancer: true} expected_chosen_service_config: null + expected_service_config_error: null expected_lb_policy: null + enable_srv_queries: true + enable_txt_queries: true + inject_broken_nameserver_list: false record_to_resolve: srv-ipv6-single-target records: _grpclb._tcp.srv-ipv6-single-target: @@ -47,7 +64,11 @@ resolver_component_tests: - {address: '[2607:f8b0:400a:801::1003]:1234', is_balancer: true} - {address: '[2607:f8b0:400a:801::1004]:1234', is_balancer: true} expected_chosen_service_config: null + expected_service_config_error: null expected_lb_policy: null + enable_srv_queries: true + enable_txt_queries: true + inject_broken_nameserver_list: false record_to_resolve: srv-ipv6-multi-target records: _grpclb._tcp.srv-ipv6-multi-target: @@ -58,8 +79,12 @@ resolver_component_tests: - {TTL: '2100', data: '2607:f8b0:400a:801::1004', type: AAAA} - expected_addrs: - {address: '1.2.3.4:1234', is_balancer: true} - expected_chosen_service_config: '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"SimpleService","waitForReady":true}]}]}' + expected_chosen_service_config: '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"SimpleService"}],"waitForReady":true}]}' + expected_service_config_error: null expected_lb_policy: round_robin + enable_srv_queries: true + enable_txt_queries: true + inject_broken_nameserver_list: false record_to_resolve: srv-ipv4-simple-service-config records: _grpclb._tcp.srv-ipv4-simple-service-config: @@ -67,68 +92,92 @@ resolver_component_tests: ipv4-simple-service-config: - {TTL: '2100', data: 1.2.3.4, type: A} _grpc_config.srv-ipv4-simple-service-config: - - {TTL: '2100', data: 'grpc_config=[{"serviceConfig":{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"SimpleService","waitForReady":true}]}]}}]', + - {TTL: '2100', data: 'grpc_config=[{"serviceConfig":{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"SimpleService"}],"waitForReady":true}]}}]', type: TXT} - expected_addrs: - {address: '1.2.3.4:443', is_balancer: false} - expected_chosen_service_config: '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"NoSrvSimpleService","waitForReady":true}]}]}' + expected_chosen_service_config: '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"NoSrvSimpleService"}],"waitForReady":true}]}' + expected_service_config_error: null expected_lb_policy: round_robin + enable_srv_queries: true + enable_txt_queries: true + inject_broken_nameserver_list: false record_to_resolve: ipv4-no-srv-simple-service-config records: ipv4-no-srv-simple-service-config: - {TTL: '2100', data: 1.2.3.4, type: A} _grpc_config.ipv4-no-srv-simple-service-config: - - {TTL: '2100', data: 'grpc_config=[{"serviceConfig":{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"NoSrvSimpleService","waitForReady":true}]}]}}]', + - {TTL: '2100', data: 'grpc_config=[{"serviceConfig":{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"NoSrvSimpleService"}],"waitForReady":true}]}}]', type: TXT} - expected_addrs: - {address: '1.2.3.4:443', is_balancer: false} expected_chosen_service_config: null + expected_service_config_error: null expected_lb_policy: null + enable_srv_queries: true + enable_txt_queries: true + inject_broken_nameserver_list: false record_to_resolve: ipv4-no-config-for-cpp records: ipv4-no-config-for-cpp: - {TTL: '2100', data: 1.2.3.4, type: A} _grpc_config.ipv4-no-config-for-cpp: - - {TTL: '2100', data: 'grpc_config=[{"clientLanguage":["python"],"serviceConfig":{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"PythonService","waitForReady":true}]}]}}]', + - {TTL: '2100', data: 'grpc_config=[{"clientLanguage":["python"],"serviceConfig":{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"PythonService"}],"waitForReady":true}]}}]', type: TXT} - expected_addrs: - {address: '1.2.3.4:443', is_balancer: false} expected_chosen_service_config: null + expected_service_config_error: null expected_lb_policy: null + enable_srv_queries: true + enable_txt_queries: true + inject_broken_nameserver_list: false record_to_resolve: ipv4-cpp-config-has-zero-percentage records: ipv4-cpp-config-has-zero-percentage: - {TTL: '2100', data: 1.2.3.4, type: A} _grpc_config.ipv4-cpp-config-has-zero-percentage: - - {TTL: '2100', data: 'grpc_config=[{"percentage":0,"serviceConfig":{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"CppService","waitForReady":true}]}]}}]', + - {TTL: '2100', data: 'grpc_config=[{"percentage":0,"serviceConfig":{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"CppService"}],"waitForReady":true}]}}]', type: TXT} - expected_addrs: - {address: '1.2.3.4:443', is_balancer: false} - expected_chosen_service_config: '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"CppService","waitForReady":true}]}]}' + expected_chosen_service_config: '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"CppService"}],"waitForReady":true}]}' + expected_service_config_error: null expected_lb_policy: round_robin + enable_srv_queries: true + enable_txt_queries: true + inject_broken_nameserver_list: false record_to_resolve: ipv4-second-language-is-cpp records: ipv4-second-language-is-cpp: - {TTL: '2100', data: 1.2.3.4, type: A} _grpc_config.ipv4-second-language-is-cpp: - - {TTL: '2100', data: 'grpc_config=[{"clientLanguage":["go"],"serviceConfig":{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"GoService","waitForReady":true}]}]}},{"clientLanguage":["c++"],"serviceConfig":{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"CppService","waitForReady":true}]}]}}]', + - {TTL: '2100', data: 'grpc_config=[{"clientLanguage":["go"],"serviceConfig":{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"GoService"}],"waitForReady":true}]}},{"clientLanguage":["c++"],"serviceConfig":{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"CppService"}],"waitForReady":true}]}}]', type: TXT} - expected_addrs: - {address: '1.2.3.4:443', is_balancer: false} - expected_chosen_service_config: '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"AlwaysPickedService","waitForReady":true}]}]}' + expected_chosen_service_config: '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"AlwaysPickedService"}],"waitForReady":true}]}' + expected_service_config_error: null expected_lb_policy: round_robin + enable_srv_queries: true + enable_txt_queries: true + inject_broken_nameserver_list: false record_to_resolve: ipv4-config-with-percentages records: ipv4-config-with-percentages: - {TTL: '2100', data: 1.2.3.4, type: A} _grpc_config.ipv4-config-with-percentages: - - {TTL: '2100', data: 'grpc_config=[{"percentage":0,"serviceConfig":{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"NeverPickedService","waitForReady":true}]}]}},{"percentage":100,"serviceConfig":{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"AlwaysPickedService","waitForReady":true}]}]}}]', + - {TTL: '2100', data: 'grpc_config=[{"percentage":0,"serviceConfig":{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"NeverPickedService"}],"waitForReady":true}]}},{"percentage":100,"serviceConfig":{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"AlwaysPickedService"}],"waitForReady":true}]}}]', type: TXT} - expected_addrs: - {address: '1.2.3.4:1234', is_balancer: true} - {address: '1.2.3.4:443', is_balancer: false} expected_chosen_service_config: null + expected_service_config_error: null expected_lb_policy: null + enable_srv_queries: true + enable_txt_queries: true + inject_broken_nameserver_list: false record_to_resolve: srv-ipv4-target-has-backend-and-balancer records: _grpclb._tcp.srv-ipv4-target-has-backend-and-balancer: @@ -141,7 +190,11 @@ resolver_component_tests: - {address: '[2607:f8b0:400a:801::1002]:1234', is_balancer: true} - {address: '[2607:f8b0:400a:801::1002]:443', is_balancer: false} expected_chosen_service_config: null + expected_service_config_error: null expected_lb_policy: null + enable_srv_queries: true + enable_txt_queries: true + inject_broken_nameserver_list: false record_to_resolve: srv-ipv6-target-has-backend-and-balancer records: _grpclb._tcp.srv-ipv6-target-has-backend-and-balancer: @@ -152,12 +205,247 @@ resolver_component_tests: - {TTL: '2100', data: '2607:f8b0:400a:801::1002', type: AAAA} - expected_addrs: - {address: '1.2.3.4:443', is_balancer: 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_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_service_config_error: null expected_lb_policy: null + enable_srv_queries: true + enable_txt_queries: true + inject_broken_nameserver_list: false record_to_resolve: ipv4-config-causing-fallback-to-tcp records: ipv4-config-causing-fallback-to-tcp: - {TTL: '2100', data: 1.2.3.4, type: A} _grpc_config.ipv4-config-causing-fallback-to-tcp: + - {TTL: '2100', data: 'grpc_config=[{"serviceConfig":{"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}]}}]', + type: TXT} +# Tests for which we don't enable SRV queries +- expected_addrs: + - {address: '2.3.4.5:443', is_balancer: false} + expected_chosen_service_config: null + expected_service_config_error: null + expected_lb_policy: null + enable_srv_queries: false + enable_txt_queries: true + inject_broken_nameserver_list: false + record_to_resolve: srv-ipv4-single-target-srv-disabled + records: + _grpclb._tcp.srv-ipv4-single-target-srv-disabled: + - {TTL: '2100', data: 0 0 1234 ipv4-single-target-srv-disabled, type: SRV} + ipv4-single-target-srv-disabled: + - {TTL: '2100', data: 1.2.3.4, type: A} + srv-ipv4-single-target-srv-disabled: + - {TTL: '2100', data: 2.3.4.5, type: A} +- expected_addrs: + - {address: '9.2.3.5:443', is_balancer: false} + - {address: '9.2.3.6:443', is_balancer: false} + - {address: '9.2.3.7:443', is_balancer: false} + expected_chosen_service_config: null + expected_service_config_error: null + expected_lb_policy: null + enable_srv_queries: false + enable_txt_queries: true + inject_broken_nameserver_list: false + record_to_resolve: srv-ipv4-multi-target-srv-disabled + records: + _grpclb._tcp.srv-ipv4-multi-target-srv-disabled: + - {TTL: '2100', data: 0 0 1234 ipv4-multi-target-srv-disabled, type: SRV} + ipv4-multi-target-srv-disabled: + - {TTL: '2100', data: 1.2.3.5, type: A} + - {TTL: '2100', data: 1.2.3.6, type: A} + - {TTL: '2100', data: 1.2.3.7, type: A} + srv-ipv4-multi-target-srv-disabled: + - {TTL: '2100', data: 9.2.3.5, type: A} + - {TTL: '2100', data: 9.2.3.6, type: A} + - {TTL: '2100', data: 9.2.3.7, type: A} +- expected_addrs: + - {address: '[2600::1001]:443', is_balancer: false} + expected_chosen_service_config: null + expected_service_config_error: null + expected_lb_policy: null + enable_srv_queries: false + enable_txt_queries: true + inject_broken_nameserver_list: false + record_to_resolve: srv-ipv6-single-target-srv-disabled + records: + _grpclb._tcp.srv-ipv6-single-target-srv-disabled: + - {TTL: '2100', data: 0 0 1234 ipv6-single-target-srv-disabled, type: SRV} + ipv6-single-target-srv-disabled: + - {TTL: '2100', data: '2607:f8b0:400a:801::1001', type: AAAA} + srv-ipv6-single-target-srv-disabled: + - {TTL: '2100', data: '2600::1001', type: AAAA} +- expected_addrs: + - {address: '[2600::1002]:443', is_balancer: false} + - {address: '[2600::1003]:443', is_balancer: false} + - {address: '[2600::1004]:443', is_balancer: false} + expected_chosen_service_config: null + expected_service_config_error: null + expected_lb_policy: null + enable_srv_queries: false + enable_txt_queries: true + inject_broken_nameserver_list: false + record_to_resolve: srv-ipv6-multi-target-srv-disabled + records: + _grpclb._tcp.srv-ipv6-multi-target-srv-disabled: + - {TTL: '2100', data: 0 0 1234 ipv6-multi-target-srv-disabled, type: SRV} + ipv6-multi-target-srv-disabled: + - {TTL: '2100', data: '2607:f8b0:400a:801::1002', type: AAAA} + - {TTL: '2100', data: '2607:f8b0:400a:801::1003', type: AAAA} + - {TTL: '2100', data: '2607:f8b0:400a:801::1004', type: AAAA} + srv-ipv6-multi-target-srv-disabled: + - {TTL: '2100', data: '2600::1002', type: AAAA} + - {TTL: '2100', data: '2600::1003', type: AAAA} + - {TTL: '2100', data: '2600::1004', type: AAAA} +- expected_addrs: + - {address: '5.5.3.4:443', is_balancer: false} + expected_chosen_service_config: '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"SimpleService"}],"waitForReady":true}]}' + expected_service_config_error: null + expected_lb_policy: round_robin + enable_srv_queries: false + enable_txt_queries: true + inject_broken_nameserver_list: false + record_to_resolve: srv-ipv4-simple-service-config-srv-disabled + records: + _grpclb._tcp.srv-ipv4-simple-service-config-srv-disabled: + - {TTL: '2100', data: 0 0 1234 ipv4-simple-service-config-srv-disabled, type: SRV} + ipv4-simple-service-config-srv-disabled: + - {TTL: '2100', data: 1.2.3.4, type: A} + srv-ipv4-simple-service-config-srv-disabled: + - {TTL: '2100', data: 5.5.3.4, type: A} + _grpc_config.srv-ipv4-simple-service-config-srv-disabled: + - {TTL: '2100', data: 'grpc_config=[{"serviceConfig":{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"SimpleService"}],"waitForReady":true}]}}]', + type: TXT} +- expected_addrs: + - {address: '1.2.3.4:1234', is_balancer: true} + expected_chosen_service_config: null + expected_service_config_error: null + expected_lb_policy: null + enable_srv_queries: true + enable_txt_queries: false + inject_broken_nameserver_list: false + record_to_resolve: srv-ipv4-simple-service-config-txt-disabled + records: + _grpclb._tcp.srv-ipv4-simple-service-config-txt-disabled: + - {TTL: '2100', data: 0 0 1234 ipv4-simple-service-config-txt-disabled, type: SRV} + ipv4-simple-service-config-txt-disabled: + - {TTL: '2100', data: 1.2.3.4, type: A} + _grpc_config.srv-ipv4-simple-service-config-txt-disabled: + - {TTL: '2100', data: 'grpc_config=[{"serviceConfig":{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"SimpleService"}],"waitForReady":true}]}}]', + type: TXT} +- expected_addrs: + - {address: '1.2.3.4:443', is_balancer: false} + expected_chosen_service_config: null + expected_service_config_error: null + expected_lb_policy: null + enable_srv_queries: true + enable_txt_queries: false + inject_broken_nameserver_list: false + record_to_resolve: ipv4-cpp-config-has-zero-percentage-txt-disabled + records: + ipv4-cpp-config-has-zero-percentage-txt-disabled: + - {TTL: '2100', data: 1.2.3.4, type: A} + _grpc_config.ipv4-cpp-config-has-zero-percentage-txt-disabled: + - {TTL: '2100', data: 'grpc_config=[{"percentage":0,"serviceConfig":{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"CppService"}],"waitForReady":true}]}}]', + type: TXT} +- expected_addrs: + - {address: '1.2.3.4:443', is_balancer: false} + expected_chosen_service_config: null + expected_service_config_error: null + expected_lb_policy: null + enable_srv_queries: true + enable_txt_queries: false + inject_broken_nameserver_list: false + record_to_resolve: ipv4-second-language-is-cpp-txt-disabled + records: + ipv4-second-language-is-cpp-txt-disabled: + - {TTL: '2100', data: 1.2.3.4, type: A} + _grpc_config.ipv4-second-language-is-cpp-txt-disabled: + - {TTL: '2100', data: 'grpc_config=[{"clientLanguage":["go"],"serviceConfig":{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"GoService"}],"waitForReady":true}]}},{"clientLanguage":["c++"],"serviceConfig":{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"CppService"}],"waitForReady":true}]}}]', + type: TXT} +- expected_addrs: + - {address: '1.2.3.4:443', is_balancer: false} + expected_chosen_service_config: null + expected_service_config_error: 'could not parse' + expected_lb_policy: null + enable_srv_queries: true + enable_txt_queries: true + inject_broken_nameserver_list: false + record_to_resolve: ipv4-svc_cfg_bad_json + records: + ipv4-svc_cfg_bad_json: + - {TTL: '2100', data: 1.2.3.4, type: A} + _grpc_config.ipv4-svc_cfg_bad_json: + - {TTL: '2100', data: 'grpc_config=[{]', + type: TXT} +- expected_addrs: + - {address: '1.2.3.4:443', is_balancer: false} + expected_chosen_service_config: null + expected_service_config_error: 'field:clientLanguage error:should be of type array' + expected_lb_policy: null + enable_srv_queries: true + enable_txt_queries: true + inject_broken_nameserver_list: false + record_to_resolve: ipv4-svc_cfg_bad_client_language + records: + ipv4-svc_cfg_bad_client_language: + - {TTL: '2100', data: 1.2.3.4, type: A} + _grpc_config.ipv4-svc_cfg_bad_client_language: + - {TTL: '2100', data: 'grpc_config=[{"clientLanguage":"go","serviceConfig":{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"GoService"}],"waitForReady":true}]}},{"clientLanguage":["c++"],"serviceConfig":{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"CppService"}],"waitForReady":true}]}}]', + type: TXT} +- expected_addrs: + - {address: '1.2.3.4:443', is_balancer: false} + expected_chosen_service_config: null + expected_service_config_error: 'field:percentage error:should be of type number' + expected_lb_policy: null + enable_srv_queries: true + enable_txt_queries: true + inject_broken_nameserver_list: false + record_to_resolve: ipv4-svc_cfg_bad_percentage + records: + ipv4-svc_cfg_bad_percentage: + - {TTL: '2100', data: 1.2.3.4, type: A} + _grpc_config.ipv4-svc_cfg_bad_percentage: + - {TTL: '2100', data: 'grpc_config=[{"percentage":"0","serviceConfig":{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"GoService"}],"waitForReady":true}]}},{"clientLanguage":["c++"],"serviceConfig":{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"CppService"}],"waitForReady":true}]}}]', + type: TXT} +- expected_addrs: + - {address: '1.2.3.4:443', is_balancer: false} + expected_chosen_service_config: null + expected_service_config_error: 'field:waitForReady error:Type should be true/false' + expected_lb_policy: null + enable_srv_queries: true + enable_txt_queries: true + inject_broken_nameserver_list: false + record_to_resolve: ipv4-svc_cfg_bad_wait_for_ready + records: + ipv4-svc_cfg_bad_wait_for_ready: + - {TTL: '2100', data: 1.2.3.4, type: A} + _grpc_config.ipv4-svc_cfg_bad_wait_for_ready: + - {TTL: '2100', data: 'grpc_config=[{"serviceConfig":{"methodConfig":[{"name":[{"method":"Foo","service":"CppService"}],"waitForReady":"true"}]}}]', + type: TXT} +# Tests for which we also exercise the resolver's ability to skip past a broken DNS server in its nameserver list +- expected_addrs: + - {address: '5.5.5.5:443', is_balancer: false} + expected_chosen_service_config: null + expected_service_config_error: null + expected_lb_policy: null + enable_srv_queries: true + enable_txt_queries: true + inject_broken_nameserver_list: true + record_to_resolve: no-srv-ipv4-single-target-inject-broken-nameservers + records: + no-srv-ipv4-single-target-inject-broken-nameservers: + - {TTL: '2100', data: 5.5.5.5, type: A} +- expected_addrs: + - {address: '1.2.3.4:443', is_balancer: 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_service_config_error: 'Service config parsing error' + expected_lb_policy: null + enable_srv_queries: true + enable_txt_queries: true + inject_broken_nameserver_list: true + record_to_resolve: ipv4-config-causing-fallback-to-tcp-inject-broken-nameservers + records: + ipv4-config-causing-fallback-to-tcp-inject-broken-nameservers: + - {TTL: '2100', data: 1.2.3.4, type: A} + _grpc_config.ipv4-config-causing-fallback-to-tcp-inject-broken-nameservers: - {TTL: '2100', data: 'grpc_config=[{"serviceConfig":{"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}]}]}}]', type: TXT} diff --git a/test/cpp/performance/BUILD b/test/cpp/performance/BUILD index 4fe95d5905e..6068c33f95f 100644 --- a/test/cpp/performance/BUILD +++ b/test/cpp/performance/BUILD @@ -31,4 +31,5 @@ grpc_cc_test( "//src/proto/grpc/testing:echo_proto", "//test/core/util:grpc_test_util_base", ], + tags = ["no_windows"], ) diff --git a/test/cpp/performance/writes_per_rpc_test.cc b/test/cpp/performance/writes_per_rpc_test.cc index baeede34ea4..b74f4d0466b 100644 --- a/test/cpp/performance/writes_per_rpc_test.cc +++ b/test/cpp/performance/writes_per_rpc_test.cc @@ -100,7 +100,7 @@ class EndpointPairFixture { } grpc_server_setup_transport(server_->c_server(), transport, nullptr, - server_args, 0); + server_args, nullptr); grpc_chttp2_transport_start_reading(transport, nullptr, nullptr); } @@ -118,7 +118,7 @@ class EndpointPairFixture { "target", &c_args, GRPC_CLIENT_DIRECT_CHANNEL, transport); grpc_chttp2_transport_start_reading(transport, nullptr, nullptr); - channel_ = CreateChannelInternal( + channel_ = ::grpc::CreateChannelInternal( "", channel, std::vector>()); @@ -255,7 +255,7 @@ TEST(WritesPerRpcTest, UnaryPingPong) { } // namespace grpc int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/cpp/qps/BUILD b/test/cpp/qps/BUILD index 26f43284a68..8855a1c155d 100644 --- a/test/cpp/qps/BUILD +++ b/test/cpp/qps/BUILD @@ -60,7 +60,6 @@ grpc_cc_library( "//src/proto/grpc/testing:payloads_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", "//test/cpp/util:test_config", "//test/cpp/util:test_util", @@ -86,7 +85,6 @@ grpc_cc_library( "//src/proto/grpc/testing:messages_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", ], @@ -170,7 +168,7 @@ grpc_cc_test( grpc_cc_test( name = "qps_openloop_test", srcs = ["qps_openloop_test.cc"], - data = ["//third_party/toolchains:RBE_USE_MACHINE_TYPE_LARGE"], + exec_compatible_with = ["//third_party/toolchains/machine_size:large"], deps = [ ":benchmark_config", ":driver_impl", @@ -205,7 +203,6 @@ grpc_cc_binary( deps = [ ":qps_worker_impl", "//:grpc++", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_config", "//test/cpp/util:test_util", diff --git a/test/cpp/qps/client.h b/test/cpp/qps/client.h index 668d9419169..ceb5cdd710d 100644 --- a/test/cpp/qps/client.h +++ b/test/cpp/qps/client.h @@ -236,58 +236,7 @@ class Client { return 0; } - protected: - bool closed_loop_; - gpr_atm thread_pool_done_; - double median_latency_collection_interval_seconds_; // In seconds - - void StartThreads(size_t num_threads) { - gpr_atm_rel_store(&thread_pool_done_, static_cast(false)); - threads_remaining_ = num_threads; - for (size_t i = 0; i < num_threads; i++) { - threads_.emplace_back(new Thread(this, i)); - } - } - - void EndThreads() { - MaybeStartRequests(); - threads_.clear(); - } - - virtual void DestroyMultithreading() = 0; - - void SetupLoadTest(const ClientConfig& config, size_t num_threads) { - // Set up the load distribution based on the number of threads - const auto& load = config.load_params(); - - std::unique_ptr random_dist; - switch (load.load_case()) { - case LoadParams::kClosedLoop: - // Closed-loop doesn't use random dist at all - break; - case LoadParams::kPoisson: - random_dist.reset( - new ExpDist(load.poisson().offered_load() / num_threads)); - break; - default: - GPR_ASSERT(false); - } - - // Set closed_loop_ based on whether or not random_dist is set - if (!random_dist) { - closed_loop_ = true; - } else { - closed_loop_ = false; - // set up interarrival timer according to random dist - interarrival_timer_.init(*random_dist, num_threads); - const auto now = gpr_now(GPR_CLOCK_MONOTONIC); - for (size_t i = 0; i < num_threads; i++) { - next_time_.push_back(gpr_time_add( - now, - gpr_time_from_nanos(interarrival_timer_.next(i), GPR_TIMESPAN))); - } - } - } + bool IsClosedLoop() { return closed_loop_; } gpr_timespec NextIssueTime(int thread_idx) { const gpr_timespec result = next_time_[thread_idx]; @@ -297,9 +246,9 @@ class Client { GPR_TIMESPAN)); return result; } - std::function NextIssuer(int thread_idx) { - return closed_loop_ ? std::function() - : std::bind(&Client::NextIssueTime, this, thread_idx); + + bool ThreadCompleted() { + return static_cast(gpr_atm_acq_load(&thread_pool_done_)); } class Thread { @@ -380,8 +329,62 @@ class Client { double interval_start_time_; }; - bool ThreadCompleted() { - return static_cast(gpr_atm_acq_load(&thread_pool_done_)); + protected: + bool closed_loop_; + gpr_atm thread_pool_done_; + double median_latency_collection_interval_seconds_; // In seconds + + void StartThreads(size_t num_threads) { + gpr_atm_rel_store(&thread_pool_done_, static_cast(false)); + threads_remaining_ = num_threads; + for (size_t i = 0; i < num_threads; i++) { + threads_.emplace_back(new Thread(this, i)); + } + } + + void EndThreads() { + MaybeStartRequests(); + threads_.clear(); + } + + virtual void DestroyMultithreading() = 0; + + void SetupLoadTest(const ClientConfig& config, size_t num_threads) { + // Set up the load distribution based on the number of threads + const auto& load = config.load_params(); + + std::unique_ptr random_dist; + switch (load.load_case()) { + case LoadParams::kClosedLoop: + // Closed-loop doesn't use random dist at all + break; + case LoadParams::kPoisson: + random_dist.reset( + new ExpDist(load.poisson().offered_load() / num_threads)); + break; + default: + GPR_ASSERT(false); + } + + // Set closed_loop_ based on whether or not random_dist is set + if (!random_dist) { + closed_loop_ = true; + } else { + closed_loop_ = false; + // set up interarrival timer according to random dist + interarrival_timer_.init(*random_dist, num_threads); + const auto now = gpr_now(GPR_CLOCK_MONOTONIC); + for (size_t i = 0; i < num_threads; i++) { + next_time_.push_back(gpr_time_add( + now, + gpr_time_from_nanos(interarrival_timer_.next(i), GPR_TIMESPAN))); + } + } + } + + std::function NextIssuer(int thread_idx) { + return closed_loop_ ? std::function() + : std::bind(&Client::NextIssueTime, this, thread_idx); } virtual void ThreadFunc(size_t thread_idx, Client::Thread* t) = 0; @@ -429,19 +432,69 @@ class ClientImpl : public Client { config.server_targets(i % config.server_targets_size()), config, create_stub_, i); } - std::vector> connecting_threads; - for (auto& c : channels_) { - connecting_threads.emplace_back(c.WaitForReady()); - } - for (auto& t : connecting_threads) { - t->join(); - } + WaitForChannelsToConnect(); median_latency_collection_interval_seconds_ = config.median_latency_collection_interval_millis() / 1e3; ClientRequestCreator create_req(&request_, config.payload_config()); } virtual ~ClientImpl() {} + const RequestType* request() { return &request_; } + + void WaitForChannelsToConnect() { + int connect_deadline_seconds = 10; + /* Allow optionally overriding connect_deadline in order + * to deal with benchmark environments in which the server + * can take a long time to become ready. */ + char* channel_connect_timeout_str = + gpr_getenv("QPS_WORKER_CHANNEL_CONNECT_TIMEOUT"); + if (channel_connect_timeout_str != nullptr && + strcmp(channel_connect_timeout_str, "") != 0) { + connect_deadline_seconds = atoi(channel_connect_timeout_str); + } + gpr_log(GPR_INFO, + "Waiting for up to %d seconds for all channels to connect", + connect_deadline_seconds); + gpr_free(channel_connect_timeout_str); + gpr_timespec connect_deadline = gpr_time_add( + gpr_now(GPR_CLOCK_REALTIME), + gpr_time_from_seconds(connect_deadline_seconds, GPR_TIMESPAN)); + CompletionQueue cq; + size_t num_remaining = 0; + for (auto& c : channels_) { + if (!c.is_inproc()) { + Channel* channel = c.get_channel(); + grpc_connectivity_state last_observed = channel->GetState(true); + if (last_observed == GRPC_CHANNEL_READY) { + gpr_log(GPR_INFO, "Channel %p connected!", channel); + } else { + num_remaining++; + channel->NotifyOnStateChange(last_observed, connect_deadline, &cq, + channel); + } + } + } + while (num_remaining > 0) { + bool ok = false; + void* tag = nullptr; + cq.Next(&tag, &ok); + Channel* channel = static_cast(tag); + if (!ok) { + gpr_log(GPR_ERROR, "Channel %p failed to connect within the deadline", + channel); + abort(); + } else { + grpc_connectivity_state last_observed = channel->GetState(true); + if (last_observed == GRPC_CHANNEL_READY) { + gpr_log(GPR_INFO, "Channel %p connected!", channel); + num_remaining--; + } else { + channel->NotifyOnStateChange(last_observed, connect_deadline, &cq, + channel); + } + } + } + } protected: const int cores_; @@ -485,31 +538,7 @@ class ClientImpl : public Client { } Channel* get_channel() { return channel_.get(); } StubType* get_stub() { return stub_.get(); } - - std::unique_ptr WaitForReady() { - return std::unique_ptr(new std::thread([this]() { - if (!is_inproc_) { - int connect_deadline = 10; - /* Allow optionally overriding connect_deadline in order - * to deal with benchmark environments in which the server - * can take a long time to become ready. */ - char* channel_connect_timeout_str = - gpr_getenv("QPS_WORKER_CHANNEL_CONNECT_TIMEOUT"); - if (channel_connect_timeout_str != nullptr && - strcmp(channel_connect_timeout_str, "") != 0) { - connect_deadline = atoi(channel_connect_timeout_str); - } - gpr_log(GPR_INFO, - "Waiting for up to %d seconds for the channel %p to connect", - connect_deadline, channel_.get()); - gpr_free(channel_connect_timeout_str); - GPR_ASSERT(channel_->WaitForConnected(gpr_time_add( - gpr_now(GPR_CLOCK_REALTIME), - gpr_time_from_seconds(connect_deadline, GPR_TIMESPAN)))); - gpr_log(GPR_INFO, "Channel %p connected!", channel_.get()); - } - })); - } + bool is_inproc() { return is_inproc_; } private: void set_channel_args(const ClientConfig& config, ChannelArguments* args) { diff --git a/test/cpp/qps/client_callback.cc b/test/cpp/qps/client_callback.cc index 87889e36dc5..dcfa2dbf875 100644 --- a/test/cpp/qps/client_callback.cc +++ b/test/cpp/qps/client_callback.cc @@ -66,13 +66,35 @@ class CallbackClient config, BenchmarkStubCreator) { num_threads_ = NumThreads(config); rpcs_done_ = 0; - SetupLoadTest(config, num_threads_); + + // Don't divide the fixed load among threads as the user threads + // only bootstrap the RPCs + SetupLoadTest(config, 1); total_outstanding_rpcs_ = config.client_channels() * config.outstanding_rpcs_per_channel(); } virtual ~CallbackClient() {} + /** + * The main thread of the benchmark will be waiting on DestroyMultithreading. + * Increment the rpcs_done_ variable to signify that the Callback RPC + * after thread completion is done. When the last outstanding rpc increments + * the counter it should also signal the main thread's conditional variable. + */ + void NotifyMainThreadOfThreadCompletion() { + std::lock_guard l(shutdown_mu_); + rpcs_done_++; + if (rpcs_done_ == total_outstanding_rpcs_) { + shutdown_cv_.notify_one(); + } + } + + gpr_timespec NextRPCIssueTime() { + std::lock_guard l(next_issue_time_mu_); + return Client::NextIssueTime(0); + } + protected: size_t num_threads_; size_t total_outstanding_rpcs_; @@ -93,24 +115,9 @@ class CallbackClient ThreadFuncImpl(t, thread_idx); } - virtual void ScheduleRpc(Thread* t, size_t thread_idx, - size_t ctx_vector_idx) = 0; - - /** - * The main thread of the benchmark will be waiting on DestroyMultithreading. - * Increment the rpcs_done_ variable to signify that the Callback RPC - * after thread completion is done. When the last outstanding rpc increments - * the counter it should also signal the main thread's conditional variable. - */ - void NotifyMainThreadOfThreadCompletion() { - std::lock_guard l(shutdown_mu_); - rpcs_done_++; - if (rpcs_done_ == total_outstanding_rpcs_) { - shutdown_cv_.notify_one(); - } - } - private: + std::mutex next_issue_time_mu_; // Used by next issue time + int NumThreads(const ClientConfig& config) { int num_threads = config.async_client_threads(); if (num_threads <= 0) { // Use dynamic sizing @@ -149,7 +156,7 @@ class CallbackUnaryClient final : public CallbackClient { bool ThreadFuncImpl(Thread* t, size_t thread_idx) override { for (size_t vector_idx = thread_idx; vector_idx < total_outstanding_rpcs_; vector_idx += num_threads_) { - ScheduleRpc(t, thread_idx, vector_idx); + ScheduleRpc(t, vector_idx); } return true; } @@ -157,26 +164,26 @@ class CallbackUnaryClient final : public CallbackClient { void InitThreadFuncImpl(size_t thread_idx) override { return; } private: - void ScheduleRpc(Thread* t, size_t thread_idx, size_t vector_idx) override { + void ScheduleRpc(Thread* t, size_t vector_idx) { if (!closed_loop_) { - gpr_timespec next_issue_time = NextIssueTime(thread_idx); + gpr_timespec next_issue_time = NextRPCIssueTime(); // Start an alarm callback to run the internal callback after // next_issue_time ctx_[vector_idx]->alarm_.experimental().Set( - next_issue_time, [this, t, thread_idx, vector_idx](bool ok) { - IssueUnaryCallbackRpc(t, thread_idx, vector_idx); + next_issue_time, [this, t, vector_idx](bool ok) { + IssueUnaryCallbackRpc(t, vector_idx); }); } else { - IssueUnaryCallbackRpc(t, thread_idx, vector_idx); + IssueUnaryCallbackRpc(t, vector_idx); } } - void IssueUnaryCallbackRpc(Thread* t, size_t thread_idx, size_t vector_idx) { + void IssueUnaryCallbackRpc(Thread* t, size_t vector_idx) { GPR_TIMER_SCOPE("CallbackUnaryClient::ThreadFunc", 0); double start = UsageTimer::Now(); ctx_[vector_idx]->stub_->experimental_async()->UnaryCall( (&ctx_[vector_idx]->context_), &request_, &ctx_[vector_idx]->response_, - [this, t, thread_idx, start, vector_idx](grpc::Status s) { + [this, t, start, vector_idx](grpc::Status s) { // Update Histogram with data from the callback run HistogramEntry entry; if (s.ok()) { @@ -193,17 +200,171 @@ class CallbackUnaryClient final : public CallbackClient { ctx_[vector_idx].reset( new CallbackClientRpcContext(ctx_[vector_idx]->stub_)); // Schedule a new RPC - ScheduleRpc(t, thread_idx, vector_idx); + ScheduleRpc(t, vector_idx); } }); } }; +class CallbackStreamingClient : public CallbackClient { + public: + CallbackStreamingClient(const ClientConfig& config) + : CallbackClient(config), + messages_per_stream_(config.messages_per_stream()) { + for (int ch = 0; ch < config.client_channels(); ch++) { + for (int i = 0; i < config.outstanding_rpcs_per_channel(); i++) { + ctx_.emplace_back( + new CallbackClientRpcContext(channels_[ch].get_stub())); + } + } + StartThreads(num_threads_); + } + ~CallbackStreamingClient() {} + + void AddHistogramEntry(double start, bool ok, Thread* thread_ptr) { + // Update Histogram with data from the callback run + HistogramEntry entry; + if (ok) { + entry.set_value((UsageTimer::Now() - start) * 1e9); + } + thread_ptr->UpdateHistogram(&entry); + } + + int messages_per_stream() { return messages_per_stream_; } + + protected: + const int messages_per_stream_; +}; + +class CallbackStreamingPingPongClient : public CallbackStreamingClient { + public: + CallbackStreamingPingPongClient(const ClientConfig& config) + : CallbackStreamingClient(config) {} + ~CallbackStreamingPingPongClient() {} +}; + +class CallbackStreamingPingPongReactor final + : public grpc::experimental::ClientBidiReactor { + public: + CallbackStreamingPingPongReactor( + CallbackStreamingPingPongClient* client, + std::unique_ptr ctx) + : client_(client), ctx_(std::move(ctx)), messages_issued_(0) {} + + void StartNewRpc() { + ctx_->stub_->experimental_async()->StreamingCall(&(ctx_->context_), this); + write_time_ = UsageTimer::Now(); + StartWrite(client_->request()); + writes_done_started_.clear(); + StartCall(); + } + + void OnWriteDone(bool ok) override { + if (!ok) { + gpr_log(GPR_ERROR, "Error writing RPC"); + } + if ((!ok || client_->ThreadCompleted()) && + !writes_done_started_.test_and_set()) { + StartWritesDone(); + } + StartRead(&ctx_->response_); + } + + void OnReadDone(bool ok) override { + client_->AddHistogramEntry(write_time_, ok, thread_ptr_); + + if (client_->ThreadCompleted() || !ok || + (client_->messages_per_stream() != 0 && + ++messages_issued_ >= client_->messages_per_stream())) { + if (!ok) { + gpr_log(GPR_ERROR, "Error reading RPC"); + } + if (!writes_done_started_.test_and_set()) { + StartWritesDone(); + } + return; + } + if (!client_->IsClosedLoop()) { + gpr_timespec next_issue_time = client_->NextRPCIssueTime(); + // Start an alarm callback to run the internal callback after + // next_issue_time + ctx_->alarm_.experimental().Set(next_issue_time, [this](bool ok) { + write_time_ = UsageTimer::Now(); + StartWrite(client_->request()); + }); + } else { + write_time_ = UsageTimer::Now(); + StartWrite(client_->request()); + } + } + + void OnDone(const Status& s) override { + if (client_->ThreadCompleted() || !s.ok()) { + client_->NotifyMainThreadOfThreadCompletion(); + return; + } + ctx_.reset(new CallbackClientRpcContext(ctx_->stub_)); + ScheduleRpc(); + } + + void ScheduleRpc() { + if (!client_->IsClosedLoop()) { + gpr_timespec next_issue_time = client_->NextRPCIssueTime(); + // Start an alarm callback to run the internal callback after + // next_issue_time + ctx_->alarm_.experimental().Set(next_issue_time, + [this](bool ok) { StartNewRpc(); }); + } else { + StartNewRpc(); + } + } + + void set_thread_ptr(Client::Thread* ptr) { thread_ptr_ = ptr; } + + CallbackStreamingPingPongClient* client_; + std::unique_ptr ctx_; + std::atomic_flag writes_done_started_; + Client::Thread* thread_ptr_; // Needed to update histogram entries + double write_time_; // Track ping-pong round start time + int messages_issued_; // Messages issued by this stream +}; + +class CallbackStreamingPingPongClientImpl final + : public CallbackStreamingPingPongClient { + public: + CallbackStreamingPingPongClientImpl(const ClientConfig& config) + : CallbackStreamingPingPongClient(config) { + for (size_t i = 0; i < total_outstanding_rpcs_; i++) + reactor_.emplace_back( + new CallbackStreamingPingPongReactor(this, std::move(ctx_[i]))); + } + ~CallbackStreamingPingPongClientImpl() {} + + bool ThreadFuncImpl(Client::Thread* t, size_t thread_idx) override { + for (size_t vector_idx = thread_idx; vector_idx < total_outstanding_rpcs_; + vector_idx += num_threads_) { + reactor_[vector_idx]->set_thread_ptr(t); + reactor_[vector_idx]->ScheduleRpc(); + } + return true; + } + + void InitThreadFuncImpl(size_t thread_idx) override {} + + private: + std::vector> reactor_; +}; + +// TODO(mhaidry) : Implement Streaming from client, server and both ways + std::unique_ptr CreateCallbackClient(const ClientConfig& config) { switch (config.rpc_type()) { case UNARY: return std::unique_ptr(new CallbackUnaryClient(config)); case STREAMING: + return std::unique_ptr( + new CallbackStreamingPingPongClientImpl(config)); case STREAMING_FROM_CLIENT: case STREAMING_FROM_SERVER: case STREAMING_BOTH_WAYS: diff --git a/test/cpp/qps/driver.cc b/test/cpp/qps/driver.cc index 11cfb4aa05a..7d4d5d99446 100644 --- a/test/cpp/qps/driver.cc +++ b/test/cpp/qps/driver.cc @@ -95,6 +95,17 @@ static deque get_workers(const string& env_name) { return out; } +std::string GetCredType( + const std::string& worker_addr, + const std::map& per_worker_credential_types, + const std::string& credential_type) { + auto it = per_worker_credential_types.find(worker_addr); + if (it != per_worker_credential_types.end()) { + return it->second; + } + return credential_type; +} + // helpers for postprocess_scenario_result static double WallTime(const ClientStats& s) { return s.time_elapsed(); } static double SystemTime(const ClientStats& s) { return s.time_system(); } @@ -198,8 +209,9 @@ std::unique_ptr RunScenario( const ServerConfig& initial_server_config, size_t num_servers, int warmup_seconds, int benchmark_seconds, int spawn_local_worker_count, const grpc::string& qps_server_target_override, - const grpc::string& credential_type, bool run_inproc, - int32_t median_latency_collection_interval_millis) { + const grpc::string& credential_type, + const std::map& per_worker_credential_types, + bool run_inproc, int32_t median_latency_collection_interval_millis) { if (run_inproc) { g_inproc_servers = new std::vector; } @@ -276,9 +288,11 @@ std::unique_ptr RunScenario( gpr_log(GPR_INFO, "Starting server on %s (worker #%" PRIuPTR ")", workers[i].c_str(), i); if (!run_inproc) { - servers[i].stub = WorkerService::NewStub(CreateChannel( + servers[i].stub = WorkerService::NewStub(grpc::CreateChannel( workers[i], GetCredentialsProvider()->GetChannelCredentials( - credential_type, &channel_args))); + GetCredType(workers[i], per_worker_credential_types, + credential_type), + &channel_args))); } else { servers[i].stub = WorkerService::NewStub( local_workers[i]->InProcessChannel(channel_args)); @@ -335,9 +349,11 @@ std::unique_ptr RunScenario( gpr_log(GPR_INFO, "Starting client on %s (worker #%" PRIuPTR ")", worker.c_str(), i + num_servers); if (!run_inproc) { - clients[i].stub = WorkerService::NewStub( - CreateChannel(worker, GetCredentialsProvider()->GetChannelCredentials( - credential_type, &channel_args))); + clients[i].stub = WorkerService::NewStub(grpc::CreateChannel( + worker, + GetCredentialsProvider()->GetChannelCredentials( + GetCredType(worker, per_worker_credential_types, credential_type), + &channel_args))); } else { clients[i].stub = WorkerService::NewStub( local_workers[i + num_servers]->InProcessChannel(channel_args)); @@ -529,7 +545,9 @@ std::unique_ptr RunScenario( return result; } -bool RunQuit(const grpc::string& credential_type) { +bool RunQuit( + const grpc::string& credential_type, + const std::map& per_worker_credential_types) { // Get client, server lists bool result = true; auto workers = get_workers("QPS_WORKERS"); @@ -539,9 +557,11 @@ bool RunQuit(const grpc::string& credential_type) { ChannelArguments channel_args; for (size_t i = 0; i < workers.size(); i++) { - auto stub = WorkerService::NewStub(CreateChannel( + auto stub = WorkerService::NewStub(grpc::CreateChannel( workers[i], GetCredentialsProvider()->GetChannelCredentials( - credential_type, &channel_args))); + GetCredType(workers[i], per_worker_credential_types, + credential_type), + &channel_args))); Void dummy; grpc::ClientContext ctx; ctx.set_wait_for_ready(true); diff --git a/test/cpp/qps/driver.h b/test/cpp/qps/driver.h index cda89f7ddfd..568871d2daa 100644 --- a/test/cpp/qps/driver.h +++ b/test/cpp/qps/driver.h @@ -32,10 +32,13 @@ std::unique_ptr RunScenario( const grpc::testing::ServerConfig& server_config, size_t num_servers, int warmup_seconds, int benchmark_seconds, int spawn_local_worker_count, const grpc::string& qps_server_target_override, - const grpc::string& credential_type, bool run_inproc, - int32_t median_latency_collection_interval_millis); + const grpc::string& credential_type, + const std::map& per_worker_credential_types, + bool run_inproc, int32_t median_latency_collection_interval_millis); -bool RunQuit(const grpc::string& credential_type); +bool RunQuit( + const grpc::string& credential_type, + const std::map& per_worker_credential_types); } // namespace testing } // namespace grpc diff --git a/test/cpp/qps/gen_build_yaml.py b/test/cpp/qps/gen_build_yaml.py index fb2caf5486a..8ca0dc6a620 100755 --- a/test/cpp/qps/gen_build_yaml.py +++ b/test/cpp/qps/gen_build_yaml.py @@ -131,4 +131,4 @@ def generate_yaml(): } -print(yaml.dump(generate_yaml())) \ No newline at end of file +print(yaml.dump(generate_yaml())) diff --git a/test/cpp/qps/inproc_sync_unary_ping_pong_test.cc b/test/cpp/qps/inproc_sync_unary_ping_pong_test.cc index 56d1730252f..6257e42ebf4 100644 --- a/test/cpp/qps/inproc_sync_unary_ping_pong_test.cc +++ b/test/cpp/qps/inproc_sync_unary_ping_pong_test.cc @@ -48,7 +48,7 @@ static void RunSynchronousUnaryPingPong() { const auto result = RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK, -2, "", - kInsecureCredentialsType, true, 0); + kInsecureCredentialsType, {}, true, 0); GetReporter()->ReportQPS(*result); GetReporter()->ReportLatency(*result); diff --git a/test/cpp/qps/json_run_localhost.cc b/test/cpp/qps/json_run_localhost.cc index 948c3088e67..42cc9e0ed76 100644 --- a/test/cpp/qps/json_run_localhost.cc +++ b/test/cpp/qps/json_run_localhost.cc @@ -24,6 +24,10 @@ #include #include +#ifdef __FreeBSD__ +#include +#endif + #include #include "src/core/lib/gpr/env.h" diff --git a/test/cpp/qps/qps_benchmark_script.bzl b/test/cpp/qps/qps_benchmark_script.bzl index b2b67d988ce..b4767ec8e09 100644 --- a/test/cpp/qps/qps_benchmark_script.bzl +++ b/test/cpp/qps/qps_benchmark_script.bzl @@ -69,12 +69,12 @@ def json_run_localhost_batch(): ], deps = [ "//:gpr", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_config", "//test/cpp/util:test_util", ], tags = [ "json_run_localhost", + "no_windows", ], ) diff --git a/test/cpp/qps/qps_json_driver.cc b/test/cpp/qps/qps_json_driver.cc index eaa0dd992c5..1d67e79b868 100644 --- a/test/cpp/qps/qps_json_driver.cc +++ b/test/cpp/qps/qps_json_driver.cc @@ -65,6 +65,16 @@ DEFINE_string(json_file_out, "", "File to write the JSON output to."); DEFINE_string(credential_type, grpc::testing::kInsecureCredentialsType, "Credential type for communication with workers"); +DEFINE_string( + per_worker_credential_types, "", + "A map of QPS worker addresses to credential types. When creating a " + "channel to a QPS worker's driver port, the qps_json_driver first checks " + "if the 'name:port' string is in the map, and it uses the corresponding " + "credential type if so. If the QPS worker's 'name:port' string is not " + "in the map, then the driver -> worker channel will be created with " + "the credentials specified in --credential_type. The value of this flag " + "is a semicolon-separated list of map entries, where each map entry is " + "a comma-separated pair."); DEFINE_bool(run_inproc, false, "Perform an in-process transport test"); DEFINE_int32( median_latency_collection_interval_millis, 0, @@ -75,16 +85,53 @@ DEFINE_int32( namespace grpc { namespace testing { -static std::unique_ptr RunAndReport(const Scenario& scenario, - bool* success) { +static std::map +ConstructPerWorkerCredentialTypesMap() { + // Parse a list of the form: "addr1,cred_type1;addr2,cred_type2;..." into + // a map. + std::string remaining = FLAGS_per_worker_credential_types; + std::map out; + while (!remaining.empty()) { + size_t next_semicolon = remaining.find(';'); + std::string next_entry = remaining.substr(0, next_semicolon); + if (next_semicolon == std::string::npos) { + remaining = ""; + } else { + remaining = remaining.substr(next_semicolon + 1, std::string::npos); + } + size_t comma = next_entry.find(','); + if (comma == std::string::npos) { + gpr_log(GPR_ERROR, + "Expectd --per_worker_credential_types to be a list " + "of the form: 'addr1,cred_type1;addr2,cred_type2;...' " + "into."); + abort(); + } + std::string addr = next_entry.substr(0, comma); + std::string cred_type = next_entry.substr(comma + 1, std::string::npos); + if (out.find(addr) != out.end()) { + gpr_log(GPR_ERROR, + "Found duplicate addr in per_worker_credential_types."); + abort(); + } + out[addr] = cred_type; + } + return out; +} + +static std::unique_ptr RunAndReport( + const Scenario& scenario, + const std::map& per_worker_credential_types, + bool* success) { std::cerr << "RUNNING SCENARIO: " << scenario.name() << "\n"; - auto result = RunScenario( - scenario.client_config(), scenario.num_clients(), - scenario.server_config(), scenario.num_servers(), - scenario.warmup_seconds(), scenario.benchmark_seconds(), - !FLAGS_run_inproc ? scenario.spawn_local_worker_count() : -2, - FLAGS_qps_server_target_override, FLAGS_credential_type, FLAGS_run_inproc, - FLAGS_median_latency_collection_interval_millis); + auto result = + RunScenario(scenario.client_config(), scenario.num_clients(), + scenario.server_config(), scenario.num_servers(), + scenario.warmup_seconds(), scenario.benchmark_seconds(), + !FLAGS_run_inproc ? scenario.spawn_local_worker_count() : -2, + FLAGS_qps_server_target_override, FLAGS_credential_type, + per_worker_credential_types, FLAGS_run_inproc, + FLAGS_median_latency_collection_interval_millis); // Amend the result with scenario config. Eventually we should adjust // RunScenario contract so we don't need to touch the result here. @@ -115,21 +162,26 @@ static std::unique_ptr RunAndReport(const Scenario& scenario, return result; } -static double GetCpuLoad(Scenario* scenario, double offered_load, - bool* success) { +static double GetCpuLoad( + Scenario* scenario, double offered_load, + const std::map& per_worker_credential_types, + bool* success) { scenario->mutable_client_config() ->mutable_load_params() ->mutable_poisson() ->set_offered_load(offered_load); - auto result = RunAndReport(*scenario, success); + auto result = RunAndReport(*scenario, per_worker_credential_types, success); return result->summary().server_cpu_usage(); } -static double BinarySearch(Scenario* scenario, double targeted_cpu_load, - double low, double high, bool* success) { +static double BinarySearch( + Scenario* scenario, double targeted_cpu_load, double low, double high, + const std::map& per_worker_credential_types, + bool* success) { while (low <= high * (1 - FLAGS_error_tolerance)) { double mid = low + (high - low) / 2; - double current_cpu_load = GetCpuLoad(scenario, mid, success); + double current_cpu_load = + GetCpuLoad(scenario, mid, per_worker_credential_types, success); gpr_log(GPR_DEBUG, "Binary Search: current_offered_load %.0f", mid); if (!*success) { gpr_log(GPR_ERROR, "Client/Server Failure"); @@ -145,12 +197,14 @@ static double BinarySearch(Scenario* scenario, double targeted_cpu_load, return low; } -static double SearchOfferedLoad(double initial_offered_load, - double targeted_cpu_load, Scenario* scenario, - bool* success) { +static double SearchOfferedLoad( + double initial_offered_load, double targeted_cpu_load, Scenario* scenario, + const std::map& per_worker_credential_types, + bool* success) { std::cerr << "RUNNING SCENARIO: " << scenario->name() << "\n"; double current_offered_load = initial_offered_load; - double current_cpu_load = GetCpuLoad(scenario, current_offered_load, success); + double current_cpu_load = GetCpuLoad(scenario, current_offered_load, + per_worker_credential_types, success); if (current_cpu_load > targeted_cpu_load) { gpr_log(GPR_ERROR, "Initial offered load too high"); return -1; @@ -158,14 +212,15 @@ static double SearchOfferedLoad(double initial_offered_load, while (*success && (current_cpu_load < targeted_cpu_load)) { current_offered_load *= 2; - current_cpu_load = GetCpuLoad(scenario, current_offered_load, success); + current_cpu_load = GetCpuLoad(scenario, current_offered_load, + per_worker_credential_types, success); gpr_log(GPR_DEBUG, "Binary Search: current_offered_load %.0f", current_offered_load); } double targeted_offered_load = BinarySearch(scenario, targeted_cpu_load, current_offered_load / 2, - current_offered_load, success); + current_offered_load, per_worker_credential_types, success); return targeted_offered_load; } @@ -183,6 +238,7 @@ static bool QpsDriver() { abort(); } + auto per_worker_credential_types = ConstructPerWorkerCredentialTypesMap(); if (scfile) { // Read the json data from disk FILE* json_file = fopen(FLAGS_scenarios_file.c_str(), "r"); @@ -198,7 +254,7 @@ static bool QpsDriver() { } else if (scjson) { json = FLAGS_scenarios_json.c_str(); } else if (FLAGS_quit) { - return RunQuit(FLAGS_credential_type); + return RunQuit(FLAGS_credential_type, per_worker_credential_types); } // Parse into an array of scenarios @@ -212,15 +268,16 @@ static bool QpsDriver() { for (int i = 0; i < scenarios.scenarios_size(); i++) { if (FLAGS_search_param == "") { const Scenario& scenario = scenarios.scenarios(i); - RunAndReport(scenario, &success); + RunAndReport(scenario, per_worker_credential_types, &success); } else { if (FLAGS_search_param == "offered_load") { Scenario* scenario = scenarios.mutable_scenarios(i); - double targeted_offered_load = - SearchOfferedLoad(FLAGS_initial_search_value, - FLAGS_targeted_cpu_load, scenario, &success); + double targeted_offered_load = SearchOfferedLoad( + FLAGS_initial_search_value, FLAGS_targeted_cpu_load, scenario, + per_worker_credential_types, &success); gpr_log(GPR_INFO, "targeted_offered_load %f", targeted_offered_load); - GetCpuLoad(scenario, targeted_offered_load, &success); + GetCpuLoad(scenario, targeted_offered_load, per_worker_credential_types, + &success); } else { gpr_log(GPR_ERROR, "Unimplemented search param"); } diff --git a/test/cpp/qps/qps_openloop_test.cc b/test/cpp/qps/qps_openloop_test.cc index 6044f4265a3..68062e66f25 100644 --- a/test/cpp/qps/qps_openloop_test.cc +++ b/test/cpp/qps/qps_openloop_test.cc @@ -52,7 +52,7 @@ static void RunQPS() { const auto result = RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK, -2, "", - kInsecureCredentialsType, false, 0); + kInsecureCredentialsType, {}, false, 0); GetReporter()->ReportQPSPerCore(*result); GetReporter()->ReportLatency(*result); diff --git a/test/cpp/qps/secure_sync_unary_ping_pong_test.cc b/test/cpp/qps/secure_sync_unary_ping_pong_test.cc index a559c82cc81..422bd617ebc 100644 --- a/test/cpp/qps/secure_sync_unary_ping_pong_test.cc +++ b/test/cpp/qps/secure_sync_unary_ping_pong_test.cc @@ -55,7 +55,7 @@ static void RunSynchronousUnaryPingPong() { const auto result = RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK, -2, "", - kInsecureCredentialsType, false, 0); + kInsecureCredentialsType, {}, false, 0); GetReporter()->ReportQPS(*result); GetReporter()->ReportLatency(*result); diff --git a/test/cpp/qps/server_callback.cc b/test/cpp/qps/server_callback.cc index 8bedd447392..4a346dd0178 100644 --- a/test/cpp/qps/server_callback.cc +++ b/test/cpp/qps/server_callback.cc @@ -34,13 +34,53 @@ class BenchmarkCallbackServiceImpl final : public BenchmarkService::ExperimentalCallbackService { public: void UnaryCall( - ServerContext* context, const SimpleRequest* request, - SimpleResponse* response, - experimental::ServerCallbackRpcController* controller) override { + ServerContext* context, const ::grpc::testing::SimpleRequest* request, + ::grpc::testing::SimpleResponse* response, + ::grpc::experimental::ServerCallbackRpcController* controller) override { auto s = SetResponse(request, response); controller->Finish(s); } + ::grpc::experimental::ServerBidiReactor<::grpc::testing::SimpleRequest, + ::grpc::testing::SimpleResponse>* + StreamingCall() override { + class Reactor + : public ::grpc::experimental::ServerBidiReactor< + ::grpc::testing::SimpleRequest, ::grpc::testing::SimpleResponse> { + public: + Reactor() {} + void OnStarted(ServerContext* context) override { StartRead(&request_); } + + void OnReadDone(bool ok) override { + if (!ok) { + Finish(::grpc::Status::OK); + return; + } + auto s = SetResponse(&request_, &response_); + if (!s.ok()) { + Finish(s); + return; + } + StartWrite(&response_); + } + + void OnWriteDone(bool ok) override { + if (!ok) { + Finish(::grpc::Status::OK); + return; + } + StartRead(&request_); + } + + void OnDone() override { delete (this); } + + private: + SimpleRequest request_; + SimpleResponse response_; + }; + return new Reactor; + } + private: static Status SetResponse(const SimpleRequest* request, SimpleResponse* response) { diff --git a/test/cpp/server/BUILD b/test/cpp/server/BUILD index 3f89d6e26e3..a4811031691 100644 --- a/test/cpp/server/BUILD +++ b/test/cpp/server/BUILD @@ -21,38 +21,41 @@ grpc_package(name = "test/cpp/server") grpc_cc_test( name = "server_builder_test", srcs = ["server_builder_test.cc"], + external_deps = [ + "gtest", + ], deps = [ "//:grpc++_unsecure", "//src/proto/grpc/testing:echo_proto", "//test/core/util:grpc_test_util_unsecure", ], - external_deps = [ - "gtest", - ], + tags = ["no_windows"], ) grpc_cc_test( name = "server_builder_with_socket_mutator_test", srcs = ["server_builder_with_socket_mutator_test.cc"], + external_deps = [ + "gtest", + ], deps = [ "//:grpc++_unsecure", "//src/proto/grpc/testing:echo_proto", "//test/core/util:grpc_test_util_unsecure", ], - external_deps = [ - "gtest", - ], + tags = ["no_windows"], ) grpc_cc_test( name = "server_request_call_test", srcs = ["server_request_call_test.cc"], + external_deps = [ + "gtest", + ], deps = [ "//:grpc++_unsecure", "//src/proto/grpc/testing:echo_proto", "//test/core/util:grpc_test_util_unsecure", ], - external_deps = [ - "gtest", - ], + tags = ["no_windows"], ) diff --git a/test/cpp/server/load_reporter/BUILD b/test/cpp/server/load_reporter/BUILD index b7c4d29d719..db5c93263ad 100644 --- a/test/cpp/server/load_reporter/BUILD +++ b/test/cpp/server/load_reporter/BUILD @@ -43,9 +43,9 @@ grpc_cc_test( "//:grpc", "//:lb_load_reporter", "//:lb_server_load_reporting_filter", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], + tags = ["no_windows"], ) grpc_cc_test( @@ -58,7 +58,6 @@ grpc_cc_test( "//:gpr", "//:grpc", "//:lb_get_cpu_stats", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], ) diff --git a/test/cpp/server/load_reporter/get_cpu_stats_test.cc b/test/cpp/server/load_reporter/get_cpu_stats_test.cc index 5b1d5fa3a49..98c15b2c69b 100644 --- a/test/cpp/server/load_reporter/get_cpu_stats_test.cc +++ b/test/cpp/server/load_reporter/get_cpu_stats_test.cc @@ -55,7 +55,7 @@ TEST(GetCpuStatsTest, Ascending) { } // namespace grpc int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/cpp/server/load_reporter/load_data_store_test.cc b/test/cpp/server/load_reporter/load_data_store_test.cc index c92c407e4f8..a3a67a28516 100644 --- a/test/cpp/server/load_reporter/load_data_store_test.cc +++ b/test/cpp/server/load_reporter/load_data_store_test.cc @@ -475,7 +475,7 @@ TEST_F(PerBalancerStoreTest, DataAggregation) { } // namespace grpc int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/cpp/server/load_reporter/load_reporter_test.cc b/test/cpp/server/load_reporter/load_reporter_test.cc index 0d56cdf431d..9d2ebfb0b4f 100644 --- a/test/cpp/server/load_reporter/load_reporter_test.cc +++ b/test/cpp/server/load_reporter/load_reporter_test.cc @@ -501,7 +501,7 @@ TEST_F(LoadReportTest, BasicReport) { } // namespace grpc int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/cpp/server/server_request_call_test.cc b/test/cpp/server/server_request_call_test.cc index 9831c061766..14b735cf13d 100644 --- a/test/cpp/server/server_request_call_test.cc +++ b/test/cpp/server/server_request_call_test.cc @@ -115,7 +115,7 @@ TEST(ServerRequestCallTest, ShortDeadlineDoesNotCauseOkayFalse) { }); auto stub = testing::EchoTestService::NewStub( - CreateChannel(address, InsecureChannelCredentials())); + grpc::CreateChannel(address, InsecureChannelCredentials())); for (int i = 0; i < 100; i++) { gpr_log(GPR_INFO, "Sending %d.", i); diff --git a/test/cpp/test/BUILD b/test/cpp/test/BUILD index c5494789190..cd980dee84d 100644 --- a/test/cpp/test/BUILD +++ b/test/cpp/test/BUILD @@ -32,7 +32,6 @@ grpc_cc_test( "//:grpc", "//:grpc++", "//:grpc++_test", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], diff --git a/test/cpp/thread_manager/BUILD b/test/cpp/thread_manager/BUILD index 093e51e3faa..30488774e4e 100644 --- a/test/cpp/thread_manager/BUILD +++ b/test/cpp/thread_manager/BUILD @@ -32,7 +32,6 @@ grpc_cc_test( "//:gpr", "//:grpc", "//:grpc++", - "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", "//test/cpp/util:test_config", "//test/cpp/util:test_util", diff --git a/test/cpp/util/BUILD b/test/cpp/util/BUILD index 57eaf3baf2f..bb1ca868ffb 100644 --- a/test/cpp/util/BUILD +++ b/test/cpp/util/BUILD @@ -93,14 +93,14 @@ grpc_cc_library( hdrs = [ "channel_trace_proto_helper.h", ], - deps = [ - "//:grpc++", - "//src/proto/grpc/channelz:channelz_proto", - ], external_deps = [ "gtest", "protobuf", ], + deps = [ + "//:grpc++", + "//src/proto/grpc/channelz:channelz_proto", + ], ) grpc_cc_library( @@ -181,6 +181,7 @@ grpc_cc_test( data = [ "//src/proto/grpc/testing:echo.proto", "//src/proto/grpc/testing:echo_messages.proto", + "//src/proto/grpc/testing:simple_messages.proto", ], external_deps = [ "gtest", @@ -192,6 +193,7 @@ grpc_cc_test( "//:grpc++_reflection", "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", + "//src/proto/grpc/testing:simple_messages_proto", "//test/core/end2end:ssl_test_data", "//test/core/util:grpc_test_util", ], @@ -233,7 +235,7 @@ grpc_cc_test( ], deps = [ "//:grpc++", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -277,7 +279,7 @@ grpc_cc_test( deps = [ "//:grpc++_error_details", "//src/proto/grpc/testing:echo_messages_proto", - "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) @@ -290,8 +292,8 @@ grpc_cc_binary( "gflags", ], deps = [ - ":grpc_cli_libs", ":grpc++_proto_reflection_desc_db", + ":grpc_cli_libs", ":test_config", "//:grpc++", "//src/proto/grpc/reflection/v1alpha:reflection_proto", diff --git a/test/cpp/util/channel_trace_proto_helper.cc b/test/cpp/util/channel_trace_proto_helper.cc index ff9d8873858..9137eda8e07 100644 --- a/test/cpp/util/channel_trace_proto_helper.cc +++ b/test/cpp/util/channel_trace_proto_helper.cc @@ -16,19 +16,19 @@ * */ -#include "test/cpp/util/channel_trace_proto_helper.h" +#include -#include -#include +#include "test/cpp/util/channel_trace_proto_helper.h" #include #include +#include +#include #include #include "src/proto/grpc/channelz/channelz.pb.h" namespace grpc { -namespace testing { namespace { @@ -37,26 +37,25 @@ namespace { // according to https://developers.google.com/protocol-buffers/docs/proto3#json template void VaidateProtoJsonTranslation(char* json_c_str) { - std::string json_str(json_c_str); + grpc::string json_str(json_c_str); Message msg; - google::protobuf::util::JsonParseOptions parse_options; + grpc::protobuf::json::JsonParseOptions parse_options; // If the following line is failing, then uncomment the last line of the // comment, and uncomment the lines that print the two strings. You can // then compare the output, and determine what fields are missing. // // parse_options.ignore_unknown_fields = true; - EXPECT_EQ(google::protobuf::util::JsonStringToMessage(json_str, &msg, - parse_options), - google::protobuf::util::Status::OK); - std::string proto_json_str; - google::protobuf::util::JsonPrintOptions print_options; + grpc::protobuf::util::Status s = + grpc::protobuf::json::JsonStringToMessage(json_str, &msg, parse_options); + EXPECT_TRUE(s.ok()); + grpc::string proto_json_str; + grpc::protobuf::json::JsonPrintOptions print_options; // We usually do not want this to be true, however it can be helpful to // uncomment and see the output produced then all fields are printed. // print_options.always_print_primitive_fields = true; - EXPECT_EQ(google::protobuf::util::MessageToJsonString(msg, &proto_json_str, - print_options), - google::protobuf::util::Status::OK); - // uncomment these to compare the the json strings. + s = grpc::protobuf::json::MessageToJsonString(msg, &proto_json_str); + EXPECT_TRUE(s.ok()); + // uncomment these to compare the json strings. // gpr_log(GPR_ERROR, "tracer json: %s", json_str.c_str()); // gpr_log(GPR_ERROR, "proto json: %s", proto_json_str.c_str()); EXPECT_EQ(json_str, proto_json_str); @@ -64,6 +63,8 @@ void VaidateProtoJsonTranslation(char* json_c_str) { } // namespace +namespace testing { + void ValidateChannelTraceProtoJsonTranslation(char* json_c_str) { VaidateProtoJsonTranslation(json_c_str); } diff --git a/test/cpp/util/cli_call_test.cc b/test/cpp/util/cli_call_test.cc index 516f3fa53dc..a91705bd514 100644 --- a/test/cpp/util/cli_call_test.cc +++ b/test/cpp/util/cli_call_test.cc @@ -74,8 +74,8 @@ class CliCallTest : public ::testing::Test { void TearDown() override { server_->Shutdown(); } void ResetStub() { - channel_ = - CreateChannel(server_address_.str(), InsecureChannelCredentials()); + channel_ = grpc::CreateChannel(server_address_.str(), + InsecureChannelCredentials()); stub_ = grpc::testing::EchoTestService::NewStub(channel_); } @@ -122,7 +122,7 @@ TEST_F(CliCallTest, SimpleRpc) { } // namespace grpc int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/cpp/util/create_test_channel.cc b/test/cpp/util/create_test_channel.cc index 0bcd4dbc844..5c32198bc3a 100644 --- a/test/cpp/util/create_test_channel.cc +++ b/test/cpp/util/create_test_channel.cc @@ -34,7 +34,7 @@ class SslCredentialProvider : public testing::CredentialTypeProvider { public: std::shared_ptr GetChannelCredentials( grpc::ChannelArguments* args) override { - return SslCredentials(SslCredentialsOptions()); + return grpc::SslCredentials(SslCredentialsOptions()); } std::shared_ptr GetServerCredentials() override { return nullptr; @@ -71,38 +71,9 @@ std::shared_ptr CreateTestChannel( const grpc::string& override_hostname, bool use_prod_roots, const std::shared_ptr& creds, const ChannelArguments& args) { - ChannelArguments channel_args(args); - std::shared_ptr channel_creds; - if (cred_type.empty()) { - return CreateCustomChannel(server, InsecureChannelCredentials(), args); - } else if (cred_type == testing::kTlsCredentialsType) { // cred_type == "ssl" - if (use_prod_roots) { - gpr_once_init(&g_once_init_add_prod_ssl_provider, &AddProdSslType); - channel_creds = testing::GetCredentialsProvider()->GetChannelCredentials( - kProdTlsCredentialsType, &channel_args); - if (!server.empty() && !override_hostname.empty()) { - channel_args.SetSslTargetNameOverride(override_hostname); - } - } else { - // override_hostname is discarded as the provider handles it. - channel_creds = testing::GetCredentialsProvider()->GetChannelCredentials( - testing::kTlsCredentialsType, &channel_args); - } - GPR_ASSERT(channel_creds != nullptr); - - const grpc::string& connect_to = - server.empty() ? override_hostname : server; - if (creds.get()) { - channel_creds = CompositeChannelCredentials(channel_creds, creds); - } - return CreateCustomChannel(connect_to, channel_creds, channel_args); - } else { - channel_creds = testing::GetCredentialsProvider()->GetChannelCredentials( - cred_type, &channel_args); - GPR_ASSERT(channel_creds != nullptr); - - return CreateCustomChannel(server, channel_creds, args); - } + return CreateTestChannel(server, cred_type, override_hostname, use_prod_roots, + creds, args, + /*interceptor_creators=*/{}); } std::shared_ptr CreateTestChannel( @@ -110,13 +81,9 @@ std::shared_ptr CreateTestChannel( testing::transport_security security_type, bool use_prod_roots, const std::shared_ptr& creds, const ChannelArguments& args) { - 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); + return CreateTestChannel(server, override_hostname, security_type, + use_prod_roots, creds, args, + /*interceptor_creators=*/{}); } std::shared_ptr CreateTestChannel( @@ -149,9 +116,116 @@ std::shared_ptr CreateTestChannel( &channel_args); GPR_ASSERT(channel_creds != nullptr); if (creds.get()) { - channel_creds = CompositeChannelCredentials(channel_creds, creds); + channel_creds = grpc::CompositeChannelCredentials(channel_creds, creds); } - return CreateCustomChannel(server, channel_creds, channel_args); + return ::grpc::CreateCustomChannel(server, channel_creds, channel_args); +} + +std::shared_ptr CreateTestChannel( + const grpc::string& server, const grpc::string& cred_type, + const grpc::string& override_hostname, bool use_prod_roots, + const std::shared_ptr& creds, const ChannelArguments& args, + std::vector< + std::unique_ptr> + interceptor_creators) { + ChannelArguments channel_args(args); + std::shared_ptr channel_creds; + if (cred_type.empty()) { + if (interceptor_creators.empty()) { + return ::grpc::CreateCustomChannel(server, InsecureChannelCredentials(), + args); + } else { + return experimental::CreateCustomChannelWithInterceptors( + server, InsecureChannelCredentials(), args, + std::move(interceptor_creators)); + } + } else if (cred_type == testing::kTlsCredentialsType) { // cred_type == "ssl" + if (use_prod_roots) { + gpr_once_init(&g_once_init_add_prod_ssl_provider, &AddProdSslType); + channel_creds = testing::GetCredentialsProvider()->GetChannelCredentials( + kProdTlsCredentialsType, &channel_args); + if (!server.empty() && !override_hostname.empty()) { + channel_args.SetSslTargetNameOverride(override_hostname); + } + } else { + // override_hostname is discarded as the provider handles it. + channel_creds = testing::GetCredentialsProvider()->GetChannelCredentials( + testing::kTlsCredentialsType, &channel_args); + } + GPR_ASSERT(channel_creds != nullptr); + + const grpc::string& connect_to = + server.empty() ? override_hostname : server; + if (creds.get()) { + channel_creds = grpc::CompositeChannelCredentials(channel_creds, creds); + } + if (interceptor_creators.empty()) { + return ::grpc::CreateCustomChannel(connect_to, channel_creds, + channel_args); + } else { + return experimental::CreateCustomChannelWithInterceptors( + connect_to, channel_creds, channel_args, + std::move(interceptor_creators)); + } + } else { + channel_creds = testing::GetCredentialsProvider()->GetChannelCredentials( + cred_type, &channel_args); + GPR_ASSERT(channel_creds != nullptr); + + if (interceptor_creators.empty()) { + return ::grpc::CreateCustomChannel(server, channel_creds, args); + } else { + return experimental::CreateCustomChannelWithInterceptors( + server, channel_creds, args, std::move(interceptor_creators)); + } + } +} + +std::shared_ptr CreateTestChannel( + const grpc::string& server, const grpc::string& override_hostname, + testing::transport_security security_type, bool use_prod_roots, + const std::shared_ptr& creds, const ChannelArguments& args, + std::vector< + std::unique_ptr> + interceptor_creators) { + grpc::string credential_type = + security_type == testing::ALTS + ? testing::kAltsCredentialsType + : (security_type == testing::TLS ? testing::kTlsCredentialsType + : testing::kInsecureCredentialsType); + return CreateTestChannel(server, credential_type, override_hostname, + use_prod_roots, creds, args, + std::move(interceptor_creators)); +} + +std::shared_ptr CreateTestChannel( + const grpc::string& server, const grpc::string& override_hostname, + testing::transport_security security_type, bool use_prod_roots, + const std::shared_ptr& creds, + std::vector< + std::unique_ptr> + interceptor_creators) { + return CreateTestChannel(server, override_hostname, security_type, + use_prod_roots, creds, ChannelArguments(), + std::move(interceptor_creators)); +} + +std::shared_ptr CreateTestChannel( + const grpc::string& server, const grpc::string& credential_type, + const std::shared_ptr& creds, + std::vector< + std::unique_ptr> + interceptor_creators) { + ChannelArguments channel_args; + std::shared_ptr channel_creds = + testing::GetCredentialsProvider()->GetChannelCredentials(credential_type, + &channel_args); + GPR_ASSERT(channel_creds != nullptr); + if (creds.get()) { + channel_creds = grpc::CompositeChannelCredentials(channel_creds, creds); + } + return experimental::CreateCustomChannelWithInterceptors( + server, channel_creds, channel_args, std::move(interceptor_creators)); } } // namespace grpc diff --git a/test/cpp/util/create_test_channel.h b/test/cpp/util/create_test_channel.h index c615fb76536..42564a31ec8 100644 --- a/test/cpp/util/create_test_channel.h +++ b/test/cpp/util/create_test_channel.h @@ -21,10 +21,15 @@ #include +#include #include -namespace grpc { +namespace grpc_impl { + class Channel; +} + +namespace grpc { namespace testing { @@ -32,34 +37,65 @@ typedef enum { INSECURE = 0, TLS, ALTS } transport_security; } // namespace testing -std::shared_ptr CreateTestChannel( +std::shared_ptr<::grpc_impl::Channel> CreateTestChannel( const grpc::string& server, testing::transport_security security_type); -std::shared_ptr CreateTestChannel( +std::shared_ptr<::grpc_impl::Channel> CreateTestChannel( const grpc::string& server, const grpc::string& override_hostname, testing::transport_security security_type, bool use_prod_roots); -std::shared_ptr CreateTestChannel( +std::shared_ptr<::grpc_impl::Channel> CreateTestChannel( const grpc::string& server, const grpc::string& override_hostname, testing::transport_security security_type, bool use_prod_roots, const std::shared_ptr& creds); -std::shared_ptr CreateTestChannel( +std::shared_ptr<::grpc_impl::Channel> CreateTestChannel( const grpc::string& server, const grpc::string& override_hostname, testing::transport_security security_type, bool use_prod_roots, const std::shared_ptr& creds, const ChannelArguments& args); -std::shared_ptr CreateTestChannel( +std::shared_ptr<::grpc_impl::Channel> CreateTestChannel( const grpc::string& server, const grpc::string& cred_type, const grpc::string& override_hostname, bool use_prod_roots, const std::shared_ptr& creds, const ChannelArguments& args); -std::shared_ptr CreateTestChannel( +std::shared_ptr<::grpc_impl::Channel> CreateTestChannel( const grpc::string& server, const grpc::string& credential_type, const std::shared_ptr& creds); +std::shared_ptr CreateTestChannel( + const grpc::string& server, const grpc::string& override_hostname, + testing::transport_security security_type, bool use_prod_roots, + const std::shared_ptr& creds, + std::vector< + std::unique_ptr> + interceptor_creators); + +std::shared_ptr CreateTestChannel( + const grpc::string& server, const grpc::string& override_hostname, + testing::transport_security security_type, bool use_prod_roots, + const std::shared_ptr& creds, const ChannelArguments& args, + std::vector< + std::unique_ptr> + interceptor_creators); + +std::shared_ptr CreateTestChannel( + const grpc::string& server, const grpc::string& cred_type, + const grpc::string& override_hostname, bool use_prod_roots, + const std::shared_ptr& creds, const ChannelArguments& args, + std::vector< + std::unique_ptr> + interceptor_creators); + +std::shared_ptr CreateTestChannel( + const grpc::string& server, const grpc::string& credential_type, + const std::shared_ptr& creds, + std::vector< + std::unique_ptr> + interceptor_creators); + } // namespace grpc #endif // GRPC_TEST_CPP_UTIL_CREATE_TEST_CHANNEL_H diff --git a/test/cpp/util/grpc_tool.cc b/test/cpp/util/grpc_tool.cc index 80eaf4f7279..dbac31170f0 100644 --- a/test/cpp/util/grpc_tool.cc +++ b/test/cpp/util/grpc_tool.cc @@ -217,7 +217,8 @@ std::shared_ptr CreateCliChannel( if (!cred.GetSslTargetNameOverride().empty()) { args.SetSslTargetNameOverride(cred.GetSslTargetNameOverride()); } - return grpc::CreateCustomChannel(server_address, cred.GetCredentials(), args); + return ::grpc::CreateCustomChannel(server_address, cred.GetCredentials(), + args); } struct Command { @@ -590,6 +591,7 @@ bool GrpcTool::CallMethod(int argc, const char** argv, call.WritesDoneAndWait(); read_thread.join(); + gpr_mu_destroy(&parser_mu); std::multimap server_trailing_metadata; Status status = call.Finish(&server_trailing_metadata); diff --git a/test/cpp/util/grpc_tool_test.cc b/test/cpp/util/grpc_tool_test.cc index be9a624a2c2..e44ada46c24 100644 --- a/test/cpp/util/grpc_tool_test.cc +++ b/test/cpp/util/grpc_tool_test.cc @@ -48,6 +48,7 @@ using grpc::testing::EchoResponse; #define ECHO_TEST_SERVICE_SUMMARY \ "Echo\n" \ + "CheckClientInitialMetadata\n" \ "RequestStream\n" \ "ResponseStream\n" \ "BidiStream\n" \ @@ -59,6 +60,8 @@ using grpc::testing::EchoResponse; "service EchoTestService {\n" \ " rpc Echo(grpc.testing.EchoRequest) returns (grpc.testing.EchoResponse) " \ "{}\n" \ + " rpc CheckClientInitialMetadata(grpc.testing.SimpleRequest) returns " \ + "(grpc.testing.SimpleResponse) {}\n" \ " rpc RequestStream(stream grpc.testing.EchoRequest) returns " \ "(grpc.testing.EchoResponse) {}\n" \ " rpc ResponseStream(grpc.testing.EchoRequest) returns (stream " \ @@ -119,7 +122,7 @@ class TestCliCredentials final : public grpc::testing::CliCredentials { return InsecureChannelCredentials(); } SslCredentialsOptions ssl_opts = {test_root_cert, "", ""}; - return SslCredentials(grpc::SslCredentialsOptions(ssl_opts)); + return grpc::SslCredentials(grpc::SslCredentialsOptions(ssl_opts)); } const grpc::string GetCredentialUsage() const override { return ""; } @@ -255,14 +258,6 @@ class GrpcToolTest : public ::testing::Test { void ShutdownServer() { server_->Shutdown(); } - void ExitWhenError(int argc, const char** argv, const CliCredentials& cred, - GrpcToolOutputCallback callback) { - int result = GrpcToolMainLib(argc, argv, cred, callback); - if (result) { - exit(result); - } - } - std::unique_ptr server_; TestServiceImpl service_; reflection::ProtoServerReflectionPlugin plugin_; @@ -415,11 +410,9 @@ TEST_F(GrpcToolTest, TypeNotFound) { const char* argv[] = {"grpc_cli", "type", server_address.c_str(), "grpc.testing.DummyRequest"}; - EXPECT_DEATH(ExitWhenError(ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1)), - ".*Type grpc.testing.DummyRequest not found.*"); - + EXPECT_TRUE(1 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, + std::placeholders::_1))); ShutdownServer(); } @@ -1173,7 +1166,7 @@ TEST_F(GrpcToolTest, ListCommand_OverrideSslHostName) { } // namespace grpc int main(int argc, char** argv) { - grpc_test_init(argc, argv); + grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); ::testing::FLAGS_gtest_death_test_style = "threadsafe"; return RUN_ALL_TESTS(); diff --git a/test/cpp/util/metrics_server.h b/test/cpp/util/metrics_server.h index 2d6ddf08043..08f6034c28e 100644 --- a/test/cpp/util/metrics_server.h +++ b/test/cpp/util/metrics_server.h @@ -21,6 +21,8 @@ #include #include +#include + #include "src/proto/grpc/testing/metrics.grpc.pb.h" #include "src/proto/grpc/testing/metrics.pb.h" diff --git a/test/cpp/util/proto_reflection_descriptor_database.cc b/test/cpp/util/proto_reflection_descriptor_database.cc index 119272ca42e..d0c1a847253 100644 --- a/test/cpp/util/proto_reflection_descriptor_database.cc +++ b/test/cpp/util/proto_reflection_descriptor_database.cc @@ -44,14 +44,17 @@ ProtoReflectionDescriptorDatabase::~ProtoReflectionDescriptorDatabase() { Status status = stream_->Finish(); if (!status.ok()) { if (status.error_code() == StatusCode::UNIMPLEMENTED) { - gpr_log(GPR_INFO, + fprintf(stderr, "Reflection request not implemented; " - "is the ServerReflection service enabled?"); + "is the ServerReflection service enabled?\n"); + } else { + fprintf(stderr, + "ServerReflectionInfo rpc failed. Error code: %d, message: %s, " + "debug info: %s\n", + static_cast(status.error_code()), + status.error_message().c_str(), + ctx_.debug_error_string().c_str()); } - gpr_log(GPR_INFO, - "ServerReflectionInfo rpc failed. Error code: %d, details: %s", - static_cast(status.error_code()), - status.error_message().c_str()); } } } diff --git a/test/cpp/util/proto_reflection_descriptor_database.h b/test/cpp/util/proto_reflection_descriptor_database.h index 46190b32179..e91546ff3a0 100644 --- a/test/cpp/util/proto_reflection_descriptor_database.h +++ b/test/cpp/util/proto_reflection_descriptor_database.h @@ -44,7 +44,7 @@ class ProtoReflectionDescriptorDatabase : public protobuf::DescriptorDatabase { // The following four methods implement DescriptorDatabase interfaces. // - // Find a file by file name. Fills in in *output and returns true if found. + // Find a file by file name. Fills in *output and returns true if found. // Otherwise, returns false, leaving the contents of *output undefined. bool FindFileByName(const string& filename, protobuf::FileDescriptorProto* output) override; diff --git a/test/cpp/util/test_credentials_provider.cc b/test/cpp/util/test_credentials_provider.cc index 0cf75f1e5f1..455f94e33d4 100644 --- a/test/cpp/util/test_credentials_provider.cc +++ b/test/cpp/util/test_credentials_provider.cc @@ -24,6 +24,7 @@ #include #include +#include #include "test/core/end2end/data/ssl_test_data.h" @@ -62,7 +63,7 @@ class DefaultCredentialsProvider : public CredentialsProvider { } else if (type == grpc::testing::kTlsCredentialsType) { SslCredentialsOptions ssl_opts = {test_root_cert, "", ""}; args->SetSslTargetNameOverride("foo.test.google.fr"); - return SslCredentials(ssl_opts); + return grpc::SslCredentials(ssl_opts); } else if (type == grpc::testing::kGoogleDefaultCredentialsType) { return grpc::GoogleDefaultCredentials(); } else { diff --git a/test/distrib/cpp/run_distrib_test_cmake.sh b/test/distrib/cpp/run_distrib_test_cmake.sh index 6ec3cab6024..f3362f1cee7 100755 --- a/test/distrib/cpp/run_distrib_test_cmake.sh +++ b/test/distrib/cpp/run_distrib_test_cmake.sh @@ -17,14 +17,16 @@ set -ex cd "$(dirname "$0")/../../.." -echo "deb http://ftp.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list +echo "deb http://archive.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list +echo 'Acquire::Check-Valid-Until "false";' > /etc/apt/apt.conf +sed -i '/deb http:\/\/deb.debian.org\/debian jessie-updates main/d' /etc/apt/sources.list apt-get update apt-get install -t jessie-backports -y libssl-dev # Install c-ares cd third_party/cares/cares git fetch origin -git checkout cares-1_13_0 +git checkout cares-1_15_0 mkdir -p cmake/build cd cmake/build cmake -DCMAKE_BUILD_TYPE=Release ../.. @@ -63,4 +65,3 @@ mkdir -p cmake/build cd cmake/build cmake ../.. make - diff --git a/test/distrib/cpp/run_distrib_test_cmake_as_externalproject.sh b/test/distrib/cpp/run_distrib_test_cmake_as_externalproject.sh index 163527fbd50..ee1e0e8337d 100755 --- a/test/distrib/cpp/run_distrib_test_cmake_as_externalproject.sh +++ b/test/distrib/cpp/run_distrib_test_cmake_as_externalproject.sh @@ -17,7 +17,9 @@ set -ex cd "$(dirname "$0")/../../.." -echo "deb http://ftp.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list +echo "deb http://archive.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list +echo 'Acquire::Check-Valid-Until "false";' > /etc/apt/apt.conf +sed -i '/deb http:\/\/deb.debian.org\/debian jessie-updates main/d' /etc/apt/sources.list apt-get update apt-get install -t jessie-backports -y libssl-dev @@ -38,4 +40,3 @@ mkdir -p cmake/build cd cmake/build cmake ../.. make - diff --git a/test/distrib/csharp/DistribTest/DistribTest.csproj b/test/distrib/csharp/DistribTest/DistribTest.csproj index 0bff9ff3e0b..e3fc94b4f23 100644 --- a/test/distrib/csharp/DistribTest/DistribTest.csproj +++ b/test/distrib/csharp/DistribTest/DistribTest.csproj @@ -1,6 +1,7 @@  + Debug AnyCPU @@ -62,6 +63,9 @@ ..\packages\Grpc.Core.__GRPC_NUGET_VERSION__\lib\net45\Grpc.Core.dll + + ..\packages\Grpc.Core.Api.__GRPC_NUGET_VERSION__\lib\net45\Grpc.Core.Api.dll + @@ -90,21 +94,30 @@ ..\packages\Google.Apis.Auth.1.15.0\lib\net45\Google.Apis.Auth.PlatformServices.dll + + ..\packages\Google.Protobuf.3.7.0\lib\net45\Google.Protobuf.dll + + + + + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + /usr/lib/mono/4.5-api diff --git a/test/distrib/csharp/DistribTest/Program.cs b/test/distrib/csharp/DistribTest/Program.cs index 376add6b7b5..0ea7211fc45 100644 --- a/test/distrib/csharp/DistribTest/Program.cs +++ b/test/distrib/csharp/DistribTest/Program.cs @@ -25,6 +25,9 @@ namespace TestGrpcPackage { public static void Main(string[] args) { + // test codegen works + var reply = new Testcodegen.HelloReply(); + // This code doesn't do much but makes sure the native extension is loaded // which is what we are testing here. Channel c = new Channel("127.0.0.1:1000", ChannelCredentials.Insecure); diff --git a/test/distrib/csharp/DistribTest/packages.config b/test/distrib/csharp/DistribTest/packages.config index 3cb2c46bcf0..5e09d5dad01 100644 --- a/test/distrib/csharp/DistribTest/packages.config +++ b/test/distrib/csharp/DistribTest/packages.config @@ -6,7 +6,9 @@ + + \ No newline at end of file diff --git a/test/distrib/csharp/DistribTest/testcodegen.proto b/test/distrib/csharp/DistribTest/testcodegen.proto new file mode 100644 index 00000000000..7845ac92c49 --- /dev/null +++ b/test/distrib/csharp/DistribTest/testcodegen.proto @@ -0,0 +1,29 @@ +// Copyright 2019 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. +// 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 testcodegen; + +service Greeter { + rpc SayHello (HelloRequest) returns (HelloReply) {} +} + +message HelloRequest { + string name = 1; +} + +message HelloReply { + string message = 1; +} diff --git a/test/distrib/csharp/run_distrib_test.sh b/test/distrib/csharp/run_distrib_test.sh index 61924b91df8..45911cd91a7 100755 --- a/test/distrib/csharp/run_distrib_test.sh +++ b/test/distrib/csharp/run_distrib_test.sh @@ -24,7 +24,7 @@ unzip -o "$EXTERNAL_GIT_ROOT/input_artifacts/csharp_nugets_windows_dotnetcli.zip # Retry "nuget restore" to work around https://github.com/grpc/grpc/issues/16312 nuget restore || nuget restore || nuget restore -xbuild DistribTest.sln +msbuild DistribTest.sln mono DistribTest/bin/Debug/DistribTest.exe diff --git a/test/distrib/python/test_packages.sh b/test/distrib/python/test_packages.sh index 755daa10211..e9f494310d6 100755 --- a/test/distrib/python/test_packages.sh +++ b/test/distrib/python/test_packages.sh @@ -37,7 +37,14 @@ TESTING_ARCHIVES=("$EXTERNAL_GIT_ROOT"/input_artifacts/grpcio-testing-[0-9]*.tar VIRTUAL_ENV=$(mktemp -d) virtualenv "$VIRTUAL_ENV" PYTHON=$VIRTUAL_ENV/bin/python -"$PYTHON" -m pip install --upgrade six pip +"$PYTHON" -m pip install --upgrade six pip wheel + +function validate_wheel_hashes() { + for file in "$@"; do + "$PYTHON" -m wheel unpack "$file" -d /tmp || return 1 + done + return 0 +} function at_least_one_installs() { for file in "$@"; do @@ -49,6 +56,16 @@ function at_least_one_installs() { } +# +# Validate the files in wheel matches their hashes and size in RECORD +# + +if [[ "$1" == "binary" ]]; then + validate_wheel_hashes "${ARCHIVES[@]}" + validate_wheel_hashes "${TOOLS_ARCHIVES[@]}" +fi + + # # Install our distributions in order of dependencies # diff --git a/third_party/BUILD b/third_party/BUILD index 5ec919dc48d..8b43d6b8300 100644 --- a/third_party/BUILD +++ b/third_party/BUILD @@ -1,5 +1,4 @@ exports_files([ - "benchmark.BUILD", "gtest.BUILD", "objective_c/Cronet/bidirectional_stream_c.h", "zlib.BUILD", diff --git a/third_party/benchmark b/third_party/benchmark index 5b7683f49e1..e776aa0275e 160000 --- a/third_party/benchmark +++ b/third_party/benchmark @@ -1 +1 @@ -Subproject commit 5b7683f49e1e9223cf9927b24f6fd3d6bd82e3f8 +Subproject commit e776aa0275e293707b6a0901e0e8d8a8a3679508 diff --git a/third_party/benchmark.BUILD b/third_party/benchmark.BUILD deleted file mode 100644 index 4c622f32a84..00000000000 --- a/third_party/benchmark.BUILD +++ /dev/null @@ -1,15 +0,0 @@ -cc_library( - name = "benchmark", - srcs = glob(["src/*.cc"]), - hdrs = glob(["include/**/*.h", "src/*.h"]), - includes = [ - "include", "." - ], - copts = [ - "-DHAVE_POSIX_REGEX" - ], - linkstatic = 1, - visibility = [ - "//visibility:public", - ], -) diff --git a/third_party/cares/cares b/third_party/cares/cares index 3be1924221e..e982924acee 160000 --- a/third_party/cares/cares +++ b/third_party/cares/cares @@ -1 +1 @@ -Subproject commit 3be1924221e1326df520f8498d704a5c4c8d0cce +Subproject commit e982924acee7f7313b4baa4ee5ec000c5e373c30 diff --git a/third_party/cares/cares.BUILD b/third_party/cares/cares.BUILD index fd14007e804..78a4590c3e0 100644 --- a/third_party/cares/cares.BUILD +++ b/third_party/cares/cares.BUILD @@ -3,6 +3,11 @@ config_setting( values = {"cpu": "darwin"}, ) +config_setting( + name = "darwin_x86_64", + values = {"cpu": "darwin_x86_64"}, +) + config_setting( name = "windows", values = {"cpu": "x64_windows"}, @@ -54,6 +59,7 @@ genrule( ":ios_armv7s": ["@com_github_grpc_grpc//third_party/cares:config_darwin/ares_config.h"], ":ios_arm64": ["@com_github_grpc_grpc//third_party/cares:config_darwin/ares_config.h"], ":darwin": ["@com_github_grpc_grpc//third_party/cares:config_darwin/ares_config.h"], + ":darwin_x86_64": ["@com_github_grpc_grpc//third_party/cares:config_darwin/ares_config.h"], ":windows": ["@com_github_grpc_grpc//third_party/cares:config_windows/ares_config.h"], ":android": ["@com_github_grpc_grpc//third_party/cares:config_android/ares_config.h"], "//conditions:default": ["@com_github_grpc_grpc//third_party/cares:config_linux/ares_config.h"], @@ -106,6 +112,7 @@ cc_library( "ares_send.c", "ares_strcasecmp.c", "ares_strdup.c", + "ares_strsplit.c", "ares_strerror.c", "ares_timeout.c", "ares_version.c", @@ -135,7 +142,9 @@ cc_library( "ares_setup.h", "ares_strcasecmp.h", "ares_strdup.h", + "ares_strsplit.h", "ares_version.h", + "ares_writev.h", "bitncmp.h", "config-win32.h", "nameser.h", @@ -164,4 +173,5 @@ cc_library( visibility = [ "//visibility:public", ], + alwayslink = 1, ) diff --git a/third_party/cares/config_android/ares_config.h b/third_party/cares/config_android/ares_config.h index 2caf1b396e3..184af4ef9a5 100644 --- a/third_party/cares/config_android/ares_config.h +++ b/third_party/cares/config_android/ares_config.h @@ -338,6 +338,9 @@ /* Define to 1 if you have the ws2tcpip.h header file. */ /* #undef HAVE_WS2TCPIP_H */ +/* Define if __system_property_get exists. */ +/* #undef HAVE___SYSTEM_PROPERTY_GET */ + /* Define to 1 if you need the malloc.h header file even with stdlib.h */ /* #undef NEED_MALLOC_H */ diff --git a/third_party/cares/config_darwin/ares_config.h b/third_party/cares/config_darwin/ares_config.h index bca7cfbcc7b..9b8fc651a18 100644 --- a/third_party/cares/config_darwin/ares_config.h +++ b/third_party/cares/config_darwin/ares_config.h @@ -333,6 +333,9 @@ /* Define to 1 if you have the ws2tcpip.h header file. */ /* #undef HAVE_WS2TCPIP_H */ +/* Define if __system_property_get exists. */ +/* #undef HAVE___SYSTEM_PROPERTY_GET */ + /* Define to 1 if you need the malloc.h header file even with stdlib.h */ /* #undef NEED_MALLOC_H */ diff --git a/third_party/cares/config_freebsd/ares_config.h b/third_party/cares/config_freebsd/ares_config.h index 7beb20c76ef..e50a11d7f37 100644 --- a/third_party/cares/config_freebsd/ares_config.h +++ b/third_party/cares/config_freebsd/ares_config.h @@ -338,6 +338,9 @@ /* Define to 1 if you have the ws2tcpip.h header file. */ /* #undef HAVE_WS2TCPIP_H */ +/* Define if __system_property_get exists. */ +/* #undef HAVE___SYSTEM_PROPERTY_GET */ + /* Define to the sub-directory where libtool stores uninstalled libraries. */ #define LT_OBJDIR ".libs/" diff --git a/third_party/cares/config_linux/ares_config.h b/third_party/cares/config_linux/ares_config.h index 065d0bc515a..3634e9d0616 100644 --- a/third_party/cares/config_linux/ares_config.h +++ b/third_party/cares/config_linux/ares_config.h @@ -338,6 +338,9 @@ /* Define to 1 if you have the ws2tcpip.h header file. */ /* #undef HAVE_WS2TCPIP_H */ +/* Define if __system_property_get exists. */ +/* #undef HAVE___SYSTEM_PROPERTY_GET */ + /* Define to 1 if you need the malloc.h header file even with stdlib.h */ /* #undef NEED_MALLOC_H */ diff --git a/third_party/cares/config_openbsd/ares_config.h b/third_party/cares/config_openbsd/ares_config.h index 3b3320db8f6..18d1ea8c2c8 100644 --- a/third_party/cares/config_openbsd/ares_config.h +++ b/third_party/cares/config_openbsd/ares_config.h @@ -338,6 +338,9 @@ /* Define to 1 if you have the ws2tcpip.h header file. */ /* #undef HAVE_WS2TCPIP_H */ +/* Define if __system_property_get exists. */ +/* #undef HAVE___SYSTEM_PROPERTY_GET */ + /* Define to the sub-directory where libtool stores uninstalled libraries. */ #define LT_OBJDIR ".libs/" diff --git a/third_party/cares/config_windows/ares_config.h b/third_party/cares/config_windows/ares_config.h index a128faac371..e984c6e4ad1 100644 --- a/third_party/cares/config_windows/ares_config.h +++ b/third_party/cares/config_windows/ares_config.h @@ -331,6 +331,9 @@ /* Define to 1 if you have the ws2tcpip.h header file. */ #define HAVE_WS2TCPIP_H +/* Define if __system_property_get exists. */ +/* #undef HAVE___SYSTEM_PROPERTY_GET */ + /* Define to 1 if you need the malloc.h header file even with stdlib.h */ /* #undef NEED_MALLOC_H */ diff --git a/third_party/gflags b/third_party/gflags index 30dbc81fb5f..28f50e0fed1 160000 --- a/third_party/gflags +++ b/third_party/gflags @@ -1 +1 @@ -Subproject commit 30dbc81fb5ffdc98ea9b14b1918bfe4e8779b26e +Subproject commit 28f50e0fed19872e0fd50dd23ce2ee8cd759338e diff --git a/third_party/protobuf b/third_party/protobuf index 48cb18e5c41..582743bf40c 160000 --- a/third_party/protobuf +++ b/third_party/protobuf @@ -1 +1 @@ -Subproject commit 48cb18e5c419ddd23d9badcfe4e9df7bde1979b2 +Subproject commit 582743bf40c5d3639a70f98f183914a2c0cd0680 diff --git a/third_party/py/python_configure.bzl b/third_party/py/python_configure.bzl index 2ba1e07049c..e6fa5ed10e9 100644 --- a/third_party/py/python_configure.bzl +++ b/third_party/py/python_configure.bzl @@ -138,10 +138,13 @@ def _symlink_genrule_for_dir(repository_ctx, def _get_python_bin(repository_ctx): """Gets the python bin path.""" - python_bin = repository_ctx.os.environ.get(_PYTHON_BIN_PATH) - if python_bin != None: - return python_bin - python_bin_path = repository_ctx.which("python") + python_bin = repository_ctx.os.environ.get(_PYTHON_BIN_PATH, 'python') + if not repository_ctx.path(python_bin).exists: + # It's a command, use 'which' to find its path. + python_bin_path = repository_ctx.which(python_bin) + else: + # It's a path, use it as it is. + python_bin_path = python_bin if python_bin_path != None: return str(python_bin_path) _fail("Cannot find python in PATH, please make sure " + diff --git a/third_party/rake-compiler-dock/Dockerfile b/third_party/rake-compiler-dock/Dockerfile index 06c721c39ba..44eddc82e80 100644 --- a/third_party/rake-compiler-dock/Dockerfile +++ b/third_party/rake-compiler-dock/Dockerfile @@ -1,8 +1,7 @@ -FROM larskanis/rake-compiler-dock:0.6.2 +FROM larskanis/rake-compiler-dock-mri:0.7.0 RUN find / -name rbconfig.rb | while read f ; do sed -i 's/0x0501/0x0600/' $f ; done RUN find / -name win32.h | while read f ; do sed -i 's/gettimeofday/rb_gettimeofday/' $f ; done -RUN sed -i 's/defined.__MINGW64__.$/1/' /usr/local/rake-compiler/ruby/i686-w64-mingw32/ruby-2.0.0-p645/include/ruby-2.0.0/ruby/win32.h RUN find / -name libwinpthread.dll.a | xargs rm RUN find / -name libwinpthread-1.dll | xargs rm RUN find / -name *msvcrt-ruby*.dll.a | while read f ; do n=`echo $f | sed s/.dll//` ; mv $f $n ; done diff --git a/third_party/toolchains/BUILD b/third_party/toolchains/BUILD index 02cd87a7b9b..0ff68f9c3bb 100644 --- a/third_party/toolchains/BUILD +++ b/third_party/toolchains/BUILD @@ -16,37 +16,111 @@ licenses(["notice"]) # Apache v2 package(default_visibility = ["//visibility:public"]) -exports_files(["RBE_USE_MACHINE_TYPE_LARGE",]) - -# Latest RBE Ubuntu16_04 container -# Update every time when a new container is released. alias( - name = "rbe_ubuntu1604", - actual = ":rbe_ubuntu1604_r328903", + name = "rbe_windows", + actual = ":rbe_windows_1803", ) -# RBE Ubuntu16_04 r328903 +# RBE Windows platform( - name = "rbe_ubuntu1604_r328903", + name = "rbe_windows_1803", constraint_values = [ "@bazel_tools//platforms:x86_64", - "@bazel_tools//platforms:linux", - "@bazel_tools//tools/cpp:clang", - "@com_github_bazelbuild_bazeltoolchains//constraints:xenial", - "@com_github_bazelbuild_bazeltoolchains//constraints/sanitizers:support_msan", + "@bazel_tools//platforms:windows", + "@bazel_tools//tools/cpp:msvc", ], remote_execution_properties = """ properties: { name: "container-image" - value:"docker://gcr.io/cloud-marketplace/google/rbe-ubuntu16-04@sha256:59bf0e191a6b5cc1ab62c2224c810681d1326bad5a27b1d36c9f40113e79da7f" + value:"docker://gcr.io/grpc-testing/rbe_windows_toolchain@sha256:689b177e4a157c431c7077d19d043de27922c37de835031f29c9093b8d5c6370" } properties: { name: "gceMachineType" # Small machines for majority of tests. value: "n1-highmem-2" } + properties:{ + name: "OSFamily" + value: "Windows" + } + + """, +) + +# RBE Ubuntu16_04 r346485 +platform( + name = "rbe_ubuntu1604", + parents = ["@rbe_default//config:platform"], + constraint_values = [ + "//third_party/toolchains/machine_size:standard", + ], + remote_execution_properties = """ + {PARENT_REMOTE_EXECUTION_PROPERTIES} properties: { - name: "gceMachineType_LARGE" # Large machines for a small set of resource-consuming tests such as combiner_tests under TSAN. - value: "n1-standard-8" + name: "gceMachineType" # Small machines for majority of tests. + value: "n1-highmem-2" + } + properties: { + name: "dockerSiblingContainers" + value: "false" + } + properties: { + name: "dockerNetwork" + value: "off" + } + properties: { + name: "dockerAddCapabilities" + value: "SYS_PTRACE" + } + properties: { + name: "dockerPrivileged" + value: "true" } """, ) + +platform( + name = "rbe_ubuntu1604_large", + parents = ["@rbe_default//config:platform"], + constraint_values = [ + "//third_party/toolchains/machine_size:large", + ], + remote_execution_properties = """ + {PARENT_REMOTE_EXECUTION_PROPERTIES} + properties: { + name: "gceMachineType" # Large machines for some resource demanding tests (TSAN). + value: "n1-standard-8" + } + properties: { + name: "dockerSiblingContainers" + value: "false" + } + properties: { + name: "dockerNetwork" + value: "off" + } + properties: { + name: "dockerAddCapabilities" + value: "SYS_PTRACE" + } + properties: { + name: "dockerPrivileged" + value: "true" + } + """, +) + +platform( + name = "local", + parents = ["@bazel_tools//platforms:target_platform"], + constraint_values = [ + "//third_party/toolchains/machine_size:standard", + ], +) + +platform( + name = "local_large", + parents = ["@bazel_tools//platforms:target_platform"], + constraint_values = [ + "//third_party/toolchains/machine_size:large", + ], +) diff --git a/third_party/toolchains/RBE_USE_MACHINE_TYPE_LARGE b/third_party/toolchains/RBE_USE_MACHINE_TYPE_LARGE deleted file mode 100644 index b1120238d7e..00000000000 --- a/third_party/toolchains/RBE_USE_MACHINE_TYPE_LARGE +++ /dev/null @@ -1 +0,0 @@ -# This file is a sentinel and is meant to be empty. diff --git a/third_party/toolchains/bazel_0.23.2_rbe_windows/BUILD b/third_party/toolchains/bazel_0.23.2_rbe_windows/BUILD new file mode 100644 index 00000000000..5ce4e00c866 --- /dev/null +++ b/third_party/toolchains/bazel_0.23.2_rbe_windows/BUILD @@ -0,0 +1,188 @@ +# Copyright 2018 The Bazel 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. + +# This becomes the BUILD file for @local_config_cc// under Windows. +licenses(["notice"]) # Apache v2 + +package(default_visibility = ["//visibility:public"]) + +load(":cc_toolchain_config.bzl", "cc_toolchain_config") + +cc_library( + name = "malloc", +) + +filegroup( + name = "empty", + srcs = [], +) + +# Hardcoded toolchain, legacy behaviour. +cc_toolchain_suite( + name = "toolchain", + toolchains = { + "armeabi-v7a|compiler": ":cc-compiler-armeabi-v7a", + "x64_windows|msvc-cl": ":cc-compiler-x64_windows", + "x64_windows|msys-gcc": ":cc-compiler-x64_windows_msys", + "x64_windows|mingw-gcc": ":cc-compiler-x64_windows_mingw", + "x64_windows_msys": ":cc-compiler-x64_windows_msys", + "x64_windows": ":cc-compiler-x64_windows", + "armeabi-v7a": ":cc-compiler-armeabi-v7a", + }, +) + +cc_toolchain( + name = "cc-compiler-x64_windows_msys", + all_files = ":empty", + ar_files = ":empty", + as_files = ":empty", + compiler_files = ":empty", + dwp_files = ":empty", + linker_files = ":empty", + objcopy_files = ":empty", + strip_files = ":empty", + supports_param_files = 1, + toolchain_config = ":msys_x64", + toolchain_identifier = "msys_x64", +) + +cc_toolchain_config( + name = "msys_x64", + compiler = "msys-gcc", + cpu = "x64_windows", +) + +toolchain( + name = "cc-toolchain-x64_windows_msys", + exec_compatible_with = [ + "@bazel_tools//platforms:x86_64", + "@bazel_tools//platforms:windows", + "@bazel_tools//tools/cpp:msys", + ], + target_compatible_with = [ + "@bazel_tools//platforms:x86_64", + "@bazel_tools//platforms:windows", + ], + toolchain = ":cc-compiler-x64_windows_msys", + toolchain_type = "@bazel_tools//tools/cpp:toolchain_type", +) + +cc_toolchain( + name = "cc-compiler-x64_windows_mingw", + all_files = ":empty", + ar_files = ":empty", + as_files = ":empty", + compiler_files = ":empty", + dwp_files = ":empty", + linker_files = ":empty", + objcopy_files = ":empty", + strip_files = ":empty", + supports_param_files = 0, + toolchain_config = ":msys_x64_mingw", + toolchain_identifier = "msys_x64_mingw", +) + +cc_toolchain_config( + name = "msys_x64_mingw", + compiler = "mingw-gcc", + cpu = "x64_windows", +) + +toolchain( + name = "cc-toolchain-x64_windows_mingw", + exec_compatible_with = [ + "@bazel_tools//platforms:x86_64", + "@bazel_tools//platforms:windows", + "@bazel_tools//tools/cpp:mingw", + ], + target_compatible_with = [ + "@bazel_tools//platforms:x86_64", + "@bazel_tools//platforms:windows", + ], + toolchain = ":cc-compiler-x64_windows_mingw", + toolchain_type = "@bazel_tools//tools/cpp:toolchain_type", +) + +cc_toolchain( + name = "cc-compiler-x64_windows", + all_files = ":empty", + ar_files = ":empty", + as_files = ":empty", + compiler_files = ":empty", + dwp_files = ":empty", + linker_files = ":empty", + objcopy_files = ":empty", + strip_files = ":empty", + supports_param_files = 1, + toolchain_config = ":msvc_x64", + toolchain_identifier = "msvc_x64", +) + +cc_toolchain_config( + name = "msvc_x64", + compiler = "msvc-cl", + cpu = "x64_windows", +) + +toolchain( + name = "cc-toolchain-x64_windows", + exec_compatible_with = [ + "@bazel_tools//platforms:x86_64", + "@bazel_tools//platforms:windows", + ], + target_compatible_with = [ + "@bazel_tools//platforms:x86_64", + "@bazel_tools//platforms:windows", + ], + toolchain = ":cc-compiler-x64_windows", + toolchain_type = "@bazel_tools//tools/cpp:toolchain_type", +) + +cc_toolchain( + name = "cc-compiler-armeabi-v7a", + all_files = ":empty", + ar_files = ":empty", + as_files = ":empty", + compiler_files = ":empty", + dwp_files = ":empty", + linker_files = ":empty", + objcopy_files = ":empty", + strip_files = ":empty", + supports_param_files = 1, + toolchain_config = ":stub_armeabi-v7a", + toolchain_identifier = "stub_armeabi-v7a", +) + +cc_toolchain_config( + name = "stub_armeabi-v7a", + compiler = "compiler", + cpu = "armeabi-v7a", +) + +toolchain( + name = "cc-toolchain-armeabi-v7a", + exec_compatible_with = [ + ], + target_compatible_with = [ + "@bazel_tools//platforms:arm", + "@bazel_tools//platforms:android", + ], + toolchain = ":cc-compiler-armeabi-v7a", + toolchain_type = "@bazel_tools//tools/cpp:toolchain_type", +) + +filegroup( + name = "link_dynamic_library", + srcs = ["link_dynamic_library.sh"], +) diff --git a/third_party/toolchains/bazel_0.23.2_rbe_windows/cc_toolchain_config.bzl b/third_party/toolchains/bazel_0.23.2_rbe_windows/cc_toolchain_config.bzl new file mode 100644 index 00000000000..790ddcb0947 --- /dev/null +++ b/third_party/toolchains/bazel_0.23.2_rbe_windows/cc_toolchain_config.bzl @@ -0,0 +1,1704 @@ +# Copyright 2019 The Bazel 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. + +"""A Starlark cc_toolchain configuration rule""" + +load( + "@bazel_tools//tools/cpp:cc_toolchain_config_lib.bzl", + "action_config", + "artifact_name_pattern", + "env_entry", + "env_set", + "feature", + "feature_set", + "flag_group", + "flag_set", + "make_variable", + "tool", + "tool_path", + "variable_with_value", + "with_feature_set", +) +load("@bazel_tools//tools/build_defs/cc:action_names.bzl", "ACTION_NAMES") + +all_compile_actions = [ + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.clif_match, + ACTION_NAMES.lto_backend, +] + +all_cpp_compile_actions = [ + ACTION_NAMES.cpp_compile, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.clif_match, +] + +preprocessor_compile_actions = [ + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.clif_match, +] + +codegen_compile_actions = [ + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.lto_backend, +] + +all_link_actions = [ + ACTION_NAMES.cpp_link_executable, + ACTION_NAMES.cpp_link_dynamic_library, + ACTION_NAMES.cpp_link_nodeps_dynamic_library, +] + +def _windows_msvc_impl(ctx): + toolchain_identifier = "msvc_x64" + host_system_name = "local" + target_system_name = "local" + target_cpu = "x64_windows" + target_libc = "msvcrt" + compiler = "msvc-cl" + abi_version = "local" + abi_libc_version = "local" + cc_target_os = None + builtin_sysroot = None + + cxx_builtin_include_directories = [ + # This is a workaround for https://github.com/bazelbuild/bazel/issues/5087. + "C:\\botcode\\w", + "c:/tools/msys64/usr/", + "C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\INCLUDE", + "C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.10240.0\\ucrt", + "C:\\Program Files (x86)\\Windows Kits\\8.1\\include\\shared", + "C:\\Program Files (x86)\\Windows Kits\\8.1\\include\\um", + "C:\\Program Files (x86)\\Windows Kits\\8.1\\include\\winrt", + ] + + cpp_link_nodeps_dynamic_library_action = action_config( + action_name = ACTION_NAMES.cpp_link_nodeps_dynamic_library, + implies = [ + "nologo", + "shared_flag", + "linkstamps", + "output_execpath_flags", + "input_param_flags", + "user_link_flags", + "default_link_flags", + "linker_subsystem_flag", + "linker_param_file", + "msvc_env", + "no_stripping", + "has_configured_linker_path", + "def_file", + ], + tools = [tool(path = "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/amd64/link.exe")], + ) + + cpp_link_static_library_action = action_config( + action_name = ACTION_NAMES.cpp_link_static_library, + implies = [ + "nologo", + "archiver_flags", + "input_param_flags", + "linker_param_file", + "msvc_env", + ], + tools = [tool(path = "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/amd64/lib.exe")], + ) + + assemble_action = action_config( + action_name = ACTION_NAMES.assemble, + implies = [ + "compiler_input_flags", + "compiler_output_flags", + "nologo", + "msvc_env", + "sysroot", + ], + tools = [tool(path = "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/amd64/ml64.exe")], + ) + + preprocess_assemble_action = action_config( + action_name = ACTION_NAMES.preprocess_assemble, + implies = [ + "compiler_input_flags", + "compiler_output_flags", + "nologo", + "msvc_env", + "sysroot", + ], + tools = [tool(path = "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/amd64/ml64.exe")], + ) + + c_compile_action = action_config( + action_name = ACTION_NAMES.c_compile, + implies = [ + "compiler_input_flags", + "compiler_output_flags", + "default_compile_flags", + "nologo", + "msvc_env", + "parse_showincludes", + "user_compile_flags", + "sysroot", + "unfiltered_compile_flags", + ], + tools = [tool(path = "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/amd64/cl.exe")], + ) + + cpp_compile_action = action_config( + action_name = ACTION_NAMES.cpp_compile, + implies = [ + "compiler_input_flags", + "compiler_output_flags", + "default_compile_flags", + "nologo", + "msvc_env", + "parse_showincludes", + "user_compile_flags", + "sysroot", + "unfiltered_compile_flags", + ], + tools = [tool(path = "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/amd64/cl.exe")], + ) + + cpp_link_executable_action = action_config( + action_name = ACTION_NAMES.cpp_link_executable, + implies = [ + "nologo", + "linkstamps", + "output_execpath_flags", + "input_param_flags", + "user_link_flags", + "default_link_flags", + "linker_subsystem_flag", + "linker_param_file", + "msvc_env", + "no_stripping", + ], + tools = [tool(path = "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/amd64/link.exe")], + ) + + cpp_link_dynamic_library_action = action_config( + action_name = ACTION_NAMES.cpp_link_dynamic_library, + implies = [ + "nologo", + "shared_flag", + "linkstamps", + "output_execpath_flags", + "input_param_flags", + "user_link_flags", + "default_link_flags", + "linker_subsystem_flag", + "linker_param_file", + "msvc_env", + "no_stripping", + "has_configured_linker_path", + "def_file", + ], + tools = [tool(path = "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/amd64/link.exe")], + ) + + action_configs = [ + assemble_action, + preprocess_assemble_action, + c_compile_action, + cpp_compile_action, + cpp_link_executable_action, + cpp_link_dynamic_library_action, + cpp_link_nodeps_dynamic_library_action, + cpp_link_static_library_action, + ] + + msvc_link_env_feature = feature( + name = "msvc_link_env", + env_sets = [ + env_set( + actions = all_link_actions + + [ACTION_NAMES.cpp_link_static_library], + env_entries = [env_entry(key = "LIB", value = "C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\LIB\\amd64;C:\\Program Files (x86)\\Windows Kits\\10\\lib\\10.0.10240.0\\ucrt\\x64;C:\\Program Files (x86)\\Windows Kits\\8.1\\lib\\winv6.3\\um\\x64;")], + ), + ], + ) + + shared_flag_feature = feature( + name = "shared_flag", + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.cpp_link_dynamic_library, + ACTION_NAMES.cpp_link_nodeps_dynamic_library, + ], + flag_groups = [flag_group(flags = ["/DLL"])], + ), + ], + ) + + determinism_feature = feature( + name = "determinism", + enabled = True, + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile], + flag_groups = [ + flag_group( + flags = [ + "/wd4117", + "-D__DATE__=\"redacted\"", + "-D__TIMESTAMP__=\"redacted\"", + "-D__TIME__=\"redacted\"", + ], + ), + ], + ), + ], + ) + + sysroot_feature = feature( + name = "sysroot", + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.cpp_link_executable, + ACTION_NAMES.cpp_link_dynamic_library, + ACTION_NAMES.cpp_link_nodeps_dynamic_library, + ], + flag_groups = [ + flag_group( + flags = ["--sysroot=%{sysroot}"], + iterate_over = "sysroot", + expand_if_available = "sysroot", + ), + ], + ), + ], + ) + + unfiltered_compile_flags_feature = feature( + name = "unfiltered_compile_flags", + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ], + flag_groups = [ + flag_group( + flags = ["%{unfiltered_compile_flags}"], + iterate_over = "unfiltered_compile_flags", + expand_if_available = "unfiltered_compile_flags", + ), + ], + ), + ], + ) + + copy_dynamic_libraries_to_binary_feature = feature(name = "copy_dynamic_libraries_to_binary") + + input_param_flags_feature = feature( + name = "input_param_flags", + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.cpp_link_dynamic_library, + ACTION_NAMES.cpp_link_nodeps_dynamic_library, + ], + flag_groups = [ + flag_group( + flags = ["/IMPLIB:%{interface_library_output_path}"], + expand_if_available = "interface_library_output_path", + ), + ], + ), + flag_set( + actions = all_link_actions, + flag_groups = [ + flag_group( + flags = ["%{libopts}"], + iterate_over = "libopts", + expand_if_available = "libopts", + ), + ], + ), + flag_set( + actions = all_link_actions + + [ACTION_NAMES.cpp_link_static_library], + flag_groups = [ + flag_group( + iterate_over = "libraries_to_link", + flag_groups = [ + flag_group( + iterate_over = "libraries_to_link.object_files", + flag_groups = [flag_group(flags = ["%{libraries_to_link.object_files}"])], + expand_if_equal = variable_with_value( + name = "libraries_to_link.type", + value = "object_file_group", + ), + ), + flag_group( + flag_groups = [flag_group(flags = ["%{libraries_to_link.name}"])], + expand_if_equal = variable_with_value( + name = "libraries_to_link.type", + value = "object_file", + ), + ), + flag_group( + flag_groups = [flag_group(flags = ["%{libraries_to_link.name}"])], + expand_if_equal = variable_with_value( + name = "libraries_to_link.type", + value = "interface_library", + ), + ), + flag_group( + flag_groups = [ + flag_group( + flags = ["%{libraries_to_link.name}"], + expand_if_false = "libraries_to_link.is_whole_archive", + ), + flag_group( + flags = ["/WHOLEARCHIVE:%{libraries_to_link.name}"], + expand_if_true = "libraries_to_link.is_whole_archive", + ), + ], + expand_if_equal = variable_with_value( + name = "libraries_to_link.type", + value = "static_library", + ), + ), + ], + expand_if_available = "libraries_to_link", + ), + ], + ), + ], + ) + + fastbuild_feature = feature( + name = "fastbuild", + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile], + flag_groups = [flag_group(flags = ["/Od", "/Z7"])], + ), + flag_set( + actions = all_link_actions, + flag_groups = [ + flag_group( + flags = ["/DEBUG:FASTLINK", "/INCREMENTAL:NO"], + ), + ], + ), + ], + implies = ["generate_pdb_file"], + ) + + user_compile_flags_feature = feature( + name = "user_compile_flags", + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ], + flag_groups = [ + flag_group( + flags = ["%{user_compile_flags}"], + iterate_over = "user_compile_flags", + expand_if_available = "user_compile_flags", + ), + ], + ), + ], + ) + + archiver_flags_feature = feature( + name = "archiver_flags", + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.cpp_link_static_library], + flag_groups = [ + flag_group( + flags = ["/OUT:%{output_execpath}"], + expand_if_available = "output_execpath", + ), + ], + ), + ], + ) + + default_link_flags_feature = feature( + name = "default_link_flags", + enabled = True, + flag_sets = [ + flag_set( + actions = all_link_actions, + flag_groups = [flag_group(flags = ["/MACHINE:X64"])], + ), + ], + ) + + static_link_msvcrt_feature = feature(name = "static_link_msvcrt") + + dynamic_link_msvcrt_debug_feature = feature( + name = "dynamic_link_msvcrt_debug", + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile], + flag_groups = [flag_group(flags = ["/MDd"])], + ), + flag_set( + actions = all_link_actions, + flag_groups = [flag_group(flags = ["/DEFAULTLIB:msvcrtd.lib"])], + ), + ], + requires = [feature_set(features = ["dbg"])], + ) + + dbg_feature = feature( + name = "dbg", + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile], + flag_groups = [flag_group(flags = ["/Od", "/Z7"])], + ), + flag_set( + actions = all_link_actions, + flag_groups = [ + flag_group( + flags = ["/DEBUG:FULL", "/INCREMENTAL:NO"], + ), + ], + ), + ], + implies = ["generate_pdb_file"], + ) + + opt_feature = feature( + name = "opt", + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile], + flag_groups = [flag_group(flags = ["/O2"])], + ), + ], + implies = ["frame_pointer"], + ) + + supports_interface_shared_libraries_feature = feature( + name = "supports_interface_shared_libraries", + enabled = True, + ) + + user_link_flags_feature = feature( + name = "user_link_flags", + flag_sets = [ + flag_set( + actions = all_link_actions, + flag_groups = [ + flag_group( + flags = ["%{user_link_flags}"], + iterate_over = "user_link_flags", + expand_if_available = "user_link_flags", + ), + ], + ), + ], + ) + + default_compile_flags_feature = feature( + name = "default_compile_flags", + enabled = True, + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.lto_backend, + ACTION_NAMES.clif_match, + ], + flag_groups = [ + flag_group( + flags = [ + "/DCOMPILER_MSVC", + "/DNOMINMAX", + "/D_WIN32_WINNT=0x0601", + "/D_CRT_SECURE_NO_DEPRECATE", + "/D_CRT_SECURE_NO_WARNINGS", + "/bigobj", + "/Zm500", + "/EHsc", + "/wd4351", + "/wd4291", + "/wd4250", + "/wd4996", + ], + ), + ], + ), + ], + ) + + msvc_compile_env_feature = feature( + name = "msvc_compile_env", + env_sets = [ + env_set( + actions = [ + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ], + env_entries = [env_entry(key = "INCLUDE", value = "C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\INCLUDE;C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.10240.0\\ucrt;C:\\Program Files (x86)\\Windows Kits\\8.1\\include\\shared;C:\\Program Files (x86)\\Windows Kits\\8.1\\include\\um;C:\\Program Files (x86)\\Windows Kits\\8.1\\include\\winrt;")], + ), + ], + ) + + preprocessor_defines_feature = feature( + name = "preprocessor_defines", + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ], + flag_groups = [ + flag_group( + flags = ["/D%{preprocessor_defines}"], + iterate_over = "preprocessor_defines", + ), + ], + ), + ], + ) + + generate_pdb_file_feature = feature( + name = "generate_pdb_file", + requires = [ + feature_set(features = ["dbg"]), + feature_set(features = ["fastbuild"]), + ], + ) + + output_execpath_flags_feature = feature( + name = "output_execpath_flags", + flag_sets = [ + flag_set( + actions = all_link_actions, + flag_groups = [ + flag_group( + flags = ["/OUT:%{output_execpath}"], + expand_if_available = "output_execpath", + ), + ], + ), + ], + ) + + dynamic_link_msvcrt_no_debug_feature = feature( + name = "dynamic_link_msvcrt_no_debug", + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile], + flag_groups = [flag_group(flags = ["/MD"])], + ), + flag_set( + actions = all_link_actions, + flag_groups = [flag_group(flags = ["/DEFAULTLIB:msvcrt.lib"])], + ), + ], + requires = [ + feature_set(features = ["fastbuild"]), + feature_set(features = ["opt"]), + ], + ) + + disable_assertions_feature = feature( + name = "disable_assertions", + enabled = True, + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile], + flag_groups = [flag_group(flags = ["/DNDEBUG"])], + with_features = [with_feature_set(features = ["opt"])], + ), + ], + ) + + has_configured_linker_path_feature = feature(name = "has_configured_linker_path") + + supports_dynamic_linker_feature = feature(name = "supports_dynamic_linker", enabled = True) + + no_stripping_feature = feature(name = "no_stripping") + + linker_param_file_feature = feature( + name = "linker_param_file", + flag_sets = [ + flag_set( + actions = all_link_actions + + [ACTION_NAMES.cpp_link_static_library], + flag_groups = [ + flag_group( + flags = ["@%{linker_param_file}"], + expand_if_available = "linker_param_file", + ), + ], + ), + ], + ) + + ignore_noisy_warnings_feature = feature( + name = "ignore_noisy_warnings", + enabled = True, + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.cpp_link_static_library], + flag_groups = [flag_group(flags = ["/ignore:4221"])], + ), + ], + ) + + no_legacy_features_feature = feature(name = "no_legacy_features") + + parse_showincludes_feature = feature( + name = "parse_showincludes", + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_header_parsing, + ], + flag_groups = [flag_group(flags = ["/showIncludes"])], + ), + ], + ) + + static_link_msvcrt_no_debug_feature = feature( + name = "static_link_msvcrt_no_debug", + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile], + flag_groups = [flag_group(flags = ["/MT"])], + ), + flag_set( + actions = all_link_actions, + flag_groups = [flag_group(flags = ["/DEFAULTLIB:libcmt.lib"])], + ), + ], + requires = [ + feature_set(features = ["fastbuild"]), + feature_set(features = ["opt"]), + ], + ) + + treat_warnings_as_errors_feature = feature( + name = "treat_warnings_as_errors", + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile], + flag_groups = [flag_group(flags = ["/WX"])], + ), + ], + ) + + windows_export_all_symbols_feature = feature(name = "windows_export_all_symbols") + + no_windows_export_all_symbols_feature = feature(name = "no_windows_export_all_symbols") + + include_paths_feature = feature( + name = "include_paths", + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ], + flag_groups = [ + flag_group( + flags = ["/I%{quote_include_paths}"], + iterate_over = "quote_include_paths", + ), + flag_group( + flags = ["/I%{include_paths}"], + iterate_over = "include_paths", + ), + flag_group( + flags = ["/I%{system_include_paths}"], + iterate_over = "system_include_paths", + ), + ], + ), + ], + ) + + linkstamps_feature = feature( + name = "linkstamps", + flag_sets = [ + flag_set( + actions = all_link_actions, + flag_groups = [ + flag_group( + flags = ["%{linkstamp_paths}"], + iterate_over = "linkstamp_paths", + expand_if_available = "linkstamp_paths", + ), + ], + ), + ], + ) + + targets_windows_feature = feature( + name = "targets_windows", + enabled = True, + implies = ["copy_dynamic_libraries_to_binary"], + ) + + linker_subsystem_flag_feature = feature( + name = "linker_subsystem_flag", + flag_sets = [ + flag_set( + actions = all_link_actions, + flag_groups = [flag_group(flags = ["/SUBSYSTEM:CONSOLE"])], + ), + ], + ) + + static_link_msvcrt_debug_feature = feature( + name = "static_link_msvcrt_debug", + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile], + flag_groups = [flag_group(flags = ["/MTd"])], + ), + flag_set( + actions = all_link_actions, + flag_groups = [flag_group(flags = ["/DEFAULTLIB:libcmtd.lib"])], + ), + ], + requires = [feature_set(features = ["dbg"])], + ) + + frame_pointer_feature = feature( + name = "frame_pointer", + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile], + flag_groups = [flag_group(flags = ["/Oy-"])], + ), + ], + ) + + compiler_output_flags_feature = feature( + name = "compiler_output_flags", + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.assemble], + flag_groups = [ + flag_group( + flag_groups = [ + flag_group( + flags = ["/Fo%{output_file}", "/Zi"], + expand_if_available = "output_file", + expand_if_not_available = "output_assembly_file", + ), + ], + expand_if_not_available = "output_preprocess_file", + ), + ], + ), + flag_set( + actions = [ + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ], + flag_groups = [ + flag_group( + flag_groups = [ + flag_group( + flags = ["/Fo%{output_file}"], + expand_if_not_available = "output_preprocess_file", + ), + ], + expand_if_available = "output_file", + expand_if_not_available = "output_assembly_file", + ), + flag_group( + flag_groups = [ + flag_group( + flags = ["/Fa%{output_file}"], + expand_if_available = "output_assembly_file", + ), + ], + expand_if_available = "output_file", + ), + flag_group( + flag_groups = [ + flag_group( + flags = ["/P", "/Fi%{output_file}"], + expand_if_available = "output_preprocess_file", + ), + ], + expand_if_available = "output_file", + ), + ], + ), + ], + ) + + nologo_feature = feature( + name = "nologo", + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.cpp_link_executable, + ACTION_NAMES.cpp_link_dynamic_library, + ACTION_NAMES.cpp_link_nodeps_dynamic_library, + ACTION_NAMES.cpp_link_static_library, + ], + flag_groups = [flag_group(flags = ["/nologo"])], + ), + ], + ) + + smaller_binary_feature = feature( + name = "smaller_binary", + enabled = True, + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile], + flag_groups = [flag_group(flags = ["/Gy", "/Gw"])], + with_features = [with_feature_set(features = ["opt"])], + ), + flag_set( + actions = all_link_actions, + flag_groups = [flag_group(flags = ["/OPT:ICF", "/OPT:REF"])], + with_features = [with_feature_set(features = ["opt"])], + ), + ], + ) + + compiler_input_flags_feature = feature( + name = "compiler_input_flags", + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ], + flag_groups = [ + flag_group( + flags = ["/c", "%{source_file}"], + expand_if_available = "source_file", + ), + ], + ), + ], + ) + + def_file_feature = feature( + name = "def_file", + flag_sets = [ + flag_set( + actions = all_link_actions, + flag_groups = [ + flag_group( + flags = ["/DEF:%{def_file_path}", "/ignore:4070"], + expand_if_available = "def_file_path", + ), + ], + ), + ], + ) + + msvc_env_feature = feature( + name = "msvc_env", + env_sets = [ + env_set( + actions = [ + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.cpp_link_executable, + ACTION_NAMES.cpp_link_dynamic_library, + ACTION_NAMES.cpp_link_nodeps_dynamic_library, + ACTION_NAMES.cpp_link_static_library, + ], + env_entries = [ + env_entry(key = "PATH", value = "C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\BIN\\amd64;C:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319;C:\\Windows\\Microsoft.NET\\Framework64\\;C:\\Program Files (x86)\\Windows Kits\\8.1\\bin\\x64;C:\\Program Files (x86)\\Windows Kits\\8.1\\bin\\x86;;C:\\Windows\\system32"), + env_entry(key = "TMP", value = "C:\\Users\\ContainerAdministrator\\AppData\\Local\\Temp"), + env_entry(key = "TEMP", value = "C:\\Users\\ContainerAdministrator\\AppData\\Local\\Temp"), + ], + ), + ], + implies = ["msvc_compile_env", "msvc_link_env"], + ) + + features = [ + no_legacy_features_feature, + nologo_feature, + has_configured_linker_path_feature, + no_stripping_feature, + targets_windows_feature, + copy_dynamic_libraries_to_binary_feature, + default_compile_flags_feature, + msvc_env_feature, + msvc_compile_env_feature, + msvc_link_env_feature, + include_paths_feature, + preprocessor_defines_feature, + parse_showincludes_feature, + generate_pdb_file_feature, + shared_flag_feature, + linkstamps_feature, + output_execpath_flags_feature, + archiver_flags_feature, + input_param_flags_feature, + linker_subsystem_flag_feature, + user_link_flags_feature, + default_link_flags_feature, + linker_param_file_feature, + static_link_msvcrt_feature, + static_link_msvcrt_no_debug_feature, + dynamic_link_msvcrt_no_debug_feature, + static_link_msvcrt_debug_feature, + dynamic_link_msvcrt_debug_feature, + dbg_feature, + fastbuild_feature, + opt_feature, + frame_pointer_feature, + disable_assertions_feature, + determinism_feature, + treat_warnings_as_errors_feature, + smaller_binary_feature, + ignore_noisy_warnings_feature, + user_compile_flags_feature, + sysroot_feature, + unfiltered_compile_flags_feature, + compiler_output_flags_feature, + compiler_input_flags_feature, + def_file_feature, + windows_export_all_symbols_feature, + no_windows_export_all_symbols_feature, + supports_dynamic_linker_feature, + supports_interface_shared_libraries_feature, + ] + + artifact_name_patterns = [ + artifact_name_pattern( + category_name = "object_file", + prefix = "", + extension = ".obj", + ), + artifact_name_pattern( + category_name = "static_library", + prefix = "", + extension = ".lib", + ), + artifact_name_pattern( + category_name = "alwayslink_static_library", + prefix = "", + extension = ".lo.lib", + ), + artifact_name_pattern( + category_name = "executable", + prefix = "", + extension = ".exe", + ), + artifact_name_pattern( + category_name = "dynamic_library", + prefix = "", + extension = ".dll", + ), + artifact_name_pattern( + category_name = "interface_library", + prefix = "", + extension = ".if.lib", + ), + ] + + make_variables = [] + + tool_paths = [ + tool_path(name = "ar", path = "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/amd64/lib.exe"), + tool_path(name = "ml", path = "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/amd64/ml64.exe"), + tool_path(name = "cpp", path = "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/amd64/cl.exe"), + tool_path(name = "gcc", path = "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/amd64/cl.exe"), + tool_path(name = "gcov", path = "wrapper/bin/msvc_nop.bat"), + tool_path(name = "ld", path = "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/amd64/link.exe"), + tool_path(name = "nm", path = "wrapper/bin/msvc_nop.bat"), + tool_path( + name = "objcopy", + path = "wrapper/bin/msvc_nop.bat", + ), + tool_path( + name = "objdump", + path = "wrapper/bin/msvc_nop.bat", + ), + tool_path( + name = "strip", + path = "wrapper/bin/msvc_nop.bat", + ), + ] + + return cc_common.create_cc_toolchain_config_info( + ctx = ctx, + features = features, + action_configs = action_configs, + artifact_name_patterns = artifact_name_patterns, + cxx_builtin_include_directories = cxx_builtin_include_directories, + toolchain_identifier = toolchain_identifier, + host_system_name = host_system_name, + target_system_name = target_system_name, + target_cpu = target_cpu, + target_libc = target_libc, + compiler = compiler, + abi_version = abi_version, + abi_libc_version = abi_libc_version, + tool_paths = tool_paths, + make_variables = make_variables, + builtin_sysroot = builtin_sysroot, + cc_target_os = None, + ) + +def _windows_msys_mingw_impl(ctx): + toolchain_identifier = "msys_x64_mingw" + host_system_name = "local" + target_system_name = "local" + target_cpu = "x64_windows" + target_libc = "mingw" + compiler = "mingw-gcc" + abi_version = "local" + abi_libc_version = "local" + cc_target_os = None + builtin_sysroot = None + action_configs = [] + + targets_windows_feature = feature( + name = "targets_windows", + implies = ["copy_dynamic_libraries_to_binary"], + enabled = True, + ) + + copy_dynamic_libraries_to_binary_feature = feature(name = "copy_dynamic_libraries_to_binary") + + gcc_env_feature = feature( + name = "gcc_env", + enabled = True, + env_sets = [ + env_set( + actions = [ + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.cpp_link_executable, + ACTION_NAMES.cpp_link_dynamic_library, + ACTION_NAMES.cpp_link_nodeps_dynamic_library, + ACTION_NAMES.cpp_link_static_library, + ], + env_entries = [ + env_entry(key = "PATH", value = "c:/tools/msys64/mingw64/bin"), + ], + ), + ], + ) + + msys_mingw_flags = [ + "-std=gnu++0x", + ] + msys_mingw_link_flags = [ + "-lstdc++", + ] + + default_compile_flags_feature = feature( + name = "default_compile_flags", + enabled = True, + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.lto_backend, + ACTION_NAMES.clif_match, + ], + ), + flag_set( + actions = [ + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.lto_backend, + ACTION_NAMES.clif_match, + ], + flag_groups = ([flag_group(flags = msys_mingw_flags)] if msys_mingw_flags else []), + ), + ], + ) + + default_link_flags_feature = feature( + name = "default_link_flags", + enabled = True, + flag_sets = [ + flag_set( + actions = all_link_actions, + flag_groups = ([flag_group(flags = msys_mingw_link_flags)] if msys_mingw_link_flags else []), + ), + ], + ) + + supports_dynamic_linker_feature = feature(name = "supports_dynamic_linker", enabled = True) + + features = [ + targets_windows_feature, + copy_dynamic_libraries_to_binary_feature, + gcc_env_feature, + default_compile_flags_feature, + default_link_flags_feature, + supports_dynamic_linker_feature, + ] + + cxx_builtin_include_directories = [ + # This is a workaround for https://github.com/bazelbuild/bazel/issues/5087. + "C:\\botcode\\w", + "c:/tools/msys64/mingw64/", + "C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\INCLUDE", + "C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.10240.0\\ucrt", + "C:\\Program Files (x86)\\Windows Kits\\8.1\\include\\shared", + "C:\\Program Files (x86)\\Windows Kits\\8.1\\include\\um", + "C:\\Program Files (x86)\\Windows Kits\\8.1\\include\\winrt", + ] + + artifact_name_patterns = [ + artifact_name_pattern( + category_name = "executable", + prefix = "", + extension = ".exe", + ), + ] + + make_variables = [] + tool_paths = [ + tool_path(name = "ar", path = "c:/tools/msys64/mingw64/bin/ar"), + tool_path(name = "compat-ld", path = "c:/tools/msys64/mingw64/bin/ld"), + tool_path(name = "cpp", path = "c:/tools/msys64/mingw64/bin/cpp"), + tool_path(name = "dwp", path = "c:/tools/msys64/mingw64/bin/dwp"), + tool_path(name = "gcc", path = "c:/tools/msys64/mingw64/bin/gcc"), + tool_path(name = "gcov", path = "c:/tools/msys64/mingw64/bin/gcov"), + tool_path(name = "ld", path = "c:/tools/msys64/mingw64/bin/ld"), + tool_path(name = "nm", path = "c:/tools/msys64/mingw64/bin/nm"), + tool_path(name = "objcopy", path = "c:/tools/msys64/mingw64/bin/objcopy"), + tool_path(name = "objdump", path = "c:/tools/msys64/mingw64/bin/objdump"), + tool_path(name = "strip", path = "c:/tools/msys64/mingw64/bin/strip"), + ] + + return cc_common.create_cc_toolchain_config_info( + ctx = ctx, + features = features, + action_configs = action_configs, + artifact_name_patterns = artifact_name_patterns, + cxx_builtin_include_directories = cxx_builtin_include_directories, + toolchain_identifier = toolchain_identifier, + host_system_name = host_system_name, + target_system_name = target_system_name, + target_cpu = target_cpu, + target_libc = target_libc, + compiler = compiler, + abi_version = abi_version, + abi_libc_version = abi_libc_version, + tool_paths = tool_paths, + make_variables = make_variables, + builtin_sysroot = builtin_sysroot, + cc_target_os = cc_target_os, + ) + +def _armeabi_impl(ctx): + toolchain_identifier = "stub_armeabi-v7a" + host_system_name = "armeabi-v7a" + target_system_name = "armeabi-v7a" + target_cpu = "armeabi-v7a" + target_libc = "armeabi-v7a" + compiler = "compiler" + abi_version = "armeabi-v7a" + abi_libc_version = "armeabi-v7a" + cc_target_os = None + builtin_sysroot = None + action_configs = [] + + supports_pic_feature = feature(name = "supports_pic", enabled = True) + supports_dynamic_linker_feature = feature(name = "supports_dynamic_linker", enabled = True) + features = [supports_dynamic_linker_feature, supports_pic_feature] + + cxx_builtin_include_directories = [ + # This is a workaround for https://github.com/bazelbuild/bazel/issues/5087. + "C:\\botcode\\w", + ] + artifact_name_patterns = [] + make_variables = [] + + tool_paths = [ + tool_path(name = "ar", path = "/bin/false"), + tool_path(name = "compat-ld", path = "/bin/false"), + tool_path(name = "cpp", path = "/bin/false"), + tool_path(name = "dwp", path = "/bin/false"), + tool_path(name = "gcc", path = "/bin/false"), + tool_path(name = "gcov", path = "/bin/false"), + tool_path(name = "ld", path = "/bin/false"), + tool_path(name = "nm", path = "/bin/false"), + tool_path(name = "objcopy", path = "/bin/false"), + tool_path(name = "objdump", path = "/bin/false"), + tool_path(name = "strip", path = "/bin/false"), + ] + + return cc_common.create_cc_toolchain_config_info( + ctx = ctx, + features = features, + action_configs = action_configs, + artifact_name_patterns = artifact_name_patterns, + cxx_builtin_include_directories = cxx_builtin_include_directories, + toolchain_identifier = toolchain_identifier, + host_system_name = host_system_name, + target_system_name = target_system_name, + target_cpu = target_cpu, + target_libc = target_libc, + compiler = compiler, + abi_version = abi_version, + abi_libc_version = abi_libc_version, + tool_paths = tool_paths, + make_variables = make_variables, + builtin_sysroot = builtin_sysroot, + cc_target_os = cc_target_os, + ) + +def _impl(ctx): + if ctx.attr.cpu == "armeabi-v7a": + return _armeabi_impl(ctx) + elif ctx.attr.cpu == "x64_windows" and ctx.attr.compiler == "msvc-cl": + return _windows_msvc_impl(ctx) + elif ctx.attr.cpu == "x64_windows" and ctx.attr.compiler == "mingw-gcc": + return _windows_msys_mingw_impl(ctx) + + tool_paths = [ + tool_path(name = "ar", path = "c:/tools/msys64/usr/bin/ar"), + tool_path(name = "compat-ld", path = "c:/tools/msys64/usr/bin/ld"), + tool_path(name = "cpp", path = "c:/tools/msys64/usr/bin/cpp"), + tool_path(name = "dwp", path = "c:/tools/msys64/usr/bin/dwp"), + tool_path(name = "gcc", path = "c:/tools/msys64/usr/bin/gcc"), + tool_path(name = "gcov", path = "c:/tools/msys64/usr/bin/gcov"), + tool_path(name = "ld", path = "c:/tools/msys64/usr/bin/ld"), + tool_path(name = "nm", path = "c:/tools/msys64/usr/bin/nm"), + tool_path(name = "objcopy", path = "c:/tools/msys64/usr/bin/objcopy"), + tool_path(name = "objdump", path = "c:/tools/msys64/usr/bin/objdump"), + tool_path(name = "strip", path = "c:/tools/msys64/usr/bin/strip"), + ] + + cxx_builtin_include_directories = [ + # This is a workaround for https://github.com/bazelbuild/bazel/issues/5087. + "C:\\botcode\\w", + "c:/tools/msys64/usr/", + "C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\INCLUDE", + "C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.10240.0\\ucrt", + "C:\\Program Files (x86)\\Windows Kits\\8.1\\include\\shared", + "C:\\Program Files (x86)\\Windows Kits\\8.1\\include\\um", + "C:\\Program Files (x86)\\Windows Kits\\8.1\\include\\winrt", + ] + + action_configs = [] + + compile_flags = [ + ] + + dbg_compile_flags = [ + ] + + opt_compile_flags = [ + ] + + cxx_flags = [ + "-std=gnu++0x", + ] + + link_flags = [ + "-lstdc++", + ] + + opt_link_flags = [ + ] + + unfiltered_compile_flags = [ + ] + + targets_windows_feature = feature( + name = "targets_windows", + implies = ["copy_dynamic_libraries_to_binary"], + enabled = True, + ) + + copy_dynamic_libraries_to_binary_feature = feature(name = "copy_dynamic_libraries_to_binary") + + gcc_env_feature = feature( + name = "gcc_env", + enabled = True, + env_sets = [ + env_set( + actions = [ + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.cpp_link_executable, + ACTION_NAMES.cpp_link_dynamic_library, + ACTION_NAMES.cpp_link_nodeps_dynamic_library, + ACTION_NAMES.cpp_link_static_library, + ], + env_entries = [ + env_entry(key = "PATH", value = "c:/tools/msys64/usr/bin"), + ], + ), + ], + ) + + windows_features = [ + targets_windows_feature, + copy_dynamic_libraries_to_binary_feature, + gcc_env_feature, + ] + + supports_pic_feature = feature( + name = "supports_pic", + enabled = True, + ) + supports_start_end_lib_feature = feature( + name = "supports_start_end_lib", + enabled = True, + ) + + default_compile_flags_feature = feature( + name = "default_compile_flags", + enabled = True, + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.lto_backend, + ACTION_NAMES.clif_match, + ], + flag_groups = ([flag_group(flags = compile_flags)] if compile_flags else []), + ), + flag_set( + actions = [ + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.lto_backend, + ACTION_NAMES.clif_match, + ], + flag_groups = ([flag_group(flags = dbg_compile_flags)] if dbg_compile_flags else []), + with_features = [with_feature_set(features = ["dbg"])], + ), + flag_set( + actions = [ + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.lto_backend, + ACTION_NAMES.clif_match, + ], + flag_groups = ([flag_group(flags = opt_compile_flags)] if opt_compile_flags else []), + with_features = [with_feature_set(features = ["opt"])], + ), + flag_set( + actions = [ + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.lto_backend, + ACTION_NAMES.clif_match, + ], + flag_groups = ([flag_group(flags = cxx_flags)] if cxx_flags else []), + ), + ], + ) + + default_link_flags_feature = feature( + name = "default_link_flags", + enabled = True, + flag_sets = [ + flag_set( + actions = all_link_actions, + flag_groups = ([flag_group(flags = link_flags)] if link_flags else []), + ), + flag_set( + actions = all_link_actions, + flag_groups = ([flag_group(flags = opt_link_flags)] if opt_link_flags else []), + with_features = [with_feature_set(features = ["opt"])], + ), + ], + ) + + dbg_feature = feature(name = "dbg") + + opt_feature = feature(name = "opt") + + sysroot_feature = feature( + name = "sysroot", + enabled = True, + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.lto_backend, + ACTION_NAMES.clif_match, + ACTION_NAMES.cpp_link_executable, + ACTION_NAMES.cpp_link_dynamic_library, + ACTION_NAMES.cpp_link_nodeps_dynamic_library, + ], + flag_groups = [ + flag_group( + flags = ["--sysroot=%{sysroot}"], + expand_if_available = "sysroot", + ), + ], + ), + ], + ) + + fdo_optimize_feature = feature( + name = "fdo_optimize", + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile], + flag_groups = [ + flag_group( + flags = [ + "-fprofile-use=%{fdo_profile_path}", + "-fprofile-correction", + ], + expand_if_available = "fdo_profile_path", + ), + ], + ), + ], + provides = ["profile"], + ) + + supports_dynamic_linker_feature = feature(name = "supports_dynamic_linker", enabled = True) + + user_compile_flags_feature = feature( + name = "user_compile_flags", + enabled = True, + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.lto_backend, + ACTION_NAMES.clif_match, + ], + flag_groups = [ + flag_group( + flags = ["%{user_compile_flags}"], + iterate_over = "user_compile_flags", + expand_if_available = "user_compile_flags", + ), + ], + ), + ], + ) + + unfiltered_compile_flags_feature = feature( + name = "unfiltered_compile_flags", + enabled = True, + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.lto_backend, + ACTION_NAMES.clif_match, + ], + flag_groups = ([flag_group(flags = unfiltered_compile_flags)] if unfiltered_compile_flags else []), + ), + ], + ) + + features = windows_features + [ + supports_pic_feature, + default_compile_flags_feature, + default_link_flags_feature, + fdo_optimize_feature, + supports_dynamic_linker_feature, + dbg_feature, + opt_feature, + user_compile_flags_feature, + sysroot_feature, + unfiltered_compile_flags_feature, + ] + + artifact_name_patterns = [ + artifact_name_pattern(category_name = "executable", prefix = "", extension = ".exe"), + ] + + make_variables = [] + + return cc_common.create_cc_toolchain_config_info( + ctx = ctx, + features = features, + action_configs = action_configs, + artifact_name_patterns = artifact_name_patterns, + cxx_builtin_include_directories = cxx_builtin_include_directories, + toolchain_identifier = "msys_x64", + host_system_name = "local", + target_system_name = "local", + target_cpu = "x64_windows", + target_libc = "msys", + compiler = "msys-gcc", + abi_version = "local", + abi_libc_version = "local", + tool_paths = tool_paths, + make_variables = make_variables, + builtin_sysroot = "", + cc_target_os = None, + ) + +cc_toolchain_config = rule( + implementation = _impl, + attrs = { + "cpu": attr.string(mandatory = True), + "compiler": attr.string(), + }, + provides = [CcToolchainConfigInfo], +) diff --git a/third_party/toolchains/bazel_0.23.2_rbe_windows/dummy_toolchain.bzl b/third_party/toolchains/bazel_0.23.2_rbe_windows/dummy_toolchain.bzl new file mode 100644 index 00000000000..45c0285d232 --- /dev/null +++ b/third_party/toolchains/bazel_0.23.2_rbe_windows/dummy_toolchain.bzl @@ -0,0 +1,23 @@ +# pylint: disable=g-bad-file-header +# Copyright 2017 The Bazel 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. + +"""Skylark rule that stubs a toolchain.""" + +def _dummy_toolchain_impl(ctx): + ctx = ctx # unused argument + toolchain = platform_common.ToolchainInfo() + return [toolchain] + +dummy_toolchain = rule(_dummy_toolchain_impl, attrs = {}) diff --git a/third_party/toolchains/machine_size/BUILD b/third_party/toolchains/machine_size/BUILD new file mode 100644 index 00000000000..cc962946c31 --- /dev/null +++ b/third_party/toolchains/machine_size/BUILD @@ -0,0 +1,31 @@ +# 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 + +package(default_visibility = ["//visibility:public"]) + +constraint_setting(name = "machine_size") + +constraint_value( + name = "large", + constraint_setting = ":machine_size", +) + +constraint_value( + name = "standard", + constraint_setting = ":machine_size", +) + +# Add other constraint values as needed (tiny, huge, etc.) in the future. diff --git a/third_party/upb b/third_party/upb new file mode 160000 index 00000000000..fa88c6017dd --- /dev/null +++ b/third_party/upb @@ -0,0 +1 @@ +Subproject commit fa88c6017ddb490aa78c57bea682193f533ed69a diff --git a/tools/bazel.rc b/tools/bazel.rc index 59e597b4723..99347495361 100644 --- a/tools/bazel.rc +++ b/tools/bazel.rc @@ -57,3 +57,7 @@ build:basicprof --copt=-DNDEBUG build:basicprof --copt=-O2 build:basicprof --copt=-DGRPC_BASIC_PROFILER build:basicprof --copt=-DGRPC_TIMERS_RDTSC + +build:python3 --python_path=python3 +build:python3 --force_python=PY3 +build:python3 --action_env=PYTHON_BIN_PATH=python3 diff --git a/tools/bazel.sh b/tools/bazel.sh new file mode 100755 index 00000000000..37fd2a242bf --- /dev/null +++ b/tools/bazel.sh @@ -0,0 +1,53 @@ +#!/bin/bash +# Copyright 2019 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. +# 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. + + +# Keeping up with Bazel's breaking changes is currently difficult. +# This script wraps calling bazel by downloading the currently +# supported version, and then calling it. This way, we can make sure +# that running bazel will always get meaningful results, at least +# until Bazel 1.0 is released. + +set -e + +VERSION=0.24.1 + +CWD=`pwd` +BASEURL=https://github.com/bazelbuild/bazel/releases/download/ +cd `dirname $0` +TOOLDIR=`pwd` + +case `uname -sm` in + "Linux x86_64") + suffix=linux-x86_64 + ;; + "Darwin x86_64") + suffix=darwin-x86_64 + ;; + *) + echo "Unsupported architecture: `uname -sm`" + exit 1 + ;; +esac + +filename=bazel-$VERSION-$suffix + +if [ ! -x $filename ] ; then + curl -L $BASEURL/$VERSION/$filename > $filename + chmod a+x $filename +fi + +cd $CWD +$TOOLDIR/$filename $@ diff --git a/tools/buildgen/generate_build_additions.sh b/tools/buildgen/generate_build_additions.sh index 5a1f4a598a7..c99ad6ee552 100755 --- a/tools/buildgen/generate_build_additions.sh +++ b/tools/buildgen/generate_build_additions.sh @@ -19,6 +19,7 @@ gen_build_yaml_dirs=" \ src/boringssl \ src/benchmark \ src/proto \ + src/upb \ src/zlib \ src/c-ares \ test/core/bad_client \ diff --git a/tools/codegen/core/gen_static_metadata.py b/tools/codegen/core/gen_static_metadata.py index adfd4a24f95..d66fdc3e835 100755 --- a/tools/codegen/core/gen_static_metadata.py +++ b/tools/codegen/core/gen_static_metadata.py @@ -64,6 +64,7 @@ CONFIG = [ # well known method names '/grpc.lb.v1.LoadBalancer/BalanceLoad', '/grpc.health.v1.Health/Watch', + '/envoy.service.discovery.v2.AggregatedDiscoveryService/StreamAggregatedResources', # compression algorithm names 'deflate', 'gzip', @@ -375,6 +376,8 @@ print >> H, '#define GRPC_CORE_LIB_TRANSPORT_STATIC_METADATA_H' print >> H print >> H, '#include ' print >> H +print >> H, '#include ' +print >> H print >> H, '#include "src/core/lib/transport/metadata.h"' print >> H print >> C, '#include ' @@ -393,7 +396,7 @@ for i, elem in enumerate(all_strs): def slice_def(i): return ('{&grpc_static_metadata_refcounts[%d],' - ' {{g_bytes+%d, %d}}}') % (i, id2strofs[i], len(all_strs[i])) + ' {{%d, g_bytes+%d}}}') % (i, len(all_strs[i]), id2strofs[i]) # validate configuration @@ -411,29 +414,19 @@ print >> H print >> C, 'static uint8_t g_bytes[] = {%s};' % (','.join( '%d' % ord(c) for c in ''.join(all_strs))) print >> C -print >> C, 'static void static_ref(void *unused) {}' -print >> C, 'static void static_unref(void *unused) {}' -print >> C, ('static const grpc_slice_refcount_vtable static_sub_vtable = ' - '{static_ref, static_unref, grpc_slice_default_eq_impl, ' - 'grpc_slice_default_hash_impl};') -print >> H, ('extern const grpc_slice_refcount_vtable ' - 'grpc_static_metadata_vtable;') -print >> C, ('const grpc_slice_refcount_vtable grpc_static_metadata_vtable = ' - '{static_ref, static_unref, grpc_static_slice_eq, ' - 'grpc_static_slice_hash};') -print >> C, ('static grpc_slice_refcount static_sub_refcnt = ' - '{&static_sub_vtable, &static_sub_refcnt};') +print >> C, ('static grpc_slice_refcount static_sub_refcnt;') print >> H, ('extern grpc_slice_refcount ' 'grpc_static_metadata_refcounts[GRPC_STATIC_MDSTR_COUNT];') print >> C, ('grpc_slice_refcount ' 'grpc_static_metadata_refcounts[GRPC_STATIC_MDSTR_COUNT] = {') for i, elem in enumerate(all_strs): - print >> C, ' {&grpc_static_metadata_vtable, &static_sub_refcnt},' + print >> C, (' grpc_slice_refcount(&static_sub_refcnt, ' + 'grpc_slice_refcount::Type::STATIC), ') print >> C, '};' print >> C print >> H, '#define GRPC_IS_STATIC_METADATA_STRING(slice) \\' -print >> H, (' ((slice).refcount != NULL && (slice).refcount->vtable == ' - '&grpc_static_metadata_vtable)') +print >> H, (' ((slice).refcount != NULL && (slice).refcount->GetType() == ' + 'grpc_slice_refcount::Type::STATIC)') print >> H print >> C, ('const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT]' ' = {') @@ -442,8 +435,8 @@ for i, elem in enumerate(all_strs): print >> C, '};' print >> C print >> H, '#define GRPC_STATIC_METADATA_INDEX(static_slice) \\' -print >> H, (' ((int)((static_slice).refcount - ' - 'grpc_static_metadata_refcounts))') +print >> H, (' (static_cast(((static_slice).refcount - ' + 'grpc_static_metadata_refcounts)))') print >> H print >> D, '# hpack fuzzing dictionary' @@ -546,10 +539,10 @@ print >> C, 'static const uint8_t elem_idxs[] = {%s};' % ','.join( '%d' % i for i in idxs) print >> C -print >> H, 'grpc_mdelem grpc_static_mdelem_for_static_strings(int a, int b);' -print >> C, 'grpc_mdelem grpc_static_mdelem_for_static_strings(int a, int b) {' +print >> H, 'grpc_mdelem grpc_static_mdelem_for_static_strings(intptr_t a, intptr_t b);' +print >> C, 'grpc_mdelem grpc_static_mdelem_for_static_strings(intptr_t a, intptr_t b) {' print >> C, ' if (a == -1 || b == -1) return GRPC_MDNULL;' -print >> C, ' uint32_t k = (uint32_t)(a * %d + b);' % len(all_strs) +print >> C, ' uint32_t k = static_cast(a * %d + b);' % len(all_strs) print >> C, ' uint32_t h = elems_phash(k);' print >> C, ' return h < GPR_ARRAY_SIZE(elem_keys) && elem_keys[h] == k && elem_idxs[h] != 255 ? GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[elem_idxs[h]], GRPC_MDELEM_STORAGE_STATIC) : GRPC_MDNULL;' print >> C, '}' @@ -575,7 +568,7 @@ print >> H, ' } named;' print >> H, '} grpc_metadata_batch_callouts;' print >> H print >> H, '#define GRPC_BATCH_INDEX_OF(slice) \\' -print >> H, ' (GRPC_IS_STATIC_METADATA_STRING((slice)) ? (grpc_metadata_batch_callouts_index)GPR_CLAMP(GRPC_STATIC_METADATA_INDEX((slice)), 0, GRPC_BATCH_CALLOUTS_COUNT) : GRPC_BATCH_CALLOUTS_COUNT)' +print >> H, ' (GRPC_IS_STATIC_METADATA_STRING((slice)) ? static_cast(GPR_CLAMP(GRPC_STATIC_METADATA_INDEX((slice)), 0, static_cast(GRPC_BATCH_CALLOUTS_COUNT))) : GRPC_BATCH_CALLOUTS_COUNT)' print >> H print >> H, 'extern const uint8_t grpc_static_accept_encoding_metadata[%d];' % ( diff --git a/tools/codegen/core/gen_upb_api.sh b/tools/codegen/core/gen_upb_api.sh new file mode 100755 index 00000000000..ff21c49362c --- /dev/null +++ b/tools/codegen/core/gen_upb_api.sh @@ -0,0 +1,62 @@ +#!/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. + +# REQUIRES: Bazel +set -ex +rm -rf src/core/ext/upb-generated +mkdir src/core/ext/upb-generated +cd third_party +cd upb +bazel build :protoc-gen-upb + +cd ../.. + +proto_files=( \ + "google/api/annotations.proto" \ + "google/api/http.proto" \ + "google/protobuf/any.proto" \ + "google/protobuf/descriptor.proto" \ + "google/protobuf/duration.proto" \ + "google/protobuf/empty.proto" \ + "google/protobuf/struct.proto" \ + "google/protobuf/timestamp.proto" \ + "google/protobuf/wrappers.proto" \ + "google/rpc/status.proto" \ + "gogoproto/gogo.proto" \ + "validate/validate.proto" \ + "envoy/type/percent.proto" \ + "envoy/type/range.proto" \ + "envoy/api/v2/core/address.proto" \ + "envoy/api/v2/core/base.proto" \ + "envoy/api/v2/core/config_source.proto" \ + "envoy/api/v2/core/grpc_service.proto" \ + "envoy/api/v2/core/health_check.proto" \ + "envoy/api/v2/core/protocol.proto" \ + "envoy/api/v2/auth/cert.proto" \ + "envoy/api/v2/cluster/circuit_breaker.proto" \ + "envoy/api/v2/cluster/outlier_detection.proto" \ + "envoy/api/v2/discovery.proto" \ + "envoy/api/v2/cds.proto" \ + "envoy/api/v2/eds.proto" \ + "envoy/api/v2/endpoint/endpoint.proto" \ + "envoy/api/v2/endpoint/load_report.proto" \ + "envoy/service/discovery/v2/ads.proto" \ + "envoy/service/load_stats/v2/lrs.proto") + +for i in "${proto_files[@]}" +do + protoc -I=$PWD/third_party/data-plane-api -I=$PWD/third_party/googleapis -I=$PWD/third_party/protobuf -I=$PWD/third_party/protoc-gen-validate $i --upb_out=./src/core/ext/upb-generated --plugin=protoc-gen-upb=third_party/upb/bazel-bin/protoc-gen-upb +done diff --git a/tools/distrib/bazel_style.cfg b/tools/distrib/bazel_style.cfg new file mode 100644 index 00000000000..a5a1fea4aba --- /dev/null +++ b/tools/distrib/bazel_style.cfg @@ -0,0 +1,4 @@ +[style] +based_on_style = google +allow_split_before_dict_value = False +spaces_around_default_or_named_assign = True diff --git a/tools/distrib/build_ruby_environment_macos.sh b/tools/distrib/build_ruby_environment_macos.sh index 9e3e3b46f80..c2c0dcde6bd 100644 --- a/tools/distrib/build_ruby_environment_macos.sh +++ b/tools/distrib/build_ruby_environment_macos.sh @@ -49,7 +49,7 @@ EOF MAKE="make -j8" -for v in 2.5.0 2.4.0 2.3.0 2.2.2 2.1.6 2.0.0-p645 ; do +for v in 2.6.0 2.5.0 2.4.0 2.3.0 2.2.2 ; do ccache -c rake -f "$CROSS_RUBY" cross-ruby VERSION="$v" HOST=x86_64-darwin11 MAKE="$MAKE" done diff --git a/tools/distrib/check_copyright.py b/tools/distrib/check_copyright.py index 787bef1778e..aed63474b2d 100755 --- a/tools/distrib/check_copyright.py +++ b/tools/distrib/check_copyright.py @@ -154,6 +154,9 @@ except subprocess.CalledProcessError: for filename in filename_list: if filename in _EXEMPT: continue + # Skip check for upb generated code. + if filename.endswith('.upb.h') or filename.endswith('.upb.c'): + continue ext = os.path.splitext(filename)[1] base = os.path.basename(filename) if ext in RE_LICENSE: diff --git a/tools/distrib/check_include_guards.py b/tools/distrib/check_include_guards.py index b8d530cce06..94794b1e43f 100755 --- a/tools/distrib/check_include_guards.py +++ b/tools/distrib/check_include_guards.py @@ -190,6 +190,9 @@ validator = GuardValidator() for filename in filename_list: if filename in KNOWN_BAD: continue + # Skip check for upb generated code. + if filename.endswith('.upb.h') or filename.endswith('.upb.c'): + continue ok = ok and validator.check(filename, args.fix) sys.exit(0 if ok else 1) diff --git a/tools/distrib/format_bazel.sh b/tools/distrib/format_bazel.sh new file mode 100755 index 00000000000..ee230118efb --- /dev/null +++ b/tools/distrib/format_bazel.sh @@ -0,0 +1,39 @@ +#!/bin/bash +# Copyright 2019 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. +# 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 + +VIRTUAL_ENV=bazel_format_virtual_environment + +CONFIG_PATH="$(dirname ${0})/bazel_style.cfg" + +python -m virtualenv ${VIRTUAL_ENV} +PYTHON=${VIRTUAL_ENV}/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 + +pushd "$(dirname "${0}")/../.." +FILES=$(find . -path ./third_party -prune -o -name '*.bzl' -print) +echo "${FILES}" | xargs "$PYTHON" -m yapf -i --style="${CONFIG_PATH}" + +if ! which buildifier &>/dev/null; then + echo 'buildifer must be installed.' >/dev/stderr + exit 1 +fi + +echo "${FILES}" | xargs buildifier --type=bzl + +popd diff --git a/tools/distrib/pylint_code.sh b/tools/distrib/pylint_code.sh index 82a818cce5a..75aed1c4814 100755 --- a/tools/distrib/pylint_code.sh +++ b/tools/distrib/pylint_code.sh @@ -20,9 +20,11 @@ cd "$(dirname "$0")/../.." DIRS=( 'src/python/grpcio/grpc' + 'src/python/grpcio_channelz/grpc_channelz' 'src/python/grpcio_health_checking/grpc_health' 'src/python/grpcio_reflection/grpc_reflection' 'src/python/grpcio_testing/grpc_testing' + 'src/python/grpcio_status/grpc_status' ) TEST_DIRS=( @@ -30,12 +32,12 @@ TEST_DIRS=( ) VIRTUALENV=python_pylint_venv -python -m virtualenv $VIRTUALENV +python3 -m virtualenv $VIRTUALENV -p $(which python3) PYTHON=$VIRTUALENV/bin/python -$PYTHON -m pip install --upgrade pip==10.0.1 -$PYTHON -m pip install pylint==1.9.2 +$PYTHON -m pip install --upgrade pip==18.1 +$PYTHON -m pip install --upgrade pylint==2.2.2 EXIT=0 for dir in "${DIRS[@]}"; do @@ -46,4 +48,10 @@ for dir in "${TEST_DIRS[@]}"; do $PYTHON -m pylint --rcfile=.pylintrc-tests -rn "$dir" || EXIT=1 done +find examples/python \ + -iname "*.py" \ + -not -name "*_pb2.py" \ + -not -name "*_pb2_grpc.py" \ + | xargs $PYTHON -m pylint --rcfile=.pylintrc-examples -rn + exit $EXIT diff --git a/tools/distrib/python/docgen.py b/tools/distrib/python/docgen.py index de47c00618d..67d0054656c 100755 --- a/tools/distrib/python/docgen.py +++ b/tools/distrib/python/docgen.py @@ -44,7 +44,7 @@ PROJECT_ROOT = os.path.abspath(os.path.join(SCRIPT_DIR, '..', '..', '..')) CONFIG = args.config SETUP_PATH = os.path.join(PROJECT_ROOT, 'setup.py') -REQUIREMENTS_PATH = os.path.join(PROJECT_ROOT, 'requirements.txt') +REQUIREMENTS_PATH = os.path.join(PROJECT_ROOT, 'requirements.bazel.txt') DOC_PATH = os.path.join(PROJECT_ROOT, 'doc/build') INCLUDE_PATH = os.path.join(PROJECT_ROOT, 'include') LIBRARY_PATH = os.path.join(PROJECT_ROOT, 'libs/{}'.format(CONFIG)) diff --git a/tools/distrib/python/grpcio_tools/grpc_tools/command.py b/tools/distrib/python/grpcio_tools/grpc_tools/command.py index 7ede05f1404..1e556f5fd66 100644 --- a/tools/distrib/python/grpcio_tools/grpc_tools/command.py +++ b/tools/distrib/python/grpcio_tools/grpc_tools/command.py @@ -21,7 +21,7 @@ import setuptools from grpc_tools import protoc -def build_package_protos(package_root): +def build_package_protos(package_root, strict_mode=False): proto_files = [] inclusion_root = os.path.abspath(package_root) for root, _, files in os.walk(inclusion_root): @@ -42,17 +42,21 @@ def build_package_protos(package_root): '--grpc_python_out={}'.format(inclusion_root), ] + [proto_file] if protoc.main(command) != 0: - sys.stderr.write('warning: {} failed'.format(command)) + if strict_mode: + raise Exception('error: {} failed'.format(command)) + else: + sys.stderr.write('warning: {} failed'.format(command)) class BuildPackageProtos(setuptools.Command): """Command to generate project *_pb2.py modules from proto files.""" description = 'build grpc protobuf modules' - user_options = [] + user_options = [('strict-mode', 's', + 'exit with non-zero value if the proto compiling fails.')] def initialize_options(self): - pass + self.strict_mode = False def finalize_options(self): pass @@ -62,4 +66,5 @@ class BuildPackageProtos(setuptools.Command): # directory is provided as an 'include' directory. We assume it's the '' key # to `self.distribution.package_dir` (and get a key error if it's not # there). - build_package_protos(self.distribution.package_dir['']) + build_package_protos(self.distribution.package_dir[''], + self.strict_mode) diff --git a/tools/distrib/python/grpcio_tools/grpc_version.py b/tools/distrib/python/grpcio_tools/grpc_version.py index 4b775e667ea..24ec4301b65 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.17.0.dev0' +VERSION = '1.22.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 7d10db0329c..e7e4ba307ec 100644 --- a/tools/distrib/python/grpcio_tools/protoc_lib_deps.py +++ b/tools/distrib/python/grpcio_tools/protoc_lib_deps.py @@ -14,10 +14,10 @@ # limitations under the License. # AUTO-GENERATED BY make_grpcio_tools.py! -CC_FILES=['google/protobuf/compiler/zip_writer.cc', 'google/protobuf/compiler/subprocess.cc', 'google/protobuf/compiler/ruby/ruby_generator.cc', 'google/protobuf/compiler/python/python_generator.cc', 'google/protobuf/compiler/plugin.pb.cc', 'google/protobuf/compiler/plugin.cc', 'google/protobuf/compiler/php/php_generator.cc', 'google/protobuf/compiler/objectivec/objectivec_primitive_field.cc', 'google/protobuf/compiler/objectivec/objectivec_oneof.cc', 'google/protobuf/compiler/objectivec/objectivec_message_field.cc', 'google/protobuf/compiler/objectivec/objectivec_message.cc', 'google/protobuf/compiler/objectivec/objectivec_map_field.cc', 'google/protobuf/compiler/objectivec/objectivec_helpers.cc', 'google/protobuf/compiler/objectivec/objectivec_generator.cc', 'google/protobuf/compiler/objectivec/objectivec_file.cc', 'google/protobuf/compiler/objectivec/objectivec_field.cc', 'google/protobuf/compiler/objectivec/objectivec_extension.cc', 'google/protobuf/compiler/objectivec/objectivec_enum_field.cc', 'google/protobuf/compiler/objectivec/objectivec_enum.cc', 'google/protobuf/compiler/js/well_known_types_embed.cc', 'google/protobuf/compiler/js/js_generator.cc', 'google/protobuf/compiler/java/java_string_field_lite.cc', 'google/protobuf/compiler/java/java_string_field.cc', 'google/protobuf/compiler/java/java_shared_code_generator.cc', 'google/protobuf/compiler/java/java_service.cc', 'google/protobuf/compiler/java/java_primitive_field_lite.cc', 'google/protobuf/compiler/java/java_primitive_field.cc', 'google/protobuf/compiler/java/java_name_resolver.cc', 'google/protobuf/compiler/java/java_message_lite.cc', 'google/protobuf/compiler/java/java_message_field_lite.cc', 'google/protobuf/compiler/java/java_message_field.cc', 'google/protobuf/compiler/java/java_message_builder_lite.cc', 'google/protobuf/compiler/java/java_message_builder.cc', 'google/protobuf/compiler/java/java_message.cc', 'google/protobuf/compiler/java/java_map_field_lite.cc', 'google/protobuf/compiler/java/java_map_field.cc', 'google/protobuf/compiler/java/java_lazy_message_field_lite.cc', 'google/protobuf/compiler/java/java_lazy_message_field.cc', 'google/protobuf/compiler/java/java_helpers.cc', 'google/protobuf/compiler/java/java_generator_factory.cc', 'google/protobuf/compiler/java/java_generator.cc', 'google/protobuf/compiler/java/java_file.cc', 'google/protobuf/compiler/java/java_field.cc', 'google/protobuf/compiler/java/java_extension_lite.cc', 'google/protobuf/compiler/java/java_extension.cc', 'google/protobuf/compiler/java/java_enum_lite.cc', 'google/protobuf/compiler/java/java_enum_field_lite.cc', 'google/protobuf/compiler/java/java_enum_field.cc', 'google/protobuf/compiler/java/java_enum.cc', 'google/protobuf/compiler/java/java_doc_comment.cc', 'google/protobuf/compiler/java/java_context.cc', 'google/protobuf/compiler/csharp/csharp_wrapper_field.cc', 'google/protobuf/compiler/csharp/csharp_source_generator_base.cc', 'google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc', 'google/protobuf/compiler/csharp/csharp_repeated_message_field.cc', 'google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc', 'google/protobuf/compiler/csharp/csharp_reflection_class.cc', 'google/protobuf/compiler/csharp/csharp_primitive_field.cc', 'google/protobuf/compiler/csharp/csharp_message_field.cc', 'google/protobuf/compiler/csharp/csharp_message.cc', 'google/protobuf/compiler/csharp/csharp_map_field.cc', 'google/protobuf/compiler/csharp/csharp_helpers.cc', 'google/protobuf/compiler/csharp/csharp_generator.cc', 'google/protobuf/compiler/csharp/csharp_field_base.cc', 'google/protobuf/compiler/csharp/csharp_enum_field.cc', 'google/protobuf/compiler/csharp/csharp_enum.cc', 'google/protobuf/compiler/csharp/csharp_doc_comment.cc', 'google/protobuf/compiler/cpp/cpp_string_field.cc', 'google/protobuf/compiler/cpp/cpp_service.cc', 'google/protobuf/compiler/cpp/cpp_primitive_field.cc', 'google/protobuf/compiler/cpp/cpp_padding_optimizer.cc', 'google/protobuf/compiler/cpp/cpp_message_field.cc', 'google/protobuf/compiler/cpp/cpp_message.cc', 'google/protobuf/compiler/cpp/cpp_map_field.cc', 'google/protobuf/compiler/cpp/cpp_helpers.cc', 'google/protobuf/compiler/cpp/cpp_generator.cc', 'google/protobuf/compiler/cpp/cpp_file.cc', 'google/protobuf/compiler/cpp/cpp_field.cc', 'google/protobuf/compiler/cpp/cpp_extension.cc', 'google/protobuf/compiler/cpp/cpp_enum_field.cc', 'google/protobuf/compiler/cpp/cpp_enum.cc', 'google/protobuf/compiler/command_line_interface.cc', 'google/protobuf/compiler/code_generator.cc', 'google/protobuf/wrappers.pb.cc', 'google/protobuf/wire_format.cc', 'google/protobuf/util/type_resolver_util.cc', 'google/protobuf/util/time_util.cc', 'google/protobuf/util/message_differencer.cc', 'google/protobuf/util/json_util.cc', 'google/protobuf/util/internal/utility.cc', 'google/protobuf/util/internal/type_info_test_helper.cc', 'google/protobuf/util/internal/type_info.cc', 'google/protobuf/util/internal/protostream_objectwriter.cc', 'google/protobuf/util/internal/protostream_objectsource.cc', 'google/protobuf/util/internal/proto_writer.cc', 'google/protobuf/util/internal/object_writer.cc', 'google/protobuf/util/internal/json_stream_parser.cc', 'google/protobuf/util/internal/json_objectwriter.cc', 'google/protobuf/util/internal/json_escaping.cc', 'google/protobuf/util/internal/field_mask_utility.cc', 'google/protobuf/util/internal/error_listener.cc', 'google/protobuf/util/internal/default_value_objectwriter.cc', 'google/protobuf/util/internal/datapiece.cc', 'google/protobuf/util/field_mask_util.cc', 'google/protobuf/util/field_comparator.cc', 'google/protobuf/util/delimited_message_util.cc', 'google/protobuf/unknown_field_set.cc', 'google/protobuf/type.pb.cc', 'google/protobuf/timestamp.pb.cc', 'google/protobuf/text_format.cc', 'google/protobuf/stubs/substitute.cc', 'google/protobuf/stubs/mathlimits.cc', 'google/protobuf/struct.pb.cc', 'google/protobuf/source_context.pb.cc', 'google/protobuf/service.cc', 'google/protobuf/reflection_ops.cc', 'google/protobuf/message.cc', 'google/protobuf/map_field.cc', 'google/protobuf/io/zero_copy_stream_impl.cc', 'google/protobuf/io/tokenizer.cc', 'google/protobuf/io/strtod.cc', 'google/protobuf/io/printer.cc', 'google/protobuf/io/gzip_stream.cc', 'google/protobuf/generated_message_table_driven.cc', 'google/protobuf/generated_message_reflection.cc', 'google/protobuf/field_mask.pb.cc', 'google/protobuf/extension_set_heavy.cc', 'google/protobuf/empty.pb.cc', 'google/protobuf/dynamic_message.cc', 'google/protobuf/duration.pb.cc', 'google/protobuf/descriptor_database.cc', 'google/protobuf/descriptor.pb.cc', 'google/protobuf/descriptor.cc', 'google/protobuf/compiler/parser.cc', 'google/protobuf/compiler/importer.cc', 'google/protobuf/api.pb.cc', 'google/protobuf/any.pb.cc', 'google/protobuf/any.cc', 'google/protobuf/wire_format_lite.cc', 'google/protobuf/stubs/time.cc', 'google/protobuf/stubs/strutil.cc', 'google/protobuf/stubs/structurally_valid.cc', 'google/protobuf/stubs/stringprintf.cc', 'google/protobuf/stubs/stringpiece.cc', 'google/protobuf/stubs/statusor.cc', 'google/protobuf/stubs/status.cc', 'google/protobuf/stubs/io_win32.cc', 'google/protobuf/stubs/int128.cc', 'google/protobuf/stubs/common.cc', 'google/protobuf/stubs/bytestream.cc', 'google/protobuf/repeated_field.cc', 'google/protobuf/message_lite.cc', 'google/protobuf/io/zero_copy_stream_impl_lite.cc', 'google/protobuf/io/zero_copy_stream.cc', 'google/protobuf/io/coded_stream.cc', 'google/protobuf/implicit_weak_message.cc', 'google/protobuf/generated_message_util.cc', 'google/protobuf/generated_message_table_driven_lite.cc', 'google/protobuf/extension_set.cc', 'google/protobuf/arenastring.cc', 'google/protobuf/arena.cc'] +CC_FILES=['google/protobuf/compiler/zip_writer.cc', 'google/protobuf/compiler/subprocess.cc', 'google/protobuf/compiler/ruby/ruby_generator.cc', 'google/protobuf/compiler/python/python_generator.cc', 'google/protobuf/compiler/plugin.pb.cc', 'google/protobuf/compiler/plugin.cc', 'google/protobuf/compiler/php/php_generator.cc', 'google/protobuf/compiler/objectivec/objectivec_primitive_field.cc', 'google/protobuf/compiler/objectivec/objectivec_oneof.cc', 'google/protobuf/compiler/objectivec/objectivec_message_field.cc', 'google/protobuf/compiler/objectivec/objectivec_message.cc', 'google/protobuf/compiler/objectivec/objectivec_map_field.cc', 'google/protobuf/compiler/objectivec/objectivec_helpers.cc', 'google/protobuf/compiler/objectivec/objectivec_generator.cc', 'google/protobuf/compiler/objectivec/objectivec_file.cc', 'google/protobuf/compiler/objectivec/objectivec_field.cc', 'google/protobuf/compiler/objectivec/objectivec_extension.cc', 'google/protobuf/compiler/objectivec/objectivec_enum_field.cc', 'google/protobuf/compiler/objectivec/objectivec_enum.cc', 'google/protobuf/compiler/js/well_known_types_embed.cc', 'google/protobuf/compiler/js/js_generator.cc', 'google/protobuf/compiler/java/java_string_field_lite.cc', 'google/protobuf/compiler/java/java_string_field.cc', 'google/protobuf/compiler/java/java_shared_code_generator.cc', 'google/protobuf/compiler/java/java_service.cc', 'google/protobuf/compiler/java/java_primitive_field_lite.cc', 'google/protobuf/compiler/java/java_primitive_field.cc', 'google/protobuf/compiler/java/java_name_resolver.cc', 'google/protobuf/compiler/java/java_message_lite.cc', 'google/protobuf/compiler/java/java_message_field_lite.cc', 'google/protobuf/compiler/java/java_message_field.cc', 'google/protobuf/compiler/java/java_message_builder_lite.cc', 'google/protobuf/compiler/java/java_message_builder.cc', 'google/protobuf/compiler/java/java_message.cc', 'google/protobuf/compiler/java/java_map_field_lite.cc', 'google/protobuf/compiler/java/java_map_field.cc', 'google/protobuf/compiler/java/java_helpers.cc', 'google/protobuf/compiler/java/java_generator_factory.cc', 'google/protobuf/compiler/java/java_generator.cc', 'google/protobuf/compiler/java/java_file.cc', 'google/protobuf/compiler/java/java_field.cc', 'google/protobuf/compiler/java/java_extension_lite.cc', 'google/protobuf/compiler/java/java_extension.cc', 'google/protobuf/compiler/java/java_enum_lite.cc', 'google/protobuf/compiler/java/java_enum_field_lite.cc', 'google/protobuf/compiler/java/java_enum_field.cc', 'google/protobuf/compiler/java/java_enum.cc', 'google/protobuf/compiler/java/java_doc_comment.cc', 'google/protobuf/compiler/java/java_context.cc', 'google/protobuf/compiler/csharp/csharp_wrapper_field.cc', 'google/protobuf/compiler/csharp/csharp_source_generator_base.cc', 'google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc', 'google/protobuf/compiler/csharp/csharp_repeated_message_field.cc', 'google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc', 'google/protobuf/compiler/csharp/csharp_reflection_class.cc', 'google/protobuf/compiler/csharp/csharp_primitive_field.cc', 'google/protobuf/compiler/csharp/csharp_message_field.cc', 'google/protobuf/compiler/csharp/csharp_message.cc', 'google/protobuf/compiler/csharp/csharp_map_field.cc', 'google/protobuf/compiler/csharp/csharp_helpers.cc', 'google/protobuf/compiler/csharp/csharp_generator.cc', 'google/protobuf/compiler/csharp/csharp_field_base.cc', 'google/protobuf/compiler/csharp/csharp_enum_field.cc', 'google/protobuf/compiler/csharp/csharp_enum.cc', 'google/protobuf/compiler/csharp/csharp_doc_comment.cc', 'google/protobuf/compiler/cpp/cpp_string_field.cc', 'google/protobuf/compiler/cpp/cpp_service.cc', 'google/protobuf/compiler/cpp/cpp_primitive_field.cc', 'google/protobuf/compiler/cpp/cpp_padding_optimizer.cc', 'google/protobuf/compiler/cpp/cpp_message_field.cc', 'google/protobuf/compiler/cpp/cpp_message.cc', 'google/protobuf/compiler/cpp/cpp_map_field.cc', 'google/protobuf/compiler/cpp/cpp_helpers.cc', 'google/protobuf/compiler/cpp/cpp_generator.cc', 'google/protobuf/compiler/cpp/cpp_file.cc', 'google/protobuf/compiler/cpp/cpp_field.cc', 'google/protobuf/compiler/cpp/cpp_extension.cc', 'google/protobuf/compiler/cpp/cpp_enum_field.cc', 'google/protobuf/compiler/cpp/cpp_enum.cc', 'google/protobuf/compiler/command_line_interface.cc', 'google/protobuf/compiler/code_generator.cc', 'google/protobuf/wrappers.pb.cc', 'google/protobuf/wire_format.cc', 'google/protobuf/util/type_resolver_util.cc', 'google/protobuf/util/time_util.cc', 'google/protobuf/util/message_differencer.cc', 'google/protobuf/util/json_util.cc', 'google/protobuf/util/internal/utility.cc', 'google/protobuf/util/internal/type_info_test_helper.cc', 'google/protobuf/util/internal/type_info.cc', 'google/protobuf/util/internal/protostream_objectwriter.cc', 'google/protobuf/util/internal/protostream_objectsource.cc', 'google/protobuf/util/internal/proto_writer.cc', 'google/protobuf/util/internal/object_writer.cc', 'google/protobuf/util/internal/json_stream_parser.cc', 'google/protobuf/util/internal/json_objectwriter.cc', 'google/protobuf/util/internal/json_escaping.cc', 'google/protobuf/util/internal/field_mask_utility.cc', 'google/protobuf/util/internal/error_listener.cc', 'google/protobuf/util/internal/default_value_objectwriter.cc', 'google/protobuf/util/internal/datapiece.cc', 'google/protobuf/util/field_mask_util.cc', 'google/protobuf/util/field_comparator.cc', 'google/protobuf/util/delimited_message_util.cc', 'google/protobuf/unknown_field_set.cc', 'google/protobuf/type.pb.cc', 'google/protobuf/timestamp.pb.cc', 'google/protobuf/text_format.cc', 'google/protobuf/stubs/substitute.cc', 'google/protobuf/stubs/mathlimits.cc', 'google/protobuf/struct.pb.cc', 'google/protobuf/source_context.pb.cc', 'google/protobuf/service.cc', 'google/protobuf/reflection_ops.cc', 'google/protobuf/message.cc', 'google/protobuf/map_field.cc', 'google/protobuf/io/zero_copy_stream_impl.cc', 'google/protobuf/io/tokenizer.cc', 'google/protobuf/io/strtod.cc', 'google/protobuf/io/printer.cc', 'google/protobuf/io/gzip_stream.cc', 'google/protobuf/generated_message_table_driven.cc', 'google/protobuf/generated_message_reflection.cc', 'google/protobuf/field_mask.pb.cc', 'google/protobuf/extension_set_heavy.cc', 'google/protobuf/empty.pb.cc', 'google/protobuf/dynamic_message.cc', 'google/protobuf/duration.pb.cc', 'google/protobuf/descriptor_database.cc', 'google/protobuf/descriptor.pb.cc', 'google/protobuf/descriptor.cc', 'google/protobuf/compiler/parser.cc', 'google/protobuf/compiler/importer.cc', 'google/protobuf/api.pb.cc', 'google/protobuf/any.pb.cc', 'google/protobuf/any.cc', 'google/protobuf/wire_format_lite.cc', 'google/protobuf/stubs/time.cc', 'google/protobuf/stubs/strutil.cc', 'google/protobuf/stubs/structurally_valid.cc', 'google/protobuf/stubs/stringprintf.cc', 'google/protobuf/stubs/stringpiece.cc', 'google/protobuf/stubs/statusor.cc', 'google/protobuf/stubs/status.cc', 'google/protobuf/stubs/io_win32.cc', 'google/protobuf/stubs/int128.cc', 'google/protobuf/stubs/common.cc', 'google/protobuf/stubs/bytestream.cc', 'google/protobuf/repeated_field.cc', 'google/protobuf/message_lite.cc', 'google/protobuf/io/zero_copy_stream_impl_lite.cc', 'google/protobuf/io/zero_copy_stream.cc', 'google/protobuf/io/coded_stream.cc', 'google/protobuf/implicit_weak_message.cc', 'google/protobuf/generated_message_util.cc', 'google/protobuf/generated_message_table_driven_lite.cc', 'google/protobuf/extension_set.cc', 'google/protobuf/arena.cc'] PROTO_FILES=['google/protobuf/wrappers.proto', 'google/protobuf/type.proto', 'google/protobuf/timestamp.proto', 'google/protobuf/struct.proto', 'google/protobuf/source_context.proto', 'google/protobuf/field_mask.proto', 'google/protobuf/empty.proto', 'google/protobuf/duration.proto', 'google/protobuf/descriptor.proto', 'google/protobuf/compiler/plugin.proto', 'google/protobuf/api.proto', 'google/protobuf/any.proto'] CC_INCLUDE='third_party/protobuf/src' PROTO_INCLUDE='third_party/protobuf/src' -PROTOBUF_SUBMODULE_VERSION="48cb18e5c419ddd23d9badcfe4e9df7bde1979b2" +PROTOBUF_SUBMODULE_VERSION="582743bf40c5d3639a70f98f183914a2c0cd0680" diff --git a/tools/distrib/sanitize.sh b/tools/distrib/sanitize.sh index fed1e64b7ca..13488b1e235 100755 --- a/tools/distrib/sanitize.sh +++ b/tools/distrib/sanitize.sh @@ -29,11 +29,11 @@ if [ "x$1" == 'x--pre-commit' ]; then fi fi CHANGED_FILES=$(eval $DIFF_COMMAND) ./tools/distrib/clang_format_code.sh - ./tools/distrib/check_copyright.py --fix --precommit + ./tools/distrib/check_copyright.py --precommit ./tools/distrib/check_trailing_newlines.sh else ./tools/buildgen/generate_projects.sh ./tools/distrib/clang_format_code.sh - ./tools/distrib/check_copyright.py --fix + ./tools/distrib/check_copyright.py ./tools/distrib/check_trailing_newlines.sh fi diff --git a/tools/dockerfile/distribtest/cpp_jessie_x64/Dockerfile b/tools/dockerfile/distribtest/cpp_jessie_x64/Dockerfile index 894f114951c..aeedec8153f 100644 --- a/tools/dockerfile/distribtest/cpp_jessie_x64/Dockerfile +++ b/tools/dockerfile/distribtest/cpp_jessie_x64/Dockerfile @@ -13,6 +13,7 @@ # limitations under the License. FROM debian:jessie +RUN sed -i '/deb http:\/\/deb.debian.org\/debian jessie-updates main/d' /etc/apt/sources.list # Install packages needed for gRPC and protobuf RUN apt-get update && apt-get install -y \ @@ -29,7 +30,9 @@ RUN apt-get update && apt-get install -y \ RUN apt-get update && apt-get install -y golang && apt-get clean -RUN echo "deb http://ftp.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list +RUN echo "deb http://archive.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list +RUN echo 'Acquire::Check-Valid-Until "false";' > /etc/apt/apt.conf +RUN sed -i '/deb http:\/\/deb.debian.org\/debian jessie-updates main/d' /etc/apt/sources.list RUN apt-get update && apt-get install -t jessie-backports -y cmake && apt-get clean CMD ["bash"] diff --git a/tools/dockerfile/distribtest/csharp_centos7_x64/Dockerfile b/tools/dockerfile/distribtest/csharp_centos7_x64/Dockerfile index e32b3cb5e25..d9473bb3a5c 100644 --- a/tools/dockerfile/distribtest/csharp_centos7_x64/Dockerfile +++ b/tools/dockerfile/distribtest/csharp_centos7_x64/Dockerfile @@ -18,6 +18,7 @@ RUN rpm --import "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x3FA7E0 RUN curl https://download.mono-project.com/repo/centos7-stable.repo | tee /etc/yum.repos.d/mono-centos7-stable.repo RUN yum install -y mono-devel +RUN yum install -y msbuild RUN yum install -y nuget diff --git a/tools/dockerfile/distribtest/ruby_centos6_x64/Dockerfile b/tools/dockerfile/distribtest/ruby_centos6_x64/Dockerfile index c3d6e03f6a1..b53ffc22d4f 100644 --- a/tools/dockerfile/distribtest/ruby_centos6_x64/Dockerfile +++ b/tools/dockerfile/distribtest/ruby_centos6_x64/Dockerfile @@ -19,10 +19,19 @@ RUN yum install -y curl RUN yum install -y tar which # Install rvm -RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 +RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB +RUN curl -sSL https://get.rvm.io | bash -s stable + +# Install Ruby 2.2 # Running the installation twice to work around docker issue when using overlay. # https://github.com/docker/docker/issues/10180 -RUN (curl -sSL https://get.rvm.io | bash -s stable --ruby) || (curl -sSL https://get.rvm.io | bash -s stable --ruby) +RUN (/bin/bash -l -c "rvm install ruby-2.2.10") || (/bin/bash -l -c "rvm install ruby-2.2.10") +RUN /bin/bash -l -c "rvm use --default ruby-2.2.10" +RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" +RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" +RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.2.10' >> ~/.bashrc" +RUN /bin/bash -l -c "gem install bundler -v 1.17.3 --no-document" + +RUN mkdir /var/local/jenkins RUN /bin/bash -l -c "echo '. /etc/profile.d/rvm.sh' >> ~/.bashrc" -RUN /bin/bash -l -c "gem install --update bundler" diff --git a/tools/dockerfile/distribtest/ruby_centos7_x64/Dockerfile b/tools/dockerfile/distribtest/ruby_centos7_x64/Dockerfile index 73207e4210d..72235bfba7f 100644 --- a/tools/dockerfile/distribtest/ruby_centos7_x64/Dockerfile +++ b/tools/dockerfile/distribtest/ruby_centos7_x64/Dockerfile @@ -14,6 +14,20 @@ FROM centos:7 -RUN yum install -y ruby +RUN yum update && yum install -y curl tar which -RUN gem install bundler +# Install rvm +RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB +RUN curl -sSL https://get.rvm.io | bash -s stable + +# Install Ruby 2.2 +RUN /bin/bash -l -c "rvm install ruby-2.2.10" +RUN /bin/bash -l -c "rvm use --default ruby-2.2.10" +RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" +RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" +RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.2.10' >> ~/.bashrc" +RUN /bin/bash -l -c "gem install bundler -v 1.17.3 --no-document" + +RUN mkdir /var/local/jenkins + +RUN /bin/bash -l -c "echo '. /etc/profile.d/rvm.sh' >> ~/.bashrc" diff --git a/tools/dockerfile/distribtest/ruby_fedora20_x64/Dockerfile b/tools/dockerfile/distribtest/ruby_fedora20_x64/Dockerfile index 200c5c28033..3d688a889f0 100644 --- a/tools/dockerfile/distribtest/ruby_fedora20_x64/Dockerfile +++ b/tools/dockerfile/distribtest/ruby_fedora20_x64/Dockerfile @@ -14,6 +14,23 @@ FROM fedora:20 -RUN yum clean all && yum update -y && yum install -y ruby findutils +# distro-sync and install openssl, per https://github.com/fedora-cloud/docker-brew-fedora/issues/19 +RUN yum clean all && yum update -y && yum distro-sync -y && yum install -y openssl gnupg which findutils -RUN gem install bundler +# Install rvm +RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB +RUN curl -sSL https://get.rvm.io | bash -s stable + +# Install Ruby 2.2 +# Running the installation twice to work around docker issue when using overlay. +# https://github.com/docker/docker/issues/10180 +RUN (/bin/bash -l -c "rvm install ruby-2.2.10") || (/bin/bash -l -c "rvm install ruby-2.2.10") +RUN /bin/bash -l -c "rvm use --default ruby-2.2.10" +RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" +RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" +RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.2.10' >> ~/.bashrc" +RUN /bin/bash -l -c "gem install bundler -v 1.17.3 --no-document" + +RUN mkdir /var/local/jenkins + +RUN /bin/bash -l -c "echo '. /etc/profile.d/rvm.sh' >> ~/.bashrc" diff --git a/tools/dockerfile/distribtest/ruby_fedora21_x64/Dockerfile b/tools/dockerfile/distribtest/ruby_fedora21_x64/Dockerfile index e1177fd99af..8044adf15dc 100644 --- a/tools/dockerfile/distribtest/ruby_fedora21_x64/Dockerfile +++ b/tools/dockerfile/distribtest/ruby_fedora21_x64/Dockerfile @@ -19,6 +19,21 @@ FROM fedora:21 # 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 findutils +# distro-sync and install openssl, per https://github.com/fedora-cloud/docker-brew-fedora/issues/19 +RUN yum clean all && yum update -y && yum distro-sync -y && yum install -y openssl gnupg which findutils tar -RUN gem install bundler +# Install rvm +RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB +RUN curl -sSL https://get.rvm.io | bash -s stable + +# Install Ruby 2.2 +RUN /bin/bash -l -c "rvm install ruby-2.2.10" +RUN /bin/bash -l -c "rvm use --default ruby-2.2.10" +RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" +RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" +RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.2.10' >> ~/.bashrc" +RUN /bin/bash -l -c "gem install bundler -v 1.17.3 --no-document" + +RUN mkdir /var/local/jenkins + +RUN /bin/bash -l -c "echo '. /etc/profile.d/rvm.sh' >> ~/.bashrc" diff --git a/tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_2/Dockerfile b/tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_2/Dockerfile new file mode 100644 index 00000000000..337fc3b5d8e --- /dev/null +++ b/tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_2/Dockerfile @@ -0,0 +1,40 @@ +# 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 + +# Install Git and basic packages. +RUN apt-get update && apt-get install -y \ + curl \ + gcc && apt-get clean + +#================== +# Ruby dependencies + +# Install rvm +RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB +RUN \curl -sSL https://get.rvm.io | bash -s stable + +# Install Ruby 2.2 +RUN /bin/bash -l -c "rvm install ruby-2.2.10" +RUN /bin/bash -l -c "rvm use --default ruby-2.2.10" +RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" +RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" +RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.2.10' >> ~/.bashrc" +RUN /bin/bash -l -c "gem install bundler -v 1.17.3 --no-document" + +RUN mkdir /var/local/jenkins + +# Define the default command. +CMD ["bash"] diff --git a/tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_3/Dockerfile b/tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_3/Dockerfile new file mode 100644 index 00000000000..9deff0661b7 --- /dev/null +++ b/tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_3/Dockerfile @@ -0,0 +1,41 @@ +# 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 + +# Install Git and basic packages. +RUN apt-get update && apt-get install -y \ + curl \ + gcc && apt-get clean + +#================== +# Ruby dependencies + +# Install rvm +RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB +RUN \curl -sSL https://get.rvm.io | bash -s stable + +# Install Ruby 2.3 +RUN /bin/bash -l -c "rvm install ruby-2.3.8" +RUN /bin/bash -l -c "rvm use --default ruby-2.3.8" +RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" +RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" +RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.3.8' >> ~/.bashrc" +RUN /bin/bash -l -c "gem update --system" +RUN /bin/bash -l -c "gem install bundler -v 1.17.3 --no-document" + +RUN mkdir /var/local/jenkins + +# Define the default command. +CMD ["bash"] diff --git a/tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_4/Dockerfile b/tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_4/Dockerfile new file mode 100644 index 00000000000..55b1b1e731d --- /dev/null +++ b/tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_4/Dockerfile @@ -0,0 +1,40 @@ +# 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 + +# Install Git and basic packages. +RUN apt-get update && apt-get install -y \ + curl \ + gcc && apt-get clean + +#================== +# Ruby dependencies + +# Install rvm +RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB +RUN \curl -sSL https://get.rvm.io | bash -s stable + +# Install Ruby 2.4 +RUN /bin/bash -l -c "rvm install ruby-2.4.5" +RUN /bin/bash -l -c "rvm use --default ruby-2.4.5" +RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" +RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" +RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.4.5' >> ~/.bashrc" +RUN /bin/bash -l -c "gem install bundler -v 1.17.3 --no-document" + +RUN mkdir /var/local/jenkins + +# Define the default command. +CMD ["bash"] diff --git a/tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_5/Dockerfile b/tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_5/Dockerfile new file mode 100644 index 00000000000..bed4b3a93ef --- /dev/null +++ b/tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_5/Dockerfile @@ -0,0 +1,40 @@ +# 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 + +# Install Git and basic packages. +RUN apt-get update && apt-get install -y \ + curl \ + gcc && apt-get clean + +#================== +# Ruby dependencies + +# Install rvm +RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB +RUN \curl -sSL https://get.rvm.io | bash -s stable + +# Install Ruby 2.5 +RUN /bin/bash -l -c "rvm install ruby-2.5.3" +RUN /bin/bash -l -c "rvm use --default ruby-2.5.3" +RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" +RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" +RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.5.3' >> ~/.bashrc" +RUN /bin/bash -l -c "gem install bundler -v 1.17.3 --no-document" + +RUN mkdir /var/local/jenkins + +# Define the default command. +CMD ["bash"] diff --git a/tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_0_0/Dockerfile b/tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_6/Dockerfile similarity index 73% rename from tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_0_0/Dockerfile rename to tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_6/Dockerfile index ff43c92c9e5..af1839eba93 100644 --- a/tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_0_0/Dockerfile +++ b/tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_6/Dockerfile @@ -23,16 +23,16 @@ RUN apt-get update && apt-get install -y \ # Ruby dependencies # Install rvm -RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 +RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB RUN \curl -sSL https://get.rvm.io | bash -s stable -# Install Ruby 2.1 -RUN /bin/bash -l -c "rvm install ruby-2.0" -RUN /bin/bash -l -c "rvm use --default ruby-2.0" -RUN /bin/bash -l -c "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc" +# Install Ruby 2.6 +RUN /bin/bash -l -c "rvm install ruby-2.6.0" +RUN /bin/bash -l -c "rvm use --default ruby-2.6.0" +RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" -RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.0' >> ~/.bashrc" -RUN /bin/bash -l -c "gem install bundler --no-ri --no-rdoc" +RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.6.0' >> ~/.bashrc" +RUN /bin/bash -l -c "gem install bundler --no-document" RUN mkdir /var/local/jenkins diff --git a/tools/dockerfile/grpc_artifact_linux_x64/Dockerfile b/tools/dockerfile/grpc_artifact_linux_x64/Dockerfile index 7ec061ebe58..a0fef12d6e1 100644 --- a/tools/dockerfile/grpc_artifact_linux_x64/Dockerfile +++ b/tools/dockerfile/grpc_artifact_linux_x64/Dockerfile @@ -15,6 +15,7 @@ # Docker file for building gRPC artifacts. FROM debian:jessie +RUN sed -i '/deb http:\/\/deb.debian.org\/debian jessie-updates main/d' /etc/apt/sources.list # Install Git and basic packages. RUN apt-get update && apt-get install -y \ @@ -49,7 +50,8 @@ RUN apt-get update && apt-get install -y \ # Ruby dependencies # Install rvm -RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 +RUN apt-get update && apt-get install -y gnupg2 +RUN gpg --keyserver hkp://pool.sks-keyservers.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB RUN \curl -sSL https://get.rvm.io | bash -s stable # Install Ruby 2.1 @@ -58,7 +60,7 @@ RUN /bin/bash -l -c "rvm use --default ruby-2.1" RUN /bin/bash -l -c "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc" RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.1' >> ~/.bashrc" -RUN /bin/bash -l -c "gem install bundler --no-ri --no-rdoc" +RUN /bin/bash -l -c "gem install bundler -v 1.17.3 --no-ri --no-rdoc" ################## @@ -72,7 +74,9 @@ RUN apt-get update && apt-get install -y \ # C# dependencies (needed to build grpc_csharp_ext) # Use cmake 3.6 from jessie-backports -RUN echo "deb http://ftp.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list +RUN echo "deb http://archive.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list +RUN echo 'Acquire::Check-Valid-Until "false";' > /etc/apt/apt.conf +RUN sed -i '/deb http:\/\/deb.debian.org\/debian jessie-updates main/d' /etc/apt/sources.list RUN apt-get update && apt-get install -t jessie-backports -y cmake && apt-get clean RUN mkdir /var/local/jenkins diff --git a/tools/dockerfile/grpc_artifact_linux_x86/Dockerfile b/tools/dockerfile/grpc_artifact_linux_x86/Dockerfile index f81d8e5ba02..8709fe0426c 100644 --- a/tools/dockerfile/grpc_artifact_linux_x86/Dockerfile +++ b/tools/dockerfile/grpc_artifact_linux_x86/Dockerfile @@ -15,6 +15,7 @@ # Docker file for building gRPC artifacts. FROM 32bit/debian:jessie +RUN sed -i '/deb http:\/\/http.debian.net\/debian jessie-updates main/d' /etc/apt/sources.list # Install Git and basic packages. RUN apt-get update && apt-get install -y \ @@ -49,7 +50,9 @@ RUN apt-get update && apt-get install -y \ # Ruby dependencies # Install rvm -RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 +# Install rvm +RUN apt-get update && apt-get install -y gnupg2 +RUN gpg2 --keyserver hkp://pool.sks-keyservers.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB RUN \curl -sSL https://get.rvm.io | bash -s stable # Install Ruby 2.1 @@ -58,13 +61,15 @@ RUN /bin/bash -l -c "rvm use --default ruby-2.1" RUN /bin/bash -l -c "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc" RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.1' >> ~/.bashrc" -RUN /bin/bash -l -c "gem install bundler --no-ri --no-rdoc" +RUN /bin/bash -l -c "gem install bundler -v 1.17.3 --no-ri --no-rdoc" ################## # C# dependencies (needed to build grpc_csharp_ext) # Use cmake 3.6 from jessie-backports -RUN echo "deb http://ftp.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list +RUN echo "deb http://archive.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list +RUN echo 'Acquire::Check-Valid-Until "false";' > /etc/apt/apt.conf +RUN sed -i '/deb http:\/\/deb.debian.org\/debian jessie-updates main/d' /etc/apt/sources.list RUN apt-get update && apt-get install -t jessie-backports -y cmake && apt-get clean RUN mkdir /var/local/jenkins diff --git a/tools/dockerfile/grpc_clang_format/Dockerfile b/tools/dockerfile/grpc_clang_format/Dockerfile index ecdc52ee316..876992fd99d 100644 --- a/tools/dockerfile/grpc_clang_format/Dockerfile +++ b/tools/dockerfile/grpc_clang_format/Dockerfile @@ -14,6 +14,7 @@ FROM debian:jessie + RUN apt-get update && apt-get -y install wget xz-utils RUN wget http://releases.llvm.org/5.0.0/clang+llvm-5.0.0-linux-x86_64-ubuntu14.04.tar.xz RUN tar xf clang+llvm-5.0.0-linux-x86_64-ubuntu14.04.tar.xz 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 0c8ecc21a0c..ab37c0ae9bd 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 @@ -29,7 +29,7 @@ for dir in $DIRS 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 '*.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 -and -not -name grpc_shadow_boringssl.h`" + files="$files `find ${CLANG_FORMAT_ROOT}/$dir -name $glob -and -not -name '*.generated.*' -and -not -name '*.upb.h' -and -not -name '*.upb.c' -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 -and -not -name grpc_shadow_boringssl.h`" done done diff --git a/tools/dockerfile/grpc_clang_tidy/Dockerfile b/tools/dockerfile/grpc_clang_tidy/Dockerfile index dec7680fcf7..a5abca0c6e3 100644 --- a/tools/dockerfile/grpc_clang_tidy/Dockerfile +++ b/tools/dockerfile/grpc_clang_tidy/Dockerfile @@ -14,6 +14,7 @@ FROM debian:jessie + RUN apt-get update && apt-get -y install wget xz-utils RUN wget http://releases.llvm.org/5.0.0/clang+llvm-5.0.0-linux-x86_64-ubuntu14.04.tar.xz RUN tar xf clang+llvm-5.0.0-linux-x86_64-ubuntu14.04.tar.xz diff --git a/tools/dockerfile/interoptest/grpc_interop_aspnetcore/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_aspnetcore/Dockerfile new file mode 100644 index 00000000000..9ad6c1f28ea --- /dev/null +++ b/tools/dockerfile/interoptest/grpc_interop_aspnetcore/Dockerfile @@ -0,0 +1,21 @@ +# Copyright 2019 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. +# 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 mcr.microsoft.com/dotnet/core/sdk:3.0.100-preview3-stretch + +# needed by get-dotnet.sh script +RUN apt-get update && apt-get install -y jq && apt-get clean + +# Define the default command. +CMD ["bash"] diff --git a/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh new file mode 100644 index 00000000000..65e848ded32 --- /dev/null +++ b/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh @@ -0,0 +1,42 @@ +#!/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 Grpc.AspNetCore.Server interop server in a base image. +set -e + +mkdir -p /var/local/git +git clone /var/local/jenkins/grpc-dotnet /var/local/git/grpc-dotnet + +# copy service account keys if available +cp -r /var/local/jenkins/service_account $HOME || true + +cd /var/local/git/grpc-dotnet + +# If needed, update dotnet SDK and put it on path +./build/get-dotnet.sh +# Normally we would source ./activate.sh +# to add dotnet to PATH, but that would only +# work for the build and not for a subsequent +# dotnet run from a different shell, +# so we create a symlink instead. +# TODO(jtattermusch): Come up with a cleaner solution. +if [ -f $(pwd)/.dotnet/dotnet ] +then + ln -s $(pwd)/.dotnet/dotnet /usr/local/bin/dotnet +fi + +./build/get-grpc.sh + +dotnet build --configuration Debug Grpc.AspNetCore.sln diff --git a/tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile index b2216c79d4c..b49fa104105 100644 --- a/tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile +++ b/tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM debian:jessie +FROM debian:stretch # Install Git and basic packages. RUN apt-get update && apt-get install -y \ @@ -67,37 +67,36 @@ RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 t #================ # C# dependencies -# Update to a newer version of mono -RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF -RUN echo "deb http://download.mono-project.com/repo/debian jessie main" | tee /etc/apt/sources.list.d/mono-official.list -RUN echo "deb http://download.mono-project.com/repo/debian wheezy-apache24-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list -RUN echo "deb http://download.mono-project.com/repo/debian wheezy-libjpeg62-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list +# cmake >=3.6 needed to build grpc_csharp_ext +RUN apt-get update && apt-get install -y cmake && apt-get clean -# Install dependencies -RUN apt-get update && apt-get -y dist-upgrade && apt-get install -y \ +# Install mono +RUN apt-get update && apt-get install -y apt-transport-https dirmngr && apt-get clean +RUN apt-key adv --no-tty --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF +RUN echo "deb https://download.mono-project.com/repo/debian stable-stretch main" | tee /etc/apt/sources.list.d/mono-official-stable.list +RUN apt-get update && apt-get install -y \ mono-devel \ ca-certificates-mono \ nuget \ && apt-get clean -RUN nuget update -self +# Install dotnet SDK +ENV DOTNET_SDK_VERSION 2.1.500 +RUN curl -sSL -o dotnet.tar.gz https://dotnetcli.blob.core.windows.net/dotnet/Sdk/$DOTNET_SDK_VERSION/dotnet-sdk-$DOTNET_SDK_VERSION-linux-x64.tar.gz \ + && mkdir -p /usr/share/dotnet \ + && tar -zxf dotnet.tar.gz -C /usr/share/dotnet \ + && rm dotnet.tar.gz \ + && ln -s /usr/share/dotnet/dotnet /usr/bin/dotnet -#================= -# Use cmake 3.6 from jessie-backports -# needed to build grpc_csharp_ext with cmake -RUN echo "deb http://ftp.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list -RUN apt-get update && apt-get install -t jessie-backports -y cmake && apt-get clean +# Install .NET Core 1.1.10 runtime (required to run netcoreapp1.1) +RUN curl -sSL -o dotnet_old.tar.gz https://dotnetcli.blob.core.windows.net/dotnet/Runtime/1.1.10/dotnet-debian.9-x64.1.1.10.tar.gz \ + && mkdir -p dotnet_old \ + && tar zxf dotnet_old.tar.gz -C dotnet_old \ + && cp -r dotnet_old/shared/Microsoft.NETCore.App/1.1.10/ /usr/share/dotnet/shared/Microsoft.NETCore.App/ \ + && rm -rf dotnet_old/ dotnet_old.tar.gz +RUN apt-get update && apt-get install -y libunwind8 && apt-get clean -# Install dotnet SDK based on https://www.microsoft.com/net/core#debian -RUN apt-get update && apt-get install -y curl libunwind8 gettext -# dotnet-dev-1.0.0-preview2-003131 -RUN curl -sSL -o dotnet100.tar.gz https://go.microsoft.com/fwlink/?LinkID=827530 -RUN mkdir -p /opt/dotnet && tar zxf dotnet100.tar.gz -C /opt/dotnet -# dotnet-dev-1.0.1 -RUN curl -sSL -o dotnet101.tar.gz https://go.microsoft.com/fwlink/?LinkID=843453 -RUN mkdir -p /opt/dotnet && tar zxf dotnet101.tar.gz -C /opt/dotnet -RUN ln -s /opt/dotnet/dotnet /usr/local/bin # Trigger the population of the local package cache ENV NUGET_XMLDOC_MODE skip diff --git a/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile index b2216c79d4c..b49fa104105 100644 --- a/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile +++ b/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM debian:jessie +FROM debian:stretch # Install Git and basic packages. RUN apt-get update && apt-get install -y \ @@ -67,37 +67,36 @@ RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 t #================ # C# dependencies -# Update to a newer version of mono -RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF -RUN echo "deb http://download.mono-project.com/repo/debian jessie main" | tee /etc/apt/sources.list.d/mono-official.list -RUN echo "deb http://download.mono-project.com/repo/debian wheezy-apache24-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list -RUN echo "deb http://download.mono-project.com/repo/debian wheezy-libjpeg62-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list +# cmake >=3.6 needed to build grpc_csharp_ext +RUN apt-get update && apt-get install -y cmake && apt-get clean -# Install dependencies -RUN apt-get update && apt-get -y dist-upgrade && apt-get install -y \ +# Install mono +RUN apt-get update && apt-get install -y apt-transport-https dirmngr && apt-get clean +RUN apt-key adv --no-tty --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF +RUN echo "deb https://download.mono-project.com/repo/debian stable-stretch main" | tee /etc/apt/sources.list.d/mono-official-stable.list +RUN apt-get update && apt-get install -y \ mono-devel \ ca-certificates-mono \ nuget \ && apt-get clean -RUN nuget update -self +# Install dotnet SDK +ENV DOTNET_SDK_VERSION 2.1.500 +RUN curl -sSL -o dotnet.tar.gz https://dotnetcli.blob.core.windows.net/dotnet/Sdk/$DOTNET_SDK_VERSION/dotnet-sdk-$DOTNET_SDK_VERSION-linux-x64.tar.gz \ + && mkdir -p /usr/share/dotnet \ + && tar -zxf dotnet.tar.gz -C /usr/share/dotnet \ + && rm dotnet.tar.gz \ + && ln -s /usr/share/dotnet/dotnet /usr/bin/dotnet -#================= -# Use cmake 3.6 from jessie-backports -# needed to build grpc_csharp_ext with cmake -RUN echo "deb http://ftp.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list -RUN apt-get update && apt-get install -t jessie-backports -y cmake && apt-get clean +# Install .NET Core 1.1.10 runtime (required to run netcoreapp1.1) +RUN curl -sSL -o dotnet_old.tar.gz https://dotnetcli.blob.core.windows.net/dotnet/Runtime/1.1.10/dotnet-debian.9-x64.1.1.10.tar.gz \ + && mkdir -p dotnet_old \ + && tar zxf dotnet_old.tar.gz -C dotnet_old \ + && cp -r dotnet_old/shared/Microsoft.NETCore.App/1.1.10/ /usr/share/dotnet/shared/Microsoft.NETCore.App/ \ + && rm -rf dotnet_old/ dotnet_old.tar.gz +RUN apt-get update && apt-get install -y libunwind8 && apt-get clean -# Install dotnet SDK based on https://www.microsoft.com/net/core#debian -RUN apt-get update && apt-get install -y curl libunwind8 gettext -# dotnet-dev-1.0.0-preview2-003131 -RUN curl -sSL -o dotnet100.tar.gz https://go.microsoft.com/fwlink/?LinkID=827530 -RUN mkdir -p /opt/dotnet && tar zxf dotnet100.tar.gz -C /opt/dotnet -# dotnet-dev-1.0.1 -RUN curl -sSL -o dotnet101.tar.gz https://go.microsoft.com/fwlink/?LinkID=843453 -RUN mkdir -p /opt/dotnet && tar zxf dotnet101.tar.gz -C /opt/dotnet -RUN ln -s /opt/dotnet/dotnet /usr/local/bin # Trigger the population of the local package cache ENV NUGET_XMLDOC_MODE skip diff --git a/tools/dockerfile/interoptest/grpc_interop_cxx/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_cxx/Dockerfile index 9ede89b78d4..e9f2a853344 100644 --- a/tools/dockerfile/interoptest/grpc_interop_cxx/Dockerfile +++ b/tools/dockerfile/interoptest/grpc_interop_cxx/Dockerfile @@ -14,6 +14,7 @@ FROM debian:jessie + # Install Git and basic packages. RUN apt-get update && apt-get install -y \ autoconf \ diff --git a/tools/dockerfile/interoptest/grpc_interop_go1.11/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_go1.11/Dockerfile new file mode 100644 index 00000000000..0892bc34599 --- /dev/null +++ b/tools/dockerfile/interoptest/grpc_interop_go1.11/Dockerfile @@ -0,0 +1,36 @@ +# Copyright 2018 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. +# 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 golang:1.11 + +# Using login shell removes Go from path, so we add it. +RUN ln -s /usr/local/go/bin/go /usr/local/bin + +#==================== +# Python dependencies + +# Install dependencies + +RUN apt-get update && apt-get install -y \ + python-all-dev \ + python3-all-dev \ + python-pip + +# Install Python packages from PyPI +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.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.11/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_go1.11/build_interop.sh new file mode 100644 index 00000000000..b11ace3a4e7 --- /dev/null +++ b/tools/dockerfile/interoptest/grpc_interop_go1.11/build_interop.sh @@ -0,0 +1,33 @@ +#!/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. +# +# Builds Go interop server and client in a base image. +set -e + +# Clone just the grpc-go source code without any dependencies. +# We are cloning from a local git repo that contains the right revision +# to test instead of using "go get" to download from Github directly. +git clone --recursive /var/local/jenkins/grpc-go src/google.golang.org/grpc + +# Get all gRPC Go dependencies +(cd src/google.golang.org/grpc && make deps && make testdeps) + +# copy service account keys if available +cp -r /var/local/jenkins/service_account $HOME || true + +# Build the interop client and server +(cd src/google.golang.org/grpc/interop/client && go install) +(cd src/google.golang.org/grpc/interop/server && go install) + diff --git a/tools/dockerfile/interoptest/grpc_interop_java/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_java/Dockerfile index fc29ada0d2d..979c14db3f6 100644 --- a/tools/dockerfile/interoptest/grpc_interop_java/Dockerfile +++ b/tools/dockerfile/interoptest/grpc_interop_java/Dockerfile @@ -14,45 +14,21 @@ FROM debian:jessie -# Install JDK 8 and Git + +# Install JDK 8 # 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/ + apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys EEA14886 && \ + apt-get update && apt-get -y install 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 -#==================== -# Python dependencies - -# Install dependencies - -RUN apt-get update && apt-get install -y \ - python-all-dev \ - python3-all-dev \ - python-pip - -# Install Python packages from PyPI -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.2.post1 six==1.10.0 twisted==17.5.0 - - -# Trigger download of as many Gradle artifacts as possible. -RUN git clone --recursive --depth 1 https://github.com/grpc/grpc-java.git && \ - cd grpc-java && \ - ./gradlew :grpc-interop-testing:installDist -PskipCodegen=true && \ - rm -r "$(pwd)" # Define the default command. CMD ["bash"] + diff --git a/tools/dockerfile/interoptest/grpc_interop_java/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_java/build_interop.sh index 0e36c193c91..8e1154679d7 100644 --- a/tools/dockerfile/interoptest/grpc_interop_java/build_interop.sh +++ b/tools/dockerfile/interoptest/grpc_interop_java/build_interop.sh @@ -16,16 +16,24 @@ # Builds Java interop server and client in a base image. set -e -mkdir -p /var/local/git -git clone --recursive --depth 1 /var/local/jenkins/grpc-java /var/local/git/grpc-java +cp -r /var/local/jenkins/grpc-java /tmp/grpc-java # copy service account keys if available cp -r /var/local/jenkins/service_account $HOME || true -cd /var/local/git/grpc-java - +pushd /tmp/grpc-java ./gradlew :grpc-interop-testing:installDist -PskipCodegen=true +mkdir -p /var/local/git/grpc-java/ +cp -r --parents -t /var/local/git/grpc-java/ \ + interop-testing/build/install/ \ + run-test-client.sh \ + run-test-server.sh + +popd +rm -r /tmp/grpc-java +rm -r "$HOME/.gradle" + # enable extra java logging mkdir -p /var/local/grpc_java_logging echo "handlers = java.util.logging.ConsoleHandler diff --git a/tools/dockerfile/interoptest/grpc_interop_java_oracle8/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_java_oracle8/Dockerfile index fc29ada0d2d..979c14db3f6 100644 --- a/tools/dockerfile/interoptest/grpc_interop_java_oracle8/Dockerfile +++ b/tools/dockerfile/interoptest/grpc_interop_java_oracle8/Dockerfile @@ -14,45 +14,21 @@ FROM debian:jessie -# Install JDK 8 and Git + +# Install JDK 8 # 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/ + apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys EEA14886 && \ + apt-get update && apt-get -y install 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 -#==================== -# Python dependencies - -# Install dependencies - -RUN apt-get update && apt-get install -y \ - python-all-dev \ - python3-all-dev \ - python-pip - -# Install Python packages from PyPI -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.2.post1 six==1.10.0 twisted==17.5.0 - - -# Trigger download of as many Gradle artifacts as possible. -RUN git clone --recursive --depth 1 https://github.com/grpc/grpc-java.git && \ - cd grpc-java && \ - ./gradlew :grpc-interop-testing:installDist -PskipCodegen=true && \ - rm -r "$(pwd)" # Define the default command. CMD ["bash"] + diff --git a/tools/dockerfile/interoptest/grpc_interop_java_oracle8/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_java_oracle8/build_interop.sh index 4c5ba4b7a3a..77d322882f7 100644 --- a/tools/dockerfile/interoptest/grpc_interop_java_oracle8/build_interop.sh +++ b/tools/dockerfile/interoptest/grpc_interop_java_oracle8/build_interop.sh @@ -16,16 +16,24 @@ # Builds Java interop server and client in a base image. set -e -mkdir -p /var/local/git -git clone --recursive --depth 1 /var/local/jenkins/grpc-java /var/local/git/grpc-java +cp -r /var/local/jenkins/grpc-java /tmp/grpc-java # copy service account keys if available cp -r /var/local/jenkins/service_account $HOME || true -cd /var/local/git/grpc-java - +pushd /tmp/grpc-java ./gradlew :grpc-interop-testing:installDist -PskipCodegen=true +mkdir -p /var/local/git/grpc-java/ +cp -r --parents -t /var/local/git/grpc-java/ \ + interop-testing/build/install/ \ + run-test-client.sh \ + run-test-server.sh + +popd +rm -r /tmp/grpc-java +rm -r "$HOME/.gradle" + # enable extra java logging mkdir -p /var/local/grpc_java_logging echo "handlers = java.util.logging.ConsoleHandler diff --git a/tools/dockerfile/interoptest/grpc_interop_node/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_node/Dockerfile index 015641684b0..283a99d0c5f 100644 --- a/tools/dockerfile/interoptest/grpc_interop_node/Dockerfile +++ b/tools/dockerfile/interoptest/grpc_interop_node/Dockerfile @@ -14,6 +14,7 @@ FROM debian:jessie + # Install Git and basic packages. RUN apt-get update && apt-get install -y \ autoconf \ diff --git a/tools/dockerfile/interoptest/grpc_interop_node/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_node/build_interop.sh index c16efc1d354..aeb82e0c9c3 100755 --- a/tools/dockerfile/interoptest/grpc_interop_node/build_interop.sh +++ b/tools/dockerfile/interoptest/grpc_interop_node/build_interop.sh @@ -29,6 +29,4 @@ cp -r /var/local/jenkins/service_account $HOME || true cd /var/local/git/grpc-node # build Node interop client & server -npm install -g node-gyp gulp -npm install -gulp setup +./setup_interop.sh diff --git a/tools/dockerfile/interoptest/grpc_interop_nodepurejs/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_nodepurejs/Dockerfile index 0006be790ee..fd089f1bc4d 100644 --- a/tools/dockerfile/interoptest/grpc_interop_nodepurejs/Dockerfile +++ b/tools/dockerfile/interoptest/grpc_interop_nodepurejs/Dockerfile @@ -14,6 +14,7 @@ FROM debian:jessie + # Install Git and basic packages. RUN apt-get update && apt-get install -y \ autoconf \ diff --git a/tools/dockerfile/interoptest/grpc_interop_nodepurejs/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_nodepurejs/build_interop.sh index d41ccacd2f9..db55f5a19f3 100755 --- a/tools/dockerfile/interoptest/grpc_interop_nodepurejs/build_interop.sh +++ b/tools/dockerfile/interoptest/grpc_interop_nodepurejs/build_interop.sh @@ -29,8 +29,4 @@ cp -r /var/local/jenkins/service_account $HOME || true cd /var/local/git/grpc-node # build Node interop client & server -npm install -g gulp -npm install -gulp js.core.install -gulp protobuf.install -gulp internal.test.install +./setup_interop_purejs.sh diff --git a/tools/dockerfile/interoptest/grpc_interop_php/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_php/Dockerfile index e987d4c88eb..04f0ac2a659 100644 --- a/tools/dockerfile/interoptest/grpc_interop_php/Dockerfile +++ b/tools/dockerfile/interoptest/grpc_interop_php/Dockerfile @@ -14,6 +14,7 @@ FROM debian:jessie + # Install Git and basic packages. RUN apt-get update && apt-get install -y \ autoconf \ diff --git a/tools/dockerfile/interoptest/grpc_interop_php7/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_php7/Dockerfile index 71a2381b776..01de0eb39e9 100644 --- a/tools/dockerfile/interoptest/grpc_interop_php7/Dockerfile +++ b/tools/dockerfile/interoptest/grpc_interop_php7/Dockerfile @@ -14,6 +14,7 @@ FROM debian:jessie + #================= # PHP7 dependencies diff --git a/tools/dockerfile/interoptest/grpc_interop_python/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_python/Dockerfile index dadd8567407..acad500f90c 100644 --- a/tools/dockerfile/interoptest/grpc_interop_python/Dockerfile +++ b/tools/dockerfile/interoptest/grpc_interop_python/Dockerfile @@ -12,8 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM debian:jessie - +FROM debian:stretch + # Install Git and basic packages. RUN apt-get update && apt-get install -y \ autoconf \ @@ -49,27 +49,24 @@ RUN apt-get update && apt-get install -y \ # Build profiling RUN apt-get update && apt-get install -y time && apt-get clean -#==================== -# Python dependencies +# Google Cloud platform API libraries +RUN apt-get update && apt-get install -y python-pip && apt-get clean +RUN pip install --upgrade google-api-python-client oauth2client -# Install dependencies +# Install Python 2.7 +RUN apt-get update && apt-get install -y python2.7 python-all-dev +RUN curl https://bootstrap.pypa.io/get-pip.py | python2.7 -RUN apt-get update && apt-get install -y \ - python-all-dev \ - python3-all-dev \ - python-pip - -# Install Python packages from PyPI -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.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 +# Add Debian 'testing' repository +RUN echo 'deb http://ftp.de.debian.org/debian testing main' >> /etc/apt/sources.list +RUN echo 'APT::Default-Release "stable";' | tee -a /etc/apt/apt.conf.d/00local RUN mkdir /var/local/jenkins # Define the default command. CMD ["bash"] + + +RUN apt-get update && apt-get -t testing install -y python3.7 python3-all-dev +RUN curl https://bootstrap.pypa.io/get-pip.py | python3.7 diff --git a/tools/dockerfile/interoptest/grpc_interop_python/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_python/build_interop.sh index 7917e1cd60d..468aa20e3fd 100755 --- a/tools/dockerfile/interoptest/grpc_interop_python/build_interop.sh +++ b/tools/dockerfile/interoptest/grpc_interop_python/build_interop.sh @@ -28,5 +28,5 @@ cp -r /var/local/jenkins/service_account $HOME || true cd /var/local/git/grpc -# interop tests only run using python2.7 currently (and python build is slow) -tools/run_tests/run_tests.py -l python --compiler python2.7 -c opt --build_only +# interop tests only run using python3.7 currently (and python build is slow) +tools/run_tests/run_tests.py -l python --compiler python3.7 -c opt --build_only diff --git a/tools/dockerfile/interoptest/grpc_interop_ruby/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_ruby/Dockerfile index 97c146bb53a..8e605a8c341 100644 --- a/tools/dockerfile/interoptest/grpc_interop_ruby/Dockerfile +++ b/tools/dockerfile/interoptest/grpc_interop_ruby/Dockerfile @@ -14,6 +14,7 @@ FROM debian:jessie + # Install Git and basic packages. RUN apt-get update && apt-get install -y \ autoconf \ @@ -68,16 +69,17 @@ RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 t # Ruby dependencies # Install rvm -RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 +RUN apt-get update && apt-get install -y gnupg2 +RUN gpg2 --keyserver hkp://pool.sks-keyservers.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB RUN \curl -sSL https://get.rvm.io | bash -s stable -# Install Ruby 2.1 -RUN /bin/bash -l -c "rvm install ruby-2.1" -RUN /bin/bash -l -c "rvm use --default ruby-2.1" -RUN /bin/bash -l -c "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc" +# Install Ruby 2.5 +RUN /bin/bash -l -c "rvm install ruby-2.5" +RUN /bin/bash -l -c "rvm use --default ruby-2.5" +RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" -RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.1' >> ~/.bashrc" -RUN /bin/bash -l -c "gem install bundler --no-ri --no-rdoc" +RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.5' >> ~/.bashrc" +RUN /bin/bash -l -c "gem install bundler --no-document -v 1.9" RUN mkdir /var/local/jenkins diff --git a/tools/dockerfile/interoptest/grpc_interop_ruby/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_ruby/build_interop.sh index b6b122ef0fd..e71ad91499a 100755 --- a/tools/dockerfile/interoptest/grpc_interop_ruby/build_interop.sh +++ b/tools/dockerfile/interoptest/grpc_interop_ruby/build_interop.sh @@ -27,7 +27,7 @@ ${name}') cp -r /var/local/jenkins/service_account $HOME || true cd /var/local/git/grpc -rvm --default use ruby-2.1 +rvm --default use ruby-2.5 # build Ruby interop client and server -(cd src/ruby && gem update bundler && bundle && rake compile) +(cd src/ruby && gem install bundler -v 1.17.3 && bundle && rake compile) diff --git a/tools/dockerfile/test/bazel/Dockerfile b/tools/dockerfile/test/bazel/Dockerfile index 0aa6209f4fd..2536fe299cb 100644 --- a/tools/dockerfile/test/bazel/Dockerfile +++ b/tools/dockerfile/test/bazel/Dockerfile @@ -14,6 +14,12 @@ FROM gcr.io/oss-fuzz-base/base-builder +# -------------------------- WARNING -------------------------------------- +# If you are making changes to this file, consider changing +# https://github.com/google/oss-fuzz/blob/master/projects/grpc/Dockerfile +# accordingly. +# ------------------------------------------------------------------------- + # Install basic packages and Bazel dependencies. RUN apt-get update && apt-get install -y software-properties-common python-software-properties RUN add-apt-repository ppa:webupd8team/java @@ -46,8 +52,9 @@ RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 t # Bazel installation RUN apt-get update && apt-get install -y wget && apt-get clean -RUN wget -q https://github.com/bazelbuild/bazel/releases/download/0.17.1/bazel-0.17.1-linux-x86_64 -O /usr/local/bin/bazel -RUN chmod 755 /usr/local/bin/bazel +RUN wget https://github.com/bazelbuild/bazel/releases/download/0.23.2/bazel-0.23.2-installer-linux-x86_64.sh && \ + bash ./bazel-0.23.2-installer-linux-x86_64.sh && \ + rm bazel-0.23.2-installer-linux-x86_64.sh RUN mkdir -p /var/local/jenkins diff --git a/tools/dockerfile/test/csharp_jessie_x64/Dockerfile b/tools/dockerfile/test/csharp_stretch_x64/Dockerfile similarity index 56% rename from tools/dockerfile/test/csharp_jessie_x64/Dockerfile rename to tools/dockerfile/test/csharp_stretch_x64/Dockerfile index 030d301a40c..04d25842094 100644 --- a/tools/dockerfile/test/csharp_jessie_x64/Dockerfile +++ b/tools/dockerfile/test/csharp_stretch_x64/Dockerfile @@ -1,4 +1,4 @@ -# Copyright 2015 gRPC authors. +# Copyright 2018 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,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM debian:jessie +FROM debian:stretch # Install Git and basic packages. RUN apt-get update && apt-get install -y \ @@ -71,37 +71,36 @@ RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 t #================ # C# dependencies -# Update to a newer version of mono -RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF -RUN echo "deb http://download.mono-project.com/repo/debian jessie main" | tee /etc/apt/sources.list.d/mono-official.list -RUN echo "deb http://download.mono-project.com/repo/debian wheezy-apache24-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list -RUN echo "deb http://download.mono-project.com/repo/debian wheezy-libjpeg62-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list +# cmake >=3.6 needed to build grpc_csharp_ext +RUN apt-get update && apt-get install -y cmake && apt-get clean -# Install dependencies -RUN apt-get update && apt-get -y dist-upgrade && apt-get install -y \ +# Install mono +RUN apt-get update && apt-get install -y apt-transport-https dirmngr && apt-get clean +RUN apt-key adv --no-tty --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF +RUN echo "deb https://download.mono-project.com/repo/debian stable-stretch main" | tee /etc/apt/sources.list.d/mono-official-stable.list +RUN apt-get update && apt-get install -y \ mono-devel \ ca-certificates-mono \ nuget \ && apt-get clean -RUN nuget update -self +# Install dotnet SDK +ENV DOTNET_SDK_VERSION 2.1.500 +RUN curl -sSL -o dotnet.tar.gz https://dotnetcli.blob.core.windows.net/dotnet/Sdk/$DOTNET_SDK_VERSION/dotnet-sdk-$DOTNET_SDK_VERSION-linux-x64.tar.gz \ + && mkdir -p /usr/share/dotnet \ + && tar -zxf dotnet.tar.gz -C /usr/share/dotnet \ + && rm dotnet.tar.gz \ + && ln -s /usr/share/dotnet/dotnet /usr/bin/dotnet -#================= -# Use cmake 3.6 from jessie-backports -# needed to build grpc_csharp_ext with cmake -RUN echo "deb http://ftp.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list -RUN apt-get update && apt-get install -t jessie-backports -y cmake && apt-get clean +# Install .NET Core 1.1.10 runtime (required to run netcoreapp1.1) +RUN curl -sSL -o dotnet_old.tar.gz https://dotnetcli.blob.core.windows.net/dotnet/Runtime/1.1.10/dotnet-debian.9-x64.1.1.10.tar.gz \ + && mkdir -p dotnet_old \ + && tar zxf dotnet_old.tar.gz -C dotnet_old \ + && cp -r dotnet_old/shared/Microsoft.NETCore.App/1.1.10/ /usr/share/dotnet/shared/Microsoft.NETCore.App/ \ + && rm -rf dotnet_old/ dotnet_old.tar.gz +RUN apt-get update && apt-get install -y libunwind8 && apt-get clean -# Install dotnet SDK based on https://www.microsoft.com/net/core#debian -RUN apt-get update && apt-get install -y curl libunwind8 gettext -# dotnet-dev-1.0.0-preview2-003131 -RUN curl -sSL -o dotnet100.tar.gz https://go.microsoft.com/fwlink/?LinkID=827530 -RUN mkdir -p /opt/dotnet && tar zxf dotnet100.tar.gz -C /opt/dotnet -# dotnet-dev-1.0.1 -RUN curl -sSL -o dotnet101.tar.gz https://go.microsoft.com/fwlink/?LinkID=843453 -RUN mkdir -p /opt/dotnet && tar zxf dotnet101.tar.gz -C /opt/dotnet -RUN ln -s /opt/dotnet/dotnet /usr/local/bin # Trigger the population of the local package cache ENV NUGET_XMLDOC_MODE skip diff --git a/tools/dockerfile/test/cxx_jessie_x64/Dockerfile b/tools/dockerfile/test/cxx_jessie_x64/Dockerfile index f9dc8f20d7c..b79faa09c05 100644 --- a/tools/dockerfile/test/cxx_jessie_x64/Dockerfile +++ b/tools/dockerfile/test/cxx_jessie_x64/Dockerfile @@ -14,6 +14,7 @@ FROM debian:jessie + # Install Git and basic packages. RUN apt-get update && apt-get install -y \ autoconf \ @@ -76,7 +77,9 @@ RUN apt-get update && apt-get -y install libgflags-dev libgtest-dev libc++-dev c # Use cmake 3.6 from jessie-backports # should only be used for images based on debian jessie. -RUN echo "deb http://ftp.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list +RUN echo "deb http://archive.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list +RUN echo 'Acquire::Check-Valid-Until "false";' > /etc/apt/apt.conf +RUN sed -i '/deb http:\/\/deb.debian.org\/debian jessie-updates main/d' /etc/apt/sources.list RUN apt-get update && apt-get install -t jessie-backports -y cmake && apt-get clean diff --git a/tools/dockerfile/test/cxx_jessie_x86/Dockerfile b/tools/dockerfile/test/cxx_jessie_x86/Dockerfile index 76015c8c42d..59b86d7247c 100644 --- a/tools/dockerfile/test/cxx_jessie_x86/Dockerfile +++ b/tools/dockerfile/test/cxx_jessie_x86/Dockerfile @@ -13,6 +13,7 @@ # limitations under the License. FROM 32bit/debian:jessie +RUN sed -i '/deb http:\/\/http.debian.net\/debian jessie-updates main/d' /etc/apt/sources.list # Install Git and basic packages. RUN apt-get update && apt-get install -y \ @@ -79,7 +80,9 @@ RUN mkdir /var/local/jenkins # Use cmake 3.6 from jessie-backports # should only be used for images based on debian jessie. -RUN echo "deb http://ftp.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list +RUN echo "deb http://archive.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list +RUN echo 'Acquire::Check-Valid-Until "false";' > /etc/apt/apt.conf +RUN sed -i '/deb http:\/\/deb.debian.org\/debian jessie-updates main/d' /etc/apt/sources.list RUN apt-get update && apt-get install -t jessie-backports -y cmake && apt-get clean diff --git a/tools/dockerfile/test/cxx_sanitizers_jessie_x64/Dockerfile b/tools/dockerfile/test/cxx_sanitizers_jessie_x64/Dockerfile index 77aac3cdec7..8bf122cd5b2 100644 --- a/tools/dockerfile/test/cxx_sanitizers_jessie_x64/Dockerfile +++ b/tools/dockerfile/test/cxx_sanitizers_jessie_x64/Dockerfile @@ -14,6 +14,7 @@ # This is the base Docker image we use for running tests on RBE FROM gcr.io/cloud-marketplace/google/rbe-debian8@sha256:1ede2a929b44d629ec5abe86eee6d7ffea1d5a4d247489a8867d46cfde3e38bd +RUN sed -i '/deb http:\/\/httpredir.debian.org\/debian jessie-updates main/d' /etc/apt/sources.list # Install Git and basic packages. RUN apt-get update && apt-get install -y \ diff --git a/tools/dockerfile/test/fuzzer/Dockerfile b/tools/dockerfile/test/fuzzer/Dockerfile index 7f871f2f62a..f9dd948a1b3 100644 --- a/tools/dockerfile/test/fuzzer/Dockerfile +++ b/tools/dockerfile/test/fuzzer/Dockerfile @@ -14,6 +14,7 @@ FROM debian:jessie + # Install Git and basic packages. RUN apt-get update && apt-get install -y \ autoconf \ @@ -76,7 +77,9 @@ RUN apt-get update && apt-get -y install libgflags-dev libgtest-dev libc++-dev c # Use cmake 3.6 from jessie-backports # should only be used for images based on debian jessie. -RUN echo "deb http://ftp.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list +RUN echo "deb http://archive.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list +RUN echo 'Acquire::Check-Valid-Until "false";' > /etc/apt/apt.conf +RUN sed -i '/deb http:\/\/deb.debian.org\/debian jessie-updates main/d' /etc/apt/sources.list RUN apt-get update && apt-get install -t jessie-backports -y cmake && apt-get clean #================= diff --git a/tools/dockerfile/test/multilang_jessie_x64/Dockerfile b/tools/dockerfile/test/multilang_jessie_x64/Dockerfile deleted file mode 100644 index 3c95554b029..00000000000 --- a/tools/dockerfile/test/multilang_jessie_x64/Dockerfile +++ /dev/null @@ -1,170 +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. - -FROM debian:jessie - -# Install Git and basic packages. -RUN apt-get update && apt-get install -y \ - autoconf \ - autotools-dev \ - build-essential \ - bzip2 \ - ccache \ - curl \ - dnsutils \ - gcc \ - gcc-multilib \ - git \ - golang \ - gyp \ - lcov \ - libc6 \ - libc6-dbg \ - libc6-dev \ - libgtest-dev \ - libtool \ - make \ - perl \ - strace \ - python-dev \ - python-setuptools \ - python-yaml \ - telnet \ - unzip \ - wget \ - zip && apt-get clean - -#================ -# Build profiling -RUN apt-get update && apt-get install -y time && apt-get clean - -# Google Cloud platform API libraries -RUN apt-get update && apt-get install -y python-pip && apt-get clean -RUN pip install --upgrade google-api-python-client oauth2client - -#================ -# C# dependencies - -# Update to a newer version of mono -RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF -RUN echo "deb http://download.mono-project.com/repo/debian jessie main" | tee /etc/apt/sources.list.d/mono-official.list -RUN echo "deb http://download.mono-project.com/repo/debian wheezy-apache24-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list -RUN echo "deb http://download.mono-project.com/repo/debian wheezy-libjpeg62-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list - -# Install dependencies -RUN apt-get update && apt-get -y dist-upgrade && apt-get install -y \ - mono-devel \ - ca-certificates-mono \ - nuget \ - && apt-get clean - -RUN nuget update -self - -#================= -# Use cmake 3.6 from jessie-backports -# needed to build grpc_csharp_ext with cmake - -RUN echo "deb http://ftp.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list -RUN apt-get update && apt-get install -t jessie-backports -y cmake && apt-get clean - -# Install dotnet SDK based on https://www.microsoft.com/net/core#debian -RUN apt-get update && apt-get install -y curl libunwind8 gettext -# dotnet-dev-1.0.0-preview2-003131 -RUN curl -sSL -o dotnet100.tar.gz https://go.microsoft.com/fwlink/?LinkID=827530 -RUN mkdir -p /opt/dotnet && tar zxf dotnet100.tar.gz -C /opt/dotnet -# dotnet-dev-1.0.1 -RUN curl -sSL -o dotnet101.tar.gz https://go.microsoft.com/fwlink/?LinkID=843453 -RUN mkdir -p /opt/dotnet && tar zxf dotnet101.tar.gz -C /opt/dotnet -RUN ln -s /opt/dotnet/dotnet /usr/local/bin - -# Trigger the population of the local package cache -ENV NUGET_XMLDOC_MODE skip -RUN mkdir warmup \ - && cd warmup \ - && dotnet new \ - && cd .. \ - && rm -rf warmup - -#================= -# C++ dependencies -RUN apt-get update && apt-get -y install libgflags-dev libgtest-dev libc++-dev clang && apt-get clean - -#================== -# Node dependencies - -# Install nvm -RUN touch .profile -RUN curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.25.4/install.sh | bash -# Install all versions of node that we want to test -RUN /bin/bash -l -c "nvm install 4 && npm config set cache /tmp/npm-cache" -RUN /bin/bash -l -c "nvm install 5 && npm config set cache /tmp/npm-cache" -RUN /bin/bash -l -c "nvm install 6 && npm config set cache /tmp/npm-cache" -RUN /bin/bash -l -c "nvm install 8 && npm config set cache /tmp/npm-cache" -RUN /bin/bash -l -c "nvm install 9 && npm config set cache /tmp/npm-cache" -RUN /bin/bash -l -c "nvm install 10 && npm config set cache /tmp/npm-cache" -RUN /bin/bash -l -c "nvm alias default 10" -#================= -# PHP dependencies - -# Install dependencies - -RUN apt-get update && apt-get install -y \ - git php5 php5-dev phpunit unzip - -#================== -# Ruby dependencies - -# Install rvm -RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 -RUN \curl -sSL https://get.rvm.io | bash -s stable - -# Install Ruby 2.1 -RUN /bin/bash -l -c "rvm install ruby-2.1" -RUN /bin/bash -l -c "rvm use --default ruby-2.1" -RUN /bin/bash -l -c "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc" -RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" -RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.1' >> ~/.bashrc" -RUN /bin/bash -l -c "gem install bundler --no-ri --no-rdoc" - -#==================== -# Python dependencies - -# Install dependencies - -RUN apt-get update && apt-get install -y \ - python-all-dev \ - python3-all-dev \ - python-pip - -# Install Python packages from PyPI -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.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 -ENV PATH ~/.local/bin:$PATH - -# Install Mako to generate files in grpc/grpc-node -RUN pip install Mako - - -RUN mkdir /var/local/jenkins - -# Define the default command. -CMD ["bash"] diff --git a/tools/dockerfile/test/node_jessie_x64/Dockerfile b/tools/dockerfile/test/node_jessie_x64/Dockerfile index 7c36fb37345..7c0b86acc0c 100644 --- a/tools/dockerfile/test/node_jessie_x64/Dockerfile +++ b/tools/dockerfile/test/node_jessie_x64/Dockerfile @@ -14,6 +14,7 @@ FROM debian:jessie + # Install Git and basic packages. RUN apt-get update && apt-get install -y \ autoconf \ diff --git a/tools/dockerfile/test/php7_jessie_x64/Dockerfile b/tools/dockerfile/test/php7_jessie_x64/Dockerfile index 0dff8399047..5cca63d4f02 100644 --- a/tools/dockerfile/test/php7_jessie_x64/Dockerfile +++ b/tools/dockerfile/test/php7_jessie_x64/Dockerfile @@ -14,6 +14,7 @@ FROM debian:jessie + #================= # PHP7 dependencies @@ -79,6 +80,12 @@ 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.2.post1 six==1.10.0 twisted==17.5.0 +#================= +# PHP Test dependencies + + RUN apt-get update && apt-get install -y \ + valgrind + RUN mkdir /var/local/jenkins diff --git a/tools/dockerfile/test/php_jessie_x64/Dockerfile b/tools/dockerfile/test/php_jessie_x64/Dockerfile index ed59e569956..ee54263f96a 100644 --- a/tools/dockerfile/test/php_jessie_x64/Dockerfile +++ b/tools/dockerfile/test/php_jessie_x64/Dockerfile @@ -14,6 +14,7 @@ FROM debian:jessie + # Install Git and basic packages. RUN apt-get update && apt-get install -y \ autoconf \ diff --git a/tools/dockerfile/test/python_alpine_x64/Dockerfile b/tools/dockerfile/test/python_alpine_x64/Dockerfile index 6e06e2d52c3..3001bf43ff6 100644 --- a/tools/dockerfile/test/python_alpine_x64/Dockerfile +++ b/tools/dockerfile/test/python_alpine_x64/Dockerfile @@ -42,13 +42,7 @@ RUN pip install virtualenv RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.0.post1 six==1.10.0 # Google Cloud platform API libraries -RUN pip install --upgrade google-api-python-client - -# Prepare ccache -RUN ln -s /usr/bin/ccache /usr/local/bin/gcc -RUN ln -s /usr/bin/ccache /usr/local/bin/g++ -RUN ln -s /usr/bin/ccache /usr/local/bin/cc -RUN ln -s /usr/bin/ccache /usr/local/bin/c++ +RUN pip install --upgrade google-api-python-client oauth2client RUN mkdir -p /var/local/jenkins diff --git a/tools/dockerfile/test/python_jessie_x64/Dockerfile b/tools/dockerfile/test/python_jessie_x64/Dockerfile index a4c3a9f91e1..367785f42fd 100644 --- a/tools/dockerfile/test/python_jessie_x64/Dockerfile +++ b/tools/dockerfile/test/python_jessie_x64/Dockerfile @@ -14,6 +14,7 @@ FROM debian:jessie + # Install Git and basic packages. RUN apt-get update && apt-get install -y \ autoconf \ diff --git a/tools/dockerfile/test/python_stretch_3.7_x64/Dockerfile b/tools/dockerfile/test/python_stretch_3.7_x64/Dockerfile index add1cc509db..45291ffdcfc 100644 --- a/tools/dockerfile/test/python_stretch_3.7_x64/Dockerfile +++ b/tools/dockerfile/test/python_stretch_3.7_x64/Dockerfile @@ -70,3 +70,6 @@ CMD ["bash"] RUN apt-get update && apt-get -t testing install -y python3.7 python3-all-dev RUN curl https://bootstrap.pypa.io/get-pip.py | python3.7 + +# for Python test coverage reporting +RUN pip install coverage diff --git a/tools/dockerfile/test/ruby_jessie_x64/Dockerfile b/tools/dockerfile/test/ruby_jessie_x64/Dockerfile index 321b501de21..767040907b2 100644 --- a/tools/dockerfile/test/ruby_jessie_x64/Dockerfile +++ b/tools/dockerfile/test/ruby_jessie_x64/Dockerfile @@ -14,6 +14,7 @@ FROM debian:jessie + # Install Git and basic packages. RUN apt-get update && apt-get install -y \ autoconf \ @@ -72,16 +73,17 @@ RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 t # Ruby dependencies # Install rvm -RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 +RUN apt-get update && apt-get install -y gnupg2 +RUN gpg2 --keyserver hkp://pool.sks-keyservers.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB RUN \curl -sSL https://get.rvm.io | bash -s stable -# Install Ruby 2.1 -RUN /bin/bash -l -c "rvm install ruby-2.1" -RUN /bin/bash -l -c "rvm use --default ruby-2.1" -RUN /bin/bash -l -c "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc" +# Install Ruby 2.5 +RUN /bin/bash -l -c "rvm install ruby-2.5" +RUN /bin/bash -l -c "rvm use --default ruby-2.5" +RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" -RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.1' >> ~/.bashrc" -RUN /bin/bash -l -c "gem install bundler --no-ri --no-rdoc" +RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.5' >> ~/.bashrc" +RUN /bin/bash -l -c "gem install bundler --no-document -v 1.9" RUN mkdir /var/local/jenkins diff --git a/tools/dockerfile/test/sanity/Dockerfile b/tools/dockerfile/test/sanity/Dockerfile index e6bdb4ee035..765bd7267a4 100644 --- a/tools/dockerfile/test/sanity/Dockerfile +++ b/tools/dockerfile/test/sanity/Dockerfile @@ -12,8 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM debian:jessie - +FROM debian:stretch + # Install Git and basic packages. RUN apt-get update && apt-get install -y \ autoconf \ @@ -53,20 +53,19 @@ RUN apt-get update && apt-get install -y time && apt-get clean RUN apt-get update && apt-get install -y python-pip && apt-get clean RUN pip install --upgrade google-api-python-client oauth2client -#==================== -# Python dependencies +# Install Python 2.7 +RUN apt-get update && apt-get install -y python2.7 python-all-dev +RUN curl https://bootstrap.pypa.io/get-pip.py | python2.7 -# Install dependencies +# Add Debian 'testing' repository +RUN echo 'deb http://ftp.de.debian.org/debian testing main' >> /etc/apt/sources.list +RUN echo 'APT::Default-Release "stable";' | tee -a /etc/apt/apt.conf.d/00local -RUN apt-get update && apt-get install -y \ - python-all-dev \ - python3-all-dev \ - python-pip -# Install Python packages from PyPI -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.2.post1 six==1.10.0 twisted==17.5.0 +RUN mkdir /var/local/jenkins + +# Define the default command. +CMD ["bash"] #================= # C++ dependencies @@ -74,16 +73,18 @@ RUN apt-get update && apt-get -y install libgflags-dev libgtest-dev libc++-dev c #======================== # Sanity test dependencies +RUN apt-get update && apt-get -t testing install -y python3.7 python3-all-dev +RUN curl https://bootstrap.pypa.io/get-pip.py | python3.7 +# Make Python 3.7 the default Python 3 version +RUN update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.7 1 RUN apt-get update && apt-get install -y \ - python-pip \ autoconf \ automake \ libtool \ curl \ - python-virtualenv \ - python-lxml \ shellcheck -RUN pip install simplejson mako +RUN python2 -m pip install simplejson mako virtualenv lxml +RUN python3 -m pip install simplejson mako virtualenv lxml RUN apt-get update && apt-get -y install wget xz-utils RUN wget http://releases.llvm.org/5.0.0/clang+llvm-5.0.0-linux-x86_64-ubuntu14.04.tar.xz @@ -93,8 +94,13 @@ ENV CLANG_FORMAT=clang-format RUN ln -s /clang+llvm-5.0.0-linux-x86_64-ubuntu14.04/bin/clang-tidy /usr/local/bin/clang-tidy ENV CLANG_TIDY=clang-tidy +#======================== +# Bazel installation -RUN mkdir /var/local/jenkins +RUN apt-get update && apt-get install -y wget && apt-get clean +RUN wget https://github.com/bazelbuild/bazel/releases/download/0.23.2/bazel-0.23.2-installer-linux-x86_64.sh && \ + bash ./bazel-0.23.2-installer-linux-x86_64.sh && \ + rm bazel-0.23.2-installer-linux-x86_64.sh # Define the default command. diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 392113c2843..667b9b3541e 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 1.17.0-dev +PROJECT_NUMBER = 1.22.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 @@ -777,6 +777,7 @@ doc/environment_variables.md \ doc/fail_fast.md \ doc/fork_support.md \ doc/g_stands_for.md \ +doc/grpc_release_schedule.md \ doc/health-checking.md \ doc/http-grpc-status-mapping.md \ doc/http2-interop-test-descriptions.md \ @@ -924,16 +925,22 @@ include/grpc/support/thd_id.h \ include/grpc/support/time.h \ include/grpc/support/workaround_list.h \ include/grpcpp/alarm.h \ +include/grpcpp/alarm_impl.h \ include/grpcpp/channel.h \ +include/grpcpp/channel_impl.h \ include/grpcpp/client_context.h \ include/grpcpp/completion_queue.h \ include/grpcpp/create_channel.h \ +include/grpcpp/create_channel_impl.h \ include/grpcpp/create_channel_posix.h \ +include/grpcpp/create_channel_posix_impl.h \ include/grpcpp/ext/health_check_service_server_builder_option.h \ include/grpcpp/generic/async_generic_service.h \ include/grpcpp/generic/generic_stub.h \ +include/grpcpp/generic/generic_stub_impl.h \ include/grpcpp/grpcpp.h \ include/grpcpp/health_check_service_interface.h \ +include/grpcpp/health_check_service_interface_impl.h \ include/grpcpp/impl/call.h \ include/grpcpp/impl/channel_argument_option.h \ include/grpcpp/impl/client_unary_call.h \ @@ -952,6 +959,7 @@ include/grpcpp/impl/codegen/client_context.h \ include/grpcpp/impl/codegen/client_interceptor.h \ include/grpcpp/impl/codegen/client_unary_call.h \ include/grpcpp/impl/codegen/completion_queue.h \ +include/grpcpp/impl/codegen/completion_queue_impl.h \ include/grpcpp/impl/codegen/completion_queue_tag.h \ include/grpcpp/impl/codegen/config.h \ include/grpcpp/impl/codegen/config_protobuf.h \ @@ -962,6 +970,7 @@ include/grpcpp/impl/codegen/grpc_library.h \ include/grpcpp/impl/codegen/intercepted_channel.h \ include/grpcpp/impl/codegen/interceptor.h \ include/grpcpp/impl/codegen/interceptor_common.h \ +include/grpcpp/impl/codegen/message_allocator.h \ include/grpcpp/impl/codegen/metadata_map.h \ include/grpcpp/impl/codegen/method_handler_impl.h \ include/grpcpp/impl/codegen/proto_buffer_reader.h \ @@ -981,6 +990,7 @@ include/grpcpp/impl/codegen/status.h \ include/grpcpp/impl/codegen/status_code_enum.h \ include/grpcpp/impl/codegen/string_ref.h \ include/grpcpp/impl/codegen/stub_options.h \ +include/grpcpp/impl/codegen/sync.h \ include/grpcpp/impl/codegen/sync_stream.h \ include/grpcpp/impl/codegen/time.h \ include/grpcpp/impl/grpc_library.h \ @@ -989,27 +999,41 @@ include/grpcpp/impl/rpc_method.h \ include/grpcpp/impl/rpc_service_method.h \ include/grpcpp/impl/serialization_traits.h \ include/grpcpp/impl/server_builder_option.h \ +include/grpcpp/impl/server_builder_option_impl.h \ include/grpcpp/impl/server_builder_plugin.h \ include/grpcpp/impl/server_initializer.h \ +include/grpcpp/impl/server_initializer_impl.h \ include/grpcpp/impl/service_type.h \ include/grpcpp/resource_quota.h \ +include/grpcpp/resource_quota_impl.h \ include/grpcpp/security/auth_context.h \ include/grpcpp/security/auth_metadata_processor.h \ +include/grpcpp/security/auth_metadata_processor_impl.h \ include/grpcpp/security/credentials.h \ +include/grpcpp/security/credentials_impl.h \ include/grpcpp/security/server_credentials.h \ +include/grpcpp/security/server_credentials_impl.h \ include/grpcpp/server.h \ include/grpcpp/server_builder.h \ +include/grpcpp/server_builder_impl.h \ include/grpcpp/server_context.h \ +include/grpcpp/server_impl.h \ include/grpcpp/server_posix.h \ +include/grpcpp/server_posix_impl.h \ include/grpcpp/support/async_stream.h \ include/grpcpp/support/async_unary_call.h \ include/grpcpp/support/byte_buffer.h \ include/grpcpp/support/channel_arguments.h \ +include/grpcpp/support/channel_arguments_impl.h \ include/grpcpp/support/client_callback.h \ +include/grpcpp/support/client_interceptor.h \ include/grpcpp/support/config.h \ +include/grpcpp/support/interceptor.h \ +include/grpcpp/support/message_allocator.h \ include/grpcpp/support/proto_buffer_reader.h \ include/grpcpp/support/proto_buffer_writer.h \ include/grpcpp/support/server_callback.h \ +include/grpcpp/support/server_interceptor.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 a96683883ca..529b35a2c39 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 1.17.0-dev +PROJECT_NUMBER = 1.22.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 @@ -777,6 +777,7 @@ doc/environment_variables.md \ doc/fail_fast.md \ doc/fork_support.md \ doc/g_stands_for.md \ +doc/grpc_release_schedule.md \ doc/health-checking.md \ doc/http-grpc-status-mapping.md \ doc/http2-interop-test-descriptions.md \ @@ -925,16 +926,22 @@ include/grpc/support/thd_id.h \ include/grpc/support/time.h \ include/grpc/support/workaround_list.h \ include/grpcpp/alarm.h \ +include/grpcpp/alarm_impl.h \ include/grpcpp/channel.h \ +include/grpcpp/channel_impl.h \ include/grpcpp/client_context.h \ include/grpcpp/completion_queue.h \ include/grpcpp/create_channel.h \ +include/grpcpp/create_channel_impl.h \ include/grpcpp/create_channel_posix.h \ +include/grpcpp/create_channel_posix_impl.h \ include/grpcpp/ext/health_check_service_server_builder_option.h \ include/grpcpp/generic/async_generic_service.h \ include/grpcpp/generic/generic_stub.h \ +include/grpcpp/generic/generic_stub_impl.h \ include/grpcpp/grpcpp.h \ include/grpcpp/health_check_service_interface.h \ +include/grpcpp/health_check_service_interface_impl.h \ include/grpcpp/impl/call.h \ include/grpcpp/impl/channel_argument_option.h \ include/grpcpp/impl/client_unary_call.h \ @@ -953,6 +960,7 @@ include/grpcpp/impl/codegen/client_context.h \ include/grpcpp/impl/codegen/client_interceptor.h \ include/grpcpp/impl/codegen/client_unary_call.h \ include/grpcpp/impl/codegen/completion_queue.h \ +include/grpcpp/impl/codegen/completion_queue_impl.h \ include/grpcpp/impl/codegen/completion_queue_tag.h \ include/grpcpp/impl/codegen/config.h \ include/grpcpp/impl/codegen/config_protobuf.h \ @@ -964,6 +972,7 @@ include/grpcpp/impl/codegen/grpc_library.h \ include/grpcpp/impl/codegen/intercepted_channel.h \ include/grpcpp/impl/codegen/interceptor.h \ include/grpcpp/impl/codegen/interceptor_common.h \ +include/grpcpp/impl/codegen/message_allocator.h \ include/grpcpp/impl/codegen/metadata_map.h \ include/grpcpp/impl/codegen/method_handler_impl.h \ include/grpcpp/impl/codegen/proto_buffer_reader.h \ @@ -983,6 +992,7 @@ include/grpcpp/impl/codegen/status.h \ include/grpcpp/impl/codegen/status_code_enum.h \ include/grpcpp/impl/codegen/string_ref.h \ include/grpcpp/impl/codegen/stub_options.h \ +include/grpcpp/impl/codegen/sync.h \ include/grpcpp/impl/codegen/sync_stream.h \ include/grpcpp/impl/codegen/time.h \ include/grpcpp/impl/grpc_library.h \ @@ -991,27 +1001,41 @@ include/grpcpp/impl/rpc_method.h \ include/grpcpp/impl/rpc_service_method.h \ include/grpcpp/impl/serialization_traits.h \ include/grpcpp/impl/server_builder_option.h \ +include/grpcpp/impl/server_builder_option_impl.h \ include/grpcpp/impl/server_builder_plugin.h \ include/grpcpp/impl/server_initializer.h \ +include/grpcpp/impl/server_initializer_impl.h \ include/grpcpp/impl/service_type.h \ include/grpcpp/resource_quota.h \ +include/grpcpp/resource_quota_impl.h \ include/grpcpp/security/auth_context.h \ include/grpcpp/security/auth_metadata_processor.h \ +include/grpcpp/security/auth_metadata_processor_impl.h \ include/grpcpp/security/credentials.h \ +include/grpcpp/security/credentials_impl.h \ include/grpcpp/security/server_credentials.h \ +include/grpcpp/security/server_credentials_impl.h \ include/grpcpp/server.h \ include/grpcpp/server_builder.h \ +include/grpcpp/server_builder_impl.h \ include/grpcpp/server_context.h \ +include/grpcpp/server_impl.h \ include/grpcpp/server_posix.h \ +include/grpcpp/server_posix_impl.h \ include/grpcpp/support/async_stream.h \ include/grpcpp/support/async_unary_call.h \ include/grpcpp/support/byte_buffer.h \ include/grpcpp/support/channel_arguments.h \ +include/grpcpp/support/channel_arguments_impl.h \ include/grpcpp/support/client_callback.h \ +include/grpcpp/support/client_interceptor.h \ include/grpcpp/support/config.h \ +include/grpcpp/support/interceptor.h \ +include/grpcpp/support/message_allocator.h \ include/grpcpp/support/proto_buffer_reader.h \ include/grpcpp/support/proto_buffer_writer.h \ include/grpcpp/support/server_callback.h \ +include/grpcpp/support/server_interceptor.h \ include/grpcpp/support/slice.h \ include/grpcpp/support/status.h \ include/grpcpp/support/status_code_enum.h \ @@ -1037,6 +1061,7 @@ 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_args.h \ src/core/lib/compression/compression_internal.h \ src/core/lib/compression/message_compress.h \ src/core/lib/compression/stream_compression.h \ @@ -1062,18 +1087,24 @@ 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/arena.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/debug_location.h \ src/core/lib/gprpp/fork.h \ +src/core/lib/gprpp/global_config.h \ +src/core/lib/gprpp/global_config_custom.h \ +src/core/lib/gprpp/global_config_env.h \ +src/core/lib/gprpp/global_config_generic.h \ src/core/lib/gprpp/inlined_vector.h \ src/core/lib/gprpp/manual_constructor.h \ +src/core/lib/gprpp/map.h \ src/core/lib/gprpp/memory.h \ -src/core/lib/gprpp/mutex_lock.h \ +src/core/lib/gprpp/optional.h \ src/core/lib/gprpp/orphanable.h \ +src/core/lib/gprpp/pair.h \ src/core/lib/gprpp/ref_counted.h \ src/core/lib/gprpp/ref_counted_ptr.h \ +src/core/lib/gprpp/sync.h \ src/core/lib/gprpp/thd.h \ src/core/lib/http/format_request.h \ src/core/lib/http/httpcli.h \ @@ -1081,11 +1112,15 @@ src/core/lib/http/parser.h \ src/core/lib/iomgr/block_annotate.h \ src/core/lib/iomgr/buffer_list.h \ src/core/lib/iomgr/call_combiner.h \ +src/core/lib/iomgr/cfstream_handle.h \ src/core/lib/iomgr/closure.h \ src/core/lib/iomgr/combiner.h \ +src/core/lib/iomgr/dynamic_annotations.h \ src/core/lib/iomgr/endpoint.h \ +src/core/lib/iomgr/endpoint_cfstream.h \ src/core/lib/iomgr/endpoint_pair.h \ src/core/lib/iomgr/error.h \ +src/core/lib/iomgr/error_cfstream.h \ src/core/lib/iomgr/error_internal.h \ src/core/lib/iomgr/ev_epoll1_linux.h \ src/core/lib/iomgr/ev_epollex_linux.h \ @@ -1094,6 +1129,7 @@ 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/grpc_if_nametoindex.h \ src/core/lib/iomgr/internal_errqueue.h \ src/core/lib/iomgr/iocp_windows.h \ src/core/lib/iomgr/iomgr.h \ @@ -1104,7 +1140,6 @@ 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 \ @@ -1141,7 +1176,6 @@ 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 \ @@ -1154,6 +1188,7 @@ src/core/lib/slice/percent_encoding.h \ src/core/lib/slice/slice_hash_table.h \ src/core/lib/slice/slice_internal.h \ src/core/lib/slice/slice_string_helpers.h \ +src/core/lib/slice/slice_utils.h \ src/core/lib/slice/slice_weak_hash_table.h \ src/core/lib/surface/api_trace.h \ src/core/lib/surface/call.h \ @@ -1176,7 +1211,6 @@ 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 \ diff --git a/tools/doxygen/Doxyfile.core b/tools/doxygen/Doxyfile.core index b78fb607ad3..7235c7b1539 100644 --- a/tools/doxygen/Doxyfile.core +++ b/tools/doxygen/Doxyfile.core @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC Core" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 7.0.0-dev +PROJECT_NUMBER = 7.0.0 # 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 @@ -784,6 +784,7 @@ doc/environment_variables.md \ doc/fail_fast.md \ doc/fork_support.md \ doc/g_stands_for.md \ +doc/grpc_release_schedule.md \ doc/health-checking.md \ doc/http-grpc-status-mapping.md \ doc/http2-interop-test-descriptions.md \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 7d105b32ce0..25c113f59c5 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC Core" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 7.0.0-dev +PROJECT_NUMBER = 7.0.0 # 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 @@ -784,6 +784,7 @@ doc/environment_variables.md \ doc/fail_fast.md \ doc/fork_support.md \ doc/g_stands_for.md \ +doc/grpc_release_schedule.md \ doc/health-checking.md \ doc/http-grpc-status-mapping.md \ doc/http2-interop-test-descriptions.md \ @@ -885,6 +886,8 @@ src/core/ext/filters/client_channel/client_channel_factory.h \ src/core/ext/filters/client_channel/client_channel_plugin.cc \ src/core/ext/filters/client_channel/connector.cc \ src/core/ext/filters/client_channel/connector.h \ +src/core/ext/filters/client_channel/global_subchannel_pool.cc \ +src/core/ext/filters/client_channel/global_subchannel_pool.h \ src/core/ext/filters/client_channel/health/health.pb.c \ src/core/ext/filters/client_channel/health/health.pb.h \ src/core/ext/filters/client_channel/health/health_check_client.cc \ @@ -922,10 +925,11 @@ src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.cc \ src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.h \ src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.cc \ src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h \ -src/core/ext/filters/client_channel/lb_policy_factory.cc \ src/core/ext/filters/client_channel/lb_policy_factory.h \ src/core/ext/filters/client_channel/lb_policy_registry.cc \ src/core/ext/filters/client_channel/lb_policy_registry.h \ +src/core/ext/filters/client_channel/local_subchannel_pool.cc \ +src/core/ext/filters/client_channel/local_subchannel_pool.h \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/parse_address.h \ src/core/ext/filters/client_channel/proxy_mapper.cc \ @@ -938,11 +942,15 @@ src/core/ext/filters/client_channel/resolver/README.md \ 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.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h \ +src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc \ +src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc \ +src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc \ +src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc \ src/core/ext/filters/client_channel/resolver/dns/native/README.md \ @@ -956,12 +964,18 @@ src/core/ext/filters/client_channel/resolver_registry.cc \ src/core/ext/filters/client_channel/resolver_registry.h \ src/core/ext/filters/client_channel/resolver_result_parsing.cc \ src/core/ext/filters/client_channel/resolver_result_parsing.h \ +src/core/ext/filters/client_channel/resolving_lb_policy.cc \ +src/core/ext/filters/client_channel/resolving_lb_policy.h \ src/core/ext/filters/client_channel/retry_throttle.cc \ src/core/ext/filters/client_channel/retry_throttle.h \ +src/core/ext/filters/client_channel/server_address.cc \ +src/core/ext/filters/client_channel/server_address.h \ +src/core/ext/filters/client_channel/service_config.cc \ +src/core/ext/filters/client_channel/service_config.h \ src/core/ext/filters/client_channel/subchannel.cc \ src/core/ext/filters/client_channel/subchannel.h \ -src/core/ext/filters/client_channel/subchannel_index.cc \ -src/core/ext/filters/client_channel/subchannel_index.h \ +src/core/ext/filters/client_channel/subchannel_pool_interface.cc \ +src/core/ext/filters/client_channel/subchannel_pool_interface.h \ src/core/ext/filters/deadline/deadline_filter.cc \ src/core/ext/filters/deadline/deadline_filter.h \ src/core/ext/filters/http/client/http_client_filter.cc \ @@ -1009,6 +1023,8 @@ src/core/ext/transport/chttp2/transport/bin_encoder.h \ src/core/ext/transport/chttp2/transport/chttp2_plugin.cc \ src/core/ext/transport/chttp2/transport/chttp2_transport.cc \ src/core/ext/transport/chttp2/transport/chttp2_transport.h \ +src/core/ext/transport/chttp2/transport/context_list.cc \ +src/core/ext/transport/chttp2/transport/context_list.h \ src/core/ext/transport/chttp2/transport/flow_control.cc \ src/core/ext/transport/chttp2/transport/flow_control.h \ src/core/ext/transport/chttp2/transport/frame.h \ @@ -1070,7 +1086,6 @@ src/core/lib/channel/connected_channel.h \ src/core/lib/channel/context.h \ src/core/lib/channel/handshaker.cc \ src/core/lib/channel/handshaker.h \ -src/core/lib/channel/handshaker_factory.cc \ src/core/lib/channel/handshaker_factory.h \ src/core/lib/channel/handshaker_registry.cc \ src/core/lib/channel/handshaker_registry.h \ @@ -1078,6 +1093,8 @@ src/core/lib/channel/status_util.cc \ src/core/lib/channel/status_util.h \ src/core/lib/compression/algorithm_metadata.h \ src/core/lib/compression/compression.cc \ +src/core/lib/compression/compression_args.cc \ +src/core/lib/compression/compression_args.h \ src/core/lib/compression/compression_internal.cc \ src/core/lib/compression/compression_internal.h \ src/core/lib/compression/message_compress.cc \ @@ -1097,7 +1114,6 @@ src/core/lib/debug/trace.h \ src/core/lib/gpr/README.md \ src/core/lib/gpr/alloc.cc \ src/core/lib/gpr/alloc.h \ -src/core/lib/gpr/arena.cc \ src/core/lib/gpr/arena.h \ src/core/lib/gpr/atm.cc \ src/core/lib/gpr/cpu_iphone.cc \ @@ -1147,19 +1163,27 @@ src/core/lib/gpr/useful.h \ src/core/lib/gpr/wrap_memcpy.cc \ src/core/lib/gprpp/README.md \ src/core/lib/gprpp/abstract.h \ +src/core/lib/gprpp/arena.cc \ +src/core/lib/gprpp/arena.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/debug_location.h \ src/core/lib/gprpp/fork.cc \ src/core/lib/gprpp/fork.h \ +src/core/lib/gprpp/global_config.h \ +src/core/lib/gprpp/global_config_custom.h \ +src/core/lib/gprpp/global_config_env.cc \ +src/core/lib/gprpp/global_config_env.h \ +src/core/lib/gprpp/global_config_generic.h \ src/core/lib/gprpp/inlined_vector.h \ src/core/lib/gprpp/manual_constructor.h \ +src/core/lib/gprpp/map.h \ src/core/lib/gprpp/memory.h \ -src/core/lib/gprpp/mutex_lock.h \ +src/core/lib/gprpp/optional.h \ src/core/lib/gprpp/orphanable.h \ +src/core/lib/gprpp/pair.h \ src/core/lib/gprpp/ref_counted.h \ src/core/lib/gprpp/ref_counted_ptr.h \ +src/core/lib/gprpp/sync.h \ src/core/lib/gprpp/thd.h \ src/core/lib/gprpp/thd_posix.cc \ src/core/lib/gprpp/thd_windows.cc \ @@ -1176,17 +1200,24 @@ src/core/lib/iomgr/buffer_list.cc \ src/core/lib/iomgr/buffer_list.h \ src/core/lib/iomgr/call_combiner.cc \ src/core/lib/iomgr/call_combiner.h \ +src/core/lib/iomgr/cfstream_handle.cc \ +src/core/lib/iomgr/cfstream_handle.h \ src/core/lib/iomgr/closure.h \ src/core/lib/iomgr/combiner.cc \ src/core/lib/iomgr/combiner.h \ +src/core/lib/iomgr/dynamic_annotations.h \ src/core/lib/iomgr/endpoint.cc \ src/core/lib/iomgr/endpoint.h \ +src/core/lib/iomgr/endpoint_cfstream.cc \ +src/core/lib/iomgr/endpoint_cfstream.h \ src/core/lib/iomgr/endpoint_pair.h \ 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/error.h \ +src/core/lib/iomgr/error_cfstream.cc \ +src/core/lib/iomgr/error_cfstream.h \ src/core/lib/iomgr/error_internal.h \ src/core/lib/iomgr/ev_epoll1_linux.cc \ src/core/lib/iomgr/ev_epoll1_linux.h \ @@ -1207,6 +1238,9 @@ src/core/lib/iomgr/gethostname.h \ 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/grpc_if_nametoindex.h \ +src/core/lib/iomgr/grpc_if_nametoindex_posix.cc \ +src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc \ src/core/lib/iomgr/internal_errqueue.cc \ src/core/lib/iomgr/internal_errqueue.h \ src/core/lib/iomgr/iocp_windows.cc \ @@ -1219,6 +1253,7 @@ src/core/lib/iomgr/iomgr_internal.cc \ src/core/lib/iomgr/iomgr_internal.h \ src/core/lib/iomgr/iomgr_posix.cc \ src/core/lib/iomgr/iomgr_posix.h \ +src/core/lib/iomgr/iomgr_posix_cfstream.cc \ src/core/lib/iomgr/iomgr_uv.cc \ src/core/lib/iomgr/iomgr_windows.cc \ src/core/lib/iomgr/is_epollexclusive_available.cc \ @@ -1228,8 +1263,6 @@ src/core/lib/iomgr/load_file.h \ src/core/lib/iomgr/lockfree_event.cc \ src/core/lib/iomgr/lockfree_event.h \ src/core/lib/iomgr/nameser.h \ -src/core/lib/iomgr/network_status_tracker.cc \ -src/core/lib/iomgr/network_status_tracker.h \ src/core/lib/iomgr/polling_entity.cc \ src/core/lib/iomgr/polling_entity.h \ src/core/lib/iomgr/pollset.cc \ @@ -1276,6 +1309,7 @@ src/core/lib/iomgr/socket_windows.h \ src/core/lib/iomgr/sys_epoll_wrapper.h \ src/core/lib/iomgr/tcp_client.cc \ src/core/lib/iomgr/tcp_client.h \ +src/core/lib/iomgr/tcp_client_cfstream.cc \ src/core/lib/iomgr/tcp_client_custom.cc \ src/core/lib/iomgr/tcp_client_posix.cc \ src/core/lib/iomgr/tcp_client_posix.h \ @@ -1313,8 +1347,6 @@ src/core/lib/iomgr/udp_server.h \ src/core/lib/iomgr/unix_sockets_posix.cc \ src/core/lib/iomgr/unix_sockets_posix.h \ src/core/lib/iomgr/unix_sockets_posix_noop.cc \ -src/core/lib/iomgr/wakeup_fd_cv.cc \ -src/core/lib/iomgr/wakeup_fd_cv.h \ src/core/lib/iomgr/wakeup_fd_eventfd.cc \ src/core/lib/iomgr/wakeup_fd_nospecial.cc \ src/core/lib/iomgr/wakeup_fd_pipe.cc \ @@ -1371,6 +1403,10 @@ src/core/lib/security/credentials/plugin/plugin_credentials.cc \ src/core/lib/security/credentials/plugin/plugin_credentials.h \ src/core/lib/security/credentials/ssl/ssl_credentials.cc \ src/core/lib/security/credentials/ssl/ssl_credentials.h \ +src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc \ +src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h \ +src/core/lib/security/credentials/tls/spiffe_credentials.cc \ +src/core/lib/security/credentials/tls/spiffe_credentials.h \ src/core/lib/security/security_connector/alts/alts_security_connector.cc \ src/core/lib/security/security_connector/alts/alts_security_connector.h \ src/core/lib/security/security_connector/fake/fake_security_connector.cc \ @@ -1387,6 +1423,8 @@ src/core/lib/security/security_connector/ssl/ssl_security_connector.cc \ src/core/lib/security/security_connector/ssl/ssl_security_connector.h \ src/core/lib/security/security_connector/ssl_utils.cc \ src/core/lib/security/security_connector/ssl_utils.h \ +src/core/lib/security/security_connector/tls/spiffe_security_connector.cc \ +src/core/lib/security/security_connector/tls/spiffe_security_connector.h \ src/core/lib/security/transport/auth_filters.h \ src/core/lib/security/transport/client_auth_filter.cc \ src/core/lib/security/transport/secure_endpoint.cc \ @@ -1411,6 +1449,7 @@ src/core/lib/slice/slice_intern.cc \ src/core/lib/slice/slice_internal.h \ src/core/lib/slice/slice_string_helpers.cc \ src/core/lib/slice/slice_string_helpers.h \ +src/core/lib/slice/slice_utils.h \ src/core/lib/slice/slice_weak_hash_table.h \ src/core/lib/surface/README.md \ src/core/lib/surface/api_trace.cc \ @@ -1462,8 +1501,6 @@ src/core/lib/transport/metadata_batch.cc \ src/core/lib/transport/metadata_batch.h \ src/core/lib/transport/pid_controller.cc \ src/core/lib/transport/pid_controller.h \ -src/core/lib/transport/service_config.cc \ -src/core/lib/transport/service_config.h \ src/core/lib/transport/static_metadata.cc \ src/core/lib/transport/static_metadata.h \ src/core/lib/transport/status_conversion.cc \ diff --git a/tools/gce/create_linux_kokoro_performance_worker_from_image.sh b/tools/gce/create_linux_kokoro_performance_worker_from_image.sh index 0f7939be4c0..1b014ad4a8e 100755 --- a/tools/gce/create_linux_kokoro_performance_worker_from_image.sh +++ b/tools/gce/create_linux_kokoro_performance_worker_from_image.sh @@ -22,7 +22,7 @@ cd "$(dirname "$0")" CLOUD_PROJECT=grpc-testing ZONE=us-central1-b # this zone allows 32core machines -LATEST_PERF_WORKER_IMAGE=grpc-performance-kokoro-v2 # update if newer image exists +LATEST_PERF_WORKER_IMAGE=grpc-performance-kokoro-v5 # update if newer image exists INSTANCE_NAME="${1:-grpc-kokoro-performance-server}" MACHINE_TYPE="${2:-n1-standard-32}" diff --git a/tools/gce/linux_kokoro_performance_worker_init.sh b/tools/gce/linux_kokoro_performance_worker_init.sh index b78695d8020..46061a0cc67 100755 --- a/tools/gce/linux_kokoro_performance_worker_init.sh +++ b/tools/gce/linux_kokoro_performance_worker_init.sh @@ -133,6 +133,12 @@ sudo cp -r dotnet105_download/shared/Microsoft.NETCore.App/1.0.5/ /usr/share/dot wget -q http://security.ubuntu.com/ubuntu/pool/main/i/icu/libicu55_55.1-7ubuntu0.4_amd64.deb sudo dpkg -i libicu55_55.1-7ubuntu0.4_amd64.deb +# Install .NET Core 1.1.10 runtime (required to run netcoreapp1.1) +wget -q -O dotnet_old.tar.gz https://download.visualstudio.microsoft.com/download/pr/b25b5650-0cb8-4699-a347-48d73650da0b/920966211e9bb1907232bbda1faa895a/dotnet-ubuntu.18.04-x64.1.1.10.tar.gz +mkdir -p dotnet_old +tar zxf dotnet_old.tar.gz -C dotnet_old +sudo cp -r dotnet_old/shared/Microsoft.NETCore.App/1.1.10/ /usr/share/dotnet/shared/Microsoft.NETCore.App/ + # Ruby dependencies gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 curl -sSL https://get.rvm.io | bash -s stable --ruby @@ -209,6 +215,13 @@ sudo mkdir /tmpfs sudo chown kbuilder /tmpfs touch /tmpfs/READY +# Disable automatic updates to prevent spurious apt-get install failures +# See https://github.com/grpc/grpc/issues/17794 +sudo sed -i 's/APT::Periodic::Update-Package-Lists "1"/APT::Periodic::Update-Package-Lists "0"/' /etc/apt/apt.conf.d/10periodic +sudo sed -i 's/APT::Periodic::AutocleanInterval "1"/APT::Periodic::AutocleanInterval "0"/' /etc/apt/apt.conf.d/10periodic +sudo sed -i 's/APT::Periodic::Update-Package-Lists "1"/APT::Periodic::Update-Package-Lists "0"/' /etc/apt/apt.conf.d/20auto-upgrades +sudo sed -i 's/APT::Periodic::Unattended-Upgrade "1"/APT::Periodic::Unattended-Upgrade "0"/' /etc/apt/apt.conf.d/20auto-upgrades + # Restart for VM to pick up kernel update echo 'Successfully initialized the linux worker, going for reboot in 10 seconds' sleep 10 diff --git a/tools/gcp/utils/big_query_utils.py b/tools/gcp/utils/big_query_utils.py index 6e9cda376ba..168b48d1e65 100755 --- a/tools/gcp/utils/big_query_utils.py +++ b/tools/gcp/utils/big_query_utils.py @@ -178,6 +178,7 @@ def insert_rows(big_query, project_id, dataset_id, table_id, rows_list): is_success = False except HttpError as http_error: print('Error inserting rows to the table %s' % table_id) + print('Error message: %s' % http_error) is_success = False return is_success diff --git a/tools/http2_interop/doc.go b/tools/http2_interop/doc.go index 6c6b5cb1938..9ae736a7566 100644 --- a/tools/http2_interop/doc.go +++ b/tools/http2_interop/doc.go @@ -1,3 +1,17 @@ +// Copyright 2019 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. +// 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. + // http2interop project doc.go /* diff --git a/tools/http2_interop/frame.go b/tools/http2_interop/frame.go index 12689e9b33d..a2df52ff4ae 100644 --- a/tools/http2_interop/frame.go +++ b/tools/http2_interop/frame.go @@ -1,3 +1,17 @@ +// Copyright 2019 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. +// 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 http2interop import ( diff --git a/tools/http2_interop/frameheader.go b/tools/http2_interop/frameheader.go index 84f6fa5c558..148268b2371 100644 --- a/tools/http2_interop/frameheader.go +++ b/tools/http2_interop/frameheader.go @@ -1,3 +1,17 @@ +// Copyright 2019 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. +// 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 http2interop import ( diff --git a/tools/http2_interop/goaway.go b/tools/http2_interop/goaway.go index 289442d615b..2321709fdc4 100644 --- a/tools/http2_interop/goaway.go +++ b/tools/http2_interop/goaway.go @@ -1,3 +1,17 @@ +// Copyright 2019 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. +// 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 http2interop import ( diff --git a/tools/http2_interop/http1frame.go b/tools/http2_interop/http1frame.go index 68ab197b652..e79d2fde5a8 100644 --- a/tools/http2_interop/http1frame.go +++ b/tools/http2_interop/http1frame.go @@ -1,3 +1,17 @@ +// Copyright 2019 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. +// 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 http2interop import ( diff --git a/tools/http2_interop/http2interop.go b/tools/http2_interop/http2interop.go index fa113961f2a..3af5134f9d8 100644 --- a/tools/http2_interop/http2interop.go +++ b/tools/http2_interop/http2interop.go @@ -1,3 +1,17 @@ +// Copyright 2019 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. +// 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 http2interop import ( diff --git a/tools/http2_interop/http2interop_test.go b/tools/http2_interop/http2interop_test.go index fb314da1964..989b60590c3 100644 --- a/tools/http2_interop/http2interop_test.go +++ b/tools/http2_interop/http2interop_test.go @@ -1,3 +1,17 @@ +// Copyright 2019 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. +// 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 http2interop import ( diff --git a/tools/http2_interop/ping.go b/tools/http2_interop/ping.go index 6011eed4511..4c6868bb414 100644 --- a/tools/http2_interop/ping.go +++ b/tools/http2_interop/ping.go @@ -1,3 +1,17 @@ +// Copyright 2019 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. +// 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 http2interop import ( diff --git a/tools/http2_interop/s6.5.go b/tools/http2_interop/s6.5.go index 4295c46f73a..89ca57f221a 100644 --- a/tools/http2_interop/s6.5.go +++ b/tools/http2_interop/s6.5.go @@ -1,3 +1,17 @@ +// Copyright 2019 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. +// 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 http2interop import ( diff --git a/tools/http2_interop/s6.5_test.go b/tools/http2_interop/s6.5_test.go index 063fd5664c8..61e8a4080e1 100644 --- a/tools/http2_interop/s6.5_test.go +++ b/tools/http2_interop/s6.5_test.go @@ -1,3 +1,17 @@ +// Copyright 2019 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. +// 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 http2interop import ( diff --git a/tools/http2_interop/settings.go b/tools/http2_interop/settings.go index 544cec01ee7..6db7c273daf 100644 --- a/tools/http2_interop/settings.go +++ b/tools/http2_interop/settings.go @@ -1,3 +1,17 @@ +// Copyright 2019 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. +// 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 http2interop import ( diff --git a/tools/http2_interop/testsuite.go b/tools/http2_interop/testsuite.go index 51d36e217ed..c361eec9cb0 100644 --- a/tools/http2_interop/testsuite.go +++ b/tools/http2_interop/testsuite.go @@ -1,3 +1,17 @@ +// Copyright 2019 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. +// 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 http2interop import ( diff --git a/tools/http2_interop/unknownframe.go b/tools/http2_interop/unknownframe.go index 0450e7e976c..dacb249b74f 100644 --- a/tools/http2_interop/unknownframe.go +++ b/tools/http2_interop/unknownframe.go @@ -1,3 +1,17 @@ +// Copyright 2019 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. +// 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 http2interop import ( diff --git a/tools/internal_ci/README.md b/tools/internal_ci/README.md index af582c471e4..fdf70774327 100644 --- a/tools/internal_ci/README.md +++ b/tools/internal_ci/README.md @@ -1,7 +1,7 @@ # Kokoro CI job configurations and testing scripts -gRPC uses a continous integration tool called "Kokoro" (a.k.a "internal CI") +gRPC uses a continuous integration tool called "Kokoro" (a.k.a "internal CI") for running majority of its open source tests. This directory contains the external part of kokoro test job configurations (the actual job definitions live in an internal repository) and the shell -scripts that act as entry points to exectute the actual tests. +scripts that act as entry points to execute the actual tests. diff --git a/tools/internal_ci/helper_scripts/prepare_build_interop_rc b/tools/internal_ci/helper_scripts/prepare_build_interop_rc index fb0f4b8054e..e462a83e522 100644 --- a/tools/internal_ci/helper_scripts/prepare_build_interop_rc +++ b/tools/internal_ci/helper_scripts/prepare_build_interop_rc @@ -28,6 +28,7 @@ git clone --recursive https://github.com/grpc/grpc-go ./../grpc-go 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 +git clone --recursive https://github.com/grpc/grpc-dotnet ./../grpc-dotnet # Download json file. mkdir ~/service_account diff --git a/tools/internal_ci/helper_scripts/prepare_build_linux_perf_rc b/tools/internal_ci/helper_scripts/prepare_build_linux_perf_rc index dc3c75a6a12..ff5593e031a 100644 --- a/tools/internal_ci/helper_scripts/prepare_build_linux_perf_rc +++ b/tools/internal_ci/helper_scripts/prepare_build_linux_perf_rc @@ -21,17 +21,13 @@ ulimit -c unlimited # Performance PR testing needs GH API key and PR metadata to comment results if [ -n "$KOKORO_GITHUB_PULL_REQUEST_NUMBER" ]; then - set +x sudo apt-get install -y jq export ghprbTargetBranch=$(curl -s https://api.github.com/repos/grpc/grpc/pulls/$KOKORO_GITHUB_PULL_REQUEST_NUMBER | jq -r .base.ref) - - gsutil cp gs://grpc-testing-secrets/github_credentials/oauth_token.txt ~/ - # TODO(matt-kwong): rename this to GITHUB_OAUTH_TOKEN after Jenkins deprecation - export JENKINS_OAUTH_TOKEN=$(cat ~/oauth_token.txt) - export ghprbPullId=$KOKORO_GITHUB_PULL_REQUEST_NUMBER - set -x fi sudo pip install tabulate +# Python dependencies for tools/run_tests/python_utils/check_on_pr.py +time python2.7 -m pip install pyjwt cryptography requests --user + git submodule update --init 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 43bc9609c7e..cbc3ef2d9a9 100644 --- a/tools/internal_ci/helper_scripts/prepare_build_macos_interop_rc +++ b/tools/internal_ci/helper_scripts/prepare_build_macos_interop_rc @@ -22,3 +22,4 @@ git clone --recursive https://github.com/grpc/grpc-go ./../grpc-go 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 +git clone --recursive https://github.com/grpc/grpc-dotnet ./../grpc-dotnet diff --git a/tools/internal_ci/helper_scripts/prepare_build_macos_rc b/tools/internal_ci/helper_scripts/prepare_build_macos_rc index 24a3545dedc..e9ec07cd0f9 100644 --- a/tools/internal_ci/helper_scripts/prepare_build_macos_rc +++ b/tools/internal_ci/helper_scripts/prepare_build_macos_rc @@ -19,39 +19,27 @@ launchctl limit maxfiles ulimit -a -# synchronize the clock -date -sudo systemsetup -setusingnetworktime off -sudo systemsetup -setnetworktimeserver "$( ipconfig getoption en0 server_identifier )" -sudo systemsetup -settimezone America/Los_Angeles -sudo systemsetup -setusingnetworktime on -date - # Add GCP credentials for BQ access -# pin google-api-python-client to avoid https://github.com/grpc/grpc/issues/15600 -pip install google-api-python-client==1.6.7 --user python +pip install google-api-python-client oauth2client --user python export GOOGLE_APPLICATION_CREDENTIALS=${KOKORO_GFILE_DIR}/GrpcTesting-d0eeee2db331.json # If this is a PR using RUN_TESTS_FLAGS var, then add flags to filter tests if [ -n "$KOKORO_GITHUB_PULL_REQUEST_NUMBER" ]; then - set +x brew update - brew install jq + brew install jq || brew upgrade jq ghprbTargetBranch=$(curl -s https://api.github.com/repos/grpc/grpc/pulls/$KOKORO_GITHUB_PULL_REQUEST_NUMBER | jq -r .base.ref) export RUN_TESTS_FLAGS="$RUN_TESTS_FLAGS --filter_pr_tests --base_branch origin/$ghprbTargetBranch" - - # TODO(matt-kwong): rename this to GITHUB_OAUTH_TOKEN after Jenkins deprecation - export JENKINS_OAUTH_TOKEN=$(cat ${KOKORO_GFILE_DIR}/oauth_token.txt) - export ghprbPullId=$KOKORO_GITHUB_PULL_REQUEST_NUMBER - set -x fi set +ex # rvm script is very verbose and exits with errorcode +# Advice from https://github.com/Homebrew/homebrew-cask/issues/8629#issuecomment-68641176 +brew update && brew upgrade brew-cask && brew cleanup && brew cask cleanup +rvm --debug requirements ruby-2.5.0 source $HOME/.rvm/scripts/rvm set -e # rvm commands are very verbose time rvm install 2.5.0 rvm use 2.5.0 --default -time gem install bundler --no-ri --no-doc +time gem install bundler -v 1.17.3 --no-ri --no-doc time gem install cocoapods --version 1.3.1 --no-ri --no-doc time gem install rake-compiler --no-ri --no-doc rvm osx-ssl-certs status all @@ -60,11 +48,13 @@ set -ex # cocoapods export LANG=en_US.UTF-8 -time pod repo update # needed by python +# pre-fetch cocoapods master repo's most recent commit only +mkdir -p ~/.cocoapods/repos +time git clone --depth 1 https://github.com/CocoaPods/Specs.git ~/.cocoapods/repos/master # python time pip install virtualenv --user python -time pip install -U Mako six tox setuptools twisted pyyaml --user python +time pip install -U Mako six tox setuptools twisted pyyaml pyjwt cryptography requests --user python export PYTHONPATH=/Library/Python/3.4/site-packages # Install Python 3.7 @@ -91,3 +81,6 @@ mkdir -p /tmpfs/DerivedData rm -rf ~/Library/Developer/Xcode/DerivedData mkdir -p ~/Library/Developer/Xcode ln -s /tmpfs/DerivedData ~/Library/Developer/Xcode/DerivedData + +# PHP tests currently require using an older version of PHPUnit +ln -sf /usr/local/bin/phpunit-5.7 /usr/local/bin/phpunit diff --git a/tools/internal_ci/helper_scripts/prepare_build_windows.bat b/tools/internal_ci/helper_scripts/prepare_build_windows.bat index f987f8a8cb5..bee59159331 100644 --- a/tools/internal_ci/helper_scripts/prepare_build_windows.bat +++ b/tools/internal_ci/helper_scripts/prepare_build_windows.bat @@ -34,6 +34,10 @@ netsh interface ip add dnsservers "Local Area Connection 8" 8.8.4.4 index=3 @rem Needed for big_query_utils python -m pip install google-api-python-client +@rem C# prerequisites: Install dotnet SDK +powershell -File src\csharp\install_dotnet_sdk.ps1 +set PATH=%LOCALAPPDATA%\Microsoft\dotnet;%PATH% + @rem Disable some unwanted dotnet options set NUGET_XMLDOC_MODE=skip set DOTNET_SKIP_FIRST_TIME_EXPERIENCE=true diff --git a/tools/internal_ci/linux/grpc_android.sh b/tools/internal_ci/linux/grpc_android.sh index 42c7f5fb042..209b30d1ad7 100755 --- a/tools/internal_ci/linux/grpc_android.sh +++ b/tools/internal_ci/linux/grpc_android.sh @@ -44,7 +44,8 @@ gcloud firebase test android run \ --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 + --device model=Nexus6,version=21,locale=en,orientation=portrait \ + --device model=walleye,version=28,locale=en,orientation=portrait # Build hello world example diff --git a/tools/internal_ci/linux/grpc_basictests_csharp.cfg b/tools/internal_ci/linux/grpc_basictests_csharp.cfg new file mode 100644 index 00000000000..017e929beff --- /dev/null +++ b/tools/internal_ci/linux/grpc_basictests_csharp.cfg @@ -0,0 +1,30 @@ +# Copyright 2019 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. +# 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. + +# 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: 60 +action { + define_artifacts { + regex: "**/*sponge_log.*" + regex: "github/grpc/reports/**" + } +} + +env_vars { + key: "RUN_TESTS_FLAGS" + value: "-f basictests linux csharp --inner_jobs 16 -j 2 --internal_ci --bq_result_table aggregate_results" +} diff --git a/tools/internal_ci/linux/grpc_basictests_node.cfg b/tools/internal_ci/linux/grpc_basictests_node.cfg new file mode 100644 index 00000000000..d7b35a04719 --- /dev/null +++ b/tools/internal_ci/linux/grpc_basictests_node.cfg @@ -0,0 +1,30 @@ +# Copyright 2019 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. +# 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. + +# 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: 60 +action { + define_artifacts { + regex: "**/*sponge_log.*" + regex: "github/grpc/reports/**" + } +} + +env_vars { + key: "RUN_TESTS_FLAGS" + value: "-f basictests linux grpc-node --inner_jobs 16 -j 2 --internal_ci --bq_result_table aggregate_results" +} diff --git a/tools/internal_ci/linux/grpc_basictests_php.cfg b/tools/internal_ci/linux/grpc_basictests_php.cfg new file mode 100644 index 00000000000..80aa0dc87bb --- /dev/null +++ b/tools/internal_ci/linux/grpc_basictests_php.cfg @@ -0,0 +1,30 @@ +# Copyright 2019 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. +# 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. + +# 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: 60 +action { + define_artifacts { + regex: "**/*sponge_log.*" + regex: "github/grpc/reports/**" + } +} + +env_vars { + key: "RUN_TESTS_FLAGS" + value: "-f basictests linux php --inner_jobs 16 -j 2 --internal_ci --bq_result_table aggregate_results" +} diff --git a/tools/internal_ci/linux/grpc_basictests_python.cfg b/tools/internal_ci/linux/grpc_basictests_python.cfg new file mode 100644 index 00000000000..444dba9f4df --- /dev/null +++ b/tools/internal_ci/linux/grpc_basictests_python.cfg @@ -0,0 +1,30 @@ +# Copyright 2019 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. +# 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. + +# 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: 60 +action { + define_artifacts { + regex: "**/*sponge_log.*" + regex: "github/grpc/reports/**" + } +} + +env_vars { + key: "RUN_TESTS_FLAGS" + value: "-f basictests linux python --inner_jobs 16 -j 2 --internal_ci --bq_result_table aggregate_results" +} diff --git a/tools/internal_ci/linux/grpc_basictests_ruby.cfg b/tools/internal_ci/linux/grpc_basictests_ruby.cfg new file mode 100644 index 00000000000..336aa469958 --- /dev/null +++ b/tools/internal_ci/linux/grpc_basictests_ruby.cfg @@ -0,0 +1,30 @@ +# Copyright 2019 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. +# 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. + +# 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: 60 +action { + define_artifacts { + regex: "**/*sponge_log.*" + regex: "github/grpc/reports/**" + } +} + +env_vars { + key: "RUN_TESTS_FLAGS" + value: "-f basictests linux ruby --inner_jobs 16 -j 2 --internal_ci --bq_result_table aggregate_results" +} 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 74778d9d291..93399f81e79 100755 --- a/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh +++ b/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh @@ -15,15 +15,9 @@ set -ex -# A temporary solution to give Kokoro credentials. -# The file name 4321_grpc-testing-service needs to match auth_credential in -# the build config. -mkdir -p ${KOKORO_KEYSTORE_DIR} -cp ${KOKORO_GFILE_DIR}/GrpcTesting-d0eeee2db331.json ${KOKORO_KEYSTORE_DIR}/4321_grpc-testing-service - # Download bazel temp_dir="$(mktemp -d)" -wget -q https://github.com/bazelbuild/bazel/releases/download/0.17.1/bazel-0.17.1-linux-x86_64 -O "${temp_dir}/bazel" +wget -q https://github.com/bazelbuild/bazel/releases/download/0.23.2/bazel-0.23.2-linux-x86_64 -O "${temp_dir}/bazel" chmod 755 "${temp_dir}/bazel" export PATH="${temp_dir}:${PATH}" # This should show ${temp_dir}/bazel @@ -35,14 +29,17 @@ cd $(dirname $0)/../../.. source tools/internal_ci/helper_scripts/prepare_build_linux_rc # to get "bazel" link for kokoro build, we need to generate -# invocation UUID, set an env var for bazel to pick it up -# and upload "bazel_invocation_ids" file as artifact. -export BAZEL_INTERNAL_INVOCATION_ID="$(uuidgen)" -echo "${BAZEL_INTERNAL_INVOCATION_ID}" >"${KOKORO_ARTIFACTS_DIR}/bazel_invocation_ids" +# invocation UUID, set a flag for bazel to use it +# and upload "bazel_invocation_ids" file as artifact. +BAZEL_INVOCATION_ID="$(uuidgen)" +echo "${BAZEL_INVOCATION_ID}" >"${KOKORO_ARTIFACTS_DIR}/bazel_invocation_ids" bazel \ --bazelrc=tools/remote_build/kokoro.bazelrc \ test \ + --invocation_id="${BAZEL_INVOCATION_ID}" \ + --workspace_status_command=tools/remote_build/workspace_status_kokoro.sh \ + --google_credentials="${KOKORO_GFILE_DIR}/GrpcTesting-d0eeee2db331.json" \ $@ \ -- //test/... || FAILED="true" 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 fdd5b2e4cde..06b93f3d80f 100644 --- a/tools/internal_ci/linux/grpc_bazel_on_foundry_dbg.sh +++ b/tools/internal_ci/linux/grpc_bazel_on_foundry_dbg.sh @@ -16,5 +16,5 @@ set -ex export UPLOAD_TEST_RESULTS=true -EXTRA_FLAGS="--config=dbg --test_timeout=300,450,1200,3600 --cache_test_results=no" +EXTRA_FLAGS="--config=dbg --cache_test_results=no" 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 30b2b17a674..66effabf972 100644 --- a/tools/internal_ci/linux/grpc_bazel_on_foundry_opt.sh +++ b/tools/internal_ci/linux/grpc_bazel_on_foundry_opt.sh @@ -16,5 +16,5 @@ set -ex export UPLOAD_TEST_RESULTS=true -EXTRA_FLAGS="--config=opt --test_timeout=300,450,1200,3600 --cache_test_results=no" +EXTRA_FLAGS="--config=opt --cache_test_results=no" github/grpc/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh "${EXTRA_FLAGS}" diff --git a/tools/internal_ci/linux/grpc_bazel_privileged_docker.sh b/tools/internal_ci/linux/grpc_bazel_privileged_docker.sh new file mode 100755 index 00000000000..ae1056d7c3d --- /dev/null +++ b/tools/internal_ci/linux/grpc_bazel_privileged_docker.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash +# Copyright 2019 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_linux_rc + +export DOCKERFILE_DIR=tools/dockerfile/test/bazel +export DOCKER_RUN_SCRIPT=$BAZEL_SCRIPT +# NET_ADMIN capability allows tests to manipulate network interfaces +exec tools/run_tests/dockerize/build_and_run_docker.sh --cap-add NET_ADMIN diff --git a/tools/internal_ci/linux/grpc_bazel_rbe_asan.cfg b/tools/internal_ci/linux/grpc_bazel_rbe_asan.cfg new file mode 100644 index 00000000000..21afbd04ee3 --- /dev/null +++ b/tools/internal_ci/linux/grpc_bazel_rbe_asan.cfg @@ -0,0 +1,30 @@ +# Copyright 2019 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. +# 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. + +# 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_asan_on_foundry.sh" +timeout_mins: 60 + +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0eeee2db331.json" +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/resultstore_api_key" + +bazel_setting { + # In order for Kokoro to recognize this as a bazel build and publish the bazel resultstore link, + # the bazel_setting section needs to be present and "upsalite_frontend_address" needs to be + # set. The rest of configuration from bazel_setting is unused (we configure everything when bazel + # command is invoked). + upsalite_frontend_address: "https://source.cloud.google.com" +} diff --git a/tools/internal_ci/linux/grpc_bazel_rbe_dbg.cfg b/tools/internal_ci/linux/grpc_bazel_rbe_dbg.cfg new file mode 100644 index 00000000000..e80321b9a8a --- /dev/null +++ b/tools/internal_ci/linux/grpc_bazel_rbe_dbg.cfg @@ -0,0 +1,30 @@ +# Copyright 2019 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. +# 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. + +# 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_bazel_on_foundry_dbg.sh" +timeout_mins: 60 + +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0eeee2db331.json" +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/resultstore_api_key" + +bazel_setting { + # In order for Kokoro to recognize this as a bazel build and publish the bazel resultstore link, + # the bazel_setting section needs to be present and "upsalite_frontend_address" needs to be + # set. The rest of configuration from bazel_setting is unused (we configure everything when bazel + # command is invoked). + upsalite_frontend_address: "https://source.cloud.google.com" +} diff --git a/tools/internal_ci/linux/grpc_bazel_rbe_incompatible_changes.cfg b/tools/internal_ci/linux/grpc_bazel_rbe_incompatible_changes.cfg new file mode 100644 index 00000000000..ee883392f4b --- /dev/null +++ b/tools/internal_ci/linux/grpc_bazel_rbe_incompatible_changes.cfg @@ -0,0 +1,30 @@ +# Copyright 2019 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. +# 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. + +# 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_bazel_rbe_incompatible_changes.sh" +timeout_mins: 60 + +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0eeee2db331.json" +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/resultstore_api_key" + +bazel_setting { + # In order for Kokoro to recognize this as a bazel build and publish the bazel resultstore link, + # the bazel_setting section needs to be present and "upsalite_frontend_address" needs to be + # set. The rest of configuration from bazel_setting is unused (we configure everything when bazel + # command is invoked). + upsalite_frontend_address: "https://source.cloud.google.com" +} diff --git a/tools/internal_ci/linux/grpc_bazel_rbe_incompatible_changes.sh b/tools/internal_ci/linux/grpc_bazel_rbe_incompatible_changes.sh new file mode 100644 index 00000000000..9c3712a07da --- /dev/null +++ b/tools/internal_ci/linux/grpc_bazel_rbe_incompatible_changes.sh @@ -0,0 +1,23 @@ +#!/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. + +set -ex + +# TODO(jtattermusch): use the latest version of bazel + +# Use --all_incompatible_changes to give an early warning about future +# bazel incompatibilities. +EXTRA_FLAGS="--config=opt --cache_test_results=no --all_incompatible_changes" +github/grpc/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh "${EXTRA_FLAGS}" diff --git a/tools/internal_ci/linux/grpc_bazel_rbe_msan.cfg b/tools/internal_ci/linux/grpc_bazel_rbe_msan.cfg new file mode 100644 index 00000000000..be939bbff55 --- /dev/null +++ b/tools/internal_ci/linux/grpc_bazel_rbe_msan.cfg @@ -0,0 +1,30 @@ +# Copyright 2019 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. +# 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. + +# 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_msan_on_foundry.sh" +timeout_mins: 60 + +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0eeee2db331.json" +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/resultstore_api_key" + +bazel_setting { + # In order for Kokoro to recognize this as a bazel build and publish the bazel resultstore link, + # the bazel_setting section needs to be present and "upsalite_frontend_address" needs to be + # set. The rest of configuration from bazel_setting is unused (we configure everything when bazel + # command is invoked). + upsalite_frontend_address: "https://source.cloud.google.com" +} diff --git a/tools/internal_ci/linux/grpc_bazel_rbe_opt.cfg b/tools/internal_ci/linux/grpc_bazel_rbe_opt.cfg new file mode 100644 index 00000000000..48a6d91f123 --- /dev/null +++ b/tools/internal_ci/linux/grpc_bazel_rbe_opt.cfg @@ -0,0 +1,30 @@ +# Copyright 2019 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. +# 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. + +# 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_bazel_on_foundry_opt.sh" +timeout_mins: 60 + +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0eeee2db331.json" +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/resultstore_api_key" + +bazel_setting { + # In order for Kokoro to recognize this as a bazel build and publish the bazel resultstore link, + # the bazel_setting section needs to be present and "upsalite_frontend_address" needs to be + # set. The rest of configuration from bazel_setting is unused (we configure everything when bazel + # command is invoked). + upsalite_frontend_address: "https://source.cloud.google.com" +} \ No newline at end of file diff --git a/tools/internal_ci/linux/grpc_bazel_rbe_tsan.cfg b/tools/internal_ci/linux/grpc_bazel_rbe_tsan.cfg new file mode 100644 index 00000000000..f45a4c2da2d --- /dev/null +++ b/tools/internal_ci/linux/grpc_bazel_rbe_tsan.cfg @@ -0,0 +1,30 @@ +# Copyright 2019 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. +# 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. + +# 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_tsan_on_foundry.sh" +timeout_mins: 60 + +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0eeee2db331.json" +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/resultstore_api_key" + +bazel_setting { + # In order for Kokoro to recognize this as a bazel build and publish the bazel resultstore link, + # the bazel_setting section needs to be present and "upsalite_frontend_address" needs to be + # set. The rest of configuration from bazel_setting is unused (we configure everything when bazel + # command is invoked). + upsalite_frontend_address: "https://source.cloud.google.com" +} diff --git a/tools/internal_ci/linux/grpc_bazel_rbe_ubsan.cfg b/tools/internal_ci/linux/grpc_bazel_rbe_ubsan.cfg new file mode 100644 index 00000000000..f0cf94ad142 --- /dev/null +++ b/tools/internal_ci/linux/grpc_bazel_rbe_ubsan.cfg @@ -0,0 +1,30 @@ +# Copyright 2019 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. +# 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. + +# 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_ubsan_on_foundry.sh" +timeout_mins: 60 + +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0eeee2db331.json" +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/resultstore_api_key" + +bazel_setting { + # In order for Kokoro to recognize this as a bazel build and publish the bazel resultstore link, + # the bazel_setting section needs to be present and "upsalite_frontend_address" needs to be + # set. The rest of configuration from bazel_setting is unused (we configure everything when bazel + # command is invoked). + upsalite_frontend_address: "https://source.cloud.google.com" +} diff --git a/tools/internal_ci/linux/grpc_coverage.sh b/tools/internal_ci/linux/grpc_coverage.sh index 97166372ab4..a91cffdf989 100755 --- a/tools/internal_ci/linux/grpc_coverage.sh +++ b/tools/internal_ci/linux/grpc_coverage.sh @@ -21,12 +21,20 @@ cd $(dirname $0)/../../.. source tools/internal_ci/helper_scripts/prepare_build_linux_rc python tools/run_tests/run_tests.py \ - --use_docker \ - -t \ - -l all \ - -c gcov \ - -x sponge_log.xml \ - -j 16 || FAILED="true" + -l c c++ -x coverage_cpp/sponge_log.xml \ + --use_docker -t -c gcov -j 2 || FAILED="true" + +python tools/run_tests/run_tests.py \ + -l python -x coverage_python/sponge_log.xml \ + --use_docker -t -c gcov -j 2 || FAILED="true" + +python tools/run_tests/run_tests.py \ + -l ruby -x coverage_ruby/sponge_log.xml \ + --use_docker -t -c gcov -j 2 || FAILED="true" + +python tools/run_tests/run_tests.py \ + -l php -x coverage_php/sponge_log.xml \ + --use_docker -t -c gcov -j 2 || FAILED="true" # HTML reports can't be easily displayed in GCS, so create a zip archive # and put it under reports directory to get it uploaded as an artifact. diff --git a/tools/internal_ci/linux/grpc_flaky_network.cfg b/tools/internal_ci/linux/grpc_flaky_network.cfg new file mode 100644 index 00000000000..07bedd79f94 --- /dev/null +++ b/tools/internal_ci/linux/grpc_flaky_network.cfg @@ -0,0 +1,23 @@ +# Copyright 2019 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. +# 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. + +# 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_bazel_privileged_docker.sh" +timeout_mins: 240 +env_vars { + key: "BAZEL_SCRIPT" + value: "tools/internal_ci/linux/grpc_flaky_network_in_docker.sh" +} diff --git a/tools/internal_ci/linux/grpc_flaky_network_in_docker.sh b/tools/internal_ci/linux/grpc_flaky_network_in_docker.sh new file mode 100755 index 00000000000..7fc8f146727 --- /dev/null +++ b/tools/internal_ci/linux/grpc_flaky_network_in_docker.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash +# Copyright 2019 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. +# 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. +# +# Run the flaky network test +# +# NOTE: No empty lines should appear in this file before igncr is set! +set -ex -o igncr || set -ex + +mkdir -p /var/local/git +git clone /var/local/jenkins/grpc /var/local/git/grpc +(cd /var/local/jenkins/grpc/ && git submodule foreach 'cd /var/local/git/grpc \ +&& git submodule update --init --reference /var/local/jenkins/grpc/${name} \ +${name}') +cd /var/local/git/grpc/test/cpp/end2end + +# iptables is used to drop traffic between client and server +apt-get install -y iptables + +bazel test --spawn_strategy=standalone --genrule_strategy=standalone --test_output=all :flaky_network_test --test_env=GRPC_VERBOSITY=debug --test_env=GRPC_TRACE=channel,client_channel,call_error,connectivity_state,tcp diff --git a/tools/internal_ci/linux/grpc_interop_matrix.sh b/tools/internal_ci/linux/grpc_interop_matrix.sh index a5220ea087f..5f1f69db952 100755 --- a/tools/internal_ci/linux/grpc_interop_matrix.sh +++ b/tools/internal_ci/linux/grpc_interop_matrix.sh @@ -22,4 +22,15 @@ cd $(dirname $0)/../../.. source tools/internal_ci/helper_scripts/prepare_build_linux_rc -tools/interop_matrix/run_interop_matrix_tests.py $RUN_TESTS_FLAGS +# TODO(jtattermusch): Diagnose out of disk space problems. Remove once not needed. +df -h + +tools/interop_matrix/run_interop_matrix_tests.py $RUN_TESTS_FLAGS || FAILED="true" + +# TODO(jtattermusch): Diagnose out of disk space problems. Remove once not needed. +df -h + +if [ "$FAILED" != "" ] +then + exit 1 +fi diff --git a/tools/internal_ci/linux/grpc_publish_packages.cfg b/tools/internal_ci/linux/grpc_publish_packages.cfg index dc9fe7d0a7a..54e03a94b60 100644 --- a/tools/internal_ci/linux/grpc_publish_packages.cfg +++ b/tools/internal_ci/linux/grpc_publish_packages.cfg @@ -24,3 +24,5 @@ action { regex: "github/grpc/artifacts/**" } } + +gfile_resources: "/bigstore/grpc-testing-secrets/nuget_credentials/artifactory_grpc_nuget_dev_api_key" diff --git a/tools/internal_ci/linux/grpc_publish_packages.sh b/tools/internal_ci/linux/grpc_publish_packages.sh index 14492301cc9..87684214d84 100755 --- a/tools/internal_ci/linux/grpc_publish_packages.sh +++ b/tools/internal_ci/linux/grpc_publish_packages.sh @@ -233,3 +233,16 @@ gsutil -m cp -r "$LOCAL_STAGING_TEMPDIR/${BUILD_RELPATH%%/*}" "$GCS_ARCHIVE_ROOT ) # Upload the new /index.xml gsutil -h "Content-Type:application/xml" cp "$NEW_INDEX" "$GCS_INDEX" + +# Upload C# nugets to the dev nuget feed +pushd "$UNZIPPED_CSHARP_PACKAGES" +docker pull mcr.microsoft.com/dotnet/core/sdk:2.1 +for nugetfile in *.nupkg +do + echo "Going to push $nugetfile" + # use nuget from a docker container to push the nupkg + set +x # IMPORTANT: avoid revealing the nuget api key by the command echo + docker run -v "$(pwd):/nugets:ro" --rm=true mcr.microsoft.com/dotnet/core/sdk:2.1 bash -c "dotnet nuget push /nugets/$nugetfile -k $(cat ${KOKORO_GFILE_DIR}/artifactory_grpc_nuget_dev_api_key) --source https://grpc.jfrog.io/grpc/api/nuget/v3/grpc-nuget-dev" + set -ex +done +popd diff --git a/tools/internal_ci/linux/grpc_python_bazel_test_in_docker.sh b/tools/internal_ci/linux/grpc_python_bazel_test_in_docker.sh index 156d65955ad..d844cff7f9a 100755 --- a/tools/internal_ci/linux/grpc_python_bazel_test_in_docker.sh +++ b/tools/internal_ci/linux/grpc_python_bazel_test_in_docker.sh @@ -25,3 +25,7 @@ git clone /var/local/jenkins/grpc /var/local/git/grpc ${name}') cd /var/local/git/grpc/test bazel test --spawn_strategy=standalone --genrule_strategy=standalone --test_output=errors //src/python/... +bazel test --spawn_strategy=standalone --genrule_strategy=standalone --test_output=errors //examples/python/... +bazel clean --expunge +bazel test --config=python3 --spawn_strategy=standalone --genrule_strategy=standalone --test_output=errors //src/python/... +bazel test --config=python3 --spawn_strategy=standalone --genrule_strategy=standalone --test_output=errors //examples/python/... diff --git a/tools/internal_ci/linux/grpc_run_tests_matrix.sh b/tools/internal_ci/linux/grpc_run_tests_matrix.sh index 4e7515227bd..f9acd814ae8 100755 --- a/tools/internal_ci/linux/grpc_run_tests_matrix.sh +++ b/tools/internal_ci/linux/grpc_run_tests_matrix.sh @@ -22,6 +22,7 @@ source tools/internal_ci/helper_scripts/prepare_build_linux_rc # If this is a PR using RUN_TESTS_FLAGS var, then add flags to filter tests if [ -n "$KOKORO_GITHUB_PULL_REQUEST_NUMBER" ] && [ -n "$RUN_TESTS_FLAGS" ]; then + sudo apt-get update sudo apt-get install -y jq ghprbTargetBranch=$(curl -s https://api.github.com/repos/grpc/grpc/pulls/$KOKORO_GITHUB_PULL_REQUEST_NUMBER | jq -r .base.ref) export RUN_TESTS_FLAGS="$RUN_TESTS_FLAGS --filter_pr_tests --base_branch origin/$ghprbTargetBranch" diff --git a/tools/internal_ci/linux/pull_request/grpc_basictests_c_cpp_opt.cfg b/tools/internal_ci/linux/pull_request/grpc_basictests_csharp.cfg similarity index 85% rename from tools/internal_ci/linux/pull_request/grpc_basictests_c_cpp_opt.cfg rename to tools/internal_ci/linux/pull_request/grpc_basictests_csharp.cfg index a681978b6e2..6a7029d9f83 100644 --- a/tools/internal_ci/linux/pull_request/grpc_basictests_c_cpp_opt.cfg +++ b/tools/internal_ci/linux/pull_request/grpc_basictests_csharp.cfg @@ -1,4 +1,4 @@ -# Copyright 2017 gRPC authors. +# Copyright 2019 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. @@ -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: 240 +timeout_mins: 60 action { define_artifacts { regex: "**/*sponge_log.*" @@ -26,5 +26,5 @@ action { env_vars { key: "RUN_TESTS_FLAGS" - value: "-f basictests linux corelang opt --inner_jobs 16 -j 1 --internal_ci --max_time=3600" + value: "-f basictests linux csharp --inner_jobs 16 -j 2 --internal_ci --max_time=3600" } diff --git a/tools/internal_ci/linux/pull_request/grpc_basictests_c_cpp_dbg.cfg b/tools/internal_ci/linux/pull_request/grpc_basictests_node.cfg similarity index 85% rename from tools/internal_ci/linux/pull_request/grpc_basictests_c_cpp_dbg.cfg rename to tools/internal_ci/linux/pull_request/grpc_basictests_node.cfg index 8a67d28ce4c..a0c67cc136c 100644 --- a/tools/internal_ci/linux/pull_request/grpc_basictests_c_cpp_dbg.cfg +++ b/tools/internal_ci/linux/pull_request/grpc_basictests_node.cfg @@ -1,4 +1,4 @@ -# Copyright 2017 gRPC authors. +# Copyright 2019 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. @@ -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: 240 +timeout_mins: 60 action { define_artifacts { regex: "**/*sponge_log.*" @@ -26,5 +26,5 @@ action { env_vars { key: "RUN_TESTS_FLAGS" - value: "-f basictests linux corelang dbg --inner_jobs 16 -j 1 --internal_ci --max_time=3600" + value: "-f basictests linux grpc-node --inner_jobs 16 -j 2 --internal_ci --max_time=3600" } diff --git a/tools/internal_ci/linux/pull_request/grpc_basictests_php.cfg b/tools/internal_ci/linux/pull_request/grpc_basictests_php.cfg new file mode 100644 index 00000000000..c844fcfae00 --- /dev/null +++ b/tools/internal_ci/linux/pull_request/grpc_basictests_php.cfg @@ -0,0 +1,30 @@ +# Copyright 2019 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. +# 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. + +# 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: 60 +action { + define_artifacts { + regex: "**/*sponge_log.*" + regex: "github/grpc/reports/**" + } +} + +env_vars { + key: "RUN_TESTS_FLAGS" + value: "-f basictests linux php --inner_jobs 16 -j 2 --internal_ci --max_time=3600" +} diff --git a/tools/internal_ci/linux/pull_request/grpc_basictests_python.cfg b/tools/internal_ci/linux/pull_request/grpc_basictests_python.cfg new file mode 100644 index 00000000000..b4e91c2a7e2 --- /dev/null +++ b/tools/internal_ci/linux/pull_request/grpc_basictests_python.cfg @@ -0,0 +1,30 @@ +# Copyright 2019 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. +# 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. + +# 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: 60 +action { + define_artifacts { + regex: "**/*sponge_log.*" + regex: "github/grpc/reports/**" + } +} + +env_vars { + key: "RUN_TESTS_FLAGS" + value: "-f basictests linux python --inner_jobs 16 -j 2 --internal_ci --max_time=3600" +} diff --git a/tools/internal_ci/linux/pull_request/grpc_basictests_ruby.cfg b/tools/internal_ci/linux/pull_request/grpc_basictests_ruby.cfg new file mode 100644 index 00000000000..49d3dad592e --- /dev/null +++ b/tools/internal_ci/linux/pull_request/grpc_basictests_ruby.cfg @@ -0,0 +1,30 @@ +# Copyright 2019 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. +# 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. + +# 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: 60 +action { + define_artifacts { + regex: "**/*sponge_log.*" + regex: "github/grpc/reports/**" + } +} + +env_vars { + key: "RUN_TESTS_FLAGS" + value: "-f basictests linux ruby --inner_jobs 16 -j 2 --internal_ci --max_time=3600" +} 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 index f1e6588517e..6cf7a881c70 100644 --- 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 @@ -15,5 +15,5 @@ set -ex -EXTRA_FLAGS="--config=dbg --test_timeout=300,450,1200,3600" +EXTRA_FLAGS="--config=dbg" 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 index 77744de49fa..76df0b245e5 100644 --- 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 @@ -15,5 +15,5 @@ set -ex -EXTRA_FLAGS="--config=opt --test_timeout=300,450,1200,3600" +EXTRA_FLAGS="--config=opt" 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_rbe_asan.cfg b/tools/internal_ci/linux/pull_request/grpc_bazel_rbe_asan.cfg new file mode 100644 index 00000000000..f978c730b7c --- /dev/null +++ b/tools/internal_ci/linux/pull_request/grpc_bazel_rbe_asan.cfg @@ -0,0 +1,30 @@ +# Copyright 2019 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. +# 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. + +# 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/pull_request/grpc_asan_on_foundry.sh" +timeout_mins: 60 + +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0eeee2db331.json" +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/resultstore_api_key" + +bazel_setting { + # In order for Kokoro to recognize this as a bazel build and publish the bazel resultstore link, + # the bazel_setting section needs to be present and "upsalite_frontend_address" needs to be + # set. The rest of configuration from bazel_setting is unused (we configure everything when bazel + # command is invoked). + upsalite_frontend_address: "https://source.cloud.google.com" +} diff --git a/tools/internal_ci/linux/pull_request/grpc_bazel_rbe_dbg.cfg b/tools/internal_ci/linux/pull_request/grpc_bazel_rbe_dbg.cfg new file mode 100644 index 00000000000..ab47a30b247 --- /dev/null +++ b/tools/internal_ci/linux/pull_request/grpc_bazel_rbe_dbg.cfg @@ -0,0 +1,30 @@ +# Copyright 2019 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. +# 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. + +# 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/pull_request/grpc_bazel_on_foundry_dbg.sh" +timeout_mins: 60 + +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0eeee2db331.json" +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/resultstore_api_key" + +bazel_setting { + # In order for Kokoro to recognize this as a bazel build and publish the bazel resultstore link, + # the bazel_setting section needs to be present and "upsalite_frontend_address" needs to be + # set. The rest of configuration from bazel_setting is unused (we configure everything when bazel + # command is invoked). + upsalite_frontend_address: "https://source.cloud.google.com" +} \ No newline at end of file diff --git a/tools/internal_ci/linux/pull_request/grpc_bazel_rbe_msan.cfg b/tools/internal_ci/linux/pull_request/grpc_bazel_rbe_msan.cfg new file mode 100644 index 00000000000..24b19f23e62 --- /dev/null +++ b/tools/internal_ci/linux/pull_request/grpc_bazel_rbe_msan.cfg @@ -0,0 +1,30 @@ +# Copyright 2019 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. +# 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. + +# 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/pull_request/grpc_msan_on_foundry.sh" +timeout_mins: 60 + +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0eeee2db331.json" +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/resultstore_api_key" + +bazel_setting { + # In order for Kokoro to recognize this as a bazel build and publish the bazel resultstore link, + # the bazel_setting section needs to be present and "upsalite_frontend_address" needs to be + # set. The rest of configuration from bazel_setting is unused (we configure everything when bazel + # command is invoked). + upsalite_frontend_address: "https://source.cloud.google.com" +} diff --git a/tools/internal_ci/linux/pull_request/grpc_bazel_rbe_opt.cfg b/tools/internal_ci/linux/pull_request/grpc_bazel_rbe_opt.cfg new file mode 100644 index 00000000000..65395f0bf6f --- /dev/null +++ b/tools/internal_ci/linux/pull_request/grpc_bazel_rbe_opt.cfg @@ -0,0 +1,30 @@ +# Copyright 2019 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. +# 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. + +# 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/pull_request/grpc_bazel_on_foundry_opt.sh" +timeout_mins: 60 + +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0eeee2db331.json" +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/resultstore_api_key" + +bazel_setting { + # In order for Kokoro to recognize this as a bazel build and publish the bazel resultstore link, + # the bazel_setting section needs to be present and "upsalite_frontend_address" needs to be + # set. The rest of configuration from bazel_setting is unused (we configure everything when bazel + # command is invoked). + upsalite_frontend_address: "https://source.cloud.google.com" +} \ No newline at end of file diff --git a/tools/internal_ci/linux/pull_request/grpc_bazel_rbe_tsan.cfg b/tools/internal_ci/linux/pull_request/grpc_bazel_rbe_tsan.cfg new file mode 100644 index 00000000000..cf65606f3cd --- /dev/null +++ b/tools/internal_ci/linux/pull_request/grpc_bazel_rbe_tsan.cfg @@ -0,0 +1,30 @@ +# Copyright 2019 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. +# 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. + +# 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/pull_request/grpc_tsan_on_foundry.sh" +timeout_mins: 60 + +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0eeee2db331.json" +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/resultstore_api_key" + +bazel_setting { + # In order for Kokoro to recognize this as a bazel build and publish the bazel resultstore link, + # the bazel_setting section needs to be present and "upsalite_frontend_address" needs to be + # set. The rest of configuration from bazel_setting is unused (we configure everything when bazel + # command is invoked). + upsalite_frontend_address: "https://source.cloud.google.com" +} diff --git a/tools/internal_ci/linux/pull_request/grpc_bazel_rbe_ubsan.cfg b/tools/internal_ci/linux/pull_request/grpc_bazel_rbe_ubsan.cfg new file mode 100644 index 00000000000..a943b89509d --- /dev/null +++ b/tools/internal_ci/linux/pull_request/grpc_bazel_rbe_ubsan.cfg @@ -0,0 +1,30 @@ +# Copyright 2019 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. +# 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. + +# 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/pull_request/grpc_ubsan_on_foundry.sh" +timeout_mins: 60 + +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0eeee2db331.json" +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/resultstore_api_key" + +bazel_setting { + # In order for Kokoro to recognize this as a bazel build and publish the bazel resultstore link, + # the bazel_setting section needs to be present and "upsalite_frontend_address" needs to be + # set. The rest of configuration from bazel_setting is unused (we configure everything when bazel + # command is invoked). + upsalite_frontend_address: "https://source.cloud.google.com" +} diff --git a/tools/internal_ci/linux/pull_request/grpc_microbenchmark_diff.cfg b/tools/internal_ci/linux/pull_request/grpc_microbenchmark_diff.cfg index 47301d61415..3c62401cc3a 100644 --- a/tools/internal_ci/linux/pull_request/grpc_microbenchmark_diff.cfg +++ b/tools/internal_ci/linux/pull_request/grpc_microbenchmark_diff.cfg @@ -17,6 +17,14 @@ # Location of the continuous shell script in repository. build_file: "grpc/tools/internal_ci/linux/grpc_microbenchmark_diff.sh" timeout_mins: 120 +before_action { + fetch_keystore { + keystore_resource { + keystore_config_id: 73836 + keyname: "grpc_checks_private_key" + } + } +} action { define_artifacts { regex: "**/*sponge_log.*" diff --git a/tools/internal_ci/linux/pull_request/grpc_trickle_diff.cfg b/tools/internal_ci/linux/pull_request/grpc_trickle_diff.cfg index 78358eac28e..69e44276625 100644 --- a/tools/internal_ci/linux/pull_request/grpc_trickle_diff.cfg +++ b/tools/internal_ci/linux/pull_request/grpc_trickle_diff.cfg @@ -17,6 +17,14 @@ # Location of the continuous shell script in repository. build_file: "grpc/tools/internal_ci/linux/grpc_trickle_diff.sh" timeout_mins: 120 +before_action { + fetch_keystore { + keystore_resource { + keystore_config_id: 73836 + keyname: "grpc_checks_private_key" + } + } +} action { define_artifacts { regex: "**/*sponge_log.*" diff --git a/tools/internal_ci/macos/grpc_basictests_c_cpp.cfg b/tools/internal_ci/macos/grpc_basictests_c_cpp.cfg new file mode 100644 index 00000000000..f16e3e8ee68 --- /dev/null +++ b/tools/internal_ci/macos/grpc_basictests_c_cpp.cfg @@ -0,0 +1,31 @@ +# Copyright 2019 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. +# 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. + +# Config file for the internal CI (in protobuf text format) + +# Location of the continuous shell script in repository. +build_file: "grpc/tools/internal_ci/macos/grpc_run_tests_matrix.sh" +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0eeee2db331.json" +timeout_mins: 120 +action { + define_artifacts { + regex: "**/*sponge_log.*" + regex: "github/grpc/reports/**" + } +} + +env_vars { + key: "RUN_TESTS_FLAGS" + value: "-f basictests macos corelang --internal_ci -j 1 --inner_jobs 4 --bq_result_table aggregate_results" +} diff --git a/tools/internal_ci/macos/grpc_basictests_csharp.cfg b/tools/internal_ci/macos/grpc_basictests_csharp.cfg new file mode 100644 index 00000000000..d3e04e71f71 --- /dev/null +++ b/tools/internal_ci/macos/grpc_basictests_csharp.cfg @@ -0,0 +1,31 @@ +# Copyright 2019 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. +# 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. + +# Config file for the internal CI (in protobuf text format) + +# Location of the continuous shell script in repository. +build_file: "grpc/tools/internal_ci/macos/grpc_run_tests_matrix.sh" +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0eeee2db331.json" +timeout_mins: 60 +action { + define_artifacts { + regex: "**/*sponge_log.*" + regex: "github/grpc/reports/**" + } +} + +env_vars { + key: "RUN_TESTS_FLAGS" + value: "-f basictests macos csharp --internal_ci -j 1 --inner_jobs 4 --bq_result_table aggregate_results" +} diff --git a/tools/internal_ci/macos/grpc_basictests_node.cfg b/tools/internal_ci/macos/grpc_basictests_node.cfg new file mode 100644 index 00000000000..9dfd6a7b9e8 --- /dev/null +++ b/tools/internal_ci/macos/grpc_basictests_node.cfg @@ -0,0 +1,31 @@ +# Copyright 2019 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. +# 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. + +# Config file for the internal CI (in protobuf text format) + +# Location of the continuous shell script in repository. +build_file: "grpc/tools/internal_ci/macos/grpc_run_tests_matrix.sh" +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0eeee2db331.json" +timeout_mins: 60 +action { + define_artifacts { + regex: "**/*sponge_log.*" + regex: "github/grpc/reports/**" + } +} + +env_vars { + key: "RUN_TESTS_FLAGS" + value: "-f basictests macos grpc-node --internal_ci -j 1 --inner_jobs 4 --bq_result_table aggregate_results" +} diff --git a/tools/internal_ci/macos/grpc_basictests_php.cfg b/tools/internal_ci/macos/grpc_basictests_php.cfg new file mode 100644 index 00000000000..091f68efaba --- /dev/null +++ b/tools/internal_ci/macos/grpc_basictests_php.cfg @@ -0,0 +1,31 @@ +# Copyright 2019 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. +# 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. + +# Config file for the internal CI (in protobuf text format) + +# Location of the continuous shell script in repository. +build_file: "grpc/tools/internal_ci/macos/grpc_run_tests_matrix.sh" +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0eeee2db331.json" +timeout_mins: 60 +action { + define_artifacts { + regex: "**/*sponge_log.*" + regex: "github/grpc/reports/**" + } +} + +env_vars { + key: "RUN_TESTS_FLAGS" + value: "-f basictests macos php --internal_ci -j 1 --inner_jobs 4 --bq_result_table aggregate_results" +} diff --git a/tools/internal_ci/macos/grpc_basictests_python.cfg b/tools/internal_ci/macos/grpc_basictests_python.cfg new file mode 100644 index 00000000000..ae80ac317ff --- /dev/null +++ b/tools/internal_ci/macos/grpc_basictests_python.cfg @@ -0,0 +1,31 @@ +# Copyright 2019 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. +# 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. + +# Config file for the internal CI (in protobuf text format) + +# Location of the continuous shell script in repository. +build_file: "grpc/tools/internal_ci/macos/grpc_run_tests_matrix.sh" +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0eeee2db331.json" +timeout_mins: 60 +action { + define_artifacts { + regex: "**/*sponge_log.*" + regex: "github/grpc/reports/**" + } +} + +env_vars { + key: "RUN_TESTS_FLAGS" + value: "-f basictests macos python --internal_ci -j 1 --inner_jobs 4 --bq_result_table aggregate_results" +} diff --git a/tools/internal_ci/macos/grpc_basictests_ruby.cfg b/tools/internal_ci/macos/grpc_basictests_ruby.cfg new file mode 100644 index 00000000000..3a28f97a54b --- /dev/null +++ b/tools/internal_ci/macos/grpc_basictests_ruby.cfg @@ -0,0 +1,31 @@ +# Copyright 2019 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. +# 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. + +# Config file for the internal CI (in protobuf text format) + +# Location of the continuous shell script in repository. +build_file: "grpc/tools/internal_ci/macos/grpc_run_tests_matrix.sh" +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0eeee2db331.json" +timeout_mins: 60 +action { + define_artifacts { + regex: "**/*sponge_log.*" + regex: "github/grpc/reports/**" + } +} + +env_vars { + key: "RUN_TESTS_FLAGS" + value: "-f basictests macos ruby --internal_ci -j 1 --inner_jobs 4 --bq_result_table aggregate_results" +} diff --git a/tools/internal_ci/macos/grpc_cfstream.cfg b/tools/internal_ci/macos/grpc_cfstream.cfg new file mode 100644 index 00000000000..2b1ce0a89c7 --- /dev/null +++ b/tools/internal_ci/macos/grpc_cfstream.cfg @@ -0,0 +1,19 @@ +# Copyright 2019 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. +# 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. + +# Config file for the internal CI (in protobuf text format) + +# Location of the continuous shell script in repository. +build_file: "grpc/tools/internal_ci/macos/grpc_run_bazel_tests.sh" + diff --git a/tools/internal_ci/macos/grpc_interop_toprod.sh b/tools/internal_ci/macos/grpc_interop_toprod.sh index e748a62e761..654da373a26 100755 --- a/tools/internal_ci/macos/grpc_interop_toprod.sh +++ b/tools/internal_ci/macos/grpc_interop_toprod.sh @@ -30,7 +30,9 @@ export GRPC_DEFAULT_SSL_ROOTS_FILE_PATH="$(pwd)/etc/roots.pem" # 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 \ + --cloud_to_prod --cloud_to_prod_auth \ + --google_default_creds_use_key_file \ + --prod_servers default gateway_v4 \ --service_account_key_file="${KOKORO_GFILE_DIR}/GrpcTesting-726eb1347f15.json" \ --skip_compute_engine_creds --internal_ci -t -j 4 || FAILED="true" diff --git a/tools/internal_ci/macos/grpc_run_bazel_tests.sh b/tools/internal_ci/macos/grpc_run_bazel_tests.sh new file mode 100644 index 00000000000..56fae8fd75f --- /dev/null +++ b/tools/internal_ci/macos/grpc_run_bazel_tests.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env bash +# Copyright 2019 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. +# 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)/../../.. + +# Download bazel +temp_dir="$(mktemp -d)" +wget -q https://github.com/bazelbuild/bazel/releases/download/0.23.2/bazel-0.23.2-darwin-x86_64 -O "${temp_dir}/bazel" +chmod 755 "${temp_dir}/bazel" +export PATH="${temp_dir}:${PATH}" +# This should show ${temp_dir}/bazel +which bazel + +./tools/run_tests/start_port_server.py + +# run cfstream_test separately because it messes with the network +bazel test --spawn_strategy=standalone --genrule_strategy=standalone --test_output=all //test/cpp/end2end:cfstream_test + +# kill port_server.py to prevent the build from hanging +ps aux | grep port_server\\.py | awk '{print $2}' | xargs kill -9 + diff --git a/tools/internal_ci/macos/pull_request/grpc_basictests_c_cpp.cfg b/tools/internal_ci/macos/pull_request/grpc_basictests_c_cpp.cfg new file mode 100644 index 00000000000..00f402d389b --- /dev/null +++ b/tools/internal_ci/macos/pull_request/grpc_basictests_c_cpp.cfg @@ -0,0 +1,31 @@ +# Copyright 2019 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. +# 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. + +# Config file for the internal CI (in protobuf text format) + +# Location of the continuous shell script in repository. +build_file: "grpc/tools/internal_ci/macos/grpc_run_tests_matrix.sh" +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0eeee2db331.json" +timeout_mins: 120 +action { + define_artifacts { + regex: "**/*sponge_log.*" + regex: "github/grpc/reports/**" + } +} + +env_vars { + key: "RUN_TESTS_FLAGS" + value: "-f basictests macos corelang --internal_ci -j 1 --inner_jobs 4 --max_time=3600" +} diff --git a/tools/internal_ci/macos/pull_request/grpc_basictests_csharp.cfg b/tools/internal_ci/macos/pull_request/grpc_basictests_csharp.cfg new file mode 100644 index 00000000000..c9c1403693c --- /dev/null +++ b/tools/internal_ci/macos/pull_request/grpc_basictests_csharp.cfg @@ -0,0 +1,31 @@ +# Copyright 2019 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. +# 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. + +# Config file for the internal CI (in protobuf text format) + +# Location of the continuous shell script in repository. +build_file: "grpc/tools/internal_ci/macos/grpc_run_tests_matrix.sh" +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0eeee2db331.json" +timeout_mins: 60 +action { + define_artifacts { + regex: "**/*sponge_log.*" + regex: "github/grpc/reports/**" + } +} + +env_vars { + key: "RUN_TESTS_FLAGS" + value: "-f basictests macos csharp --internal_ci -j 1 --inner_jobs 4 --max_time=3600" +} diff --git a/tools/internal_ci/macos/pull_request/grpc_basictests_node.cfg b/tools/internal_ci/macos/pull_request/grpc_basictests_node.cfg new file mode 100644 index 00000000000..ed729ef5a91 --- /dev/null +++ b/tools/internal_ci/macos/pull_request/grpc_basictests_node.cfg @@ -0,0 +1,31 @@ +# Copyright 2019 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. +# 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. + +# Config file for the internal CI (in protobuf text format) + +# Location of the continuous shell script in repository. +build_file: "grpc/tools/internal_ci/macos/grpc_run_tests_matrix.sh" +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0eeee2db331.json" +timeout_mins: 60 +action { + define_artifacts { + regex: "**/*sponge_log.*" + regex: "github/grpc/reports/**" + } +} + +env_vars { + key: "RUN_TESTS_FLAGS" + value: "-f basictests macos grpc-node --internal_ci -j 1 --inner_jobs 4 --max_time=3600" +} diff --git a/tools/internal_ci/macos/pull_request/grpc_basictests_php.cfg b/tools/internal_ci/macos/pull_request/grpc_basictests_php.cfg new file mode 100644 index 00000000000..11b17874c28 --- /dev/null +++ b/tools/internal_ci/macos/pull_request/grpc_basictests_php.cfg @@ -0,0 +1,31 @@ +# Copyright 2019 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. +# 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. + +# Config file for the internal CI (in protobuf text format) + +# Location of the continuous shell script in repository. +build_file: "grpc/tools/internal_ci/macos/grpc_run_tests_matrix.sh" +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0eeee2db331.json" +timeout_mins: 60 +action { + define_artifacts { + regex: "**/*sponge_log.*" + regex: "github/grpc/reports/**" + } +} + +env_vars { + key: "RUN_TESTS_FLAGS" + value: "-f basictests macos php --internal_ci -j 1 --inner_jobs 4 --max_time=3600" +} diff --git a/tools/internal_ci/macos/pull_request/grpc_basictests_python.cfg b/tools/internal_ci/macos/pull_request/grpc_basictests_python.cfg new file mode 100644 index 00000000000..c86871f80cb --- /dev/null +++ b/tools/internal_ci/macos/pull_request/grpc_basictests_python.cfg @@ -0,0 +1,31 @@ +# Copyright 2019 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. +# 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. + +# Config file for the internal CI (in protobuf text format) + +# Location of the continuous shell script in repository. +build_file: "grpc/tools/internal_ci/macos/grpc_run_tests_matrix.sh" +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0eeee2db331.json" +timeout_mins: 60 +action { + define_artifacts { + regex: "**/*sponge_log.*" + regex: "github/grpc/reports/**" + } +} + +env_vars { + key: "RUN_TESTS_FLAGS" + value: "-f basictests macos python --internal_ci -j 1 --inner_jobs 4 --max_time=3600" +} diff --git a/tools/internal_ci/macos/pull_request/grpc_basictests_ruby.cfg b/tools/internal_ci/macos/pull_request/grpc_basictests_ruby.cfg new file mode 100644 index 00000000000..5729bf8f751 --- /dev/null +++ b/tools/internal_ci/macos/pull_request/grpc_basictests_ruby.cfg @@ -0,0 +1,31 @@ +# Copyright 2019 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. +# 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. + +# Config file for the internal CI (in protobuf text format) + +# Location of the continuous shell script in repository. +build_file: "grpc/tools/internal_ci/macos/grpc_run_tests_matrix.sh" +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0eeee2db331.json" +timeout_mins: 60 +action { + define_artifacts { + regex: "**/*sponge_log.*" + regex: "github/grpc/reports/**" + } +} + +env_vars { + key: "RUN_TESTS_FLAGS" + value: "-f basictests macos ruby --internal_ci -j 1 --inner_jobs 4 --max_time=3600" +} diff --git a/tools/internal_ci/macos/pull_request/grpc_ios_binary_size.cfg b/tools/internal_ci/macos/pull_request/grpc_ios_binary_size.cfg index fb215bdf994..f639b4ef77c 100644 --- a/tools/internal_ci/macos/pull_request/grpc_ios_binary_size.cfg +++ b/tools/internal_ci/macos/pull_request/grpc_ios_binary_size.cfg @@ -16,8 +16,15 @@ # Location of the continuous shell script in repository. build_file: "grpc/tools/internal_ci/macos/grpc_ios_binary_size.sh" -timeout_mins: 60 -gfile_resources: "/bigstore/grpc-testing-secrets/github_credentials/oauth_token.txt" +timeout_mins: 90 +before_action { + fetch_keystore { + keystore_resource { + keystore_config_id: 73836 + keyname: "grpc_checks_private_key" + } + } +} action { define_artifacts { regex: "**/*sponge_log.*" diff --git a/tools/internal_ci/windows/bazel_rbe.bat b/tools/internal_ci/windows/bazel_rbe.bat new file mode 100644 index 00000000000..8f2c534c5ef --- /dev/null +++ b/tools/internal_ci/windows/bazel_rbe.bat @@ -0,0 +1,31 @@ +@rem Copyright 2019 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 TODO(jtattermusch): make this generate less output +choco install bazel -y --version 0.23.2 --limit-output + +cd github/grpc +set PATH=C:\tools\msys64\usr\bin;C:\Python27;%PATH% + +@rem Generate a random UUID and store in "bazel_invocation_ids" artifact file +powershell -Command "[guid]::NewGuid().ToString()" >%KOKORO_ARTIFACTS_DIR%/bazel_invocation_ids +set /p BAZEL_INVOCATION_ID=<%KOKORO_ARTIFACTS_DIR%/bazel_invocation_ids + +@rem TODO(jtattermusch): windows RBE should be able to use the same credentials as Linux RBE. +bazel --bazelrc=tools/remote_build/windows.bazelrc build --invocation_id="%BAZEL_INVOCATION_ID%" --workspace_status_command=tools/remote_build/workspace_status_kokoro.sh :all --incompatible_disallow_filetype=false --google_credentials=%KOKORO_GFILE_DIR%/rbe-windows-credentials.json +set BAZEL_EXITCODE=%errorlevel% + +@rem TODO(jtattermusch): upload results to bigquery + +exit /b %BAZEL_EXITCODE% diff --git a/tools/internal_ci/windows/grpc_basictests_c.cfg b/tools/internal_ci/windows/grpc_basictests_c.cfg new file mode 100644 index 00000000000..223cf389d0e --- /dev/null +++ b/tools/internal_ci/windows/grpc_basictests_c.cfg @@ -0,0 +1,30 @@ +# Copyright 2019 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. +# 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. + +# Config file for the internal CI (in protobuf text format) + +# Location of the continuous shell script in repository. +build_file: "grpc/tools/internal_ci/windows/grpc_run_tests_matrix.bat" +timeout_mins: 120 +action { + define_artifacts { + regex: "**/*sponge_log.*" + regex: "github/grpc/reports/**" + } +} + +env_vars { + key: "RUN_TESTS_FLAGS" + value: "-f basictests windows c -j 1 --inner_jobs 8 --internal_ci --bq_result_table aggregate_results" +} diff --git a/tools/internal_ci/windows/grpc_basictests_csharp.cfg b/tools/internal_ci/windows/grpc_basictests_csharp.cfg new file mode 100644 index 00000000000..17a362fb32a --- /dev/null +++ b/tools/internal_ci/windows/grpc_basictests_csharp.cfg @@ -0,0 +1,30 @@ +# Copyright 2019 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. +# 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. + +# Config file for the internal CI (in protobuf text format) + +# Location of the continuous shell script in repository. +build_file: "grpc/tools/internal_ci/windows/grpc_run_tests_matrix.bat" +timeout_mins: 60 +action { + define_artifacts { + regex: "**/*sponge_log.*" + regex: "github/grpc/reports/**" + } +} + +env_vars { + key: "RUN_TESTS_FLAGS" + value: "-f basictests windows csharp -j 1 --inner_jobs 8 --internal_ci --bq_result_table aggregate_results" +} diff --git a/tools/internal_ci/windows/grpc_basictests_python.cfg b/tools/internal_ci/windows/grpc_basictests_python.cfg new file mode 100644 index 00000000000..b0f6f6772d3 --- /dev/null +++ b/tools/internal_ci/windows/grpc_basictests_python.cfg @@ -0,0 +1,30 @@ +# Copyright 2019 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. +# 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. + +# Config file for the internal CI (in protobuf text format) + +# Location of the continuous shell script in repository. +build_file: "grpc/tools/internal_ci/windows/grpc_run_tests_matrix.bat" +timeout_mins: 60 +action { + define_artifacts { + regex: "**/*sponge_log.*" + regex: "github/grpc/reports/**" + } +} + +env_vars { + key: "RUN_TESTS_FLAGS" + value: "-f basictests windows python -j 1 --inner_jobs 8 --internal_ci --bq_result_table aggregate_results" +} diff --git a/tools/internal_ci/windows/grpc_bazel_rbe_dbg.cfg b/tools/internal_ci/windows/grpc_bazel_rbe_dbg.cfg new file mode 100644 index 00000000000..f958fed33dd --- /dev/null +++ b/tools/internal_ci/windows/grpc_bazel_rbe_dbg.cfg @@ -0,0 +1,32 @@ +# Copyright 2019 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. +# 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. + +# Config file for the internal CI (in protobuf text format) + +# Location of the continuous shell script in repository. +build_file: "grpc/tools/internal_ci/windows/bazel_rbe.bat" + +timeout_mins: 60 + +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0eeee2db331.json" +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/resultstore_api_key" +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/rbe-windows-credentials.json" + +bazel_setting { + # In order for Kokoro to recognize this as a bazel build and publish the bazel resultstore link, + # the bazel_setting section needs to be present and "upsalite_frontend_address" needs to be + # set. The rest of configuration from bazel_setting is unused (we configure everything when bazel + # command is invoked). + upsalite_frontend_address: "https://source.cloud.google.com" +} diff --git a/tools/internal_ci/windows/pull_request/grpc_basictests_c.cfg b/tools/internal_ci/windows/pull_request/grpc_basictests_c.cfg new file mode 100644 index 00000000000..4cedcae9a87 --- /dev/null +++ b/tools/internal_ci/windows/pull_request/grpc_basictests_c.cfg @@ -0,0 +1,30 @@ +# Copyright 2019 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. +# 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. + +# Config file for the internal CI (in protobuf text format) + +# Location of the continuous shell script in repository. +build_file: "grpc/tools/internal_ci/windows/grpc_run_tests_matrix.bat" +timeout_mins: 120 +action { + define_artifacts { + regex: "**/*sponge_log.*" + regex: "github/grpc/reports/**" + } +} + +env_vars { + key: "RUN_TESTS_FLAGS" + value: "-f basictests windows c -j 1 --inner_jobs 8 --internal_ci --max_time=3600" +} diff --git a/tools/internal_ci/windows/pull_request/grpc_basictests_csharp.cfg b/tools/internal_ci/windows/pull_request/grpc_basictests_csharp.cfg new file mode 100644 index 00000000000..e1c5af108ec --- /dev/null +++ b/tools/internal_ci/windows/pull_request/grpc_basictests_csharp.cfg @@ -0,0 +1,30 @@ +# Copyright 2019 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. +# 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. + +# Config file for the internal CI (in protobuf text format) + +# Location of the continuous shell script in repository. +build_file: "grpc/tools/internal_ci/windows/grpc_run_tests_matrix.bat" +timeout_mins: 60 +action { + define_artifacts { + regex: "**/*sponge_log.*" + regex: "github/grpc/reports/**" + } +} + +env_vars { + key: "RUN_TESTS_FLAGS" + value: "-f basictests windows csharp -j 1 --inner_jobs 8 --internal_ci --max_time=3600" +} diff --git a/tools/internal_ci/windows/pull_request/grpc_basictests_python.cfg b/tools/internal_ci/windows/pull_request/grpc_basictests_python.cfg new file mode 100644 index 00000000000..6947e8e1b4e --- /dev/null +++ b/tools/internal_ci/windows/pull_request/grpc_basictests_python.cfg @@ -0,0 +1,30 @@ +# Copyright 2019 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. +# 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. + +# Config file for the internal CI (in protobuf text format) + +# Location of the continuous shell script in repository. +build_file: "grpc/tools/internal_ci/windows/grpc_run_tests_matrix.bat" +timeout_mins: 60 +action { + define_artifacts { + regex: "**/*sponge_log.*" + regex: "github/grpc/reports/**" + } +} + +env_vars { + key: "RUN_TESTS_FLAGS" + value: "-f basictests windows python -j 1 --inner_jobs 8 --internal_ci --max_time=3600" +} diff --git a/tools/internal_ci/windows/pull_request/grpc_bazel_rbe_dbg.cfg b/tools/internal_ci/windows/pull_request/grpc_bazel_rbe_dbg.cfg new file mode 100644 index 00000000000..f958fed33dd --- /dev/null +++ b/tools/internal_ci/windows/pull_request/grpc_bazel_rbe_dbg.cfg @@ -0,0 +1,32 @@ +# Copyright 2019 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. +# 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. + +# Config file for the internal CI (in protobuf text format) + +# Location of the continuous shell script in repository. +build_file: "grpc/tools/internal_ci/windows/bazel_rbe.bat" + +timeout_mins: 60 + +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0eeee2db331.json" +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/resultstore_api_key" +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/rbe-windows-credentials.json" + +bazel_setting { + # In order for Kokoro to recognize this as a bazel build and publish the bazel resultstore link, + # the bazel_setting section needs to be present and "upsalite_frontend_address" needs to be + # set. The rest of configuration from bazel_setting is unused (we configure everything when bazel + # command is invoked). + upsalite_frontend_address: "https://source.cloud.google.com" +} diff --git a/tools/interop_matrix/README.md b/tools/interop_matrix/README.md index db84d9b454c..9d5c777cdee 100644 --- a/tools/interop_matrix/README.md +++ b/tools/interop_matrix/README.md @@ -1,9 +1,9 @@ # Overview -This directory contains scripts that facilitate building and running gRPC tests for combinations of language/runtimes (known as matrix). +This directory contains scripts that facilitate building and running gRPC interoperability tests for combinations of language/runtimes (known as matrix). The setup builds gRPC docker images for each language/runtime and upload it to Google Container Registry (GCR). These images, encapsulating gRPC stack -from specific releases/tag, are used to test version compatiblity between gRPC release versions. +from specific releases/tag, are used to test version compatibility between gRPC release versions. ## Step-by-step instructions for adding a GCR image for a new release for compatibility test We have continuous nightly test setup to test gRPC backward compatibility between old clients and latest server. When a gRPC developer creates a new gRPC release, s/he is also responsible to add the just-released gRPC client to the nightly test. The steps are: @@ -11,8 +11,9 @@ We have continuous nightly test setup to test gRPC backward compatibility betwee - Build new client docker image(s). For example, for C and wrapper languages release `v1.9.9`, do - `tools/interop_matrix/create_matrix_images.py --git_checkout --release=v1.9.9 --upload_images --language cxx csharp python ruby php` - Verify that the new docker image was built successfully and uploaded to GCR. For example, - - `gcloud beta container images list --repository gcr.io/grpc-testing` shows image repos. - - `gcloud beta container images list-tags gcr.io/grpc-testing/grpc_interop_java_oracle8` should show an image entry with tag `v1.9.9`. + - `gcloud container images list --repository gcr.io/grpc-testing` lists available images. + - `gcloud container images list-tags gcr.io/grpc-testing/grpc_interop_java_oracle8` should show an image entry with tag `v1.9.9`. + - images can also be viewed in https://pantheon.corp.google.com/gcr/images/grpc-testing?project=grpc-testing - Verify the just-created docker client image would pass backward compatibility test (it should). For example, - `gcloud docker -- pull gcr.io/grpc-testing/grpc_interop_java_oracle8:v1.9.9` followed by - `docker_image=gcr.io/grpc-testing/grpc_interop_java_oracle8:v1.9.9 tools/interop_matrix/testcases/java__master` @@ -20,13 +21,11 @@ We have continuous nightly test setup to test gRPC backward compatibility betwee - (Optional) clean up the tmp directory to where grpc source is cloned at `/export/hda3/tmp/grpc_matrix/`. For more details on each step, refer to sections below. -## Instructions for adding new language/runtimes* +## Instructions for adding new language/runtimes - Create new `Dockerfile.template`, `build_interop.sh.template` for the language/runtime under `template/tools/dockerfile/`. - Run `tools/buildgen/generate_projects.sh` to create corresponding files under `tools/dockerfile/`. - Add language/runtimes to `client_matrix.py` following existing language/runtimes examples. -- Run `tools/interop_matrix/create_matrix_images.py` which will build and upload images to GCR. Unless you are also building images for a gRPC release, make sure not to set `--release` (the default release 'master' is used for testing). - -*: Please delete your docker images at https://pantheon.corp.google.com/gcr/images/grpc-testing?project=grpc-testing afterwards. Permissions to access GrpcTesting project is required for this step. +- Run `tools/interop_matrix/create_matrix_images.py` which will build (and upload) images to GCR. ## Instructions for creating new test cases - Create test cases by running `LANG= [RELEASE=] ./create_testcases.sh`. For example, @@ -39,13 +38,13 @@ For more details on each step, refer to sections below. - `--release` specifies a git release tag. Defaults to `--release=all`. Make sure the GCR images with the tag have been created using `create_matrix_images.py` above. - `--language` specifies a language. Defaults to `--language=all`. For example, To test all languages for all gRPC releases across all runtimes, do `tools/interop_matrix/run_interop_matrix_test.py --release=all`. -- The output for all the test cases is recorded in a junit style xml file (default to 'report.xml'). +- The output for all the test cases is recorded in a junit style xml file (defaults to 'report.xml'). ## Instructions for running test cases against a GCR image manually -- Download docker image from GCR. For example: `gcloud docker -- pull gcr.io/grpc-testing/grpc_interop_go1.7:master`. +- Download docker image from GCR. For example: `gcloud docker -- pull gcr.io/grpc-testing/grpc_interop_go1.8:v1.16.0`. - Run test cases by specifying `docker_image` variable inline with the test case script created above. For example: - - `docker_image=gcr.io/grpc-testing/grpc_interop_go1.7:master ./testcases/go__master` will run go__master test cases against `go1.7` with gRPC release `master` docker image in GCR. + - `docker_image=gcr.io/grpc-testing/grpc_interop_go1.8:v1.16.0 ./testcases/go__master` will run go__master test cases against `go1.8` with gRPC release `v1.16.0` docker image in GCR. Note: - File path starting with `tools/` or `template/` are relative to the grpc repo root dir. File path starting with `./` are relative to current directory (`tools/interop_matrix`). diff --git a/tools/interop_matrix/client_matrix.py b/tools/interop_matrix/client_matrix.py index ff3344cd95d..234c71295b3 100644 --- a/tools/interop_matrix/client_matrix.py +++ b/tools/interop_matrix/client_matrix.py @@ -15,6 +15,8 @@ # Defines languages, runtimes and releases for backward compatibility testing +from collections import OrderedDict + def get_github_repo(lang): return { @@ -27,15 +29,27 @@ def get_github_repo(lang): def get_release_tags(lang): - return map(lambda r: get_release_tag_name(r), LANG_RELEASE_MATRIX[lang]) + """Returns list of known releases for given language.""" + return list(LANG_RELEASE_MATRIX[lang].keys()) -def get_release_tag_name(release_info): - assert len(release_info.keys()) == 1 - return release_info.keys()[0] +def get_runtimes_for_lang_release(lang, release): + """Get list of valid runtimes for given release of lang.""" + runtimes = list(LANG_RUNTIME_MATRIX[lang]) + release_info = LANG_RELEASE_MATRIX[lang].get(release) + if release_info and release_info.runtime_subset: + runtimes = list(release_info.runtime_subset) + + # check that all selected runtimes are valid for given language + for runtime in runtimes: + assert runtime in LANG_RUNTIME_MATRIX[lang] + return runtimes def should_build_docker_interop_image_from_release_tag(lang): + # All dockerfile definitions live in grpc/grpc repository. + # For language that have a separate repo, we need to use + # dockerfile definitions from head of grpc/grpc. if lang in ['go', 'java', 'node']: return False return True @@ -44,7 +58,7 @@ def should_build_docker_interop_image_from_release_tag(lang): # Dictionary of runtimes per language LANG_RUNTIME_MATRIX = { 'cxx': ['cxx'], # This is actually debian8. - 'go': ['go1.7', 'go1.8'], + 'go': ['go1.8', 'go1.11'], 'java': ['java_oracle8'], 'python': ['python'], 'node': ['node'], @@ -53,437 +67,210 @@ LANG_RUNTIME_MATRIX = { 'csharp': ['csharp', 'csharpcoreclr'], } + +class ReleaseInfo: + """Info about a single release of a language""" + + def __init__(self, patch=[], runtime_subset=[], testcases_file=None): + self.patch = patch + self.runtime_subset = runtime_subset + self.testcases_file = testcases_file + + # Dictionary of known releases for given language. LANG_RELEASE_MATRIX = { - 'cxx': [ - { - 'v1.0.1': None - }, - { - 'v1.1.4': None - }, - { - 'v1.2.5': None - }, - { - 'v1.3.9': None - }, - { - 'v1.4.2': None - }, - { - 'v1.6.6': None - }, - { - 'v1.7.2': None - }, - { - 'v1.8.0': None - }, - { - 'v1.9.1': None - }, - { - 'v1.10.1': None - }, - { - 'v1.11.1': None - }, - { - 'v1.12.0': None - }, - { - 'v1.13.0': None - }, - { - 'v1.14.1': None - }, - { - 'v1.15.0': None - }, - { - 'v1.16.0': None - }, - ], - 'go': [ - { - 'v1.0.5': None - }, - { - 'v1.2.1': None - }, - { - 'v1.3.0': None - }, - { - 'v1.4.2': None - }, - { - 'v1.5.2': None - }, - { - 'v1.6.0': None - }, - { - 'v1.7.4': None - }, - { - 'v1.8.2': None - }, - { - 'v1.9.2': None - }, - { - 'v1.10.1': None - }, - { - 'v1.11.3': None - }, - { - 'v1.12.2': None - }, - { - 'v1.13.0': None - }, - { - 'v1.14.0': None - }, - { - 'v1.15.0': None - }, - { - 'v1.16.0': None - }, - ], - 'java': [ - { - 'v1.0.3': None - }, - { - 'v1.1.2': None - }, - { - 'v1.2.0': None - }, - { - 'v1.3.1': None - }, - { - 'v1.4.0': None - }, - { - 'v1.5.0': None - }, - { - 'v1.6.1': None - }, - { - 'v1.7.0': None - }, - { - 'v1.8.0': None - }, - { - 'v1.9.1': None - }, - { - 'v1.10.1': None - }, - { - 'v1.11.0': None - }, - { - 'v1.12.0': None - }, - { - 'v1.13.1': None - }, - { - 'v1.14.0': None - }, - { - 'v1.15.0': None - }, - { - 'v1.16.1': None - }, - ], - 'python': [ - { - 'v1.0.x': None - }, - { - 'v1.1.4': None - }, - { - 'v1.2.5': None - }, - { - 'v1.3.9': None - }, - { - 'v1.4.2': None - }, - { - 'v1.6.6': None - }, - { - 'v1.7.2': None - }, - { - 'v1.8.1': None # first python 1.8 release is 1.8.1 - }, - { - 'v1.9.1': None - }, - { - 'v1.10.1': None - }, - { - 'v1.11.1': None - }, - { - 'v1.12.0': None - }, - { - 'v1.13.0': None - }, - { - 'v1.14.1': None - }, - { - 'v1.15.0': None - }, - { - 'v1.16.0': None - }, - ], - 'node': [ - { - 'v1.0.1': None - }, - { - 'v1.1.4': None - }, - { - 'v1.2.5': None - }, - { - 'v1.3.9': None - }, - { - 'v1.4.2': None - }, - { - 'v1.6.6': None - }, + 'cxx': + OrderedDict([ + ('v1.0.1', ReleaseInfo()), + ('v1.1.4', ReleaseInfo()), + ('v1.2.5', ReleaseInfo()), + ('v1.3.9', ReleaseInfo()), + ('v1.4.2', ReleaseInfo()), + ('v1.6.6', ReleaseInfo()), + ('v1.7.2', ReleaseInfo()), + ('v1.8.0', ReleaseInfo()), + ('v1.9.1', ReleaseInfo()), + ('v1.10.1', ReleaseInfo()), + ('v1.11.1', ReleaseInfo()), + ('v1.12.0', ReleaseInfo()), + ('v1.13.0', ReleaseInfo()), + ('v1.14.1', ReleaseInfo()), + ('v1.15.0', ReleaseInfo()), + ('v1.16.0', ReleaseInfo()), + ('v1.17.1', ReleaseInfo()), + ('v1.18.0', ReleaseInfo()), + ('v1.19.0', ReleaseInfo()), + ('v1.20.0', ReleaseInfo()), + ]), + 'go': + OrderedDict([ + ('v1.0.5', ReleaseInfo(runtime_subset=['go1.8'])), + ('v1.2.1', ReleaseInfo(runtime_subset=['go1.8'])), + ('v1.3.0', ReleaseInfo(runtime_subset=['go1.8'])), + ('v1.4.2', ReleaseInfo(runtime_subset=['go1.8'])), + ('v1.5.2', ReleaseInfo(runtime_subset=['go1.8'])), + ('v1.6.0', ReleaseInfo(runtime_subset=['go1.8'])), + ('v1.7.4', ReleaseInfo(runtime_subset=['go1.8'])), + ('v1.8.2', ReleaseInfo(runtime_subset=['go1.8'])), + ('v1.9.2', ReleaseInfo(runtime_subset=['go1.8'])), + ('v1.10.1', ReleaseInfo(runtime_subset=['go1.8'])), + ('v1.11.3', ReleaseInfo(runtime_subset=['go1.8'])), + ('v1.12.2', ReleaseInfo(runtime_subset=['go1.8'])), + ('v1.13.0', ReleaseInfo(runtime_subset=['go1.8'])), + ('v1.14.0', ReleaseInfo(runtime_subset=['go1.8'])), + ('v1.15.0', ReleaseInfo(runtime_subset=['go1.8'])), + ('v1.16.0', ReleaseInfo(runtime_subset=['go1.8'])), + ('v1.17.0', ReleaseInfo(runtime_subset=['go1.11'])), + ('v1.18.0', ReleaseInfo(runtime_subset=['go1.11'])), + ('v1.19.0', ReleaseInfo(runtime_subset=['go1.11'])), + ('v1.20.0', ReleaseInfo(runtime_subset=['go1.11'])), + ]), + 'java': + OrderedDict([ + ('v1.0.3', ReleaseInfo()), + ('v1.1.2', ReleaseInfo()), + ('v1.2.0', ReleaseInfo()), + ('v1.3.1', ReleaseInfo()), + ('v1.4.0', ReleaseInfo()), + ('v1.5.0', ReleaseInfo()), + ('v1.6.1', ReleaseInfo()), + ('v1.7.0', ReleaseInfo()), + ('v1.8.0', ReleaseInfo()), + ('v1.9.1', ReleaseInfo()), + ('v1.10.1', ReleaseInfo()), + ('v1.11.0', ReleaseInfo()), + ('v1.12.0', ReleaseInfo()), + ('v1.13.1', ReleaseInfo()), + ('v1.14.0', ReleaseInfo()), + ('v1.15.0', ReleaseInfo()), + ('v1.16.1', ReleaseInfo()), + ('v1.17.1', ReleaseInfo()), + ('v1.18.0', ReleaseInfo()), + ('v1.19.0', ReleaseInfo()), + ('v1.20.0', ReleaseInfo()), + ]), + 'python': + OrderedDict([ + ('v1.0.x', ReleaseInfo(testcases_file='python__v1.0.x')), + ('v1.1.4', ReleaseInfo(testcases_file='python__v1.0.x')), + ('v1.2.5', ReleaseInfo(testcases_file='python__v1.0.x')), + ('v1.3.9', ReleaseInfo(testcases_file='python__v1.0.x')), + ('v1.4.2', ReleaseInfo(testcases_file='python__v1.0.x')), + ('v1.6.6', ReleaseInfo(testcases_file='python__v1.0.x')), + ('v1.7.2', ReleaseInfo(testcases_file='python__v1.0.x')), + ('v1.8.1', ReleaseInfo(testcases_file='python__v1.0.x')), + ('v1.9.1', ReleaseInfo(testcases_file='python__v1.0.x')), + ('v1.10.1', ReleaseInfo(testcases_file='python__v1.0.x')), + ('v1.11.1', ReleaseInfo(testcases_file='python__v1.11.1')), + ('v1.12.0', ReleaseInfo(testcases_file='python__v1.11.1')), + ('v1.13.0', ReleaseInfo(testcases_file='python__v1.11.1')), + ('v1.14.1', ReleaseInfo(testcases_file='python__v1.11.1')), + ('v1.15.0', ReleaseInfo(testcases_file='python__v1.11.1')), + ('v1.16.0', ReleaseInfo(testcases_file='python__v1.11.1')), + ('v1.17.1', ReleaseInfo(testcases_file='python__v1.11.1')), + ('v1.18.0', ReleaseInfo()), + ('v1.19.0', ReleaseInfo()), + ('v1.20.0', ReleaseInfo()), + ]), + 'node': + OrderedDict([ + ('v1.0.1', ReleaseInfo(testcases_file='node__v1.0.1')), + ('v1.1.4', ReleaseInfo(testcases_file='node__v1.1.4')), + ('v1.2.5', ReleaseInfo(testcases_file='node__v1.1.4')), + ('v1.3.9', ReleaseInfo(testcases_file='node__v1.1.4')), + ('v1.4.2', ReleaseInfo(testcases_file='node__v1.1.4')), + ('v1.6.6', ReleaseInfo(testcases_file='node__v1.1.4')), # TODO: https://github.com/grpc/grpc-node/issues/235. - #{ - # 'v1.7.2': None - #}, - { - 'v1.8.4': None - }, - { - 'v1.9.1': None - }, - { - 'v1.10.0': None - }, - { - 'v1.11.3': None - }, - { - 'v1.12.4': None - }, - ], - 'ruby': [ - { - 'v1.0.1': { - 'patch': [ - 'tools/dockerfile/interoptest/grpc_interop_ruby/Dockerfile', - 'tools/dockerfile/interoptest/grpc_interop_ruby/build_interop.sh', - ] - } - }, - { - 'v1.1.4': None - }, - { - 'v1.2.5': None - }, - { - 'v1.3.9': None - }, - { - 'v1.4.2': None - }, - { - 'v1.6.6': None - }, - { - 'v1.7.2': None - }, - { - 'v1.8.0': None - }, - { - 'v1.9.1': None - }, - { - 'v1.10.1': None - }, - { - 'v1.11.1': None - }, - { - 'v1.12.0': None - }, - { - 'v1.13.0': None - }, - { - 'v1.14.1': None - }, - { - 'v1.15.0': None - }, - { - 'v1.16.0': None - }, - ], - 'php': [ - { - 'v1.0.1': None - }, - { - 'v1.1.4': None - }, - { - 'v1.2.5': None - }, - { - 'v1.3.9': None - }, - { - 'v1.4.2': None - }, - { - 'v1.6.6': None - }, - { - 'v1.7.2': None - }, - { - 'v1.8.0': None - }, - { - 'v1.9.1': None - }, - { - 'v1.10.1': None - }, - { - 'v1.11.1': None - }, - { - 'v1.12.0': None - }, - { - 'v1.13.0': None - }, - { - 'v1.14.1': None - }, - { - 'v1.15.0': None - }, - { - 'v1.16.0': None - }, - ], - 'csharp': [ - { - 'v1.0.1': { - 'patch': [ - 'tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile', - 'tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile', - ] - } - }, - { - 'v1.1.4': None - }, - { - 'v1.2.5': None - }, - { - 'v1.3.9': None - }, - { - 'v1.4.2': None - }, - { - 'v1.6.6': None - }, - { - 'v1.7.2': None - }, - { - 'v1.8.0': None - }, - { - 'v1.9.1': None - }, - { - 'v1.10.1': None - }, - { - 'v1.11.1': None - }, - { - 'v1.12.0': None - }, - { - 'v1.13.0': None - }, - { - 'v1.14.1': None - }, - { - 'v1.15.0': None - }, - { - 'v1.16.0': None - }, - ], -} - -# This matrix lists the version of testcases to use for a release. As new -# releases come out, some older docker commands for running tests need to be -# changed, hence the need for specifying which commands to use for a -# particular version in some cases. If not specified, xxx__master file will be -# used. For example, all java versions will run the commands in java__master. -# The testcases files exist under the testcases directory. -TESTCASES_VERSION_MATRIX = { - 'node_v1.0.1': 'node__v1.0.1', - 'node_v1.1.4': 'node__v1.1.4', - 'node_v1.2.5': 'node__v1.1.4', - 'node_v1.3.9': 'node__v1.1.4', - 'node_v1.4.2': 'node__v1.1.4', - 'node_v1.6.6': 'node__v1.1.4', - 'ruby_v1.0.1': 'ruby__v1.0.1', - 'csharp_v1.0.1': 'csharp__v1.1.4', - '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.1': 'python__v1.0.x', + # ('v1.7.2', ReleaseInfo()), + ('v1.8.4', ReleaseInfo()), + ('v1.9.1', ReleaseInfo()), + ('v1.10.0', ReleaseInfo()), + ('v1.11.3', ReleaseInfo()), + ('v1.12.4', ReleaseInfo()), + ]), + 'ruby': + OrderedDict([ + ('v1.0.1', + ReleaseInfo( + patch=[ + 'tools/dockerfile/interoptest/grpc_interop_ruby/Dockerfile', + 'tools/dockerfile/interoptest/grpc_interop_ruby/build_interop.sh', + ], + testcases_file='ruby__v1.0.1')), + ('v1.1.4', ReleaseInfo()), + ('v1.2.5', ReleaseInfo()), + ('v1.3.9', ReleaseInfo()), + ('v1.4.2', ReleaseInfo()), + ('v1.6.6', ReleaseInfo()), + ('v1.7.2', ReleaseInfo()), + ('v1.8.0', ReleaseInfo()), + ('v1.9.1', ReleaseInfo()), + ('v1.10.1', ReleaseInfo()), + ('v1.11.1', ReleaseInfo()), + ('v1.12.0', ReleaseInfo()), + ('v1.13.0', ReleaseInfo()), + ('v1.14.1', ReleaseInfo()), + ('v1.15.0', ReleaseInfo()), + ('v1.16.0', ReleaseInfo()), + ('v1.17.1', ReleaseInfo()), + ('v1.18.0', + ReleaseInfo(patch=[ + 'tools/dockerfile/interoptest/grpc_interop_ruby/build_interop.sh', + ])), + # TODO: https://github.com/grpc/grpc/issues/18262. + # If you are not encountering the error in above issue + # go ahead and upload the docker image for new releases. + ]), + 'php': + OrderedDict([ + ('v1.0.1', ReleaseInfo()), + ('v1.1.4', ReleaseInfo()), + ('v1.2.5', ReleaseInfo()), + ('v1.3.9', ReleaseInfo()), + ('v1.4.2', ReleaseInfo()), + ('v1.6.6', ReleaseInfo()), + ('v1.7.2', ReleaseInfo()), + ('v1.8.0', ReleaseInfo()), + ('v1.9.1', ReleaseInfo()), + ('v1.10.1', ReleaseInfo()), + ('v1.11.1', ReleaseInfo()), + ('v1.12.0', ReleaseInfo()), + ('v1.13.0', ReleaseInfo()), + ('v1.14.1', ReleaseInfo()), + ('v1.15.0', ReleaseInfo()), + ('v1.16.0', ReleaseInfo()), + ('v1.17.1', ReleaseInfo()), + ('v1.18.0', ReleaseInfo()), + # TODO:https://github.com/grpc/grpc/issues/18264 + # Error in above issues needs to be resolved. + ]), + 'csharp': + OrderedDict([ + ('v1.0.1', + ReleaseInfo( + patch=[ + 'tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile', + 'tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile', + ], + testcases_file='csharp__v1.1.4')), + ('v1.1.4', ReleaseInfo(testcases_file='csharp__v1.1.4')), + ('v1.2.5', ReleaseInfo(testcases_file='csharp__v1.1.4')), + ('v1.3.9', ReleaseInfo(testcases_file='csharp__v1.3.9')), + ('v1.4.2', ReleaseInfo(testcases_file='csharp__v1.3.9')), + ('v1.6.6', ReleaseInfo(testcases_file='csharp__v1.3.9')), + ('v1.7.2', ReleaseInfo(testcases_file='csharp__v1.3.9')), + ('v1.8.0', ReleaseInfo(testcases_file='csharp__v1.3.9')), + ('v1.9.1', ReleaseInfo(testcases_file='csharp__v1.3.9')), + ('v1.10.1', ReleaseInfo(testcases_file='csharp__v1.3.9')), + ('v1.11.1', ReleaseInfo(testcases_file='csharp__v1.3.9')), + ('v1.12.0', ReleaseInfo(testcases_file='csharp__v1.3.9')), + ('v1.13.0', ReleaseInfo(testcases_file='csharp__v1.3.9')), + ('v1.14.1', ReleaseInfo(testcases_file='csharp__v1.3.9')), + ('v1.15.0', ReleaseInfo(testcases_file='csharp__v1.3.9')), + ('v1.16.0', ReleaseInfo(testcases_file='csharp__v1.3.9')), + ('v1.17.1', ReleaseInfo(testcases_file='csharp__v1.3.9')), + ('v1.18.0', ReleaseInfo(testcases_file='csharp__v1.18.0')), + ('v1.19.0', ReleaseInfo(testcases_file='csharp__v1.18.0')), + ('v1.20.0', ReleaseInfo()), + ]), } diff --git a/tools/interop_matrix/create_matrix_images.py b/tools/interop_matrix/create_matrix_images.py index c2568efba0f..28dc4be0f4d 100755 --- a/tools/interop_matrix/create_matrix_images.py +++ b/tools/interop_matrix/create_matrix_images.py @@ -39,10 +39,9 @@ _LANGUAGES = client_matrix.LANG_RUNTIME_MATRIX.keys() # All gRPC release tags, flattened, deduped and sorted. _RELEASES = sorted( list( - set( - client_matrix.get_release_tag_name(info) - for lang in client_matrix.LANG_RELEASE_MATRIX.values() - for info in lang))) + set(release + for release_dict in client_matrix.LANG_RELEASE_MATRIX.values() + for release in release_dict.keys()))) # Destination directory inside docker image to keep extra info from build time. _BUILD_INFO = '/var/local/build_info' @@ -217,7 +216,7 @@ def build_all_images_for_release(lang, release): }.get(lang, 'GRPC_ROOT') env[var] = stack_base - for runtime in client_matrix.LANG_RUNTIME_MATRIX[lang]: + for runtime in client_matrix.get_runtimes_for_lang_release(lang, release): job = build_image_jobspec(runtime, env, release, stack_base) docker_images.append(job.tag) build_jobs.append(job) @@ -260,11 +259,10 @@ atexit.register(cleanup) def maybe_apply_patches_on_git_tag(stack_base, lang, release): files_to_patch = [] - for release_info in client_matrix.LANG_RELEASE_MATRIX[lang]: - if client_matrix.get_release_tag_name(release_info) == release: - if release_info[release] is not None: - files_to_patch = release_info[release].get('patch') - break + + release_info = client_matrix.LANG_RELEASE_MATRIX[lang].get(release) + if release_info: + files_to_patch = release_info.patch if not files_to_patch: return patch_file_relative_path = 'patches/%s_%s/git_repo.patch' % (lang, release) diff --git a/tools/interop_matrix/patches/ruby_v1.18.0/git_repo.patch b/tools/interop_matrix/patches/ruby_v1.18.0/git_repo.patch new file mode 100644 index 00000000000..dfa3cfc031a --- /dev/null +++ b/tools/interop_matrix/patches/ruby_v1.18.0/git_repo.patch @@ -0,0 +1,10 @@ +diff --git a/tools/dockerfile/interoptest/grpc_interop_ruby/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_ruby/build_interop.sh +index 67f66090ae..e71ad91499 100755 +--- a/tools/dockerfile/interoptest/grpc_interop_ruby/build_interop.sh ++++ b/tools/dockerfile/interoptest/grpc_interop_ruby/build_interop.sh +@@ -30,4 +30,4 @@ cd /var/local/git/grpc + rvm --default use ruby-2.5 + + # build Ruby interop client and server +-(cd src/ruby && gem update bundler && bundle && rake compile) ++(cd src/ruby && gem install bundler -v 1.17.3 && bundle && rake compile) diff --git a/tools/interop_matrix/run_interop_matrix_tests.py b/tools/interop_matrix/run_interop_matrix_tests.py index 6cf2a9b0365..3f92c8e6641 100755 --- a/tools/interop_matrix/run_interop_matrix_tests.py +++ b/tools/interop_matrix/run_interop_matrix_tests.py @@ -44,10 +44,9 @@ _LANGUAGES = client_matrix.LANG_RUNTIME_MATRIX.keys() # All gRPC release tags, flattened, deduped and sorted. _RELEASES = sorted( list( - set( - client_matrix.get_release_tag_name(info) - for lang in client_matrix.LANG_RELEASE_MATRIX.values() - for info in lang))) + set(release + for release_dict in client_matrix.LANG_RELEASE_MATRIX.values() + for release in release_dict.keys()))) argp = argparse.ArgumentParser(description='Run interop tests.') argp.add_argument('-j', '--jobs', default=multiprocessing.cpu_count(), type=int) @@ -113,35 +112,39 @@ def _get_test_images_for_lang(lang, release_arg, image_path_prefix): return {} releases = [release_arg] - # Images tuples keyed by runtime. + # Image tuples keyed by runtime. images = {} - for runtime in client_matrix.LANG_RUNTIME_MATRIX[lang]: - image_path = '%s/grpc_interop_%s' % (image_path_prefix, runtime) - images[runtime] = [ - (tag, '%s:%s' % (image_path, tag)) for tag in releases - ] + for tag in releases: + for runtime in client_matrix.get_runtimes_for_lang_release(lang, tag): + image_name = '%s/grpc_interop_%s:%s' % (image_path_prefix, runtime, + tag) + image_tuple = (tag, image_name) + + if not images.has_key(runtime): + images[runtime] = [] + images[runtime].append(image_tuple) return images def _read_test_cases_file(lang, runtime, release): """Read test cases from a bash-like file and return a list of commands""" - testcase_dir = os.path.join(os.path.dirname(__file__), 'testcases') - filename_prefix = lang - if lang == 'csharp': - # TODO(jtattermusch): remove this odd specialcase - filename_prefix = runtime # Check to see if we need to use a particular version of test cases. - lang_version = '%s_%s' % (filename_prefix, release) - if lang_version in client_matrix.TESTCASES_VERSION_MATRIX: - testcase_file = os.path.join( - testcase_dir, client_matrix.TESTCASES_VERSION_MATRIX[lang_version]) - else: + release_info = client_matrix.LANG_RELEASE_MATRIX[lang].get(release) + if release_info: + testcases_file = release_info.testcases_file + if not testcases_file: # TODO(jtattermusch): remove the double-underscore, it is pointless - testcase_file = os.path.join(testcase_dir, - '%s__master' % filename_prefix) + testcases_file = '%s__master' % lang + # For csharp, the testcases file used depends on the runtime + # TODO(jtattermusch): remove this odd specialcase + if lang == 'csharp' and runtime == 'csharpcoreclr': + testcases_file = testcases_file.replace('csharp_', 'csharpcoreclr_') + + testcases_filepath = os.path.join( + os.path.dirname(__file__), 'testcases', testcases_file) lines = [] - with open(testcase_file) as f: + with open(testcases_filepath) as f: for line in f.readlines(): line = re.sub('\\#.*$', '', line) # remove hash comments line = line.strip() @@ -168,25 +171,35 @@ def _generate_test_case_jobspecs(lang, runtime, release, suite_name): for line in testcase_lines: # TODO(jtattermusch): revisit the logic for updating test case commands # what it currently being done seems fragile. - m = re.search('--test_case=(.*)"', line) - shortname = m.group(1) if m else 'unknown_test' - m = re.search('--server_host_override=(.*).sandbox.googleapis.com', - line) - server = m.group(1) if m else 'unknown_server' - # If server_host arg is not None, replace the original - # server_host with the one provided or append to the end of - # the command if server_host does not appear originally. - if args.server_host: - if line.find('--server_host=') > -1: - line = re.sub('--server_host=[^ ]*', - '--server_host=%s' % args.server_host, line) - else: - line = '%s --server_host=%s"' % (line[:-1], args.server_host) + # Extract test case name from the command line + m = re.search(r'--test_case=(\w+)', line) + testcase_name = m.group(1) if m else 'unknown_test' + + # Extract the server name from the command line + if '--server_host_override=' in line: + m = re.search( + r'--server_host_override=((.*).sandbox.googleapis.com)', line) + else: + m = re.search(r'--server_host=((.*).sandbox.googleapis.com)', line) + server = m.group(1) if m else 'unknown_server' + server_short = m.group(2) if m else 'unknown_server' + + # replace original server_host argument + assert '--server_host=' in line + line = re.sub(r'--server_host=[^ ]*', + r'--server_host=%s' % args.server_host, line) + + # some interop tests don't set server_host_override (see #17407), + # but we need to use it if different host is set via cmdline args. + if args.server_host != server and not '--server_host_override=' in line: + line = re.sub(r'(--server_host=[^ ]*)', + r'\1 --server_host_override=%s' % server, line) spec = jobset.JobSpec( cmdline=line, - shortname='%s:%s:%s:%s' % (suite_name, lang, server, shortname), + shortname='%s:%s:%s:%s' % (suite_name, lang, server_short, + testcase_name), timeout_seconds=_TEST_TIMEOUT_SECONDS, shell=True, flake_retries=5 if args.allow_flakes else 0) @@ -211,7 +224,8 @@ def _pull_images_for_lang(lang, images): cmdline=cmdline, shortname='pull_image_%s' % (image), timeout_seconds=_PULL_IMAGE_TIMEOUT_SECONDS, - shell=True) + shell=True, + flake_retries=2) download_specs.append(spec) # too many image downloads at once tend to get stuck max_pull_jobs = min(args.jobs, _MAX_PARALLEL_DOWNLOADS) @@ -232,10 +246,13 @@ def _run_tests_for_lang(lang, runtime, images, xml_report_tree): images is a list of (, ) tuple. """ + skip_tests = False if not _pull_images_for_lang(lang, images): jobset.message( - 'FAILED', 'Image download failed. Exiting.', do_newline=True) - return 1 + 'FAILED', + 'Image download failed. Skipping tests for language "%s"' % lang, + do_newline=True) + skip_tests = True total_num_failures = 0 for release, image in images: @@ -246,17 +263,22 @@ def _run_tests_for_lang(lang, runtime, images, xml_report_tree): if not job_spec_list: jobset.message( 'FAILED', 'No test cases were found.', do_newline=True) - return 1 + total_num_failures += 1 + continue num_failures, resultset = jobset.run( job_spec_list, newline_on_success=True, add_env={'docker_image': image}, - maxjobs=args.jobs) + maxjobs=args.jobs, + skip_jobs=skip_tests) if args.bq_result_table and resultset: upload_test_results.upload_interop_results_to_bq( resultset, args.bq_result_table) - if num_failures: + if skip_tests: + jobset.message('FAILED', 'Tests were skipped', do_newline=True) + total_num_failures += 1 + elif num_failures: jobset.message('FAILED', 'Some tests failed', do_newline=True) total_num_failures += num_failures else: @@ -266,6 +288,8 @@ def _run_tests_for_lang(lang, runtime, images, xml_report_tree): 'grpc_interop_matrix', suite_name, str(uuid.uuid4())) + # cleanup all downloaded docker images + for _, image in images: if not args.keep: _cleanup_docker_image(image) diff --git a/tools/interop_matrix/testcases/csharp__master b/tools/interop_matrix/testcases/csharp__master old mode 100644 new mode 100755 index c3cd6a48f88..e526b3c1cfd --- a/tools/interop_matrix/testcases/csharp__master +++ b/tools/interop_matrix/testcases/csharp__master @@ -1,20 +1,22 @@ #!/bin/bash -echo "Testing ${docker_image:=grpc_interop_csharp:a95229ca-d387-4127-ad48-69a7464e23b8}" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=timeout_on_sleeping_server" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --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" +# DO NOT MODIFY +# This file is generated by run_interop_tests.py/create_testcases.sh +echo "Testing ${docker_image:=grpc_interop_csharp:9296f21a-f657-4bb0-82a7-24fc527abcbd}" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=large_unary --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=large_unary --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --use_tls=true" diff --git a/tools/interop_matrix/testcases/csharp__v1.18.0 b/tools/interop_matrix/testcases/csharp__v1.18.0 new file mode 100644 index 00000000000..34444c71025 --- /dev/null +++ b/tools/interop_matrix/testcases/csharp__v1.18.0 @@ -0,0 +1,23 @@ +#!/bin/bash +# DO NOT MODIFY +# This file is generated by run_interop_tests.py/create_testcases.sh +echo "Testing ${docker_image:=grpc_interop_csharp:71b05977-476b-4e57-9752-dd211c9e3741}" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=large_unary --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=large_unary --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --use_tls=true" + diff --git a/tools/interop_matrix/testcases/csharp__v1.3.9 b/tools/interop_matrix/testcases/csharp__v1.3.9 new file mode 100644 index 00000000000..c3cd6a48f88 --- /dev/null +++ b/tools/interop_matrix/testcases/csharp__v1.3.9 @@ -0,0 +1,20 @@ +#!/bin/bash +echo "Testing ${docker_image:=grpc_interop_csharp:a95229ca-d387-4127-ad48-69a7464e23b8}" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=timeout_on_sleeping_server" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --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/csharpcoreclr__master b/tools/interop_matrix/testcases/csharpcoreclr__master old mode 100644 new mode 100755 index aa8b9dd86d1..e14ec047630 --- a/tools/interop_matrix/testcases/csharpcoreclr__master +++ b/tools/interop_matrix/testcases/csharpcoreclr__master @@ -1,20 +1,22 @@ #!/bin/bash -echo "Testing ${docker_image:=grpc_interop_csharpcoreclr:c7fbed09-e4c1-4aab-8dd9-1285b2c9598e}" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=timeout_on_sleeping_server" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --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" +# DO NOT MODIFY +# This file is generated by run_interop_tests.py/create_testcases.sh +echo "Testing ${docker_image:=grpc_interop_csharpcoreclr:33395965-11d7-4b12-bcd6-a272d4015207}" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp2.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=large_unary --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp2.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp2.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp2.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp2.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp2.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp2.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp2.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp2.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp2.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=large_unary --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp2.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp2.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp2.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp2.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp2.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp2.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp2.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp2.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --use_tls=true" diff --git a/tools/interop_matrix/testcases/csharpcoreclr__v1.1.4 b/tools/interop_matrix/testcases/csharpcoreclr__v1.1.4 new file mode 100644 index 00000000000..aa8b9dd86d1 --- /dev/null +++ b/tools/interop_matrix/testcases/csharpcoreclr__v1.1.4 @@ -0,0 +1,20 @@ +#!/bin/bash +echo "Testing ${docker_image:=grpc_interop_csharpcoreclr:c7fbed09-e4c1-4aab-8dd9-1285b2c9598e}" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=timeout_on_sleeping_server" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --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/csharpcoreclr__v1.18.0 b/tools/interop_matrix/testcases/csharpcoreclr__v1.18.0 new file mode 100755 index 00000000000..3ca145e4c11 --- /dev/null +++ b/tools/interop_matrix/testcases/csharpcoreclr__v1.18.0 @@ -0,0 +1,22 @@ +#!/bin/bash +# DO NOT MODIFY +# This file is generated by run_interop_tests.py/create_testcases.sh +echo "Testing ${docker_image:=grpc_interop_csharpcoreclr:bae17a7e-5450-4781-8982-e82cb89db6dd}" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=large_unary --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=large_unary --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --use_tls=true" diff --git a/tools/interop_matrix/testcases/csharpcoreclr__v1.3.9 b/tools/interop_matrix/testcases/csharpcoreclr__v1.3.9 new file mode 100644 index 00000000000..aa8b9dd86d1 --- /dev/null +++ b/tools/interop_matrix/testcases/csharpcoreclr__v1.3.9 @@ -0,0 +1,20 @@ +#!/bin/bash +echo "Testing ${docker_image:=grpc_interop_csharpcoreclr:c7fbed09-e4c1-4aab-8dd9-1285b2c9598e}" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=timeout_on_sleeping_server" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --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/node__v1.1.4 b/tools/interop_matrix/testcases/node__v1.1.4 index 99ea2f0bc47..9e31fbf97dc 100644 --- a/tools/interop_matrix/testcases/node__v1.1.4 +++ b/tools/interop_matrix/testcases/node__v1.1.4 @@ -1,20 +1,20 @@ #!/bin/bash echo "Testing ${docker_image:=grpc_interop_node:1415ecbf-5d0f-423e-8c2c-e0cb6d154e73}" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=timeout_on_sleeping_server" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=timeout_on_sleeping_server" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=timeout_on_sleeping_server" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=timeout_on_sleeping_server" diff --git a/tools/interop_matrix/testcases/python__master b/tools/interop_matrix/testcases/python__master index 467e41ff82f..39e160188c7 100755 --- a/tools/interop_matrix/testcases/python__master +++ b/tools/interop_matrix/testcases/python__master @@ -1,20 +1,22 @@ #!/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_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\"" +# DO NOT MODIFY +# This file is generated by run_interop_tests.py/create_testcases.sh +echo "Testing ${docker_image:=grpc_interop_python:4fa5bb4b-5d57-4882-8c8e-551fb899b86a}" +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 "py37_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=large_unary --use_tls=true\"" +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 "py37_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --use_tls=true\"" +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 "py37_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --use_tls=true\"" +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 "py37_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --use_tls=true\"" +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 "py37_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --use_tls=true\"" +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 "py37_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --use_tls=true\"" +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 "py37_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --use_tls=true\"" +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 "py37_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --use_tls=true\"" +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 "py37_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --use_tls=true\"" +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 "py37_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=large_unary --use_tls=true\"" +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 "py37_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --use_tls=true\"" +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 "py37_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --use_tls=true\"" +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 "py37_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --use_tls=true\"" +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 "py37_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --use_tls=true\"" +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 "py37_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --use_tls=true\"" +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 "py37_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --use_tls=true\"" +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 "py37_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --use_tls=true\"" +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 "py37_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --use_tls=true\"" diff --git a/tools/interop_matrix/testcases/python__v1.11.1 b/tools/interop_matrix/testcases/python__v1.11.1 new file mode 100755 index 00000000000..467e41ff82f --- /dev/null +++ b/tools/interop_matrix/testcases/python__v1.11.1 @@ -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_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/profiling/bloat/bloat_diff.py b/tools/profiling/bloat/bloat_diff.py index 91611c2ca4a..36189151e9e 100755 --- a/tools/profiling/bloat/bloat_diff.py +++ b/tools/profiling/bloat/bloat_diff.py @@ -25,7 +25,7 @@ import sys sys.path.append( os.path.join( os.path.dirname(sys.argv[0]), '..', '..', 'run_tests', 'python_utils')) -import comment_on_pr +import check_on_pr argp = argparse.ArgumentParser(description='Perform diff on microbenchmarks') @@ -90,4 +90,4 @@ for lib in LIBS: text += '\n\n' print text -comment_on_pr.comment_on_pr('```\n%s\n```' % text) +check_on_pr.check_on_pr('Bloat Difference', '```\n%s\n```' % text) diff --git a/tools/profiling/ios_bin/binary_size.py b/tools/profiling/ios_bin/binary_size.py index d4d134fef37..f0c8dd01a01 100755 --- a/tools/profiling/ios_bin/binary_size.py +++ b/tools/profiling/ios_bin/binary_size.py @@ -26,7 +26,7 @@ from parse_link_map import parse_link_map sys.path.append( os.path.join( os.path.dirname(sys.argv[0]), '..', '..', 'run_tests', 'python_utils')) -import comment_on_pr +import check_on_pr # Only show diff 1KB or greater diff_threshold = 1000 @@ -147,4 +147,4 @@ for frameworks in [False, True]: print text -comment_on_pr.comment_on_pr('```\n%s\n```' % text) +check_on_pr.check_on_pr('Binary Size', '```\n%s\n```' % text) diff --git a/tools/profiling/microbenchmarks/bm_diff/bm_main.py b/tools/profiling/microbenchmarks/bm_diff/bm_main.py index 96c63ba060e..e5061b24f57 100755 --- a/tools/profiling/microbenchmarks/bm_diff/bm_main.py +++ b/tools/profiling/microbenchmarks/bm_diff/bm_main.py @@ -30,7 +30,7 @@ import subprocess sys.path.append( os.path.join( os.path.dirname(sys.argv[0]), '..', '..', 'run_tests', 'python_utils')) -import comment_on_pr +import check_on_pr sys.path.append( os.path.join( @@ -152,7 +152,7 @@ def main(args): if note: text = note + '\n\n' + text print('%s' % text) - comment_on_pr.comment_on_pr('```\n%s\n```' % text) + check_on_pr.check_on_pr('Benchmark', '```\n%s\n```' % text) if __name__ == '__main__': diff --git a/tools/profiling/qps/qps_diff.py b/tools/profiling/qps/qps_diff.py index 393f862b4db..2c73b236e25 100755 --- a/tools/profiling/qps/qps_diff.py +++ b/tools/profiling/qps/qps_diff.py @@ -33,7 +33,7 @@ import bm_speedup sys.path.append( os.path.join( os.path.dirname(sys.argv[0]), '..', '..', 'run_tests', 'python_utils')) -import comment_on_pr +import check_on_pr def _args(): @@ -164,7 +164,7 @@ def main(args): else: text = '[qps] No significant performance differences' print('%s' % text) - comment_on_pr.comment_on_pr('```\n%s\n```' % text) + check_on_pr.check_on_pr('QPS', '```\n%s\n```' % text) if __name__ == '__main__': diff --git a/tools/release/release_notes.py b/tools/release/release_notes.py new file mode 100644 index 00000000000..46e01843535 --- /dev/null +++ b/tools/release/release_notes.py @@ -0,0 +1,369 @@ +#Copyright 2019 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. +"""Generate draft and release notes in Markdown from Github PRs. + +You'll need a github API token to avoid being rate-limited. See +https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/ + +This script collects PRs using "git log X..Y" from local repo where X and Y are +tags or release branch names of previous and current releases respectively. +Typically, notes are generated before the release branch is labelled so Y is +almost always the name of the release branch. X is the previous release branch +if this is not a patch release. Otherwise, it is the previous release tag. +For example, for release v1.17.0, X will be origin/v1.16.x and for release v1.17.3, +X will be v1.17.2. In both cases Y will be origin/v1.17.x. + +""" + +from collections import defaultdict +import base64 +import json + +content_header = """Draft Release Notes For {version} +-- +Final release notes will be generated from the PR titles that have *"release notes:yes"* label. If you have any additional notes please add them below. These will be appended to auto generated release notes. Previous releases notes are [here](https://github.com/grpc/grpc/releases). + +**Also, look at the PRs listed below against your name.** Please apply the missing labels and make necessary corrections (like fixing the title) to the PR in Github. Final release notes will be generated just before the release on {date}. + +Add additional notes not in PRs +-- + +Core +- + + +C++ +- + + +C# +- + + +Objective-C +- + + +PHP +- + + +Python +- + + +Ruby +- + + +""" + +rl_header = """This is the {version} release ([{name}](https://github.com/grpc/grpc/blob/master/doc/g_stands_for.md)) of gRPC Core. + +Please see the notes for the previous releases here: https://github.com/grpc/grpc/releases. Please consult https://grpc.io/ for all information regarding this product. + +This release contains refinements, improvements, and bug fixes, with highlights listed below. + + +""" + +HTML_URL = "https://github.com/grpc/grpc/pull/" +API_URL = 'https://api.github.com/repos/grpc/grpc/pulls/' + + +def get_commit_log(prevRelLabel, relBranch): + """Return the output of 'git log --pretty=online --merges prevRelLabel..relBranch' """ + + import subprocess + print("Running git log --pretty=oneline --merges " + prevRelLabel + ".." + + relBranch) + return subprocess.check_output([ + "git", "log", "--pretty=oneline", "--merges", + "%s..%s" % (prevRelLabel, relBranch) + ]) + + +def get_pr_data(pr_num): + """Get the PR data from github. Return 'error' on exception""" + + try: + from urllib2 import Request, urlopen, HTTPError + except ImportError: + import urllib + from urllib.request import Request, urlopen, HTTPError + url = API_URL + pr_num + req = Request(url) + req.add_header('Authorization', 'token %s' % TOKEN) + try: + f = urlopen(req) + response = json.loads(f.read().decode('utf-8')) + #print(response) + except HTTPError as e: + response = json.loads(e.fp.read().decode('utf-8')) + if 'message' in response: + print(response['message']) + response = "error" + return response + + +def get_pr_titles(gitLogs): + import re + error_count = 0 + match = b"Merge pull request #(\d+)" + prlist = re.findall(match, gitLogs, re.MULTILINE) + print("\nPRs matching 'Merge pull request #':") + print(prlist) + print("\n") + langs_pr = defaultdict(list) + for pr_num in prlist: + pr_num = str(pr_num) + print("---------- getting data for PR " + pr_num) + pr = get_pr_data(pr_num) + if pr == "error": + print("\n***ERROR*** Error in getting data for PR " + pr_num + "\n") + error_count += 1 + continue + rl_no_found = False + rl_yes_found = False + lang_found = False + for label in pr['labels']: + if label['name'] == 'release notes: yes': + rl_yes_found = True + elif label['name'] == 'release notes: no': + rl_no_found = True + elif label['name'].startswith('lang/'): + lang_found = True + lang = label['name'].split('/')[1].lower() + #lang = lang[0].upper() + lang[1:] + body = pr["title"] + if not body.endswith("."): + body = body + "." + if not pr["merged_by"]: + print("\n***ERROR***: No merge_by found for PR " + pr_num + "\n") + error_count += 1 + continue + + prline = "- " + body + " ([#" + pr_num + "](" + HTML_URL + pr_num + "))" + detail = "- " + pr["merged_by"]["login"] + "@ " + prline + prline = prline.encode('ascii', 'ignore') + detail = detail.encode('ascii', 'ignore') + print(detail) + #if no RL label + if not rl_no_found and not rl_yes_found: + print("Release notes label missing for " + pr_num) + langs_pr["nolabel"].append(detail) + elif rl_yes_found and not lang_found: + print("Lang label missing for " + pr_num) + langs_pr["nolang"].append(detail) + elif rl_no_found: + print("'Release notes:no' found for " + pr_num) + langs_pr["notinrel"].append(detail) + elif rl_yes_found: + print("'Release notes:yes' found for " + pr_num + " with lang " + + lang) + langs_pr["inrel"].append(detail) + langs_pr[lang].append(prline) + + return langs_pr, error_count + + +def write_draft(langs_pr, file, version, date): + file.write(content_header.format(version=version, date=date)) + file.write("PRs with missing release notes label - please fix in Github\n") + file.write("---\n") + file.write("\n") + if langs_pr["nolabel"]: + langs_pr["nolabel"].sort() + file.write("\n".join(langs_pr["nolabel"])) + else: + file.write("- None") + file.write("\n") + file.write("\n") + file.write("PRs with missing lang label - please fix in Github\n") + file.write("---\n") + file.write("\n") + if langs_pr["nolang"]: + langs_pr["nolang"].sort() + file.write("\n".join(langs_pr["nolang"])) + else: + file.write("- None") + file.write("\n") + file.write("\n") + file.write( + "PRs going into release notes - please check title and fix in Github. Do not edit here.\n" + ) + file.write("---\n") + file.write("\n") + if langs_pr["inrel"]: + langs_pr["inrel"].sort() + file.write("\n".join(langs_pr["inrel"])) + else: + file.write("- None") + file.write("\n") + file.write("\n") + file.write("PRs not going into release notes\n") + file.write("---\n") + file.write("\n") + if langs_pr["notinrel"]: + langs_pr["notinrel"].sort() + file.write("\n".join(langs_pr["notinrel"])) + else: + file.write("- None") + file.write("\n") + file.write("\n") + + +def write_rel_notes(langs_pr, file, version, name): + file.write(rl_header.format(version=version, name=name)) + if langs_pr["core"]: + file.write("Core\n---\n\n") + file.write("\n".join(langs_pr["core"])) + file.write("\n") + file.write("\n") + if langs_pr["c++"]: + file.write("C++\n---\n\n") + file.write("\n".join(langs_pr["c++"])) + file.write("\n") + file.write("\n") + if langs_pr["c#"]: + file.write("C#\n---\n\n") + file.write("\n".join(langs_pr["c#"])) + file.write("\n") + file.write("\n") + if langs_pr["go"]: + file.write("Go\n---\n\n") + file.write("\n".join(langs_pr["go"])) + file.write("\n") + file.write("\n") + if langs_pr["Java"]: + file.write("Java\n---\n\n") + file.write("\n".join(langs_pr["Java"])) + file.write("\n") + file.write("\n") + if langs_pr["node"]: + file.write("Node\n---\n\n") + file.write("\n".join(langs_pr["node"])) + file.write("\n") + file.write("\n") + if langs_pr["objc"]: + file.write("Objective-C\n---\n\n") + file.write("\n".join(langs_pr["objc"])) + file.write("\n") + file.write("\n") + if langs_pr["php"]: + file.write("PHP\n---\n\n") + file.write("\n".join(langs_pr["php"])) + file.write("\n") + file.write("\n") + if langs_pr["python"]: + file.write("Python\n---\n\n") + file.write("\n".join(langs_pr["python"])) + file.write("\n") + file.write("\n") + if langs_pr["ruby"]: + file.write("Ruby\n---\n\n") + file.write("\n".join(langs_pr["ruby"])) + file.write("\n") + file.write("\n") + if langs_pr["other"]: + file.write("Other\n---\n\n") + file.write("\n".join(langs_pr["other"])) + file.write("\n") + file.write("\n") + + +def build_args_parser(): + import argparse + parser = argparse.ArgumentParser() + parser.add_argument( + 'release_version', type=str, help='New release version e.g. 1.14.0') + parser.add_argument( + 'release_name', type=str, help='New release name e.g. gladiolus') + parser.add_argument( + 'release_date', type=str, help='Release date e.g. 7/30/18') + parser.add_argument( + 'previous_release_label', + type=str, + help='Previous release branch/tag e.g. v1.13.x') + parser.add_argument( + 'release_branch', + type=str, + help='Current release branch e.g. origin/v1.14.x') + parser.add_argument( + 'draft_filename', type=str, help='Name of the draft file e.g. draft.md') + parser.add_argument( + 'release_notes_filename', + type=str, + help='Name of the release notes file e.g. relnotes.md') + parser.add_argument( + '--token', + type=str, + default='', + help='GitHub API token to avoid being rate limited') + return parser + + +def main(): + import os + global TOKEN + + parser = build_args_parser() + args = parser.parse_args() + version, name, date = args.release_version, args.release_name, args.release_date + start, end = args.previous_release_label, args.release_branch + + TOKEN = args.token + if TOKEN == '': + try: + TOKEN = os.environ["GITHUB_TOKEN"] + except: + pass + if TOKEN == '': + print( + "Error: Github API token required. Either include param --token= or set environment variable GITHUB_TOKEN to your github token" + ) + return + + langs_pr, error_count = get_pr_titles(get_commit_log(start, end)) + + draft_file, rel_file = args.draft_filename, args.release_notes_filename + filename = os.path.abspath(draft_file) + if os.path.exists(filename): + file = open(filename, 'r+') + else: + file = open(filename, 'w') + + file.seek(0) + write_draft(langs_pr, file, version, date) + file.truncate() + file.close() + print("\nDraft notes written to " + filename) + + filename = os.path.abspath(rel_file) + if os.path.exists(filename): + file = open(filename, 'r+') + else: + file = open(filename, 'w') + + file.seek(0) + write_rel_notes(langs_pr, file, version, name) + file.truncate() + file.close() + print("\nRelease notes written to " + filename) + if error_count > 0: + print("\n\n*** Errors were encountered. See log. *********\n") + + +if __name__ == "__main__": + main() diff --git a/tools/remote_build/README.md b/tools/remote_build/README.md index 19739e9ee12..2cd5f03daf1 100644 --- a/tools/remote_build/README.md +++ b/tools/remote_build/README.md @@ -12,7 +12,7 @@ and tests run by Kokoro CI. - See [Installing Bazel](https://docs.bazel.build/versions/master/install.html) for instructions how to install bazel on your system. -- Setup application default credentials for running remote builds by following [RBE Credentials Setup](https://cloud.google.com/remote-build-execution/docs/getting-started#set_credentials) +- Setup application default credentials for running remote builds by following the ["Set credentials" section](https://cloud.google.com/remote-build-execution/docs/results-ui/getting-started-results-ui). (Note: for the ResultStore UI upload to work, you'll need a special kind of application default credentials, so if the build event upload doesn't work, doublecheck the instructions) ## Running remote build manually from dev workstation @@ -29,5 +29,11 @@ Sanitizer runs (asan, msan, tsan, ubsan): bazel --bazelrc=tools/remote_build/manual.bazelrc test --config=asan //test/... ``` +Run on Windows MSVC: +``` +# RBE manual run only for c-core (must be run on a Windows host machine) +bazel --bazelrc=tools/remote_build/windows.bazelrc build :all [--credentials_json=(path to service account credentials)] +``` + Available command line options can be found in [Bazel command line reference](https://docs.bazel.build/versions/master/command-line-reference.html) diff --git a/tools/remote_build/kokoro.bazelrc b/tools/remote_build/kokoro.bazelrc index 11462bd301c..064e94b2e15 100644 --- a/tools/remote_build/kokoro.bazelrc +++ b/tools/remote_build/kokoro.bazelrc @@ -21,12 +21,8 @@ build --remote_executor=remotebuildexecution.googleapis.com build --tls_enabled=true build --auth_enabled=true -# magic location where kokoro script puts the credentials -build --auth_credentials=/tmpfs/src/keystore/4321_grpc-testing-service -build --auth_scope=https://www.googleapis.com/auth/cloud-source-tools build --bes_backend=buildeventservice.googleapis.com -build --bes_best_effort=false build --bes_timeout=600s build --project_id=grpc-testing diff --git a/tools/remote_build/manual.bazelrc b/tools/remote_build/manual.bazelrc index b4fdc70637e..fcd41f57521 100644 --- a/tools/remote_build/manual.bazelrc +++ b/tools/remote_build/manual.bazelrc @@ -37,9 +37,5 @@ build --project_id=grpc-testing build --jobs=100 -# TODO(jtattermusch): this should be part of the common config -# but currently sanitizers use different test_timeout values -build --test_timeout=300,450,1200,3600 - # print output for tests that fail (default is "summary") build --test_output=errors diff --git a/tools/remote_build/rbe_common.bazelrc b/tools/remote_build/rbe_common.bazelrc index 75a42a317e8..69394fe092b 100644 --- a/tools/remote_build/rbe_common.bazelrc +++ b/tools/remote_build/rbe_common.bazelrc @@ -1,3 +1,4 @@ +#@IgnoreInspection BashAddShebang # Copyright 2018 The gRPC Authors # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,10 +19,10 @@ startup --host_jvm_args=-Dbazel.DigestFunction=SHA256 -build --crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.0/bazel_0.16.1/default:toolchain -build --extra_toolchains=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.0/bazel_0.16.1/cpp:cc-toolchain-clang-x86_64-default +build --crosstool_top=@rbe_default//cc:toolchain +build --extra_toolchains=@rbe_default//config:cc-toolchain # Use custom execution platforms defined in third_party/toolchains -build --extra_execution_platforms=//third_party/toolchains:rbe_ubuntu1604 +build --extra_execution_platforms=//third_party/toolchains:rbe_ubuntu1604,//third_party/toolchains:rbe_ubuntu1604_large build --host_platform=//third_party/toolchains:rbe_ubuntu1604 build --platforms=//third_party/toolchains:rbe_ubuntu1604 @@ -43,6 +44,10 @@ build --define GRPC_PORT_ISOLATED_RUNTIME=1 # without verbose gRPC logs the test outputs are not very useful test --test_env=GRPC_VERBOSITY=debug +# Default test timeouts for all RBE tests (sanitizers override these values) +# TODO(jtattermusch): revisit the non-standard test timeout values +build --test_timeout=300,450,1200,3600 + # address sanitizer: most settings are already in %workspace%/.bazelrc # we only need a few additional ones that are Foundry specific build:asan --copt=-gmlt @@ -61,9 +66,9 @@ build:msan --cxxopt=--stdlib=libc++ # setting LD_LIBRARY_PATH is necessary # to avoid "libc++.so.1: cannot open shared object file" build:msan --action_env=LD_LIBRARY_PATH=/usr/local/lib -build:msan --host_crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.0/bazel_0.16.1/default:toolchain +build:msan --host_crosstool_top=@rbe_default//cc:toolchain # override the config-agnostic crosstool_top -build:msan --crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.0/bazel_0.16.1/msan:toolchain +build:msan --crosstool_top=@rbe_msan//cc:toolchain # thread sanitizer: most settings are already in %workspace%/.bazelrc # we only need a few additional ones that are Foundry specific @@ -71,6 +76,7 @@ build:tsan --copt=-gmlt # TODO(jtattermusch): use more reasonable test timeout build:tsan --test_timeout=3600 build:tsan --test_tag_filters=-qps_json_driver +build:tsan --extra_execution_platforms=//third_party/toolchains:rbe_ubuntu1604,//third_party/toolchains:rbe_ubuntu1604_large # undefined behavior sanitizer: most settings are already in %workspace%/.bazelrc # we only need a few additional ones that are Foundry specific @@ -78,8 +84,4 @@ build:ubsan --copt=-gmlt # TODO(jtattermusch): use more reasonable test timeout build:ubsan --test_timeout=3600 # override the config-agnostic crosstool_top ---crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/experimental/ubuntu16_04_clang/1.0/bazel_0.16.1/ubsan:toolchain -# TODO(jtattermusch): remove this once Foundry adds the env to the docker image. -# ubsan needs symbolizer to work properly, otherwise the suppression file doesn't work -# and we get test failures. -build:ubsan --action_env=UBSAN_SYMBOLIZER_PATH=/usr/local/bin/llvm-symbolizer +build:ubsan --crosstool_top=@bazel_toolchains//configs/experimental/ubuntu16_04_clang/1.2/bazel_0.21.0/ubsan:toolchain diff --git a/tools/remote_build/windows.bazelrc b/tools/remote_build/windows.bazelrc new file mode 100644 index 00000000000..492489f3613 --- /dev/null +++ b/tools/remote_build/windows.bazelrc @@ -0,0 +1,49 @@ +startup --host_jvm_args=-Dbazel.DigestFunction=SHA256 + +build --remote_cache=remotebuildexecution.googleapis.com +build --remote_executor=remotebuildexecution.googleapis.com +build --tls_enabled=true + +build --host_crosstool_top=//third_party/toolchains/bazel_0.23.2_rbe_windows:toolchain +build --crosstool_top=//third_party/toolchains/bazel_0.23.2_rbe_windows:toolchain +build --extra_toolchains=//third_party/toolchains/bazel_0.23.2_rbe_windows:cc-toolchain-x64_windows +# Use custom execution platforms defined in third_party/toolchains +build --extra_execution_platforms=//third_party/toolchains:rbe_windows +build --host_platform=//third_party/toolchains:rbe_windows +build --platforms=//third_party/toolchains:rbe_windows + +build --shell_executable=C:\\tools\\msys64\\usr\\bin\\bash.exe +build --python_path=C:\\Python27\\python.exe + +build --spawn_strategy=remote +build --strategy=Javac=remote +build --strategy=Closure=remote +build --genrule_strategy=remote +build --remote_timeout=3600 + +build --remote_instance_name=projects/grpc-testing/instances/grpc-windows-rbe-test + +build --verbose_failures=true + +build --experimental_strict_action_env=true +build --action_env=BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN=1 + +# don't use port server +build --define GRPC_PORT_ISOLATED_RUNTIME=1 +build --test_tag_filters=-no_windows +build --build_tag_filters=-no_windows + +# without verbose gRPC logs the test outputs are not very useful +test --test_env=GRPC_VERBOSITY=debug + +# Set flags for uploading to BES in order to view results in the Bazel Build +# Results UI. +build --bes_backend="buildeventservice.googleapis.com" +build --bes_timeout=60s +build --bes_results_url="https://source.cloud.google.com/results/invocations/" +build --project_id=grpc-testing + +build --jobs=30 + +# print output for tests that fail (default is "summary") +build --test_output=errors diff --git a/tools/remote_build/workspace_status_kokoro.sh b/tools/remote_build/workspace_status_kokoro.sh new file mode 100755 index 00000000000..8d5db7f8bd5 --- /dev/null +++ b/tools/remote_build/workspace_status_kokoro.sh @@ -0,0 +1,26 @@ +#!/bin/bash +# Copyright 2018 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. +# 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. + +# Adds additional labels to results page for Bazel RBE builds on Kokoro + +# Provide a way to go from Bazel RBE links back to Kokoro job results +# which is important for debugging test infrastructure problems. +# TODO(jtattermusch): replace this workaround by something more user-friendly. +echo "KOKORO_RESULTSTORE_URL https://source.cloud.google.com/results/invocations/${KOKORO_BUILD_ID}" +echo "KOKORO_SPONGE_URL http://sponge.corp.google.com/${KOKORO_BUILD_ID}" + +echo "KOKORO_BUILD_NUMBER ${KOKORO_BUILD_NUMBER}" +echo "KOKORO_JOB_NAME ${KOKORO_JOB_NAME}" +echo "KOKORO_GITHUB_COMMIT ${KOKORO_GITHUB_COMMIT}" diff --git a/tools/run_tests/artifacts/build_artifact_protoc.sh b/tools/run_tests/artifacts/build_artifact_protoc.sh index 6d433f2dad4..a5b6e2f3482 100755 --- a/tools/run_tests/artifacts/build_artifact_protoc.sh +++ b/tools/run_tests/artifacts/build_artifact_protoc.sh @@ -14,6 +14,7 @@ # limitations under the License. # Use devtoolset environment that has GCC 4.8 before set -ex +# shellcheck disable=SC1091 source scl_source enable devtoolset-2 set -ex diff --git a/tools/run_tests/artifacts/build_artifact_python.sh b/tools/run_tests/artifacts/build_artifact_python.sh index 65f2d1c7659..e451ced338f 100755 --- a/tools/run_tests/artifacts/build_artifact_python.sh +++ b/tools/run_tests/artifacts/build_artifact_python.sh @@ -105,9 +105,15 @@ then "${PIP}" install grpcio-tools --no-index --find-links "file://$ARTIFACT_DIR/" # Build grpcio_testing source distribution - ${SETARCH_CMD} "${PYTHON}" src/python/grpcio_testing/setup.py sdist + ${SETARCH_CMD} "${PYTHON}" src/python/grpcio_testing/setup.py preprocess \ + sdist cp -r src/python/grpcio_testing/dist/* "$ARTIFACT_DIR" + # Build grpcio_channelz source distribution + ${SETARCH_CMD} "${PYTHON}" src/python/grpcio_channelz/setup.py \ + preprocess build_package_protos sdist + cp -r src/python/grpcio_channelz/dist/* "$ARTIFACT_DIR" + # Build grpcio_health_checking source distribution ${SETARCH_CMD} "${PYTHON}" src/python/grpcio_health_checking/setup.py \ preprocess build_package_protos sdist @@ -117,6 +123,11 @@ then ${SETARCH_CMD} "${PYTHON}" src/python/grpcio_reflection/setup.py \ preprocess build_package_protos sdist cp -r src/python/grpcio_reflection/dist/* "$ARTIFACT_DIR" + + # Build grpcio_status source distribution + ${SETARCH_CMD} "${PYTHON}" src/python/grpcio_status/setup.py \ + preprocess sdist + cp -r src/python/grpcio_status/dist/* "$ARTIFACT_DIR" fi cp -r dist/* "$ARTIFACT_DIR" diff --git a/tools/run_tests/artifacts/build_artifact_ruby.sh b/tools/run_tests/artifacts/build_artifact_ruby.sh index 5ab4cf21b4e..09423ce5391 100755 --- a/tools/run_tests/artifacts/build_artifact_ruby.sh +++ b/tools/run_tests/artifacts/build_artifact_ruby.sh @@ -18,7 +18,9 @@ SYSTEM=$(uname | cut -f 1 -d_) cd "$(dirname "$0")/../../.." set +ex +# shellcheck disable=SC1091 [[ -s /etc/profile.d/rvm.sh ]] && . /etc/profile.d/rvm.sh +# shellcheck disable=SC1090 [[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm" set -ex @@ -36,7 +38,7 @@ fi set +ex rvm use default -gem install bundler --update +gem install bundler -v 1.17.3 tools/run_tests/helper_scripts/bundle_install_wrapper.sh diff --git a/tools/run_tests/artifacts/build_package_python.sh b/tools/run_tests/artifacts/build_package_python.sh index d93e8979fcc..35c78e9a93e 100755 --- a/tools/run_tests/artifacts/build_package_python.sh +++ b/tools/run_tests/artifacts/build_package_python.sh @@ -19,14 +19,26 @@ cd "$(dirname "$0")/../../.." mkdir -p artifacts/ +# All the python packages have been built in the artifact phase already +# and we only collect them here to deliver them to the distribtest phase. cp -r "${EXTERNAL_GIT_ROOT}"/input_artifacts/python_*/* artifacts/ || true +apt-get install -y python-pip +python -m pip install -U pip +python -m pip install -U wheel + strip_binary_wheel() { - TEMP_WHEEL_DIR=$(mktemp -d) - unzip "$1" -d "$TEMP_WHEEL_DIR" - find "$TEMP_WHEEL_DIR" -name "_protoc_compiler*.so" -exec strip --strip-debug {} ";" - find "$TEMP_WHEEL_DIR" -name "cygrpc*.so" -exec strip --strip-debug {} ";" - (cd "$TEMP_WHEEL_DIR" && zip -r - .) > "$1" + WHEEL_PATH="$1" + TEMP_WHEEL_DIR=$(mktemp -d) + python -m wheel unpack "$WHEEL_PATH" -d "$TEMP_WHEEL_DIR" + find "$TEMP_WHEEL_DIR" -name "_protoc_compiler*.so" -exec strip --strip-debug {} ";" + find "$TEMP_WHEEL_DIR" -name "cygrpc*.so" -exec strip --strip-debug {} ";" + + WHEEL_FILE=$(basename "$WHEEL_PATH") + DISTRIBUTION_NAME=$(basename "$WHEEL_PATH" | cut -d '-' -f 1) + VERSION=$(basename "$WHEEL_PATH" | cut -d '-' -f 2) + python -m wheel pack "$TEMP_WHEEL_DIR/$DISTRIBUTION_NAME-$VERSION" -d "$TEMP_WHEEL_DIR" + mv "$TEMP_WHEEL_DIR/$WHEEL_FILE" "$WHEEL_PATH" } for wheel in artifacts/*.whl; do diff --git a/tools/run_tests/artifacts/distribtest_targets.py b/tools/run_tests/artifacts/distribtest_targets.py index e02f4bffcd4..fd68a4dc747 100644 --- a/tools/run_tests/artifacts/distribtest_targets.py +++ b/tools/run_tests/artifacts/distribtest_targets.py @@ -336,9 +336,11 @@ def targets(): PythonDistribTest('linux', 'x64', 'ubuntu1404', source=True), PythonDistribTest('linux', 'x64', 'ubuntu1604', source=True), RubyDistribTest('linux', 'x64', 'wheezy'), - RubyDistribTest('linux', 'x64', 'jessie'), - RubyDistribTest('linux', 'x86', 'jessie'), - RubyDistribTest('linux', 'x64', 'jessie', ruby_version='ruby_2_0_0'), + RubyDistribTest('linux', 'x64', 'jessie', ruby_version='ruby_2_2'), + RubyDistribTest('linux', 'x64', 'jessie', ruby_version='ruby_2_3'), + RubyDistribTest('linux', 'x64', 'jessie', ruby_version='ruby_2_4'), + RubyDistribTest('linux', 'x64', 'jessie', ruby_version='ruby_2_5'), + RubyDistribTest('linux', 'x64', 'jessie', ruby_version='ruby_2_6'), RubyDistribTest('linux', 'x64', 'centos6'), RubyDistribTest('linux', 'x64', 'centos7'), RubyDistribTest('linux', 'x64', 'fedora20'), diff --git a/tools/run_tests/artifacts/run_in_workspace.sh b/tools/run_tests/artifacts/run_in_workspace.sh index 20181e077c2..f4719b0a4ae 100755 --- a/tools/run_tests/artifacts/run_in_workspace.sh +++ b/tools/run_tests/artifacts/run_in_workspace.sh @@ -19,7 +19,8 @@ set -ex cd "$(dirname "$0")/../../.." -export repo_root=$(pwd) +repo_root=$(pwd) +export repo_root # TODO: fix file to pass shellcheck diff --git a/tools/run_tests/dockerize/build_and_run_docker.sh b/tools/run_tests/dockerize/build_and_run_docker.sh index 3f01fbc7b7d..9d0efc8b407 100755 --- a/tools/run_tests/dockerize/build_and_run_docker.sh +++ b/tools/run_tests/dockerize/build_and_run_docker.sh @@ -20,7 +20,7 @@ set -ex cd "$(dirname "$0")/../../.." git_root=$(pwd) -cd - +cd - # shellcheck disable=SC2103 # Inputs # DOCKERFILE_DIR - Directory in which Dockerfile file is located. diff --git a/tools/run_tests/dockerize/build_docker_and_run_tests.sh b/tools/run_tests/dockerize/build_docker_and_run_tests.sh index 614049cae53..a63e1be96d2 100755 --- a/tools/run_tests/dockerize/build_docker_and_run_tests.sh +++ b/tools/run_tests/dockerize/build_docker_and_run_tests.sh @@ -20,10 +20,7 @@ set -ex cd "$(dirname "$0")/../../.." git_root=$(pwd) -cd - - -# Ensure existence of ccache directory -mkdir -p /tmp/ccache +cd - # shellcheck disable=SC2103 # Inputs # DOCKERFILE_DIR - Directory in which Dockerfile file is located. @@ -51,13 +48,12 @@ docker_instance_git_root=/var/local/jenkins/grpc # Run tests inside docker DOCKER_EXIT_CODE=0 # TODO: silence complaint about $TTY_FLAG expansion in some other way -# shellcheck disable=SC2086 +# shellcheck disable=SC2086,SC2154 docker run \ --cap-add SYS_PTRACE \ -e "RUN_TESTS_COMMAND=$RUN_TESTS_COMMAND" \ -e "config=$config" \ -e "arch=$arch" \ - -e CCACHE_DIR=/tmp/ccache \ -e THIS_IS_REALLY_NEEDED='see https://github.com/docker/docker/issues/14203 for why docker is awful' \ -e HOST_GIT_ROOT="$git_root" \ -e LOCAL_GIT_ROOT=$docker_instance_git_root \ @@ -73,7 +69,6 @@ docker run \ --sysctl net.ipv6.conf.all.disable_ipv6=0 \ -v ~/.config/gcloud:/root/.config/gcloud \ -v "$git_root:$docker_instance_git_root" \ - -v /tmp/ccache:/tmp/ccache \ -v /tmp/npm-cache:/tmp/npm-cache \ -w /var/local/git/grpc \ --name="$CONTAINER_NAME" \ diff --git a/tools/run_tests/dockerize/build_interop_image.sh b/tools/run_tests/dockerize/build_interop_image.sh index fcfcdeb4e41..fe37defd146 100755 --- a/tools/run_tests/dockerize/build_interop_image.sh +++ b/tools/run_tests/dockerize/build_interop_image.sh @@ -16,7 +16,7 @@ # This script is invoked by run_interop_tests.py to build the docker image # for interop testing. You should never need to call this script on your own. -set -x +set -ex # Params: # INTEROP_IMAGE - name of tag of the final interop image @@ -64,7 +64,13 @@ else echo "WARNING: grpc-node not found, it won't be mounted to the docker container." fi -mkdir -p /tmp/ccache +echo "GRPC_DOTNET_ROOT: ${GRPC_DOTNET_ROOT:=$(cd ../grpc-dotnet && pwd)}" +if [ -n "$GRPC_DOTNET_ROOT" ] +then + MOUNT_ARGS+=" -v $GRPC_DOTNET_ROOT:/var/local/jenkins/grpc-dotnet:ro" +else + echo "WARNING: grpc-dotnet not found, it won't be mounted to the docker container." +fi # Mount service account dir if available. # If service_directory does not contain the service account JSON file, @@ -92,9 +98,6 @@ else docker build -t "$BASE_IMAGE" --force-rm=true "tools/dockerfile/interoptest/$BASE_NAME" || exit $? fi -# Create a local branch so the child Docker script won't complain -git branch -f jenkins-docker - CONTAINER_NAME="build_${BASE_NAME}_$(uuidgen)" # Prepare image for interop tests, commit it on success. @@ -105,14 +108,12 @@ CONTAINER_NAME="build_${BASE_NAME}_$(uuidgen)" # shellcheck disable=SC2086 (docker run \ --cap-add SYS_PTRACE \ - -e CCACHE_DIR=/tmp/ccache \ -e THIS_IS_REALLY_NEEDED='see https://github.com/docker/docker/issues/14203 for why docker is awful' \ -e THIS_IS_REALLY_NEEDED_ONCE_AGAIN='For issue 4835. See https://github.com/docker/docker/issues/14203 for why docker is awful' \ -i \ $TTY_FLAG \ $MOUNT_ARGS \ $BUILD_INTEROP_DOCKER_EXTRA_ARGS \ - -v /tmp/ccache:/tmp/ccache \ --name="$CONTAINER_NAME" \ "$BASE_IMAGE" \ bash -l "/var/local/jenkins/grpc/tools/dockerfile/interoptest/$BASE_NAME/build_interop.sh" \ diff --git a/tools/run_tests/dockerize/docker_run_tests.sh b/tools/run_tests/dockerize/docker_run_tests.sh index c41734c92d2..2a3b6f53efa 100755 --- a/tools/run_tests/dockerize/docker_run_tests.sh +++ b/tools/run_tests/dockerize/docker_run_tests.sh @@ -18,7 +18,7 @@ set -e -export CONFIG=$config +export CONFIG=${config:-opt} export ASAN_SYMBOLIZER_PATH=/usr/bin/llvm-symbolizer export PATH=$PATH:/usr/bin/llvm-symbolizer @@ -38,16 +38,8 @@ exit_code=0 $RUN_TESTS_COMMAND || exit_code=$? -cd reports -echo '' > index.html -find . -maxdepth 1 -mindepth 1 -type d | sort | while read d ; do - d=${d#*/} - n=${d//_/ } - echo "$n
" >> index.html -done -echo '' >> index.html -cd .. - +# The easiest way to copy all the reports files from inside of +# the docker container is to zip them and then copy the zip. zip -r reports.zip reports find . -name report.xml -print0 | xargs -0 -r zip reports.zip find . -name sponge_log.xml -print0 | xargs -0 -r zip reports.zip diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 100eb45ac53..452cad3022d 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -4,7 +4,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -21,7 +20,8 @@ { "deps": [ "gpr", - "gpr_test_util" + "grpc_test_util_unsecure", + "grpc_unsecure" ], "headers": [], "is_filegroup": false, @@ -36,7 +36,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -53,7 +52,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -70,7 +68,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -87,7 +84,8 @@ { "deps": [ "gpr", - "gpr_test_util" + "grpc_test_util_unsecure", + "grpc_unsecure" ], "headers": [], "is_filegroup": false, @@ -102,8 +100,8 @@ { "deps": [ "gpr", - "gpr_test_util", - "grpc" + "grpc", + "grpc_test_util" ], "headers": [], "is_filegroup": false, @@ -118,7 +116,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util", "test_tcp_server" @@ -166,7 +163,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -183,7 +179,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -215,7 +210,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -232,7 +226,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -249,7 +242,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -266,7 +258,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -283,7 +274,23 @@ { "deps": [ "gpr", - "gpr_test_util", + "grpc", + "grpc_test_util" + ], + "headers": [], + "is_filegroup": false, + "language": "c", + "name": "close_fd_test", + "src": [ + "test/core/bad_connection/close_fd_test.cc" + ], + "third_party": false, + "type": "target" + }, + { + "deps": [ + "gpr", + "grpc", "grpc_test_util" ], "headers": [], @@ -299,7 +306,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -316,7 +322,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -333,7 +338,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -350,7 +354,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -367,7 +370,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -384,7 +386,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -401,7 +402,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -418,7 +418,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -435,7 +434,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -452,7 +450,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -469,7 +466,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -486,7 +482,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -503,8 +498,8 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", + "grpc_test_util", "transport_security_test_lib" ], "headers": [], @@ -520,7 +515,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -537,7 +531,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -554,7 +547,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -571,7 +563,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -588,7 +579,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -605,7 +595,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -622,7 +611,8 @@ { "deps": [ "gpr", - "gpr_test_util" + "grpc_test_util_unsecure", + "grpc_unsecure" ], "headers": [], "is_filegroup": false, @@ -637,7 +627,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -654,7 +643,8 @@ { "deps": [ "gpr", - "gpr_test_util" + "grpc_test_util_unsecure", + "grpc_unsecure" ], "headers": [], "is_filegroup": false, @@ -669,7 +659,8 @@ { "deps": [ "gpr", - "gpr_test_util" + "grpc_test_util_unsecure", + "grpc_unsecure" ], "headers": [], "is_filegroup": false, @@ -684,7 +675,8 @@ { "deps": [ "gpr", - "gpr_test_util" + "grpc_test_util_unsecure", + "grpc_unsecure" ], "headers": [], "is_filegroup": false, @@ -699,7 +691,8 @@ { "deps": [ "gpr", - "gpr_test_util" + "grpc_test_util_unsecure", + "grpc_unsecure" ], "headers": [], "is_filegroup": false, @@ -714,7 +707,8 @@ { "deps": [ "gpr", - "gpr_test_util" + "grpc_test_util_unsecure", + "grpc_unsecure" ], "headers": [], "is_filegroup": false, @@ -729,7 +723,8 @@ { "deps": [ "gpr", - "gpr_test_util" + "grpc_test_util_unsecure", + "grpc_unsecure" ], "headers": [], "is_filegroup": false, @@ -744,7 +739,8 @@ { "deps": [ "gpr", - "gpr_test_util" + "grpc_test_util_unsecure", + "grpc_unsecure" ], "headers": [], "is_filegroup": false, @@ -759,7 +755,8 @@ { "deps": [ "gpr", - "gpr_test_util" + "grpc_test_util_unsecure", + "grpc_unsecure" ], "headers": [], "is_filegroup": false, @@ -774,7 +771,8 @@ { "deps": [ "gpr", - "gpr_test_util" + "grpc_test_util_unsecure", + "grpc_unsecure" ], "headers": [], "is_filegroup": false, @@ -789,7 +787,8 @@ { "deps": [ "gpr", - "gpr_test_util" + "grpc_test_util_unsecure", + "grpc_unsecure" ], "headers": [], "is_filegroup": false, @@ -804,7 +803,8 @@ { "deps": [ "gpr", - "gpr_test_util" + "grpc_test_util_unsecure", + "grpc_unsecure" ], "headers": [], "is_filegroup": false, @@ -819,7 +819,8 @@ { "deps": [ "gpr", - "gpr_test_util" + "grpc_test_util_unsecure", + "grpc_unsecure" ], "headers": [], "is_filegroup": false, @@ -834,7 +835,8 @@ { "deps": [ "gpr", - "gpr_test_util" + "grpc_test_util_unsecure", + "grpc_unsecure" ], "headers": [], "is_filegroup": false, @@ -849,7 +851,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -866,7 +867,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -883,7 +883,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -900,7 +899,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -917,7 +915,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -934,7 +931,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -951,7 +947,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -968,7 +963,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1001,7 +995,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1018,7 +1011,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1035,7 +1027,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1052,7 +1043,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1069,7 +1059,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1102,7 +1091,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1119,7 +1107,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1152,7 +1139,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1169,7 +1155,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1190,7 +1175,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1211,7 +1195,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1243,7 +1226,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1260,7 +1242,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1277,7 +1258,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1294,7 +1274,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1311,7 +1290,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1328,7 +1306,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1345,7 +1322,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1362,7 +1338,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1379,7 +1354,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1396,7 +1370,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1413,7 +1386,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1433,7 +1405,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1450,7 +1421,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1467,7 +1437,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1484,7 +1453,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1501,7 +1469,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1518,7 +1485,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1535,7 +1501,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1552,7 +1517,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1569,7 +1533,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1586,7 +1549,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1603,7 +1565,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1620,7 +1581,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1637,7 +1597,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1654,7 +1613,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1671,7 +1629,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1688,7 +1645,8 @@ { "deps": [ "gpr", - "gpr_test_util" + "grpc_test_util_unsecure", + "grpc_unsecure" ], "headers": [], "is_filegroup": false, @@ -1703,7 +1661,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1720,7 +1677,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1737,7 +1693,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1754,7 +1709,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1771,7 +1725,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1788,7 +1741,22 @@ { "deps": [ "gpr", - "gpr_test_util", + "grpc", + "grpc_test_util" + ], + "headers": [], + "is_filegroup": false, + "language": "c", + "name": "parse_address_with_named_scope_id_test", + "src": [ + "test/core/client_channel/parse_address_with_named_scope_id_test.cc" + ], + "third_party": false, + "type": "target" + }, + { + "deps": [ + "gpr", "grpc", "grpc_test_util" ], @@ -1805,7 +1773,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1822,7 +1789,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1839,14 +1805,13 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], "headers": [], "is_filegroup": false, "language": "c", - "name": "resolve_address_posix_test", + "name": "resolve_address_using_ares_resolver_posix_test", "src": [ "test/core/iomgr/resolve_address_posix_test.cc" ], @@ -1856,7 +1821,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1873,7 +1837,22 @@ { "deps": [ "gpr", - "gpr_test_util", + "grpc", + "grpc_test_util" + ], + "headers": [], + "is_filegroup": false, + "language": "c", + "name": "resolve_address_using_native_resolver_posix_test", + "src": [ + "test/core/iomgr/resolve_address_posix_test.cc" + ], + "third_party": false, + "type": "target" + }, + { + "deps": [ + "gpr", "grpc", "grpc_test_util" ], @@ -1890,7 +1869,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1907,7 +1885,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1924,7 +1901,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1941,7 +1917,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1958,7 +1933,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1975,7 +1949,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -1992,7 +1965,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2009,7 +1981,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2026,7 +1997,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2043,7 +2013,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2060,7 +2029,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2077,7 +2045,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2094,7 +2061,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2111,7 +2077,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2128,8 +2093,8 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", + "grpc_test_util", "transport_security_test_lib" ], "headers": [], @@ -2145,7 +2110,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2162,7 +2126,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2179,7 +2142,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2196,7 +2158,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2213,7 +2174,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2230,7 +2190,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2247,7 +2206,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2264,7 +2222,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2281,7 +2238,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2298,7 +2254,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2315,7 +2270,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2332,7 +2286,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2349,7 +2302,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2366,7 +2318,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2383,7 +2334,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2400,7 +2350,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2417,7 +2366,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2434,7 +2382,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2451,24 +2398,6 @@ { "deps": [ "gpr", - "gpr_test_util", - "grpc", - "grpc_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c", - "name": "wakeup_fd_cv_test", - "src": [ - "test/core/iomgr/wakeup_fd_cv_test.cc" - ], - "third_party": false, - "type": "target" - }, - { - "deps": [ - "gpr", - "gpr_test_util", "grpc++_test_util_unsecure", "grpc++_unsecure", "grpc_test_util_unsecure", @@ -2504,8 +2433,8 @@ "deps": [ "alts_test_util", "gpr", - "gpr_test_util", - "grpc" + "grpc", + "grpc_test_util" ], "headers": [], "is_filegroup": false, @@ -2696,7 +2625,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -2715,7 +2643,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -2734,7 +2661,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -2751,7 +2677,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -2771,7 +2696,27 @@ "deps": [ "benchmark", "gpr", - "gpr_test_util", + "grpc++_test_config", + "grpc++_test_util_unsecure", + "grpc++_unsecure", + "grpc_benchmark", + "grpc_test_util_unsecure", + "grpc_unsecure" + ], + "headers": [], + "is_filegroup": false, + "language": "c++", + "name": "bm_alarm", + "src": [ + "test/cpp/microbenchmarks/bm_alarm.cc" + ], + "third_party": false, + "type": "target" + }, + { + "deps": [ + "benchmark", + "gpr", "grpc++_test_config", "grpc++_test_util_unsecure", "grpc++_unsecure", @@ -2793,7 +2738,27 @@ "deps": [ "benchmark", "gpr", - "gpr_test_util", + "grpc++_test_config", + "grpc++_test_util_unsecure", + "grpc++_unsecure", + "grpc_benchmark", + "grpc_test_util_unsecure", + "grpc_unsecure" + ], + "headers": [], + "is_filegroup": false, + "language": "c++", + "name": "bm_byte_buffer", + "src": [ + "test/cpp/microbenchmarks/bm_byte_buffer.cc" + ], + "third_party": false, + "type": "target" + }, + { + "deps": [ + "benchmark", + "gpr", "grpc++_test_config", "grpc++_test_util_unsecure", "grpc++_unsecure", @@ -2811,11 +2776,60 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "benchmark", + "bm_callback_test_service_impl", + "gpr", + "grpc++_test_config", + "grpc++_test_util_unsecure", + "grpc++_unsecure", + "grpc_benchmark", + "grpc_test_util_unsecure", + "grpc_unsecure" + ], + "headers": [ + "test/cpp/microbenchmarks/callback_streaming_ping_pong.h" + ], + "is_filegroup": false, + "language": "c++", + "name": "bm_callback_streaming_ping_pong", + "src": [ + "test/cpp/microbenchmarks/bm_callback_streaming_ping_pong.cc", + "test/cpp/microbenchmarks/callback_streaming_ping_pong.h" + ], + "third_party": false, + "type": "target" + }, + { + "deps": [ + "benchmark", + "bm_callback_test_service_impl", + "gpr", + "grpc++_test_config", + "grpc++_test_util_unsecure", + "grpc++_unsecure", + "grpc_benchmark", + "grpc_test_util_unsecure", + "grpc_unsecure" + ], + "headers": [ + "test/cpp/microbenchmarks/callback_unary_ping_pong.h" + ], + "is_filegroup": false, + "language": "c++", + "name": "bm_callback_unary_ping_pong", + "src": [ + "test/cpp/microbenchmarks/bm_callback_unary_ping_pong.cc", + "test/cpp/microbenchmarks/callback_unary_ping_pong.h" + ], + "third_party": false, + "type": "target" + }, { "deps": [ "benchmark", "gpr", - "gpr_test_util", "grpc++_test_config", "grpc++_test_util_unsecure", "grpc++_unsecure", @@ -2837,7 +2851,6 @@ "deps": [ "benchmark", "gpr", - "gpr_test_util", "grpc++_test_config", "grpc++_test_util_unsecure", "grpc++_unsecure", @@ -2859,7 +2872,6 @@ "deps": [ "benchmark", "gpr", - "gpr_test_util", "grpc++_test_config", "grpc++_test_util_unsecure", "grpc++_unsecure", @@ -2881,7 +2893,6 @@ "deps": [ "benchmark", "gpr", - "gpr_test_util", "grpc++_test_config", "grpc++_test_util_unsecure", "grpc++_unsecure", @@ -2903,7 +2914,6 @@ "deps": [ "benchmark", "gpr", - "gpr_test_util", "grpc++_test_config", "grpc++_test_util_unsecure", "grpc++_unsecure", @@ -2925,7 +2935,6 @@ "deps": [ "benchmark", "gpr", - "gpr_test_util", "grpc++_test_config", "grpc++_test_util_unsecure", "grpc++_unsecure", @@ -2947,7 +2956,6 @@ "deps": [ "benchmark", "gpr", - "gpr_test_util", "grpc++_test_config", "grpc++_test_util_unsecure", "grpc++_unsecure", @@ -2969,7 +2977,6 @@ "deps": [ "benchmark", "gpr", - "gpr_test_util", "grpc++_test_config", "grpc++_test_util_unsecure", "grpc++_unsecure", @@ -2994,7 +3001,6 @@ "deps": [ "benchmark", "gpr", - "gpr_test_util", "grpc++_test_config", "grpc++_test_util_unsecure", "grpc++_unsecure", @@ -3019,7 +3025,6 @@ "deps": [ "benchmark", "gpr", - "gpr_test_util", "grpc++_test_config", "grpc++_test_util_unsecure", "grpc++_unsecure", @@ -3041,7 +3046,6 @@ "deps": [ "benchmark", "gpr", - "gpr_test_util", "grpc++_test_config", "grpc++_test_util_unsecure", "grpc++_unsecure", @@ -3066,7 +3070,6 @@ "deps": [ "benchmark", "gpr", - "gpr_test_util", "grpc++_test_config", "grpc++_test_util_unsecure", "grpc++_unsecure", @@ -3088,7 +3091,6 @@ "deps": [ "benchmark", "gpr", - "gpr_test_util", "grpc++_test_config", "grpc++_test_util_unsecure", "grpc++_unsecure", @@ -3106,10 +3108,30 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "benchmark", + "gpr", + "grpc++_test_config", + "grpc++_test_util_unsecure", + "grpc++_unsecure", + "grpc_benchmark", + "grpc_test_util_unsecure", + "grpc_unsecure" + ], + "headers": [], + "is_filegroup": false, + "language": "c++", + "name": "bm_timer", + "src": [ + "test/cpp/microbenchmarks/bm_timer.cc" + ], + "third_party": false, + "type": "target" + }, { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -3158,7 +3180,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test", @@ -3179,7 +3200,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test", @@ -3199,7 +3219,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -3220,7 +3239,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test", @@ -3271,7 +3289,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -3288,7 +3305,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -3308,7 +3324,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -3319,7 +3334,8 @@ "language": "c++", "name": "client_callback_end2end_test", "src": [ - "test/cpp/end2end/client_callback_end2end_test.cc" + "test/cpp/end2end/client_callback_end2end_test.cc", + "test/cpp/end2end/interceptors_util.cc" ], "third_party": false, "type": "target" @@ -3327,7 +3343,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -3350,7 +3365,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -3369,9 +3383,9 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", + "grpc++_test_config", "grpc++_test_util", "grpc_test_util" ], @@ -3388,7 +3402,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -3411,7 +3424,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -3507,6 +3519,22 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "gpr", + "grpc", + "grpc_test_util" + ], + "headers": [], + "is_filegroup": false, + "language": "c++", + "name": "context_list_test", + "src": [ + "test/core/transport/chttp2/context_list_test.cc" + ], + "third_party": false, + "type": "target" + }, { "deps": [ "gpr", @@ -3526,7 +3554,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc_test_util" @@ -3544,7 +3571,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc_test_util" @@ -3577,7 +3603,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc_test_util" @@ -3595,7 +3620,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -3637,7 +3661,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -3656,7 +3679,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -3675,7 +3697,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -3691,11 +3712,42 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "gpr", + "grpc_test_util_unsecure" + ], + "headers": [], + "is_filegroup": false, + "language": "c++", + "name": "global_config_env_test", + "src": [ + "test/core/gprpp/global_config_env_test.cc" + ], + "third_party": false, + "type": "target" + }, + { + "deps": [ + "gpr", + "grpc_test_util_unsecure" + ], + "headers": [], + "is_filegroup": false, + "language": "c++", + "name": "global_config_test", + "src": [ + "test/core/gprpp/global_config_test.cc" + ], + "third_party": false, + "type": "target" + }, { "deps": [ "gpr", "grpc", - "grpc++" + "grpc++", + "grpc++_test_config" ], "headers": [ "src/proto/grpc/testing/compiler_test.grpc.pb.h", @@ -3745,6 +3797,27 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "gpr", + "grpc", + "grpc++", + "grpc++_test", + "grpc_test_util" + ], + "headers": [ + "test/core/gprpp/map_tester.h" + ], + "is_filegroup": false, + "language": "c++", + "name": "grpc_core_map_test", + "src": [ + "test/core/gprpp/map_test.cc", + "test/core/gprpp/map_tester.h" + ], + "third_party": false, + "type": "target" + }, { "deps": [ "grpc_plugin_support" @@ -3776,7 +3849,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -3863,7 +3935,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_codegen_proto", @@ -3914,7 +3985,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -3937,7 +4007,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test", @@ -3959,7 +4028,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test", @@ -3981,7 +4049,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -4017,7 +4084,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -4036,7 +4102,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test", @@ -4055,7 +4120,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_core_stats", @@ -4077,7 +4141,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_config", @@ -4097,7 +4160,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_config", @@ -4118,7 +4180,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++_test_config", "grpc_test_util" @@ -4136,7 +4197,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_config", @@ -4156,7 +4216,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test", @@ -4172,6 +4231,24 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "gpr", + "grpc", + "grpc++", + "grpc++_test_util", + "grpc_test_util" + ], + "headers": [], + "is_filegroup": false, + "language": "c++", + "name": "message_allocator_end2end_test", + "src": [ + "test/cpp/end2end/message_allocator_end2end_test.cc" + ], + "third_party": false, + "type": "target" + }, { "deps": [ "gpr", @@ -4198,7 +4275,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -4222,7 +4298,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -4255,7 +4330,24 @@ { "deps": [ "gpr", - "gpr_test_util", + "grpc", + "grpc++", + "grpc++_test", + "grpc_test_util" + ], + "headers": [], + "is_filegroup": false, + "language": "c++", + "name": "optional_test", + "src": [ + "test/core/gprpp/optional_test.cc" + ], + "third_party": false, + "type": "target" + }, + { + "deps": [ + "gpr", "grpc", "grpc++", "grpc++_test", @@ -4274,7 +4366,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_proto_reflection_desc_db", @@ -4312,7 +4403,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_config", @@ -4333,7 +4423,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_core_stats", @@ -4355,7 +4444,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_core_stats", @@ -4377,7 +4465,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_core_stats", @@ -4404,7 +4491,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -4423,7 +4509,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_config", @@ -4453,7 +4538,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_config", @@ -4485,7 +4569,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test", @@ -4504,7 +4587,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test", @@ -4523,7 +4605,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -4540,7 +4621,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -4559,7 +4639,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_core_stats", @@ -4581,7 +4660,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -4600,7 +4678,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc++_test_util_unsecure", "grpc++_unsecure", "grpc_test_util_unsecure", @@ -4626,7 +4703,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc++_test_util_unsecure", "grpc++_unsecure", "grpc_test_util_unsecure", @@ -4652,7 +4728,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test", @@ -4671,7 +4746,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -4690,9 +4764,9 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", + "grpc++_test_config", "grpc++_test_util", "grpc_test_util" ], @@ -4709,7 +4783,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -4728,7 +4801,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -4751,7 +4823,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc++_test_util_unsecure", "grpc++_unsecure", "grpc_test_util_unsecure", @@ -4777,7 +4848,42 @@ { "deps": [ "gpr", - "gpr_test_util", + "grpc", + "grpc++", + "grpc++_test_util", + "grpc_test_util" + ], + "headers": [], + "is_filegroup": false, + "language": "c++", + "name": "service_config_end2end_test", + "src": [ + "test/cpp/end2end/service_config_end2end_test.cc" + ], + "third_party": false, + "type": "target" + }, + { + "deps": [ + "gpr", + "grpc", + "grpc++", + "grpc++_test", + "grpc_test_util" + ], + "headers": [], + "is_filegroup": false, + "language": "c++", + "name": "service_config_test", + "src": [ + "test/core/client_channel/service_config_test.cc" + ], + "third_party": false, + "type": "target" + }, + { + "deps": [ + "gpr", "grpc", "grpc++", "grpc++_test_util", @@ -4796,7 +4902,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -4813,7 +4918,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -4830,7 +4934,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++_test_util", "grpc_test_util" @@ -4876,7 +4979,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -4895,7 +4997,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_config", @@ -4958,7 +5059,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc++_test_util_unsecure", "grpc++_unsecure", "grpc_test_util_unsecure", @@ -4977,7 +5077,24 @@ { "deps": [ "gpr", - "gpr_test_util", + "grpc", + "grpc++", + "grpc++_test_util", + "grpc_test_util" + ], + "headers": [], + "is_filegroup": false, + "language": "c++", + "name": "time_change_test", + "src": [ + "test/cpp/end2end/time_change_test.cc" + ], + "third_party": false, + "type": "target" + }, + { + "deps": [ + "gpr", "grpc", "grpc++", "grpc++_test_util", @@ -5012,7 +5129,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_util", @@ -5028,6 +5144,28 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "gpr", + "grpc", + "grpc++", + "grpc++_test_util", + "grpc_test_util" + ], + "headers": [ + "src/proto/grpc/lb/v1/load_balancer.grpc.pb.h", + "src/proto/grpc/lb/v1/load_balancer.pb.h", + "src/proto/grpc/lb/v1/load_balancer_mock.grpc.pb.h" + ], + "is_filegroup": false, + "language": "c++", + "name": "xds_end2end_test", + "src": [ + "test/cpp/end2end/xds_end2end_test.cc" + ], + "third_party": false, + "type": "target" + }, { "deps": [ "gpr", @@ -5085,707 +5223,6 @@ { "deps": [ "boringssl", - "boringssl_crypto_test_data_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_crypto_test_data", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_asn1_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_asn1_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_base64_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_base64_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_bio_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_bio_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_buf_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_buf_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_bytestring_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_bytestring_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_chacha_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_chacha_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_aead_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_aead_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_cipher_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_cipher_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_cmac_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_cmac_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_compiler_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_compiler_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_constant_time_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_constant_time_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_ed25519_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_ed25519_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_spake25519_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_spake25519_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util", - "boringssl_x25519_test_lib" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_x25519_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_dh_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_dh_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_digest_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_digest_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_dsa_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_dsa_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_ecdh_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_ecdh_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_err_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_err_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_evp_extra_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_evp_extra_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_evp_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_evp_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_pbkdf_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_pbkdf_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_scrypt_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_scrypt_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_aes_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_aes_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_bn_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_bn_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_ec_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_ec_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_p256-x86_64_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_p256-x86_64_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_ecdsa_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_ecdsa_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_gcm_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_gcm_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_ctrdrbg_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_ctrdrbg_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_hkdf_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_hkdf_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_hmac_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_hmac_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_lhash_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_lhash_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_obj_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_obj_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_pkcs7_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_pkcs7_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_pkcs12_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_pkcs12_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_pkcs8_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_pkcs8_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_poly1305_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_poly1305_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_pool_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_pool_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_refcount_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_refcount_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_rsa_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_rsa_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_self_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_self_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_file_test_gtest_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_file_test_gtest", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_gtest_main_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_gtest_main", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util", - "boringssl_thread_test_lib" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_thread_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util", - "boringssl_x509_test_lib" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_x509_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_tab_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_tab_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util", - "boringssl_v3name_test_lib" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_v3name_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_span_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_span_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_ssl_test_lib", "boringssl_test_util" ], "headers": [], @@ -5796,11 +5233,25 @@ "third_party": true, "type": "target" }, + { + "deps": [ + "boringssl", + "boringssl_test_util" + ], + "headers": [], + "is_filegroup": false, + "language": "c++", + "name": "boringssl_crypto_test", + "src": [ + "src/boringssl/crypto_test_data.cc" + ], + "third_party": true, + "type": "target" + }, { "deps": [ "bad_client_test", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -5818,7 +5269,6 @@ "deps": [ "bad_client_test", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -5836,7 +5286,6 @@ "deps": [ "bad_client_test", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -5854,7 +5303,6 @@ "deps": [ "bad_client_test", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -5872,7 +5320,6 @@ "deps": [ "bad_client_test", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -5890,7 +5337,6 @@ "deps": [ "bad_client_test", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -5908,7 +5354,6 @@ "deps": [ "bad_client_test", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -5926,7 +5371,6 @@ "deps": [ "bad_client_test", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -5944,7 +5388,6 @@ "deps": [ "bad_client_test", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -5962,7 +5405,6 @@ "deps": [ "bad_client_test", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -5980,7 +5422,6 @@ "deps": [ "bad_client_test", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -5998,7 +5439,6 @@ "deps": [ "bad_ssl_test_server", "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6015,7 +5455,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6033,7 +5472,6 @@ "deps": [ "end2end_tests", "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6051,7 +5489,6 @@ "deps": [ "end2end_tests", "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6069,7 +5506,6 @@ "deps": [ "end2end_tests", "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6087,7 +5523,6 @@ "deps": [ "end2end_tests", "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6105,7 +5540,6 @@ "deps": [ "end2end_tests", "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6123,7 +5557,6 @@ "deps": [ "end2end_tests", "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6141,7 +5574,6 @@ "deps": [ "end2end_tests", "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6159,7 +5591,6 @@ "deps": [ "end2end_tests", "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6177,7 +5608,6 @@ "deps": [ "end2end_tests", "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6195,16 +5625,49 @@ "deps": [ "end2end_tests", "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], "headers": [], "is_filegroup": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "src": [ - "test/core/end2end/fixtures/h2_local.cc" + "test/core/end2end/fixtures/h2_local_ipv4.cc" + ], + "third_party": false, + "type": "target" + }, + { + "deps": [ + "end2end_tests", + "gpr", + "grpc", + "grpc_test_util" + ], + "headers": [], + "is_filegroup": false, + "language": "c", + "name": "h2_local_ipv6_test", + "src": [ + "test/core/end2end/fixtures/h2_local_ipv6.cc" + ], + "third_party": false, + "type": "target" + }, + { + "deps": [ + "end2end_tests", + "gpr", + "grpc", + "grpc_test_util" + ], + "headers": [], + "is_filegroup": false, + "language": "c", + "name": "h2_local_uds_test", + "src": [ + "test/core/end2end/fixtures/h2_local_uds.cc" ], "third_party": false, "type": "target" @@ -6213,7 +5676,6 @@ "deps": [ "end2end_tests", "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6231,7 +5693,6 @@ "deps": [ "end2end_tests", "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6249,7 +5710,6 @@ "deps": [ "end2end_tests", "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6267,7 +5727,6 @@ "deps": [ "end2end_tests", "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6285,7 +5744,6 @@ "deps": [ "end2end_tests", "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6303,7 +5761,23 @@ "deps": [ "end2end_tests", "gpr", - "gpr_test_util", + "grpc", + "grpc_test_util" + ], + "headers": [], + "is_filegroup": false, + "language": "c", + "name": "h2_spiffe_test", + "src": [ + "test/core/end2end/fixtures/h2_spiffe.cc" + ], + "third_party": false, + "type": "target" + }, + { + "deps": [ + "end2end_tests", + "gpr", "grpc", "grpc_test_util" ], @@ -6321,7 +5795,23 @@ "deps": [ "end2end_tests", "gpr", - "gpr_test_util", + "grpc", + "grpc_test_util" + ], + "headers": [], + "is_filegroup": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "src": [ + "test/core/end2end/fixtures/h2_ssl_cred_reload.cc" + ], + "third_party": false, + "type": "target" + }, + { + "deps": [ + "end2end_tests", + "gpr", "grpc", "grpc_test_util" ], @@ -6339,7 +5829,6 @@ "deps": [ "end2end_tests", "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6357,7 +5846,6 @@ "deps": [ "end2end_tests", "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6375,7 +5863,6 @@ "deps": [ "end2end_nosec_tests", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -6393,7 +5880,6 @@ "deps": [ "end2end_nosec_tests", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -6411,7 +5897,6 @@ "deps": [ "end2end_nosec_tests", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -6429,7 +5914,6 @@ "deps": [ "end2end_nosec_tests", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -6447,7 +5931,6 @@ "deps": [ "end2end_nosec_tests", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -6465,7 +5948,6 @@ "deps": [ "end2end_nosec_tests", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -6483,7 +5965,6 @@ "deps": [ "end2end_nosec_tests", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -6501,7 +5982,6 @@ "deps": [ "end2end_nosec_tests", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -6519,7 +5999,6 @@ "deps": [ "end2end_nosec_tests", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -6537,7 +6016,6 @@ "deps": [ "end2end_nosec_tests", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -6555,7 +6033,6 @@ "deps": [ "end2end_nosec_tests", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -6573,7 +6050,6 @@ "deps": [ "end2end_nosec_tests", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -6591,7 +6067,6 @@ "deps": [ "end2end_nosec_tests", "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -6607,8 +6082,8 @@ }, { "deps": [ + "dns_test_util", "gpr", - "gpr_test_util", "grpc++_test_config", "grpc++_test_util_unsecure", "grpc++_unsecure", @@ -6627,8 +6102,8 @@ }, { "deps": [ + "dns_test_util", "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_config", @@ -6648,7 +6123,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_config", @@ -6668,7 +6142,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_config", @@ -6688,7 +6161,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc++_test_config", "grpc++_test_util_unsecure", "grpc++_unsecure", @@ -6708,7 +6180,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_config", @@ -6727,8 +6198,8 @@ }, { "deps": [ + "dns_test_util", "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_config", @@ -6748,7 +6219,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6766,7 +6236,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6784,7 +6253,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6802,7 +6270,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6820,7 +6287,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6838,7 +6304,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6856,7 +6321,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6874,7 +6338,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6892,7 +6355,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6910,7 +6372,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6928,7 +6389,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6946,7 +6406,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6964,7 +6423,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -6982,7 +6440,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -7052,23 +6509,6 @@ "third_party": false, "type": "lib" }, - { - "deps": [ - "gpr" - ], - "headers": [ - "test/core/util/test_config.h" - ], - "is_filegroup": false, - "language": "c", - "name": "gpr_test_util", - "src": [ - "test/core/util/test_config.cc", - "test/core/util/test_config.h" - ], - "third_party": false, - "type": "lib" - }, { "deps": [ "census", @@ -7125,7 +6565,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util_base" ], @@ -7151,7 +6590,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc_test_util_base", "grpc_unsecure" ], @@ -7200,7 +6638,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util", "test_tcp_server" @@ -7221,7 +6658,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -7238,6 +6674,48 @@ "third_party": false, "type": "lib" }, + { + "deps": [ + "benchmark", + "gpr", + "grpc++_test_config", + "grpc++_test_util_unsecure", + "grpc++_unsecure", + "grpc_benchmark", + "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_mock.grpc.pb.h", + "test/cpp/microbenchmarks/callback_test_service.h" + ], + "is_filegroup": false, + "language": "c++", + "name": "bm_callback_test_service_impl", + "src": [ + "test/cpp/microbenchmarks/callback_test_service.cc", + "test/cpp/microbenchmarks/callback_test_service.h" + ], + "third_party": false, + "type": "lib" + }, + { + "deps": [], + "headers": [ + "test/cpp/naming/dns_test_util.h" + ], + "is_filegroup": false, + "language": "c++", + "name": "dns_test_util", + "src": [ + "test/cpp/naming/dns_test_util.cc", + "test/cpp/naming/dns_test_util.h" + ], + "third_party": false, + "type": "lib" + }, { "deps": [ "gpr", @@ -7327,6 +6805,7 @@ "headers": [ "include/grpc++/support/error_details.h", "include/grpcpp/support/error_details.h", + "include/grpcpp/support/error_details_impl.h", "src/proto/grpc/status/status.grpc.pb.h", "src/proto/grpc/status/status.pb.h", "src/proto/grpc/status/status_mock.grpc.pb.h" @@ -7337,6 +6816,7 @@ "src": [ "include/grpc++/support/error_details.h", "include/grpcpp/support/error_details.h", + "include/grpcpp/support/error_details_impl.h", "src/cpp/util/error_details.cc" ], "third_party": false, @@ -7371,6 +6851,7 @@ "headers": [ "include/grpc++/ext/proto_server_reflection_plugin.h", "include/grpcpp/ext/proto_server_reflection_plugin.h", + "include/grpcpp/ext/proto_server_reflection_plugin_impl.h", "src/cpp/ext/proto_server_reflection.h" ], "is_filegroup": false, @@ -7379,6 +6860,7 @@ "src": [ "include/grpc++/ext/proto_server_reflection_plugin.h", "include/grpcpp/ext/proto_server_reflection_plugin.h", + "include/grpcpp/ext/proto_server_reflection_plugin_impl.h", "src/cpp/ext/proto_server_reflection.cc", "src/cpp/ext/proto_server_reflection.h", "src/cpp/ext/proto_server_reflection_plugin.cc" @@ -7427,6 +6909,10 @@ "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", + "src/proto/grpc/testing/simple_messages.grpc.pb.h", + "src/proto/grpc/testing/simple_messages.pb.h", + "src/proto/grpc/testing/simple_messages_mock.grpc.pb.h", + "test/cpp/end2end/test_health_check_service_impl.h", "test/cpp/end2end/test_service_impl.h", "test/cpp/util/byte_buffer_proto_helper.h", "test/cpp/util/channel_trace_proto_helper.h", @@ -7439,6 +6925,8 @@ "language": "c++", "name": "grpc++_test_util", "src": [ + "test/cpp/end2end/test_health_check_service_impl.cc", + "test/cpp/end2end/test_health_check_service_impl.h", "test/cpp/end2end/test_service_impl.cc", "test/cpp/end2end/test_service_impl.h", "test/cpp/util/byte_buffer_proto_helper.cc", @@ -7480,6 +6968,10 @@ "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", + "src/proto/grpc/testing/simple_messages.grpc.pb.h", + "src/proto/grpc/testing/simple_messages.pb.h", + "src/proto/grpc/testing/simple_messages_mock.grpc.pb.h", + "test/cpp/end2end/test_health_check_service_impl.h", "test/cpp/end2end/test_service_impl.h", "test/cpp/util/byte_buffer_proto_helper.h", "test/cpp/util/string_ref_helper.h", @@ -7489,6 +6981,8 @@ "language": "c++", "name": "grpc++_test_util_unsecure", "src": [ + "test/cpp/end2end/test_health_check_service_impl.cc", + "test/cpp/end2end/test_health_check_service_impl.h", "test/cpp/end2end/test_service_impl.cc", "test/cpp/end2end/test_service_impl.h", "test/cpp/util/byte_buffer_proto_helper.cc", @@ -7651,6 +7145,7 @@ ], "headers": [ "include/grpcpp/ext/channelz_service_plugin.h", + "include/grpcpp/ext/channelz_service_plugin_impl.h", "src/cpp/server/channelz/channelz_service.h" ], "is_filegroup": false, @@ -7658,6 +7153,7 @@ "name": "grpcpp_channelz", "src": [ "include/grpcpp/ext/channelz_service_plugin.h", + "include/grpcpp/ext/channelz_service_plugin_impl.h", "src/cpp/server/channelz/channelz_service.cc", "src/cpp/server/channelz/channelz_service.h", "src/cpp/server/channelz/channelz_service_plugin.cc" @@ -7722,7 +7218,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_config", @@ -7777,7 +7272,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc++", "grpc++_test_config", @@ -8106,679 +7600,13 @@ "third_party": true, "type": "lib" }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_crypto_test_data_lib", - "src": [ - "src/boringssl/crypto_test_data.cc" - ], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_asn1_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_base64_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_bio_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_buf_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_bytestring_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_chacha_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_aead_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_cipher_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_cmac_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_compiler_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_constant_time_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_ed25519_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_spake25519_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_x25519_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_dh_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_digest_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_dsa_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_ecdh_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_err_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_evp_extra_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_evp_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_pbkdf_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_scrypt_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_aes_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_bn_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_ec_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_p256-x86_64_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_ecdsa_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_gcm_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_ctrdrbg_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_hkdf_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_hmac_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_lhash_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_obj_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_pkcs7_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_pkcs12_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_pkcs8_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_poly1305_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_pool_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_refcount_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_rsa_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_self_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_file_test_gtest_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_gtest_main_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_thread_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_x509_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_tab_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_v3name_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_span_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_ssl_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, { "deps": [], "headers": [ "third_party/benchmark/include/benchmark/benchmark.h", - "third_party/benchmark/include/benchmark/benchmark_api.h", - "third_party/benchmark/include/benchmark/reporter.h", "third_party/benchmark/src/arraysize.h", "third_party/benchmark/src/benchmark_api_internal.h", + "third_party/benchmark/src/benchmark_register.h", "third_party/benchmark/src/check.h", "third_party/benchmark/src/colorprint.h", "third_party/benchmark/src/commandlineflags.h", @@ -8790,9 +7618,10 @@ "third_party/benchmark/src/mutex.h", "third_party/benchmark/src/re.h", "third_party/benchmark/src/sleep.h", - "third_party/benchmark/src/stat.h", + "third_party/benchmark/src/statistics.h", "third_party/benchmark/src/string_util.h", - "third_party/benchmark/src/sysinfo.h", + "third_party/benchmark/src/thread_manager.h", + "third_party/benchmark/src/thread_timer.h", "third_party/benchmark/src/timers.h" ], "is_filegroup": false, @@ -8802,6 +7631,26 @@ "third_party": false, "type": "lib" }, + { + "deps": [], + "headers": [ + "third_party/upb/google/protobuf/descriptor.upb.h", + "third_party/upb/upb/decode.h", + "third_party/upb/upb/def.h", + "third_party/upb/upb/encode.h", + "third_party/upb/upb/handlers.h", + "third_party/upb/upb/msg.h", + "third_party/upb/upb/msgfactory.h", + "third_party/upb/upb/sink.h", + "third_party/upb/upb/upb.h" + ], + "is_filegroup": false, + "language": "c", + "name": "upb", + "src": [], + "third_party": false, + "type": "lib" + }, { "deps": [], "headers": [ @@ -8845,6 +7694,7 @@ "third_party/cares/cares/ares_setup.h", "third_party/cares/cares/ares_strcasecmp.h", "third_party/cares/cares/ares_strdup.h", + "third_party/cares/cares/ares_strsplit.h", "third_party/cares/cares/ares_version.h", "third_party/cares/cares/bitncmp.h", "third_party/cares/cares/config-win32.h", @@ -8864,7 +7714,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -8884,7 +7733,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -8904,7 +7752,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc", "grpc_test_util" ], @@ -8941,6 +7788,7 @@ "test/core/end2end/tests/empty_batch.cc", "test/core/end2end/tests/filter_call_init_fails.cc", "test/core/end2end/tests/filter_causes_close.cc", + "test/core/end2end/tests/filter_context.cc", "test/core/end2end/tests/filter_latency.cc", "test/core/end2end/tests/filter_status_code.cc", "test/core/end2end/tests/graceful_server_shutdown.cc", @@ -8955,7 +7803,6 @@ "test/core/end2end/tests/max_connection_idle.cc", "test/core/end2end/tests/max_message_length.cc", "test/core/end2end/tests/negative_deadline.cc", - "test/core/end2end/tests/network_status_change.cc", "test/core/end2end/tests/no_error_on_hotpath.cc", "test/core/end2end/tests/no_logging.cc", "test/core/end2end/tests/no_op.cc", @@ -9005,7 +7852,6 @@ { "deps": [ "gpr", - "gpr_test_util", "grpc_test_util_unsecure", "grpc_unsecure" ], @@ -9041,6 +7887,7 @@ "test/core/end2end/tests/empty_batch.cc", "test/core/end2end/tests/filter_call_init_fails.cc", "test/core/end2end/tests/filter_causes_close.cc", + "test/core/end2end/tests/filter_context.cc", "test/core/end2end/tests/filter_latency.cc", "test/core/end2end/tests/filter_status_code.cc", "test/core/end2end/tests/graceful_server_shutdown.cc", @@ -9055,7 +7902,6 @@ "test/core/end2end/tests/max_connection_idle.cc", "test/core/end2end/tests/max_message_length.cc", "test/core/end2end/tests/negative_deadline.cc", - "test/core/end2end/tests/network_status_change.cc", "test/core/end2end/tests/no_error_on_hotpath.cc", "test/core/end2end/tests/no_logging.cc", "test/core/end2end/tests/no_op.cc", @@ -9282,7 +8128,6 @@ "name": "gpr_base", "src": [ "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", @@ -9315,7 +8160,9 @@ "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/arena.cc", "src/core/lib/gprpp/fork.cc", + "src/core/lib/gprpp/global_config_env.cc", "src/core/lib/gprpp/thd_posix.cc", "src/core/lib/gprpp/thd_windows.cc", "src/core/lib/profiling/basic_timers.cc", @@ -9363,13 +8210,18 @@ "src/core/lib/gpr/tmpfile.h", "src/core/lib/gpr/useful.h", "src/core/lib/gprpp/abstract.h", + "src/core/lib/gprpp/arena.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/fork.h", + "src/core/lib/gprpp/global_config.h", + "src/core/lib/gprpp/global_config_custom.h", + "src/core/lib/gprpp/global_config_env.h", + "src/core/lib/gprpp/global_config_generic.h", "src/core/lib/gprpp/manual_constructor.h", + "src/core/lib/gprpp/map.h", "src/core/lib/gprpp/memory.h", - "src/core/lib/gprpp/mutex_lock.h", + "src/core/lib/gprpp/pair.h", + "src/core/lib/gprpp/sync.h", "src/core/lib/gprpp/thd.h", "src/core/lib/profiling/timers.h" ], @@ -9411,13 +8263,18 @@ "src/core/lib/gpr/tmpfile.h", "src/core/lib/gpr/useful.h", "src/core/lib/gprpp/abstract.h", + "src/core/lib/gprpp/arena.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/fork.h", + "src/core/lib/gprpp/global_config.h", + "src/core/lib/gprpp/global_config_custom.h", + "src/core/lib/gprpp/global_config_env.h", + "src/core/lib/gprpp/global_config_generic.h", "src/core/lib/gprpp/manual_constructor.h", + "src/core/lib/gprpp/map.h", "src/core/lib/gprpp/memory.h", - "src/core/lib/gprpp/mutex_lock.h", + "src/core/lib/gprpp/pair.h", + "src/core/lib/gprpp/sync.h", "src/core/lib/gprpp/thd.h", "src/core/lib/profiling/timers.h" ], @@ -9516,10 +8373,10 @@ "src/core/lib/channel/channelz_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_args.cc", "src/core/lib/compression/compression_internal.cc", "src/core/lib/compression/message_compress.cc", "src/core/lib/compression/stream_compression.cc", @@ -9532,12 +8389,15 @@ "src/core/lib/http/parser.cc", "src/core/lib/iomgr/buffer_list.cc", "src/core/lib/iomgr/call_combiner.cc", + "src/core/lib/iomgr/cfstream_handle.cc", "src/core/lib/iomgr/combiner.cc", "src/core/lib/iomgr/endpoint.cc", + "src/core/lib/iomgr/endpoint_cfstream.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/error_cfstream.cc", "src/core/lib/iomgr/ev_epoll1_linux.cc", "src/core/lib/iomgr/ev_epollex_linux.cc", "src/core/lib/iomgr/ev_poll_posix.cc", @@ -9550,18 +8410,20 @@ "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/grpc_if_nametoindex_posix.cc", + "src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc", "src/core/lib/iomgr/internal_errqueue.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_posix_cfstream.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", @@ -9585,6 +8447,7 @@ "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_cfstream.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", @@ -9609,7 +8472,6 @@ "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", @@ -9649,7 +8511,6 @@ "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", @@ -9695,6 +8556,7 @@ "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_args.h", "src/core/lib/compression/compression_internal.h", "src/core/lib/compression/message_compress.h", "src/core/lib/compression/stream_compression.h", @@ -9704,6 +8566,7 @@ "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/optional.h", "src/core/lib/gprpp/orphanable.h", "src/core/lib/gprpp/ref_counted.h", "src/core/lib/gprpp/ref_counted_ptr.h", @@ -9713,11 +8576,15 @@ "src/core/lib/iomgr/block_annotate.h", "src/core/lib/iomgr/buffer_list.h", "src/core/lib/iomgr/call_combiner.h", + "src/core/lib/iomgr/cfstream_handle.h", "src/core/lib/iomgr/closure.h", "src/core/lib/iomgr/combiner.h", + "src/core/lib/iomgr/dynamic_annotations.h", "src/core/lib/iomgr/endpoint.h", + "src/core/lib/iomgr/endpoint_cfstream.h", "src/core/lib/iomgr/endpoint_pair.h", "src/core/lib/iomgr/error.h", + "src/core/lib/iomgr/error_cfstream.h", "src/core/lib/iomgr/error_internal.h", "src/core/lib/iomgr/ev_epoll1_linux.h", "src/core/lib/iomgr/ev_epollex_linux.h", @@ -9726,6 +8593,7 @@ "src/core/lib/iomgr/exec_ctx.h", "src/core/lib/iomgr/executor.h", "src/core/lib/iomgr/gethostname.h", + "src/core/lib/iomgr/grpc_if_nametoindex.h", "src/core/lib/iomgr/internal_errqueue.h", "src/core/lib/iomgr/iocp_windows.h", "src/core/lib/iomgr/iomgr.h", @@ -9736,7 +8604,6 @@ "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", @@ -9773,7 +8640,6 @@ "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", @@ -9785,6 +8651,7 @@ "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_utils.h", "src/core/lib/slice/slice_weak_hash_table.h", "src/core/lib/surface/api_trace.h", "src/core/lib/surface/call.h", @@ -9807,7 +8674,6 @@ "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", @@ -9847,6 +8713,7 @@ "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_args.h", "src/core/lib/compression/compression_internal.h", "src/core/lib/compression/message_compress.h", "src/core/lib/compression/stream_compression.h", @@ -9856,6 +8723,7 @@ "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/optional.h", "src/core/lib/gprpp/orphanable.h", "src/core/lib/gprpp/ref_counted.h", "src/core/lib/gprpp/ref_counted_ptr.h", @@ -9865,11 +8733,15 @@ "src/core/lib/iomgr/block_annotate.h", "src/core/lib/iomgr/buffer_list.h", "src/core/lib/iomgr/call_combiner.h", + "src/core/lib/iomgr/cfstream_handle.h", "src/core/lib/iomgr/closure.h", "src/core/lib/iomgr/combiner.h", + "src/core/lib/iomgr/dynamic_annotations.h", "src/core/lib/iomgr/endpoint.h", + "src/core/lib/iomgr/endpoint_cfstream.h", "src/core/lib/iomgr/endpoint_pair.h", "src/core/lib/iomgr/error.h", + "src/core/lib/iomgr/error_cfstream.h", "src/core/lib/iomgr/error_internal.h", "src/core/lib/iomgr/ev_epoll1_linux.h", "src/core/lib/iomgr/ev_epollex_linux.h", @@ -9878,6 +8750,7 @@ "src/core/lib/iomgr/exec_ctx.h", "src/core/lib/iomgr/executor.h", "src/core/lib/iomgr/gethostname.h", + "src/core/lib/iomgr/grpc_if_nametoindex.h", "src/core/lib/iomgr/internal_errqueue.h", "src/core/lib/iomgr/iocp_windows.h", "src/core/lib/iomgr/iomgr.h", @@ -9888,7 +8761,6 @@ "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", @@ -9925,7 +8797,6 @@ "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", @@ -9937,6 +8808,7 @@ "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_utils.h", "src/core/lib/slice/slice_weak_hash_table.h", "src/core/lib/surface/api_trace.h", "src/core/lib/surface/call.h", @@ -9959,7 +8831,6 @@ "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", @@ -9971,33 +8842,6 @@ "third_party": false, "type": "filegroup" }, - { - "deps": [ - "gpr", - "gpr_base_headers", - "grpc_base_headers" - ], - "headers": [ - "src/core/lib/iomgr/cfstream_handle.h", - "src/core/lib/iomgr/endpoint_cfstream.h", - "src/core/lib/iomgr/error_cfstream.h" - ], - "is_filegroup": true, - "language": "c", - "name": "grpc_cfstream", - "src": [ - "src/core/lib/iomgr/cfstream_handle.cc", - "src/core/lib/iomgr/cfstream_handle.h", - "src/core/lib/iomgr/endpoint_cfstream.cc", - "src/core/lib/iomgr/endpoint_cfstream.h", - "src/core/lib/iomgr/error_cfstream.cc", - "src/core/lib/iomgr/error_cfstream.h", - "src/core/lib/iomgr/iomgr_posix_cfstream.cc", - "src/core/lib/iomgr/tcp_client_cfstream.cc" - ], - "third_party": false, - "type": "filegroup" - }, { "deps": [ "gpr", @@ -10029,12 +8873,14 @@ "src/core/ext/filters/client_channel/client_channel_channelz.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/global_subchannel_pool.h", "src/core/ext/filters/client_channel/health/health_check_client.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/local_subchannel_pool.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", @@ -10042,9 +8888,12 @@ "src/core/ext/filters/client_channel/resolver_factory.h", "src/core/ext/filters/client_channel/resolver_registry.h", "src/core/ext/filters/client_channel/resolver_result_parsing.h", + "src/core/ext/filters/client_channel/resolving_lb_policy.h", "src/core/ext/filters/client_channel/retry_throttle.h", + "src/core/ext/filters/client_channel/server_address.h", + "src/core/ext/filters/client_channel/service_config.h", "src/core/ext/filters/client_channel/subchannel.h", - "src/core/ext/filters/client_channel/subchannel_index.h" + "src/core/ext/filters/client_channel/subchannel_pool_interface.h" ], "is_filegroup": true, "language": "c", @@ -10062,6 +8911,8 @@ "src/core/ext/filters/client_channel/client_channel_plugin.cc", "src/core/ext/filters/client_channel/connector.cc", "src/core/ext/filters/client_channel/connector.h", + "src/core/ext/filters/client_channel/global_subchannel_pool.cc", + "src/core/ext/filters/client_channel/global_subchannel_pool.h", "src/core/ext/filters/client_channel/health/health_check_client.cc", "src/core/ext/filters/client_channel/health/health_check_client.h", "src/core/ext/filters/client_channel/http_connect_handshaker.cc", @@ -10070,10 +8921,11 @@ "src/core/ext/filters/client_channel/http_proxy.h", "src/core/ext/filters/client_channel/lb_policy.cc", "src/core/ext/filters/client_channel/lb_policy.h", - "src/core/ext/filters/client_channel/lb_policy_factory.cc", "src/core/ext/filters/client_channel/lb_policy_factory.h", "src/core/ext/filters/client_channel/lb_policy_registry.cc", "src/core/ext/filters/client_channel/lb_policy_registry.h", + "src/core/ext/filters/client_channel/local_subchannel_pool.cc", + "src/core/ext/filters/client_channel/local_subchannel_pool.h", "src/core/ext/filters/client_channel/parse_address.cc", "src/core/ext/filters/client_channel/parse_address.h", "src/core/ext/filters/client_channel/proxy_mapper.cc", @@ -10087,12 +8939,18 @@ "src/core/ext/filters/client_channel/resolver_registry.h", "src/core/ext/filters/client_channel/resolver_result_parsing.cc", "src/core/ext/filters/client_channel/resolver_result_parsing.h", + "src/core/ext/filters/client_channel/resolving_lb_policy.cc", + "src/core/ext/filters/client_channel/resolving_lb_policy.h", "src/core/ext/filters/client_channel/retry_throttle.cc", "src/core/ext/filters/client_channel/retry_throttle.h", + "src/core/ext/filters/client_channel/server_address.cc", + "src/core/ext/filters/client_channel/server_address.h", + "src/core/ext/filters/client_channel/service_config.cc", + "src/core/ext/filters/client_channel/service_config.h", "src/core/ext/filters/client_channel/subchannel.cc", "src/core/ext/filters/client_channel/subchannel.h", - "src/core/ext/filters/client_channel/subchannel_index.cc", - "src/core/ext/filters/client_channel/subchannel_index.h" + "src/core/ext/filters/client_channel/subchannel_pool_interface.cc", + "src/core/ext/filters/client_channel/subchannel_pool_interface.h" ], "third_party": false, "type": "filegroup" @@ -10398,7 +9256,8 @@ ], "headers": [ "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h", - "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h" ], "is_filegroup": true, "language": "c", @@ -10407,11 +9266,15 @@ "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.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc" ], @@ -10496,6 +9359,8 @@ "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/tls/grpc_tls_credentials_options.h", + "src/core/lib/security/credentials/tls/spiffe_credentials.h", "src/core/lib/security/security_connector/alts/alts_security_connector.h", "src/core/lib/security/security_connector/fake/fake_security_connector.h", "src/core/lib/security/security_connector/load_system_roots.h", @@ -10504,6 +9369,7 @@ "src/core/lib/security/security_connector/security_connector.h", "src/core/lib/security/security_connector/ssl/ssl_security_connector.h", "src/core/lib/security/security_connector/ssl_utils.h", + "src/core/lib/security/security_connector/tls/spiffe_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", @@ -10549,6 +9415,10 @@ "src/core/lib/security/credentials/plugin/plugin_credentials.h", "src/core/lib/security/credentials/ssl/ssl_credentials.cc", "src/core/lib/security/credentials/ssl/ssl_credentials.h", + "src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc", + "src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h", + "src/core/lib/security/credentials/tls/spiffe_credentials.cc", + "src/core/lib/security/credentials/tls/spiffe_credentials.h", "src/core/lib/security/security_connector/alts/alts_security_connector.cc", "src/core/lib/security/security_connector/alts/alts_security_connector.h", "src/core/lib/security/security_connector/fake/fake_security_connector.cc", @@ -10565,6 +9435,8 @@ "src/core/lib/security/security_connector/ssl/ssl_security_connector.h", "src/core/lib/security/security_connector/ssl_utils.cc", "src/core/lib/security/security_connector/ssl_utils.h", + "src/core/lib/security/security_connector/tls/spiffe_security_connector.cc", + "src/core/lib/security/security_connector/tls/spiffe_security_connector.h", "src/core/lib/security/transport/auth_filters.h", "src/core/lib/security/transport/client_auth_filter.cc", "src/core/lib/security/transport/secure_endpoint.cc", @@ -10619,7 +9491,6 @@ "deps": [ "cmdline", "gpr", - "gpr_test_util", "grpc_base", "grpc_client_channel", "grpc_transport_chttp2" @@ -10628,6 +9499,7 @@ "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h", "test/core/end2end/cq_verifier.h", "test/core/end2end/fixtures/http_proxy_fixture.h", + "test/core/end2end/fixtures/local_util.h", "test/core/end2end/fixtures/proxy.h", "test/core/iomgr/endpoint_tests.h", "test/core/util/debugger_macros.h", @@ -10642,6 +9514,8 @@ "test/core/util/port_server_client.h", "test/core/util/slice_splitter.h", "test/core/util/subprocess.h", + "test/core/util/test_config.h", + "test/core/util/test_lb_policies.h", "test/core/util/tracer_util.h", "test/core/util/trickle_endpoint.h" ], @@ -10655,6 +9529,8 @@ "test/core/end2end/cq_verifier.h", "test/core/end2end/fixtures/http_proxy_fixture.cc", "test/core/end2end/fixtures/http_proxy_fixture.h", + "test/core/end2end/fixtures/local_util.cc", + "test/core/end2end/fixtures/local_util.h", "test/core/end2end/fixtures/proxy.cc", "test/core/end2end/fixtures/proxy.h", "test/core/iomgr/endpoint_tests.cc", @@ -10685,6 +9561,10 @@ "test/core/util/subprocess.h", "test/core/util/subprocess_posix.cc", "test/core/util/subprocess_windows.cc", + "test/core/util/test_config.cc", + "test/core/util/test_config.h", + "test/core/util/test_lb_policies.cc", + "test/core/util/test_lb_policies.h", "test/core/util/tracer_util.cc", "test/core/util/tracer_util.h", "test/core/util/trickle_endpoint.cc", @@ -10736,6 +9616,7 @@ "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/context_list.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", @@ -10765,6 +9646,8 @@ "src/core/ext/transport/chttp2/transport/chttp2_plugin.cc", "src/core/ext/transport/chttp2/transport/chttp2_transport.cc", "src/core/ext/transport/chttp2/transport/chttp2_transport.h", + "src/core/ext/transport/chttp2/transport/context_list.cc", + "src/core/ext/transport/chttp2/transport/context_list.h", "src/core/ext/transport/chttp2/transport/flow_control.cc", "src/core/ext/transport/chttp2/transport/flow_control.h", "src/core/ext/transport/chttp2/transport/frame.h", @@ -11163,6 +10046,7 @@ }, { "deps": [ + "grpc++_internal_hdrs_only", "grpc_codegen" ], "headers": [ @@ -11211,6 +10095,7 @@ "include/grpcpp/impl/codegen/client_interceptor.h", "include/grpcpp/impl/codegen/client_unary_call.h", "include/grpcpp/impl/codegen/completion_queue.h", + "include/grpcpp/impl/codegen/completion_queue_impl.h", "include/grpcpp/impl/codegen/completion_queue_tag.h", "include/grpcpp/impl/codegen/config.h", "include/grpcpp/impl/codegen/core_codegen_interface.h", @@ -11219,6 +10104,7 @@ "include/grpcpp/impl/codegen/intercepted_channel.h", "include/grpcpp/impl/codegen/interceptor.h", "include/grpcpp/impl/codegen/interceptor_common.h", + "include/grpcpp/impl/codegen/message_allocator.h", "include/grpcpp/impl/codegen/metadata_map.h", "include/grpcpp/impl/codegen/method_handler_impl.h", "include/grpcpp/impl/codegen/rpc_method.h", @@ -11287,6 +10173,7 @@ "include/grpcpp/impl/codegen/client_interceptor.h", "include/grpcpp/impl/codegen/client_unary_call.h", "include/grpcpp/impl/codegen/completion_queue.h", + "include/grpcpp/impl/codegen/completion_queue_impl.h", "include/grpcpp/impl/codegen/completion_queue_tag.h", "include/grpcpp/impl/codegen/config.h", "include/grpcpp/impl/codegen/core_codegen_interface.h", @@ -11295,6 +10182,7 @@ "include/grpcpp/impl/codegen/intercepted_channel.h", "include/grpcpp/impl/codegen/interceptor.h", "include/grpcpp/impl/codegen/interceptor_common.h", + "include/grpcpp/impl/codegen/message_allocator.h", "include/grpcpp/impl/codegen/metadata_map.h", "include/grpcpp/impl/codegen/method_handler_impl.h", "include/grpcpp/impl/codegen/rpc_method.h", @@ -11359,6 +10247,7 @@ "gpr", "gpr_base_headers", "grpc++_codegen_base", + "grpc++_internal_hdrs_only", "grpc_base_headers", "grpc_transport_inproc_headers", "health_proto", @@ -11411,16 +10300,22 @@ "include/grpc++/support/sync_stream.h", "include/grpc++/support/time.h", "include/grpcpp/alarm.h", + "include/grpcpp/alarm_impl.h", "include/grpcpp/channel.h", + "include/grpcpp/channel_impl.h", "include/grpcpp/client_context.h", "include/grpcpp/completion_queue.h", "include/grpcpp/create_channel.h", + "include/grpcpp/create_channel_impl.h", "include/grpcpp/create_channel_posix.h", + "include/grpcpp/create_channel_posix_impl.h", "include/grpcpp/ext/health_check_service_server_builder_option.h", "include/grpcpp/generic/async_generic_service.h", "include/grpcpp/generic/generic_stub.h", + "include/grpcpp/generic/generic_stub_impl.h", "include/grpcpp/grpcpp.h", "include/grpcpp/health_check_service_interface.h", + "include/grpcpp/health_check_service_interface_impl.h", "include/grpcpp/impl/call.h", "include/grpcpp/impl/channel_argument_option.h", "include/grpcpp/impl/client_unary_call.h", @@ -11431,27 +10326,41 @@ "include/grpcpp/impl/rpc_service_method.h", "include/grpcpp/impl/serialization_traits.h", "include/grpcpp/impl/server_builder_option.h", + "include/grpcpp/impl/server_builder_option_impl.h", "include/grpcpp/impl/server_builder_plugin.h", "include/grpcpp/impl/server_initializer.h", + "include/grpcpp/impl/server_initializer_impl.h", "include/grpcpp/impl/service_type.h", "include/grpcpp/resource_quota.h", + "include/grpcpp/resource_quota_impl.h", "include/grpcpp/security/auth_context.h", "include/grpcpp/security/auth_metadata_processor.h", + "include/grpcpp/security/auth_metadata_processor_impl.h", "include/grpcpp/security/credentials.h", + "include/grpcpp/security/credentials_impl.h", "include/grpcpp/security/server_credentials.h", + "include/grpcpp/security/server_credentials_impl.h", "include/grpcpp/server.h", "include/grpcpp/server_builder.h", + "include/grpcpp/server_builder_impl.h", "include/grpcpp/server_context.h", + "include/grpcpp/server_impl.h", "include/grpcpp/server_posix.h", + "include/grpcpp/server_posix_impl.h", "include/grpcpp/support/async_stream.h", "include/grpcpp/support/async_unary_call.h", "include/grpcpp/support/byte_buffer.h", "include/grpcpp/support/channel_arguments.h", + "include/grpcpp/support/channel_arguments_impl.h", "include/grpcpp/support/client_callback.h", + "include/grpcpp/support/client_interceptor.h", "include/grpcpp/support/config.h", + "include/grpcpp/support/interceptor.h", + "include/grpcpp/support/message_allocator.h", "include/grpcpp/support/proto_buffer_reader.h", "include/grpcpp/support/proto_buffer_writer.h", "include/grpcpp/support/server_callback.h", + "include/grpcpp/support/server_interceptor.h", "include/grpcpp/support/slice.h", "include/grpcpp/support/status.h", "include/grpcpp/support/status_code_enum.h", @@ -11516,16 +10425,22 @@ "include/grpc++/support/sync_stream.h", "include/grpc++/support/time.h", "include/grpcpp/alarm.h", + "include/grpcpp/alarm_impl.h", "include/grpcpp/channel.h", + "include/grpcpp/channel_impl.h", "include/grpcpp/client_context.h", "include/grpcpp/completion_queue.h", "include/grpcpp/create_channel.h", + "include/grpcpp/create_channel_impl.h", "include/grpcpp/create_channel_posix.h", + "include/grpcpp/create_channel_posix_impl.h", "include/grpcpp/ext/health_check_service_server_builder_option.h", "include/grpcpp/generic/async_generic_service.h", "include/grpcpp/generic/generic_stub.h", + "include/grpcpp/generic/generic_stub_impl.h", "include/grpcpp/grpcpp.h", "include/grpcpp/health_check_service_interface.h", + "include/grpcpp/health_check_service_interface_impl.h", "include/grpcpp/impl/call.h", "include/grpcpp/impl/channel_argument_option.h", "include/grpcpp/impl/client_unary_call.h", @@ -11536,27 +10451,41 @@ "include/grpcpp/impl/rpc_service_method.h", "include/grpcpp/impl/serialization_traits.h", "include/grpcpp/impl/server_builder_option.h", + "include/grpcpp/impl/server_builder_option_impl.h", "include/grpcpp/impl/server_builder_plugin.h", "include/grpcpp/impl/server_initializer.h", + "include/grpcpp/impl/server_initializer_impl.h", "include/grpcpp/impl/service_type.h", "include/grpcpp/resource_quota.h", + "include/grpcpp/resource_quota_impl.h", "include/grpcpp/security/auth_context.h", "include/grpcpp/security/auth_metadata_processor.h", + "include/grpcpp/security/auth_metadata_processor_impl.h", "include/grpcpp/security/credentials.h", + "include/grpcpp/security/credentials_impl.h", "include/grpcpp/security/server_credentials.h", + "include/grpcpp/security/server_credentials_impl.h", "include/grpcpp/server.h", "include/grpcpp/server_builder.h", + "include/grpcpp/server_builder_impl.h", "include/grpcpp/server_context.h", + "include/grpcpp/server_impl.h", "include/grpcpp/server_posix.h", + "include/grpcpp/server_posix_impl.h", "include/grpcpp/support/async_stream.h", "include/grpcpp/support/async_unary_call.h", "include/grpcpp/support/byte_buffer.h", "include/grpcpp/support/channel_arguments.h", + "include/grpcpp/support/channel_arguments_impl.h", "include/grpcpp/support/client_callback.h", + "include/grpcpp/support/client_interceptor.h", "include/grpcpp/support/config.h", + "include/grpcpp/support/interceptor.h", + "include/grpcpp/support/message_allocator.h", "include/grpcpp/support/proto_buffer_reader.h", "include/grpcpp/support/proto_buffer_writer.h", "include/grpcpp/support/server_callback.h", + "include/grpcpp/support/server_interceptor.h", "include/grpcpp/support/slice.h", "include/grpcpp/support/status.h", "include/grpcpp/support/status_code_enum.h", @@ -11623,6 +10552,20 @@ "third_party": false, "type": "filegroup" }, + { + "deps": [], + "headers": [ + "include/grpcpp/impl/codegen/sync.h" + ], + "is_filegroup": true, + "language": "c++", + "name": "grpc++_internal_hdrs_only", + "src": [ + "include/grpcpp/impl/codegen/sync.h" + ], + "third_party": false, + "type": "filegroup" + }, { "deps": [], "headers": [ diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index 340343caf00..930f7f8748d 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -311,6 +311,30 @@ ], "uses_polling": false }, + { + "args": [], + "benchmark": false, + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [ + "tsan" + ], + "exclude_iomgrs": [], + "flaky": false, + "gtest": false, + "language": "c", + "name": "close_fd_test", + "platforms": [ + "linux", + "mac", + "posix" + ], + "uses_polling": true + }, { "args": [], "benchmark": false, @@ -2057,6 +2081,28 @@ ], "uses_polling": false }, + { + "args": [], + "benchmark": false, + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "gtest": false, + "language": "c", + "name": "parse_address_with_named_scope_id_test", + "platforms": [ + "linux", + "mac", + "posix" + ], + "uses_polling": false + }, { "args": [], "benchmark": false, @@ -2082,7 +2128,9 @@ "uses_polling": false }, { - "args": [], + "args": [ + "--resolver=ares" + ], "benchmark": false, "ci_platforms": [ "linux", @@ -2097,7 +2145,7 @@ "flaky": false, "gtest": false, "language": "c", - "name": "resolve_address_posix_test", + "name": "resolve_address_using_ares_resolver_posix_test", "platforms": [ "linux", "mac", @@ -2131,6 +2179,32 @@ ], "uses_polling": true }, + { + "args": [ + "--resolver=native" + ], + "benchmark": false, + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "gtest": false, + "language": "c", + "name": "resolve_address_using_native_resolver_posix_test", + "platforms": [ + "linux", + "mac", + "posix" + ], + "uses_polling": true + }, { "args": [ "--resolver=native" @@ -2885,30 +2959,6 @@ ], "uses_polling": true }, - { - "args": [], - "benchmark": false, - "ci_platforms": [ - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [ - "uv" - ], - "flaky": false, - "gtest": false, - "language": "c", - "name": "wakeup_fd_cv_test", - "platforms": [ - "linux", - "mac", - "posix" - ], - "uses_polling": true - }, { "args": [], "benchmark": false, @@ -3341,6 +3391,28 @@ ], "uses_polling": false }, + { + "args": [], + "benchmark": true, + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "gtest": false, + "language": "c++", + "name": "bm_alarm", + "platforms": [ + "linux", + "mac", + "posix" + ], + "uses_polling": true + }, { "args": [], "benchmark": true, @@ -3363,6 +3435,28 @@ ], "uses_polling": false }, + { + "args": [], + "benchmark": true, + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "gtest": false, + "language": "c++", + "name": "bm_byte_buffer", + "platforms": [ + "linux", + "mac", + "posix" + ], + "uses_polling": false + }, { "args": [], "benchmark": true, @@ -3385,6 +3479,50 @@ ], "uses_polling": false }, + { + "args": [], + "benchmark": true, + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "gtest": false, + "language": "c++", + "name": "bm_callback_streaming_ping_pong", + "platforms": [ + "linux", + "mac", + "posix" + ], + "uses_polling": true + }, + { + "args": [], + "benchmark": true, + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "gtest": false, + "language": "c++", + "name": "bm_callback_unary_ping_pong", + "platforms": [ + "linux", + "mac", + "posix" + ], + "uses_polling": true + }, { "args": [], "benchmark": true, @@ -3551,8 +3689,7 @@ "exclude_configs": [], "exclude_iomgrs": [], "excluded_poll_engines": [ - "poll", - "poll-cv" + "poll" ], "flaky": false, "gtest": false, @@ -3578,8 +3715,7 @@ "exclude_configs": [], "exclude_iomgrs": [], "excluded_poll_engines": [ - "poll", - "poll-cv" + "poll" ], "flaky": false, "gtest": false, @@ -3607,8 +3743,7 @@ ], "exclude_iomgrs": [], "excluded_poll_engines": [ - "poll", - "poll-cv" + "poll" ], "flaky": false, "gtest": false, @@ -3634,8 +3769,7 @@ "exclude_configs": [], "exclude_iomgrs": [], "excluded_poll_engines": [ - "poll", - "poll-cv" + "poll" ], "flaky": false, "gtest": false, @@ -3693,6 +3827,28 @@ ], "uses_polling": true }, + { + "args": [], + "benchmark": true, + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "gtest": false, + "language": "c++", + "name": "bm_timer", + "platforms": [ + "linux", + "mac", + "posix" + ], + "uses_polling": false + }, { "args": [], "benchmark": false, @@ -4123,6 +4279,30 @@ ], "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": "context_list_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "uses_polling": false + }, { "args": [], "benchmark": false, @@ -4363,6 +4543,54 @@ ], "uses_polling": true }, + { + "args": [], + "benchmark": false, + "ci_platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "gtest": false, + "language": "c++", + "name": "global_config_env_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": false, + "language": "c++", + "name": "global_config_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "uses_polling": false + }, { "args": [ "--generated_file_path=gens/src/proto/grpc/testing/" @@ -4413,6 +4641,30 @@ ], "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": "grpc_core_map_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "uses_polling": false + }, { "args": [], "benchmark": false, @@ -4697,6 +4949,30 @@ ], "uses_polling": false }, + { + "args": [], + "benchmark": false, + "ci_platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "cpu_cost": 0.5, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "gtest": true, + "language": "c++", + "name": "message_allocator_end2end_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "uses_polling": true + }, { "args": [], "benchmark": false, @@ -4769,6 +5045,30 @@ ], "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": "optional_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "uses_polling": true + }, { "args": [], "benchmark": false, @@ -5189,6 +5489,54 @@ ], "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": "service_config_end2end_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": "service_config_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "uses_polling": true + }, { "args": [], "benchmark": false, @@ -5406,6 +5754,28 @@ ], "uses_polling": true }, + { + "args": [], + "benchmark": false, + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "gtest": true, + "language": "c++", + "name": "time_change_test", + "platforms": [ + "linux", + "mac", + "posix" + ], + "uses_polling": true + }, { "args": [], "benchmark": false, @@ -5476,6 +5846,30 @@ ], "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": "xds_end2end_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "uses_polling": true + }, { "args": [], "benchmark": false, @@ -5930,1306 +6324,6 @@ ], "uses_polling": true }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_crypto_test_data", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_asn1_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_base64_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_bio_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_buf_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_bytestring_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_chacha_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_aead_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_cipher_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_cmac_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_compiler_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_constant_time_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_ed25519_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_spake25519_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_x25519_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_dh_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_digest_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_dsa_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_ecdh_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_err_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_evp_extra_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_evp_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_pbkdf_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_scrypt_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_aes_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_bn_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_ec_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_p256-x86_64_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_ecdsa_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_gcm_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_ctrdrbg_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_hkdf_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_hmac_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_lhash_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_obj_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_pkcs7_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_pkcs12_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_pkcs8_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_poly1305_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_pool_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_refcount_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_rsa_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_self_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_file_test_gtest", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_gtest_main", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_thread_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_x509_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_tab_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_v3name_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_span_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, { "args": [], "boringssl": true, @@ -7256,6 +6350,32 @@ "windows" ] }, + { + "args": [], + "boringssl": true, + "ci_platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "cpu_cost": 1.0, + "defaults": "boringssl", + "exclude_configs": [ + "asan", + "ubsan" + ], + "flaky": false, + "gtest": true, + "language": "c++", + "name": "boringssl_crypto_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ] + }, { "args": [ "authority_not_supported" @@ -7741,6 +6861,29 @@ "posix" ] }, + { + "args": [ + "filter_context" + ], + "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": [ "filter_latency" @@ -8065,29 +7208,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "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": [ "no_error_on_hotpath" @@ -9516,6 +8636,29 @@ "posix" ] }, + { + "args": [ + "filter_context" + ], + "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": [ "filter_latency" @@ -9840,29 +8983,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "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": [ "no_error_on_hotpath" @@ -11247,6 +10367,28 @@ "posix" ] }, + { + "args": [ + "filter_context" + ], + "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": [ "filter_latency" @@ -11557,28 +10699,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "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": [ "no_error_on_hotpath" @@ -12849,6 +11969,29 @@ "posix" ] }, + { + "args": [ + "filter_context" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_fd_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_latency" @@ -13148,29 +12291,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [ - "uv" - ], - "flaky": false, - "language": "c", - "name": "h2_fd_test", - "platforms": [ - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" @@ -14185,6 +13305,29 @@ "posix" ] }, + { + "args": [ + "filter_context" + ], + "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": [ "filter_latency" @@ -14509,29 +13652,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "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": [ "no_error_on_hotpath" @@ -15874,6 +14994,25 @@ "linux" ] }, + { + "args": [ + "filter_context" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_full+pipe_test", + "platforms": [ + "linux" + ] + }, { "args": [ "filter_latency" @@ -16140,25 +15279,6 @@ "linux" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "linux" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [ - "uv" - ], - "flaky": false, - "language": "c", - "name": "h2_full+pipe_test", - "platforms": [ - "linux" - ] - }, { "args": [ "no_error_on_hotpath" @@ -17423,6 +16543,29 @@ "posix" ] }, + { + "args": [ + "filter_context" + ], + "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": [ "filter_latency" @@ -17724,29 +16867,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "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": [ "no_error_on_hotpath" @@ -19152,6 +18272,29 @@ "posix" ] }, + { + "args": [ + "filter_context" + ], + "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": [ "filter_latency" @@ -19476,29 +18619,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "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": [ "no_error_on_hotpath" @@ -20946,6 +20066,30 @@ "posix" ] }, + { + "args": [ + "filter_context" + ], + "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": [ "filter_latency" @@ -21282,30 +20426,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "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": [ "no_error_on_hotpath" @@ -22330,7 +21450,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22353,7 +21473,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22376,7 +21496,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22399,7 +21519,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22422,7 +21542,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22445,7 +21565,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22468,7 +21588,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22491,7 +21611,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22514,7 +21634,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22537,7 +21657,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22560,7 +21680,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22583,7 +21703,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22606,7 +21726,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22629,7 +21749,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22652,7 +21772,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22675,7 +21795,7 @@ ], "flaky": true, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22698,7 +21818,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22721,7 +21841,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22744,7 +21864,30 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "filter_context" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22767,7 +21910,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22790,7 +21933,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22813,7 +21956,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22836,7 +21979,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22859,7 +22002,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22882,7 +22025,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22905,7 +22048,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22928,7 +22071,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22951,7 +22094,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22974,7 +22117,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -22997,7 +22140,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23020,7 +22163,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23043,7 +22186,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23066,30 +22209,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", - "platforms": [ - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [ - "uv" - ], - "flaky": false, - "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23112,7 +22232,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23135,7 +22255,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23158,7 +22278,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23181,7 +22301,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23204,7 +22324,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23227,7 +22347,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23250,7 +22370,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23273,7 +22393,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23296,7 +22416,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23319,7 +22439,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23342,7 +22462,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23365,7 +22485,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23388,7 +22508,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23411,7 +22531,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23434,7 +22554,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23457,7 +22577,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23480,7 +22600,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23503,7 +22623,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23526,7 +22646,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23549,7 +22669,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23572,7 +22692,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23595,7 +22715,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23618,7 +22738,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23641,7 +22761,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23664,7 +22784,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23687,7 +22807,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23710,7 +22830,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23733,7 +22853,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23756,7 +22876,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23779,7 +22899,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23802,7 +22922,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23825,7 +22945,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23848,7 +22968,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23871,7 +22991,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23894,7 +23014,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23917,7 +23037,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23940,7 +23060,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23963,7 +23083,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -23986,7 +23106,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -24009,7 +23129,7 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", "platforms": [ "linux", "mac", @@ -24032,7 +23152,3457 @@ ], "flaky": false, "language": "c", - "name": "h2_local_test", + "name": "h2_local_ipv4_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "authority_not_supported" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "bad_hostname" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "bad_ping" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "binary_metadata" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "call_creds" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "cancel_after_accept" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "cancel_after_client_done" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "cancel_after_invoke" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "cancel_after_round_trip" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "cancel_before_invoke" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "cancel_in_a_vacuum" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "cancel_with_status" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "channelz" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "compressed_payload" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "connectivity" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "disappearing_server" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": true, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "empty_batch" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "filter_call_init_fails" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "filter_causes_close" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "filter_context" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "filter_latency" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "filter_status_code" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "graceful_server_shutdown" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "high_initial_seqno" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "hpack_size" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "idempotent_request" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "invoke_large_request" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "keepalive_timeout" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "large_metadata" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "max_concurrent_streams" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "max_connection_age" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "max_connection_idle" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "max_message_length" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "negative_deadline" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "no_error_on_hotpath" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "no_logging" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "no_op" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "payload" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "ping" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "ping_pong_streaming" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "registered_call" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "request_with_flags" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "request_with_payload" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "resource_quota_server" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_cancellation" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_disabled" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_exceeds_buffer_size_in_initial_batch" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_exceeds_buffer_size_in_subsequent_batch" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_non_retriable_status" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "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_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_recv_initial_metadata" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_recv_message" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_server_pushback_delay" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_server_pushback_disabled" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_streaming" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_streaming_after_commit" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_streaming_succeeds_before_replay_finished" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_throttled" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_too_many_attempts" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "server_finishes_request" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "shutdown_finishes_calls" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "shutdown_finishes_tags" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "simple_cacheable_request" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "simple_delayed_request" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "simple_metadata" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "simple_request" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "stream_compression_compressed_payload" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "stream_compression_payload" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "stream_compression_ping_pong_streaming" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "streaming_error_response" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "trailing_metadata" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "workaround_cronet_compression" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "write_buffering" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "write_buffering_at_end" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "authority_not_supported" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "bad_hostname" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "bad_ping" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "binary_metadata" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "call_creds" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "cancel_after_accept" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "cancel_after_client_done" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "cancel_after_invoke" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "cancel_after_round_trip" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "cancel_before_invoke" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "cancel_in_a_vacuum" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "cancel_with_status" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "channelz" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "compressed_payload" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "connectivity" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "disappearing_server" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": true, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "empty_batch" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "filter_call_init_fails" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "filter_causes_close" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "filter_context" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "filter_latency" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "filter_status_code" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "graceful_server_shutdown" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "high_initial_seqno" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "hpack_size" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "idempotent_request" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "invoke_large_request" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "keepalive_timeout" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "large_metadata" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "max_concurrent_streams" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "max_connection_age" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "max_connection_idle" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "max_message_length" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "negative_deadline" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "no_error_on_hotpath" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "no_logging" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "no_op" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "payload" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "ping" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "ping_pong_streaming" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "registered_call" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "request_with_flags" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "request_with_payload" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "resource_quota_server" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_cancellation" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_disabled" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_exceeds_buffer_size_in_initial_batch" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_exceeds_buffer_size_in_subsequent_batch" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_non_retriable_status" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "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_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_recv_initial_metadata" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_recv_message" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_server_pushback_delay" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_server_pushback_disabled" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_streaming" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_streaming_after_commit" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_streaming_succeeds_before_replay_finished" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_throttled" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_too_many_attempts" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "server_finishes_request" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "shutdown_finishes_calls" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "shutdown_finishes_tags" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "simple_cacheable_request" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "simple_delayed_request" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "simple_metadata" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "simple_request" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "stream_compression_compressed_payload" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "stream_compression_payload" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "stream_compression_ping_pong_streaming" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "streaming_error_response" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "trailing_metadata" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "workaround_cronet_compression" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "write_buffering" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "write_buffering_at_end" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", "platforms": [ "linux", "mac", @@ -24543,6 +27113,30 @@ "posix" ] }, + { + "args": [ + "filter_context" + ], + "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": [ "filter_latency" @@ -24879,30 +27473,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "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": [ "no_error_on_hotpath" @@ -26319,6 +28889,30 @@ "posix" ] }, + { + "args": [ + "filter_context" + ], + "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": [ "filter_latency" @@ -26559,30 +29153,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "windows", - "linux", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [ - "uv" - ], - "flaky": false, - "language": "c", - "name": "h2_proxy_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_logging" @@ -27447,6 +30017,30 @@ "posix" ] }, + { + "args": [ + "filter_context" + ], + "ci_platforms": [ + "windows", + "linux", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_sockpair_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_latency" @@ -27759,30 +30353,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "windows", - "linux", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [ - "uv" - ], - "flaky": false, - "language": "c", - "name": "h2_sockpair_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" @@ -28719,6 +31289,30 @@ "posix" ] }, + { + "args": [ + "filter_context" + ], + "ci_platforms": [ + "windows", + "linux", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_sockpair+trace_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_latency" @@ -29007,30 +31601,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "windows", - "linux", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [ - "uv" - ], - "flaky": false, - "language": "c", - "name": "h2_sockpair+trace_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" @@ -29951,6 +32521,32 @@ "posix" ] }, + { + "args": [ + "filter_context" + ], + "ci_platforms": [ + "windows", + "linux", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [ + "msan" + ], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_sockpair_1byte_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_latency" @@ -30289,32 +32885,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "windows", - "linux", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [ - "msan" - ], - "exclude_iomgrs": [ - "uv" - ], - "flaky": false, - "language": "c", - "name": "h2_sockpair_1byte_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" @@ -30887,6 +33457,1781 @@ "posix" ] }, + { + "args": [ + "authority_not_supported" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "bad_hostname" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "bad_ping" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "binary_metadata" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "call_creds" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "call_host_override" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "cancel_after_accept" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "cancel_after_client_done" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "cancel_after_invoke" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "cancel_after_round_trip" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "cancel_before_invoke" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "cancel_in_a_vacuum" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "cancel_with_status" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "channelz" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "compressed_payload" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "connectivity" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "default_host" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "disappearing_server" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": true, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "empty_batch" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "filter_call_init_fails" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "filter_causes_close" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "filter_context" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "filter_latency" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "filter_status_code" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "graceful_server_shutdown" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "high_initial_seqno" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "hpack_size" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "idempotent_request" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "invoke_large_request" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "keepalive_timeout" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "large_metadata" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "max_concurrent_streams" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "max_connection_age" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "max_connection_idle" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "max_message_length" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "negative_deadline" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "no_error_on_hotpath" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "no_logging" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "no_op" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "payload" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "ping" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "ping_pong_streaming" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "registered_call" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "request_with_flags" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "request_with_payload" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "resource_quota_server" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_cancellation" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_disabled" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_exceeds_buffer_size_in_initial_batch" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_exceeds_buffer_size_in_subsequent_batch" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_non_retriable_status" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "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_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_recv_initial_metadata" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_recv_message" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_server_pushback_delay" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_server_pushback_disabled" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_streaming" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_streaming_after_commit" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_streaming_succeeds_before_replay_finished" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_throttled" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_too_many_attempts" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "server_finishes_request" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "shutdown_finishes_calls" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "shutdown_finishes_tags" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "simple_cacheable_request" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "simple_delayed_request" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "simple_metadata" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "simple_request" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "stream_compression_compressed_payload" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "stream_compression_payload" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "stream_compression_ping_pong_streaming" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "streaming_error_response" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "trailing_metadata" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "workaround_cronet_compression" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "write_buffering" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "write_buffering_at_end" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "authority_not_supported" @@ -31372,6 +35717,29 @@ "posix" ] }, + { + "args": [ + "filter_context" + ], + "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": [ "filter_latency" @@ -31696,29 +36064,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "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": [ "no_error_on_hotpath" @@ -32662,6 +37007,1781 @@ "posix" ] }, + { + "args": [ + "authority_not_supported" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "bad_hostname" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "bad_ping" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "binary_metadata" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "call_creds" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "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_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "cancel_after_accept" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "cancel_after_client_done" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "cancel_after_invoke" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "cancel_after_round_trip" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "cancel_before_invoke" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "cancel_in_a_vacuum" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "cancel_with_status" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "channelz" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "compressed_payload" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "connectivity" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "default_host" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "disappearing_server" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": true, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "empty_batch" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "filter_call_init_fails" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "filter_causes_close" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "filter_context" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "filter_latency" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "filter_status_code" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "graceful_server_shutdown" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "high_initial_seqno" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "hpack_size" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "idempotent_request" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "invoke_large_request" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "keepalive_timeout" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "large_metadata" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "max_concurrent_streams" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "max_connection_age" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "max_connection_idle" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "max_message_length" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "negative_deadline" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "no_error_on_hotpath" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "no_logging" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "no_op" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "payload" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "ping" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "ping_pong_streaming" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "registered_call" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "request_with_flags" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "request_with_payload" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "resource_quota_server" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_cancellation" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_disabled" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_exceeds_buffer_size_in_initial_batch" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_exceeds_buffer_size_in_subsequent_batch" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_non_retriable_status" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "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_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_recv_initial_metadata" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_recv_message" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_server_pushback_delay" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_server_pushback_disabled" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_streaming" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_streaming_after_commit" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_streaming_succeeds_before_replay_finished" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_throttled" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_too_many_attempts" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "server_finishes_request" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "shutdown_finishes_calls" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "shutdown_finishes_tags" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "simple_cacheable_request" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "simple_delayed_request" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "simple_metadata" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "simple_request" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "stream_compression_compressed_payload" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "stream_compression_payload" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "stream_compression_ping_pong_streaming" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "streaming_error_response" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "trailing_metadata" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "workaround_cronet_compression" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "write_buffering" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "write_buffering_at_end" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_cred_reload_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "authority_not_supported" @@ -33094,6 +39214,30 @@ "posix" ] }, + { + "args": [ + "filter_context" + ], + "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": [ "filter_latency" @@ -33334,30 +39478,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "windows", - "linux", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [ - "uv" - ], - "flaky": false, - "language": "c", - "name": "h2_ssl_proxy_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_logging" @@ -34275,6 +40395,29 @@ "posix" ] }, + { + "args": [ + "filter_context" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_latency" @@ -34597,29 +40740,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "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": [ "no_error_on_hotpath" @@ -35885,6 +42005,29 @@ "posix" ] }, + { + "args": [ + "filter_context" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "inproc_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_latency" @@ -36092,29 +42235,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" @@ -36991,6 +43111,29 @@ "posix" ] }, + { + "args": [ + "filter_context" + ], + "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": [ "filter_latency" @@ -37315,29 +43458,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "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": [ "no_error_on_hotpath" @@ -38743,6 +44863,29 @@ "posix" ] }, + { + "args": [ + "filter_context" + ], + "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": [ "filter_latency" @@ -39067,29 +45210,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "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": [ "no_error_on_hotpath" @@ -40355,6 +46475,29 @@ "posix" ] }, + { + "args": [ + "filter_context" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_fd_nosec_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_latency" @@ -40654,29 +46797,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [ - "uv" - ], - "flaky": false, - "language": "c", - "name": "h2_fd_nosec_test", - "platforms": [ - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" @@ -41668,6 +47788,29 @@ "posix" ] }, + { + "args": [ + "filter_context" + ], + "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": [ "filter_latency" @@ -41992,29 +48135,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "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": [ "no_error_on_hotpath" @@ -43338,6 +49458,25 @@ "linux" ] }, + { + "args": [ + "filter_context" + ], + "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": [ "filter_latency" @@ -43604,25 +49743,6 @@ "linux" ] }, - { - "args": [ - "network_status_change" - ], - "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": [ "no_error_on_hotpath" @@ -44864,6 +50984,29 @@ "posix" ] }, + { + "args": [ + "filter_context" + ], + "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": [ "filter_latency" @@ -45165,29 +51308,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "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": [ "no_error_on_hotpath" @@ -46570,6 +52690,29 @@ "posix" ] }, + { + "args": [ + "filter_context" + ], + "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": [ "filter_latency" @@ -46894,29 +53037,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "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": [ "no_error_on_hotpath" @@ -48340,6 +54460,30 @@ "posix" ] }, + { + "args": [ + "filter_context" + ], + "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": [ "filter_latency" @@ -48676,30 +54820,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "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": [ "no_error_on_hotpath" @@ -50116,6 +56236,30 @@ "posix" ] }, + { + "args": [ + "filter_context" + ], + "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": [ "filter_latency" @@ -50356,30 +56500,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "windows", - "linux", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [ - "uv" - ], - "flaky": false, - "language": "c", - "name": "h2_proxy_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_logging" @@ -51220,6 +57340,30 @@ "posix" ] }, + { + "args": [ + "filter_context" + ], + "ci_platforms": [ + "windows", + "linux", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_sockpair_nosec_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_latency" @@ -51532,30 +57676,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "windows", - "linux", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [ - "uv" - ], - "flaky": false, - "language": "c", - "name": "h2_sockpair_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" @@ -52468,6 +58588,30 @@ "posix" ] }, + { + "args": [ + "filter_context" + ], + "ci_platforms": [ + "windows", + "linux", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_sockpair+trace_nosec_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_latency" @@ -52756,30 +58900,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "windows", - "linux", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [ - "uv" - ], - "flaky": false, - "language": "c", - "name": "h2_sockpair+trace_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" @@ -53674,6 +59794,32 @@ "posix" ] }, + { + "args": [ + "filter_context" + ], + "ci_platforms": [ + "windows", + "linux", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [ + "msan" + ], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_sockpair_1byte_nosec_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_latency" @@ -54012,32 +60158,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "windows", - "linux", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [ - "msan" - ], - "exclude_iomgrs": [ - "uv" - ], - "flaky": false, - "language": "c", - "name": "h2_sockpair_1byte_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" @@ -55024,6 +61144,29 @@ "posix" ] }, + { + "args": [ + "filter_context" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_uds_nosec_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_latency" @@ -55346,29 +61489,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "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": [ "no_error_on_hotpath" @@ -56732,7 +62852,7 @@ { "args": [ "--scenarios_json", - "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"server_config\": {\"async_server_threads\": 0, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}], \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"threads_per_cq\": 0, \"server_type\": \"SYNC_SERVER\"}, \"num_servers\": 1, \"num_clients\": 0, \"client_config\": {\"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}], \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"UNARY\", \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"threads_per_cq\": 0, \"load_params\": {\"closed_loop\": {}}, \"client_type\": \"ASYNC_CLIENT\", \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}" + "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}], \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"threads_per_cq\": 0, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}], \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"UNARY\", \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"threads_per_cq\": 0, \"load_params\": {\"closed_loop\": {}}, \"client_type\": \"ASYNC_CLIENT\", \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}" ], "auto_timeout_scaling": false, "boringssl": true, @@ -56745,9 +62865,7 @@ "tsan", "asan" ], - "excluded_poll_engines": [ - "poll-cv" - ], + "excluded_poll_engines": [], "flaky": false, "language": "c++", "name": "json_run_localhost", @@ -56786,7 +62904,7 @@ { "args": [ "--scenarios_json", - "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"server_config\": {\"async_server_threads\": 0, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}], \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"threads_per_cq\": 0, \"server_type\": \"SYNC_SERVER\"}, \"num_servers\": 1, \"num_clients\": 0, \"client_config\": {\"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}], \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"threads_per_cq\": 0, \"load_params\": {\"closed_loop\": {}}, \"client_type\": \"ASYNC_CLIENT\", \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}" + "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}], \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"threads_per_cq\": 0, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}], \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"threads_per_cq\": 0, \"load_params\": {\"closed_loop\": {}}, \"client_type\": \"ASYNC_CLIENT\", \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}" ], "auto_timeout_scaling": false, "boringssl": true, @@ -56799,9 +62917,7 @@ "tsan", "asan" ], - "excluded_poll_engines": [ - "poll-cv" - ], + "excluded_poll_engines": [], "flaky": false, "language": "c++", "name": "json_run_localhost", @@ -57698,7 +63814,7 @@ { "args": [ "--scenarios_json", - "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"server_config\": {\"async_server_threads\": 0, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}, {\"int_value\": 1, \"name\": \"grpc.minimal_stack\"}], \"security_params\": null, \"threads_per_cq\": 0, \"server_type\": \"SYNC_SERVER\"}, \"num_servers\": 1, \"num_clients\": 0, \"client_config\": {\"security_params\": null, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}, {\"int_value\": 1, \"name\": \"grpc.minimal_stack\"}], \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"UNARY\", \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"threads_per_cq\": 0, \"load_params\": {\"closed_loop\": {}}, \"client_type\": \"ASYNC_CLIENT\", \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}" + "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}, {\"int_value\": 1, \"name\": \"grpc.minimal_stack\"}], \"security_params\": null, \"threads_per_cq\": 0, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"security_params\": null, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}, {\"int_value\": 1, \"name\": \"grpc.minimal_stack\"}], \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"UNARY\", \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"threads_per_cq\": 0, \"load_params\": {\"closed_loop\": {}}, \"client_type\": \"ASYNC_CLIENT\", \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}" ], "auto_timeout_scaling": false, "boringssl": true, @@ -57711,9 +63827,7 @@ "tsan", "asan" ], - "excluded_poll_engines": [ - "poll-cv" - ], + "excluded_poll_engines": [], "flaky": false, "language": "c++", "name": "json_run_localhost", @@ -57752,7 +63866,7 @@ { "args": [ "--scenarios_json", - "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"server_config\": {\"async_server_threads\": 0, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}, {\"int_value\": 1, \"name\": \"grpc.minimal_stack\"}], \"security_params\": null, \"threads_per_cq\": 0, \"server_type\": \"SYNC_SERVER\"}, \"num_servers\": 1, \"num_clients\": 0, \"client_config\": {\"security_params\": null, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}, {\"int_value\": 1, \"name\": \"grpc.minimal_stack\"}], \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"threads_per_cq\": 0, \"load_params\": {\"closed_loop\": {}}, \"client_type\": \"ASYNC_CLIENT\", \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}" + "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}, {\"int_value\": 1, \"name\": \"grpc.minimal_stack\"}], \"security_params\": null, \"threads_per_cq\": 0, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"security_params\": null, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}, {\"int_value\": 1, \"name\": \"grpc.minimal_stack\"}], \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"threads_per_cq\": 0, \"load_params\": {\"closed_loop\": {}}, \"client_type\": \"ASYNC_CLIENT\", \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}" ], "auto_timeout_scaling": false, "boringssl": true, @@ -57765,9 +63879,7 @@ "tsan", "asan" ], - "excluded_poll_engines": [ - "poll-cv" - ], + "excluded_poll_engines": [], "flaky": false, "language": "c++", "name": "json_run_localhost", @@ -58691,7 +64803,7 @@ "args": [ "--run_inproc", "--scenarios_json", - "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"server_config\": {\"async_server_threads\": 0, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}, {\"int_value\": 1, \"name\": \"grpc.minimal_stack\"}], \"security_params\": null, \"threads_per_cq\": 0, \"server_type\": \"SYNC_SERVER\"}, \"num_servers\": 1, \"num_clients\": 0, \"client_config\": {\"security_params\": null, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}, {\"int_value\": 1, \"name\": \"grpc.minimal_stack\"}], \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"UNARY\", \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"threads_per_cq\": 0, \"load_params\": {\"closed_loop\": {}}, \"client_type\": \"ASYNC_CLIENT\", \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}" + "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}, {\"int_value\": 1, \"name\": \"grpc.minimal_stack\"}], \"security_params\": null, \"threads_per_cq\": 0, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"security_params\": null, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}, {\"int_value\": 1, \"name\": \"grpc.minimal_stack\"}], \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"UNARY\", \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"threads_per_cq\": 0, \"load_params\": {\"closed_loop\": {}}, \"client_type\": \"ASYNC_CLIENT\", \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}" ], "boringssl": true, "ci_platforms": [ @@ -58703,9 +64815,7 @@ "tsan", "asan" ], - "excluded_poll_engines": [ - "poll-cv" - ], + "excluded_poll_engines": [], "flaky": false, "language": "c++", "name": "qps_json_driver", @@ -58745,7 +64855,7 @@ "args": [ "--run_inproc", "--scenarios_json", - "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"server_config\": {\"async_server_threads\": 0, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}, {\"int_value\": 1, \"name\": \"grpc.minimal_stack\"}], \"security_params\": null, \"threads_per_cq\": 0, \"server_type\": \"SYNC_SERVER\"}, \"num_servers\": 1, \"num_clients\": 0, \"client_config\": {\"security_params\": null, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}, {\"int_value\": 1, \"name\": \"grpc.minimal_stack\"}], \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"threads_per_cq\": 0, \"load_params\": {\"closed_loop\": {}}, \"client_type\": \"ASYNC_CLIENT\", \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}" + "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}, {\"int_value\": 1, \"name\": \"grpc.minimal_stack\"}], \"security_params\": null, \"threads_per_cq\": 0, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"security_params\": null, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}, {\"int_value\": 1, \"name\": \"grpc.minimal_stack\"}], \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"threads_per_cq\": 0, \"load_params\": {\"closed_loop\": {}}, \"client_type\": \"ASYNC_CLIENT\", \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}" ], "boringssl": true, "ci_platforms": [ @@ -58757,9 +64867,7 @@ "tsan", "asan" ], - "excluded_poll_engines": [ - "poll-cv" - ], + "excluded_poll_engines": [], "flaky": false, "language": "c++", "name": "qps_json_driver", @@ -59750,7 +65858,7 @@ { "args": [ "--scenarios_json", - "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"server_config\": {\"async_server_threads\": 0, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}], \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"threads_per_cq\": 0, \"server_type\": \"SYNC_SERVER\"}, \"num_servers\": 1, \"num_clients\": 0, \"client_config\": {\"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}], \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 10, \"rpc_type\": \"UNARY\", \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"threads_per_cq\": 0, \"load_params\": {\"closed_loop\": {}}, \"client_type\": \"ASYNC_CLIENT\", \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}" + "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}], \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"threads_per_cq\": 0, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}], \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 10, \"rpc_type\": \"UNARY\", \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"threads_per_cq\": 0, \"load_params\": {\"closed_loop\": {}}, \"client_type\": \"ASYNC_CLIENT\", \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}" ], "auto_timeout_scaling": false, "boringssl": true, @@ -59777,9 +65885,7 @@ "stapprof", "ubsan" ], - "excluded_poll_engines": [ - "poll-cv" - ], + "excluded_poll_engines": [], "flaky": false, "language": "c++", "name": "json_run_localhost", @@ -59832,7 +65938,7 @@ { "args": [ "--scenarios_json", - "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"server_config\": {\"async_server_threads\": 0, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}], \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"threads_per_cq\": 0, \"server_type\": \"SYNC_SERVER\"}, \"num_servers\": 1, \"num_clients\": 0, \"client_config\": {\"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}], \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 10, \"rpc_type\": \"STREAMING\", \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"threads_per_cq\": 0, \"load_params\": {\"closed_loop\": {}}, \"client_type\": \"ASYNC_CLIENT\", \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}" + "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}], \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"threads_per_cq\": 0, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}], \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 10, \"rpc_type\": \"STREAMING\", \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"threads_per_cq\": 0, \"load_params\": {\"closed_loop\": {}}, \"client_type\": \"ASYNC_CLIENT\", \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}" ], "auto_timeout_scaling": false, "boringssl": true, @@ -59859,9 +65965,7 @@ "stapprof", "ubsan" ], - "excluded_poll_engines": [ - "poll-cv" - ], + "excluded_poll_engines": [], "flaky": false, "language": "c++", "name": "json_run_localhost", @@ -61234,7 +67338,7 @@ { "args": [ "--scenarios_json", - "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"server_config\": {\"async_server_threads\": 0, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}, {\"int_value\": 1, \"name\": \"grpc.minimal_stack\"}], \"security_params\": null, \"threads_per_cq\": 0, \"server_type\": \"SYNC_SERVER\"}, \"num_servers\": 1, \"num_clients\": 0, \"client_config\": {\"security_params\": null, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}, {\"int_value\": 1, \"name\": \"grpc.minimal_stack\"}], \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 10, \"rpc_type\": \"UNARY\", \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"threads_per_cq\": 0, \"load_params\": {\"closed_loop\": {}}, \"client_type\": \"ASYNC_CLIENT\", \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}" + "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}, {\"int_value\": 1, \"name\": \"grpc.minimal_stack\"}], \"security_params\": null, \"threads_per_cq\": 0, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"security_params\": null, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}, {\"int_value\": 1, \"name\": \"grpc.minimal_stack\"}], \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 10, \"rpc_type\": \"UNARY\", \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"threads_per_cq\": 0, \"load_params\": {\"closed_loop\": {}}, \"client_type\": \"ASYNC_CLIENT\", \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}" ], "auto_timeout_scaling": false, "boringssl": true, @@ -61261,9 +67365,7 @@ "stapprof", "ubsan" ], - "excluded_poll_engines": [ - "poll-cv" - ], + "excluded_poll_engines": [], "flaky": false, "language": "c++", "name": "json_run_localhost", @@ -61316,7 +67418,7 @@ { "args": [ "--scenarios_json", - "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"server_config\": {\"async_server_threads\": 0, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}, {\"int_value\": 1, \"name\": \"grpc.minimal_stack\"}], \"security_params\": null, \"threads_per_cq\": 0, \"server_type\": \"SYNC_SERVER\"}, \"num_servers\": 1, \"num_clients\": 0, \"client_config\": {\"security_params\": null, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}, {\"int_value\": 1, \"name\": \"grpc.minimal_stack\"}], \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 10, \"rpc_type\": \"STREAMING\", \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"threads_per_cq\": 0, \"load_params\": {\"closed_loop\": {}}, \"client_type\": \"ASYNC_CLIENT\", \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}" + "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}, {\"int_value\": 1, \"name\": \"grpc.minimal_stack\"}], \"security_params\": null, \"threads_per_cq\": 0, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"security_params\": null, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}, {\"int_value\": 1, \"name\": \"grpc.minimal_stack\"}], \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 10, \"rpc_type\": \"STREAMING\", \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"threads_per_cq\": 0, \"load_params\": {\"closed_loop\": {}}, \"client_type\": \"ASYNC_CLIENT\", \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}" ], "auto_timeout_scaling": false, "boringssl": true, @@ -61343,9 +67445,7 @@ "stapprof", "ubsan" ], - "excluded_poll_engines": [ - "poll-cv" - ], + "excluded_poll_engines": [], "flaky": false, "language": "c++", "name": "json_run_localhost", @@ -133794,6 +139894,29 @@ ], "uses_polling": false }, + { + "args": [ + "test/core/end2end/fuzzers/client_fuzzer_corpus/clusterfuzz-testcase-minimized-grpc_client_fuzzer-5765697914404864" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "client_fuzzer_one_entry", + "platforms": [ + "mac", + "linux" + ], + "uses_polling": false + }, { "args": [ "test/core/end2end/fuzzers/client_fuzzer_corpus/crash-12b69708d452b3cefe2da4a708a1030a661d37fc" @@ -165465,6 +171588,29 @@ ], "uses_polling": false }, + { + "args": [ + "test/core/slice/percent_decode_corpus/clusterfuzz-testcase-minimized-grpc_percent_decode_fuzzer-5652313562808320" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "percent_decode_fuzzer_one_entry", + "platforms": [ + "mac", + "linux" + ], + "uses_polling": false + }, { "args": [ "test/core/slice/percent_decode_corpus/d5b2a7177339ba2b7ce2f60e5f4459bef1e72758" diff --git a/tools/run_tests/helper_scripts/build_python.sh b/tools/run_tests/helper_scripts/build_python.sh index 8394f07e518..7cd1ef9d517 100755 --- a/tools/run_tests/helper_scripts/build_python.sh +++ b/tools/run_tests/helper_scripts/build_python.sh @@ -189,6 +189,11 @@ pip_install_dir "$ROOT" $VENV_PYTHON "$ROOT/tools/distrib/python/make_grpcio_tools.py" pip_install_dir "$ROOT/tools/distrib/python/grpcio_tools" +# Build/install Channelz +$VENV_PYTHON "$ROOT/src/python/grpcio_channelz/setup.py" preprocess +$VENV_PYTHON "$ROOT/src/python/grpcio_channelz/setup.py" build_package_protos +pip_install_dir "$ROOT/src/python/grpcio_channelz" + # Build/install health checking $VENV_PYTHON "$ROOT/src/python/grpcio_health_checking/setup.py" preprocess $VENV_PYTHON "$ROOT/src/python/grpcio_health_checking/setup.py" build_package_protos @@ -199,12 +204,18 @@ $VENV_PYTHON "$ROOT/src/python/grpcio_reflection/setup.py" preprocess $VENV_PYTHON "$ROOT/src/python/grpcio_reflection/setup.py" build_package_protos pip_install_dir "$ROOT/src/python/grpcio_reflection" +# Build/install status proto mapping +$VENV_PYTHON "$ROOT/src/python/grpcio_status/setup.py" preprocess +$VENV_PYTHON "$ROOT/src/python/grpcio_status/setup.py" build_package_protos +pip_install_dir "$ROOT/src/python/grpcio_status" + # Install testing pip_install_dir "$ROOT/src/python/grpcio_testing" # Build/install tests $VENV_PYTHON -m pip install coverage==4.4 oauth2client==4.1.0 \ - google-auth==1.0.0 requests==2.14.2 + google-auth==1.0.0 requests==2.14.2 \ + googleapis-common-protos==1.5.5 $VENV_PYTHON "$ROOT/src/python/grpcio_tests/setup.py" preprocess $VENV_PYTHON "$ROOT/src/python/grpcio_tests/setup.py" build_package_protos pip_install_dir "$ROOT/src/python/grpcio_tests" diff --git a/tools/run_tests/helper_scripts/run_grpc-node.sh b/tools/run_tests/helper_scripts/run_grpc-node.sh index 747aae7fd57..d14753a4d54 100755 --- a/tools/run_tests/helper_scripts/run_grpc-node.sh +++ b/tools/run_tests/helper_scripts/run_grpc-node.sh @@ -16,6 +16,8 @@ # This script runs grpc/grpc-node tests with their grpc submodule updated # to this reference +set -ex + # cd to gRPC root directory cd "$(dirname "$0")/../../.." 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 7ff877e8306..1c48ed20ba6 100755 --- a/tools/run_tests/helper_scripts/run_ruby_end2end_tests.sh +++ b/tools/run_tests/helper_scripts/run_ruby_end2end_tests.sh @@ -30,4 +30,6 @@ time ruby src/ruby/end2end/multiple_killed_watching_threads_driver.rb || EXIT_CO time ruby src/ruby/end2end/load_grpc_with_gc_stress_driver.rb || EXIT_CODE=1 time ruby src/ruby/end2end/client_memory_usage_driver.rb || EXIT_CODE=1 time ruby src/ruby/end2end/package_with_underscore_checker.rb || EXIT_CODE=1 +time ruby src/ruby/end2end/graceful_sig_handling_driver.rb || EXIT_CODE=1 +time ruby src/ruby/end2end/graceful_sig_stop_driver.rb || EXIT_CODE=1 exit $EXIT_CODE diff --git a/tools/run_tests/helper_scripts/run_tests_in_workspace.sh b/tools/run_tests/helper_scripts/run_tests_in_workspace.sh index 790c0418816..fa7a7aac0a0 100755 --- a/tools/run_tests/helper_scripts/run_tests_in_workspace.sh +++ b/tools/run_tests/helper_scripts/run_tests_in_workspace.sh @@ -20,7 +20,8 @@ set -ex cd "$(dirname "$0")/../../.." -export repo_root="$(pwd)" +repo_root="$(pwd)" +export repo_root rm -rf "${WORKSPACE_NAME}" git clone . "${WORKSPACE_NAME}" diff --git a/tools/run_tests/interop/with_nvm.sh b/tools/run_tests/interop/with_nvm.sh index 887f9f6a9f2..55f4b2b8759 100755 --- a/tools/run_tests/interop/with_nvm.sh +++ b/tools/run_tests/interop/with_nvm.sh @@ -15,5 +15,6 @@ # limitations under the License. # Makes sure NVM is loaded before executing the command passed as an argument +# shellcheck disable=SC1090 source ~/.nvm/nvm.sh "$@" diff --git a/tools/run_tests/interop/with_rvm.sh b/tools/run_tests/interop/with_rvm.sh index 41e6efcb566..82bce9da125 100755 --- a/tools/run_tests/interop/with_rvm.sh +++ b/tools/run_tests/interop/with_rvm.sh @@ -15,5 +15,6 @@ # limitations under the License. # Makes sure RVM is loaded before executing the command passed as an argument +# shellcheck disable=SC1091 source /usr/local/rvm/scripts/rvm "$@" diff --git a/tools/run_tests/performance/OWNERS b/tools/run_tests/performance/OWNERS deleted file mode 100644 index 9cf8c131111..00000000000 --- a/tools/run_tests/performance/OWNERS +++ /dev/null @@ -1,9 +0,0 @@ -set noparent - -# These owners are in place to ensure that scenario_result_schema.json is not -# modified without also running tools/run_tests/performance/patch_scenario_results_schema.py -# to update the BigQuery schema - -@ncteisen -@apolcyn -@jtattermusch diff --git a/tools/run_tests/performance/build_performance.sh b/tools/run_tests/performance/build_performance.sh index ab6bffdc34a..6c22e2d37d0 100755 --- a/tools/run_tests/performance/build_performance.sh +++ b/tools/run_tests/performance/build_performance.sh @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +# shellcheck disable=SC1090 source ~/.rvm/scripts/rvm set -ex diff --git a/tools/run_tests/performance/build_performance_go.sh b/tools/run_tests/performance/build_performance_go.sh index 812728d4ceb..3aa203a6eed 100755 --- a/tools/run_tests/performance/build_performance_go.sh +++ b/tools/run_tests/performance/build_performance_go.sh @@ -17,7 +17,8 @@ set -ex cd "$(dirname "$0")/../../.." -export GOPATH=$(pwd)/../gopath +GOPATH=$(pwd)/../gopath +export GOPATH # Get grpc-go and the dependencies but get rid of the upstream/master version go get google.golang.org/grpc diff --git a/tools/run_tests/performance/build_performance_node.sh b/tools/run_tests/performance/build_performance_node.sh index 12e08722648..b5b5d9a1a27 100755 --- a/tools/run_tests/performance/build_performance_node.sh +++ b/tools/run_tests/performance/build_performance_node.sh @@ -15,6 +15,7 @@ set +ex +# shellcheck disable=SC1090 . "$HOME/.nvm/nvm.sh" nvm install 10 diff --git a/tools/run_tests/performance/build_performance_php7.sh b/tools/run_tests/performance/build_performance_php7.sh index 37ca9ee8770..386c7862abd 100755 --- a/tools/run_tests/performance/build_performance_php7.sh +++ b/tools/run_tests/performance/build_performance_php7.sh @@ -23,7 +23,7 @@ python tools/run_tests/run_tests.py -l php7 -c "$CONFIG" --build_only -j 8 cd src/php/tests/qps composer install # Install protobuf C-extension for php -cd vendor/google/protobuf/php/ext/google/protobuf +cd ../../../../third_party/protobuf/php/ext/google/protobuf phpize ./configure make diff --git a/tools/run_tests/performance/run_worker_csharp.sh b/tools/run_tests/performance/run_worker_csharp.sh index 6546d6010b1..af944f9fefa 100755 --- a/tools/run_tests/performance/run_worker_csharp.sh +++ b/tools/run_tests/performance/run_worker_csharp.sh @@ -18,6 +18,6 @@ set -ex cd "$(dirname "$0")/../../.." # needed to correctly locate testca -cd src/csharp/Grpc.IntegrationTesting.QpsWorker/bin/Release/netcoreapp1.0 +cd src/csharp/Grpc.IntegrationTesting.QpsWorker/bin/Release/netcoreapp2.1 dotnet exec Grpc.IntegrationTesting.QpsWorker.dll "$@" diff --git a/tools/run_tests/performance/run_worker_go.sh b/tools/run_tests/performance/run_worker_go.sh index f8e821a2656..1127f4f25ac 100755 --- a/tools/run_tests/performance/run_worker_go.sh +++ b/tools/run_tests/performance/run_worker_go.sh @@ -17,6 +17,7 @@ set -ex cd "$(dirname "$0")/../../.." -export GOPATH=$(pwd)/../gopath +GOPATH=$(pwd)/../gopath +export GOPATH "${GOPATH}/bin/worker" "$@" diff --git a/tools/run_tests/performance/run_worker_node.sh b/tools/run_tests/performance/run_worker_node.sh index 3e5dd18edb3..658cd508116 100755 --- a/tools/run_tests/performance/run_worker_node.sh +++ b/tools/run_tests/performance/run_worker_node.sh @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +# shellcheck disable=SC1090 . "$HOME/.nvm/nvm.sh" nvm use 10 diff --git a/tools/run_tests/performance/run_worker_php.sh b/tools/run_tests/performance/run_worker_php.sh index 2fe2493e601..97292a9978f 100755 --- a/tools/run_tests/performance/run_worker_php.sh +++ b/tools/run_tests/performance/run_worker_php.sh @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +# shellcheck disable=SC1090 source ~/.rvm/scripts/rvm set -ex diff --git a/tools/run_tests/performance/run_worker_ruby.sh b/tools/run_tests/performance/run_worker_ruby.sh index 729c5cec977..ed448463360 100755 --- a/tools/run_tests/performance/run_worker_ruby.sh +++ b/tools/run_tests/performance/run_worker_ruby.sh @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +# shellcheck disable=SC1090 source ~/.rvm/scripts/rvm set -ex diff --git a/tools/run_tests/performance/scenario_config.py b/tools/run_tests/performance/scenario_config.py index 481918c52e4..ac25b22d9e4 100644 --- a/tools/run_tests/performance/scenario_config.py +++ b/tools/run_tests/performance/scenario_config.py @@ -463,8 +463,7 @@ class CXXLanguage: secure=secure, minimal_stack=not secure, categories=smoketest_categories + inproc_categories + - [SCALABLE], - excluded_poll_engines=['poll-cv']) + [SCALABLE]) yield _ping_pong_scenario( 'cpp_protobuf_async_client_unary_1channel_64wide_128Breq_8MBresp_%s' @@ -490,8 +489,7 @@ class CXXLanguage: secure=secure, minimal_stack=not secure, categories=smoketest_categories + inproc_categories + - [SCALABLE], - excluded_poll_engines=['poll-cv']) + [SCALABLE]) yield _ping_pong_scenario( 'cpp_protobuf_async_unary_ping_pong_%s_1MB' % secstr, diff --git a/tools/run_tests/python_utils/check_on_pr.py b/tools/run_tests/python_utils/check_on_pr.py new file mode 100644 index 00000000000..f2b0f24e4fe --- /dev/null +++ b/tools/run_tests/python_utils/check_on_pr.py @@ -0,0 +1,141 @@ +# Copyright 2018 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. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import print_function +import os +import sys +import json +import time +import datetime +import traceback + +import requests +import jwt + +_GITHUB_API_PREFIX = 'https://api.github.com' +_GITHUB_REPO = 'grpc/grpc' +_GITHUB_APP_ID = 22338 +_INSTALLATION_ID = 519109 + +_ACCESS_TOKEN_CACHE = None +_ACCESS_TOKEN_FETCH_RETRIES = 6 +_ACCESS_TOKEN_FETCH_RETRIES_INTERVAL_S = 15 + + +def _jwt_token(): + github_app_key = open( + os.path.join(os.environ['KOKORO_KEYSTORE_DIR'], + '73836_grpc_checks_private_key'), 'rb').read() + return jwt.encode( + { + 'iat': int(time.time()), + 'exp': int(time.time() + 60 * 10), # expire in 10 minutes + 'iss': _GITHUB_APP_ID, + }, + github_app_key, + algorithm='RS256') + + +def _access_token(): + global _ACCESS_TOKEN_CACHE + if _ACCESS_TOKEN_CACHE == None or _ACCESS_TOKEN_CACHE['exp'] < time.time(): + for i in range(_ACCESS_TOKEN_FETCH_RETRIES): + resp = requests.post( + url='https://api.github.com/app/installations/%s/access_tokens' + % _INSTALLATION_ID, + headers={ + 'Authorization': 'Bearer %s' % _jwt_token().decode('ASCII'), + 'Accept': 'application/vnd.github.machine-man-preview+json', + }) + + try: + _ACCESS_TOKEN_CACHE = { + 'token': resp.json()['token'], + 'exp': time.time() + 60 + } + break + except (KeyError, ValueError) as e: + traceback.print_exc(e) + print('HTTP Status %d %s' % (resp.status_code, resp.reason)) + print("Fetch access token from Github API failed:") + print(resp.text) + if i != _ACCESS_TOKEN_FETCH_RETRIES - 1: + print('Retrying after %.2f second.' % + _ACCESS_TOKEN_FETCH_RETRIES_INTERVAL_S) + time.sleep(_ACCESS_TOKEN_FETCH_RETRIES_INTERVAL_S) + else: + print("error: Unable to fetch access token, exiting...") + sys.exit(0) + + return _ACCESS_TOKEN_CACHE['token'] + + +def _call(url, method='GET', json=None): + if not url.startswith('https://'): + url = _GITHUB_API_PREFIX + url + headers = { + 'Authorization': 'Bearer %s' % _access_token(), + 'Accept': 'application/vnd.github.antiope-preview+json', + } + return requests.request(method=method, url=url, headers=headers, json=json) + + +def _latest_commit(): + resp = _call('/repos/%s/pulls/%s/commits' % + (_GITHUB_REPO, + os.environ['KOKORO_GITHUB_PULL_REQUEST_NUMBER'])) + return resp.json()[-1] + + +def check_on_pr(name, summary, success=True): + """Create/Update a check on current pull request. + + The check runs are aggregated by their name, so newer check will update the + older check with the same name. + + Requires environment variable 'KOKORO_GITHUB_PULL_REQUEST_NUMBER' to indicate which pull request + should be updated. + + Args: + name: The name of the check. + summary: A str in Markdown to be used as the detail information of the check. + success: A bool indicates whether the check is succeed or not. + """ + if 'KOKORO_GIT_COMMIT' not in os.environ: + print('Missing KOKORO_GIT_COMMIT env var: not checking') + return + if 'KOKORO_KEYSTORE_DIR' not in os.environ: + print('Missing KOKORO_KEYSTORE_DIR env var: not checking') + return + if 'KOKORO_GITHUB_PULL_REQUEST_NUMBER' not in os.environ: + print('Missing KOKORO_GITHUB_PULL_REQUEST_NUMBER env var: not checking') + return + completion_time = str( + datetime.datetime.utcnow().replace(microsecond=0).isoformat()) + 'Z' + resp = _call( + '/repos/%s/check-runs' % _GITHUB_REPO, + method='POST', + json={ + 'name': name, + 'head_sha': os.environ['KOKORO_GIT_COMMIT'], + 'status': 'completed', + 'completed_at': completion_time, + 'conclusion': 'success' if success else 'failure', + 'output': { + 'title': name, + 'summary': summary, + } + }) + print('Result of Creating/Updating Check on PR:', + json.dumps(resp.json(), indent=2)) diff --git a/tools/run_tests/python_utils/comment_on_pr.py b/tools/run_tests/python_utils/comment_on_pr.py deleted file mode 100644 index 399c996d4db..00000000000 --- a/tools/run_tests/python_utils/comment_on_pr.py +++ /dev/null @@ -1,37 +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. - -import os -import json -import urllib2 - - -def comment_on_pr(text): - if 'JENKINS_OAUTH_TOKEN' not in os.environ: - print 'Missing JENKINS_OAUTH_TOKEN env var: not commenting' - return - if 'ghprbPullId' not in os.environ: - print 'Missing ghprbPullId env var: not commenting' - return - req = urllib2.Request( - url='https://api.github.com/repos/grpc/grpc/issues/%s/comments' % - os.environ['ghprbPullId'], - data=json.dumps({ - 'body': text - }), - headers={ - 'Authorization': 'token %s' % os.environ['JENKINS_OAUTH_TOKEN'], - 'Content-Type': 'application/json', - }) - print urllib2.urlopen(req).read() diff --git a/tools/run_tests/python_utils/upload_rbe_results.py b/tools/run_tests/python_utils/upload_rbe_results.py old mode 100644 new mode 100755 index 3f3bd382bb6..e6504799d66 --- a/tools/run_tests/python_utils/upload_rbe_results.py +++ b/tools/run_tests/python_utils/upload_rbe_results.py @@ -122,7 +122,7 @@ def _get_resultstore_data(api_key, invocation_id): while True: req = urllib2.Request( url= - 'https://resultstore.googleapis.com/v2/invocations/%s/targets/-/configuredTargets/-/actions?key=%s&pageToken=%s' + 'https://resultstore.googleapis.com/v2/invocations/%s/targets/-/configuredTargets/-/actions?key=%s&pageToken=%s&fields=next_page_token,actions.id,actions.status_attributes,actions.timing,actions.test_action' % (invocation_id, api_key, page_token), headers={ 'Content-Type': 'application/json' @@ -146,6 +146,8 @@ if __name__ == "__main__": invocation_id = args.invocation_id or _get_invocation_id() resultstore_actions = _get_resultstore_data(api_key, invocation_id) + # google.devtools.resultstore.v2.Action schema: + # https://github.com/googleapis/googleapis/blob/master/google/devtools/resultstore/v2/action.proto bq_rows = [] for index, action in enumerate(resultstore_actions): # Filter out non-test related data, such as build results. @@ -185,6 +187,10 @@ if __name__ == "__main__": 'startTime': resultstore_actions[index - 1]['timing']['startTime'] } + elif 'testSuite' not in action['testAction']: + continue + elif 'tests' not in action['testAction']['testSuite']: + continue else: test_cases = action['testAction']['testSuite']['tests'][0][ 'testSuite']['tests'] diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py index ff6682c3cf8..cc6901bdebe 100755 --- a/tools/run_tests/run_interop_tests.py +++ b/tools/run_tests/run_interop_tests.py @@ -65,6 +65,18 @@ _SKIP_ADVANCED = [ _SKIP_SPECIAL_STATUS_MESSAGE = ['special_status_message'] +_GOOGLE_DEFAULT_CREDS_TEST_CASE = 'google_default_credentials' + +_SKIP_GOOGLE_DEFAULT_CREDS = [ + _GOOGLE_DEFAULT_CREDS_TEST_CASE, +] + +_COMPUTE_ENGINE_CHANNEL_CREDS_TEST_CASE = 'compute_engine_channel_credentials' + +_SKIP_COMPUTE_ENGINE_CHANNEL_CREDS = [ + _COMPUTE_ENGINE_CHANNEL_CREDS_TEST_CASE, +] + _TEST_TIMEOUT = 3 * 60 # disable this test on core-based languages, @@ -100,7 +112,9 @@ class CXXLanguage: return {} def unimplemented_test_cases(self): - return _SKIP_DATA_FRAME_PADDING + _SKIP_SPECIAL_STATUS_MESSAGE + return _SKIP_DATA_FRAME_PADDING + \ + _SKIP_SPECIAL_STATUS_MESSAGE + \ + _SKIP_COMPUTE_ENGINE_CHANNEL_CREDS def unimplemented_test_cases_server(self): return [] @@ -129,7 +143,11 @@ class CSharpLanguage: return {} def unimplemented_test_cases(self): - return _SKIP_SERVER_COMPRESSION + _SKIP_DATA_FRAME_PADDING + _SKIP_SPECIAL_STATUS_MESSAGE + return _SKIP_SERVER_COMPRESSION + \ + _SKIP_DATA_FRAME_PADDING + \ + _SKIP_SPECIAL_STATUS_MESSAGE + \ + _SKIP_GOOGLE_DEFAULT_CREDS + \ + _SKIP_COMPUTE_ENGINE_CHANNEL_CREDS def unimplemented_test_cases_server(self): return _SKIP_COMPRESSION @@ -141,8 +159,8 @@ class CSharpLanguage: class CSharpCoreCLRLanguage: def __init__(self): - self.client_cwd = 'src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0' - self.server_cwd = 'src/csharp/Grpc.IntegrationTesting.Server/bin/Debug/netcoreapp1.0' + self.client_cwd = 'src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp2.1' + self.server_cwd = 'src/csharp/Grpc.IntegrationTesting.Server/bin/Debug/netcoreapp2.1' self.safename = str(self) def client_cmd(self, args): @@ -158,7 +176,11 @@ class CSharpCoreCLRLanguage: return {} def unimplemented_test_cases(self): - return _SKIP_SERVER_COMPRESSION + _SKIP_DATA_FRAME_PADDING + _SKIP_SPECIAL_STATUS_MESSAGE + return _SKIP_SERVER_COMPRESSION + \ + _SKIP_DATA_FRAME_PADDING + \ + _SKIP_SPECIAL_STATUS_MESSAGE + \ + _SKIP_GOOGLE_DEFAULT_CREDS + \ + _SKIP_COMPUTE_ENGINE_CHANNEL_CREDS def unimplemented_test_cases_server(self): return _SKIP_COMPRESSION @@ -167,6 +189,38 @@ class CSharpCoreCLRLanguage: return 'csharpcoreclr' +class AspNetCoreLanguage: + + def __init__(self): + self.client_cwd = '../grpc-dotnet/testassets/InteropTestsClient/bin/Debug/netcoreapp3.0' + self.server_cwd = '../grpc-dotnet/testassets/InteropTestsWebsite/bin/Debug/netcoreapp3.0' + self.safename = str(self) + + def cloud_to_prod_env(self): + return {} + + def client_cmd(self, args): + return ['dotnet', 'exec', 'InteropTestsClient.dll'] + args + + def server_cmd(self, args): + return ['dotnet', 'exec', 'InteropTestsWebsite.dll'] + args + + def global_env(self): + return {} + + def unimplemented_test_cases(self): + return _SKIP_COMPRESSION + \ + _SKIP_SPECIAL_STATUS_MESSAGE + \ + _AUTH_TEST_CASES + \ + ['cancel_after_first_response', 'ping_pong'] + + def unimplemented_test_cases_server(self): + return _SKIP_COMPRESSION + _SKIP_SPECIAL_STATUS_MESSAGE + + def __str__(self): + return 'aspnetcore' + + class DartLanguage: def __init__(self): @@ -188,7 +242,10 @@ class DartLanguage: return {} def unimplemented_test_cases(self): - return _SKIP_COMPRESSION + _SKIP_SPECIAL_STATUS_MESSAGE + return _SKIP_COMPRESSION + \ + _SKIP_SPECIAL_STATUS_MESSAGE + \ + _SKIP_GOOGLE_DEFAULT_CREDS + \ + _SKIP_COMPUTE_ENGINE_CHANNEL_CREDS def unimplemented_test_cases_server(self): return _SKIP_COMPRESSION + _SKIP_SPECIAL_STATUS_MESSAGE @@ -309,7 +366,11 @@ class Http2Server: return {} def unimplemented_test_cases(self): - return _TEST_CASES + _SKIP_DATA_FRAME_PADDING + _SKIP_SPECIAL_STATUS_MESSAGE + return _TEST_CASES + \ + _SKIP_DATA_FRAME_PADDING + \ + _SKIP_SPECIAL_STATUS_MESSAGE + \ + _SKIP_GOOGLE_DEFAULT_CREDS + \ + _SKIP_COMPUTE_ENGINE_CHANNEL_CREDS def unimplemented_test_cases_server(self): return _TEST_CASES @@ -339,7 +400,10 @@ class Http2Client: return {} def unimplemented_test_cases(self): - return _TEST_CASES + _SKIP_SPECIAL_STATUS_MESSAGE + return _TEST_CASES + \ + _SKIP_SPECIAL_STATUS_MESSAGE + \ + _SKIP_GOOGLE_DEFAULT_CREDS + \ + _SKIP_COMPUTE_ENGINE_CHANNEL_CREDS def unimplemented_test_cases_server(self): return _TEST_CASES @@ -376,7 +440,10 @@ class NodeLanguage: return {} def unimplemented_test_cases(self): - return _SKIP_COMPRESSION + _SKIP_DATA_FRAME_PADDING + return _SKIP_COMPRESSION + \ + _SKIP_DATA_FRAME_PADDING + \ + _SKIP_GOOGLE_DEFAULT_CREDS + \ + _SKIP_COMPUTE_ENGINE_CHANNEL_CREDS def unimplemented_test_cases_server(self): return _SKIP_COMPRESSION @@ -406,7 +473,10 @@ class NodePureJSLanguage: return {} def unimplemented_test_cases(self): - return _SKIP_COMPRESSION + _SKIP_DATA_FRAME_PADDING + return _SKIP_COMPRESSION + \ + _SKIP_DATA_FRAME_PADDING + \ + _SKIP_GOOGLE_DEFAULT_CREDS + \ + _SKIP_COMPUTE_ENGINE_CHANNEL_CREDS def unimplemented_test_cases_server(self): return [] @@ -431,7 +501,11 @@ class PHPLanguage: return {} def unimplemented_test_cases(self): - return _SKIP_COMPRESSION + _SKIP_DATA_FRAME_PADDING + _SKIP_SPECIAL_STATUS_MESSAGE + return _SKIP_COMPRESSION + \ + _SKIP_DATA_FRAME_PADDING + \ + _SKIP_SPECIAL_STATUS_MESSAGE + \ + _SKIP_GOOGLE_DEFAULT_CREDS + \ + _SKIP_COMPUTE_ENGINE_CHANNEL_CREDS def unimplemented_test_cases_server(self): return [] @@ -456,7 +530,11 @@ class PHP7Language: return {} def unimplemented_test_cases(self): - return _SKIP_COMPRESSION + _SKIP_DATA_FRAME_PADDING + _SKIP_SPECIAL_STATUS_MESSAGE + return _SKIP_COMPRESSION + \ + _SKIP_DATA_FRAME_PADDING + \ + _SKIP_SPECIAL_STATUS_MESSAGE + \ + _SKIP_GOOGLE_DEFAULT_CREDS + \ + _SKIP_COMPUTE_ENGINE_CHANNEL_CREDS def unimplemented_test_cases_server(self): return [] @@ -491,7 +569,12 @@ class ObjcLanguage: # cmdline argument. Here we return all but one test cases as unimplemented, # and depend upon ObjC test's behavior that it runs all cases even when # we tell it to run just one. - return _TEST_CASES[1:] + _SKIP_COMPRESSION + _SKIP_DATA_FRAME_PADDING + _SKIP_SPECIAL_STATUS_MESSAGE + return _TEST_CASES[1:] + \ + _SKIP_COMPRESSION + \ + _SKIP_DATA_FRAME_PADDING + \ + _SKIP_SPECIAL_STATUS_MESSAGE + \ + _SKIP_GOOGLE_DEFAULT_CREDS + \ + _SKIP_COMPUTE_ENGINE_CHANNEL_CREDS def unimplemented_test_cases_server(self): return _SKIP_COMPRESSION @@ -526,7 +609,11 @@ class RubyLanguage: return {} def unimplemented_test_cases(self): - return _SKIP_SERVER_COMPRESSION + _SKIP_DATA_FRAME_PADDING + _SKIP_SPECIAL_STATUS_MESSAGE + return _SKIP_SERVER_COMPRESSION + \ + _SKIP_DATA_FRAME_PADDING + \ + _SKIP_SPECIAL_STATUS_MESSAGE + \ + _SKIP_GOOGLE_DEFAULT_CREDS + \ + _SKIP_COMPUTE_ENGINE_CHANNEL_CREDS def unimplemented_test_cases_server(self): return _SKIP_COMPRESSION @@ -545,13 +632,13 @@ class PythonLanguage: def client_cmd(self, args): return [ - 'py27_native/bin/python', 'src/python/grpcio_tests/setup.py', + 'py37_native/bin/python', 'src/python/grpcio_tests/setup.py', 'run_interop', '--client', '--args="{}"'.format(' '.join(args)) ] def client_cmd_http2interop(self, args): return [ - 'py27_native/bin/python', + 'py37_native/bin/python', 'src/python/grpcio_tests/tests/http2/negative_http2_client.py', ] + args @@ -560,7 +647,7 @@ class PythonLanguage: def server_cmd(self, args): return [ - 'py27_native/bin/python', 'src/python/grpcio_tests/setup.py', + 'py37_native/bin/python', 'src/python/grpcio_tests/setup.py', 'run_interop', '--server', '--args="{}"'.format(' '.join(args)) ] @@ -571,7 +658,10 @@ class PythonLanguage: } def unimplemented_test_cases(self): - return _SKIP_COMPRESSION + _SKIP_DATA_FRAME_PADDING + return _SKIP_COMPRESSION + \ + _SKIP_DATA_FRAME_PADDING + \ + _SKIP_GOOGLE_DEFAULT_CREDS + \ + _SKIP_COMPUTE_ENGINE_CHANNEL_CREDS def unimplemented_test_cases_server(self): return _SKIP_COMPRESSION @@ -584,6 +674,7 @@ _LANGUAGES = { 'c++': CXXLanguage(), 'csharp': CSharpLanguage(), 'csharpcoreclr': CSharpCoreCLRLanguage(), + 'aspnetcore': AspNetCoreLanguage(), 'dart': DartLanguage(), 'go': GoLanguage(), 'java': JavaLanguage(), @@ -599,8 +690,8 @@ _LANGUAGES = { # languages supported as cloud_to_cloud servers _SERVERS = [ - 'c++', 'node', 'csharp', 'csharpcoreclr', 'java', 'go', 'ruby', 'python', - 'dart' + 'c++', 'node', 'csharp', 'csharpcoreclr', 'aspnetcore', 'java', 'go', + 'ruby', 'python', 'dart' ] _TEST_CASES = [ @@ -614,8 +705,12 @@ _TEST_CASES = [ ] _AUTH_TEST_CASES = [ - 'compute_engine_creds', 'jwt_token_creds', 'oauth2_auth_token', - 'per_rpc_creds' + 'compute_engine_creds', + 'jwt_token_creds', + 'oauth2_auth_token', + 'per_rpc_creds', + _GOOGLE_DEFAULT_CREDS_TEST_CASE, + _COMPUTE_ENGINE_CHANNEL_CREDS_TEST_CASE, ] _HTTP2_TEST_CASES = ['tls', 'framing'] @@ -641,9 +736,7 @@ _LANGUAGES_FOR_ALTS_TEST_CASES = ['java', 'go', 'c++'] _SERVERS_FOR_ALTS_TEST_CASES = ['java', 'go', 'c++'] -_TRANSPORT_SECURITY_OPTIONS = [ - 'tls', 'alts', 'google_default_credentials', 'insecure' -] +_TRANSPORT_SECURITY_OPTIONS = ['tls', 'alts', 'insecure'] DOCKER_WORKDIR_ROOT = '/var/local/git/grpc' @@ -714,7 +807,10 @@ def compute_engine_creds_required(language, test_case): return False -def auth_options(language, test_case, service_account_key_file=None): +def auth_options(language, + test_case, + google_default_creds_use_key_file, + service_account_key_file=None): """Returns (cmdline, env) tuple with cloud_to_prod_auth test options.""" language = str(language) @@ -728,9 +824,6 @@ def auth_options(language, test_case, service_account_key_file=None): key_file_arg = '--service_account_key_file=%s' % service_account_key_file default_account_arg = '--default_service_account=830293263384-compute@developer.gserviceaccount.com' - # TODO: When using google_default_credentials outside of cloud-to-prod, the environment variable - # 'GOOGLE_APPLICATION_CREDENTIALS' needs to be set for the test case - # 'jwt_token_creds' to work. if test_case in ['jwt_token_creds', 'per_rpc_creds', 'oauth2_auth_token']: if language in [ 'csharp', 'csharpcoreclr', 'node', 'php', 'php7', 'python', @@ -750,6 +843,14 @@ def auth_options(language, test_case, service_account_key_file=None): if test_case == 'compute_engine_creds': cmdargs += [oauth_scope_arg, default_account_arg] + if test_case == _GOOGLE_DEFAULT_CREDS_TEST_CASE: + if google_default_creds_use_key_file: + env['GOOGLE_APPLICATION_CREDENTIALS'] = service_account_key_file + cmdargs += [default_account_arg] + + if test_case == _COMPUTE_ENGINE_CHANNEL_CREDS_TEST_CASE: + cmdargs += [default_account_arg] + return (cmdargs, env) @@ -759,7 +860,7 @@ def _job_kill_handler(job): # When the job times out and we decide to kill it, # we need to wait a before restarting the job # to prevent "container name already in use" error. - # TODO(jtattermusch): figure out a cleaner way to to this. + # TODO(jtattermusch): figure out a cleaner way to this. time.sleep(2) @@ -767,6 +868,7 @@ def cloud_to_prod_jobspec(language, test_case, server_host_nickname, server_host, + google_default_creds_use_key_file, docker_image=None, auth=False, manual_cmd_log=None, @@ -775,8 +877,7 @@ def cloud_to_prod_jobspec(language, """Creates jobspec for cloud-to-prod interop test""" container_name = None cmdargs = [ - '--server_host=%s' % server_host, - '--server_host_override=%s' % server_host, '--server_port=443', + '--server_host=%s' % server_host, '--server_port=443', '--test_case=%s' % test_case ] if transport_security == 'tls': @@ -786,14 +887,21 @@ def cloud_to_prod_jobspec(language, transport_security_options = [ '--custom_credentials_type=google_default_credentials' ] + elif transport_security == 'compute_engine_channel_creds' and str( + language) in ['go', 'java', 'javaokhttp']: + transport_security_options = [ + '--custom_credentials_type=compute_engine_channel_creds' + ] else: - print('Invalid transport security option %s in cloud_to_prod_jobspec.' % - transport_security) + print( + 'Invalid transport security option %s in cloud_to_prod_jobspec. Lang: %s' + % (str(language), transport_security)) sys.exit(1) cmdargs = cmdargs + transport_security_options environ = dict(language.cloud_to_prod_env(), **language.global_env()) if auth: auth_cmdargs, auth_env = auth_options(language, test_case, + google_default_creds_use_key_file, service_account_key_file) cmdargs += auth_cmdargs environ.update(auth_env) @@ -1071,6 +1179,14 @@ argp.add_argument( action='store_const', const=True, help='Run cloud_to_prod_auth tests.') +argp.add_argument( + '--google_default_creds_use_key_file', + default=False, + action='store_const', + const=True, + help=('Whether or not we should use a key file for the ' + 'google_default_credentials test case, e.g. by ' + 'setting env var GOOGLE_APPLICATION_CREDENTIALS.')) argp.add_argument( '--prod_servers', choices=prod_servers.keys(), @@ -1312,10 +1428,8 @@ try: jobs = [] if args.cloud_to_prod: - if args.transport_security not in ['tls', 'google_default_credentials']: - print( - 'TLS or google default credential is always enabled for cloud_to_prod scenarios.' - ) + if args.transport_security not in ['tls']: + print('TLS is always enabled for cloud_to_prod scenarios.') for server_host_nickname in args.prod_servers: for language in languages: for test_case in _TEST_CASES: @@ -1326,6 +1440,8 @@ try: test_case, server_host_nickname, prod_servers[server_host_nickname], + google_default_creds_use_key_file=args. + google_default_creds_use_key_file, docker_image=docker_images.get(str(language)), manual_cmd_log=client_manual_cmd_log, service_account_key_file=args. @@ -1340,6 +1456,8 @@ try: test_case, server_host_nickname, prod_servers[server_host_nickname], + google_default_creds_use_key_file=args. + google_default_creds_use_key_file, docker_image=docker_images.get( str(language)), manual_cmd_log=client_manual_cmd_log, @@ -1348,6 +1466,23 @@ try: transport_security= 'google_default_credentials') jobs.append(google_default_creds_test_job) + if str(language) in ['go', 'java', 'javaokhttp']: + compute_engine_channel_creds_test_job = cloud_to_prod_jobspec( + language, + test_case, + server_host_nickname, + prod_servers[server_host_nickname], + google_default_creds_use_key_file=args. + google_default_creds_use_key_file, + docker_image=docker_images.get( + str(language)), + manual_cmd_log=client_manual_cmd_log, + service_account_key_file=args. + service_account_key_file, + transport_security= + 'compute_engine_channel_creds') + jobs.append( + compute_engine_channel_creds_test_job) if args.http2_interop: for test_case in _HTTP2_TEST_CASES: @@ -1356,6 +1491,8 @@ try: test_case, server_host_nickname, prod_servers[server_host_nickname], + google_default_creds_use_key_file=args. + google_default_creds_use_key_file, docker_image=docker_images.get(str(http2Interop)), manual_cmd_log=client_manual_cmd_log, service_account_key_file=args.service_account_key_file, @@ -1363,10 +1500,8 @@ try: jobs.append(test_job) if args.cloud_to_prod_auth: - if args.transport_security not in ['tls', 'google_default_credentials']: - print( - 'TLS or google default credential is always enabled for cloud_to_prod scenarios.' - ) + if args.transport_security not in ['tls']: + print('TLS is always enabled for cloud_to_prod scenarios.') for server_host_nickname in args.prod_servers: for language in languages: for test_case in _AUTH_TEST_CASES: @@ -1374,36 +1509,26 @@ try: not compute_engine_creds_required( language, test_case)): if not test_case in language.unimplemented_test_cases(): - tls_test_job = cloud_to_prod_jobspec( + if test_case == _GOOGLE_DEFAULT_CREDS_TEST_CASE: + transport_security = 'google_default_credentials' + elif test_case == _COMPUTE_ENGINE_CHANNEL_CREDS_TEST_CASE: + transport_security = 'compute_engine_channel_creds' + else: + transport_security = 'tls' + test_job = cloud_to_prod_jobspec( language, test_case, server_host_nickname, prod_servers[server_host_nickname], + google_default_creds_use_key_file=args. + google_default_creds_use_key_file, 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, - transport_security='tls') - jobs.append(tls_test_job) - if str(language) in [ - 'go' - ]: # Add more languages to the list to turn on tests. - google_default_creds_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, - transport_security= - 'google_default_credentials') - jobs.append(google_default_creds_test_job) - + transport_security=transport_security) + jobs.append(test_job) for server in args.override_server: server_name = server[0] (server_host, server_port) = server[1].split(':') diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py index a1f2aaab2f3..a7a9dbd48d0 100755 --- a/tools/run_tests/run_tests.py +++ b/tools/run_tests/run_tests.py @@ -61,7 +61,7 @@ _FORCE_ENVIRON_FOR_WRAPPERS = { } _POLLING_STRATEGIES = { - 'linux': ['epollex', 'epoll1', 'poll', 'poll-cv'], + 'linux': ['epollex', 'epoll1', 'poll'], 'mac': ['poll'], } @@ -106,6 +106,7 @@ def platform_string(): _DEFAULT_TIMEOUT_SECONDS = 5 * 60 +_PRE_BUILD_STEP_TIMEOUT_SECONDS = 10 * 60 def run_shell_command(cmd, env=None, cwd=None): @@ -344,15 +345,6 @@ class CLanguage(object): # Scale overall test timeout if running under various sanitizers. # scaling value is based on historical data analysis timeout_scaling *= 3 - elif polling_strategy == 'poll-cv': - # scale test timeout if running with poll-cv - # sanitizer and poll-cv scaling is not cumulative to ensure - # reasonable timeout values. - # TODO(jtattermusch): based on historical data and 5min default - # test timeout poll-cv scaling is currently not useful. - # Leaving here so it can be reintroduced if the default test timeout - # is decreased in the future. - timeout_scaling *= 1 if self.config.build_config in target['exclude_configs']: continue @@ -756,9 +748,10 @@ class PythonLanguage(object): def dockerfile_dir(self): return 'tools/dockerfile/test/python_%s_%s' % ( - self.python_manager_name(), _docker_arch_suffix(self.args.arch)) + self._python_manager_name(), _docker_arch_suffix(self.args.arch)) - def python_manager_name(self): + def _python_manager_name(self): + """Choose the docker image to use based on python version.""" if self.args.compiler in [ 'python2.7', 'python3.5', 'python3.6', 'python3.7' ]: @@ -771,6 +764,7 @@ class PythonLanguage(object): return 'stretch_3.7' def _get_pythons(self, args): + """Get python runtimes to test with, based on current platform, architecture, compiler etc.""" if args.arch == 'x86': bits = '32' else: @@ -940,7 +934,7 @@ class CSharpLanguage(object): self._cmake_arch_option = 'x64' else: _check_compiler(self.args.compiler, ['default', 'coreclr']) - self._docker_distro = 'jessie' + self._docker_distro = 'stretch' def test_specs(self): with open('src/csharp/tests.json') as f: @@ -952,7 +946,7 @@ class CSharpLanguage(object): assembly_extension = '.exe' if self.args.compiler == 'coreclr': - assembly_subdir += '/netcoreapp1.0' + assembly_subdir += '/netcoreapp2.1' runtime_cmd = ['dotnet', 'exec'] assembly_extension = '.dll' else: @@ -1067,33 +1061,6 @@ class ObjCLanguage(object): shortname='objc-plugin-tests', cpu_cost=1e6, environ=_FORCE_ENVIRON_FOR_WRAPPERS), - self.config.job_spec( - ['src/objective-c/tests/build_one_example.sh'], - timeout_seconds=10 * 60, - shortname='objc-build-example-helloworld', - cpu_cost=1e6, - environ={ - 'SCHEME': 'HelloWorld', - 'EXAMPLE_PATH': 'examples/objective-c/helloworld' - }), - self.config.job_spec( - ['src/objective-c/tests/build_one_example.sh'], - timeout_seconds=10 * 60, - shortname='objc-build-example-routeguide', - cpu_cost=1e6, - environ={ - 'SCHEME': 'RouteGuideClient', - 'EXAMPLE_PATH': 'examples/objective-c/route_guide' - }), - self.config.job_spec( - ['src/objective-c/tests/build_one_example.sh'], - timeout_seconds=10 * 60, - shortname='objc-build-example-authsample', - cpu_cost=1e6, - environ={ - 'SCHEME': 'AuthSample', - 'EXAMPLE_PATH': 'examples/objective-c/auth_sample' - }), self.config.job_spec( ['src/objective-c/tests/build_one_example.sh'], timeout_seconds=10 * 60, @@ -1124,7 +1091,7 @@ class ObjCLanguage(object): }), self.config.job_spec( ['test/core/iomgr/ios/CFStreamTests/run_tests.sh'], - timeout_seconds=10 * 60, + timeout_seconds=20 * 60, shortname='cfstream-tests', cpu_cost=1e6, environ=_FORCE_ENVIRON_FOR_WRAPPERS), @@ -1340,9 +1307,9 @@ argp.add_argument( argp.add_argument( '-l', '--language', - choices=['all'] + sorted(_LANGUAGES.keys()), + choices=sorted(_LANGUAGES.keys()), nargs='+', - default=['all']) + required=True) argp.add_argument( '-S', '--stop_on_failure', default=False, action='store_const', const=True) argp.add_argument( @@ -1513,17 +1480,7 @@ build_config = run_config.build_config if args.travis: _FORCE_ENVIRON_FOR_WRAPPERS = {'GRPC_TRACE': 'api'} -if 'all' in args.language: - lang_list = list(_LANGUAGES.keys()) -else: - lang_list = args.language -# We don't support code coverage on some languages -if 'gcov' in args.config: - for bad in ['csharp', 'grpc-node', 'objc', 'sanity']: - if bad in lang_list: - lang_list.remove(bad) - -languages = set(_LANGUAGES[l] for l in lang_list) +languages = set(_LANGUAGES[l] for l in args.language) for l in languages: l.configure(run_config, args) @@ -1535,7 +1492,7 @@ if any(language.make_options() for language in languages): ) sys.exit(1) else: - # Combining make options is not clean and just happens to work. It allows C/C++ and C# to build + # Combining make options is not clean and just happens to work. It allows C & C++ to build # together, and is only used under gcov. All other configs should build languages individually. language_make_options = list( set([ @@ -1558,16 +1515,9 @@ if args.use_docker: dockerfile_dirs = set([l.dockerfile_dir() for l in languages]) if len(dockerfile_dirs) > 1: - if 'gcov' in args.config: - dockerfile_dir = 'tools/dockerfile/test/multilang_jessie_x64' - print( - 'Using multilang_jessie_x64 docker image for code coverage for ' - 'all languages.') - else: - print( - 'Languages to be tested require running under different docker ' - 'images.') - sys.exit(1) + print('Languages to be tested require running under different docker ' + 'images.') + sys.exit(1) else: dockerfile_dir = next(iter(dockerfile_dirs)) @@ -1649,7 +1599,10 @@ def build_step_environ(cfg): build_steps = list( set( jobset.JobSpec( - cmdline, environ=build_step_environ(build_config), flake_retries=2) + cmdline, + environ=build_step_environ(build_config), + timeout_seconds=_PRE_BUILD_STEP_TIMEOUT_SECONDS, + flake_retries=2) for l in languages for cmdline in l.pre_build_steps())) if make_targets: diff --git a/tools/run_tests/run_tests_matrix.py b/tools/run_tests/run_tests_matrix.py index d93add00cd2..785dff36eab 100755 --- a/tools/run_tests/run_tests_matrix.py +++ b/tools/run_tests/run_tests_matrix.py @@ -197,6 +197,7 @@ def _create_test_jobs(extra_args=[], inner_jobs=_DEFAULT_INNER_JOBS): inner_jobs=inner_jobs, timeout_seconds=_CPP_RUNTESTS_TIMEOUT) + # C# tests on .NET desktop/mono test_jobs += _generate_jobs( languages=['csharp'], configs=['dbg', 'opt'], @@ -204,6 +205,16 @@ def _create_test_jobs(extra_args=[], inner_jobs=_DEFAULT_INNER_JOBS): labels=['basictests', 'multilang'], extra_args=extra_args, inner_jobs=inner_jobs) + # C# tests on .NET core + test_jobs += _generate_jobs( + languages=['csharp'], + configs=['dbg', 'opt'], + platforms=['linux', 'macos', 'windows'], + arch='default', + compiler='coreclr', + labels=['basictests', 'multilang'], + extra_args=extra_args, + inner_jobs=inner_jobs) test_jobs += _generate_jobs( languages=['python'], @@ -392,16 +403,6 @@ def _create_portability_test_jobs(extra_args=[], extra_args=extra_args, inner_jobs=inner_jobs) - test_jobs += _generate_jobs( - languages=['csharp'], - configs=['dbg'], - platforms=['linux'], - arch='default', - compiler='coreclr', - labels=['portability', 'multilang'], - extra_args=extra_args, - inner_jobs=inner_jobs) - test_jobs += _generate_jobs( languages=['c'], configs=['dbg'], diff --git a/tools/run_tests/sanity/check_bazel_workspace.py b/tools/run_tests/sanity/check_bazel_workspace.py index d562fffc8a9..2017f58323c 100755 --- a/tools/run_tests/sanity/check_bazel_workspace.py +++ b/tools/run_tests/sanity/check_bazel_workspace.py @@ -34,7 +34,8 @@ git_submodule_hashes = { for s in git_submodules } -_BAZEL_TOOLCHAINS_DEP_NAME = 'com_github_bazelbuild_bazeltoolchains' +_BAZEL_SKYLIB_DEP_NAME = 'bazel_skylib' +_BAZEL_TOOLCHAINS_DEP_NAME = 'bazel_toolchains' _TWISTED_TWISTED_DEP_NAME = 'com_github_twisted_twisted' _YAML_PYYAML_DEP_NAME = 'com_github_yaml_pyyaml' _TWISTED_INCREMENTAL_DEP_NAME = 'com_github_twisted_incremental' @@ -42,6 +43,7 @@ _ZOPEFOUNDATION_ZOPE_INTERFACE_DEP_NAME = 'com_github_zopefoundation_zope_interf _TWISTED_CONSTANTLY_DEP_NAME = 'com_github_twisted_constantly' _GRPC_DEP_NAMES = [ + 'upb', 'boringssl', 'com_github_madler_zlib', 'com_google_protobuf', @@ -52,6 +54,7 @@ _GRPC_DEP_NAMES = [ 'com_github_cares_cares', 'com_google_absl', 'io_opencensus_cpp', + _BAZEL_SKYLIB_DEP_NAME, _BAZEL_TOOLCHAINS_DEP_NAME, _TWISTED_TWISTED_DEP_NAME, _YAML_PYYAML_DEP_NAME, @@ -61,6 +64,7 @@ _GRPC_DEP_NAMES = [ ] _GRPC_BAZEL_ONLY_DEPS = [ + _BAZEL_SKYLIB_DEP_NAME, _BAZEL_TOOLCHAINS_DEP_NAME, _TWISTED_TWISTED_DEP_NAME, _YAML_PYYAML_DEP_NAME, @@ -110,6 +114,8 @@ bazel_file += '\ngrpc_deps()\n' bazel_file += '\ngrpc_test_only_deps()\n' build_rules = { 'native': eval_state, + 'http_archive': lambda **args: eval_state.http_archive(**args), + 'load': lambda a, b: None, } exec bazel_file in build_rules for name in _GRPC_DEP_NAMES: @@ -149,6 +155,8 @@ for name in _GRPC_DEP_NAMES: names_and_urls_with_overridden_name, overridden_name=name) rules = { 'native': state, + 'http_archive': lambda **args: state.http_archive(**args), + 'load': lambda a, b: None, } exec bazel_file in rules assert name not in names_and_urls_with_overridden_name.keys() diff --git a/tools/run_tests/sanity/check_port_platform.py b/tools/run_tests/sanity/check_port_platform.py index fff828eaee8..79e7f9c4033 100755 --- a/tools/run_tests/sanity/check_port_platform.py +++ b/tools/run_tests/sanity/check_port_platform.py @@ -35,6 +35,9 @@ def check_port_platform_inclusion(directory_root): continue if filename.endswith('.pb.h') or filename.endswith('.pb.c'): continue + # Skip check for upb generated code. + if filename.endswith('.upb.h') or filename.endswith('.upb.c'): + continue with open(path) as f: all_lines_in_file = f.readlines() for index, l in enumerate(all_lines_in_file): diff --git a/tools/run_tests/sanity/check_submodules.sh b/tools/run_tests/sanity/check_submodules.sh index fa2628f18ea..b15b8d3b077 100755 --- a/tools/run_tests/sanity/check_submodules.sh +++ b/tools/run_tests/sanity/check_submodules.sh @@ -27,19 +27,20 @@ want_submodules=$(mktemp /tmp/submXXXXXX) git submodule | awk '{ print $1 }' | sort > "$submodules" cat << EOF | awk '{ print $1 }' | sort > "$want_submodules" cc4bed2d74f7c8717e31f9579214ab52a9c9c610 third_party/abseil-cpp (cc4bed2) - 5b7683f49e1e9223cf9927b24f6fd3d6bd82e3f8 third_party/benchmark (v1.2.0) + e776aa0275e293707b6a0901e0e8d8a8a3679508 third_party/benchmark (v1.2.0) 73594cde8c9a52a102c4341c244c833aa61b9c06 third_party/bloaty (remotes/origin/wide-14-g73594cd) b29b21a81b32ec273f118f589f46d56ad3332420 third_party/boringssl (remotes/origin/chromium-stable) afc30d43eef92979b05776ec0963c9cede5fb80f third_party/boringssl-with-bazel (fips-20180716-116-gafc30d43e) - 3be1924221e1326df520f8498d704a5c4c8d0cce third_party/cares/cares (cares-1_13_0) + e982924acee7f7313b4baa4ee5ec000c5e373c30 third_party/cares/cares (cares-1_15_0) 911001cdca003337bdb93fab32740cde61bafee3 third_party/data-plane-api (heads/master) - 30dbc81fb5ffdc98ea9b14b1918bfe4e8779b26e third_party/gflags (v2.2.0-5-g30dbc81) + 28f50e0fed19872e0fd50dd23ce2ee8cd759338e third_party/gflags (v2.2.0-5-g30dbc81) 80ed4d0bbf65d57cc267dfc63bd2584557f11f9b third_party/googleapis (common-protos-1_3_1-915-g80ed4d0bb) ec44c6c1675c25b9827aacd08c02433cccde7780 third_party/googletest (release-1.8.0) 6599cac0965be8e5a835ab7a5684bbef033d5ad0 third_party/libcxx (heads/release_60) 9245d481eb3e890f708ff2d7dadf2a10c04748ba third_party/libcxxabi (heads/release_60) - 48cb18e5c419ddd23d9badcfe4e9df7bde1979b2 third_party/protobuf (v3.6.0.1-37-g48cb18e5) + 582743bf40c5d3639a70f98f183914a2c0cd0680 third_party/protobuf (v3.7.0-rc.2-20-g582743bf) e143189bf6f37b3957fb31743df6a1bcf4a8c685 third_party/protoc-gen-validate (v0.0.10) + fa88c6017ddb490aa78c57bea682193f533ed69a third_party/upb (heads/master) cacf7f1d4e3d44d871b605da3b647f07d718623f third_party/zlib (v1.2.11) EOF